Statistics
| Branch: | Tag: | Revision:

root / lib / rapi / connector.py @ 69ab2e12

History | View | Annotate | Download (8.2 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 b459a848 Andrea Spadaccini
# pylint: disable=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 e23881ed Michael Hanselmann
_DISK_PATTERN = r"\d+"
42 bf968b7f Michael Hanselmann
43 a2f92677 Michael Hanselmann
# the connection map is created at the end of this file
44 10b207d4 Oleksiy Mishchenko
CONNECTOR = {}
45 10b207d4 Oleksiy Mishchenko
46 10b207d4 Oleksiy Mishchenko
47 10b207d4 Oleksiy Mishchenko
class Mapper:
48 10b207d4 Oleksiy Mishchenko
  """Map resource to method.
49 10b207d4 Oleksiy Mishchenko

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

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

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

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

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

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

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

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

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

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

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

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

139 b58a4d16 Michael Hanselmann
  This is the root of the version 2 API.
140 fc72a3a3 Oleksiy Mishchenko

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

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

148 fc72a3a3 Oleksiy Mishchenko
    """
149 fc72a3a3 Oleksiy Mishchenko
    return baserlib.BuildUriList(_getResources("2"), "/2/%s")
150 fc72a3a3 Oleksiy Mishchenko
151 fc72a3a3 Oleksiy Mishchenko
152 0897dc97 Adeodato Simo
def GetHandlers(node_name_pattern, instance_name_pattern,
153 1c7fd467 Michael Hanselmann
                group_name_pattern, job_id_pattern, disk_pattern,
154 1c7fd467 Michael Hanselmann
                query_res_pattern):
155 bf968b7f Michael Hanselmann
  """Returns all supported resources and their handlers.
156 bf968b7f Michael Hanselmann

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