Statistics
| Branch: | Tag: | Revision:

root / lib / rapi / connector.py @ 0dbaa9ca

History | View | Annotate | Download (7.1 kB)

1 10b207d4 Oleksiy Mishchenko
#
2 10b207d4 Oleksiy Mishchenko
#
3 10b207d4 Oleksiy Mishchenko
4 10b207d4 Oleksiy Mishchenko
# Copyright (C) 2006, 2007, 2008 Google Inc.
5 10b207d4 Oleksiy Mishchenko
#
6 10b207d4 Oleksiy Mishchenko
# This program is free software; you can redistribute it and/or modify
7 10b207d4 Oleksiy Mishchenko
# it under the terms of the GNU General Public License as published by
8 10b207d4 Oleksiy Mishchenko
# the Free Software Foundation; either version 2 of the License, or
9 10b207d4 Oleksiy Mishchenko
# (at your option) any later version.
10 10b207d4 Oleksiy Mishchenko
#
11 10b207d4 Oleksiy Mishchenko
# This program is distributed in the hope that it will be useful, but
12 10b207d4 Oleksiy Mishchenko
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 10b207d4 Oleksiy Mishchenko
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 10b207d4 Oleksiy Mishchenko
# General Public License for more details.
15 10b207d4 Oleksiy Mishchenko
#
16 10b207d4 Oleksiy Mishchenko
# You should have received a copy of the GNU General Public License
17 10b207d4 Oleksiy Mishchenko
# along with this program; if not, write to the Free Software
18 10b207d4 Oleksiy Mishchenko
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 10b207d4 Oleksiy Mishchenko
# 02110-1301, USA.
20 10b207d4 Oleksiy Mishchenko
21 10b207d4 Oleksiy Mishchenko
"""Remote API connection map.
22 10b207d4 Oleksiy Mishchenko

23 10b207d4 Oleksiy Mishchenko
"""
24 10b207d4 Oleksiy Mishchenko
25 fe267188 Iustin Pop
# pylint: disable-msg=C0103
26 fe267188 Iustin Pop
27 fe267188 Iustin Pop
# C0103: Invalid name, since the R_* names are not conforming
28 fe267188 Iustin Pop
29 10b207d4 Oleksiy Mishchenko
import cgi
30 10b207d4 Oleksiy Mishchenko
import re
31 10b207d4 Oleksiy Mishchenko
32 a2f92677 Michael Hanselmann
from ganeti import constants
33 a2f92677 Michael Hanselmann
from ganeti import http
34 691c81b7 Michael Hanselmann
from ganeti import utils
35 10b207d4 Oleksiy Mishchenko
36 a2f92677 Michael Hanselmann
from ganeti.rapi import baserlib
37 10b207d4 Oleksiy Mishchenko
from ganeti.rapi import rlib2
38 10b207d4 Oleksiy Mishchenko
39 bf968b7f Michael Hanselmann
40 bf968b7f Michael Hanselmann
_NAME_PATTERN = r"[\w\._-]+"
41 bf968b7f Michael Hanselmann
42 a2f92677 Michael Hanselmann
# the connection map is created at the end of this file
43 10b207d4 Oleksiy Mishchenko
CONNECTOR = {}
44 10b207d4 Oleksiy Mishchenko
45 10b207d4 Oleksiy Mishchenko
46 10b207d4 Oleksiy Mishchenko
class Mapper:
47 10b207d4 Oleksiy Mishchenko
  """Map resource to method.
48 10b207d4 Oleksiy Mishchenko

49 10b207d4 Oleksiy Mishchenko
  """
50 e11ddf13 Iustin Pop
  def __init__(self, connector=None):
51 10b207d4 Oleksiy Mishchenko
    """Resource mapper constructor.
52 10b207d4 Oleksiy Mishchenko

53 c41eea6e Iustin Pop
    @param connector: a dictionary, mapping method name with URL path regexp
54 10b207d4 Oleksiy Mishchenko

55 10b207d4 Oleksiy Mishchenko
    """
56 e11ddf13 Iustin Pop
    if connector is None:
57 e11ddf13 Iustin Pop
      connector = CONNECTOR
58 10b207d4 Oleksiy Mishchenko
    self._connector = connector
59 10b207d4 Oleksiy Mishchenko
60 10b207d4 Oleksiy Mishchenko
  def getController(self, uri):
