Statistics
| Branch: | Tag: | Revision:

root / lib / rapi / connector.py @ 5a9c3f46

History | View | Annotate | Download (3.8 kB)

1
#
2
#
3

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

    
21
"""Remote API connection map.
22

23
"""
24

    
25
import cgi
26
import re
27

    
28
from ganeti import constants
29
from ganeti import http
30

    
31
from ganeti.rapi import baserlib
32
from ganeti.rapi import rlib1
33
from ganeti.rapi import rlib2
34

    
35
# the connection map is created at the end of this file
36
CONNECTOR = {}
37

    
38

    
39
class Mapper:
40
  """Map resource to method.
41

42
  """
43
  def __init__(self, connector=CONNECTOR):
44
    """Resource mapper constructor.
45

46
    @param connector: a dictionary, mapping method name with URL path regexp
47

48
    """
49
    self._connector = connector
50

    
51
  def getController(self, uri):
52
    """Find method for a given URI.
53

54
    @param uri: string with URI
55

56
    @return: None if no method is found or a tuple containing
57
        the following fields:
58
            - method: name of method mapped to URI
59
            - items: a list of variable intems in the path
60
            - args: a dictionary with additional parameters from URL
61

62
    """
63
    if '?' in uri:
64
      (path, query) = uri.split('?', 1)
65
      args = cgi.parse_qs(query)
66
    else:
67
      path = uri
68
      query = None
69
      args = {}
70

    
71
    result = None
72

    
73
    for key, handler in self._connector.iteritems():
74
      # Regex objects
75
      if hasattr(key, "match"):
76
        m = key.match(path)
77
        if m:
78
          result = (handler, list(m.groups()), args)
79
          break
80

    
81
      # String objects
82
      elif key == path:
83
        result = (handler, [], args)
84
        break
85

    
86
    if result:
87
      return result
88
    else:
89
      raise http.HttpNotFound()
90

    
91

    
92
class R_root(baserlib.R_Generic):
93
  """/ resource.
94

95
  """
96
  DOC_URI = "/"
97

    
98
  def GET(self):
99
    """Show the list of mapped resources.
100

101
    @return: a dictionary with 'name' and 'uri' keys for each of them.
102

103
    """
104
    root_pattern = re.compile('^R_([a-zA-Z0-9]+)$')
105

    
106
    rootlist = []
107
    for handler in CONNECTOR.values():
108
      m = root_pattern.match(handler.__name__)
109
      if m:
110
        name = m.group(1)
111
        if name != 'root':
112
          rootlist.append(name)
113

    
114
    return baserlib.BuildUriList(rootlist, "/%s")
115

    
116

    
117
CONNECTOR.update({
118
  "/": R_root,
119

    
120
  "/version": rlib1.R_version,
121

    
122
  "/tags": rlib1.R_tags,
123
  "/info": rlib1.R_info,
124

    
125
  "/nodes": rlib2.R_nodes,
126
  re.compile(r'^/nodes/([\w\._-]+)$'): rlib1.R_nodes_name,
127
  re.compile(r'^/nodes/([\w\._-]+)/tags$'): rlib1.R_nodes_name_tags,
128

    
129
  "/instances": rlib2.R_instances,
130
  re.compile(r'^/instances/([\w\._-]+)$'): rlib1.R_instances_name,
131
  re.compile(r'^/instances/([\w\._-]+)/tags$'): rlib1.R_instances_name_tags,
132

    
133
  "/os": rlib1.R_os,
134

    
135
  "/2/jobs": rlib2.R_2_jobs,
136
  "/2/nodes": rlib2.R_2_nodes,
137
  "/2/instances": rlib2.R_2_instances,
138
  re.compile(r'^/2/instances/([\w\._-]+)$'): rlib1.R_instances_name,
139
  re.compile(r'^/2/instances/([\w\._-]+)/tags$'): rlib2.R_2_instances_name_tags,
140
  re.compile(r'^/2/instances/([\w\._-]+)/reboot$'):
141
      rlib2.R_2_instances_name_reboot,
142
  re.compile(r'^/2/instances/([\w\._-]+)/shutdown$'):
143
      rlib2.R_2_instances_name_shutdown,
144
  re.compile(r'^/2/instances/([\w\._-]+)/startup$'):
145
      rlib2.R_2_instances_name_startup,
146
  re.compile(r'/2/jobs/(%s)$' % constants.JOB_ID_TEMPLATE): rlib2.R_2_jobs_id,
147
  })