X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/7eac4a4d56abfbe67ab9fe536a25892ea56b23f0..80b898f91857135374733f0e486bb4f8968e735d:/lib/rapi/connector.py diff --git a/lib/rapi/connector.py b/lib/rapi/connector.py index aa60a0a..b701d71 100644 --- a/lib/rapi/connector.py +++ b/lib/rapi/connector.py @@ -22,7 +22,7 @@ """ -# pylint: disable-msg=C0103 +# pylint: disable=C0103 # C0103: Invalid name, since the R_* names are not conforming @@ -31,12 +31,13 @@ import re from ganeti import constants from ganeti import http +from ganeti import utils -from ganeti.rapi import baserlib from ganeti.rapi import rlib2 _NAME_PATTERN = r"[\w\._-]+" +_DISK_PATTERN = r"\d+" # the connection map is created at the end of this file CONNECTOR = {} @@ -68,148 +69,120 @@ class Mapper: - args: a dictionary with additional parameters from URL """ - if '?' in uri: - (path, query) = uri.split('?', 1) + if "?" in uri: + (path, query) = uri.split("?", 1) args = cgi.parse_qs(query) else: path = uri query = None args = {} - result = None + # Try to find handler for request path + result = utils.FindMatch(self._connector, path) - for key, handler in self._connector.iteritems(): - # Regex objects - if hasattr(key, "match"): - m = key.match(path) - if m: - result = (handler, list(m.groups()), args) - break - - # String objects - elif key == path: - result = (handler, [], args) - break - - if result: - return result - else: + if result is None: raise http.HttpNotFound() + (handler, groups) = result -class R_root(baserlib.R_Generic): - """/ resource. - - """ - @staticmethod - def GET(): - """Show the list of mapped resources. - - @return: a dictionary with 'name' and 'uri' keys for each of them. - - """ - root_pattern = re.compile('^R_([a-zA-Z0-9]+)$') - - rootlist = [] - for handler in CONNECTOR.values(): - m = root_pattern.match(handler.__name__) - if m: - name = m.group(1) - if name != 'root': - rootlist.append(name) - - return baserlib.BuildUriList(rootlist, "/%s") - - -def _getResources(id_): - """Return a list of resources underneath given id. - - This is to generalize querying of version resources lists. + return (handler, groups, args) - @return: a list of resources names. - """ - r_pattern = re.compile('^R_%s_([a-zA-Z0-9]+)$' % id_) - - rlist = [] - for handler in CONNECTOR.values(): - m = r_pattern.match(handler.__name__) - if m: - name = m.group(1) - rlist.append(name) - - return rlist - - -class R_2(baserlib.R_Generic): - """ /2 resource, the root of the version 2 API. - - """ - @staticmethod - def GET(): - """Show the list of mapped resources. - - @return: a dictionary with 'name' and 'uri' keys for each of them. - - """ - return baserlib.BuildUriList(_getResources("2"), "/2/%s") - - -def GetHandlers(node_name_pattern, instance_name_pattern, job_id_pattern): +def GetHandlers(node_name_pattern, instance_name_pattern, + group_name_pattern, job_id_pattern, disk_pattern, + query_res_pattern): """Returns all supported resources and their handlers. """ + # Important note: New resources should always be added under /2. During a + # discussion in July 2010 it was decided that having per-resource versions + # is more flexible and future-compatible than versioning the whole remote + # API. return { - "/": R_root, + "/": rlib2.R_root, + "/2": rlib2.R_2, "/version": rlib2.R_version, - "/2": R_2, - "/2/nodes": rlib2.R_2_nodes, - re.compile(r'^/2/nodes/(%s)$' % node_name_pattern): + re.compile(r"^/2/nodes/(%s)$" % node_name_pattern): rlib2.R_2_nodes_name, - re.compile(r'^/2/nodes/(%s)/tags$' % node_name_pattern): + re.compile(r"^/2/nodes/(%s)/powercycle$" % node_name_pattern): + rlib2.R_2_nodes_name_powercycle, + re.compile(r"^/2/nodes/(%s)/tags$" % node_name_pattern): rlib2.R_2_nodes_name_tags, - re.compile(r'^/2/nodes/(%s)/role$' % node_name_pattern): + re.compile(r"^/2/nodes/(%s)/role$" % node_name_pattern): rlib2.R_2_nodes_name_role, - re.compile(r'^/2/nodes/(%s)/evacuate$' % node_name_pattern): + re.compile(r"^/2/nodes/(%s)/evacuate$" % node_name_pattern): rlib2.R_2_nodes_name_evacuate, - re.compile(r'^/2/nodes/(%s)/migrate$' % node_name_pattern): + re.compile(r"^/2/nodes/(%s)/migrate$" % node_name_pattern): rlib2.R_2_nodes_name_migrate, - re.compile(r'^/2/nodes/(%s)/storage$' % node_name_pattern): + re.compile(r"^/2/nodes/(%s)/modify$" % node_name_pattern): + rlib2.R_2_nodes_name_modify, + re.compile(r"^/2/nodes/(%s)/storage$" % node_name_pattern): rlib2.R_2_nodes_name_storage, - re.compile(r'^/2/nodes/(%s)/storage/modify$' % node_name_pattern): + re.compile(r"^/2/nodes/(%s)/storage/modify$" % node_name_pattern): rlib2.R_2_nodes_name_storage_modify, - re.compile(r'^/2/nodes/(%s)/storage/repair$' % node_name_pattern): + re.compile(r"^/2/nodes/(%s)/storage/repair$" % node_name_pattern): rlib2.R_2_nodes_name_storage_repair, "/2/instances": rlib2.R_2_instances, - re.compile(r'^/2/instances/(%s)$' % instance_name_pattern): + re.compile(r"^/2/instances/(%s)$" % instance_name_pattern): rlib2.R_2_instances_name, - re.compile(r'^/2/instances/(%s)/info$' % instance_name_pattern): + re.compile(r"^/2/instances/(%s)/info$" % instance_name_pattern): rlib2.R_2_instances_name_info, - re.compile(r'^/2/instances/(%s)/tags$' % instance_name_pattern): + re.compile(r"^/2/instances/(%s)/tags$" % instance_name_pattern): rlib2.R_2_instances_name_tags, - re.compile(r'^/2/instances/(%s)/reboot$' % instance_name_pattern): + re.compile(r"^/2/instances/(%s)/reboot$" % instance_name_pattern): rlib2.R_2_instances_name_reboot, - re.compile(r'^/2/instances/(%s)/reinstall$' % instance_name_pattern): + re.compile(r"^/2/instances/(%s)/reinstall$" % instance_name_pattern): rlib2.R_2_instances_name_reinstall, - re.compile(r'^/2/instances/(%s)/replace-disks$' % instance_name_pattern): + re.compile(r"^/2/instances/(%s)/replace-disks$" % instance_name_pattern): rlib2.R_2_instances_name_replace_disks, - re.compile(r'^/2/instances/(%s)/shutdown$' % instance_name_pattern): + re.compile(r"^/2/instances/(%s)/shutdown$" % instance_name_pattern): rlib2.R_2_instances_name_shutdown, - re.compile(r'^/2/instances/(%s)/startup$' % instance_name_pattern): + re.compile(r"^/2/instances/(%s)/startup$" % instance_name_pattern): rlib2.R_2_instances_name_startup, - re.compile(r'^/2/instances/(%s)/activate-disks$' % instance_name_pattern): + re.compile(r"^/2/instances/(%s)/activate-disks$" % instance_name_pattern): rlib2.R_2_instances_name_activate_disks, - re.compile(r'^/2/instances/(%s)/deactivate-disks$' % instance_name_pattern): + re.compile(r"^/2/instances/(%s)/deactivate-disks$" % instance_name_pattern): rlib2.R_2_instances_name_deactivate_disks, + re.compile(r"^/2/instances/(%s)/recreate-disks$" % instance_name_pattern): + rlib2.R_2_instances_name_recreate_disks, + re.compile(r"^/2/instances/(%s)/prepare-export$" % instance_name_pattern): + rlib2.R_2_instances_name_prepare_export, + re.compile(r"^/2/instances/(%s)/export$" % instance_name_pattern): + rlib2.R_2_instances_name_export, + re.compile(r"^/2/instances/(%s)/migrate$" % instance_name_pattern): + rlib2.R_2_instances_name_migrate, + re.compile(r"^/2/instances/(%s)/failover$" % instance_name_pattern): + rlib2.R_2_instances_name_failover, + re.compile(r"^/2/instances/(%s)/rename$" % instance_name_pattern): + rlib2.R_2_instances_name_rename, + re.compile(r"^/2/instances/(%s)/modify$" % instance_name_pattern): + rlib2.R_2_instances_name_modify, + re.compile(r"^/2/instances/(%s)/disk/(%s)/grow$" % + (instance_name_pattern, disk_pattern)): + rlib2.R_2_instances_name_disk_grow, + re.compile(r"^/2/instances/(%s)/console$" % instance_name_pattern): + rlib2.R_2_instances_name_console, + + "/2/groups": rlib2.R_2_groups, + re.compile(r"^/2/groups/(%s)$" % group_name_pattern): + rlib2.R_2_groups_name, + re.compile(r"^/2/groups/(%s)/modify$" % group_name_pattern): + rlib2.R_2_groups_name_modify, + re.compile(r"^/2/groups/(%s)/rename$" % group_name_pattern): + rlib2.R_2_groups_name_rename, + re.compile(r"^/2/groups/(%s)/assign-nodes$" % group_name_pattern): + rlib2.R_2_groups_name_assign_nodes, + re.compile(r"^/2/groups/(%s)/tags$" % group_name_pattern): + rlib2.R_2_groups_name_tags, "/2/jobs": rlib2.R_2_jobs, - re.compile(r'/2/jobs/(%s)$' % job_id_pattern): + re.compile(r"^/2/jobs/(%s)$" % job_id_pattern): rlib2.R_2_jobs_id, - re.compile(r'/2/jobs/(%s)/wait$' % job_id_pattern): + re.compile(r"^/2/jobs/(%s)/wait$" % job_id_pattern): rlib2.R_2_jobs_id_wait, "/2/tags": rlib2.R_2_tags, @@ -217,8 +190,13 @@ def GetHandlers(node_name_pattern, instance_name_pattern, job_id_pattern): "/2/os": rlib2.R_2_os, "/2/redistribute-config": rlib2.R_2_redist_config, "/2/features": rlib2.R_2_features, + "/2/modify": rlib2.R_2_cluster_modify, + re.compile(r"^/2/query/(%s)$" % query_res_pattern): rlib2.R_2_query, + re.compile(r"^/2/query/(%s)/fields$" % query_res_pattern): + rlib2.R_2_query_fields, } -CONNECTOR.update(GetHandlers(_NAME_PATTERN, _NAME_PATTERN, - constants.JOB_ID_TEMPLATE)) +CONNECTOR.update(GetHandlers(_NAME_PATTERN, _NAME_PATTERN, _NAME_PATTERN, + constants.JOB_ID_TEMPLATE, _DISK_PATTERN, + _NAME_PATTERN))