Statistics
| Branch: | Tag: | Revision:

root / lib / rapi / connector.py @ 84f2756e

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
    Args:
47
      con: a dictionary, mapping method name with URL path regexp
48

49
    """
50
    self._connector = connector
51

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

55
    Args:
56
      uri: string with URI
57

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

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

    
73
    result = None
74

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

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

    
88
    if result:
89
      return result
90
    else:
91
      raise http.HttpNotFound()
92

    
93

    
94
class R_root(baserlib.R_Generic):
95
  """/ resource.
96

97
  """
98
  DOC_URI = "/"
99

    
100
  def GET(self):
101
    """Show the list of mapped resources.
102

103
    Returns:
104
      A dictionary with 'name' and 'uri' keys for each of them.
105

106
    """
107
    root_pattern = re.compile('^R_([a-zA-Z0-9]+)$')
108

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

    
117
    return baserlib.BuildUriList(rootlist, "/%s")
118

    
119

    
120
CONNECTOR.update({
121
  "/": R_root,
122

    
123
  "/version": rlib1.R_version,
124

    
125
  "/tags": rlib1.R_tags,
126
  "/info": rlib1.R_info,
127

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

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

    
136
  "/os": rlib1.R_os,
137

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