61 10b207d4 Oleksiy Mishchenko
    """Find method for a given URI.
62 10b207d4 Oleksiy Mishchenko

63 c41eea6e Iustin Pop
    @param uri: string with URI
64 10b207d4 Oleksiy Mishchenko

65 c41eea6e Iustin Pop
    @return: None if no method is found or a tuple containing
66 c41eea6e Iustin Pop
        the following fields:
67 c41eea6e Iustin Pop
            - method: name of method mapped to URI
68 c41eea6e Iustin Pop
            - items: a list of variable intems in the path
69 c41eea6e Iustin Pop
            - args: a dictionary with additional parameters from URL
70 10b207d4 Oleksiy Mishchenko

71 10b207d4 Oleksiy Mishchenko
    """
72 10b207d4 Oleksiy Mishchenko
    if '?' in uri:
73 10b207d4 Oleksiy Mishchenko
      (path, query) = uri.split('?', 1)
74 10b207d4 Oleksiy Mishchenko
      args = cgi.parse_qs(query)
75 10b207d4 Oleksiy Mishchenko
    else:
76 10b207d4 Oleksiy Mishchenko
      path = uri
77 10b207d4 Oleksiy Mishchenko
      query = None
78 10b207d4 Oleksiy Mishchenko
      args = {}
79 10b207d4 Oleksiy Mishchenko
80 691c81b7 Michael Hanselmann
    # Try to find handler for request path
81 691c81b7 Michael Hanselmann
    result = utils.FindMatch(self._connector, path)
82 10b207d4 Oleksiy Mishchenko
83 691c81b7 Michael Hanselmann
    if result is None:
84 691c81b7 Michael Hanselmann
      raise http.HttpNotFound()
85 10b207d4 Oleksiy Mishchenko
86 691c81b7 Michael Hanselmann
    (handler, groups) = result
87 10b207d4 Oleksiy Mishchenko
88 691c81b7 Michael Hanselmann
    return (handler, groups, args)
89 10b207d4 Oleksiy Mishchenko
90 10b207d4 Oleksiy Mishchenko
91 10b207d4 Oleksiy Mishchenko
class R_root(baserlib.R_Generic):
92 10b207d4 Oleksiy Mishchenko
  """/ resource.
93 10b207d4 Oleksiy Mishchenko

94 10b207d4 Oleksiy Mishchenko
  """
95 0b5303da Iustin Pop
  _ROOT_PATTERN = re.compile("^R_([a-zA-Z0-9]+)$")
96 0b5303da Iustin Pop
97 0b5303da Iustin Pop
  @classmethod
98 0b5303da Iustin Pop
  def GET(cls):
99 10b207d4 Oleksiy Mishchenko
    """Show the list of mapped resources.
100 a2f92677 Michael Hanselmann

101 c41eea6e Iustin Pop
    @return: a dictionary with 'name' and 'uri' keys for each of them.
102 10b207d4 Oleksiy Mishchenko

103 10b207d4 Oleksiy Mishchenko
    """
104 10b207d4 Oleksiy Mishchenko
    rootlist = []
105 10b207d4 Oleksiy Mishchenko
    for handler in CONNECTOR.values():
106 0b5303da Iustin Pop
      m = cls._ROOT_PATTERN.match(handler.__name__)
107 10b207d4 Oleksiy Mishchenko
      if m:
108 10b207d4 Oleksiy Mishchenko
        name = m.group(1)
109 10b207d4 Oleksiy Mishchenko
        if name != 'root':
110 10b207d4 Oleksiy Mishchenko
          rootlist.append(name)
111 10b207d4 Oleksiy Mishchenko
112 10b207d4 Oleksiy Mishchenko
    return baserlib.BuildUriList(rootlist, "/%s")
113 10b207d4 Oleksiy Mishchenko
114 10b207d4 Oleksiy Mishchenko
115 69b99987 Michael Hanselmann
def _getResources(id_):
116 fc72a3a3 Oleksiy Mishchenko
  """Return a list of resources underneath given id.
117 fc72a3a3 Oleksiy Mishchenko

118 fc72a3a3 Oleksiy Mishchenko
  This is to generalize querying of version resources lists.
119 fc72a3a3 Oleksiy Mishchenko

120 fc72a3a3 Oleksiy Mishchenko
  @return: a list of resources names.
121 fc72a3a3 Oleksiy Mishchenko

122 fc72a3a3 Oleksiy Mishchenko
  """
123 69b99987 Michael Hanselmann
  r_pattern = re.compile('^R_%s_([a-zA-Z0-9]+)$' % id_)
124 fc72a3a3 Oleksiy Mishchenko
125 fc72a3a3 Oleksiy Mishchenko
  rlist = []
