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=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  from ganeti import utils 
 35   
 36  from ganeti.rapi import baserlib 
 37  from ganeti.rapi import rlib2 
 38   
 39   
 40  _NAME_PATTERN = r"[\w\._-]+" 
 41  _DISK_PATTERN = r"\d+" 
 42   
 43  # the connection map is created at the end of this file 
 44  CONNECTOR = {} 
45 46 47 -class Mapper:
48 """Map resource to method. 49 50 """
51 - def __init__(self, connector=None):
52 """Resource mapper constructor. 53 54 @param connector: a dictionary, mapping method name with URL path regexp 55 56 """ 57 if connector is None: 58 connector = CONNECTOR 59 self._connector = connector
60
61 - def getController(self, uri):
62 """Find method for a given URI. 63 64 @param uri: string with URI 65 66 @return: None if no method is found or a tuple containing 67 the following fields: 68 - method: name of method mapped to URI 69 - items: a list of variable intems in the path 70 - args: a dictionary with additional parameters from URL 71 72 """ 73 if "?" in uri: 74 (path, query) = uri.split("?", 1) 75 args = cgi.parse_qs(query) 76 else: 77 path = uri 78 query = None 79 args = {} 80 81 # Try to find handler for request path 82 result = utils.FindMatch(self._connector, path) 83 84 if result is None: 85 raise http.HttpNotFound() 86 87 (handler, groups) = result 88 89 return (handler, groups, args)
90
91 92 -class R_root(baserlib.R_Generic):
93 """/ resource. 94 95 """ 96 _ROOT_PATTERN = re.compile("^R_([a-zA-Z0-9]+)$") 97 98 @classmethod
99 - def GET(cls):
100 """Show the list of mapped resources. 101 102 @return: a dictionary with 'name' and 'uri' keys for each of them. 103 104 """ 105 rootlist = [] 106 for handler in CONNECTOR.values(): 107 m = cls._ROOT_PATTERN.match(handler.__name__) 108 if m: 109 name = m.group(1) 110 if name != "root": 111 rootlist.append(name) 112 113 return baserlib.BuildUriList(rootlist, "/%s")
114
115 116 -def _getResources(id_):
117 """Return a list of resources underneath given id. 118 119 This is to generalize querying of version resources lists. 120 121 @return: a list of resources names. 122 123 """ 124 r_pattern = re.compile("^R_%s_([a-zA-Z0-9]+)$" % id_) 125 126 rlist = [] 127 for handler in CONNECTOR.values(): 128 m = r_pattern.match(handler.__name__) 129 if m: 130 name = m.group(1) 131 rlist.append(name) 132 133 return rlist
134
135 136 -class R_2(baserlib.R_Generic):
137 """/2 resource. 138 139 This is the root of the version 2 API. 140 141 """ 142 @staticmethod
143 - def GET():
144 """Show the list of mapped resources. 145 146 @return: a dictionary with 'name' and 'uri' keys for each of them. 147 148 """ 149 return baserlib.BuildUriList(_getResources("2"), "/2/%s")
150
151 152 -def GetHandlers(node_name_pattern, instance_name_pattern, 153 group_name_pattern, job_id_pattern, disk_pattern, 154 query_res_pattern):
155 """Returns all supported resources and their handlers. 156 157 """ 158 # Important note: New resources should always be added under /2. During a 159 # discussion in July 2010 it was decided that having per-resource versions 160 # is more flexible and future-compatible than versioning the whole remote 161 # API. 162 return { 163 "/": R_root, 164 165 "/version": rlib2.R_version, 166 167 "/2": R_2, 168 169 "/2/nodes": rlib2.R_2_nodes, 170 re.compile(r"^/2/nodes/(%s)$" % node_name_pattern): 171 rlib2.R_2_nodes_name, 172 re.compile(r"^/2/nodes/(%s)/tags$" % node_name_pattern): 173 rlib2.R_2_nodes_name_tags, 174 re.compile(r"^/2/nodes/(%s)/role$" % node_name_pattern): 175 rlib2.R_2_nodes_name_role, 176 re.compile(r"^/2/nodes/(%s)/evacuate$" % node_name_pattern): 177 rlib2.R_2_nodes_name_evacuate, 178 re.compile(r"^/2/nodes/(%s)/migrate$" % node_name_pattern): 179 rlib2.R_2_nodes_name_migrate, 180 re.compile(r"^/2/nodes/(%s)/storage$" % node_name_pattern): 181 rlib2.R_2_nodes_name_storage, 182 re.compile(r"^/2/nodes/(%s)/storage/modify$" % node_name_pattern): 183 rlib2.R_2_nodes_name_storage_modify, 184 re.compile(r"^/2/nodes/(%s)/storage/repair$" % node_name_pattern): 185 rlib2.R_2_nodes_name_storage_repair, 186 187 "/2/instances": rlib2.R_2_instances, 188 re.compile(r"^/2/instances/(%s)$" % instance_name_pattern): 189 rlib2.R_2_instances_name, 190 re.compile(r"^/2/instances/(%s)/info$" % instance_name_pattern): 191 rlib2.R_2_instances_name_info, 192 re.compile(r"^/2/instances/(%s)/tags$" % instance_name_pattern): 193 rlib2.R_2_instances_name_tags, 194 re.compile(r"^/2/instances/(%s)/reboot$" % instance_name_pattern): 195 rlib2.R_2_instances_name_reboot, 196 re.compile(r"^/2/instances/(%s)/reinstall$" % instance_name_pattern): 197 rlib2.R_2_instances_name_reinstall, 198 re.compile(r"^/2/instances/(%s)/replace-disks$" % instance_name_pattern): 199 rlib2.R_2_instances_name_replace_disks, 200 re.compile(r"^/2/instances/(%s)/shutdown$" % instance_name_pattern): 201 rlib2.R_2_instances_name_shutdown, 202 re.compile(r"^/2/instances/(%s)/startup$" % instance_name_pattern): 203 rlib2.R_2_instances_name_startup, 204 re.compile(r"^/2/instances/(%s)/activate-disks$" % instance_name_pattern): 205 rlib2.R_2_instances_name_activate_disks, 206 re.compile(r"^/2/instances/(%s)/deactivate-disks$" % instance_name_pattern): 207 rlib2.R_2_instances_name_deactivate_disks, 208 re.compile(r"^/2/instances/(%s)/prepare-export$" % instance_name_pattern): 209 rlib2.R_2_instances_name_prepare_export, 210 re.compile(r"^/2/instances/(%s)/export$" % instance_name_pattern): 211 rlib2.R_2_instances_name_export, 212 re.compile(r"^/2/instances/(%s)/migrate$" % instance_name_pattern): 213 rlib2.R_2_instances_name_migrate, 214 re.compile(r"^/2/instances/(%s)/failover$" % instance_name_pattern): 215 rlib2.R_2_instances_name_failover, 216 re.compile(r"^/2/instances/(%s)/rename$" % instance_name_pattern): 217 rlib2.R_2_instances_name_rename, 218 re.compile(r"^/2/instances/(%s)/modify$" % instance_name_pattern): 219 rlib2.R_2_instances_name_modify, 220 re.compile(r"^/2/instances/(%s)/disk/(%s)/grow$" % 221 (instance_name_pattern, disk_pattern)): 222 rlib2.R_2_instances_name_disk_grow, 223 re.compile(r"^/2/instances/(%s)/console$" % instance_name_pattern): 224 rlib2.R_2_instances_name_console, 225 226 "/2/groups": rlib2.R_2_groups, 227 re.compile(r"^/2/groups/(%s)$" % group_name_pattern): 228 rlib2.R_2_groups_name, 229 re.compile(r"^/2/groups/(%s)/modify$" % group_name_pattern): 230 rlib2.R_2_groups_name_modify, 231 re.compile(r"^/2/groups/(%s)/rename$" % group_name_pattern): 232 rlib2.R_2_groups_name_rename, 233 re.compile(r"^/2/groups/(%s)/assign-nodes$" % group_name_pattern): 234 rlib2.R_2_groups_name_assign_nodes, 235 re.compile(r"^/2/groups/(%s)/tags$" % group_name_pattern): 236 rlib2.R_2_groups_name_tags, 237 238 "/2/jobs": rlib2.R_2_jobs, 239 re.compile(r"^/2/jobs/(%s)$" % job_id_pattern): 240 rlib2.R_2_jobs_id, 241 re.compile(r"^/2/jobs/(%s)/wait$" % job_id_pattern): 242 rlib2.R_2_jobs_id_wait, 243 244 "/2/tags": rlib2.R_2_tags, 245 "/2/info": rlib2.R_2_info, 246 "/2/os": rlib2.R_2_os, 247 "/2/redistribute-config": rlib2.R_2_redist_config, 248 "/2/features": rlib2.R_2_features, 249 "/2/modify": rlib2.R_2_cluster_modify, 250 re.compile(r"^/2/query/(%s)$" % query_res_pattern): rlib2.R_2_query, 251 re.compile(r"^/2/query/(%s)/fields$" % query_res_pattern): 252 rlib2.R_2_query_fields, 253 }
254 255 256 CONNECTOR.update(GetHandlers(_NAME_PATTERN, _NAME_PATTERN, _NAME_PATTERN, 257 constants.JOB_ID_TEMPLATE, _DISK_PATTERN, 258 _NAME_PATTERN)) 259