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.
14 from __future__ import print_function
21 from cmframework.apis import cmmanage
22 from cmframework.apis import cmerror
25 class VerboseLogger(object):
26 def __call__(self, msg):
30 class CMCLIHandler(object):
33 self.verbose_logger = VerboseLogger()
35 def _init_api(self, ip, port, client_lib, verbose):
38 logger = self.verbose_logger
41 serverip = socket.gethostbyname(ip)
42 except Exception: # pylint: disable=broad-except
43 # use localhost in-case we cannot resolve the provided hostname
44 serverip = '127.0.0.1'
46 self.api = cmmanage.CMManage(serverip, port, client_lib, logger)
48 def set_handler(self, subparser):
49 subparser.set_defaults(handler=self)
51 # pylint: disable=no-self-use, unused-argument
52 def init_subparser(self, subparsers):
53 raise cmerror.CMError('Not implemented')
55 # pylint: disable=no-self-use, unused-argument
56 def __call__(self, args):
57 raise cmerror.CMError('Not implemented')
60 class CMCLIGetPropertyHandler(CMCLIHandler):
61 def init_subparser(self, subparsers):
62 subparser = subparsers.add_parser('get-property', help='Get a property value')
63 subparser.add_argument('--property',
68 subparser.add_argument('--snapshot',
71 metavar='SNAPSHOT-NAME',
73 self.set_handler(subparser)
75 def __call__(self, args):
76 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
78 snapshot = args.snapshot
79 value = self.api.get_property(name, snapshot)
83 class CMCLIGetPropertiesHandler(CMCLIHandler):
84 def init_subparser(self, subparsers):
85 subparser = subparsers.add_parser('get-properties',
86 help='Get the properties matching a filter')
87 subparser.add_argument('--matching-filter',
89 dest='matching_filter',
90 metavar='MATCHING-FILTER',
92 subparser.add_argument('--snapshot',
95 metavar='SNAPSHOT-NAME',
97 self.set_handler(subparser)
99 def __call__(self, args):
100 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
101 matching_filter = args.matching_filter
102 snapshot = args.snapshot
103 props = self.api.get_properties(matching_filter, snapshot)
104 for name, value in props.iteritems():
105 print('%s=%s' % (name, value))
108 class CMCLISetPropertyHandler(CMCLIHandler):
109 def init_subparser(self, subparsers):
110 subparser = subparsers.add_parser('set-property', help='Set a property')
111 subparser.add_argument('--property',
114 metavar='NAME VALUE',
117 self.set_handler(subparser)
119 def __call__(self, args):
120 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
122 change_uuid = self.api.set_property(prop[0], prop[1])
123 print("change-uuid:%s" % change_uuid)
126 class CMCLISetPropertiesHandler(CMCLIHandler):
127 def init_subparser(self, subparsers):
128 subparser = subparsers.add_parser('set-properties', help='Set a group of properties')
129 subparser.add_argument('--property',
132 metavar='NAME VALUE',
135 self.set_handler(subparser)
137 def __call__(self, args):
138 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
145 change_uuid = self.api.set_properties(dic)
146 print("change-uuid:%s" % change_uuid)
149 class CMCLIDeletePropertyHandler(CMCLIHandler):
150 def init_subparser(self, subparsers):
151 subparser = subparsers.add_parser('delete-property', help='Delete a property')
152 subparser.add_argument('--property',
157 self.set_handler(subparser)
159 def __call__(self, args):
160 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
162 change_uuid = self.api.delete_property(name)
163 print("change-uuid:%s" % change_uuid)
166 class CMCLIDeletePropertiesWithFilterHandler(CMCLIHandler):
167 def init_subparser(self, subparsers):
168 subparser = subparsers.add_parser('delete-properties-with-filter',
169 help='Delete properties matching a filter')
170 subparser.add_argument('--matching-filter',
172 dest='matching_filter',
173 metavar='MATCHING-FILTER',
175 self.set_handler(subparser)
177 def __call__(self, args):
178 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
179 matching_filter = args.matching_filter
180 change_uuid = self.api.delete_properties(matching_filter)
181 print("change-uuid:%s" % change_uuid)
184 class CMCLIDeletePropertiesHandler(CMCLIHandler):
185 def init_subparser(self, subparsers):
186 subparser = subparsers.add_parser('delete-properties', help='Delete a group of properties')
187 subparser.add_argument('--property',
190 metavar='PROPERY-NAME',
192 self.set_handler(subparser)
194 def __call__(self, args):
195 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
197 change_uuid = self.api.delete_properties(props)
198 print("change-uuid:%s" % change_uuid)
201 class CMCLICreateSnapshotHandler(CMCLIHandler):
202 def init_subparser(self, subparsers):
203 subparser = subparsers.add_parser('create-snapshot',
204 help='Take a snapshot of the configuration data')
205 subparser.add_argument('--name',
207 dest='snapshot_full_name',
208 metavar='SNAPSHOT-FULL-NAME',
210 self.set_handler(subparser)
212 def __call__(self, args):
213 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
214 snapshot = args.snapshot_full_name
215 self.api.create_snapshot(snapshot)
218 class CMCLIRestoreSnapshotHandler(CMCLIHandler):
219 def init_subparser(self, subparsers):
220 subparser = subparsers.add_parser('restore-snapshot',
221 help='Restore a configuration snapshot')
222 subparser.add_argument('--name',
224 dest='snapshot_full_name',
225 metavar='SNAPSHOT-FULL-NAME',
227 self.set_handler(subparser)
229 def __call__(self, args):
230 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
231 snapshot = args.snapshot_full_name
232 self.api.restore_snapshot(snapshot)
235 class CMCLIDeleteSnapshotHandler(CMCLIHandler):
236 def init_subparser(self, subparsers):
237 subparser = subparsers.add_parser('delete-snapshot', help='Delete a configuration snapshot')
238 subparser.add_argument('--name',
240 dest='snapshot_full_name',
241 metavar='SNAPSHOT-FULL-NAME',
243 self.set_handler(subparser)
245 def __call__(self, args):
246 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
247 snapshot = args.snapshot_full_name
248 self.api.delete_snapshot(snapshot)
251 class CMCLIListSnapshotHandler(CMCLIHandler):
252 def init_subparser(self, subparsers):
253 subparser = subparsers.add_parser('list-snapshots', help='List all configuration snapshots')
254 self.set_handler(subparser)
256 def __call__(self, args):
257 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
258 snapshots = self.api.list_snapshots()
259 sorted_snapshots = sorted(snapshots, key=lambda k: k['creation_date'])
261 t = prettytable.PrettyTable(['Name', 'Date', 'Release', 'Build'])
262 t.set_style(prettytable.PLAIN_COLUMNS)
264 for snapshot in sorted_snapshots:
265 t.add_row([snapshot['name'],
266 snapshot['creation_date'],
272 class CMCLIActivateHandler(CMCLIHandler):
273 def init_subparser(self, subparsers):
274 subparser = subparsers.add_parser(
276 help='Activate the configuration in all or specified node')
277 subparser.add_argument('--node-name',
282 self.set_handler(subparser)
284 def __call__(self, args):
285 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
286 node_name = args.node_name
287 self.api.activate(node_name)
290 class CMCLIRebootHandler(CMCLIHandler):
291 def init_subparser(self, subparsers):
292 subparser = subparsers.add_parser('reboot-request',
293 help=('Request reboot of a specified node '
294 'during activation'))
295 subparser.add_argument('--node-name',
300 self.set_handler(subparser)
302 def __call__(self, args):
303 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
304 node_name = args.node_name
305 self.api.reboot_node(node_name)
308 class CMCLIBootstrapHandler(CMCLIHandler):
309 def init_subparser(self, subparsers):
310 subparser = subparsers.add_parser('bootstrap',
311 help='Bootsrap the backend with the user config data')
312 subparser.add_argument('--config',
315 metavar='INITIAL-USER-CONFIG',
317 subparser.add_argument('--plugin_path',
320 metavar='BOOTSTRAP-PLUGIN-PATH',
322 self.set_handler(subparser)
324 def __call__(self, args):
325 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
326 from cmframework.utils.cmuserconfig import UserConfig
327 uc = UserConfig(args.config, args.plugin_path)
328 flat_config = uc.get_flat_config()
329 self.api.set_properties(flat_config)
332 class CMCLIAnsibleInventoryHandler(CMCLIHandler):
333 def init_subparser(self, subparsers):
334 subparser = subparsers.add_parser('ansible-inventory',
335 help='Prints the ansible inventory json to output')
336 subparser.add_argument('--plugin_path',
338 default='/opt/cmframework/inventoryhandlers',
340 metavar='INVENTORY-HANDLERS-PLUGIN-PATH',
342 self.set_handler(subparser)
344 def __call__(self, args):
345 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
346 from cmframework.utils.cmansibleinventory import AnsibleInventory
349 properties = self.api.get_properties('.*')
351 inventory = AnsibleInventory(properties, args.plugin_path)
352 inv = inventory.generate_inventory()
354 print (json.dumps(inv, indent=4, sort_keys=True))
357 class CMAnsiblePlaybookHandler(CMCLIHandler):
358 def init_subparser(self, subparsers):
359 subparser = subparsers.add_parser('ansible-playbooks-generate',
360 help=('Generate the ansible playbooks for the '
361 'bootstrapping, provisioning, '
362 'postconfig and finalizing phases'))
363 subparser.add_argument('--bootstrapping-playbooks-path',
365 default='/etc/lcm/playbooks/installation/bootstrapping',
366 dest='bootstrapping_path',
367 metavar='BOOTSTRAPPING-PLAYBOOKS-PATH',
369 subparser.add_argument('--provisioning-playbooks-path',
371 default='/etc/lcm/playbooks/installation/provisioning',
372 dest='provisioning_path',
373 metavar='PROVISIONING-PLAYBOOKS-PATH',
375 subparser.add_argument('--postconfig-playbooks-path',
377 default='/etc/lcm/playbooks/installation/postconfig',
378 dest='postconfig_path',
379 metavar='POSTCONFIG-PLAYBOOKS-PATH',
381 subparser.add_argument('--finalize-playbooks-path',
383 default='/etc/lcm/playbooks/installation/finalize',
384 dest='finalize_path',
385 metavar='FINALIZE-PLAYBOOKS-PATH',
387 subparser.add_argument('--destination-path',
389 default='/opt/openstack-ansible/playbooks/',
390 dest='destination_path',
391 metavar='DESTINATION-PATH',
393 self.set_handler(subparser)
395 def __call__(self, args):
396 from cmframework.utils.cmansibleplaybooks import AnsiblePlaybooks
398 playbooks = AnsiblePlaybooks(args.destination_path, args.bootstrapping_path,
399 args.provisioning_path, args.postconfig_path,
401 playbooks.generate_playbooks()
404 class CMCLIDisableAutomaticActivationHandler(CMCLIHandler):
405 def init_subparser(self, subparsers):
406 subparser = subparsers.add_parser('disable-automatic-activation',
407 help='Disable automatic activation')
408 self.set_handler(subparser)
410 def __call__(self, args):
411 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
412 self.api.disable_automatic_activation()
415 class CMCLIEnableAutomaticActivationHandler(CMCLIHandler):
416 def init_subparser(self, subparsers):
417 subparser = subparsers.add_parser('enable-automatic-activation',
418 help='Enable automatic activation')
419 self.set_handler(subparser)
421 def __call__(self, args):
422 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
423 self.api.enable_automatic_activation()
426 class CMCLIGetChangesStatesHandler(CMCLIHandler):
427 def init_subparser(self, subparsers):
428 subparser = subparsers.add_parser('get-changes-states',
429 help='Get the configuration changes states')
430 subparser.add_argument('--uuid',
433 metavar='CHANGE_UUID',
435 self.set_handler(subparser)
437 def __call__(self, args):
438 self._init_api(args.ip, args.port, args.client_lib, args.verbose)
441 change_uuid = args.change_uuid
443 result = self.api.get_changes_states(change_uuid)
444 pp = pprint.PrettyPrinter(indent=4)
448 def get_handlers_list():
450 for name, obj in inspect.getmembers(sys.modules[__name__]):
451 if inspect.isclass(obj):
452 if name != 'CMCLIHandler':
453 if issubclass(obj, CMCLIHandler):
454 handlers.append(obj())
459 handlers = get_handlers_list()
460 for handler in handlers:
461 print('handler is ', handler)
464 if __name__ == '__main__':