backend: Two small style fixes
[ganeti-local] / lib / rapi / connector.py
index ecf82c7..3ef842b 100644 (file)
 
 """
 
+# pylint: disable-msg=C0103
+
+# C0103: Invalid name, since the R_* names are not conforming
+
 import cgi
 import re
 
@@ -29,9 +33,11 @@ from ganeti import constants
 from ganeti import http
 
 from ganeti.rapi import baserlib
-from ganeti.rapi import rlib1
 from ganeti.rapi import rlib2
 
+
+_NAME_PATTERN = r"[\w\._-]+"
+
 # the connection map is created at the end of this file
 CONNECTOR = {}
 
@@ -40,26 +46,26 @@ class Mapper:
   """Map resource to method.
 
   """
-  def __init__(self, connector=CONNECTOR):
+  def __init__(self, connector=None):
     """Resource mapper constructor.
 
-    Args:
-      con: a dictionary, mapping method name with URL path regexp
+    @param connector: a dictionary, mapping method name with URL path regexp
 
     """
+    if connector is None:
+      connector = CONNECTOR
     self._connector = connector
 
   def getController(self, uri):
     """Find method for a given URI.
 
-    Args:
-      uri: string with URI
+    @param uri: string with URI
 
-    Returns:
-      None if no method is found or a tuple containing the following fields:
-        methd: name of method mapped to URI
-        items: a list of variable intems in the path
-        args: a dictionary with additional parameters from URL
+    @return: None if no method is found or a tuple containing
+        the following fields:
+            - method: name of method mapped to URI
+            - items: a list of variable intems in the path
+            - args: a dictionary with additional parameters from URL
 
     """
     if '?' in uri:
@@ -88,20 +94,18 @@ class Mapper:
     if result:
       return result
     else:
-      raise http.HTTPNotFound()
+      raise http.HttpNotFound()
 
 
 class R_root(baserlib.R_Generic):
   """/ resource.
 
   """
-  DOC_URI = "/"
-
-  def GET(self):
+  @staticmethod
+  def GET():
     """Show the list of mapped resources.
 
-    Returns:
-      A dictionary with 'name' and 'uri' keys for each of them.
+    @return: a dictionary with 'name' and 'uri' keys for each of them.
 
     """
     root_pattern = re.compile('^R_([a-zA-Z0-9]+)$')
@@ -117,34 +121,97 @@ class R_root(baserlib.R_Generic):
     return baserlib.BuildUriList(rootlist, "/%s")
 
 
-CONNECTOR.update({
-  "/": R_root,
+def _getResources(id_):
+  """Return a list of resources underneath given id.
 
-  "/version": rlib1.R_version,
+  This is to generalize querying of version resources lists.
 
-  "/tags": rlib1.R_tags,
-  "/info": rlib1.R_info,
+  @return: a list of resources names.
 
-  "/nodes": rlib1.R_nodes,
-  re.compile(r'^/nodes/([\w\._-]+)$'): rlib1.R_nodes_name,
-  re.compile(r'^/nodes/([\w\._-]+)/tags$'): rlib1.R_nodes_name_tags,
+  """
+  r_pattern = re.compile('^R_%s_([a-zA-Z0-9]+)$' % id_)
 
-  "/instances": rlib1.R_instances,
-  re.compile(r'^/instances/([\w\._-]+)$'): rlib1.R_instances_name,
-  re.compile(r'^/instances/([\w\._-]+)/tags$'): rlib1.R_instances_name_tags,
+  rlist = []
+  for handler in CONNECTOR.values():
+    m = r_pattern.match(handler.__name__)
+    if m:
+      name = m.group(1)
+      rlist.append(name)
 
-  "/os": rlib1.R_os,
+  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.
 
-  "/2/jobs": rlib2.R_2_jobs,
-  "/2/nodes": rlib2.R_2_nodes,
-  "/2/instances": rlib2.R_2_instances,
-  re.compile(r'^/2/instances/([\w\._-]+)$'): rlib1.R_instances_name,
-  re.compile(r'^/2/instances/([\w\._-]+)/tags$'): rlib2.R_2_instances_name_tags,
-  re.compile(r'^/2/instances/([\w\._-]+)/reboot$'):
+    @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):
+  """Returns all supported resources and their handlers.
+
+  """
+  return {
+    "/": R_root,
+
+    "/version": rlib2.R_version,
+
+    "/2": R_2,
+
+    "/2/nodes": rlib2.R_2_nodes,
+    re.compile(r'^/2/nodes/(%s)$' % node_name_pattern):
+      rlib2.R_2_nodes_name,
+    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):
+      rlib2.R_2_nodes_name_role,
+    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):
+      rlib2.R_2_nodes_name_migrate,
+    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):
+      rlib2.R_2_nodes_name_storage_modify,
+    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):
+      rlib2.R_2_instances_name,
+    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):
+      rlib2.R_2_instances_name_tags,
+    re.compile(r'^/2/instances/(%s)/reboot$' % instance_name_pattern):
       rlib2.R_2_instances_name_reboot,
-  re.compile(r'^/2/instances/([\w\._-]+)/shutdown$'):
+    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):
+      rlib2.R_2_instances_name_replace_disks,
+    re.compile(r'^/2/instances/(%s)/shutdown$' % instance_name_pattern):
       rlib2.R_2_instances_name_shutdown,
-  re.compile(r'^/2/instances/([\w\._-]+)/startup$'):
+    re.compile(r'^/2/instances/(%s)/startup$' % instance_name_pattern):
       rlib2.R_2_instances_name_startup,
-  re.compile(r'/2/jobs/(%s)$' % constants.JOB_ID_TEMPLATE): rlib2.R_2_jobs_id,
-  })
+
+    "/2/jobs": rlib2.R_2_jobs,
+    re.compile(r'/2/jobs/(%s)$' % job_id_pattern):
+      rlib2.R_2_jobs_id,
+
+    "/2/tags": rlib2.R_2_tags,
+    "/2/info": rlib2.R_2_info,
+    "/2/os": rlib2.R_2_os,
+    "/2/redistribute-config": rlib2.R_2_redist_config,
+    }
+
+
+CONNECTOR.update(GetHandlers(_NAME_PATTERN, _NAME_PATTERN,
+                             constants.JOB_ID_TEMPLATE))