Statistics
| Branch: | Tag: | Revision:

root / lib / rapi / connector.py @ 82e186f8

History | View | Annotate | Download (5.7 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 10b207d4 Oleksiy Mishchenko
import cgi
26 10b207d4 Oleksiy Mishchenko
import re
27 10b207d4 Oleksiy Mishchenko
28 a2f92677 Michael Hanselmann
from ganeti import constants
29 a2f92677 Michael Hanselmann
from ganeti import http
30 10b207d4 Oleksiy Mishchenko
31 a2f92677 Michael Hanselmann
from ganeti.rapi import baserlib
32 10b207d4 Oleksiy Mishchenko
from ganeti.rapi import rlib2
33 10b207d4 Oleksiy Mishchenko
34 bf968b7f Michael Hanselmann
35 bf968b7f Michael Hanselmann
_NAME_PATTERN = r"[\w\._-]+"
36 bf968b7f Michael Hanselmann
37 a2f92677 Michael Hanselmann
# the connection map is created at the end of this file
38 10b207d4 Oleksiy Mishchenko
CONNECTOR = {}
39 10b207d4 Oleksiy Mishchenko
40 10b207d4 Oleksiy Mishchenko
41 10b207d4 Oleksiy Mishchenko
class Mapper:
42 10b207d4 Oleksiy Mishchenko
  """Map resource to method.
43 10b207d4 Oleksiy Mishchenko

44 10b207d4 Oleksiy Mishchenko
  """
45 10b207d4 Oleksiy Mishchenko
  def __init__(self, connector=CONNECTOR):
46 10b207d4 Oleksiy Mishchenko
    """Resource mapper constructor.
47 10b207d4 Oleksiy Mishchenko

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

50 10b207d4 Oleksiy Mishchenko
    """
51 10b207d4 Oleksiy Mishchenko
    self._connector = connector
52 10b207d4 Oleksiy Mishchenko
53 10b207d4 Oleksiy Mishchenko
  def getController(self, uri):
54 10b207d4 Oleksiy Mishchenko
    """Find method for a given URI.
55 10b207d4 Oleksiy Mishchenko

56 c41eea6e Iustin Pop
    @param uri: string with URI
57 10b207d4 Oleksiy Mishchenko

58 c41eea6e Iustin Pop
    @return: None if no method is found or a tuple containing
59 c41eea6e Iustin Pop
        the following fields:
60 c41eea6e Iustin Pop
            - method: name of method mapped to URI
61 c41eea6e Iustin Pop
            - items: a list of variable intems in the path
62 c41eea6e Iustin Pop
            - args: a dictionary with additional parameters from URL
63 10b207d4 Oleksiy Mishchenko

64 10b207d4 Oleksiy Mishchenko
    """
65 10b207d4 Oleksiy Mishchenko
    if '?' in uri:
66 10b207d4 Oleksiy Mishchenko
      (path, query) = uri.split('?', 1)
67 10b207d4 Oleksiy Mishchenko
      args = cgi.parse_qs(query)
68 10b207d4 Oleksiy Mishchenko
    else:
69 10b207d4 Oleksiy Mishchenko
      path = uri
70 10b207d4 Oleksiy Mishchenko
      query = None
71 10b207d4 Oleksiy Mishchenko
      args = {}
72 10b207d4 Oleksiy Mishchenko
73 10b207d4 Oleksiy Mishchenko
    result = None
74 10b207d4 Oleksiy Mishchenko
75 10b207d4 Oleksiy Mishchenko
    for key, handler in self._connector.iteritems():
76 10b207d4 Oleksiy Mishchenko
      # Regex objects
77 10b207d4 Oleksiy Mishchenko
      if hasattr(key, "match"):
78 10b207d4 Oleksiy Mishchenko
        m = key.match(path)
79 10b207d4 Oleksiy Mishchenko
        if m:
80 10b207d4 Oleksiy Mishchenko
          result = (handler, list(m.groups()), args)
81 10b207d4 Oleksiy Mishchenko
          break
82 10b207d4 Oleksiy Mishchenko
83 10b207d4 Oleksiy Mishchenko
      # String objects
84 10b207d4 Oleksiy Mishchenko
      elif key == path:
85 10b207d4 Oleksiy Mishchenko
        result = (handler, [], args)
86 10b207d4 Oleksiy Mishchenko
        break
87 10b207d4 Oleksiy Mishchenko
88 a0638838 Oleksiy Mishchenko
    if result:
89 10b207d4 Oleksiy Mishchenko
      return result
90 10b207d4 Oleksiy Mishchenko
    else:
91 84f2756e Michael Hanselmann
      raise http.HttpNotFound()
92 10b207d4 Oleksiy Mishchenko
93 10b207d4 Oleksiy Mishchenko
94 10b207d4 Oleksiy Mishchenko
class R_root(baserlib.R_Generic):
95 10b207d4 Oleksiy Mishchenko
  """/ resource.
96 10b207d4 Oleksiy Mishchenko

97 10b207d4 Oleksiy Mishchenko
  """
98 10b207d4 Oleksiy Mishchenko
  def GET(self):
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
    root_pattern = re.compile('^R_([a-zA-Z0-9]+)$')
105 10b207d4 Oleksiy Mishchenko
106 10b207d4 Oleksiy Mishchenko
    rootlist = []
107 10b207d4 Oleksiy Mishchenko
    for handler in CONNECTOR.values():
108 10b207d4 Oleksiy Mishchenko
      m = root_pattern.match(handler.__name__)
109 10b207d4 Oleksiy Mishchenko
      if m:
110 10b207d4 Oleksiy Mishchenko
        name = m.group(1)
111 10b207d4 Oleksiy Mishchenko
        if name != 'root':
112 10b207d4 Oleksiy Mishchenko
          rootlist.append(name)
113 10b207d4 Oleksiy Mishchenko
114 10b207d4 Oleksiy Mishchenko
    return baserlib.BuildUriList(rootlist, "/%s")
115 10b207d4 Oleksiy Mishchenko
116 10b207d4 Oleksiy Mishchenko
117 69b99987 Michael Hanselmann
def _getResources(id_):
118 fc72a3a3 Oleksiy Mishchenko
  """Return a list of resources underneath given id.
119 fc72a3a3 Oleksiy Mishchenko

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

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

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

140 fc72a3a3 Oleksiy Mishchenko
  """
141 fc72a3a3 Oleksiy Mishchenko
  def GET(self):
142 fc72a3a3 Oleksiy Mishchenko
    """Show the list of mapped resources.
143 fc72a3a3 Oleksiy Mishchenko

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

146 fc72a3a3 Oleksiy Mishchenko
    """
147 fc72a3a3 Oleksiy Mishchenko
    return baserlib.BuildUriList(_getResources("2"), "/2/%s")
148 fc72a3a3 Oleksiy Mishchenko
149 fc72a3a3 Oleksiy Mishchenko
150 bf968b7f Michael Hanselmann
def GetHandlers(node_name_pattern, instance_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 bf968b7f Michael Hanselmann
  return {
155 bf968b7f Michael Hanselmann
    "/": R_root,
156 bf968b7f Michael Hanselmann
157 bf968b7f Michael Hanselmann
    "/version": rlib2.R_version,
158 10b207d4 Oleksiy Mishchenko
159 bf968b7f Michael Hanselmann
    "/2": R_2,
160 10b207d4 Oleksiy Mishchenko
161 bf968b7f Michael Hanselmann
    "/2/nodes": rlib2.R_2_nodes,
162 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)$' % node_name_pattern):
163 bf968b7f Michael Hanselmann
      rlib2.R_2_nodes_name,
164 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)/tags$' % node_name_pattern):
165 bf968b7f Michael Hanselmann
      rlib2.R_2_nodes_name_tags,
166 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)/role$' % node_name_pattern):
167 bf968b7f Michael Hanselmann
      rlib2.R_2_nodes_name_role,
