Revision 798f1ac9 lib/rapi/connector.py

b/lib/rapi/connector.py
88 88
    return (handler, groups, args)
89 89

  
90 90

  
91
def _ConvertPattern(value):
92
  """Converts URI pattern into a regular expression group.
93

  
94
  Used by L{_CompileHandlerPath}.
95

  
96
  """
97
  if isinstance(value, UriPattern):
98
    return "(%s)" % value.content
99
  else:
100
    return value
101

  
102

  
103
def _CompileHandlerPath(*args):
104
  """Compiles path for RAPI resource into regular expression.
105

  
106
  @return: Compiled regular expression object
107

  
108
  """
109
  return re.compile("^%s$" % "".join(map(_ConvertPattern, args)))
110

  
111

  
112
class UriPattern(object):
113
  __slots__ = [
114
    "content",
115
    ]
116

  
117
  def __init__(self, content):
118
    self.content = content
119

  
120

  
91 121
def GetHandlers(node_name_pattern, instance_name_pattern,
92 122
                group_name_pattern, network_name_pattern,
93 123
                job_id_pattern, disk_pattern,
94
                query_res_pattern):
124
                query_res_pattern,
125
                translate=None):
95 126
  """Returns all supported resources and their handlers.
96 127

  
128
  C{node_name_pattern} and the other C{*_pattern} parameters are wrapped in
129
  L{UriPattern} and, if used in a URI, passed to the function specified using
130
  C{translate}. C{translate} receives 1..N parameters which are either plain
131
  strings or instances of L{UriPattern} and returns a dictionary key suitable
132
  for the caller of C{GetHandlers}. The default implementation in
133
  L{_CompileHandlerPath} returns a compiled regular expression in which each
134
  pattern is a group.
135

  
136
  @rtype: dict
137

  
97 138
  """
139
  if translate is None:
140
    translate_fn = _CompileHandlerPath
141
  else:
142
    translate_fn = translate
143

  
144
  node_name = UriPattern(node_name_pattern)
145
  instance_name = UriPattern(instance_name_pattern)
146
  group_name = UriPattern(group_name_pattern)
147
  network_name = UriPattern(network_name_pattern)
148
  job_id = UriPattern(job_id_pattern)
149
  disk = UriPattern(disk_pattern)
150
  query_res = UriPattern(query_res_pattern)
151

  
98 152
  # Important note: New resources should always be added under /2. During a
99 153
  # discussion in July 2010 it was decided that having per-resource versions
100 154
  # is more flexible and future-compatible than versioning the whole remote
101 155
  # API.
156
  # TODO: Consider a different data structure where all keys are of the same
157
  # type. Strings are faster to look up in a dictionary than iterating and
158
  # matching regular expressions, therefore maybe two separate dictionaries
159
  # should be used.
