Package ganeti :: Package rapi :: Module connector
[hide private]
[frames] | no frames]

Source Code for Module ganeti.rapi.connector

  1  # 
  2  # 
  3   
  4  # Copyright (C) 2006, 2007, 2008 Google Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, but 
 12  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 14  # General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the Free Software 
 18  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
 19  # 02110-1301, USA. 
 20   
 21  """Remote API connection map. 
 22   
 23  """ 
 24   
 25  # pylint: disable-msg=C0103 
 26   
 27  # C0103: Invalid name, since the R_* names are not conforming 
 28   
 29  import cgi 
 30  import re 
 31   
 32  from ganeti import constants 
 33  from ganeti import http 
 34   
 35  from ganeti.rapi import baserlib 
 36  from ganeti.rapi import rlib2 
 37   
 38  # the connection map is created at the end of this file 
 39  CONNECTOR = {} 
 40   
 41   
42 -class Mapper:
43 """Map resource to method. 44 45 """
46 - def __init__(self, connector=CONNECTOR):
47 """Resource mapper constructor. 48 49 @param connector: a dictionary, mapping method name with URL path regexp 50 51 """ 52 self._connector = connector
53
54 - def getController(self, uri):
55 """Find method for a given URI. 56 57 @param uri: string with URI 58 59 @return: None if no method is found or a tuple containing 60 the following fields: 61 - method: name of method mapped to URI 62 - items: a list of variable intems in the path 63 - args: a dictionary with additional parameters from URL 64 65 """ 66 if '?' in uri: 67 (path, query) = uri.split('?', 1) 68 args = cgi.parse_qs(query) 69 else: 70 path = uri 71 query = None 72 args = {} 73 74 result = None 75 76 for key, handler in self._connector.iteritems(): 77 # Regex objects 78 if hasattr(key, "match"): 79 m = key.match(path) 80 if m: 81 result = (handler, list(m.groups()), args) 82 break 83 84 # String objects 85 elif key == path: 86 result = (handler, [], args) 87 break 88 89 if result: 90 return result 91 else: 92 raise http.HttpNotFound()
93 94
95 -class R_root(baserlib.R_Generic):
96 """/ resource. 97 98 """ 99 DOC_URI = "/" 100
101 - def GET(self):
102 """Show the list of mapped resources. 103 104 @return: a dictionary with 'name' and 'uri' keys for each of them. 105 106 """ 107 root_pattern = re.compile('^R_([a-zA-Z0-9]+)$') 108 109 rootlist = [] 110 for handler in CONNECTOR.values(): 111 m = root_pattern.match(handler.__name__) 112 if m: 113 name = m.group(1) 114 if name != 'root': 115 rootlist.append(name) 116 117 return baserlib.BuildUriList(rootlist, "/%s")
118 119
120 -def _getResources(id):
121 """Return a list of resources underneath given id. 122 123 This is to generalize querying of version resources lists. 124 125 @return: a list of resources names. 126 127 """ 128 r_pattern = re.compile('^R_%s_([a-zA-Z0-9]+)$' % id) 129 130 rlist = [] 131 for handler in CONNECTOR.values(): 132 m = r_pattern.match(handler.__name__) 133 if m: 134 name = m.group(1) 135 rlist.append(name) 136 137 return rlist
138 139
140 -class R_2(baserlib.R_Generic):
141 """ /2 resource, the root of the version 2 API. 142 143 """ 144 DOC_URI = "/2" 145
146 - def GET(self):
147 """Show the list of mapped resources. 148 149 @return: a dictionary with 'name' and 'uri' keys for each of them. 150 151 """ 152 return baserlib.BuildUriList(_getResources("2"), "/2/%s")
153 154 155 CONNECTOR.update({ 156 "/": R_root, 157 158 "/version": rlib2.R_version, 159 160 "/2": R_2, 161 "/2/jobs": rlib2.R_2_jobs, 162 "/2/nodes": rlib2.R_2_nodes, 163 re.compile(r'^/2/nodes/([\w\._-]+)$'): rlib2.R_2_nodes_name, 164 re.compile(r'^/2/nodes/([\w\._-]+)/tags$'): rlib2.R_2_nodes_name_tags, 165 "/2/instances": rlib2.R_2_instances, 166 re.compile(r'^/2/instances/([\w\._-]+)$'): rlib2.R_2_instances_name, 167 re.compile(r'^/2/instances/([\w\._-]+)/tags$'): rlib2.R_2_instances_name_tags, 168 re.compile(r'^/2/instances/([\w\._-]+)/reboot$'): 169 rlib2.R_2_instances_name_reboot, 170 re.compile(r'^/2/instances/([\w\._-]+)/reinstall$'): 171 rlib2.R_2_instances_name_reinstall, 172 re.compile(r'^/2/instances/([\w\._-]+)/shutdown$'): 173 rlib2.R_2_instances_name_shutdown, 174 re.compile(r'^/2/instances/([\w\._-]+)/startup$'): 175 rlib2.R_2_instances_name_startup, 176 re.compile(r'/2/jobs/(%s)$' % constants.JOB_ID_TEMPLATE): rlib2.R_2_jobs_id, 177 "/2/tags": rlib2.R_2_tags, 178 "/2/info": rlib2.R_2_info, 179 "/2/os": rlib2.R_2_os, 180 }) 181