168 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)/evacuate$' % node_name_pattern):
169 73452f12 Michael Hanselmann
      rlib2.R_2_nodes_name_evacuate,
170 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)/migrate$' % node_name_pattern):
171 1c482bab Michael Hanselmann
      rlib2.R_2_nodes_name_migrate,
172 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)/storage$' % node_name_pattern):
173 7a95a954 Michael Hanselmann
      rlib2.R_2_nodes_name_storage,
174 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)/storage/modify$' % node_name_pattern):
175 1e82bc80 Michael Hanselmann
      rlib2.R_2_nodes_name_storage_modify,
176 bf968b7f Michael Hanselmann
    re.compile(r'^/2/nodes/(%s)/storage/repair$' % node_name_pattern):
177 723f4565 Michael Hanselmann
      rlib2.R_2_nodes_name_storage_repair,
178 bf968b7f Michael Hanselmann
179 bf968b7f Michael Hanselmann
    "/2/instances": rlib2.R_2_instances,
180 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)$' % instance_name_pattern):
181 bf968b7f Michael Hanselmann
      rlib2.R_2_instances_name,
182 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/info$' % instance_name_pattern):
183 d8260842 Michael Hanselmann
      rlib2.R_2_instances_name_info,
184 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/tags$' % instance_name_pattern):
185 bf968b7f Michael Hanselmann
      rlib2.R_2_instances_name_tags,
186 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/reboot$' % instance_name_pattern):
187 2276aa29 Oleksiy Mishchenko
      rlib2.R_2_instances_name_reboot,
188 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/reinstall$' % instance_name_pattern):
189 e5b7c4ca Iustin Pop
      rlib2.R_2_instances_name_reinstall,
190 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/replace-disks$' % instance_name_pattern):
191 4c98b915 Michael Hanselmann
      rlib2.R_2_instances_name_replace_disks,
192 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/shutdown$' % instance_name_pattern):
193 0c55c24b Oleksiy Mishchenko
      rlib2.R_2_instances_name_shutdown,
194 bf968b7f Michael Hanselmann
    re.compile(r'^/2/instances/(%s)/startup$' % instance_name_pattern):
195 0c55c24b Oleksiy Mishchenko
      rlib2.R_2_instances_name_startup,
196 bf968b7f Michael Hanselmann
197 bf968b7f Michael Hanselmann
    "/2/jobs": rlib2.R_2_jobs,
198 bf968b7f Michael Hanselmann
    re.compile(r'/2/jobs/(%s)$' % job_id_pattern):
199 bf968b7f Michael Hanselmann
      rlib2.R_2_jobs_id,
200 bf968b7f Michael Hanselmann
201 bf968b7f Michael Hanselmann
    "/2/tags": rlib2.R_2_tags,
202 bf968b7f Michael Hanselmann
    "/2/info": rlib2.R_2_info,
203 bf968b7f Michael Hanselmann
    "/2/os": rlib2.R_2_os,
204 508e9b20 Michael Hanselmann
    "/2/redistribute-config": rlib2.R_2_redist_config,
205 bf968b7f Michael Hanselmann
    }
206 bf968b7f Michael Hanselmann
207 bf968b7f Michael Hanselmann
208 bf968b7f Michael Hanselmann
CONNECTOR.update(GetHandlers(_NAME_PATTERN, _NAME_PATTERN,
209 bf968b7f Michael Hanselmann
                             constants.JOB_ID_TEMPLATE))