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  # All rights reserved. 
  6  # 
  7  # Redistribution and use in source and binary forms, with or without 
  8  # modification, are permitted provided that the following conditions are 
  9  # met: 
 10  # 
 11  # 1. Redistributions of source code must retain the above copyright notice, 
 12  # this list of conditions and the following disclaimer. 
 13  # 
 14  # 2. Redistributions in binary form must reproduce the above copyright 
 15  # notice, this list of conditions and the following disclaimer in the 
 16  # documentation and/or other materials provided with the distribution. 
 17  # 
 18  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
 19  # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
 20  # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 21  # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
 22  # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 23  # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 24  # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
 25  # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 26  # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 27  # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 28  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 29   
 30  """Remote API connection map. 
 31   
 32  """ 
 33   
 34  # pylint: disable=C0103 
 35   
 36  # C0103: Invalid name, since the R_* names are not conforming 
 37   
 38  import re 
 39  import urlparse 
 40   
 41  from ganeti import constants 
 42  from ganeti import http 
 43  from ganeti import utils 
 44   
 45  from ganeti.rapi import rlib2 
 46   
 47   
 48  _NAME_PATTERN = r"[\w\._-]+" 
 49  _DISK_PATTERN = r"\d+" 
 50   
 51  # the connection map is created at the end of this file 
 52  CONNECTOR = {} 
 53   
 54   
