1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 """Remote API connection map.
22
23 """
24
25
26
27
28
29 import cgi
30 import re
31
32 from ganeti import constants
33 from ganeti import http
34 from ganeti import utils
35
36 from ganeti.rapi import rlib2
37
38
39 _NAME_PATTERN = r"[\w\._-]+"
40 _DISK_PATTERN = r"\d+"
41
42
43 CONNECTOR = {}
44
45
47 """Map resource to method.
48
49 """
51 """Resource mapper constructor.
52
53 @param connector: a dictionary, mapping method name with URL path regexp
54
55 """
56 if connector is None:
57 connector = CONNECTOR
58 self._connector = connector
59
61 """Find method for a given URI.
62
63 @param uri: string with URI
64
65 @return: None if no method is found or a tuple containing
66 the following fields:
67 - method: name of method mapped to URI
68 - items: a list of variable intems in the path
69 - args: a dictionary with additional parameters from URL
70
71 """
72 if "?" in uri:
73 (path, query) = uri.split("?", 1)
74 args = cgi.parse_qs(query)
75 else:
76 path = uri
77 query = None
78 args = {}
79
80
81 result = utils.FindMatch(self._connector, path)
82
83 if result is None:
84 raise http.HttpNotFound()
85
86 (handler, groups) = result
87
88 return (handler, groups, args)
89
90
91 -def GetHandlers(node_name_pattern, instance_name_pattern,
92 group_name_pattern, job_id_pattern, disk_pattern,
93 query_res_pattern):
94 """Returns all supported resources and their handlers.
95
96 """
97
98
99
100
101 return {
102 "/": rlib2.R_root,
103 "/2": rlib2.R_2,
104
105 "/version": rlib2.R_version,
106
107 "/2/nodes": rlib2.R_2_nodes,
108 re.compile(r"^/2/nodes/(%s)$" % node_name_pattern):
109 rlib2.R_2_nodes_name,
110 re.compile(r"^/2/nodes/(%s)/powercycle$" % node_name_pattern):
111 rlib2.R_2_nodes_name_powercycle,
112 re.compile(r"^/2/nodes/(%s)/tags$" % node_name_pattern):
113 rlib2.R_2_nodes_name_tags,
114 re.compile(r"^/2/nodes/(%s)/role$" % node_name_pattern):
115 rlib2.R_2_nodes_name_role,
116 re.compile(r"^/2/nodes/(%s)/evacuate$" % node_name_pattern):
117 rlib2.R_2_nodes_name_evacuate,
118 re.compile(r"^/2/nodes/(%s)/migrate$" % node_name_pattern):
119 rlib2.R_2_nodes_name_migrate,
120 re.compile(r"^/2/nodes/(%s)/modify$" % node_name_pattern):
121 rlib2.R_2_nodes_name_modify,
122 re.compile(r"^/2/nodes/(%s)/storage$" % node_name_pattern):
123 rlib2.R_2_nodes_name_storage,
124 re.compile(r"^/2/nodes/(%s)/storage/modify$" % node_name_pattern):
125 rlib2.R_2_nodes_name_storage_modify,
126 re.compile(r"^/2/nodes/(%s)/storage/repair$" % node_name_pattern):
127 rlib2.R_2_nodes_name_storage_repair,
128
129 "/2/instances": rlib2.R_2_instances,
130 re.compile(r"^/2/instances/(%s)$" % instance_name_pattern):
131 rlib2.R_2_instances_name,
132 re.compile(r"^/2/instances/(%s)/info$" % instance_name_pattern):
133 rlib2.R_2_instances_name_info,
134 re.compile(r"^/2/instances/(%s)/tags$" % instance_name_pattern):
135 rlib2.R_2_instances_name_tags,
136 re.compile(r"^/2/instances/(%s)/reboot$" % instance_name_pattern):
137 rlib2.R_2_instances_name_reboot,
138 re.compile(r"^/2/instances/(%s)/reinstall$" % instance_name_pattern):
139 rlib2.R_2_instances_name_reinstall,
140 re.compile(r"^/2/instances/(%s)/replace-disks$" % instance_name_pattern):
141 rlib2.R_2_instances_name_replace_disks,
142 re.compile(r"^/2/instances/(%s)/shutdown$" % instance_name_pattern):
143 rlib2.R_2_instances_name_shutdown,
144 re.compile(r"^/2/instances/(%s)/startup$" % instance_name_pattern):
145 rlib2.R_2_instances_name_startup,
146 re.compile(r"^/2/instances/(%s)/activate-disks$" % instance_name_pattern):
147 rlib2.R_2_instances_name_activate_disks,
148 re.compile(r"^/2/instances/(%s)/deactivate-disks$" % instance_name_pattern):
149 rlib2.R_2_instances_name_deactivate_disks,
150 re.compile(r"^/2/instances/(%s)/recreate-disks$" % instance_name_pattern):
151 rlib2.R_2_instances_name_recreate_disks,
152 re.compile(r"^/2/instances/(%s)/prepare-export$" % instance_name_pattern):
153 rlib2.R_2_instances_name_prepare_export,
154 re.compile(r"^/2/instances/(%s)/export$" % instance_name_pattern):
155 rlib2.R_2_instances_name_export,
156 re.compile(r"^/2/instances/(%s)/migrate$" % instance_name_pattern):
157 rlib2.R_2_instances_name_migrate,
158 re.compile(r"^/2/instances/(%s)/failover$" % instance_name_pattern):
159 rlib2.R_2_instances_name_failover,
160 re.compile(r"^/2/instances/(%s)/rename$" % instance_name_pattern):
161 rlib2.R_2_instances_name_rename,
162 re.compile(r"^/2/instances/(%s)/modify$" % instance_name_pattern):
163 rlib2.R_2_instances_name_modify,
164 re.compile(r"^/2/instances/(%s)/disk/(%s)/grow$" %
165 (instance_name_pattern, disk_pattern)):
166 rlib2.R_2_instances_name_disk_grow,
167 re.compile(r"^/2/instances/(%s)/console$" % instance_name_pattern):
168 rlib2.R_2_instances_name_console,
169
170 "/2/groups": rlib2.R_2_groups,
171 re.compile(r"^/2/groups/(%s)$" % group_name_pattern):
172 rlib2.R_2_groups_name,
173 re.compile(r"^/2/groups/(%s)/modify$" % group_name_pattern):
174 rlib2.R_2_groups_name_modify,
175 re.compile(r"^/2/groups/(%s)/rename$" % group_name_pattern):
176 rlib2.R_2_groups_name_rename,
177 re.compile(r"^/2/groups/(%s)/assign-nodes$" % group_name_pattern):
178 rlib2.R_2_groups_name_assign_nodes,
179 re.compile(r"^/2/groups/(%s)/tags$" % group_name_pattern):
180 rlib2.R_2_groups_name_tags,
181
182 "/2/jobs": rlib2.R_2_jobs,
183 re.compile(r"^/2/jobs/(%s)$" % job_id_pattern):
184 rlib2.R_2_jobs_id,
185 re.compile(r"^/2/jobs/(%s)/wait$" % job_id_pattern):
186 rlib2.R_2_jobs_id_wait,
187
188 "/2/tags": rlib2.R_2_tags,
189 "/2/info": rlib2.R_2_info,
190 "/2/os": rlib2.R_2_os,
191 "/2/redistribute-config": rlib2.R_2_redist_config,
192 "/2/features": rlib2.R_2_features,
193 "/2/modify": rlib2.R_2_cluster_modify,
194 re.compile(r"^/2/query/(%s)$" % query_res_pattern): rlib2.R_2_query,
195 re.compile(r"^/2/query/(%s)/fields$" % query_res_pattern):
196 rlib2.R_2_query_fields,
197 }
198
199
200 CONNECTOR.update(GetHandlers(_NAME_PATTERN, _NAME_PATTERN, _NAME_PATTERN,
201 constants.JOB_ID_TEMPLATE, _DISK_PATTERN,
202 _NAME_PATTERN))
203