126 fc72a3a3 Oleksiy Mishchenko
  for handler in CONNECTOR.values():
127 fc72a3a3 Oleksiy Mishchenko
    m = r_pattern.match(handler.__name__)
128 fc72a3a3 Oleksiy Mishchenko
    if m:
129 fc72a3a3 Oleksiy Mishchenko
      name = m.group(1)
130 fc72a3a3 Oleksiy Mishchenko
      rlist.append(name)
131 fc72a3a3 Oleksiy Mishchenko
132 fc72a3a3 Oleksiy Mishchenko
  return rlist
133 fc72a3a3 Oleksiy Mishchenko
134 fc72a3a3 Oleksiy Mishchenko
135 fc72a3a3 Oleksiy Mishchenko
class R_2(baserlib.R_Generic):
136 bf4a90af Iustin Pop
  """ /2 resource, the root of the version 2 API.
137 fc72a3a3 Oleksiy Mishchenko

138 fc72a3a3 Oleksiy Mishchenko
  """
139 7e950d31 Iustin Pop
  @staticmethod
140 7e950d31 Iustin Pop
  def GET():
141 fc72a3a3 Oleksiy Mishchenko
    """Show the list of mapped resources.
142 fc72a3a3 Oleksiy Mishchenko

143 fc72a3a3 Oleksiy Mishchenko
    @return: a dictionary with 'name' and 'uri' keys for each of them.
144 fc72a3a3 Oleksiy Mishchenko

145 fc72a3a3 Oleksiy Mishchenko
    """
146 fc72a3a3 Oleksiy Mishchenko
    return baserlib.BuildUriList(_getResources("2"), "/2/%s")
147 fc72a3a3 Oleksiy Mishchenko
148 fc72a3a3 Oleksiy Mishchenko
149 0897dc97 Adeodato Simo
def GetHandlers(node_name_pattern, instance_name_pattern,
150 0897dc97 Adeodato Simo
                group_name_pattern, job_id_pattern):
151 bf968b7f Michael Hanselmann
  """Returns all supported resources and their handlers.
152 bf968b7f Michael Hanselmann

153 bf968b7f Michael Hanselmann
  """
154 2c0be3d0 Michael Hanselmann
  # Important note: New resources should always be added under /2. During a
155 2c0be3d0 Michael Hanselmann
  # discussion in July 2010 it was decided that having per-resource versions
156 2c0be3d0 Michael Hanselmann
  # is more flexible and future-compatible than versioning the whole remote
157 2c0be3d0 Michael Hanselmann
  # API.
158 bf968b7f Michael Hanselmann
  return {
159 bf968b7f Michael Hanselmann
    "/": R_root,
160 bf968b7f Michael Hanselmann
161 bf968b7f Michael Hanselmann
    "/version": rlib2.R_version,
162 10b207d4 Oleksiy Mishchenko
163 bf968b7f Michael Hanselmann
    "/2": R_2,
164 10b207d4 Oleksiy Mishchenko
165 bf968b7f Michael Hanselmann
    "/2/nodes": rlib2.R_2_nodes,
166 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)$' % node_name_pattern):
167 bf968b7f Michael Hanselmann
      rlib2.R_2_nodes_name,
168 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)/tags$' % node_name_pattern):
169 bf968b7f Michael Hanselmann
      rlib2.R_2_nodes_name_tags,
170 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)/role$' % node_name_pattern):
171 bf968b7f Michael Hanselmann
      rlib2.R_2_nodes_name_role,
172 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)/evacuate$' % node_name_pattern):
173 73452f12 Michael Hanselmann
      rlib2.R_2_nodes_name_evacuate,
174 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)/migrate$' % node_name_pattern):
175 1c482bab Michael Hanselmann
      rlib2.R_2_nodes_name_migrate,
176 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)/storage$' % node_name_pattern):
177 7a95a954 Michael Hanselmann
      rlib2.R_2_nodes_name_storage,
178 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)/storage/modify$' % node_name_pattern):
179 1e82bc80 Michael Hanselmann
      rlib2.R_2_nodes_name_storage_modify,
180 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)/storage/repair$' % node_name_pattern):
181 723f4565 Michael Hanselmann
      rlib2.R_2_nodes_name_storage_repair,
182 bf968b7f Michael Hanselmann
183 bf968b7f Michael Hanselmann
    "/2/instances": rlib2.R_2_instances,
184 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)$' % instance_name_pattern):
185 bf968b7f Michael Hanselmann
      rlib2.R_2_instances_name,
