sdncontroller mgmt using sol005 api
[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 # SDN controller operations
931 ####################
932
933 @cli.command(name='sdnc-create')
934 @click.option('--name',
935 prompt=True,
936 help='Name to create sdn controller')
937 @click.option('--type',
938 prompt=True,
939 help='SDN controller type')
940 @click.option('--sdn_controller_version',
941 help='SDN controller username')
942 @click.option('--ip_address',
943 prompt=True,
944 help='SDN controller IP address')
945 @click.option('--port',
946 prompt=True,
947 help='SDN controller port')
948 @click.option('--switch_dpid',
949 prompt=True,
950 help='Switch DPID (Openflow Datapath ID)')
951 @click.option('--user',
952 help='SDN controller username')
953 @click.option('--password',
954 hide_input=True,
955 confirmation_prompt=True,
956 help='SDN controller password')
957 #@click.option('--description',
958 # default='no description',
959 # help='human readable description')
960 @click.pass_context
961 def sdnc_create(ctx,
962 name,
963 type,
964 sdn_controller_version,
965 ip_address,
966 port,
967 switch_dpid,
968 user,
969 password):
970 '''creates a new SDN controller
971 '''
972 sdncontroller = {}
973 sdncontroller['name'] = name
974 sdncontroller['type'] = type
975 sdncontroller['ip'] = ip_address
976 sdncontroller['port'] = int(port)
977 sdncontroller['dpid'] = switch_dpid
978 if sdn_controller_version:
979 sdncontroller['version'] = sdn_controller_version
980 if user:
981 sdncontroller['user'] = user
982 if password:
983 sdncontroller['password'] = password
984 # sdncontroller['description'] = description
985 try:
986 check_client_version(ctx.obj, ctx.command.name)
987 ctx.obj.sdnc.create(name, sdncontroller)
988 except ClientException as inst:
989 print(inst.message)
990
991
992 @cli.command(name='sdnc-update', short_help='updates an SDN controller')
993 @click.argument('name')
994 @click.option('--newname', help='New name for the SDN controller')
995 @click.option('--type', help='SDN controller type')
996 @click.option('--sdn_controller_version', help='SDN controller username')
997 @click.option('--ip_address', help='SDN controller IP address')
998 @click.option('--port', help='SDN controller port')
999 @click.option('--switch_dpid', help='Switch DPID (Openflow Datapath ID)')
1000 @click.option('--user', help='SDN controller username')
1001 @click.option('--password', help='SDN controller password')
1002 #@click.option('--description', default=None, help='human readable description')
1003 @click.pass_context
1004 def sdnc_update(ctx,
1005 name,
1006 newname,
1007 type,
1008 sdn_controller_version,
1009 ip_address,
1010 port,
1011 switch_dpid,
1012 user,
1013 password):
1014 '''updates an SDN controller
1015
1016 NAME: name or ID of the SDN controller
1017 '''
1018 sdncontroller = {}
1019 if newname: sdncontroller['name'] = newname
1020 if type: sdncontroller['type'] = type
1021 if ip_address: sdncontroller['ip'] = ip_address
1022 if port: sdncontroller['port'] = int(port)
1023 if switch_dpid: sdncontroller['dpid'] = switch_dpid
1024 # sdncontroller['description'] = description
1025 if sdn_controller_version is not None:
1026 if sdn_controller_version=="":
1027 sdncontroller['version'] = None
1028 else:
1029 sdncontroller['version'] = sdn_controller_version
1030 if user is not None:
1031 if user=="":
1032 sdncontroller['user'] = None
1033 else:
1034 sdncontroller['user'] = user
1035 if password is not None:
1036 if password=="":
1037 sdncontroller['password'] = None
1038 else:
1039 sdncontroller['password'] = user
1040 try:
1041 check_client_version(ctx.obj, ctx.command.name)
1042 ctx.obj.sdnc.update(name, sdncontroller)
1043 except ClientException as inst:
1044 print(inst.message)
1045 exit(1)
1046
1047
1048 @cli.command(name='sdnc-delete')
1049 @click.argument('name')
1050 @click.pass_context
1051 def sdnc_delete(ctx, name):
1052 '''deletes an SDN controller
1053
1054 NAME: name or ID of the SDN controller to be deleted
1055 '''
1056 try:
1057 check_client_version(ctx.obj, ctx.command.name)
1058 ctx.obj.sdnc.delete(name)
1059 except ClientException as inst:
1060 print(inst.message)
1061 exit(1)
1062
1063
1064 @cli.command(name='sdnc-list')
1065 @click.option('--filter', default=None,
1066 help='restricts the list to the SDN controllers matching the filter')
1067 @click.pass_context
1068 def sdnc_list(ctx, filter):
1069 '''list all SDN controllers'''
1070 try:
1071 check_client_version(ctx.obj, ctx.command.name)
1072 resp = ctx.obj.sdnc.list(filter)
1073 except ClientException as inst:
1074 print(inst.message)
1075 exit(1)
1076 table = PrettyTable(['name', 'id'])
1077 for sdnc in resp:
1078 table.add_row([sdnc['name'], sdnc['_id']])
1079 table.align = 'l'
1080 print(table)
1081
1082
1083 @cli.command(name='sdnc-show')
1084 @click.argument('name')
1085 @click.pass_context
1086 def sdnc_show(ctx, name):
1087 '''shows the details of an SDN controller
1088
1089 NAME: name or ID of the SDN controller
1090 '''
1091 try:
1092 check_client_version(ctx.obj, ctx.command.name)
1093 resp = ctx.obj.sdnc.get(name)
1094 except ClientException as inst:
1095 print(inst.message)
1096 exit(1)
1097
1098 table = PrettyTable(['key', 'attribute'])
1099 for k, v in resp.items():
1100 table.add_row([k, json.dumps(v, indent=2)])
1101 table.align = 'l'
1102 print(table)
1103
1104
1105 ####################
1106 # Other operations
1107 ####################
1108
1109 @cli.command(name='upload-package')
1110 @click.argument('filename')
1111 @click.pass_context
1112 def upload_package(ctx, filename):
1113 '''uploads a VNF package or NS package
1114
1115 FILENAME: VNF or NS package file (tar.gz)
1116 '''
1117 try:
1118 ctx.obj.package.upload(filename)
1119 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
1120 if fullclassname != 'osmclient.sol005.client.Client':
1121 ctx.obj.package.wait_for_upload(filename)
1122 except ClientException as inst:
1123 print(inst.message)
1124 exit(1)
1125
1126
1127 @cli.command(name='ns-scaling-show')
1128 @click.argument('ns_name')
1129 @click.pass_context
1130 def show_ns_scaling(ctx, ns_name):
1131 check_client_version(ctx.obj, ctx.command.name, 'v1')
1132 resp = ctx.obj.ns.list()
1133
1134 table = PrettyTable(
1135 ['group-name',
1136 'instance-id',
1137 'operational status',
1138 'create-time',
1139 'vnfr ids'])
1140
1141 for ns in resp:
1142 if ns_name == ns['name']:
1143 nsopdata = ctx.obj.ns.get_opdata(ns['id'])
1144 scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
1145 for record in scaling_records:
1146 if 'instance' in record:
1147 instances = record['instance']
1148 for inst in instances:
1149 table.add_row(
1150 [record['scaling-group-name-ref'],
1151 inst['instance-id'],
1152 inst['op-status'],
1153 time.strftime('%Y-%m-%d %H:%M:%S',
1154 time.localtime(
1155 inst['create-time'])),
1156 inst['vnfrs']])
1157 table.align = 'l'
1158 print(table)
1159
1160
1161 @cli.command(name='ns-scale')
1162 @click.argument('ns_name')
1163 @click.option('--ns_scale_group', prompt=True)
1164 @click.option('--index', prompt=True)
1165 @click.pass_context
1166 def ns_scale(ctx, ns_name, ns_scale_group, index):
1167 check_client_version(ctx.obj, ctx.command.name, 'v1')
1168 ctx.obj.ns.scale(ns_name, ns_scale_group, index)
1169
1170
1171 @cli.command(name='config-agent-list')
1172 @click.pass_context
1173 def config_agent_list(ctx):
1174 check_client_version(ctx.obj, ctx.command.name, 'v1')
1175 table = PrettyTable(['name', 'account-type', 'details'])
1176 for account in ctx.obj.vca.list():
1177 table.add_row(
1178 [account['name'],
1179 account['account-type'],
1180 account['juju']])
1181 table.align = 'l'
1182 print(table)
1183
1184
1185 @cli.command(name='config-agent-delete')
1186 @click.argument('name')
1187 @click.pass_context
1188 def config_agent_delete(ctx, name):
1189 try:
1190 check_client_version(ctx.obj, ctx.command.name, 'v1')
1191 ctx.obj.vca.delete(name)
1192 except ClientException as inst:
1193 print(inst.message)
1194 exit(1)
1195
1196
1197 @cli.command(name='config-agent-add')
1198 @click.option('--name',
1199 prompt=True)
1200 @click.option('--account_type',
1201 prompt=True)
1202 @click.option('--server',
1203 prompt=True)
1204 @click.option('--user',
1205 prompt=True)
1206 @click.option('--secret',
1207 prompt=True,
1208 hide_input=True,
1209 confirmation_prompt=True)
1210 @click.pass_context
1211 def config_agent_add(ctx, name, account_type, server, user, secret):
1212 try:
1213 check_client_version(ctx.obj, ctx.command.name, 'v1')
1214 ctx.obj.vca.create(name, account_type, server, user, secret)
1215 except ClientException as inst:
1216 print(inst.message)
1217 exit(1)
1218
1219 @cli.command(name='ro-dump')
1220 @click.pass_context
1221 def ro_dump(ctx):
1222 check_client_version(ctx.obj, ctx.command.name, 'v1')
1223 resp = ctx.obj.vim.get_resource_orchestrator()
1224 table = PrettyTable(['key', 'attribute'])
1225 for k, v in resp.items():
1226 table.add_row([k, json.dumps(v, indent=2)])
1227 table.align = 'l'
1228 print(table)
1229
1230
1231 @cli.command(name='vcs-list')
1232 @click.pass_context
1233 def vcs_list(ctx):
1234 check_client_version(ctx.obj, ctx.command.name, 'v1')
1235 resp = ctx.obj.utils.get_vcs_info()
1236 table = PrettyTable(['component name', 'state'])
1237 for component in resp:
1238 table.add_row([component['component_name'], component['state']])
1239 table.align = 'l'
1240 print(table)
1241
1242
1243 @cli.command(name='ns-action')
1244 @click.argument('ns_name')
1245 @click.option('--vnf_name', default=None)
1246 @click.option('--action_name', prompt=True)
1247 @click.option('--params', prompt=True)
1248 @click.pass_context
1249 def ns_action(ctx,
1250 ns_name,
1251 vnf_name,
1252 action_name,
1253 params):
1254 '''executes an action/primitive over a NS instance
1255
1256 NS_NAME: name or ID of the NS instance
1257 '''
1258 try:
1259 check_client_version(ctx.obj, ctx.command.name)
1260 op_data={}
1261 if vnf_name:
1262 op_data['vnf_member_index'] = vnf_name
1263 op_data['primitive'] = action_name
1264 op_data['primitive_params'] = yaml.load(params)
1265 ctx.obj.ns.exec_op(ns_name, op_name='action', op_data=op_data)
1266
1267 except ClientException as inst:
1268 print(inst.message)
1269 exit(1)
1270
1271
1272 if __name__ == '__main__':
1273 cli()