3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
17 from cmframework.apis import cmerror
18 from cmframework.server import cmrestapi
19 from cmframework.server.cmhttperrors import CMHTTPErrors
22 class CMRestAPIV1(cmrestapi.CMRestAPI):
23 def __init__(self, processor):
24 logging.debug('CMRestAPIV1 constructor called')
25 cmrestapi.CMRestAPI.__init__(self, 'v1.0', 'current', '1.0', processor)
27 def get_property(self, rpc):
29 Request: GET http://<cm-vip:port>/cm/v1.0/properties/
30 <property-name>?snapshot=<snapshot name>
32 "name": "<name of the property>",
33 "value": "<value of the property>",
37 logging.debug('get_property called')
39 snapshot_name = rpc.req_filter.get('snapshot', None)
40 if isinstance(snapshot_name, list):
41 snapshot_name = snapshot_name[0]
42 prop_name = rpc.req_params['property']
43 value = self.processor.get_property(prop_name, snapshot_name)
45 reply['name'] = prop_name
46 reply['value'] = value
47 rpc.rep_status = CMHTTPErrors.get_ok_status()
48 rpc.rep_body = json.dumps(reply)
49 except cmerror.CMError as exp:
50 rpc.rep_status = CMHTTPErrors.get_resource_not_found_status()
52 rpc.rep_status += str(exp)
54 rpc.rep_status = CMHTTPErrors.get_resource_not_found_status()
55 except Exception as exp: # pylint: disable=broad-except
56 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
58 rpc.rep_status += str(exp)
60 def get_properties(self, rpc):
62 Request: GET http://<cm-vip:port>/cm/v1.0/properties?
63 prop-name-filter=<filter>&snapshot=<snapshot name>
67 "name": "<name of the property>",
68 "value": "<value of the property>"
71 "name": "<name of the property>",
72 "value": "<value of the property>"
79 logging.debug('get_properties called')
81 prop_name_filter = rpc.req_filter.get('prop-name-filter', '')
82 if isinstance(prop_name_filter, list):
83 prop_name_filter = prop_name_filter[0]
84 snapshot_name = rpc.req_filter.get('snapshot', None)
85 if isinstance(snapshot_name, list):
86 snapshot_name = snapshot_name[0]
87 result = self.processor.get_properties(prop_name_filter, snapshot_name)
89 rpc.rep_status = CMHTTPErrors.get_resource_not_found_status()
93 for key, value in result.iteritems():
98 reply['properties'] = items
99 rpc.rep_status = CMHTTPErrors.get_ok_status()
100 rpc.rep_body = json.dumps(reply)
101 except cmerror.CMError as exp:
102 rpc.rep_status = CMHTTPErrors.get_resource_not_found_status()
103 rpc.rep_status += ','
104 rpc.rep_status += str(exp)
105 except Exception as exp: # pylint: disable=broad-except
106 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
107 rpc.rep_status += ','
108 rpc.rep_status += str(exp)
110 def set_property(self, rpc):
112 Request: POST http://<cm-vip:port>/cm/v1.0/properties/<property-name>
114 "value": "<value of the property>"
116 Response: http status set correctly
118 "change-uuid": "<uuid>"
122 logging.debug('set_property called')
125 rpc.rep_status = CMHTTPErrors.get_request_not_ok_status()
127 request = json.loads(rpc.req_body)
128 name = rpc.req_params['property']
129 value = request['value']
130 uuid_value = self.processor.set_property(name, value)
131 rpc.rep_status = CMHTTPErrors.get_ok_status()
133 reply['change-uuid'] = uuid_value
134 rpc.rep_body = json.dumps(reply)
135 except cmerror.CMError as exp:
136 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
137 rpc.rep_status += ','
138 rpc.rep_status += str(exp)
140 rpc.rep_status = CMHTTPErrors.get_request_not_ok_status()
141 except Exception as exp: # pylint: disable=broad-except
142 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
143 rpc.rep_status += ','
144 rpc.rep_status += str(exp)
146 def set_properties(self, rpc):
148 Request: POST http://<cm-vip:port>/cm/v1.0/properties
150 "overwrite": True|False,
153 "name": "<name of the property>",
154 "value": "<value of the property>"
157 "name": "<name of the property>",
158 "value": "<value of the property>"
165 "change-uuid": "<uuid>"
169 logging.debug('set_properties called')
172 rpc.rep_status = CMHTTPErrors.get_request_not_ok_status()
174 request = json.loads(rpc.req_body)
176 if 'overwrite' in request:
177 overwrite = request['overwrite']
178 items = request['properties']
182 value = entry['value']
184 uuid_value = self.processor.set_properties(data, overwrite)
185 rpc.rep_status = CMHTTPErrors.get_ok_status()
187 reply['change-uuid'] = uuid_value
188 rpc.rep_body = json.dumps(reply)
189 except cmerror.CMError as exp:
190 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
191 rpc.rep_status += ','
192 rpc.rep_status += str(exp)
194 rpc.rep_status = CMHTTPErrors.get_request_not_ok_status()
195 except Exception as exp: # pylint: disable=broad-except
196 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
197 rpc.rep_status += ','
198 rpc.rep_status += str(exp)
200 def delete_property(self, rpc):
202 Request: DELETE http://<cm-vip:port>/cm/v1.0/properties/<property-name>
203 Response: http response with proper status
205 "change-uuid": "<uuid>"
209 logging.debug('delete_property called')
211 prop = rpc.req_params['property']
212 uuid_value = self.processor.delete_property(prop)
213 rpc.rep_status = CMHTTPErrors.get_ok_status()
215 reply['change-uuid'] = uuid_value
216 rpc.rep_body = json.dumps(reply)
217 except cmerror.CMError as exp:
218 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
219 rpc.rep_status += ','
220 rpc.rep_status += str(exp)
222 rpc.rep_status = CMHTTPErrors.get_request_not_ok_status()
223 except Exception as exp: # pylint: disable=broad-except
224 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
225 rpc.rep_status += ','
226 rpc.rep_status += str(exp)
228 def delete_properties(self, rpc):
230 Request: DELETE http://<cm-vip:port>/cm/v1.0/properties?prop-name-filter=<filter>
232 'properties': [ <prop-name>,
237 Response: http response with proper status
239 "change-uuid": "<uuid>"
243 logging.debug('delete_properties called')
245 if not rpc.req_filter and not rpc.req_body:
246 rpc.rep_status = CMHTTPErrors.get_request_not_ok_status()
249 arg = rpc.req_filter.get('prop-name-filter', '')
250 if isinstance(arg, list):
253 body = json.loads(rpc.req_body)
254 arg = body['properties']
255 uuid_value = self.processor.delete_properties(arg)
256 rpc.rep_status = CMHTTPErrors.get_ok_status()
258 reply['change-uuid'] = uuid_value
259 rpc.rep_body = json.dumps(reply)
260 except cmerror.CMError as exp:
261 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
262 rpc.rep_status += ','
263 rpc.rep_status += str(exp)
265 rpc.rep_status = CMHTTPErrors.get_request_not_ok_status()
266 except Exception as exp: # pylint: disable=broad-except
267 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
268 rpc.rep_status += ','
269 rpc.rep_status += str(exp)
271 def create_snapshot(self, rpc):
273 Request: GET http://<cm-vip:port>/cm/v1.0/snapshots/<snapshot name>
274 Response: http response with proper status
277 logging.debug('create snapshot called')
279 snapshot_name = rpc.req_params['snapshot']
280 self.processor.create_snapshot(snapshot_name)
281 rpc.rep_status = CMHTTPErrors.get_ok_status()
282 except cmerror.CMError as exp:
283 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
284 rpc.rep_status += ','
285 rpc.rep_status += str(exp)
286 except Exception as exp: # pylint: disable=broad-except
287 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
288 rpc.rep_status += ','
289 rpc.rep_status += str(exp)
291 def restore_snapshot(self, rpc):
293 Request: POST http://<cm-vip:port>/cm/v1.0/snapshots/<snapshot name>
294 Response: http response with proper status
297 logging.debug('restore_snapshot called')
299 snapshot_name = rpc.req_params['snapshot']
300 self.processor.restore_snapshot(snapshot_name)
301 rpc.rep_status = CMHTTPErrors.get_ok_status()
302 except cmerror.CMError as exp:
303 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
304 rpc.rep_status += ','
305 rpc.rep_status += str(exp)
306 except Exception as exp:
307 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
308 rpc.rep_status += ','
309 rpc.rep_status += str(exp)
311 def delete_snapshot(self, rpc):
313 Request: DELETE http://<cm-vip:port>/cm/v1.0/snapshots/<snapshot name>
314 Response: http response with proper status
317 logging.debug('delete_snapshot called')
319 snapshot_name = rpc.req_params['snapshot']
320 self.processor.delete_snapshot(snapshot_name)
321 rpc.rep_status = CMHTTPErrors.get_ok_status()
322 except cmerror.CMError as exp:
323 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
324 rpc.rep_status += ','
325 rpc.rep_status += str(exp)
326 except KeyError as exp:
327 rpc.rep_status = CMHTTPErrors.get_request_not_ok_status()
328 except Exception as exp:
329 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
330 rpc.rep_status += ','
331 rpc.rep_status += str(exp)
333 def list_snapshots(self, rpc):
335 Request: GET http://<cm-vip:port>/cm/v1.0/snapshots
338 "<name of the snapshot>",
344 logging.debug('list_snapshots called')
346 snapshots = self.processor.list_snapshots()
347 if not bool(snapshots):
348 rpc.rep_status = CMHTTPErrors.get_resource_not_found_status()
351 reply['snapshots'] = snapshots
352 rpc.rep_status = CMHTTPErrors.get_ok_status()
353 rpc.rep_body = json.dumps(reply)
354 except cmerror.CMError as exp:
355 rpc.rep_status = CMHTTPErrors.get_resource_not_found_status()
356 rpc.rep_status += ','
357 rpc.rep_status += str(exp)
358 except Exception as exp: # pylint: disable=broad-except
359 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
360 rpc.rep_status += ','
361 rpc.rep_status += str(exp)
363 def activate(self, rpc):
365 Request: POST http://<cm-vip:port>/cm/v1.0/activator/<node-name>
366 Response: http response with proper status
368 "change-uuid": "<uuid>"
372 logging.debug('activate called')
374 node_name = rpc.req_params.get('node', None)
375 uuid_value = self.processor.activate(node_name)
376 rpc.rep_status = CMHTTPErrors.get_ok_status()
378 reply['change-uuid'] = uuid_value
379 rpc.rep_body = json.dumps(reply)
380 except cmerror.CMError as exp:
381 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
382 rpc.rep_status += ','
383 rpc.rep_status += str(exp)
384 except Exception as exp: # pylint: disable=broad-except
385 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
386 rpc.rep_status += ','
387 rpc.rep_status += str(exp)
389 def activate_node(self, rpc):
391 Request: GET http://<cm-vip:port>/cm/v1.0/activator/agent/<node name>
393 "name": "<name of the node>",
394 "reboot": "<boolean value indicating whether a reboot is needed>",
398 logging.debug('activate_node called')
400 node_name = rpc.req_params['node']
401 reboot_needed = self.processor.activate_node(node_name)
403 reply['name'] = node_name
404 reply['reboot'] = reboot_needed
405 rpc.rep_status = CMHTTPErrors.get_ok_status()
406 rpc.rep_body = json.dumps(reply)
407 except cmerror.CMError as exp:
408 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
409 rpc.rep_status += ','
410 rpc.rep_status += str(exp)
411 except Exception as exp: # pylint: disable=broad-except
412 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
413 rpc.rep_status += ','
414 rpc.rep_status += str(exp)
416 def set_automatic_activation_state(self, rpc, state):
418 Request: POST http://<cm-vip:port>/cm/v1.0/activator/disable
419 or POST http://<cm-vip:port>/cm/v1.0/activator/enable
420 Response: http response with proper status
423 logging.debug('set_automatic_activation_state called')
425 self.processor.set_automatic_activation_state(state)
426 rpc.rep_status = CMHTTPErrors.get_ok_status()
427 except cmerror.CMError as exp:
428 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
429 rpc.rep_status += ','
430 rpc.rep_status += str(exp)
431 except Exception as exp: # pylint: disable=broad-except
432 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
433 rpc.rep_status += ','
434 rpc.rep_status += str(exp)
436 def reboot_node(self, rpc):
438 Request: GET http://<cm-vip:port>/cm/v1.0/reboot?node-name=<node name>
440 "node-name": "<name of the node>",
444 logging.debug('reboot_node called')
446 if not rpc.req_filter:
447 rpc.rep_status = CMHTTPErrors.get_request_not_ok_status()
449 node_name = rpc.req_filter.get('node-name', None)
450 if isinstance(node_name, list):
451 node_name = node_name[0]
452 self.processor.reboot_request(node_name)
454 reply['node-name'] = node_name
455 rpc.rep_status = CMHTTPErrors.get_ok_status()
456 rpc.rep_body = json.dumps(reply)
457 except cmerror.CMError as exp:
458 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
459 rpc.rep_status += ','
460 rpc.rep_status += str(exp)
461 except Exception as exp: # pylint: disable=broad-except
462 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
463 rpc.rep_status += ','
464 rpc.rep_status += str(exp)
466 def get_changes_states(self, rpc):
468 Request: GET http://<cm-vip:port>/cm/v1.0/changes?changd-uuid-filter=<filter>
472 "failed-plugins": { "plugin-name":"error", ... }
477 logging.debug('get_changes_states called')
480 changemonitor = self.processor.changemonitor
481 change_uuid_value = None
482 change_uuid_list = rpc.req_filter.get('change-uuid-filter', None)
484 change_uuid_value = change_uuid_list[0]
485 state = changemonitor.get_change_state(change_uuid_value)
486 reply[change_uuid_value] = {}
487 reply[change_uuid_value]["state"] = state.state
488 reply[change_uuid_value]["failed-plugins"] = state.failed_plugins
490 changes = changemonitor.get_all_changes_states()
491 for change_uuid, state in changes.iteritems():
492 reply[change_uuid] = {}
493 reply[change_uuid]["state"] = state.state
494 reply[change_uuid]["failed-plugins"] = state.failed_plugins
496 rpc.rep_status = CMHTTPErrors.get_ok_status()
497 rpc.rep_body = json.dumps(reply)
498 except cmerror.CMError as exp:
499 rpc.rep_status = CMHTTPErrors.get_resource_not_found_status()
500 rpc.rep_status += ','
501 rpc.rep_status += str(exp)
503 rpc.rep_status = CMHTTPErrors.get_resource_not_found_status()
504 except Exception as exp: # pylint: disable=broad-except
505 rpc.rep_status = CMHTTPErrors.get_internal_error_status()
506 rpc.rep_status += ','
507 rpc.rep_status += str(exp)