186 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/info$' % instance_name_pattern):
187 d8260842 Michael Hanselmann
      rlib2.R_2_instances_name_info,
188 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/tags$' % instance_name_pattern):
189 bf968b7f Michael Hanselmann
      rlib2.R_2_instances_name_tags,
190 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/reboot$' % instance_name_pattern):
191 2276aa29 Oleksiy Mishchenko
      rlib2.R_2_instances_name_reboot,
192 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/reinstall$' % instance_name_pattern):
193 e5b7c4ca Iustin Pop
      rlib2.R_2_instances_name_reinstall,
194 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/replace-disks$' % instance_name_pattern):
195 4c98b915 Michael Hanselmann
      rlib2.R_2_instances_name_replace_disks,
196 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/shutdown$' % instance_name_pattern):
197 0c55c24b Oleksiy Mishchenko
      rlib2.R_2_instances_name_shutdown,
198 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/startup$' % instance_name_pattern):
199 0c55c24b Oleksiy Mishchenko
      rlib2.R_2_instances_name_startup,
200 2197b66f René Nussbaumer
    re.compile(r'^/2/instances/(%s)/activate-disks$' % instance_name_pattern):
201 2197b66f René Nussbaumer
      rlib2.R_2_instances_name_activate_disks,
202 0a37de5f René Nussbaumer
    re.compile(r'^/2/instances/(%s)/deactivate-disks$' % instance_name_pattern):
203 0a37de5f René Nussbaumer
      rlib2.R_2_instances_name_deactivate_disks,
204 ebeb600f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/prepare-export$' % instance_name_pattern):
205 ebeb600f Michael Hanselmann
      rlib2.R_2_instances_name_prepare_export,
206 ebeb600f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/export$' % instance_name_pattern):
207 ebeb600f Michael Hanselmann
      rlib2.R_2_instances_name_export,
208 5823e0d2 Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/migrate$' % instance_name_pattern):
209 5823e0d2 Michael Hanselmann
      rlib2.R_2_instances_name_migrate,
210 d56e7dc7 Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/rename$' % instance_name_pattern):
211 d56e7dc7 Michael Hanselmann
      rlib2.R_2_instances_name_rename,
212 3882937a Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/modify$' % instance_name_pattern):
213 3882937a Michael Hanselmann
      rlib2.R_2_instances_name_modify,
214 bf968b7f Michael Hanselmann
215 0897dc97 Adeodato Simo
    "/2/groups": rlib2.R_2_groups,
216 0897dc97 Adeodato Simo
    re.compile(r'^/2/groups/(%s)$' % group_name_pattern):
217 0897dc97 Adeodato Simo
      rlib2.R_2_groups_name,
218 0dbaa9ca Adeodato Simo
    re.compile(r'^/2/groups/(%s)/rename$' % group_name_pattern):
219 0dbaa9ca Adeodato Simo
      rlib2.R_2_groups_name_rename,
220 0897dc97 Adeodato Simo
221 bf968b7f Michael Hanselmann
    "/2/jobs": rlib2.R_2_jobs,
222 2c0be3d0 Michael Hanselmann
    re.compile(r"^/2/jobs/(%s)$" % job_id_pattern):
223 bf968b7f Michael Hanselmann
      rlib2.R_2_jobs_id,
224 2c0be3d0 Michael Hanselmann
    re.compile(r"^/2/jobs/(%s)/wait$" % job_id_pattern):
225 793a8f7c Michael Hanselmann
      rlib2.R_2_jobs_id_wait,
226 bf968b7f Michael Hanselmann
227 bf968b7f Michael Hanselmann
    "/2/tags": rlib2.R_2_tags,
228 bf968b7f Michael Hanselmann
    "/2/info": rlib2.R_2_info,
229 bf968b7f Michael Hanselmann
    "/2/os": rlib2.R_2_os,
230 508e9b20 Michael Hanselmann
    "/2/redistribute-config": rlib2.R_2_redist_config,
231 7eac4a4d Michael Hanselmann
    "/2/features": rlib2.R_2_features,
232 bf968b7f Michael Hanselmann
    }
233 bf968b7f Michael Hanselmann
234 bf968b7f Michael Hanselmann
235 0897dc97 Adeodato Simo
CONNECTOR.update(GetHandlers(_NAME_PATTERN, _NAME_PATTERN, _NAME_PATTERN,
236 bf968b7f Michael Hanselmann
                             constants.JOB_ID_TEMPLATE))