102 160
  return {
103 161
    "/": rlib2.R_root,
104 162
    "/2": rlib2.R_2,
......
106 164
    "/version": rlib2.R_version,
107 165

  
108 166
    "/2/nodes": rlib2.R_2_nodes,
109
    re.compile(r"^/2/nodes/(%s)$" % node_name_pattern):
167

  
168
    translate_fn("/2/nodes/", node_name):
110 169
      rlib2.R_2_nodes_name,
111
    re.compile(r"^/2/nodes/(%s)/powercycle$" % node_name_pattern):
170
    translate_fn("/2/nodes/", node_name, "/powercycle"):
112 171
      rlib2.R_2_nodes_name_powercycle,
113
    re.compile(r"^/2/nodes/(%s)/tags$" % node_name_pattern):
172
    translate_fn("/2/nodes/", node_name, "/tags"):
114 173
      rlib2.R_2_nodes_name_tags,
115
    re.compile(r"^/2/nodes/(%s)/role$" % node_name_pattern):
174
    translate_fn("/2/nodes/", node_name, "/role"):
116 175
      rlib2.R_2_nodes_name_role,
117
    re.compile(r"^/2/nodes/(%s)/evacuate$" % node_name_pattern):
176
    translate_fn("/2/nodes/", node_name, "/evacuate"):
118 177
      rlib2.R_2_nodes_name_evacuate,
119
    re.compile(r"^/2/nodes/(%s)/migrate$" % node_name_pattern):
178
    translate_fn("/2/nodes/", node_name, "/migrate"):
120 179
      rlib2.R_2_nodes_name_migrate,
121
    re.compile(r"^/2/nodes/(%s)/modify$" % node_name_pattern):
180
    translate_fn("/2/nodes/", node_name, "/modify"):
122 181
      rlib2.R_2_nodes_name_modify,
123
    re.compile(r"^/2/nodes/(%s)/storage$" % node_name_pattern):
182
    translate_fn("/2/nodes/", node_name, "/storage"):
124 183
      rlib2.R_2_nodes_name_storage,
125
    re.compile(r"^/2/nodes/(%s)/storage/modify$" % node_name_pattern):
184
    translate_fn("/2/nodes/", node_name, "/storage/modify"):
126 185
      rlib2.R_2_nodes_name_storage_modify,
127
    re.compile(r"^/2/nodes/(%s)/storage/repair$" % node_name_pattern):
186
    translate_fn("/2/nodes/", node_name, "/storage/repair"):
128 187
      rlib2.R_2_nodes_name_storage_repair,
129 188

  
130 189
    "/2/instances": rlib2.R_2_instances,
131
    re.compile(r"^/2/instances/(%s)$" % instance_name_pattern):
190
    translate_fn("/2/instances/", instance_name):
132 191
      rlib2.R_2_instances_name,
133
    re.compile(r"^/2/instances/(%s)/info$" % instance_name_pattern):
192
    translate_fn("/2/instances/", instance_name, "/info"):
134 193
      rlib2.R_2_instances_name_info,
135
    re.compile(r"^/2/instances/(%s)/tags$" % instance_name_pattern):
194
    translate_fn("/2/instances/", instance_name, "/tags"):
136 195
      rlib2.R_2_instances_name_tags,
137
    re.compile(r"^/2/instances/(%s)/reboot$" % instance_name_pattern):
196
    translate_fn("/2/instances/", instance_name, "/reboot"):
138 197
      rlib2.R_2_instances_name_reboot,
139
    re.compile(r"^/2/instances/(%s)/reinstall$" % instance_name_pattern):
198
    translate_fn("/2/instances/", instance_name, "/reinstall"):
140 199
      rlib2.R_2_instances_name_reinstall,
141
    re.compile(r"^/2/instances/(%s)/replace-disks$" % instance_name_pattern):
200
    translate_fn("/2/instances/", instance_name, "/replace-disks"):
142 201
      rlib2.R_2_instances_name_replace_disks,
143
    re.compile(r"^/2/instances/(%s)/shutdown$" % instance_name_pattern):
202
    translate_fn("/2/instances/", instance_name, "/shutdown"):
144 203
      rlib2.R_2_instances_name_shutdown,
145
    re.compile(r"^/2/instances/(%s)/startup$" % instance_name_pattern):
204
    translate_fn("/2/instances/", instance_name, "/startup"):
146 205
      rlib2.R_2_instances_name_startup,
147
    re.compile(r"^/2/instances/(%s)/activate-disks$" % instance_name_pattern):
206
    translate_fn("/2/instances/", instance_name, "/activate-disks"):
148 207
      rlib2.R_2_instances_name_activate_disks,
149
    re.compile(r"^/2/instances/(%s)/deactivate-disks$" % instance_name_pattern):
208
    translate_fn("/2/instances/", instance_name, "/deactivate-disks"):
150 209
      rlib2.R_2_instances_name_deactivate_disks,
151
    re.compile(r"^/2/instances/(%s)/recreate-disks$" % instance_name_pattern):
210
    translate_fn("/2/instances/", instance_name, "/recreate-disks"):
152 211
      rlib2.R_2_instances_name_recreate_disks,
153
    re.compile(r"^/2/instances/(%s)/prepare-export$" % instance_name_pattern):
212
    translate_fn("/2/instances/", instance_name, "/prepare-export"):
154 213
      rlib2.R_2_instances_name_prepare_export,
155
    re.compile(r"^/2/instances/(%s)/export$" % instance_name_pattern):
214
    translate_fn("/2/instances/", instance_name, "/export"):
156 215
      rlib2.R_2_instances_name_export,
157
    re.compile(r"^/2/instances/(%s)/migrate$" % instance_name_pattern):
216
    translate_fn("/2/instances/", instance_name, "/migrate"):
158 217
      rlib2.R_2_instances_name_migrate,
159
    re.compile(r"^/2/instances/(%s)/failover$" % instance_name_pattern):
218
    translate_fn("/2/instances/", instance_name, "/failover"):
160 219
      rlib2.R_2_instances_name_failover,
161
    re.compile(r"^/2/instances/(%s)/rename$" % instance_name_pattern):
220
    translate_fn("/2/instances/", instance_name, "/rename"):
162 221
      rlib2.R_2_instances_name_rename,
163
    re.compile(r"^/2/instances/(%s)/modify$" % instance_name_pattern):
222
    translate_fn("/2/instances/", instance_name, "/modify"):
164 223
      rlib2.R_2_instances_name_modify,
165
    re.compile(r"^/2/instances/(%s)/disk/(%s)/grow$" %
166
               (instance_name_pattern, disk_pattern)):
224
    translate_fn("/2/instances/", instance_name, "/disk/", disk, "/grow"):
167 225
      rlib2.R_2_instances_name_disk_grow,
168
    re.compile(r"^/2/instances/(%s)/console$" % instance_name_pattern):
226
    translate_fn("/2/instances/", instance_name, "/console"):
169 227
      rlib2.R_2_instances_name_console,
170 228

  
171 229
    "/2/networks": rlib2.R_2_networks,
172
    re.compile(r"^/2/networks/(%s)$" % network_name_pattern):
230
    translate_fn("/2/networks/", network_name):
173 231
      rlib2.R_2_networks_name,
174
    re.compile(r"^/2/networks/(%s)/connect$" % network_name_pattern):
232
    translate_fn("/2/networks/", network_name, "/connect"):
175 233
      rlib2.R_2_networks_name_connect,
176
    re.compile(r"^/2/networks/(%s)/disconnect$" % network_name_pattern):
234
    translate_fn("/2/networks/", network_name, "/disconnect"):
177 235
      rlib2.R_2_networks_name_disconnect,
178
    re.compile(r"^/2/networks/(%s)/modify$" % network_name_pattern):
236
    translate_fn("/2/networks/", network_name, "/modify"):
179 237
      rlib2.R_2_networks_name_modify,
180
    re.compile(r"^/2/networks/(%s)/tags$" % network_name_pattern):
238
    translate_fn("/2/networks/", network_name, "/tags"):
181 239
      rlib2.R_2_networks_name_tags,
182 240

  
183 241
    "/2/groups": rlib2.R_2_groups,
184
    re.compile(r"^/2/groups/(%s)$" % group_name_pattern):
242
    translate_fn("/2/groups/", group_name):
185 243
      rlib2.R_2_groups_name,
186
    re.compile(r"^/2/groups/(%s)/modify$" % group_name_pattern):
244
    translate_fn("/2/groups/", group_name, "/modify"):
187 245
      rlib2.R_2_groups_name_modify,
188
    re.compile(r"^/2/groups/(%s)/rename$" % group_name_pattern):
246
    translate_fn("/2/groups/", group_name, "/rename"):
189 247
      rlib2.R_2_groups_name_rename,
190
    re.compile(r"^/2/groups/(%s)/assign-nodes$" % group_name_pattern):
248
    translate_fn("/2/groups/", group_name, "/assign-nodes"):
191 249
      rlib2.R_2_groups_name_assign_nodes,
192
    re.compile(r"^/2/groups/(%s)/tags$" % group_name_pattern):
250
    translate_fn("/2/groups/", group_name, "/tags"):
193 251
      rlib2.R_2_groups_name_tags,
194 252

  
195 253
    "/2/jobs": rlib2.R_2_jobs,
196
    re.compile(r"^/2/jobs/(%s)$" % job_id_pattern):
254
    translate_fn("/2/jobs/", job_id):
197 255
      rlib2.R_2_jobs_id,
198
    re.compile(r"^/2/jobs/(%s)/wait$" % job_id_pattern):
256
    translate_fn("/2/jobs/", job_id, "/wait"):
199 257
      rlib2.R_2_jobs_id_wait,
200 258

  
201 259
    "/2/instances-multi-alloc": rlib2.R_2_instances_multi_alloc,
......
205 263
    "/2/redistribute-config": rlib2.R_2_redist_config,
206 264
    "/2/features": rlib2.R_2_features,
207 265
    "/2/modify": rlib2.R_2_cluster_modify,
208
    re.compile(r"^/2/query/(%s)$" % query_res_pattern): rlib2.R_2_query,
209
    re.compile(r"^/2/query/(%s)/fields$" % query_res_pattern):
266

  
267
    translate_fn("/2/query/", query_res):
268
      rlib2.R_2_query,
269
    translate_fn("/2/query/", query_res, "/fields"):
210 270
      rlib2.R_2_query_fields,
211 271
    }
212 272

  

Also available in: Unified diff