55 -class Mapper(object):
56 """Map resource to method. 57 58 """
59 - def __init__(self, connector=None):
60 """Resource mapper constructor. 61 62 @param connector: a dictionary, mapping method name with URL path regexp 63 64 """ 65 if connector is None: 66 connector = CONNECTOR 67 self._connector = connector
68
69 - def getController(self, uri):
70 """Find method for a given URI. 71 72 @param uri: string with URI 73 74 @return: None if no method is found or a tuple containing 75 the following fields: 76 - method: name of method mapped to URI 77 - items: a list of variable intems in the path 78 - args: a dictionary with additional parameters from URL 79 80 """ 81 if "?" in uri: 82 (path, query) = uri.split("?", 1) 83 args = urlparse.parse_qs(query) 84 else: 85 path = uri 86 query = None 87 args = {} 88 89 # Try to find handler for request path 90 result = utils.FindMatch(self._connector, path) 91 92 if result is None: 93 raise http.HttpNotFound() 94 95 (handler, groups) = result 96 97 return (handler, groups, args)
98 99
100 -def _ConvertPattern(value):
101 """Converts URI pattern into a regular expression group. 102 103 Used by L{_CompileHandlerPath}. 104 105 """ 106 if isinstance(value, UriPattern): 107 return "(%s)" % value.content 108 else: 109 return value
110 111
112 -def _CompileHandlerPath(*args):
113 """Compiles path for RAPI resource into regular expression. 114 115 @return: Compiled regular expression object 116 117 """ 118 return re.compile("^%s$" % "".join(map(_ConvertPattern, args)))
119 120
121 -class UriPattern(object):
122 __slots__ = [ 123 "content", 124 ] 125
126 - def __init__(self, content):
127 self.content = content
128 129
130 -def GetHandlers(node_name_pattern, instance_name_pattern, 131 group_name_pattern, network_name_pattern, 132 job_id_pattern, disk_pattern, 133 query_res_pattern, 134 translate=None):
135 """Returns all supported resources and their handlers. 136 137 C{node_name_pattern} and the other C{*_pattern} parameters are wrapped in 138 L{UriPattern} and, if used in a URI, passed to the function specified using 139 C{translate}. C{translate} receives 1..N parameters which are either plain 140 strings or instances of L{UriPattern} and returns a dictionary key suitable 141 for the caller of C{GetHandlers}. The default implementation in 142 L{_CompileHandlerPath} returns a compiled regular expression in which each 143 pattern is a group. 144 145 @rtype: dict 146 147 """ 148 if translate is None: 149 translate_fn = _CompileHandlerPath 150 else: 151 translate_fn = translate 152 153 node_name = UriPattern(node_name_pattern) 154 instance_name = UriPattern(instance_name_pattern) 155 group_name = UriPattern(group_name_pattern) 156 network_name = UriPattern(network_name_pattern) 157 job_id = UriPattern(job_id_pattern) 158 disk = UriPattern(disk_pattern) 159 query_res = UriPattern(query_res_pattern) 160 161 # Important note: New resources should always be added under /2. During a 162 # discussion in July 2010 it was decided that having per-resource versions 163 # is more flexible and future-compatible than versioning the whole remote 164 # API. 165 # TODO: Consider a different data structure where all keys are of the same 166 # type. Strings are faster to look up in a dictionary than iterating and 167 # matching regular expressions, therefore maybe two separate dictionaries 168 # should be used. 169 return { 170 "/": rlib2.R_root, 171 "/2": rlib2.R_2, 172 173 "/version": rlib2.R_version, 174 175 "/2/nodes": rlib2.R_2_nodes, 176 177 translate_fn("/2/nodes/", node_name): 178 rlib2.R_2_nodes_name, 179 translate_fn("/2/nodes/", node_name, "/powercycle"): 180 rlib2.R_2_nodes_name_powercycle, 181 translate_fn("/2/nodes/", node_name, "/tags"): 182 rlib2.R_2_nodes_name_tags, 183 translate_fn("/2/nodes/", node_name, "/role"): 184 rlib2.R_2_nodes_name_role, 185 translate_fn("/2/nodes/", node_name, "/evacuate"): 186 rlib2.R_2_nodes_name_evacuate, 187 translate_fn("/2/nodes/", node_name, "/migrate"): 188 rlib2.R_2_nodes_name_migrate, 189 translate_fn("/2/nodes/", node_name, "/modify"): 190 rlib2.R_2_nodes_name_modify, 191 translate_fn("/2/nodes/", node_name, "/storage"): 192 rlib2.R_2_nodes_name_storage, 193 translate_fn("/2/nodes/", node_name, "/storage/modify"): 194 rlib2.R_2_nodes_name_storage_modify, 195 translate_fn("/2/nodes/", node_name, "/storage/repair"): 196 rlib2.R_2_nodes_name_storage_repair, 197 198 "/2/instances": rlib2.R_2_instances, 199 translate_fn("/2/instances/", instance_name): 200 rlib2.R_2_instances_name, 201 translate_fn("/2/instances/", instance_name, "/info"): 202 rlib2.R_2_instances_name_info, 203 translate_fn("/2/instances/", instance_name, "/tags"): 204 rlib2.R_2_instances_name_tags, 205 translate_fn("/2/instances/", instance_name, "/reboot"): 206 rlib2.R_2_instances_name_reboot, 207 translate_fn("/2/instances/", instance_name, "/reinstall"): 208 rlib2.R_2_instances_name_reinstall, 209 translate_fn("/2/instances/", instance_name, "/replace-disks"): 210 rlib2.R_2_instances_name_replace_disks, 211 translate_fn("/2/instances/", instance_name, "/shutdown"): 212 rlib2.R_2_instances_name_shutdown, 213 translate_fn("/2/instances/", instance_name, "/startup"): 214 rlib2.R_2_instances_name_startup, 215 translate_fn("/2/instances/", instance_name, "/activate-disks"): 216 rlib2.R_2_instances_name_activate_disks, 217 translate_fn("/2/instances/", instance_name, "/deactivate-disks"): 218 rlib2.R_2_instances_name_deactivate_disks, 219 translate_fn("/2/instances/", instance_name, "/recreate-disks"): 220 rlib2.R_2_instances_name_recreate_disks, 221 translate_fn("/2/instances/", instance_name, "/prepare-export"): 222 rlib2.R_2_instances_name_prepare_export, 223 translate_fn("/2/instances/", instance_name, "/export"): 224 rlib2.R_2_instances_name_export, 225 translate_fn("/2/instances/", instance_name, "/migrate"): 226 rlib2.R_2_instances_name_migrate, 227 translate_fn("/2/instances/", instance_name, "/failover"): 228 rlib2.R_2_instances_name_failover, 229 translate_fn("/2/instances/", instance_name, "/rename"): 230 rlib2.R_2_instances_name_rename, 231 translate_fn("/2/instances/", instance_name, "/modify"): 232 rlib2.R_2_instances_name_modify, 233 translate_fn("/2/instances/", instance_name, "/disk/", disk, "/grow"): 234 rlib2.R_2_instances_name_disk_grow, 235 translate_fn("/2/instances/", instance_name, "/console"): 236 rlib2.R_2_instances_name_console, 237 238 "/2/networks": rlib2.R_2_networks, 239 translate_fn("/2/networks/", network_name): 240 rlib2.R_2_networks_name, 241 translate_fn("/2/networks/", network_name, "/connect"): 242 rlib2.R_2_networks_name_connect, 243 translate_fn("/2/networks/", network_name, "/disconnect"): 244 rlib2.R_2_networks_name_disconnect, 245 translate_fn("/2/networks/", network_name, "/modify"): 246 rlib2.R_2_networks_name_modify, 247 translate_fn("/2/networks/", network_name, "/tags"): 248 rlib2.R_2_networks_name_tags, 249 250 "/2/groups": rlib2.R_2_groups, 251 translate_fn("/2/groups/", group_name): 252 rlib2.R_2_groups_name, 253 translate_fn("/2/groups/", group_name, "/modify"): 254 rlib2.R_2_groups_name_modify, 255 translate_fn("/2/groups/", group_name, "/rename"): 256 rlib2.R_2_groups_name_rename, 257 translate_fn("/2/groups/", group_name, "/assign-nodes"): 258 rlib2.R_2_groups_name_assign_nodes, 259 translate_fn("/2/groups/", group_name, "/tags"): 260 rlib2.R_2_groups_name_tags, 261 262 "/2/jobs": rlib2.R_2_jobs, 263 translate_fn("/2/jobs/", job_id): 264 rlib2.R_2_jobs_id, 265 translate_fn("/2/jobs/", job_id, "/wait"): 266 rlib2.R_2_jobs_id_wait, 267 268 "/2/instances-multi-alloc": rlib2.R_2_instances_multi_alloc, 269 "/2/tags": rlib2.R_2_tags, 270 "/2/info": rlib2.R_2_info, 271 "/2/os": rlib2.R_2_os, 272 "/2/redistribute-config": rlib2.R_2_redist_config, 273 "/2/features": rlib2.R_2_features, 274 "/2/modify": rlib2.R_2_cluster_modify, 275 276 translate_fn("/2/query/", query_res): 277 rlib2.R_2_query, 278 translate_fn("/2/query/", query_res, "/fields"): 279 rlib2.R_2_query_fields, 280 }
281 282 283 CONNECTOR.update(GetHandlers(_NAME_PATTERN, _NAME_PATTERN, 284 _NAME_PATTERN, _NAME_PATTERN, 285 constants.JOB_ID_TEMPLATE, _DISK_PATTERN, 286 _NAME_PATTERN)) 287