osm.py: fix when guessing the fullclassname in check_client_version
[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 option')
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 for ns in resp:
117 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
118 if fullclassname == 'osmclient.sol005.client.Client':
119 nsr = ns
120 else:
121 nsopdata = ctx.obj.ns.get_opdata(ns['id'])
122 nsr = nsopdata['nsr:nsr']
123 opstatus = nsr['operational-status'] if 'operational-status' in nsr else 'Not found'
124 configstatus = nsr['config-status'] if 'config-status' in nsr else 'Not found'
125 if configstatus == "config_not_needed":
126 configstatus = "configured (no charms)"
127 table.add_row(
128 [nsr['name'],
129 nsr['_id'],
130 opstatus,
131 configstatus])
132 table.align = 'l'
133 print(table)
134
135
136 def nsd_list(ctx, filter):
137 if filter:
138 check_client_version(ctx.obj, '--filter')
139 resp = ctx.obj.nsd.list(filter)
140 else:
141 resp = ctx.obj.nsd.list()
142 #print yaml.safe_dump(resp)
143 table = PrettyTable(['nsd name', 'id'])
144 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
145 if fullclassname == 'osmclient.sol005.client.Client':
146 for ns in resp:
147 name = ns['name'] if 'name' in ns else '-'
148 table.add_row([name, ns['_id']])
149 else:
150 for ns in resp:
151 table.add_row([ns['name'], ns['id']])
152 table.align = 'l'
153 print(table)
154
155
156 @cli.command(name='nsd-list')
157 @click.option('--filter', default=None,
158 help='restricts the list to the NSD/NSpkg matching the filter')
159 @click.pass_context
160 def nsd_list1(ctx, filter):
161 '''list all NSD/NSpkg in the system'''
162 nsd_list(ctx,filter)
163
164
165 @cli.command(name='nspkg-list')
166 @click.option('--filter', default=None,
167 help='restricts the list to the NSD/NSpkg matching the filter')
168 @click.pass_context
169 def nsd_list2(ctx, filter):
170 '''list all NSD/NSpkg in the system'''
171 nsd_list(ctx,filter)
172
173
174 def vnfd_list(ctx, filter):
175 if filter:
176 check_client_version(ctx.obj, '--filter')
177 resp = ctx.obj.vnfd.list(filter)
178 else:
179 resp = ctx.obj.vnfd.list()
180 #print yaml.safe_dump(resp)
181 table = PrettyTable(['vnfd name', 'id'])
182 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
183 if fullclassname == 'osmclient.sol005.client.Client':
184 for vnfd in resp:
185 name = vnfd['name'] if 'name' in vnfd else '-'
186 table.add_row([name, vnfd['_id']])
187 else:
188 for vnfd in resp:
189 table.add_row([vnfd['name'], vnfd['id']])
190 table.align = 'l'
191 print(table)
192
193
194 @cli.command(name='vnfd-list')
195 @click.option('--filter', default=None,
196 help='restricts the list to the VNFD/VNFpkg matching the filter')
197 @click.pass_context
198 def vnfd_list1(ctx, filter):
199 '''list all VNFD/VNFpkg in the system'''
200 vnfd_list(ctx,filter)
201
202
203 @cli.command(name='vnfpkg-list')
204 @click.option('--filter', default=None,
205 help='restricts the list to the VNFD/VNFpkg matching the filter')
206 @click.pass_context
207 def vnfd_list2(ctx, filter):
208 '''list all VNFD/VNFpkg in the system'''
209 vnfd_list(ctx,filter)
210
211
212 @cli.command(name='vnf-list')
213 @click.pass_context
214 def vnf_list(ctx):
215 ''' list all VNF instances'''
216 resp = ctx.obj.vnf.list()
217 table = PrettyTable(
218 ['vnf name',
219 'id',
220 'operational status',
221 'config status'])
222 for vnfr in resp:
223 if 'mgmt-interface' not in vnfr:
224 vnfr['mgmt-interface'] = {}
225 vnfr['mgmt-interface']['ip-address'] = None
226 table.add_row(
227 [vnfr['name'],
228 vnfr['id'],
229 vnfr['operational-status'],
230 vnfr['config-status']])
231 table.align = 'l'
232 print(table)
233
234
235 ####################
236 # SHOW operations
237 ####################
238
239 def nsd_show(ctx, name, literal):
240 try:
241 resp = ctx.obj.nsd.get(name)
242 #resp = ctx.obj.nsd.get_individual(name)
243 except ClientException as inst:
244 print(inst.message)
245 exit(1)
246
247 if literal:
248 print yaml.safe_dump(resp)
249 return
250
251 table = PrettyTable(['field', 'value'])
252 for k, v in resp.items():
253 table.add_row([k, json.dumps(v, indent=2)])
254 table.align = 'l'
255 print(table)
256
257
258 @cli.command(name='nsd-show', short_help='shows the content of a NSD')
259 @click.option('--literal', is_flag=True,
260 help='print literally, no pretty table')
261 @click.argument('name')
262 @click.pass_context
263 def nsd_show1(ctx, name, literal):
264 '''shows the content of a NSD
265
266 NAME: name or ID of the NSD/NSpkg
267 '''
268 nsd_show(ctx, name, literal)
269
270
271 @cli.command(name='nspkg-show', short_help='shows the content of a NSD')
272 @click.option('--literal', is_flag=True,
273 help='print literally, no pretty table')
274 @click.argument('name')
275 @click.pass_context
276 def nsd_show2(ctx, name, literal):
277 '''shows the content of a NSD
278
279 NAME: name or ID of the NSD/NSpkg
280 '''
281 nsd_show(ctx, name, literal)
282
283
284 def vnfd_show(ctx, name, literal):
285 try:
286 resp = ctx.obj.vnfd.get(name)
287 #resp = ctx.obj.vnfd.get_individual(name)
288 except ClientException as inst:
289 print(inst.message)
290 exit(1)
291
292 if literal:
293 print yaml.safe_dump(resp)
294 return
295
296 table = PrettyTable(['field', 'value'])
297 for k, v in resp.items():
298 table.add_row([k, json.dumps(v, indent=2)])
299 table.align = 'l'
300 print(table)
301
302
303 @cli.command(name='vnfd-show', short_help='shows the content of a VNFD')
304 @click.option('--literal', is_flag=True,
305 help='print literally, no pretty table')
306 @click.argument('name')
307 @click.pass_context
308 def vnfd_show1(ctx, name, literal):
309 '''shows the content of a VNFD
310
311 NAME: name or ID of the VNFD/VNFpkg
312 '''
313 vnfd_show(ctx, name, literal)
314
315
316 @cli.command(name='vnfpkg-show', short_help='shows the content of a VNFD')
317 @click.option('--literal', is_flag=True,
318 help='print literally, no pretty table')
319 @click.argument('name')
320 @click.pass_context
321 def vnfd_show2(ctx, name, literal):
322 '''shows the content of a VNFD
323
324 NAME: name or ID of the VNFD/VNFpkg
325 '''
326 vnfd_show(ctx, name, literal)
327
328
329 @cli.command(name='ns-show', short_help='shows the info of a NS instance')
330 @click.argument('name')
331 @click.option('--literal', is_flag=True,
332 help='print literally, no pretty table')
333 @click.option('--filter', default=None)
334 @click.pass_context
335 def ns_show(ctx, name, literal, filter):
336 '''shows the info of a NS instance
337
338 NAME: name or ID of the NS instance
339 '''
340 try:
341 ns = ctx.obj.ns.get(name)
342 except ClientException as inst:
343 print(inst.message)
344 exit(1)
345
346 if literal:
347 print yaml.safe_dump(resp)
348 return
349
350 table = PrettyTable(['field', 'value'])
351
352 for k, v in ns.items():
353 if filter is None or filter in k:
354 table.add_row([k, json.dumps(v, indent=2)])
355
356 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
357 if fullclassname != 'osmclient.sol005.client.Client':
358 nsopdata = ctx.obj.ns.get_opdata(ns['id'])
359 nsr_optdata = nsopdata['nsr:nsr']
360 for k, v in nsr_optdata.items():
361 if filter is None or filter in k:
362 table.add_row([k, json.dumps(v, indent=2)])
363 table.align = 'l'
364 print(table)
365
366
367 @cli.command(name='vnf-show', short_help='shows the info of a VNF instance')
368 @click.argument('name')
369 @click.option('--literal', is_flag=True,
370 help='print literally, no pretty table')
371 @click.option('--filter', default=None)
372 @click.pass_context
373 def vnf_show(ctx, name, literal, filter):
374 '''shows the info of a VNF instance
375
376 NAME: name or ID of the VNF instance
377 '''
378 try:
379 check_client_version(ctx.obj, ctx.command.name, 'v1')
380 resp = ctx.obj.vnf.get(name)
381 except ClientException as inst:
382 print(inst.message)
383 exit(1)
384
385 if literal:
386 print yaml.safe_dump(resp)
387 return
388
389 table = PrettyTable(['field', 'value'])
390 for k, v in resp.items():
391 if filter is None or filter in k:
392 table.add_row([k, json.dumps(v, indent=2)])
393 table.align = 'l'
394 print(table)
395
396
397 @cli.command(name='vnf-monitoring-show')
398 @click.argument('vnf_name')
399 @click.pass_context
400 def vnf_monitoring_show(ctx, vnf_name):
401 try:
402 check_client_version(ctx.obj, ctx.command.name, 'v1')
403 resp = ctx.obj.vnf.get_monitoring(vnf_name)
404 except ClientException as inst:
405 print(inst.message)
406 exit(1)
407
408 table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
409 if resp is not None:
410 for monitor in resp:
411 table.add_row(
412 [vnf_name,
413 monitor['name'],
414 monitor['value-integer'],
415 monitor['units']])
416 table.align = 'l'
417 print(table)
418
419
420 @cli.command(name='ns-monitoring-show')
421 @click.argument('ns_name')
422 @click.pass_context
423 def ns_monitoring_show(ctx, ns_name):
424 try:
425 check_client_version(ctx.obj, ctx.command.name, 'v1')
426 resp = ctx.obj.ns.get_monitoring(ns_name)
427 except ClientException as inst:
428 print(inst.message)
429 exit(1)
430
431 table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
432 for key, val in resp.items():
433 for monitor in val:
434 table.add_row(
435 [key,
436 monitor['name'],
437 monitor['value-integer'],
438 monitor['units']])
439 table.align = 'l'
440 print(table)
441
442
443 ####################
444 # CREATE operations
445 ####################
446
447 def nsd_create(ctx, filename, overwrite):
448 try:
449 check_client_version(ctx.obj, ctx.command.name)
450 ctx.obj.nsd.create(filename, overwrite)
451 except ClientException as inst:
452 print(inst.message)
453 exit(1)
454
455
456 @cli.command(name='nsd-create', short_help='creates a new NSD/NSpkg')
457 @click.argument('filename')
458 @click.option('--overwrite', default=None,
459 help='overwrites some fields in NSD')
460 @click.pass_context
461 def nsd_create1(ctx, filename, overwrite):
462 '''creates a new NSD/NSpkg
463
464 FILENAME: NSD yaml file or NSpkg tar.gz file
465 '''
466 nsd_create(ctx, filename, overwrite)
467
468
469 @cli.command(name='nspkg-create', short_help='creates a new NSD/NSpkg')
470 @click.argument('filename')
471 @click.option('--overwrite', default=None,
472 help='overwrites some fields in NSD')
473 @click.pass_context
474 def nsd_create2(ctx, filename, overwrite):
475 '''creates a new NSD/NSpkg
476
477 FILENAME: NSD yaml file or NSpkg tar.gz file
478 '''
479 nsd_create(ctx, filename, overwrite)
480
481
482 def vnfd_create(ctx, filename, overwrite):
483 try:
484 check_client_version(ctx.obj, ctx.command.name)
485 ctx.obj.vnfd.create(filename, overwrite)
486 except ClientException as inst:
487 print(inst.message)
488 exit(1)
489
490
491 @cli.command(name='vnfd-create', short_help='creates a new VNFD/VNFpkg')
492 @click.argument('filename')
493 @click.option('--overwrite', default=None,
494 help='overwrites some fields in VNFD')
495 @click.pass_context
496 def vnfd_create1(ctx, filename, overwrite):
497 '''creates a new VNFD/VNFpkg
498
499 FILENAME: VNFD yaml file or VNFpkg tar.gz file
500 '''
501 vnfd_create(ctx, filename, overwrite)
502
503
504 @cli.command(name='vnfpkg-create', short_help='creates a new VNFD/VNFpkg')
505 @click.argument('filename')
506 @click.option('--overwrite', default=None,
507 help='overwrites some fields in VNFD')
508 @click.pass_context
509 def vnfd_create2(ctx, filename, overwrite):
510 '''creates a new VNFD/VNFpkg
511
512 FILENAME: VNFD yaml file or VNFpkg tar.gz file
513 '''
514 vnfd_create(ctx, filename, overwrite)
515
516
517 @cli.command(name='ns-create')
518 @click.option('--ns_name',
519 prompt=True)
520 @click.option('--nsd_name',
521 prompt=True)
522 @click.option('--vim_account',
523 prompt=True)
524 @click.option('--admin_status',
525 default='ENABLED',
526 help='administration status')
527 @click.option('--ssh_keys',
528 default=None,
529 help='comma separated list of keys to inject to vnfs')
530 @click.option('--config',
531 default=None,
532 help='ns specific yaml configuration')
533 @click.pass_context
534 def ns_create(ctx,
535 nsd_name,
536 ns_name,
537 vim_account,
538 admin_status,
539 ssh_keys,
540 config):
541 '''creates a new NS instance'''
542 try:
543 if config:
544 check_client_version(ctx.obj, '--config', 'v1')
545 ctx.obj.ns.create(
546 nsd_name,
547 ns_name,
548 config=config,
549 ssh_keys=ssh_keys,
550 account=vim_account)
551 except ClientException as inst:
552 print(inst.message)
553 exit(1)
554
555
556 ####################
557 # UPDATE operations
558 ####################
559
560 def nsd_update(ctx, name, content):
561 try:
562 check_client_version(ctx.obj, ctx.command.name)
563 ctx.obj.nsd.update(name, content)
564 except ClientException as inst:
565 print(inst.message)
566 exit(1)
567
568 @cli.command(name='nsd-update', short_help='updates a NSD/NSpkg')
569 @click.argument('name')
570 @click.option('--content', default=None,
571 help='filename with the NSD/NSpkg replacing the current one')
572 @click.pass_context
573 def nsd_update1(ctx, name, content):
574 '''updates a NSD/NSpkg
575
576 NAME: name or ID of the NSD/NSpkg
577 '''
578 nsd_update(ctx, name, content)
579
580
581 @cli.command(name='nspkg-update', short_help='updates a NSD/NSpkg')
582 @click.argument('name')
583 @click.option('--content', default=None,
584 help='filename with the NSD/NSpkg replacing the current one')
585 @click.pass_context
586 def nsd_update2(ctx, name, content):
587 '''updates a NSD/NSpkg
588
589 NAME: name or ID of the NSD/NSpkg
590 '''
591 nsd_update(ctx, name, content)
592
593
594 def vnfd_update(ctx, name, content):
595 try:
596 check_client_version(ctx.obj, ctx.command.name)
597 ctx.obj.vnfd.update(name, content)
598 except ClientException as inst:
599 print(inst.message)
600 exit(1)
601
602
603 @cli.command(name='vnfd-update', short_help='updates a new VNFD/VNFpkg')
604 @click.argument('name')
605 @click.option('--content', default=None,
606 help='filename with the VNFD/VNFpkg replacing the current one')
607 @click.pass_context
608 def vnfd_update1(ctx, name, content):
609 '''updates a VNFD/VNFpkg
610
611 NAME: name or ID of the VNFD/VNFpkg
612 '''
613 vnfd_update(ctx, name, content)
614
615
616 @cli.command(name='vnfpkg-update', short_help='updates a VNFD/VNFpkg')
617 @click.argument('name')
618 @click.option('--content', default=None,
619 help='filename with the VNFD/VNFpkg replacing the current one')
620 @click.pass_context
621 def vnfd_update2(ctx, name, content):
622 '''updates a VNFD/VNFpkg
623
624 NAME: VNFD yaml file or VNFpkg tar.gz file
625 '''
626 vnfd_update(ctx, name, content)
627
628
629 ####################
630 # DELETE operations
631 ####################
632
633 def nsd_delete(ctx, name):
634 try:
635 ctx.obj.nsd.delete(name)
636 except ClientException as inst:
637 print(inst.message)
638 exit(1)
639
640
641 @cli.command(name='nsd-delete', short_help='deletes a NSD/NSpkg')
642 @click.argument('name')
643 @click.pass_context
644 def nsd_delete1(ctx, name):
645 '''deletes a NSD/NSpkg
646
647 NAME: name or ID of the NSD/NSpkg to be deleted
648 '''
649 nsd_delete(ctx, name)
650
651
652 @cli.command(name='nspkg-delete', short_help='deletes a NSD/NSpkg')
653 @click.argument('name')
654 @click.pass_context
655 def nsd_delete2(ctx, name):
656 '''deletes a NSD/NSpkg
657
658 NAME: name or ID of the NSD/NSpkg to be deleted
659 '''
660 nsd_delete(ctx, name)
661
662
663 def vnfd_delete(ctx, name):
664 try:
665 ctx.obj.vnfd.delete(name)
666 except ClientException as inst:
667 print(inst.message)
668 exit(1)
669
670
671 @cli.command(name='vnfd-delete', short_help='deletes a VNFD/VNFpkg')
672 @click.argument('name')
673 @click.pass_context
674 def vnfd_delete1(ctx, name):
675 '''deletes a VNFD/VNFpkg
676
677 NAME: name or ID of the VNFD/VNFpkg to be deleted
678 '''
679 vnfd_delete(ctx, name)
680
681
682 @cli.command(name='vnfpkg-delete', short_help='deletes a VNFD/VNFpkg')
683 @click.argument('name')
684 @click.pass_context
685 def vnfd_delete2(ctx, name):
686 '''deletes a VNFD/VNFpkg
687
688 NAME: name or ID of the VNFD/VNFpkg to be deleted
689 '''
690 vnfd_delete(ctx, name)
691
692
693 @cli.command(name='ns-delete', short_help='deletes a NS instance')
694 @click.argument('name')
695 @click.pass_context
696 def ns_delete(ctx, name):
697 '''deletes a NS instance
698
699 NAME: name or ID of the NS instance to be deleted
700 '''
701 try:
702 ctx.obj.ns.delete(name)
703 except ClientException as inst:
704 print(inst.message)
705 exit(1)
706
707
708 ####################
709 # VIM operations
710 ####################
711
712 @cli.command(name='vim-create')
713 @click.option('--name',
714 prompt=True,
715 help='Name to create datacenter')
716 @click.option('--user',
717 prompt=True,
718 help='VIM username')
719 @click.option('--password',
720 prompt=True,
721 hide_input=True,
722 confirmation_prompt=True,
723 help='VIM password')
724 @click.option('--auth_url',
725 prompt=True,
726 help='VIM url')
727 @click.option('--tenant',
728 prompt=True,
729 help='VIM tenant name')
730 @click.option('--config',
731 default=None,
732 help='VIM specific config parameters')
733 @click.option('--account_type',
734 default='openstack',
735 help='VIM type')
736 @click.option('--description',
737 default='no description',
738 help='human readable description')
739 @click.pass_context
740 def vim_create(ctx,
741 name,
742 user,
743 password,
744 auth_url,
745 tenant,
746 config,
747 account_type,
748 description):
749 '''creates a new VIM account
750 '''
751 vim = {}
752 vim['vim-username'] = user
753 vim['vim-password'] = password
754 vim['vim-url'] = auth_url
755 vim['vim-tenant-name'] = tenant
756 vim['config'] = config
757 vim['vim-type'] = account_type
758 vim['description'] = description
759 try:
760 ctx.obj.vim.create(name, vim)
761 except ClientException as inst:
762 print(inst.message)
763 exit(1)
764
765
766 @cli.command(name='vim-update', short_help='updates a VIM account')
767 @click.argument('name')
768 @click.option('--newname', default=None, help='New name for the VIM account')
769 @click.option('--user', default=None, help='VIM username')
770 @click.option('--password', default=None, help='VIM password')
771 @click.option('--auth_url', default=None, help='VIM url')
772 @click.option('--tenant', default=None, help='VIM tenant name')
773 @click.option('--config', default=None, help='VIM specific config parameters')
774 @click.option('--account_type', default=None, help='VIM type')
775 @click.option('--description', default=None, help='human readable description')
776 @click.pass_context
777 def vim_update(ctx,
778 name,
779 newname,
780 user,
781 password,
782 auth_url,
783 tenant,
784 config,
785 account_type,
786 description):
787 '''updates a VIM account
788
789 NAME: name or ID of the VIM account
790 '''
791 vim = {}
792 if newname:
793 vim['name'] = newname
794 vim['vim_user'] = user
795 vim['vim_password'] = password
796 vim['vim_url'] = auth_url
797 vim['vim-tenant-name'] = tenant
798 vim['config'] = config
799 vim['vim_type'] = account_type
800 vim['description'] = description
801 try:
802 check_client_version(ctx.obj, ctx.command.name)
803 ctx.obj.vim.update(name, vim)
804 except ClientException as inst:
805 print(inst.message)
806 exit(1)
807
808
809 @cli.command(name='vim-delete')
810 @click.argument('name')
811 @click.pass_context
812 def vim_delete(ctx, name):
813 '''deletes a VIM account
814
815 NAME: name or ID of the VIM account to be deleted
816 '''
817 try:
818 ctx.obj.vim.delete(name)
819 except ClientException as inst:
820 print(inst.message)
821 exit(1)
822
823
824 @cli.command(name='vim-list')
825 @click.option('--ro_update/--no_ro_update',
826 default=False,
827 help='update list from RO')
828 @click.option('--filter', default=None,
829 help='restricts the list to the VIM accounts matching the filter')
830 @click.pass_context
831 def vim_list(ctx, ro_update, filter):
832 '''list all VIM accounts'''
833 if filter:
834 check_client_version(ctx.obj, '--filter')
835 if ro_update:
836 check_client_version(ctx.obj, '--ro_update', 'v1')
837 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
838 if fullclassname == 'osmclient.sol005.client.Client':
839 resp = ctx.obj.vim.list(filter)
840 else:
841 resp = ctx.obj.vim.list(ro_update)
842 table = PrettyTable(['vim name', 'uuid'])
843 for vim in resp:
844 table.add_row([vim['name'], vim['uuid']])
845 table.align = 'l'
846 print(table)
847
848
849 @cli.command(name='vim-show')
850 @click.argument('name')
851 @click.pass_context
852 def vim_show(ctx, name):
853 '''shows the details of a VIM account
854
855 NAME: name or ID of the VIM account
856 '''
857 try:
858 resp = ctx.obj.vim.get(name)
859 except ClientException as inst:
860 print(inst.message)
861 exit(1)
862
863 table = PrettyTable(['key', 'attribute'])
864 for k, v in resp.items():
865 table.add_row([k, json.dumps(v, indent=2)])
866 table.align = 'l'
867 print(table)
868
869
870 ####################
871 # Other operations
872 ####################
873
874 @cli.command(name='upload-package')
875 @click.argument('filename')
876 @click.pass_context
877 def upload_package(ctx, filename):
878 '''uploads a VNF package or NS package
879
880 FILENAME: VNF or NS package file (tar.gz)
881 '''
882 try:
883 ctx.obj.package.upload(filename)
884 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
885 if fullclassname != 'osmclient.sol005.client.Client':
886 ctx.obj.package.wait_for_upload(filename)
887 except ClientException as inst:
888 print(inst.message)
889 exit(1)
890
891
892 @cli.command(name='ns-scaling-show')
893 @click.argument('ns_name')
894 @click.pass_context
895 def show_ns_scaling(ctx, ns_name):
896 check_client_version(ctx.obj, ctx.command.name, 'v1')
897 resp = ctx.obj.ns.list()
898
899 table = PrettyTable(
900 ['group-name',
901 'instance-id',
902 'operational status',
903 'create-time',
904 'vnfr ids'])
905
906 for ns in resp:
907 if ns_name == ns['name']:
908 nsopdata = ctx.obj.ns.get_opdata(ns['id'])
909 scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
910 for record in scaling_records:
911 if 'instance' in record:
912 instances = record['instance']
913 for inst in instances:
914 table.add_row(
915 [record['scaling-group-name-ref'],
916 inst['instance-id'],
917 inst['op-status'],
918 time.strftime('%Y-%m-%d %H:%M:%S',
919 time.localtime(
920 inst['create-time'])),
921 inst['vnfrs']])
922 table.align = 'l'
923 print(table)
924
925
926 @cli.command(name='ns-scale')
927 @click.argument('ns_name')
928 @click.option('--ns_scale_group', prompt=True)
929 @click.option('--index', prompt=True)
930 @click.pass_context
931 def ns_scale(ctx, ns_name, ns_scale_group, index):
932 check_client_version(ctx.obj, ctx.command.name, 'v1')
933 ctx.obj.ns.scale(ns_name, ns_scale_group, index)
934
935
936 @cli.command(name='config-agent-list')
937 @click.pass_context
938 def config_agent_list(ctx):
939 check_client_version(ctx.obj, ctx.command.name, 'v1')
940 table = PrettyTable(['name', 'account-type', 'details'])
941 for account in ctx.obj.vca.list():
942 table.add_row(
943 [account['name'],
944 account['account-type'],
945 account['juju']])
946 table.align = 'l'
947 print(table)
948
949
950 @cli.command(name='config-agent-delete')
951 @click.argument('name')
952 @click.pass_context
953 def config_agent_delete(ctx, name):
954 try:
955 check_client_version(ctx.obj, ctx.command.name, 'v1')
956 ctx.obj.vca.delete(name)
957 except ClientException as inst:
958 print(inst.message)
959 exit(1)
960
961
962 @cli.command(name='config-agent-add')
963 @click.option('--name',
964 prompt=True)
965 @click.option('--account_type',
966 prompt=True)
967 @click.option('--server',
968 prompt=True)
969 @click.option('--user',
970 prompt=True)
971 @click.option('--secret',
972 prompt=True,
973 hide_input=True,
974 confirmation_prompt=True)
975 @click.pass_context
976 def config_agent_add(ctx, name, account_type, server, user, secret):
977 try:
978 check_client_version(ctx.obj, ctx.command.name, 'v1')
979 ctx.obj.vca.create(name, account_type, server, user, secret)
980 except ClientException as inst:
981 print(inst.message)
982 exit(1)
983
984 @cli.command(name='ro-dump')
985 @click.pass_context
986 def ro_dump(ctx):
987 check_client_version(ctx.obj, ctx.command.name, 'v1')
988 resp = ctx.obj.vim.get_resource_orchestrator()
989 table = PrettyTable(['key', 'attribute'])
990 for k, v in resp.items():
991 table.add_row([k, json.dumps(v, indent=2)])
992 table.align = 'l'
993 print(table)
994
995
996 @cli.command(name='vcs-list')
997 @click.pass_context
998 def vcs_list(ctx):
999 check_client_version(ctx.obj, ctx.command.name, 'v1')
1000 resp = ctx.obj.utils.get_vcs_info()
1001 table = PrettyTable(['component name', 'state'])
1002 for component in resp:
1003 table.add_row([component['component_name'], component['state']])
1004 table.align = 'l'
1005 print(table)
1006
1007
1008 if __name__ == '__main__':
1009 cli()