new commands: ns-op-list, ns-op-show, ns-action
[osm/osmclient.git] / osmclient / scripts / osm.py
1 # Copyright 2017-2018 Sandvine
2 # Copyright 2018 Telefonica
3 #
4 # All Rights Reserved.
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License"); you may
7 # not use this file except in compliance with the License. You may obtain
8 # a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 # License for the specific language governing permissions and limitations
16 # under the License.
17 """
18 OSM shell/cli
19 """
20
21 import click
22 from osmclient import client
23 from osmclient.common.exceptions import ClientException
24 from prettytable import PrettyTable
25 import yaml
26 import json
27 import time
28
29 def check_client_version(obj, what, version='sol005'):
30 '''
31 Checks the version of the client object and raises error if it not the expected.
32
33 :param obj: the client object
34 :what: the function or command under evaluation (used when an error is raised)
35 :return: -
36 :raises ClientError: if the specified version does not match the client version
37 '''
38 fullclassname = obj.__module__ + "." + obj.__class__.__name__
39 message = 'The following commands or options are only supported with the option "--sol005": {}'.format(what)
40 if version == 'v1':
41 message = 'The following commands or options are not supported when using option "--sol005": {}'.format(what)
42 if fullclassname != 'osmclient.{}.client.Client'.format(version):
43 raise ClientException(message)
44 return
45
46 @click.group()
47 @click.option('--hostname',
48 default=None,
49 envvar='OSM_HOSTNAME',
50 help='hostname of server. ' +
51 'Also can set OSM_HOSTNAME in environment')
52 @click.option('--so-port',
53 default=None,
54 envvar='OSM_SO_PORT',
55 help='hostname of server. ' +
56 'Also can set OSM_SO_PORT in environment')
57 @click.option('--so-project',
58 default=None,
59 envvar='OSM_SO_PROJECT',
60 help='Project Name in SO. ' +
61 'Also can set OSM_SO_PROJECT in environment')
62 @click.option('--ro-hostname',
63 default=None,
64 envvar='OSM_RO_HOSTNAME',
65 help='hostname of RO server. ' +
66 'Also can set OSM_RO_HOSTNAME in environment')
67 @click.option('--ro-port',
68 default=9090,
69 envvar='OSM_RO_PORT',
70 help='hostname of RO server. ' +
71 'Also can set OSM_RO_PORT in environment')
72 @click.option('--sol005',
73 is_flag=True,
74 envvar='OSM_SOL005',
75 help='Use ETSI NFV SOL005 API')
76 @click.pass_context
77 def cli(ctx, hostname, so_port, so_project, ro_hostname, ro_port, sol005):
78 if hostname is None:
79 print(
80 "either hostname option or OSM_HOSTNAME " +
81 "environment variable needs to be specified")
82 exit(1)
83 kwargs={}
84 if so_port is not None:
85 kwargs['so_port']=so_port
86 if so_project is not None:
87 kwargs['so_project']=so_project
88 if ro_hostname is not None:
89 kwargs['ro_host']=ro_hostname
90 if ro_port is not None:
91 kwargs['ro_port']=ro_port
92
93 ctx.obj = client.Client(host=hostname, sol005=sol005, **kwargs)
94
95
96 ####################
97 # LIST operations
98 ####################
99
100 @cli.command(name='ns-list')
101 @click.option('--filter', default=None,
102 help='restricts the list to the NS instances matching the filter')
103 @click.pass_context
104 def ns_list(ctx, filter):
105 '''list all NS instances'''
106 if filter:
107 check_client_version(ctx.obj, '--filter')
108 resp = ctx.obj.ns.list(filter)
109 else:
110 resp = ctx.obj.ns.list()
111 table = PrettyTable(
112 ['ns instance name',
113 'id',
114 'operational status',
115 'config status',
116 'detailed status'])
117 for ns in resp:
118 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
119 if fullclassname == 'osmclient.sol005.client.Client':
120 nsr = ns
121 nsr_name = nsr['name']
122 nsr_id = nsr['_id']
123 else:
124 nsopdata = ctx.obj.ns.get_opdata(ns['id'])
125 nsr = nsopdata['nsr:nsr']
126 nsr_name = nsr['name-ref']
127 nsr_id = nsr['ns-instance-config-ref']
128 opstatus = nsr['operational-status'] if 'operational-status' in nsr else 'Not found'
129 configstatus = nsr['config-status'] if 'config-status' in nsr else 'Not found'
130 detailed_status = nsr['detailed-status'] if 'detailed-status' in nsr else 'Not found'
131 if configstatus == "config_not_needed":
132 configstatus = "configured (no charms)"
133 table.add_row(
134 [nsr_name,
135 nsr_id,
136 opstatus,
137 configstatus,
138 detailed_status])
139 table.align = 'l'
140 print(table)
141
142
143 def nsd_list(ctx, filter):
144 if filter:
145 check_client_version(ctx.obj, '--filter')
146 resp = ctx.obj.nsd.list(filter)
147 else:
148 resp = ctx.obj.nsd.list()
149 #print yaml.safe_dump(resp)
150 table = PrettyTable(['nsd name', 'id'])
151 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
152 if fullclassname == 'osmclient.sol005.client.Client':
153 for ns in resp:
154 name = ns['name'] if 'name' in ns else '-'
155 table.add_row([name, ns['_id']])
156 else:
157 for ns in resp:
158 table.add_row([ns['name'], ns['id']])
159 table.align = 'l'
160 print(table)
161
162
163 @cli.command(name='nsd-list')
164 @click.option('--filter', default=None,
165 help='restricts the list to the NSD/NSpkg matching the filter')
166 @click.pass_context
167 def nsd_list1(ctx, filter):
168 '''list all NSD/NSpkg in the system'''
169 nsd_list(ctx,filter)
170
171
172 @cli.command(name='nspkg-list')
173 @click.option('--filter', default=None,
174 help='restricts the list to the NSD/NSpkg matching the filter')
175 @click.pass_context
176 def nsd_list2(ctx, filter):
177 '''list all NSD/NSpkg in the system'''
178 nsd_list(ctx,filter)
179
180
181 def vnfd_list(ctx, filter):
182 if filter:
183 check_client_version(ctx.obj, '--filter')
184 resp = ctx.obj.vnfd.list(filter)
185 else:
186 resp = ctx.obj.vnfd.list()
187 #print yaml.safe_dump(resp)
188 table = PrettyTable(['vnfd name', 'id'])
189 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
190 if fullclassname == 'osmclient.sol005.client.Client':
191 for vnfd in resp:
192 name = vnfd['name'] if 'name' in vnfd else '-'
193 table.add_row([name, vnfd['_id']])
194 else:
195 for vnfd in resp:
196 table.add_row([vnfd['name'], vnfd['id']])
197 table.align = 'l'
198 print(table)
199
200
201 @cli.command(name='vnfd-list')
202 @click.option('--filter', default=None,
203 help='restricts the list to the VNFD/VNFpkg matching the filter')
204 @click.pass_context
205 def vnfd_list1(ctx, filter):
206 '''list all VNFD/VNFpkg in the system'''
207 vnfd_list(ctx,filter)
208
209
210 @cli.command(name='vnfpkg-list')
211 @click.option('--filter', default=None,
212 help='restricts the list to the VNFD/VNFpkg matching the filter')
213 @click.pass_context
214 def vnfd_list2(ctx, filter):
215 '''list all VNFD/VNFpkg in the system'''
216 vnfd_list(ctx,filter)
217
218
219 @cli.command(name='vnf-list')
220 @click.pass_context
221 def vnf_list(ctx):
222 ''' list all VNF instances'''
223 try:
224 check_client_version(ctx.obj, ctx.command.name, 'v1')
225 resp = ctx.obj.vnf.list()
226 except ClientException as inst:
227 print(inst.message)
228 exit(1)
229 table = PrettyTable(
230 ['vnf name',
231 'id',
232 'operational status',
233 'config status'])
234 for vnfr in resp:
235 if 'mgmt-interface' not in vnfr:
236 vnfr['mgmt-interface'] = {}
237 vnfr['mgmt-interface']['ip-address'] = None
238 table.add_row(
239 [vnfr['name'],
240 vnfr['id'],
241 vnfr['operational-status'],
242 vnfr['config-status']])
243 table.align = 'l'
244 print(table)
245
246 @cli.command(name='ns-op-list')
247 @click.argument('name')
248 @click.pass_context
249 def ns_op_list(ctx, name):
250 '''shows the history of operations over a NS instance
251
252 NAME: name or ID of the NS instance
253 '''
254 try:
255 check_client_version(ctx.obj, ctx.command.name)
256 resp = ctx.obj.ns.list_op(name)
257 except ClientException as inst:
258 print(inst.message)
259 exit(1)
260
261 table = PrettyTable(['id', 'operation', 'status'])
262 for op in resp:
263 table.add_row([op['id'], op['lcmOperationType'],
264 op['operationState']])
265 table.align = 'l'
266 print(table)
267
268 ####################
269 # SHOW operations
270 ####################
271
272 def nsd_show(ctx, name, literal):
273 try:
274 resp = ctx.obj.nsd.get(name)
275 #resp = ctx.obj.nsd.get_individual(name)
276 except ClientException as inst:
277 print(inst.message)
278 exit(1)
279
280 if literal:
281 print yaml.safe_dump(resp)
282 return
283
284 table = PrettyTable(['field', 'value'])
285 for k, v in resp.items():
286 table.add_row([k, json.dumps(v, indent=2)])
287 table.align = 'l'
288 print(table)
289
290
291 @cli.command(name='nsd-show', short_help='shows the content of a NSD')
292 @click.option('--literal', is_flag=True,
293 help='print literally, no pretty table')
294 @click.argument('name')
295 @click.pass_context
296 def nsd_show1(ctx, name, literal):
297 '''shows the content of a NSD
298
299 NAME: name or ID of the NSD/NSpkg
300 '''
301 nsd_show(ctx, name, literal)
302
303
304 @cli.command(name='nspkg-show', short_help='shows the content of a NSD')
305 @click.option('--literal', is_flag=True,
306 help='print literally, no pretty table')
307 @click.argument('name')
308 @click.pass_context
309 def nsd_show2(ctx, name, literal):
310 '''shows the content of a NSD
311
312 NAME: name or ID of the NSD/NSpkg
313 '''
314 nsd_show(ctx, name, literal)
315
316
317 def vnfd_show(ctx, name, literal):
318 try:
319 resp = ctx.obj.vnfd.get(name)
320 #resp = ctx.obj.vnfd.get_individual(name)
321 except ClientException as inst:
322 print(inst.message)
323 exit(1)
324
325 if literal:
326 print yaml.safe_dump(resp)
327 return
328
329 table = PrettyTable(['field', 'value'])
330 for k, v in resp.items():
331 table.add_row([k, json.dumps(v, indent=2)])
332 table.align = 'l'
333 print(table)
334
335
336 @cli.command(name='vnfd-show', short_help='shows the content of a VNFD')
337 @click.option('--literal', is_flag=True,
338 help='print literally, no pretty table')
339 @click.argument('name')
340 @click.pass_context
341 def vnfd_show1(ctx, name, literal):
342 '''shows the content of a VNFD
343
344 NAME: name or ID of the VNFD/VNFpkg
345 '''
346 vnfd_show(ctx, name, literal)
347
348
349 @cli.command(name='vnfpkg-show', short_help='shows the content of a VNFD')
350 @click.option('--literal', is_flag=True,
351 help='print literally, no pretty table')
352 @click.argument('name')
353 @click.pass_context
354 def vnfd_show2(ctx, name, literal):
355 '''shows the content of a VNFD
356
357 NAME: name or ID of the VNFD/VNFpkg
358 '''
359 vnfd_show(ctx, name, literal)
360
361
362 @cli.command(name='ns-show', short_help='shows the info of a NS instance')
363 @click.argument('name')
364 @click.option('--literal', is_flag=True,
365 help='print literally, no pretty table')
366 @click.option('--filter', default=None)
367 @click.pass_context
368 def ns_show(ctx, name, literal, filter):
369 '''shows the info of a NS instance
370
371 NAME: name or ID of the NS instance
372 '''
373 try:
374 ns = ctx.obj.ns.get(name)
375 except ClientException as inst:
376 print(inst.message)
377 exit(1)
378
379 if literal:
380 print yaml.safe_dump(resp)
381 return
382
383 table = PrettyTable(['field', 'value'])
384
385 for k, v in ns.items():
386 if filter is None or filter in k:
387 table.add_row([k, json.dumps(v, indent=2)])
388
389 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
390 if fullclassname != 'osmclient.sol005.client.Client':
391 nsopdata = ctx.obj.ns.get_opdata(ns['id'])
392 nsr_optdata = nsopdata['nsr:nsr']
393 for k, v in nsr_optdata.items():
394 if filter is None or filter in k:
395 table.add_row([k, json.dumps(v, indent=2)])
396 table.align = 'l'
397 print(table)
398
399
400 @cli.command(name='vnf-show', short_help='shows the info of a VNF instance')
401 @click.argument('name')
402 @click.option('--literal', is_flag=True,
403 help='print literally, no pretty table')
404 @click.option('--filter', default=None)
405 @click.pass_context
406 def vnf_show(ctx, name, literal, filter):
407 '''shows the info of a VNF instance
408
409 NAME: name or ID of the VNF instance
410 '''
411 try:
412 check_client_version(ctx.obj, ctx.command.name, 'v1')
413 resp = ctx.obj.vnf.get(name)
414 except ClientException as inst:
415 print(inst.message)
416 exit(1)
417
418 if literal:
419 print yaml.safe_dump(resp)
420 return
421
422 table = PrettyTable(['field', 'value'])
423 for k, v in resp.items():
424 if filter is None or filter in k:
425 table.add_row([k, json.dumps(v, indent=2)])
426 table.align = 'l'
427 print(table)
428
429
430 @cli.command(name='vnf-monitoring-show')
431 @click.argument('vnf_name')
432 @click.pass_context
433 def vnf_monitoring_show(ctx, vnf_name):
434 try:
435 check_client_version(ctx.obj, ctx.command.name, 'v1')
436 resp = ctx.obj.vnf.get_monitoring(vnf_name)
437 except ClientException as inst:
438 print(inst.message)
439 exit(1)
440
441 table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
442 if resp is not None:
443 for monitor in resp:
444 table.add_row(
445 [vnf_name,
446 monitor['name'],
447 monitor['value-integer'],
448 monitor['units']])
449 table.align = 'l'
450 print(table)
451
452
453 @cli.command(name='ns-monitoring-show')
454 @click.argument('ns_name')
455 @click.pass_context
456 def ns_monitoring_show(ctx, ns_name):
457 try:
458 check_client_version(ctx.obj, ctx.command.name, 'v1')
459 resp = ctx.obj.ns.get_monitoring(ns_name)
460 except ClientException as inst:
461 print(inst.message)
462 exit(1)
463
464 table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
465 for key, val in resp.items():
466 for monitor in val:
467 table.add_row(
468 [key,
469 monitor['name'],
470 monitor['value-integer'],
471 monitor['units']])
472 table.align = 'l'
473 print(table)
474
475 @cli.command(name='ns-op-show', short_help='shows the info of an operation')
476 @click.argument('id')
477 @click.option('--filter', default=None)
478 @click.pass_context
479 def ns_op_show(ctx, id, filter):
480 '''shows the detailed info of an operation
481
482 ID: operation identifier
483 '''
484 try:
485 check_client_version(ctx.obj, ctx.command.name)
486 op_info = ctx.obj.ns.get_op(id)
487 except ClientException as inst:
488 print(inst.message)
489 exit(1)
490
491 table = PrettyTable(['field', 'value'])
492 for k, v in op_info.items():
493 if filter is None or filter in k:
494 table.add_row([k, json.dumps(v, indent=2)])
495 table.align = 'l'
496 print(table)
497
498
499 ####################
500 # CREATE operations
501 ####################
502
503 def nsd_create(ctx, filename, overwrite):
504 try:
505 check_client_version(ctx.obj, ctx.command.name)
506 ctx.obj.nsd.create(filename, overwrite)
507 except ClientException as inst:
508 print(inst.message)
509 exit(1)
510
511
512 @cli.command(name='nsd-create', short_help='creates a new NSD/NSpkg')
513 @click.argument('filename')
514 @click.option('--overwrite', default=None,
515 help='overwrites some fields in NSD')
516 @click.pass_context
517 def nsd_create1(ctx, filename, overwrite):
518 '''creates a new NSD/NSpkg
519
520 FILENAME: NSD yaml file or NSpkg tar.gz file
521 '''
522 nsd_create(ctx, filename, overwrite)
523
524
525 @cli.command(name='nspkg-create', short_help='creates a new NSD/NSpkg')
526 @click.argument('filename')
527 @click.option('--overwrite', default=None,
528 help='overwrites some fields in NSD')
529 @click.pass_context
530 def nsd_create2(ctx, filename, overwrite):
531 '''creates a new NSD/NSpkg
532
533 FILENAME: NSD yaml file or NSpkg tar.gz file
534 '''
535 nsd_create(ctx, filename, overwrite)
536
537
538 def vnfd_create(ctx, filename, overwrite):
539 try:
540 check_client_version(ctx.obj, ctx.command.name)
541 ctx.obj.vnfd.create(filename, overwrite)
542 except ClientException as inst:
543 print(inst.message)
544 exit(1)
545
546
547 @cli.command(name='vnfd-create', short_help='creates a new VNFD/VNFpkg')
548 @click.argument('filename')
549 @click.option('--overwrite', default=None,
550 help='overwrites some fields in VNFD')
551 @click.pass_context
552 def vnfd_create1(ctx, filename, overwrite):
553 '''creates a new VNFD/VNFpkg
554
555 FILENAME: VNFD yaml file or VNFpkg tar.gz file
556 '''
557 vnfd_create(ctx, filename, overwrite)
558
559
560 @cli.command(name='vnfpkg-create', short_help='creates a new VNFD/VNFpkg')
561 @click.argument('filename')
562 @click.option('--overwrite', default=None,
563 help='overwrites some fields in VNFD')
564 @click.pass_context
565 def vnfd_create2(ctx, filename, overwrite):
566 '''creates a new VNFD/VNFpkg
567
568 FILENAME: VNFD yaml file or VNFpkg tar.gz file
569 '''
570 vnfd_create(ctx, filename, overwrite)
571
572
573 @cli.command(name='ns-create')
574 @click.option('--ns_name',
575 prompt=True)
576 @click.option('--nsd_name',
577 prompt=True)
578 @click.option('--vim_account',
579 prompt=True)
580 @click.option('--admin_status',
581 default='ENABLED',
582 help='administration status')
583 @click.option('--ssh_keys',
584 default=None,
585 help='comma separated list of keys to inject to vnfs')
586 @click.option('--config',
587 default=None,
588 help='ns specific yaml configuration:\nvnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
589 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]')
590 @click.pass_context
591 def ns_create(ctx,
592 nsd_name,
593 ns_name,
594 vim_account,
595 admin_status,
596 ssh_keys,
597 config):
598 '''creates a new NS instance'''
599 try:
600 # if config:
601 # check_client_version(ctx.obj, '--config', 'v1')
602 ctx.obj.ns.create(
603 nsd_name,
604 ns_name,
605 config=config,
606 ssh_keys=ssh_keys,
607 account=vim_account)
608 except ClientException as inst:
609 print(inst.message)
610 exit(1)
611
612
613 ####################
614 # UPDATE operations
615 ####################
616
617 def nsd_update(ctx, name, content):
618 try:
619 check_client_version(ctx.obj, ctx.command.name)
620 ctx.obj.nsd.update(name, content)
621 except ClientException as inst:
622 print(inst.message)
623 exit(1)
624
625 @cli.command(name='nsd-update', short_help='updates a NSD/NSpkg')
626 @click.argument('name')
627 @click.option('--content', default=None,
628 help='filename with the NSD/NSpkg replacing the current one')
629 @click.pass_context
630 def nsd_update1(ctx, name, content):
631 '''updates a NSD/NSpkg
632
633 NAME: name or ID of the NSD/NSpkg
634 '''
635 nsd_update(ctx, name, content)
636
637
638 @cli.command(name='nspkg-update', short_help='updates a NSD/NSpkg')
639 @click.argument('name')
640 @click.option('--content', default=None,
641 help='filename with the NSD/NSpkg replacing the current one')
642 @click.pass_context
643 def nsd_update2(ctx, name, content):
644 '''updates a NSD/NSpkg
645
646 NAME: name or ID of the NSD/NSpkg
647 '''
648 nsd_update(ctx, name, content)
649
650
651 def vnfd_update(ctx, name, content):
652 try:
653 check_client_version(ctx.obj, ctx.command.name)
654 ctx.obj.vnfd.update(name, content)
655 except ClientException as inst:
656 print(inst.message)
657 exit(1)
658
659
660 @cli.command(name='vnfd-update', short_help='updates a new VNFD/VNFpkg')
661 @click.argument('name')
662 @click.option('--content', default=None,
663 help='filename with the VNFD/VNFpkg replacing the current one')
664 @click.pass_context
665 def vnfd_update1(ctx, name, content):
666 '''updates a VNFD/VNFpkg
667
668 NAME: name or ID of the VNFD/VNFpkg
669 '''
670 vnfd_update(ctx, name, content)
671
672
673 @cli.command(name='vnfpkg-update', short_help='updates a VNFD/VNFpkg')
674 @click.argument('name')
675 @click.option('--content', default=None,
676 help='filename with the VNFD/VNFpkg replacing the current one')
677 @click.pass_context
678 def vnfd_update2(ctx, name, content):
679 '''updates a VNFD/VNFpkg
680
681 NAME: VNFD yaml file or VNFpkg tar.gz file
682 '''
683 vnfd_update(ctx, name, content)
684
685
686 ####################
687 # DELETE operations
688 ####################
689
690 def nsd_delete(ctx, name):
691 try:
692 ctx.obj.nsd.delete(name)
693 except ClientException as inst:
694 print(inst.message)
695 exit(1)
696
697
698 @cli.command(name='nsd-delete', short_help='deletes a NSD/NSpkg')
699 @click.argument('name')
700 @click.pass_context
701 def nsd_delete1(ctx, name):
702 '''deletes a NSD/NSpkg
703
704 NAME: name or ID of the NSD/NSpkg to be deleted
705 '''
706 nsd_delete(ctx, name)
707
708
709 @cli.command(name='nspkg-delete', short_help='deletes a NSD/NSpkg')
710 @click.argument('name')
711 @click.pass_context
712 def nsd_delete2(ctx, name):
713 '''deletes a NSD/NSpkg
714
715 NAME: name or ID of the NSD/NSpkg to be deleted
716 '''
717 nsd_delete(ctx, name)
718
719
720 def vnfd_delete(ctx, name):
721 try:
722 ctx.obj.vnfd.delete(name)
723 except ClientException as inst:
724 print(inst.message)
725 exit(1)
726
727
728 @cli.command(name='vnfd-delete', short_help='deletes a VNFD/VNFpkg')
729 @click.argument('name')
730 @click.pass_context
731 def vnfd_delete1(ctx, name):
732 '''deletes a VNFD/VNFpkg
733
734 NAME: name or ID of the VNFD/VNFpkg to be deleted
735 '''
736 vnfd_delete(ctx, name)
737
738
739 @cli.command(name='vnfpkg-delete', short_help='deletes a VNFD/VNFpkg')
740 @click.argument('name')
741 @click.pass_context
742 def vnfd_delete2(ctx, name):
743 '''deletes a VNFD/VNFpkg
744
745 NAME: name or ID of the VNFD/VNFpkg to be deleted
746 '''
747 vnfd_delete(ctx, name)
748
749
750 @cli.command(name='ns-delete', short_help='deletes a NS instance')
751 @click.argument('name')
752 @click.pass_context
753 def ns_delete(ctx, name):
754 '''deletes a NS instance
755
756 NAME: name or ID of the NS instance to be deleted
757 '''
758 try:
759 ctx.obj.ns.delete(name)
760 except ClientException as inst:
761 print(inst.message)
762 exit(1)
763
764
765 ####################
766 # VIM operations
767 ####################
768
769 @cli.command(name='vim-create')
770 @click.option('--name',
771 prompt=True,
772 help='Name to create datacenter')
773 @click.option('--user',
774 prompt=True,
775 help='VIM username')
776 @click.option('--password',
777 prompt=True,
778 hide_input=True,
779 confirmation_prompt=True,
780 help='VIM password')
781 @click.option('--auth_url',
782 prompt=True,
783 help='VIM url')
784 @click.option('--tenant',
785 prompt=True,
786 help='VIM tenant name')
787 @click.option('--config',
788 default=None,
789 help='VIM specific config parameters')
790 @click.option('--account_type',
791 default='openstack',
792 help='VIM type')
793 @click.option('--description',
794 default='no description',
795 help='human readable description')
796 @click.pass_context
797 def vim_create(ctx,
798 name,
799 user,
800 password,
801 auth_url,
802 tenant,
803 config,
804 account_type,
805 description):
806 '''creates a new VIM account
807 '''
808 vim = {}
809 vim['vim-username'] = user
810 vim['vim-password'] = password
811 vim['vim-url'] = auth_url
812 vim['vim-tenant-name'] = tenant
813 vim['config'] = config
814 vim['vim-type'] = account_type
815 vim['description'] = description
816 try:
817 ctx.obj.vim.create(name, vim)
818 except ClientException as inst:
819 print(inst.message)
820 exit(1)
821
822
823 @cli.command(name='vim-update', short_help='updates a VIM account')
824 @click.argument('name')
825 @click.option('--newname', default=None, help='New name for the VIM account')
826 @click.option('--user', default=None, help='VIM username')
827 @click.option('--password', default=None, help='VIM password')
828 @click.option('--auth_url', default=None, help='VIM url')
829 @click.option('--tenant', default=None, help='VIM tenant name')
830 @click.option('--config', default=None, help='VIM specific config parameters')
831 @click.option('--account_type', default=None, help='VIM type')
832 @click.option('--description', default=None, help='human readable description')
833 @click.pass_context
834 def vim_update(ctx,
835 name,
836 newname,
837 user,
838 password,
839 auth_url,
840 tenant,
841 config,
842 account_type,
843 description):
844 '''updates a VIM account
845
846 NAME: name or ID of the VIM account
847 '''
848 vim = {}
849 if newname:
850 vim['name'] = newname
851 vim['vim_user'] = user
852 vim['vim_password'] = password
853 vim['vim_url'] = auth_url
854 vim['vim-tenant-name'] = tenant
855 vim['config'] = config
856 vim['vim_type'] = account_type
857 vim['description'] = description
858 try:
859 check_client_version(ctx.obj, ctx.command.name)
860 ctx.obj.vim.update(name, vim)
861 except ClientException as inst:
862 print(inst.message)
863 exit(1)
864
865
866 @cli.command(name='vim-delete')
867 @click.argument('name')
868 @click.pass_context
869 def vim_delete(ctx, name):
870 '''deletes a VIM account
871
872 NAME: name or ID of the VIM account to be deleted
873 '''
874 try:
875 ctx.obj.vim.delete(name)
876 except ClientException as inst:
877 print(inst.message)
878 exit(1)
879
880
881 @cli.command(name='vim-list')
882 @click.option('--ro_update/--no_ro_update',
883 default=False,
884 help='update list from RO')
885 @click.option('--filter', default=None,
886 help='restricts the list to the VIM accounts matching the filter')
887 @click.pass_context
888 def vim_list(ctx, ro_update, filter):
889 '''list all VIM accounts'''
890 if filter:
891 check_client_version(ctx.obj, '--filter')
892 if ro_update:
893 check_client_version(ctx.obj, '--ro_update', 'v1')
894 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
895 if fullclassname == 'osmclient.sol005.client.Client':
896 resp = ctx.obj.vim.list(filter)
897 else:
898 resp = ctx.obj.vim.list(ro_update)
899 table = PrettyTable(['vim name', 'uuid'])
900 for vim in resp:
901 table.add_row([vim['name'], vim['uuid']])
902 table.align = 'l'
903 print(table)
904
905
906 @cli.command(name='vim-show')
907 @click.argument('name')
908 @click.pass_context
909 def vim_show(ctx, name):
910 '''shows the details of a VIM account
911
912 NAME: name or ID of the VIM account
913 '''
914 try:
915 resp = ctx.obj.vim.get(name)
916 if 'vim_password' in resp:
917 resp['vim_password']='********'
918 except ClientException as inst:
919 print(inst.message)
920 exit(1)
921
922 table = PrettyTable(['key', 'attribute'])
923 for k, v in resp.items():
924 table.add_row([k, json.dumps(v, indent=2)])
925 table.align = 'l'
926 print(table)
927
928
929 ####################
930 # Other operations
931 ####################
932
933 @cli.command(name='upload-package')
934 @click.argument('filename')
935 @click.pass_context
936 def upload_package(ctx, filename):
937 '''uploads a VNF package or NS package
938
939 FILENAME: VNF or NS package file (tar.gz)
940 '''
941 try:
942 ctx.obj.package.upload(filename)
943 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
944 if fullclassname != 'osmclient.sol005.client.Client':
945 ctx.obj.package.wait_for_upload(filename)
946 except ClientException as inst:
947 print(inst.message)
948 exit(1)
949
950
951 @cli.command(name='ns-scaling-show')
952 @click.argument('ns_name')
953 @click.pass_context
954 def show_ns_scaling(ctx, ns_name):
955 check_client_version(ctx.obj, ctx.command.name, 'v1')
956 resp = ctx.obj.ns.list()
957
958 table = PrettyTable(
959 ['group-name',
960 'instance-id',
961 'operational status',
962 'create-time',
963 'vnfr ids'])
964
965 for ns in resp:
966 if ns_name == ns['name']:
967 nsopdata = ctx.obj.ns.get_opdata(ns['id'])
968 scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
969 for record in scaling_records:
970 if 'instance' in record:
971 instances = record['instance']
972 for inst in instances:
973 table.add_row(
974 [record['scaling-group-name-ref'],
975 inst['instance-id'],
976 inst['op-status'],
977 time.strftime('%Y-%m-%d %H:%M:%S',
978 time.localtime(
979 inst['create-time'])),
980 inst['vnfrs']])
981 table.align = 'l'
982 print(table)
983
984
985 @cli.command(name='ns-scale')
986 @click.argument('ns_name')
987 @click.option('--ns_scale_group', prompt=True)
988 @click.option('--index', prompt=True)
989 @click.pass_context
990 def ns_scale(ctx, ns_name, ns_scale_group, index):
991 check_client_version(ctx.obj, ctx.command.name, 'v1')
992 ctx.obj.ns.scale(ns_name, ns_scale_group, index)
993
994
995 @cli.command(name='config-agent-list')
996 @click.pass_context
997 def config_agent_list(ctx):
998 check_client_version(ctx.obj, ctx.command.name, 'v1')
999 table = PrettyTable(['name', 'account-type', 'details'])
1000 for account in ctx.obj.vca.list():
1001 table.add_row(
1002 [account['name'],
1003 account['account-type'],
1004 account['juju']])
1005 table.align = 'l'
1006 print(table)
1007
1008
1009 @cli.command(name='config-agent-delete')
1010 @click.argument('name')
1011 @click.pass_context
1012 def config_agent_delete(ctx, name):
1013 try:
1014 check_client_version(ctx.obj, ctx.command.name, 'v1')
1015 ctx.obj.vca.delete(name)
1016 except ClientException as inst:
1017 print(inst.message)
1018 exit(1)
1019
1020
1021 @cli.command(name='config-agent-add')
1022 @click.option('--name',
1023 prompt=True)
1024 @click.option('--account_type',
1025 prompt=True)
1026 @click.option('--server',
1027 prompt=True)
1028 @click.option('--user',
1029 prompt=True)
1030 @click.option('--secret',
1031 prompt=True,
1032 hide_input=True,
1033 confirmation_prompt=True)
1034 @click.pass_context
1035 def config_agent_add(ctx, name, account_type, server, user, secret):
1036 try:
1037 check_client_version(ctx.obj, ctx.command.name, 'v1')
1038 ctx.obj.vca.create(name, account_type, server, user, secret)
1039 except ClientException as inst:
1040 print(inst.message)
1041 exit(1)
1042
1043 @cli.command(name='ro-dump')
1044 @click.pass_context
1045 def ro_dump(ctx):
1046 check_client_version(ctx.obj, ctx.command.name, 'v1')
1047 resp = ctx.obj.vim.get_resource_orchestrator()
1048 table = PrettyTable(['key', 'attribute'])
1049 for k, v in resp.items():
1050 table.add_row([k, json.dumps(v, indent=2)])
1051 table.align = 'l'
1052 print(table)
1053
1054
1055 @cli.command(name='vcs-list')
1056 @click.pass_context
1057 def vcs_list(ctx):
1058 check_client_version(ctx.obj, ctx.command.name, 'v1')
1059 resp = ctx.obj.utils.get_vcs_info()
1060 table = PrettyTable(['component name', 'state'])
1061 for component in resp:
1062 table.add_row([component['component_name'], component['state']])
1063 table.align = 'l'
1064 print(table)
1065
1066
1067 @cli.command(name='ns-action')
1068 @click.argument('ns_name')
1069 @click.option('--vnf_name', default=None)
1070 @click.option('--action_name', prompt=True)
1071 @click.option('--params', prompt=True)
1072 @click.pass_context
1073 def ns_action(ctx,
1074 ns_name,
1075 vnf_name,
1076 params):
1077 '''executes an action/primitive over a NS instance
1078
1079 NS_NAME: name or ID of the NS instance
1080 '''
1081 try:
1082 check_client_version(ctx.obj, ctx.command.name)
1083 op_data={}
1084 if vnf_name:
1085 op_data['vnf_member_index'] = vnf_name
1086 op_data['primitive'] = action_name
1087 op_data['primitive_params'] = yaml.load(params)
1088 ctx.obj.ns.exec_op(ns_name, op_name='action', op_data=op_data)
1089
1090 except ClientException as inst:
1091 print(inst.message)
1092 exit(1)
1093
1094
1095 if __name__ == '__main__':
1096 cli()