osm.py: added config_file option to nsi_create
[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 import pycurl
29
30 def check_client_version(obj, what, version='sol005'):
31 '''
32 Checks the version of the client object and raises error if it not the expected.
33
34 :param obj: the client object
35 :what: the function or command under evaluation (used when an error is raised)
36 :return: -
37 :raises ClientError: if the specified version does not match the client version
38 '''
39 fullclassname = obj.__module__ + "." + obj.__class__.__name__
40 message = 'The following commands or options are only supported with the option "--sol005": {}'.format(what)
41 if version == 'v1':
42 message = 'The following commands or options are not supported when using option "--sol005": {}'.format(what)
43 if fullclassname != 'osmclient.{}.client.Client'.format(version):
44 raise ClientException(message)
45 return
46
47 @click.group()
48 @click.option('--hostname',
49 default="127.0.0.1",
50 envvar='OSM_HOSTNAME',
51 help='hostname of server. ' +
52 'Also can set OSM_HOSTNAME in environment')
53 @click.option('--sol005/--no-sol005',
54 default=True,
55 envvar='OSM_SOL005',
56 help='Use ETSI NFV SOL005 API (default) or the previous SO API. ' +
57 'Also can set OSM_SOL005 in environment')
58 @click.option('--user',
59 default=None,
60 envvar='OSM_USER',
61 help='user (only from Release FOUR, defaults to admin). ' +
62 'Also can set OSM_USER in environment')
63 @click.option('--password',
64 default=None,
65 envvar='OSM_PASSWORD',
66 help='password (only from Release FOUR, defaults to admin). ' +
67 'Also can set OSM_PASSWORD in environment')
68 @click.option('--project',
69 default=None,
70 envvar='OSM_PROJECT',
71 help='project (only from Release FOUR, defaults to admin). ' +
72 'Also can set OSM_PROJECT in environment')
73 @click.option('--so-port',
74 default=None,
75 envvar='OSM_SO_PORT',
76 help='hostname of server. ' +
77 'Also can set OSM_SO_PORT in environment')
78 @click.option('--so-project',
79 default=None,
80 envvar='OSM_SO_PROJECT',
81 help='Project Name in SO. ' +
82 'Also can set OSM_SO_PROJECT in environment')
83 @click.option('--ro-hostname',
84 default=None,
85 envvar='OSM_RO_HOSTNAME',
86 help='hostname of RO server. ' +
87 'Also can set OSM_RO_HOSTNAME in environment')
88 @click.option('--ro-port',
89 default=None,
90 envvar='OSM_RO_PORT',
91 help='hostname of RO server. ' +
92 'Also can set OSM_RO_PORT in environment')
93 @click.pass_context
94 def cli(ctx, hostname, sol005, user, password, project, so_port, so_project, ro_hostname, ro_port):
95 if hostname is None:
96 print((
97 "either hostname option or OSM_HOSTNAME " +
98 "environment variable needs to be specified"))
99 exit(1)
100 kwargs={}
101 if so_port is not None:
102 kwargs['so_port']=so_port
103 if so_project is not None:
104 kwargs['so_project']=so_project
105 if ro_hostname is not None:
106 kwargs['ro_host']=ro_hostname
107 if ro_port is not None:
108 kwargs['ro_port']=ro_port
109 if user is not None:
110 kwargs['user']=user
111 if password is not None:
112 kwargs['password']=password
113 if project is not None:
114 kwargs['project']=project
115
116 ctx.obj = client.Client(host=hostname, sol005=sol005, **kwargs)
117
118
119 ####################
120 # LIST operations
121 ####################
122
123 @cli.command(name='ns-list')
124 @click.option('--filter', default=None,
125 help='restricts the list to the NS instances matching the filter.')
126 @click.pass_context
127 def ns_list(ctx, filter):
128 '''list all NS instances
129
130 \b
131 Options:
132 --filter filterExpr Restricts the list to the NS instances matching the filter
133
134 \b
135 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
136 concatenated using the "&" character:
137
138 \b
139 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
140 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
141 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
142 attrName := string
143 value := scalar value
144
145 \b
146 where:
147 * zero or more occurrences
148 ? zero or one occurrence
149 [] grouping of expressions to be used with ? and *
150 "" quotation marks for marking string constants
151 <> name separator
152
153 \b
154 "AttrName" is the name of one attribute in the data type that defines the representation
155 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
156 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
157 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
158 entries, it means that the operator "op" is applied to the attribute addressed by the last
159 <attrName> entry included in the concatenation. All simple filter expressions are combined
160 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
161 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
162 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
163 prefix". If an attribute referenced in an expression is an array, an object that contains a
164 corresponding array shall be considered to match the expression if any of the elements in the
165 array matches all expressions that have the same attribute prefix.
166
167 \b
168 Filter examples:
169 --filter admin-status=ENABLED
170 --filter nsd-ref=<NSD_NAME>
171 --filter nsd.vendor=<VENDOR>
172 --filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME>
173 --filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME>
174 '''
175 if filter:
176 check_client_version(ctx.obj, '--filter')
177 resp = ctx.obj.ns.list(filter)
178 else:
179 resp = ctx.obj.ns.list()
180 table = PrettyTable(
181 ['ns instance name',
182 'id',
183 'operational status',
184 'config status',
185 'detailed status'])
186 for ns in resp:
187 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
188 if fullclassname == 'osmclient.sol005.client.Client':
189 nsr = ns
190 nsr_name = nsr['name']
191 nsr_id = nsr['_id']
192 else:
193 nsopdata = ctx.obj.ns.get_opdata(ns['id'])
194 nsr = nsopdata['nsr:nsr']
195 nsr_name = nsr['name-ref']
196 nsr_id = nsr['ns-instance-config-ref']
197 opstatus = nsr['operational-status'] if 'operational-status' in nsr else 'Not found'
198 configstatus = nsr['config-status'] if 'config-status' in nsr else 'Not found'
199 detailed_status = nsr['detailed-status'] if 'detailed-status' in nsr else 'Not found'
200 if configstatus == "config_not_needed":
201 configstatus = "configured (no charms)"
202 table.add_row(
203 [nsr_name,
204 nsr_id,
205 opstatus,
206 configstatus,
207 detailed_status])
208 table.align = 'l'
209 print(table)
210
211
212 def nsd_list(ctx, filter):
213 if filter:
214 check_client_version(ctx.obj, '--filter')
215 resp = ctx.obj.nsd.list(filter)
216 else:
217 resp = ctx.obj.nsd.list()
218 #print yaml.safe_dump(resp)
219 table = PrettyTable(['nsd name', 'id'])
220 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
221 if fullclassname == 'osmclient.sol005.client.Client':
222 for ns in resp:
223 name = ns['name'] if 'name' in ns else '-'
224 table.add_row([name, ns['_id']])
225 else:
226 for ns in resp:
227 table.add_row([ns['name'], ns['id']])
228 table.align = 'l'
229 print(table)
230
231
232 @cli.command(name='nsd-list')
233 @click.option('--filter', default=None,
234 help='restricts the list to the NSD/NSpkg matching the filter')
235 @click.pass_context
236 def nsd_list1(ctx, filter):
237 '''list all NSD/NSpkg in the system'''
238 nsd_list(ctx,filter)
239
240
241 @cli.command(name='nspkg-list')
242 @click.option('--filter', default=None,
243 help='restricts the list to the NSD/NSpkg matching the filter')
244 @click.pass_context
245 def nsd_list2(ctx, filter):
246 '''list all NSD/NSpkg in the system'''
247 nsd_list(ctx,filter)
248
249
250 def vnfd_list(ctx, filter):
251 if filter:
252 check_client_version(ctx.obj, '--filter')
253 resp = ctx.obj.vnfd.list(filter)
254 else:
255 resp = ctx.obj.vnfd.list()
256 #print yaml.safe_dump(resp)
257 table = PrettyTable(['vnfd name', 'id'])
258 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
259 if fullclassname == 'osmclient.sol005.client.Client':
260 for vnfd in resp:
261 name = vnfd['name'] if 'name' in vnfd else '-'
262 table.add_row([name, vnfd['_id']])
263 else:
264 for vnfd in resp:
265 table.add_row([vnfd['name'], vnfd['id']])
266 table.align = 'l'
267 print(table)
268
269
270 @cli.command(name='vnfd-list')
271 @click.option('--filter', default=None,
272 help='restricts the list to the VNFD/VNFpkg matching the filter')
273 @click.pass_context
274 def vnfd_list1(ctx, filter):
275 '''list all VNFD/VNFpkg in the system'''
276 vnfd_list(ctx,filter)
277
278
279 @cli.command(name='vnfpkg-list')
280 @click.option('--filter', default=None,
281 help='restricts the list to the VNFD/VNFpkg matching the filter')
282 @click.pass_context
283 def vnfd_list2(ctx, filter):
284 '''list all VNFD/VNFpkg in the system'''
285 vnfd_list(ctx,filter)
286
287
288 @cli.command(name='vnf-list')
289 @click.option('--ns', default=None, help='NS instance id or name to restrict the VNF list')
290 @click.option('--filter', default=None,
291 help='restricts the list to the VNF instances matching the filter.')
292 @click.pass_context
293 def vnf_list(ctx, ns, filter):
294 '''list all VNF instances
295
296 \b
297 Options:
298 --ns TEXT NS instance id or name to restrict the VNF list
299 --filter filterExpr Restricts the list to the VNF instances matching the filter
300
301 \b
302 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
303 concatenated using the "&" character:
304
305 \b
306 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
307 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
308 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
309 attrName := string
310 value := scalar value
311
312 \b
313 where:
314 * zero or more occurrences
315 ? zero or one occurrence
316 [] grouping of expressions to be used with ? and *
317 "" quotation marks for marking string constants
318 <> name separator
319
320 \b
321 "AttrName" is the name of one attribute in the data type that defines the representation
322 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
323 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
324 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
325 entries, it means that the operator "op" is applied to the attribute addressed by the last
326 <attrName> entry included in the concatenation. All simple filter expressions are combined
327 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
328 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
329 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
330 prefix". If an attribute referenced in an expression is an array, an object that contains a
331 corresponding array shall be considered to match the expression if any of the elements in the
332 array matches all expressions that have the same attribute prefix.
333
334 \b
335 Filter examples:
336 --filter vim-account-id=<VIM_ACCOUNT_ID>
337 --filter vnfd-ref=<VNFD_NAME>
338 --filter vdur.ip-address=<IP_ADDRESS>
339 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
340 '''
341 try:
342 if ns or filter:
343 if ns:
344 check_client_version(ctx.obj, '--ns')
345 if filter:
346 check_client_version(ctx.obj, '--filter')
347 resp = ctx.obj.vnf.list(ns, filter)
348 else:
349 resp = ctx.obj.vnf.list()
350 except ClientException as inst:
351 print((inst.message))
352 exit(1)
353 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
354 if fullclassname == 'osmclient.sol005.client.Client':
355 table = PrettyTable(
356 ['vnf id',
357 'name',
358 'ns id',
359 'vnf member index',
360 'vnfd name',
361 'vim account id',
362 'ip address'])
363 for vnfr in resp:
364 name = vnfr['name'] if 'name' in vnfr else '-'
365 table.add_row(
366 [vnfr['_id'],
367 name,
368 vnfr['nsr-id-ref'],
369 vnfr['member-vnf-index-ref'],
370 vnfr['vnfd-ref'],
371 vnfr['vim-account-id'],
372 vnfr['ip-address']])
373 else:
374 table = PrettyTable(
375 ['vnf name',
376 'id',
377 'operational status',
378 'config status'])
379 for vnfr in resp:
380 if 'mgmt-interface' not in vnfr:
381 vnfr['mgmt-interface'] = {}
382 vnfr['mgmt-interface']['ip-address'] = None
383 table.add_row(
384 [vnfr['name'],
385 vnfr['id'],
386 vnfr['operational-status'],
387 vnfr['config-status']])
388 table.align = 'l'
389 print(table)
390
391 @cli.command(name='ns-op-list')
392 @click.argument('name')
393 @click.pass_context
394 def ns_op_list(ctx, name):
395 '''shows the history of operations over a NS instance
396
397 NAME: name or ID of the NS instance
398 '''
399 try:
400 check_client_version(ctx.obj, ctx.command.name)
401 resp = ctx.obj.ns.list_op(name)
402 except ClientException as inst:
403 print((inst.message))
404 exit(1)
405
406 table = PrettyTable(['id', 'operation', 'status'])
407 for op in resp:
408 table.add_row([op['id'], op['lcmOperationType'],
409 op['operationState']])
410 table.align = 'l'
411 print(table)
412
413
414 def nsi_list(ctx, filter):
415 '''list all Network Slice Instances'''
416 try:
417 check_client_version(ctx.obj, ctx.command.name)
418 resp = ctx.obj.nsi.list(filter)
419 except ClientException as inst:
420 print((inst.message))
421 exit(1)
422 table = PrettyTable(
423 ['netslice instance name',
424 'id',
425 'operational status',
426 'config status',
427 'detailed status'])
428 for nsi in resp:
429 nsi_name = nsi['name']
430 nsi_id = nsi['_id']
431 opstatus = nsi['operational-status'] if 'operational-status' in nsi else 'Not found'
432 configstatus = nsi['config-status'] if 'config-status' in nsi else 'Not found'
433 detailed_status = nsi['detailed-status'] if 'detailed-status' in nsi else 'Not found'
434 if configstatus == "config_not_needed":
435 configstatus = "configured (no charms)"
436 table.add_row(
437 [nsi_name,
438 nsi_id,
439 opstatus,
440 configstatus,
441 detailed_status])
442 table.align = 'l'
443 print(table)
444
445
446 @cli.command(name='nsi-list')
447 @click.option('--filter', default=None,
448 help='restricts the list to the Network Slice Instances matching the filter')
449 @click.pass_context
450 def nsi_list1(ctx, filter):
451 '''list all Network Slice Instances (NSI)'''
452 nsi_list(ctx,filter)
453
454
455 @cli.command(name='netslice-instance-list')
456 @click.option('--filter', default=None,
457 help='restricts the list to the Network Slice Instances matching the filter')
458 @click.pass_context
459 def nsi_list2(ctx, filter):
460 '''list all Network Slice Instances (NSI)'''
461 nsi_list(ctx,filter)
462
463
464 def nst_list(ctx, filter):
465 try:
466 check_client_version(ctx.obj, ctx.command.name)
467 resp = ctx.obj.nst.list(filter)
468 except ClientException as inst:
469 print((inst.message))
470 exit(1)
471 #print yaml.safe_dump(resp)
472 table = PrettyTable(['nst name', 'id'])
473 for nst in resp:
474 name = nst['name'] if 'name' in nst else '-'
475 table.add_row([name, nst['_id']])
476 table.align = 'l'
477 print(table)
478
479
480 @cli.command(name='nst-list')
481 @click.option('--filter', default=None,
482 help='restricts the list to the NST matching the filter')
483 @click.pass_context
484 def nst_list1(ctx, filter):
485 '''list all Network Slice Templates (NST) in the system'''
486 nst_list(ctx,filter)
487
488
489 @cli.command(name='netslice-template-list')
490 @click.option('--filter', default=None,
491 help='restricts the list to the NST matching the filter')
492 @click.pass_context
493 def nst_list2(ctx, filter):
494 '''list all Network Slice Templates (NST) in the system'''
495 nst_list(ctx,filter)
496
497
498 def nsi_op_list(ctx, name):
499 try:
500 check_client_version(ctx.obj, ctx.command.name)
501 resp = ctx.obj.nsi.list_op(name)
502 except ClientException as inst:
503 print((inst.message))
504 exit(1)
505 table = PrettyTable(['id', 'operation', 'status'])
506 for op in resp:
507 table.add_row([op['id'], op['lcmOperationType'],
508 op['operationState']])
509 table.align = 'l'
510 print(table)
511
512
513 @cli.command(name='nsi-op-list')
514 @click.argument('name')
515 @click.pass_context
516 def nsi_op_list1(ctx, name):
517 '''shows the history of operations over a Network Slice Instance (NSI)
518
519 NAME: name or ID of the Network Slice Instance
520 '''
521 nsi_op_list(ctx,name)
522
523
524 @cli.command(name='netslice-instance-op-list')
525 @click.argument('name')
526 @click.pass_context
527 def nsi_op_list2(ctx, name):
528 '''shows the history of operations over a Network Slice Instance (NSI)
529
530 NAME: name or ID of the Network Slice Instance
531 '''
532 nsi_op_list(ctx,name)
533
534
535 ####################
536 # SHOW operations
537 ####################
538
539 def nsd_show(ctx, name, literal):
540 try:
541 resp = ctx.obj.nsd.get(name)
542 #resp = ctx.obj.nsd.get_individual(name)
543 except ClientException as inst:
544 print((inst.message))
545 exit(1)
546
547 if literal:
548 print(yaml.safe_dump(resp))
549 return
550
551 table = PrettyTable(['field', 'value'])
552 for k, v in list(resp.items()):
553 table.add_row([k, json.dumps(v, indent=2)])
554 table.align = 'l'
555 print(table)
556
557
558 @cli.command(name='nsd-show', short_help='shows the content of a NSD')
559 @click.option('--literal', is_flag=True,
560 help='print literally, no pretty table')
561 @click.argument('name')
562 @click.pass_context
563 def nsd_show1(ctx, name, literal):
564 '''shows the content of a NSD
565
566 NAME: name or ID of the NSD/NSpkg
567 '''
568 nsd_show(ctx, name, literal)
569
570
571 @cli.command(name='nspkg-show', short_help='shows the content of a NSD')
572 @click.option('--literal', is_flag=True,
573 help='print literally, no pretty table')
574 @click.argument('name')
575 @click.pass_context
576 def nsd_show2(ctx, name, literal):
577 '''shows the content of a NSD
578
579 NAME: name or ID of the NSD/NSpkg
580 '''
581 nsd_show(ctx, name, literal)
582
583
584 def vnfd_show(ctx, name, literal):
585 try:
586 resp = ctx.obj.vnfd.get(name)
587 #resp = ctx.obj.vnfd.get_individual(name)
588 except ClientException as inst:
589 print((inst.message))
590 exit(1)
591
592 if literal:
593 print(yaml.safe_dump(resp))
594 return
595
596 table = PrettyTable(['field', 'value'])
597 for k, v in list(resp.items()):
598 table.add_row([k, json.dumps(v, indent=2)])
599 table.align = 'l'
600 print(table)
601
602
603 @cli.command(name='vnfd-show', short_help='shows the content of a VNFD')
604 @click.option('--literal', is_flag=True,
605 help='print literally, no pretty table')
606 @click.argument('name')
607 @click.pass_context
608 def vnfd_show1(ctx, name, literal):
609 '''shows the content of a VNFD
610
611 NAME: name or ID of the VNFD/VNFpkg
612 '''
613 vnfd_show(ctx, name, literal)
614
615
616 @cli.command(name='vnfpkg-show', short_help='shows the content of a VNFD')
617 @click.option('--literal', is_flag=True,
618 help='print literally, no pretty table')
619 @click.argument('name')
620 @click.pass_context
621 def vnfd_show2(ctx, name, literal):
622 '''shows the content of a VNFD
623
624 NAME: name or ID of the VNFD/VNFpkg
625 '''
626 vnfd_show(ctx, name, literal)
627
628
629 @cli.command(name='ns-show', short_help='shows the info of a NS instance')
630 @click.argument('name')
631 @click.option('--literal', is_flag=True,
632 help='print literally, no pretty table')
633 @click.option('--filter', default=None)
634 @click.pass_context
635 def ns_show(ctx, name, literal, filter):
636 '''shows the info of a NS instance
637
638 NAME: name or ID of the NS instance
639 '''
640 try:
641 ns = ctx.obj.ns.get(name)
642 except ClientException as inst:
643 print((inst.message))
644 exit(1)
645
646 if literal:
647 print(yaml.safe_dump(ns))
648 return
649
650 table = PrettyTable(['field', 'value'])
651
652 for k, v in list(ns.items()):
653 if filter is None or filter in k:
654 table.add_row([k, json.dumps(v, indent=2)])
655
656 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
657 if fullclassname != 'osmclient.sol005.client.Client':
658 nsopdata = ctx.obj.ns.get_opdata(ns['id'])
659 nsr_optdata = nsopdata['nsr:nsr']
660 for k, v in list(nsr_optdata.items()):
661 if filter is None or filter in k:
662 table.add_row([k, json.dumps(v, indent=2)])
663 table.align = 'l'
664 print(table)
665
666
667 @cli.command(name='vnf-show', short_help='shows the info of a VNF instance')
668 @click.argument('name')
669 @click.option('--literal', is_flag=True,
670 help='print literally, no pretty table')
671 @click.option('--filter', default=None)
672 @click.pass_context
673 def vnf_show(ctx, name, literal, filter):
674 '''shows the info of a VNF instance
675
676 NAME: name or ID of the VNF instance
677 '''
678 try:
679 check_client_version(ctx.obj, ctx.command.name)
680 resp = ctx.obj.vnf.get(name)
681 except ClientException as inst:
682 print((inst.message))
683 exit(1)
684
685 if literal:
686 print(yaml.safe_dump(resp))
687 return
688
689 table = PrettyTable(['field', 'value'])
690 for k, v in list(resp.items()):
691 if filter is None or filter in k:
692 table.add_row([k, json.dumps(v, indent=2)])
693 table.align = 'l'
694 print(table)
695
696
697 @cli.command(name='vnf-monitoring-show')
698 @click.argument('vnf_name')
699 @click.pass_context
700 def vnf_monitoring_show(ctx, vnf_name):
701 try:
702 check_client_version(ctx.obj, ctx.command.name, 'v1')
703 resp = ctx.obj.vnf.get_monitoring(vnf_name)
704 except ClientException as inst:
705 print((inst.message))
706 exit(1)
707
708 table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
709 if resp is not None:
710 for monitor in resp:
711 table.add_row(
712 [vnf_name,
713 monitor['name'],
714 monitor['value-integer'],
715 monitor['units']])
716 table.align = 'l'
717 print(table)
718
719
720 @cli.command(name='ns-monitoring-show')
721 @click.argument('ns_name')
722 @click.pass_context
723 def ns_monitoring_show(ctx, ns_name):
724 try:
725 check_client_version(ctx.obj, ctx.command.name, 'v1')
726 resp = ctx.obj.ns.get_monitoring(ns_name)
727 except ClientException as inst:
728 print((inst.message))
729 exit(1)
730
731 table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
732 for key, val in list(resp.items()):
733 for monitor in val:
734 table.add_row(
735 [key,
736 monitor['name'],
737 monitor['value-integer'],
738 monitor['units']])
739 table.align = 'l'
740 print(table)
741
742
743 @cli.command(name='ns-op-show', short_help='shows the info of an operation')
744 @click.argument('id')
745 @click.option('--filter', default=None)
746 @click.pass_context
747 def ns_op_show(ctx, id, filter):
748 '''shows the detailed info of an operation
749
750 ID: operation identifier
751 '''
752 try:
753 check_client_version(ctx.obj, ctx.command.name)
754 op_info = ctx.obj.ns.get_op(id)
755 except ClientException as inst:
756 print((inst.message))
757 exit(1)
758
759 table = PrettyTable(['field', 'value'])
760 for k, v in list(op_info.items()):
761 if filter is None or filter in k:
762 table.add_row([k, json.dumps(v, indent=2)])
763 table.align = 'l'
764 print(table)
765
766
767 def nst_show(ctx, name, literal):
768 try:
769 check_client_version(ctx.obj, ctx.command.name)
770 resp = ctx.obj.nst.get(name)
771 #resp = ctx.obj.nst.get_individual(name)
772 except ClientException as inst:
773 print((inst.message))
774 exit(1)
775
776 if literal:
777 print(yaml.safe_dump(resp))
778 return
779
780 table = PrettyTable(['field', 'value'])
781 for k, v in list(resp.items()):
782 table.add_row([k, json.dumps(v, indent=2)])
783 table.align = 'l'
784 print(table)
785
786
787 @cli.command(name='nst-show', short_help='shows the content of a Network Slice Template (NST)')
788 @click.option('--literal', is_flag=True,
789 help='print literally, no pretty table')
790 @click.argument('name')
791 @click.pass_context
792 def nst_show1(ctx, name, literal):
793 '''shows the content of a Network Slice Template (NST)
794
795 NAME: name or ID of the NST
796 '''
797 nst_show(ctx, name, literal)
798
799
800 @cli.command(name='netslice-template-show', short_help='shows the content of a Network Slice Template (NST)')
801 @click.option('--literal', is_flag=True,
802 help='print literally, no pretty table')
803 @click.argument('name')
804 @click.pass_context
805 def nst_show2(ctx, name, literal):
806 '''shows the content of a Network Slice Template (NST)
807
808 NAME: name or ID of the NST
809 '''
810 nst_show(ctx, name, literal)
811
812
813 def nsi_show(ctx, name, literal, filter):
814 try:
815 check_client_version(ctx.obj, ctx.command.name)
816 nsi = ctx.obj.nsi.get(name)
817 except ClientException as inst:
818 print((inst.message))
819 exit(1)
820
821 if literal:
822 print(yaml.safe_dump(nsi))
823 return
824
825 table = PrettyTable(['field', 'value'])
826
827 for k, v in list(nsi.items()):
828 if filter is None or filter in k:
829 table.add_row([k, json.dumps(v, indent=2)])
830
831 table.align = 'l'
832 print(table)
833
834
835 @cli.command(name='nsi-show', short_help='shows the content of a Network Slice Instance (NSI)')
836 @click.argument('name')
837 @click.option('--literal', is_flag=True,
838 help='print literally, no pretty table')
839 @click.option('--filter', default=None)
840 @click.pass_context
841 def nsi_show1(ctx, name, literal, filter):
842 '''shows the content of a Network Slice Instance (NSI)
843
844 NAME: name or ID of the Network Slice Instance
845 '''
846 nsi_show(ctx, name, literal, filter)
847
848
849 @cli.command(name='netslice-instance-show', short_help='shows the content of a Network Slice Instance (NSI)')
850 @click.argument('name')
851 @click.option('--literal', is_flag=True,
852 help='print literally, no pretty table')
853 @click.option('--filter', default=None)
854 @click.pass_context
855 def nsi_show2(ctx, name, literal, filter):
856 '''shows the content of a Network Slice Instance (NSI)
857
858 NAME: name or ID of the Network Slice Instance
859 '''
860 nsi_show(ctx, name, literal, filter)
861
862
863 def nsi_op_show(ctx, id, filter):
864 try:
865 check_client_version(ctx.obj, ctx.command.name)
866 op_info = ctx.obj.nsi.get_op(id)
867 except ClientException as inst:
868 print((inst.message))
869 exit(1)
870
871 table = PrettyTable(['field', 'value'])
872 for k, v in list(op_info.items()):
873 if filter is None or filter in k:
874 table.add_row([k, json.dumps(v, indent=2)])
875 table.align = 'l'
876 print(table)
877
878
879 @cli.command(name='nsi-op-show', short_help='shows the info of an operation over a Network Slice Instance(NSI)')
880 @click.argument('id')
881 @click.option('--filter', default=None)
882 @click.pass_context
883 def nsi_op_show1(ctx, id, filter):
884 '''shows the info of an operation over a Network Slice Instance(NSI)
885
886 ID: operation identifier
887 '''
888 nsi_op_show(ctx, id, filter)
889
890
891 @cli.command(name='netslice-instance-op-show', short_help='shows the info of an operation over a Network Slice Instance(NSI)')
892 @click.argument('id')
893 @click.option('--filter', default=None)
894 @click.pass_context
895 def nsi_op_show2(ctx, id, filter):
896 '''shows the info of an operation over a Network Slice Instance(NSI)
897
898 ID: operation identifier
899 '''
900 nsi_op_show(ctx, id, filter)
901
902
903 ####################
904 # CREATE operations
905 ####################
906
907 def nsd_create(ctx, filename, overwrite):
908 try:
909 check_client_version(ctx.obj, ctx.command.name)
910 ctx.obj.nsd.create(filename, overwrite)
911 except ClientException as inst:
912 print((inst.message))
913 exit(1)
914
915
916 @cli.command(name='nsd-create', short_help='creates a new NSD/NSpkg')
917 @click.argument('filename')
918 @click.option('--overwrite', default=None,
919 help='overwrites some fields in NSD')
920 @click.pass_context
921 def nsd_create1(ctx, filename, overwrite):
922 '''creates a new NSD/NSpkg
923
924 FILENAME: NSD yaml file or NSpkg tar.gz file
925 '''
926 nsd_create(ctx, filename, overwrite)
927
928
929 @cli.command(name='nspkg-create', short_help='creates a new NSD/NSpkg')
930 @click.argument('filename')
931 @click.option('--overwrite', default=None,
932 help='overwrites some fields in NSD')
933 @click.pass_context
934 def nsd_create2(ctx, filename, overwrite):
935 '''creates a new NSD/NSpkg
936
937 FILENAME: NSD yaml file or NSpkg tar.gz file
938 '''
939 nsd_create(ctx, filename, overwrite)
940
941
942 def vnfd_create(ctx, filename, overwrite):
943 try:
944 check_client_version(ctx.obj, ctx.command.name)
945 ctx.obj.vnfd.create(filename, overwrite)
946 except ClientException as inst:
947 print((inst.message))
948 exit(1)
949
950
951 @cli.command(name='vnfd-create', short_help='creates a new VNFD/VNFpkg')
952 @click.argument('filename')
953 @click.option('--overwrite', default=None,
954 help='overwrites some fields in VNFD')
955 @click.pass_context
956 def vnfd_create1(ctx, filename, overwrite):
957 '''creates a new VNFD/VNFpkg
958
959 FILENAME: VNFD yaml file or VNFpkg tar.gz file
960 '''
961 vnfd_create(ctx, filename, overwrite)
962
963
964 @cli.command(name='vnfpkg-create', short_help='creates a new VNFD/VNFpkg')
965 @click.argument('filename')
966 @click.option('--overwrite', default=None,
967 help='overwrites some fields in VNFD')
968 @click.pass_context
969 def vnfd_create2(ctx, filename, overwrite):
970 '''creates a new VNFD/VNFpkg
971
972 FILENAME: VNFD yaml file or VNFpkg tar.gz file
973 '''
974 vnfd_create(ctx, filename, overwrite)
975
976
977 @cli.command(name='ns-create', short_help='creates a new Network Service instance')
978 @click.option('--ns_name',
979 prompt=True, help='name of the NS instance')
980 @click.option('--nsd_name',
981 prompt=True, help='name of the NS descriptor')
982 @click.option('--vim_account',
983 prompt=True, help='default VIM account id or name for the deployment')
984 @click.option('--admin_status',
985 default='ENABLED',
986 help='administration status')
987 @click.option('--ssh_keys',
988 default=None,
989 help='comma separated list of public key files to inject to vnfs')
990 @click.option('--config',
991 default=None,
992 help='ns specific yaml configuration')
993 @click.option('--config_file',
994 default=None,
995 help='ns specific yaml configuration file')
996 @click.pass_context
997 def ns_create(ctx,
998 nsd_name,
999 ns_name,
1000 vim_account,
1001 admin_status,
1002 ssh_keys,
1003 config,
1004 config_file):
1005 '''creates a new NS instance'''
1006 try:
1007 if config_file:
1008 check_client_version(ctx.obj, '--config_file')
1009 if config:
1010 raise ClientException('"--config" option is incompatible with "--config_file" option')
1011 with open(config_file, 'r') as cf:
1012 config=cf.read()
1013 ctx.obj.ns.create(
1014 nsd_name,
1015 ns_name,
1016 config=config,
1017 ssh_keys=ssh_keys,
1018 account=vim_account)
1019 except ClientException as inst:
1020 print((inst.message))
1021 exit(1)
1022
1023
1024 def nst_create(ctx, filename, overwrite):
1025 try:
1026 check_client_version(ctx.obj, ctx.command.name)
1027 ctx.obj.nst.create(filename, overwrite)
1028 except ClientException as inst:
1029 print((inst.message))
1030 exit(1)
1031
1032
1033 @cli.command(name='nst-create', short_help='creates a new Network Slice Template (NST)')
1034 @click.argument('filename')
1035 @click.option('--overwrite', default=None,
1036 help='overwrites some fields in NST')
1037 @click.pass_context
1038 def nst_create1(ctx, filename, overwrite):
1039 '''creates a new Network Slice Template (NST)
1040
1041 FILENAME: NST yaml file or NSTpkg tar.gz file
1042 '''
1043 nst_create(ctx, filename, overwrite)
1044
1045
1046 @cli.command(name='netslice-template-create', short_help='creates a new Network Slice Template (NST)')
1047 @click.argument('filename')
1048 @click.option('--overwrite', default=None,
1049 help='overwrites some fields in NST')
1050 @click.pass_context
1051 def nst_create2(ctx, filename, overwrite):
1052 '''creates a new Network Slice Template (NST)
1053
1054 FILENAME: NST yaml file or NSTpkg tar.gz file
1055 '''
1056 nst_create(ctx, filename, overwrite)
1057
1058
1059 def nsi_create(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file):
1060 '''creates a new Network Slice Instance (NSI)'''
1061 try:
1062 check_client_version(ctx.obj, ctx.command.name)
1063 if config_file:
1064 if config:
1065 raise ClientException('"--config" option is incompatible with "--config_file" option')
1066 with open(config_file, 'r') as cf:
1067 config=cf.read()
1068 ctx.obj.nsi.create(nst_name, nsi_name, config=config, ssh_keys=ssh_keys,
1069 account=vim_account)
1070 except ClientException as inst:
1071 print((inst.message))
1072 exit(1)
1073
1074
1075 @cli.command(name='nsi-create', short_help='creates a new Network Slice Instance')
1076 @click.option('--nsi_name', prompt=True, help='name of the Network Slice Instance')
1077 @click.option('--nst_name', prompt=True, help='name of the Network Slice Template')
1078 @click.option('--vim_account', prompt=True, help='default VIM account id or name for the deployment')
1079 @click.option('--ssh_keys', default=None,
1080 help='comma separated list of keys to inject to vnfs')
1081 @click.option('--config', default=None,
1082 help='Netslice specific yaml configuration:\n'
1083 'netslice_subnet: [\n'
1084 'id: TEXT, vim_account: TEXT,\n'
1085 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1086 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1087 '],\n'
1088 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1089 )
1090 @click.option('--config_file',
1091 default=None,
1092 help='nsi specific yaml configuration file')
1093 @click.pass_context
1094 def nsi_create1(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file):
1095 '''creates a new Network Slice Instance (NSI)'''
1096 nsi_create(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file)
1097
1098
1099 @cli.command(name='netslice-instance-create', short_help='creates a new Network Slice Instance')
1100 @click.option('--nsi_name', prompt=True, help='name of the Network Slice Instance')
1101 @click.option('--nst_name', prompt=True, help='name of the Network Slice Template')
1102 @click.option('--vim_account', prompt=True, help='default VIM account id or name for the deployment')
1103 @click.option('--ssh_keys', default=None,
1104 help='comma separated list of keys to inject to vnfs')
1105 @click.option('--config', default=None,
1106 help='Netslice specific yaml configuration:\n'
1107 'netslice_subnet: [\n'
1108 'id: TEXT, vim_account: TEXT,\n'
1109 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1110 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1111 '],\n'
1112 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1113 )
1114 @click.option('--config_file',
1115 default=None,
1116 help='nsi specific yaml configuration file')
1117 @click.pass_context
1118 def nsi_create2(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file):
1119 '''creates a new Network Slice Instance (NSI)'''
1120 nsi_create(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file)
1121
1122
1123 ####################
1124 # UPDATE operations
1125 ####################
1126
1127 def nsd_update(ctx, name, content):
1128 try:
1129 check_client_version(ctx.obj, ctx.command.name)
1130 ctx.obj.nsd.update(name, content)
1131 except ClientException as inst:
1132 print((inst.message))
1133 exit(1)
1134
1135
1136 @cli.command(name='nsd-update', short_help='updates a NSD/NSpkg')
1137 @click.argument('name')
1138 @click.option('--content', default=None,
1139 help='filename with the NSD/NSpkg replacing the current one')
1140 @click.pass_context
1141 def nsd_update1(ctx, name, content):
1142 '''updates a NSD/NSpkg
1143
1144 NAME: name or ID of the NSD/NSpkg
1145 '''
1146 nsd_update(ctx, name, content)
1147
1148
1149 @cli.command(name='nspkg-update', short_help='updates a NSD/NSpkg')
1150 @click.argument('name')
1151 @click.option('--content', default=None,
1152 help='filename with the NSD/NSpkg replacing the current one')
1153 @click.pass_context
1154 def nsd_update2(ctx, name, content):
1155 '''updates a NSD/NSpkg
1156
1157 NAME: name or ID of the NSD/NSpkg
1158 '''
1159 nsd_update(ctx, name, content)
1160
1161
1162 def vnfd_update(ctx, name, content):
1163 try:
1164 check_client_version(ctx.obj, ctx.command.name)
1165 ctx.obj.vnfd.update(name, content)
1166 except ClientException as inst:
1167 print((inst.message))
1168 exit(1)
1169
1170
1171 @cli.command(name='vnfd-update', short_help='updates a new VNFD/VNFpkg')
1172 @click.argument('name')
1173 @click.option('--content', default=None,
1174 help='filename with the VNFD/VNFpkg replacing the current one')
1175 @click.pass_context
1176 def vnfd_update1(ctx, name, content):
1177 '''updates a VNFD/VNFpkg
1178
1179 NAME: name or ID of the VNFD/VNFpkg
1180 '''
1181 vnfd_update(ctx, name, content)
1182
1183
1184 @cli.command(name='vnfpkg-update', short_help='updates a VNFD/VNFpkg')
1185 @click.argument('name')
1186 @click.option('--content', default=None,
1187 help='filename with the VNFD/VNFpkg replacing the current one')
1188 @click.pass_context
1189 def vnfd_update2(ctx, name, content):
1190 '''updates a VNFD/VNFpkg
1191
1192 NAME: VNFD yaml file or VNFpkg tar.gz file
1193 '''
1194 vnfd_update(ctx, name, content)
1195
1196
1197 def nst_update(ctx, name, content):
1198 try:
1199 check_client_version(ctx.obj, ctx.command.name)
1200 ctx.obj.nst.update(name, content)
1201 except ClientException as inst:
1202 print((inst.message))
1203 exit(1)
1204
1205
1206 @cli.command(name='nst-update', short_help='updates a Network Slice Template (NST)')
1207 @click.argument('name')
1208 @click.option('--content', default=None,
1209 help='filename with the NST/NSTpkg replacing the current one')
1210 @click.pass_context
1211 def nst_update1(ctx, name, content):
1212 '''updates a Network Slice Template (NST)
1213
1214 NAME: name or ID of the NSD/NSpkg
1215 '''
1216 nst_update(ctx, name, content)
1217
1218
1219 @cli.command(name='netslice-template-update', short_help='updates a Network Slice Template (NST)')
1220 @click.argument('name')
1221 @click.option('--content', default=None,
1222 help='filename with the NST/NSTpkg replacing the current one')
1223 @click.pass_context
1224 def nst_update2(ctx, name, content):
1225 '''updates a Network Slice Template (NST)
1226
1227 NAME: name or ID of the NSD/NSpkg
1228 '''
1229 nst_update(ctx, name, content)
1230
1231
1232 ####################
1233 # DELETE operations
1234 ####################
1235
1236 def nsd_delete(ctx, name, force):
1237 try:
1238 if not force:
1239 ctx.obj.nsd.delete(name)
1240 else:
1241 check_client_version(ctx.obj, '--force')
1242 ctx.obj.nsd.delete(name, force)
1243 except ClientException as inst:
1244 print((inst.message))
1245 exit(1)
1246
1247
1248 @cli.command(name='nsd-delete', short_help='deletes a NSD/NSpkg')
1249 @click.argument('name')
1250 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1251 @click.pass_context
1252 def nsd_delete1(ctx, name, force):
1253 '''deletes a NSD/NSpkg
1254
1255 NAME: name or ID of the NSD/NSpkg to be deleted
1256 '''
1257 nsd_delete(ctx, name, force)
1258
1259
1260 @cli.command(name='nspkg-delete', short_help='deletes a NSD/NSpkg')
1261 @click.argument('name')
1262 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1263 @click.pass_context
1264 def nsd_delete2(ctx, name, force):
1265 '''deletes a NSD/NSpkg
1266
1267 NAME: name or ID of the NSD/NSpkg to be deleted
1268 '''
1269 nsd_delete(ctx, name, force)
1270
1271
1272 def vnfd_delete(ctx, name, force):
1273 try:
1274 if not force:
1275 ctx.obj.vnfd.delete(name)
1276 else:
1277 check_client_version(ctx.obj, '--force')
1278 ctx.obj.vnfd.delete(name, force)
1279 except ClientException as inst:
1280 print((inst.message))
1281 exit(1)
1282
1283
1284 @cli.command(name='vnfd-delete', short_help='deletes a VNFD/VNFpkg')
1285 @click.argument('name')
1286 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1287 @click.pass_context
1288 def vnfd_delete1(ctx, name, force):
1289 '''deletes a VNFD/VNFpkg
1290
1291 NAME: name or ID of the VNFD/VNFpkg to be deleted
1292 '''
1293 vnfd_delete(ctx, name, force)
1294
1295
1296 @cli.command(name='vnfpkg-delete', short_help='deletes a VNFD/VNFpkg')
1297 @click.argument('name')
1298 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1299 @click.pass_context
1300 def vnfd_delete2(ctx, name, force):
1301 '''deletes a VNFD/VNFpkg
1302
1303 NAME: name or ID of the VNFD/VNFpkg to be deleted
1304 '''
1305 vnfd_delete(ctx, name, force)
1306
1307
1308 @cli.command(name='ns-delete', short_help='deletes a NS instance')
1309 @click.argument('name')
1310 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1311 @click.pass_context
1312 def ns_delete(ctx, name, force):
1313 '''deletes a NS instance
1314
1315 NAME: name or ID of the NS instance to be deleted
1316 '''
1317 try:
1318 if not force:
1319 ctx.obj.ns.delete(name)
1320 else:
1321 check_client_version(ctx.obj, '--force')
1322 ctx.obj.ns.delete(name, force)
1323 except ClientException as inst:
1324 print((inst.message))
1325 exit(1)
1326
1327
1328 def nst_delete(ctx, name, force):
1329 try:
1330 check_client_version(ctx.obj, ctx.command.name)
1331 ctx.obj.nst.delete(name, force)
1332 except ClientException as inst:
1333 print((inst.message))
1334 exit(1)
1335
1336
1337 @cli.command(name='nst-delete', short_help='deletes a Network Slice Template (NST)')
1338 @click.argument('name')
1339 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1340 @click.pass_context
1341 def nst_delete1(ctx, name, force):
1342 '''deletes a Network Slice Template (NST)
1343
1344 NAME: name or ID of the NST/NSTpkg to be deleted
1345 '''
1346 nst_delete(ctx, name, force)
1347
1348
1349 @cli.command(name='netslice-template-delete', short_help='deletes a Network Slice Template (NST)')
1350 @click.argument('name')
1351 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1352 @click.pass_context
1353 def nst_delete2(ctx, name, force):
1354 '''deletes a Network Slice Template (NST)
1355
1356 NAME: name or ID of the NST/NSTpkg to be deleted
1357 '''
1358 nst_delete(ctx, name, force)
1359
1360
1361 def nsi_delete(ctx, name, force):
1362 try:
1363 check_client_version(ctx.obj, ctx.command.name)
1364 ctx.obj.nsi.delete(name, force)
1365 except ClientException as inst:
1366 print((inst.message))
1367 exit(1)
1368
1369
1370 @cli.command(name='nsi-delete', short_help='deletes a Network Slice Instance (NSI)')
1371 @click.argument('name')
1372 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1373 @click.pass_context
1374 def nsi_delete1(ctx, name, force):
1375 '''deletes a Network Slice Instance (NSI)
1376
1377 NAME: name or ID of the Network Slice instance to be deleted
1378 '''
1379 nsi_delete(ctx, name, force)
1380
1381
1382 @cli.command(name='netslice-instance-delete', short_help='deletes a Network Slice Instance (NSI)')
1383 @click.argument('name')
1384 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1385 @click.pass_context
1386 def nsi_delete2(ctx, name, force):
1387 '''deletes a Network Slice Instance (NSI)
1388
1389 NAME: name or ID of the Network Slice instance to be deleted
1390 '''
1391 nsi_delete(ctx, name, force)
1392
1393
1394 ####################
1395 # VIM operations
1396 ####################
1397
1398 @cli.command(name='vim-create')
1399 @click.option('--name',
1400 prompt=True,
1401 help='Name to create datacenter')
1402 @click.option('--user',
1403 prompt=True,
1404 help='VIM username')
1405 @click.option('--password',
1406 prompt=True,
1407 hide_input=True,
1408 confirmation_prompt=True,
1409 help='VIM password')
1410 @click.option('--auth_url',
1411 prompt=True,
1412 help='VIM url')
1413 @click.option('--tenant',
1414 prompt=True,
1415 help='VIM tenant name')
1416 @click.option('--config',
1417 default=None,
1418 help='VIM specific config parameters')
1419 @click.option('--account_type',
1420 default='openstack',
1421 help='VIM type')
1422 @click.option('--description',
1423 default='no description',
1424 help='human readable description')
1425 @click.option('--sdn_controller', default=None, help='Name or id of the SDN controller associated to this VIM account')
1426 @click.option('--sdn_port_mapping', default=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1427 @click.pass_context
1428 def vim_create(ctx,
1429 name,
1430 user,
1431 password,
1432 auth_url,
1433 tenant,
1434 config,
1435 account_type,
1436 description,
1437 sdn_controller,
1438 sdn_port_mapping):
1439 '''creates a new VIM account
1440 '''
1441 try:
1442 if sdn_controller:
1443 check_client_version(ctx.obj, '--sdn_controller')
1444 if sdn_port_mapping:
1445 check_client_version(ctx.obj, '--sdn_port_mapping')
1446 vim = {}
1447 vim['vim-username'] = user
1448 vim['vim-password'] = password
1449 vim['vim-url'] = auth_url
1450 vim['vim-tenant-name'] = tenant
1451 vim['vim-type'] = account_type
1452 vim['description'] = description
1453 vim['config'] = config
1454 if sdn_controller or sdn_port_mapping:
1455 ctx.obj.vim.create(name, vim, sdn_controller, sdn_port_mapping)
1456 else:
1457 ctx.obj.vim.create(name, vim)
1458 except ClientException as inst:
1459 print((inst.message))
1460 exit(1)
1461
1462
1463 @cli.command(name='vim-update', short_help='updates a VIM account')
1464 @click.argument('name')
1465 @click.option('--newname', help='New name for the VIM account')
1466 @click.option('--user', help='VIM username')
1467 @click.option('--password', help='VIM password')
1468 @click.option('--auth_url', help='VIM url')
1469 @click.option('--tenant', help='VIM tenant name')
1470 @click.option('--config', help='VIM specific config parameters')
1471 @click.option('--account_type', help='VIM type')
1472 @click.option('--description', help='human readable description')
1473 @click.option('--sdn_controller', default=None, help='Name or id of the SDN controller associated to this VIM account')
1474 @click.option('--sdn_port_mapping', default=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1475 @click.pass_context
1476 def vim_update(ctx,
1477 name,
1478 newname,
1479 user,
1480 password,
1481 auth_url,
1482 tenant,
1483 config,
1484 account_type,
1485 description,
1486 sdn_controller,
1487 sdn_port_mapping):
1488 '''updates a VIM account
1489
1490 NAME: name or ID of the VIM account
1491 '''
1492 try:
1493 check_client_version(ctx.obj, ctx.command.name)
1494 vim = {}
1495 if newname: vim['name'] = newname
1496 if user: vim['vim_user'] = user
1497 if password: vim['vim_password'] = password
1498 if auth_url: vim['vim_url'] = auth_url
1499 if tenant: vim['vim-tenant-name'] = tenant
1500 if account_type: vim['vim_type'] = account_type
1501 if description: vim['description'] = description
1502 if config: vim['config'] = config
1503 ctx.obj.vim.update(name, vim, sdn_controller, sdn_port_mapping)
1504 except ClientException as inst:
1505 print((inst.message))
1506 exit(1)
1507
1508
1509 @cli.command(name='vim-delete')
1510 @click.argument('name')
1511 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1512 @click.pass_context
1513 def vim_delete(ctx, name, force):
1514 '''deletes a VIM account
1515
1516 NAME: name or ID of the VIM account to be deleted
1517 '''
1518 try:
1519 if not force:
1520 ctx.obj.vim.delete(name)
1521 else:
1522 check_client_version(ctx.obj, '--force')
1523 ctx.obj.vim.delete(name, force)
1524 except ClientException as inst:
1525 print((inst.message))
1526 exit(1)
1527
1528
1529 @cli.command(name='vim-list')
1530 @click.option('--ro_update/--no_ro_update',
1531 default=False,
1532 help='update list from RO')
1533 @click.option('--filter', default=None,
1534 help='restricts the list to the VIM accounts matching the filter')
1535 @click.pass_context
1536 def vim_list(ctx, ro_update, filter):
1537 '''list all VIM accounts'''
1538 if filter:
1539 check_client_version(ctx.obj, '--filter')
1540 if ro_update:
1541 check_client_version(ctx.obj, '--ro_update', 'v1')
1542 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
1543 if fullclassname == 'osmclient.sol005.client.Client':
1544 resp = ctx.obj.vim.list(filter)
1545 else:
1546 resp = ctx.obj.vim.list(ro_update)
1547 table = PrettyTable(['vim name', 'uuid'])
1548 for vim in resp:
1549 table.add_row([vim['name'], vim['uuid']])
1550 table.align = 'l'
1551 print(table)
1552
1553
1554 @cli.command(name='vim-show')
1555 @click.argument('name')
1556 @click.pass_context
1557 def vim_show(ctx, name):
1558 '''shows the details of a VIM account
1559
1560 NAME: name or ID of the VIM account
1561 '''
1562 try:
1563 resp = ctx.obj.vim.get(name)
1564 if 'vim_password' in resp:
1565 resp['vim_password']='********'
1566 except ClientException as inst:
1567 print((inst.message))
1568 exit(1)
1569
1570 table = PrettyTable(['key', 'attribute'])
1571 for k, v in list(resp.items()):
1572 table.add_row([k, json.dumps(v, indent=2)])
1573 table.align = 'l'
1574 print(table)
1575
1576
1577 ####################
1578 # SDN controller operations
1579 ####################
1580
1581 @cli.command(name='sdnc-create')
1582 @click.option('--name',
1583 prompt=True,
1584 help='Name to create sdn controller')
1585 @click.option('--type',
1586 prompt=True,
1587 help='SDN controller type')
1588 @click.option('--sdn_controller_version',
1589 help='SDN controller username')
1590 @click.option('--ip_address',
1591 prompt=True,
1592 help='SDN controller IP address')
1593 @click.option('--port',
1594 prompt=True,
1595 help='SDN controller port')
1596 @click.option('--switch_dpid',
1597 prompt=True,
1598 help='Switch DPID (Openflow Datapath ID)')
1599 @click.option('--user',
1600 help='SDN controller username')
1601 @click.option('--password',
1602 hide_input=True,
1603 confirmation_prompt=True,
1604 help='SDN controller password')
1605 #@click.option('--description',
1606 # default='no description',
1607 # help='human readable description')
1608 @click.pass_context
1609 def sdnc_create(ctx,
1610 name,
1611 type,
1612 sdn_controller_version,
1613 ip_address,
1614 port,
1615 switch_dpid,
1616 user,
1617 password):
1618 '''creates a new SDN controller
1619 '''
1620 sdncontroller = {}
1621 sdncontroller['name'] = name
1622 sdncontroller['type'] = type
1623 sdncontroller['ip'] = ip_address
1624 sdncontroller['port'] = int(port)
1625 sdncontroller['dpid'] = switch_dpid
1626 if sdn_controller_version:
1627 sdncontroller['version'] = sdn_controller_version
1628 if user:
1629 sdncontroller['user'] = user
1630 if password:
1631 sdncontroller['password'] = password
1632 # sdncontroller['description'] = description
1633 try:
1634 check_client_version(ctx.obj, ctx.command.name)
1635 ctx.obj.sdnc.create(name, sdncontroller)
1636 except ClientException as inst:
1637 print((inst.message))
1638
1639
1640 @cli.command(name='sdnc-update', short_help='updates an SDN controller')
1641 @click.argument('name')
1642 @click.option('--newname', help='New name for the SDN controller')
1643 @click.option('--type', help='SDN controller type')
1644 @click.option('--sdn_controller_version', help='SDN controller username')
1645 @click.option('--ip_address', help='SDN controller IP address')
1646 @click.option('--port', help='SDN controller port')
1647 @click.option('--switch_dpid', help='Switch DPID (Openflow Datapath ID)')
1648 @click.option('--user', help='SDN controller username')
1649 @click.option('--password', help='SDN controller password')
1650 #@click.option('--description', default=None, help='human readable description')
1651 @click.pass_context
1652 def sdnc_update(ctx,
1653 name,
1654 newname,
1655 type,
1656 sdn_controller_version,
1657 ip_address,
1658 port,
1659 switch_dpid,
1660 user,
1661 password):
1662 '''updates an SDN controller
1663
1664 NAME: name or ID of the SDN controller
1665 '''
1666 sdncontroller = {}
1667 if newname: sdncontroller['name'] = newname
1668 if type: sdncontroller['type'] = type
1669 if ip_address: sdncontroller['ip'] = ip_address
1670 if port: sdncontroller['port'] = int(port)
1671 if switch_dpid: sdncontroller['dpid'] = switch_dpid
1672 # sdncontroller['description'] = description
1673 if sdn_controller_version is not None:
1674 if sdn_controller_version=="":
1675 sdncontroller['version'] = None
1676 else:
1677 sdncontroller['version'] = sdn_controller_version
1678 if user is not None:
1679 if user=="":
1680 sdncontroller['user'] = None
1681 else:
1682 sdncontroller['user'] = user
1683 if password is not None:
1684 if password=="":
1685 sdncontroller['password'] = None
1686 else:
1687 sdncontroller['password'] = user
1688 try:
1689 check_client_version(ctx.obj, ctx.command.name)
1690 ctx.obj.sdnc.update(name, sdncontroller)
1691 except ClientException as inst:
1692 print((inst.message))
1693 exit(1)
1694
1695
1696 @cli.command(name='sdnc-delete')
1697 @click.argument('name')
1698 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1699 @click.pass_context
1700 def sdnc_delete(ctx, name, force):
1701 '''deletes an SDN controller
1702
1703 NAME: name or ID of the SDN controller to be deleted
1704 '''
1705 try:
1706 check_client_version(ctx.obj, ctx.command.name)
1707 ctx.obj.sdnc.delete(name, force)
1708 except ClientException as inst:
1709 print((inst.message))
1710 exit(1)
1711
1712
1713 @cli.command(name='sdnc-list')
1714 @click.option('--filter', default=None,
1715 help='restricts the list to the SDN controllers matching the filter')
1716 @click.pass_context
1717 def sdnc_list(ctx, filter):
1718 '''list all SDN controllers'''
1719 try:
1720 check_client_version(ctx.obj, ctx.command.name)
1721 resp = ctx.obj.sdnc.list(filter)
1722 except ClientException as inst:
1723 print((inst.message))
1724 exit(1)
1725 table = PrettyTable(['name', 'id'])
1726 for sdnc in resp:
1727 table.add_row([sdnc['name'], sdnc['_id']])
1728 table.align = 'l'
1729 print(table)
1730
1731
1732 @cli.command(name='sdnc-show')
1733 @click.argument('name')
1734 @click.pass_context
1735 def sdnc_show(ctx, name):
1736 '''shows the details of an SDN controller
1737
1738 NAME: name or ID of the SDN controller
1739 '''
1740 try:
1741 check_client_version(ctx.obj, ctx.command.name)
1742 resp = ctx.obj.sdnc.get(name)
1743 except ClientException as inst:
1744 print((inst.message))
1745 exit(1)
1746
1747 table = PrettyTable(['key', 'attribute'])
1748 for k, v in list(resp.items()):
1749 table.add_row([k, json.dumps(v, indent=2)])
1750 table.align = 'l'
1751 print(table)
1752
1753
1754 ####################
1755 # Project mgmt operations
1756 ####################
1757
1758 @cli.command(name='project-create')
1759 @click.argument('name')
1760 #@click.option('--description',
1761 # default='no description',
1762 # help='human readable description')
1763 @click.pass_context
1764 def project_create(ctx, name):
1765 '''Creates a new project
1766
1767 NAME: name of the project
1768 '''
1769 project = {}
1770 project['name'] = name
1771 try:
1772 check_client_version(ctx.obj, ctx.command.name)
1773 ctx.obj.project.create(name, project)
1774 except ClientException as inst:
1775 print(inst.message)
1776
1777
1778 @cli.command(name='project-delete')
1779 @click.argument('name')
1780 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1781 @click.pass_context
1782 def project_delete(ctx, name):
1783 '''deletes a project
1784
1785 NAME: name or ID of the project to be deleted
1786 '''
1787 try:
1788 check_client_version(ctx.obj, ctx.command.name)
1789 ctx.obj.project.delete(name)
1790 except ClientException as inst:
1791 print(inst.message)
1792 exit(1)
1793
1794
1795 @cli.command(name='project-list')
1796 @click.option('--filter', default=None,
1797 help='restricts the list to the projects matching the filter')
1798 @click.pass_context
1799 def project_list(ctx, filter):
1800 '''list all projects'''
1801 try:
1802 check_client_version(ctx.obj, ctx.command.name)
1803 resp = ctx.obj.project.list(filter)
1804 except ClientException as inst:
1805 print(inst.message)
1806 exit(1)
1807 table = PrettyTable(['name', 'id'])
1808 for proj in resp:
1809 table.add_row([proj['name'], proj['_id']])
1810 table.align = 'l'
1811 print(table)
1812
1813
1814 @cli.command(name='project-show')
1815 @click.argument('name')
1816 @click.pass_context
1817 def project_show(ctx, name):
1818 '''shows the details of a project
1819
1820 NAME: name or ID of the project
1821 '''
1822 try:
1823 check_client_version(ctx.obj, ctx.command.name)
1824 resp = ctx.obj.project.get(name)
1825 except ClientException as inst:
1826 print(inst.message)
1827 exit(1)
1828
1829 table = PrettyTable(['key', 'attribute'])
1830 for k, v in resp.items():
1831 table.add_row([k, json.dumps(v, indent=2)])
1832 table.align = 'l'
1833 print(table)
1834
1835
1836 ####################
1837 # User mgmt operations
1838 ####################
1839
1840 @cli.command(name='user-create')
1841 @click.argument('username')
1842 @click.option('--password',
1843 prompt=True,
1844 hide_input=True,
1845 confirmation_prompt=True,
1846 help='user password')
1847 @click.option('--projects',
1848 default=None,
1849 help='list of project ids that the user belongs to')
1850 #@click.option('--description',
1851 # default='no description',
1852 # help='human readable description')
1853 @click.pass_context
1854 def user_create(ctx, username, password, projects):
1855 '''Creates a new user
1856
1857 USERNAME: name of the user
1858 '''
1859 user = {}
1860 user['username'] = username
1861 user['password'] = password
1862 user['projects'] = projects
1863 try:
1864 check_client_version(ctx.obj, ctx.command.name)
1865 ctx.obj.user.create(username, user)
1866 except ClientException as inst:
1867 print(inst.message)
1868
1869
1870 @cli.command(name='user-delete')
1871 @click.argument('name')
1872 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1873 @click.pass_context
1874 def user_delete(ctx, name):
1875 '''deletes a user
1876
1877 NAME: name or ID of the user to be deleted
1878 '''
1879 try:
1880 check_client_version(ctx.obj, ctx.command.name)
1881 ctx.obj.user.delete(name)
1882 except ClientException as inst:
1883 print(inst.message)
1884 exit(1)
1885
1886
1887 @cli.command(name='user-list')
1888 @click.option('--filter', default=None,
1889 help='restricts the list to the users matching the filter')
1890 @click.pass_context
1891 def user_list(ctx, filter):
1892 '''list all users'''
1893 try:
1894 check_client_version(ctx.obj, ctx.command.name)
1895 resp = ctx.obj.user.list(filter)
1896 except ClientException as inst:
1897 print(inst.message)
1898 exit(1)
1899 table = PrettyTable(['name', 'id'])
1900 for user in resp:
1901 table.add_row([user['name'], user['_id']])
1902 table.align = 'l'
1903 print(table)
1904
1905
1906 @cli.command(name='user-show')
1907 @click.argument('name')
1908 @click.pass_context
1909 def user_show(ctx, name):
1910 '''shows the details of a user
1911
1912 NAME: name or ID of the user
1913 '''
1914 try:
1915 check_client_version(ctx.obj, ctx.command.name)
1916 resp = ctx.obj.user.get(name)
1917 if 'password' in resp:
1918 resp['password']='********'
1919 except ClientException as inst:
1920 print(inst.message)
1921 exit(1)
1922
1923 table = PrettyTable(['key', 'attribute'])
1924 for k, v in resp.items():
1925 table.add_row([k, json.dumps(v, indent=2)])
1926 table.align = 'l'
1927 print(table)
1928
1929
1930 ####################
1931 # Fault Management operations
1932 ####################
1933
1934 @cli.command(name='ns-alarm-create')
1935 @click.argument('name')
1936 @click.option('--ns', prompt=True, help='NS instance id or name')
1937 @click.option('--vnf', prompt=True,
1938 help='VNF name (VNF member index as declared in the NSD)')
1939 @click.option('--vdu', prompt=True,
1940 help='VDU name (VDU name as declared in the VNFD)')
1941 @click.option('--metric', prompt=True,
1942 help='Name of the metric (e.g. cpu_utilization)')
1943 @click.option('--severity', default='WARNING',
1944 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
1945 @click.option('--threshold_value', prompt=True,
1946 help='threshold value that, when crossed, an alarm is triggered')
1947 @click.option('--threshold_operator', prompt=True,
1948 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
1949 @click.option('--statistic', default='AVERAGE',
1950 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
1951 @click.pass_context
1952 def ns_alarm_create(ctx, name, ns, vnf, vdu, metric, severity,
1953 threshold_value, threshold_operator, statistic):
1954 '''creates a new alarm for a NS instance'''
1955 ns_instance = ctx.obj.ns.get(ns)
1956 alarm = {}
1957 alarm['alarm_name'] = name
1958 alarm['ns_id'] = ns_instance['_id']
1959 alarm['correlation_id'] = ns_instance['_id']
1960 alarm['vnf_member_index'] = vnf
1961 alarm['vdu_name'] = vdu
1962 alarm['metric_name'] = metric
1963 alarm['severity'] = severity
1964 alarm['threshold_value'] = int(threshold_value)
1965 alarm['operation'] = threshold_operator
1966 alarm['statistic'] = statistic
1967 try:
1968 check_client_version(ctx.obj, ctx.command.name)
1969 ctx.obj.ns.create_alarm(alarm)
1970 except ClientException as inst:
1971 print((inst.message))
1972 exit(1)
1973
1974
1975 #@cli.command(name='ns-alarm-delete')
1976 #@click.argument('name')
1977 #@click.pass_context
1978 #def ns_alarm_delete(ctx, name):
1979 # '''deletes an alarm
1980 #
1981 # NAME: name of the alarm to be deleted
1982 # '''
1983 # try:
1984 # check_client_version(ctx.obj, ctx.command.name)
1985 # ctx.obj.ns.delete_alarm(name)
1986 # except ClientException as inst:
1987 # print(inst.message)
1988 # exit(1)
1989
1990
1991 ####################
1992 # Performance Management operations
1993 ####################
1994
1995 @cli.command(name='ns-metric-export')
1996 @click.option('--ns', prompt=True, help='NS instance id or name')
1997 @click.option('--vnf', prompt=True,
1998 help='VNF name (VNF member index as declared in the NSD)')
1999 @click.option('--vdu', prompt=True,
2000 help='VDU name (VDU name as declared in the VNFD)')
2001 @click.option('--metric', prompt=True,
2002 help='name of the metric (e.g. cpu_utilization)')
2003 #@click.option('--period', default='1w',
2004 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
2005 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
2006 @click.pass_context
2007 def ns_metric_export(ctx, ns, vnf, vdu, metric, interval):
2008 '''exports a metric to the internal OSM bus, which can be read by other apps
2009 '''
2010 ns_instance = ctx.obj.ns.get(ns)
2011 metric_data = {}
2012 metric_data['ns_id'] = ns_instance['_id']
2013 metric_data['correlation_id'] = ns_instance['_id']
2014 metric_data['vnf_member_index'] = vnf
2015 metric_data['vdu_name'] = vdu
2016 metric_data['metric_name'] = metric
2017 metric_data['collection_unit'] = 'WEEK'
2018 metric_data['collection_period'] = 1
2019 try:
2020 check_client_version(ctx.obj, ctx.command.name)
2021 if not interval:
2022 print('{}'.format(ctx.obj.ns.export_metric(metric_data)))
2023 else:
2024 i = 1
2025 while True:
2026 print('{} {}'.format(ctx.obj.ns.export_metric(metric_data),i))
2027 time.sleep(int(interval))
2028 i+=1
2029 except ClientException as inst:
2030 print((inst.message))
2031 exit(1)
2032
2033
2034 ####################
2035 # Other operations
2036 ####################
2037
2038 @cli.command(name='upload-package')
2039 @click.argument('filename')
2040 @click.pass_context
2041 def upload_package(ctx, filename):
2042 '''uploads a VNF package or NS package
2043
2044 FILENAME: VNF or NS package file (tar.gz)
2045 '''
2046 try:
2047 ctx.obj.package.upload(filename)
2048 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
2049 if fullclassname != 'osmclient.sol005.client.Client':
2050 ctx.obj.package.wait_for_upload(filename)
2051 except ClientException as inst:
2052 print((inst.message))
2053 exit(1)
2054
2055
2056 @cli.command(name='ns-scaling-show')
2057 @click.argument('ns_name')
2058 @click.pass_context
2059 def show_ns_scaling(ctx, ns_name):
2060 '''shows the status of a NS scaling operation
2061
2062 NS_NAME: name of the NS instance being scaled
2063 '''
2064 try:
2065 check_client_version(ctx.obj, ctx.command.name, 'v1')
2066 resp = ctx.obj.ns.list()
2067 except ClientException as inst:
2068 print((inst.message))
2069 exit(1)
2070
2071 table = PrettyTable(
2072 ['group-name',
2073 'instance-id',
2074 'operational status',
2075 'create-time',
2076 'vnfr ids'])
2077
2078 for ns in resp:
2079 if ns_name == ns['name']:
2080 nsopdata = ctx.obj.ns.get_opdata(ns['id'])
2081 scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
2082 for record in scaling_records:
2083 if 'instance' in record:
2084 instances = record['instance']
2085 for inst in instances:
2086 table.add_row(
2087 [record['scaling-group-name-ref'],
2088 inst['instance-id'],
2089 inst['op-status'],
2090 time.strftime('%Y-%m-%d %H:%M:%S',
2091 time.localtime(
2092 inst['create-time'])),
2093 inst['vnfrs']])
2094 table.align = 'l'
2095 print(table)
2096
2097
2098 @cli.command(name='ns-scale')
2099 @click.argument('ns_name')
2100 @click.option('--ns_scale_group', prompt=True)
2101 @click.option('--index', prompt=True)
2102 @click.pass_context
2103 def ns_scale(ctx, ns_name, ns_scale_group, index):
2104 '''scales NS
2105
2106 NS_NAME: name of the NS instance to be scaled
2107 '''
2108 try:
2109 check_client_version(ctx.obj, ctx.command.name, 'v1')
2110 ctx.obj.ns.scale(ns_name, ns_scale_group, index)
2111 except ClientException as inst:
2112 print((inst.message))
2113 exit(1)
2114
2115
2116 @cli.command(name='config-agent-list')
2117 @click.pass_context
2118 def config_agent_list(ctx):
2119 '''list config agents'''
2120 try:
2121 check_client_version(ctx.obj, ctx.command.name, 'v1')
2122 except ClientException as inst:
2123 print((inst.message))
2124 exit(1)
2125 table = PrettyTable(['name', 'account-type', 'details'])
2126 for account in ctx.obj.vca.list():
2127 table.add_row(
2128 [account['name'],
2129 account['account-type'],
2130 account['juju']])
2131 table.align = 'l'
2132 print(table)
2133
2134
2135 @cli.command(name='config-agent-delete')
2136 @click.argument('name')
2137 @click.pass_context
2138 def config_agent_delete(ctx, name):
2139 '''deletes a config agent
2140
2141 NAME: name of the config agent to be deleted
2142 '''
2143 try:
2144 check_client_version(ctx.obj, ctx.command.name, 'v1')
2145 ctx.obj.vca.delete(name)
2146 except ClientException as inst:
2147 print((inst.message))
2148 exit(1)
2149
2150
2151 @cli.command(name='config-agent-add')
2152 @click.option('--name',
2153 prompt=True)
2154 @click.option('--account_type',
2155 prompt=True)
2156 @click.option('--server',
2157 prompt=True)
2158 @click.option('--user',
2159 prompt=True)
2160 @click.option('--secret',
2161 prompt=True,
2162 hide_input=True,
2163 confirmation_prompt=True)
2164 @click.pass_context
2165 def config_agent_add(ctx, name, account_type, server, user, secret):
2166 '''adds a config agent'''
2167 try:
2168 check_client_version(ctx.obj, ctx.command.name, 'v1')
2169 ctx.obj.vca.create(name, account_type, server, user, secret)
2170 except ClientException as inst:
2171 print((inst.message))
2172 exit(1)
2173
2174 @cli.command(name='ro-dump')
2175 @click.pass_context
2176 def ro_dump(ctx):
2177 '''shows RO agent information'''
2178 check_client_version(ctx.obj, ctx.command.name, 'v1')
2179 resp = ctx.obj.vim.get_resource_orchestrator()
2180 table = PrettyTable(['key', 'attribute'])
2181 for k, v in list(resp.items()):
2182 table.add_row([k, json.dumps(v, indent=2)])
2183 table.align = 'l'
2184 print(table)
2185
2186
2187 @cli.command(name='vcs-list')
2188 @click.pass_context
2189 def vcs_list(ctx):
2190 check_client_version(ctx.obj, ctx.command.name, 'v1')
2191 resp = ctx.obj.utils.get_vcs_info()
2192 table = PrettyTable(['component name', 'state'])
2193 for component in resp:
2194 table.add_row([component['component_name'], component['state']])
2195 table.align = 'l'
2196 print(table)
2197
2198
2199 @cli.command(name='ns-action')
2200 @click.argument('ns_name')
2201 @click.option('--vnf_name', default=None)
2202 @click.option('--action_name', prompt=True)
2203 @click.option('--params', prompt=True)
2204 @click.pass_context
2205 def ns_action(ctx,
2206 ns_name,
2207 vnf_name,
2208 action_name,
2209 params):
2210 '''executes an action/primitive over a NS instance
2211
2212 NS_NAME: name or ID of the NS instance
2213 '''
2214 try:
2215 check_client_version(ctx.obj, ctx.command.name)
2216 op_data={}
2217 if vnf_name:
2218 op_data['vnf_member_index'] = vnf_name
2219 op_data['primitive'] = action_name
2220 op_data['primitive_params'] = yaml.load(params)
2221 ctx.obj.ns.exec_op(ns_name, op_name='action', op_data=op_data)
2222
2223 except ClientException as inst:
2224 print((inst.message))
2225 exit(1)
2226
2227
2228 @cli.command(name='vnf-scale')
2229 @click.argument('ns_name')
2230 @click.argument('vnf_name')
2231 @click.option('--scaling-group', prompt=True, help="scaling-group-descriptor name to use")
2232 @click.option('--scale-in', default=False, is_flag=True, help="performs a scale in operation")
2233 @click.option('--scale-out', default=False, is_flag=True, help="performs a scale out operation (by default)")
2234 @click.pass_context
2235 def vnf_scale(ctx,
2236 ns_name,
2237 vnf_name,
2238 scaling_group,
2239 scale_in,
2240 scale_out):
2241 '''executes a VNF scale (adding/removing VDUs)
2242
2243 \b
2244 NS_NAME: name or ID of the NS instance.
2245 VNF_NAME: member-vnf-index in the NS to be scaled.
2246 '''
2247 try:
2248 check_client_version(ctx.obj, ctx.command.name)
2249 if not scale_in and not scale_out:
2250 scale_out = True
2251 ctx.obj.ns.scale_vnf(ns_name, vnf_name, scaling_group, scale_in, scale_out)
2252 except ClientException as inst:
2253 print((inst.message))
2254 exit(1)
2255
2256
2257 if __name__ == '__main__':
2258 try:
2259 cli()
2260 except pycurl.error as e:
2261 print(e)
2262 print('Maybe "--hostname" option or OSM_HOSTNAME' +
2263 'environment variable needs to be specified')
2264 exit(1)
2265