Support of network slices
[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):
1060 '''creates a new Network Slice Instance (NSI)'''
1061 try:
1062 check_client_version(ctx.obj, ctx.command.name)
1063 ctx.obj.nsi.create(nst_name, nsi_name, config=config, ssh_keys=ssh_keys,
1064 account=vim_account)
1065 except ClientException as inst:
1066 print((inst.message))
1067 exit(1)
1068
1069
1070 @cli.command(name='nsi-create', short_help='creates a new Network Slice Instance')
1071 @click.option('--nsi_name', prompt=True, help='name of the Network Slice Instance')
1072 @click.option('--nst_name', prompt=True, help='name of the Network Slice Template')
1073 @click.option('--vim_account', prompt=True, help='default VIM account id or name for the deployment')
1074 @click.option('--ssh_keys', default=None,
1075 help='comma separated list of keys to inject to vnfs')
1076 @click.option('--config', default=None,
1077 help='Netslice specific yaml configuration:\n'
1078 'netslice_subnet: [\n'
1079 'id: TEXT, vim_account: TEXT,\n'
1080 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1081 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1082 '],\n'
1083 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1084 )
1085 @click.pass_context
1086 def nsi_create1(ctx, nst_name, nsi_name, vim_account, ssh_keys, config):
1087 '''creates a new Network Slice Instance (NSI)'''
1088 nsi_create(ctx, nst_name, nsi_name, vim_account, ssh_keys, config)
1089
1090
1091 @cli.command(name='netslice-instance-create', short_help='creates a new Network Slice Instance')
1092 @click.option('--nsi_name', prompt=True, help='name of the Network Slice Instance')
1093 @click.option('--nst_name', prompt=True, help='name of the Network Slice Template')
1094 @click.option('--vim_account', prompt=True, help='default VIM account id or name for the deployment')
1095 @click.option('--ssh_keys', default=None,
1096 help='comma separated list of keys to inject to vnfs')
1097 @click.option('--config', default=None,
1098 help='Netslice specific yaml configuration:\n'
1099 'netslice_subnet: [\n'
1100 'id: TEXT, vim_account: TEXT,\n'
1101 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1102 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1103 '],\n'
1104 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1105 )
1106 @click.pass_context
1107 def nsi_create2(ctx, nst_name, nsi_name, vim_account, ssh_keys, config):
1108 '''creates a new Network Slice Instance (NSI)'''
1109 nsi_create(ctx, nst_name, nsi_name, vim_account, ssh_keys, config)
1110
1111
1112 ####################
1113 # UPDATE operations
1114 ####################
1115
1116 def nsd_update(ctx, name, content):
1117 try:
1118 check_client_version(ctx.obj, ctx.command.name)
1119 ctx.obj.nsd.update(name, content)
1120 except ClientException as inst:
1121 print((inst.message))
1122 exit(1)
1123
1124
1125 @cli.command(name='nsd-update', short_help='updates a NSD/NSpkg')
1126 @click.argument('name')
1127 @click.option('--content', default=None,
1128 help='filename with the NSD/NSpkg replacing the current one')
1129 @click.pass_context
1130 def nsd_update1(ctx, name, content):
1131 '''updates a NSD/NSpkg
1132
1133 NAME: name or ID of the NSD/NSpkg
1134 '''
1135 nsd_update(ctx, name, content)
1136
1137
1138 @cli.command(name='nspkg-update', short_help='updates a NSD/NSpkg')
1139 @click.argument('name')
1140 @click.option('--content', default=None,
1141 help='filename with the NSD/NSpkg replacing the current one')
1142 @click.pass_context
1143 def nsd_update2(ctx, name, content):
1144 '''updates a NSD/NSpkg
1145
1146 NAME: name or ID of the NSD/NSpkg
1147 '''
1148 nsd_update(ctx, name, content)
1149
1150
1151 def vnfd_update(ctx, name, content):
1152 try:
1153 check_client_version(ctx.obj, ctx.command.name)
1154 ctx.obj.vnfd.update(name, content)
1155 except ClientException as inst:
1156 print((inst.message))
1157 exit(1)
1158
1159
1160 @cli.command(name='vnfd-update', short_help='updates a new VNFD/VNFpkg')
1161 @click.argument('name')
1162 @click.option('--content', default=None,
1163 help='filename with the VNFD/VNFpkg replacing the current one')
1164 @click.pass_context
1165 def vnfd_update1(ctx, name, content):
1166 '''updates a VNFD/VNFpkg
1167
1168 NAME: name or ID of the VNFD/VNFpkg
1169 '''
1170 vnfd_update(ctx, name, content)
1171
1172
1173 @cli.command(name='vnfpkg-update', short_help='updates a VNFD/VNFpkg')
1174 @click.argument('name')
1175 @click.option('--content', default=None,
1176 help='filename with the VNFD/VNFpkg replacing the current one')
1177 @click.pass_context
1178 def vnfd_update2(ctx, name, content):
1179 '''updates a VNFD/VNFpkg
1180
1181 NAME: VNFD yaml file or VNFpkg tar.gz file
1182 '''
1183 vnfd_update(ctx, name, content)
1184
1185
1186 def nst_update(ctx, name, content):
1187 try:
1188 check_client_version(ctx.obj, ctx.command.name)
1189 ctx.obj.nst.update(name, content)
1190 except ClientException as inst:
1191 print((inst.message))
1192 exit(1)
1193
1194
1195 @cli.command(name='nst-update', short_help='updates a Network Slice Template (NST)')
1196 @click.argument('name')
1197 @click.option('--content', default=None,
1198 help='filename with the NST/NSTpkg replacing the current one')
1199 @click.pass_context
1200 def nst_update1(ctx, name, content):
1201 '''updates a Network Slice Template (NST)
1202
1203 NAME: name or ID of the NSD/NSpkg
1204 '''
1205 nst_update(ctx, name, content)
1206
1207
1208 @cli.command(name='netslice-template-update', short_help='updates a Network Slice Template (NST)')
1209 @click.argument('name')
1210 @click.option('--content', default=None,
1211 help='filename with the NST/NSTpkg replacing the current one')
1212 @click.pass_context
1213 def nst_update2(ctx, name, content):
1214 '''updates a Network Slice Template (NST)
1215
1216 NAME: name or ID of the NSD/NSpkg
1217 '''
1218 nst_update(ctx, name, content)
1219
1220
1221 ####################
1222 # DELETE operations
1223 ####################
1224
1225 def nsd_delete(ctx, name, force):
1226 try:
1227 if not force:
1228 ctx.obj.nsd.delete(name)
1229 else:
1230 check_client_version(ctx.obj, '--force')
1231 ctx.obj.nsd.delete(name, force)
1232 except ClientException as inst:
1233 print((inst.message))
1234 exit(1)
1235
1236
1237 @cli.command(name='nsd-delete', short_help='deletes a NSD/NSpkg')
1238 @click.argument('name')
1239 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1240 @click.pass_context
1241 def nsd_delete1(ctx, name, force):
1242 '''deletes a NSD/NSpkg
1243
1244 NAME: name or ID of the NSD/NSpkg to be deleted
1245 '''
1246 nsd_delete(ctx, name, force)
1247
1248
1249 @cli.command(name='nspkg-delete', short_help='deletes a NSD/NSpkg')
1250 @click.argument('name')
1251 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1252 @click.pass_context
1253 def nsd_delete2(ctx, name, force):
1254 '''deletes a NSD/NSpkg
1255
1256 NAME: name or ID of the NSD/NSpkg to be deleted
1257 '''
1258 nsd_delete(ctx, name, force)
1259
1260
1261 def vnfd_delete(ctx, name, force):
1262 try:
1263 if not force:
1264 ctx.obj.vnfd.delete(name)
1265 else:
1266 check_client_version(ctx.obj, '--force')
1267 ctx.obj.vnfd.delete(name, force)
1268 except ClientException as inst:
1269 print((inst.message))
1270 exit(1)
1271
1272
1273 @cli.command(name='vnfd-delete', short_help='deletes a VNFD/VNFpkg')
1274 @click.argument('name')
1275 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1276 @click.pass_context
1277 def vnfd_delete1(ctx, name, force):
1278 '''deletes a VNFD/VNFpkg
1279
1280 NAME: name or ID of the VNFD/VNFpkg to be deleted
1281 '''
1282 vnfd_delete(ctx, name, force)
1283
1284
1285 @cli.command(name='vnfpkg-delete', short_help='deletes a VNFD/VNFpkg')
1286 @click.argument('name')
1287 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1288 @click.pass_context
1289 def vnfd_delete2(ctx, name, force):
1290 '''deletes a VNFD/VNFpkg
1291
1292 NAME: name or ID of the VNFD/VNFpkg to be deleted
1293 '''
1294 vnfd_delete(ctx, name, force)
1295
1296
1297 @cli.command(name='ns-delete', short_help='deletes a NS instance')
1298 @click.argument('name')
1299 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1300 @click.pass_context
1301 def ns_delete(ctx, name, force):
1302 '''deletes a NS instance
1303
1304 NAME: name or ID of the NS instance to be deleted
1305 '''
1306 try:
1307 if not force:
1308 ctx.obj.ns.delete(name)
1309 else:
1310 check_client_version(ctx.obj, '--force')
1311 ctx.obj.ns.delete(name, force)
1312 except ClientException as inst:
1313 print((inst.message))
1314 exit(1)
1315
1316
1317 def nst_delete(ctx, name, force):
1318 try:
1319 check_client_version(ctx.obj, ctx.command.name)
1320 ctx.obj.nst.delete(name, force)
1321 except ClientException as inst:
1322 print((inst.message))
1323 exit(1)
1324
1325
1326 @cli.command(name='nst-delete', short_help='deletes a Network Slice Template (NST)')
1327 @click.argument('name')
1328 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1329 @click.pass_context
1330 def nst_delete1(ctx, name, force):
1331 '''deletes a Network Slice Template (NST)
1332
1333 NAME: name or ID of the NST/NSTpkg to be deleted
1334 '''
1335 nst_delete(ctx, name, force)
1336
1337
1338 @cli.command(name='netslice-template-delete', short_help='deletes a Network Slice Template (NST)')
1339 @click.argument('name')
1340 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1341 @click.pass_context
1342 def nst_delete2(ctx, name, force):
1343 '''deletes a Network Slice Template (NST)
1344
1345 NAME: name or ID of the NST/NSTpkg to be deleted
1346 '''
1347 nst_delete(ctx, name, force)
1348
1349
1350 def nsi_delete(ctx, name, force):
1351 try:
1352 check_client_version(ctx.obj, ctx.command.name)
1353 ctx.obj.nsi.delete(name, force)
1354 except ClientException as inst:
1355 print((inst.message))
1356 exit(1)
1357
1358
1359 @cli.command(name='nsi-delete', short_help='deletes a Network Slice Instance (NSI)')
1360 @click.argument('name')
1361 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1362 @click.pass_context
1363 def nsi_delete1(ctx, name, force):
1364 '''deletes a Network Slice Instance (NSI)
1365
1366 NAME: name or ID of the Network Slice instance to be deleted
1367 '''
1368 nsi_delete(ctx, name, force)
1369
1370
1371 @cli.command(name='netslice-instance-delete', short_help='deletes a Network Slice Instance (NSI)')
1372 @click.argument('name')
1373 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1374 @click.pass_context
1375 def nsi_delete2(ctx, name, force):
1376 '''deletes a Network Slice Instance (NSI)
1377
1378 NAME: name or ID of the Network Slice instance to be deleted
1379 '''
1380 nsi_delete(ctx, name, force)
1381
1382
1383 ####################
1384 # VIM operations
1385 ####################
1386
1387 @cli.command(name='vim-create')
1388 @click.option('--name',
1389 prompt=True,
1390 help='Name to create datacenter')
1391 @click.option('--user',
1392 prompt=True,
1393 help='VIM username')
1394 @click.option('--password',
1395 prompt=True,
1396 hide_input=True,
1397 confirmation_prompt=True,
1398 help='VIM password')
1399 @click.option('--auth_url',
1400 prompt=True,
1401 help='VIM url')
1402 @click.option('--tenant',
1403 prompt=True,
1404 help='VIM tenant name')
1405 @click.option('--config',
1406 default=None,
1407 help='VIM specific config parameters')
1408 @click.option('--account_type',
1409 default='openstack',
1410 help='VIM type')
1411 @click.option('--description',
1412 default='no description',
1413 help='human readable description')
1414 @click.option('--sdn_controller', default=None, help='Name or id of the SDN controller associated to this VIM account')
1415 @click.option('--sdn_port_mapping', default=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1416 @click.pass_context
1417 def vim_create(ctx,
1418 name,
1419 user,
1420 password,
1421 auth_url,
1422 tenant,
1423 config,
1424 account_type,
1425 description,
1426 sdn_controller,
1427 sdn_port_mapping):
1428 '''creates a new VIM account
1429 '''
1430 try:
1431 if sdn_controller:
1432 check_client_version(ctx.obj, '--sdn_controller')
1433 if sdn_port_mapping:
1434 check_client_version(ctx.obj, '--sdn_port_mapping')
1435 vim = {}
1436 vim['vim-username'] = user
1437 vim['vim-password'] = password
1438 vim['vim-url'] = auth_url
1439 vim['vim-tenant-name'] = tenant
1440 vim['vim-type'] = account_type
1441 vim['description'] = description
1442 vim['config'] = config
1443 if sdn_controller or sdn_port_mapping:
1444 ctx.obj.vim.create(name, vim, sdn_controller, sdn_port_mapping)
1445 else:
1446 ctx.obj.vim.create(name, vim)
1447 except ClientException as inst:
1448 print((inst.message))
1449 exit(1)
1450
1451
1452 @cli.command(name='vim-update', short_help='updates a VIM account')
1453 @click.argument('name')
1454 @click.option('--newname', help='New name for the VIM account')
1455 @click.option('--user', help='VIM username')
1456 @click.option('--password', help='VIM password')
1457 @click.option('--auth_url', help='VIM url')
1458 @click.option('--tenant', help='VIM tenant name')
1459 @click.option('--config', help='VIM specific config parameters')
1460 @click.option('--account_type', help='VIM type')
1461 @click.option('--description', help='human readable description')
1462 @click.option('--sdn_controller', default=None, help='Name or id of the SDN controller associated to this VIM account')
1463 @click.option('--sdn_port_mapping', default=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1464 @click.pass_context
1465 def vim_update(ctx,
1466 name,
1467 newname,
1468 user,
1469 password,
1470 auth_url,
1471 tenant,
1472 config,
1473 account_type,
1474 description,
1475 sdn_controller,
1476 sdn_port_mapping):
1477 '''updates a VIM account
1478
1479 NAME: name or ID of the VIM account
1480 '''
1481 try:
1482 check_client_version(ctx.obj, ctx.command.name)
1483 vim = {}
1484 if newname: vim['name'] = newname
1485 if user: vim['vim_user'] = user
1486 if password: vim['vim_password'] = password
1487 if auth_url: vim['vim_url'] = auth_url
1488 if tenant: vim['vim-tenant-name'] = tenant
1489 if account_type: vim['vim_type'] = account_type
1490 if description: vim['description'] = description
1491 if config: vim['config'] = config
1492 ctx.obj.vim.update(name, vim, sdn_controller, sdn_port_mapping)
1493 except ClientException as inst:
1494 print((inst.message))
1495 exit(1)
1496
1497
1498 @cli.command(name='vim-delete')
1499 @click.argument('name')
1500 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1501 @click.pass_context
1502 def vim_delete(ctx, name, force):
1503 '''deletes a VIM account
1504
1505 NAME: name or ID of the VIM account to be deleted
1506 '''
1507 try:
1508 if not force:
1509 ctx.obj.vim.delete(name)
1510 else:
1511 check_client_version(ctx.obj, '--force')
1512 ctx.obj.vim.delete(name, force)
1513 except ClientException as inst:
1514 print((inst.message))
1515 exit(1)
1516
1517
1518 @cli.command(name='vim-list')
1519 @click.option('--ro_update/--no_ro_update',
1520 default=False,
1521 help='update list from RO')
1522 @click.option('--filter', default=None,
1523 help='restricts the list to the VIM accounts matching the filter')
1524 @click.pass_context
1525 def vim_list(ctx, ro_update, filter):
1526 '''list all VIM accounts'''
1527 if filter:
1528 check_client_version(ctx.obj, '--filter')
1529 if ro_update:
1530 check_client_version(ctx.obj, '--ro_update', 'v1')
1531 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
1532 if fullclassname == 'osmclient.sol005.client.Client':
1533 resp = ctx.obj.vim.list(filter)
1534 else:
1535 resp = ctx.obj.vim.list(ro_update)
1536 table = PrettyTable(['vim name', 'uuid'])
1537 for vim in resp:
1538 table.add_row([vim['name'], vim['uuid']])
1539 table.align = 'l'
1540 print(table)
1541
1542
1543 @cli.command(name='vim-show')
1544 @click.argument('name')
1545 @click.pass_context
1546 def vim_show(ctx, name):
1547 '''shows the details of a VIM account
1548
1549 NAME: name or ID of the VIM account
1550 '''
1551 try:
1552 resp = ctx.obj.vim.get(name)
1553 if 'vim_password' in resp:
1554 resp['vim_password']='********'
1555 except ClientException as inst:
1556 print((inst.message))
1557 exit(1)
1558
1559 table = PrettyTable(['key', 'attribute'])
1560 for k, v in list(resp.items()):
1561 table.add_row([k, json.dumps(v, indent=2)])
1562 table.align = 'l'
1563 print(table)
1564
1565
1566 ####################
1567 # SDN controller operations
1568 ####################
1569
1570 @cli.command(name='sdnc-create')
1571 @click.option('--name',
1572 prompt=True,
1573 help='Name to create sdn controller')
1574 @click.option('--type',
1575 prompt=True,
1576 help='SDN controller type')
1577 @click.option('--sdn_controller_version',
1578 help='SDN controller username')
1579 @click.option('--ip_address',
1580 prompt=True,
1581 help='SDN controller IP address')
1582 @click.option('--port',
1583 prompt=True,
1584 help='SDN controller port')
1585 @click.option('--switch_dpid',
1586 prompt=True,
1587 help='Switch DPID (Openflow Datapath ID)')
1588 @click.option('--user',
1589 help='SDN controller username')
1590 @click.option('--password',
1591 hide_input=True,
1592 confirmation_prompt=True,
1593 help='SDN controller password')
1594 #@click.option('--description',
1595 # default='no description',
1596 # help='human readable description')
1597 @click.pass_context
1598 def sdnc_create(ctx,
1599 name,
1600 type,
1601 sdn_controller_version,
1602 ip_address,
1603 port,
1604 switch_dpid,
1605 user,
1606 password):
1607 '''creates a new SDN controller
1608 '''
1609 sdncontroller = {}
1610 sdncontroller['name'] = name
1611 sdncontroller['type'] = type
1612 sdncontroller['ip'] = ip_address
1613 sdncontroller['port'] = int(port)
1614 sdncontroller['dpid'] = switch_dpid
1615 if sdn_controller_version:
1616 sdncontroller['version'] = sdn_controller_version
1617 if user:
1618 sdncontroller['user'] = user
1619 if password:
1620 sdncontroller['password'] = password
1621 # sdncontroller['description'] = description
1622 try:
1623 check_client_version(ctx.obj, ctx.command.name)
1624 ctx.obj.sdnc.create(name, sdncontroller)
1625 except ClientException as inst:
1626 print((inst.message))
1627
1628
1629 @cli.command(name='sdnc-update', short_help='updates an SDN controller')
1630 @click.argument('name')
1631 @click.option('--newname', help='New name for the SDN controller')
1632 @click.option('--type', help='SDN controller type')
1633 @click.option('--sdn_controller_version', help='SDN controller username')
1634 @click.option('--ip_address', help='SDN controller IP address')
1635 @click.option('--port', help='SDN controller port')
1636 @click.option('--switch_dpid', help='Switch DPID (Openflow Datapath ID)')
1637 @click.option('--user', help='SDN controller username')
1638 @click.option('--password', help='SDN controller password')
1639 #@click.option('--description', default=None, help='human readable description')
1640 @click.pass_context
1641 def sdnc_update(ctx,
1642 name,
1643 newname,
1644 type,
1645 sdn_controller_version,
1646 ip_address,
1647 port,
1648 switch_dpid,
1649 user,
1650 password):
1651 '''updates an SDN controller
1652
1653 NAME: name or ID of the SDN controller
1654 '''
1655 sdncontroller = {}
1656 if newname: sdncontroller['name'] = newname
1657 if type: sdncontroller['type'] = type
1658 if ip_address: sdncontroller['ip'] = ip_address
1659 if port: sdncontroller['port'] = int(port)
1660 if switch_dpid: sdncontroller['dpid'] = switch_dpid
1661 # sdncontroller['description'] = description
1662 if sdn_controller_version is not None:
1663 if sdn_controller_version=="":
1664 sdncontroller['version'] = None
1665 else:
1666 sdncontroller['version'] = sdn_controller_version
1667 if user is not None:
1668 if user=="":
1669 sdncontroller['user'] = None
1670 else:
1671 sdncontroller['user'] = user
1672 if password is not None:
1673 if password=="":
1674 sdncontroller['password'] = None
1675 else:
1676 sdncontroller['password'] = user
1677 try:
1678 check_client_version(ctx.obj, ctx.command.name)
1679 ctx.obj.sdnc.update(name, sdncontroller)
1680 except ClientException as inst:
1681 print((inst.message))
1682 exit(1)
1683
1684
1685 @cli.command(name='sdnc-delete')
1686 @click.argument('name')
1687 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1688 @click.pass_context
1689 def sdnc_delete(ctx, name, force):
1690 '''deletes an SDN controller
1691
1692 NAME: name or ID of the SDN controller to be deleted
1693 '''
1694 try:
1695 check_client_version(ctx.obj, ctx.command.name)
1696 ctx.obj.sdnc.delete(name, force)
1697 except ClientException as inst:
1698 print((inst.message))
1699 exit(1)
1700
1701
1702 @cli.command(name='sdnc-list')
1703 @click.option('--filter', default=None,
1704 help='restricts the list to the SDN controllers matching the filter')
1705 @click.pass_context
1706 def sdnc_list(ctx, filter):
1707 '''list all SDN controllers'''
1708 try:
1709 check_client_version(ctx.obj, ctx.command.name)
1710 resp = ctx.obj.sdnc.list(filter)
1711 except ClientException as inst:
1712 print((inst.message))
1713 exit(1)
1714 table = PrettyTable(['name', 'id'])
1715 for sdnc in resp:
1716 table.add_row([sdnc['name'], sdnc['_id']])
1717 table.align = 'l'
1718 print(table)
1719
1720
1721 @cli.command(name='sdnc-show')
1722 @click.argument('name')
1723 @click.pass_context
1724 def sdnc_show(ctx, name):
1725 '''shows the details of an SDN controller
1726
1727 NAME: name or ID of the SDN controller
1728 '''
1729 try:
1730 check_client_version(ctx.obj, ctx.command.name)
1731 resp = ctx.obj.sdnc.get(name)
1732 except ClientException as inst:
1733 print((inst.message))
1734 exit(1)
1735
1736 table = PrettyTable(['key', 'attribute'])
1737 for k, v in list(resp.items()):
1738 table.add_row([k, json.dumps(v, indent=2)])
1739 table.align = 'l'
1740 print(table)
1741
1742
1743 ####################
1744 # Project mgmt operations
1745 ####################
1746
1747 @cli.command(name='project-create')
1748 @click.argument('name')
1749 #@click.option('--description',
1750 # default='no description',
1751 # help='human readable description')
1752 @click.pass_context
1753 def project_create(ctx, name):
1754 '''Creates a new project
1755
1756 NAME: name of the project
1757 '''
1758 project = {}
1759 project['name'] = name
1760 try:
1761 check_client_version(ctx.obj, ctx.command.name)
1762 ctx.obj.project.create(name, project)
1763 except ClientException as inst:
1764 print(inst.message)
1765
1766
1767 @cli.command(name='project-delete')
1768 @click.argument('name')
1769 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1770 @click.pass_context
1771 def project_delete(ctx, name):
1772 '''deletes a project
1773
1774 NAME: name or ID of the project to be deleted
1775 '''
1776 try:
1777 check_client_version(ctx.obj, ctx.command.name)
1778 ctx.obj.project.delete(name)
1779 except ClientException as inst:
1780 print(inst.message)
1781 exit(1)
1782
1783
1784 @cli.command(name='project-list')
1785 @click.option('--filter', default=None,
1786 help='restricts the list to the projects matching the filter')
1787 @click.pass_context
1788 def project_list(ctx, filter):
1789 '''list all projects'''
1790 try:
1791 check_client_version(ctx.obj, ctx.command.name)
1792 resp = ctx.obj.project.list(filter)
1793 except ClientException as inst:
1794 print(inst.message)
1795 exit(1)
1796 table = PrettyTable(['name', 'id'])
1797 for proj in resp:
1798 table.add_row([proj['name'], proj['_id']])
1799 table.align = 'l'
1800 print(table)
1801
1802
1803 @cli.command(name='project-show')
1804 @click.argument('name')
1805 @click.pass_context
1806 def project_show(ctx, name):
1807 '''shows the details of a project
1808
1809 NAME: name or ID of the project
1810 '''
1811 try:
1812 check_client_version(ctx.obj, ctx.command.name)
1813 resp = ctx.obj.project.get(name)
1814 except ClientException as inst:
1815 print(inst.message)
1816 exit(1)
1817
1818 table = PrettyTable(['key', 'attribute'])
1819 for k, v in resp.items():
1820 table.add_row([k, json.dumps(v, indent=2)])
1821 table.align = 'l'
1822 print(table)
1823
1824
1825 ####################
1826 # User mgmt operations
1827 ####################
1828
1829 @cli.command(name='user-create')
1830 @click.argument('username')
1831 @click.option('--password',
1832 prompt=True,
1833 hide_input=True,
1834 confirmation_prompt=True,
1835 help='user password')
1836 @click.option('--projects',
1837 default=None,
1838 help='list of project ids that the user belongs to')
1839 #@click.option('--description',
1840 # default='no description',
1841 # help='human readable description')
1842 @click.pass_context
1843 def user_create(ctx, username, password, projects):
1844 '''Creates a new user
1845
1846 USERNAME: name of the user
1847 '''
1848 user = {}
1849 user['username'] = username
1850 user['password'] = password
1851 user['projects'] = projects
1852 try:
1853 check_client_version(ctx.obj, ctx.command.name)
1854 ctx.obj.user.create(username, user)
1855 except ClientException as inst:
1856 print(inst.message)
1857
1858
1859 @cli.command(name='user-delete')
1860 @click.argument('name')
1861 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1862 @click.pass_context
1863 def user_delete(ctx, name):
1864 '''deletes a user
1865
1866 NAME: name or ID of the user to be deleted
1867 '''
1868 try:
1869 check_client_version(ctx.obj, ctx.command.name)
1870 ctx.obj.user.delete(name)
1871 except ClientException as inst:
1872 print(inst.message)
1873 exit(1)
1874
1875
1876 @cli.command(name='user-list')
1877 @click.option('--filter', default=None,
1878 help='restricts the list to the users matching the filter')
1879 @click.pass_context
1880 def user_list(ctx, filter):
1881 '''list all users'''
1882 try:
1883 check_client_version(ctx.obj, ctx.command.name)
1884 resp = ctx.obj.user.list(filter)
1885 except ClientException as inst:
1886 print(inst.message)
1887 exit(1)
1888 table = PrettyTable(['name', 'id'])
1889 for user in resp:
1890 table.add_row([user['name'], user['_id']])
1891 table.align = 'l'
1892 print(table)
1893
1894
1895 @cli.command(name='user-show')
1896 @click.argument('name')
1897 @click.pass_context
1898 def user_show(ctx, name):
1899 '''shows the details of a user
1900
1901 NAME: name or ID of the user
1902 '''
1903 try:
1904 check_client_version(ctx.obj, ctx.command.name)
1905 resp = ctx.obj.user.get(name)
1906 if 'password' in resp:
1907 resp['password']='********'
1908 except ClientException as inst:
1909 print(inst.message)
1910 exit(1)
1911
1912 table = PrettyTable(['key', 'attribute'])
1913 for k, v in resp.items():
1914 table.add_row([k, json.dumps(v, indent=2)])
1915 table.align = 'l'
1916 print(table)
1917
1918
1919 ####################
1920 # Fault Management operations
1921 ####################
1922
1923 @cli.command(name='ns-alarm-create')
1924 @click.argument('name')
1925 @click.option('--ns', prompt=True, help='NS instance id or name')
1926 @click.option('--vnf', prompt=True,
1927 help='VNF name (VNF member index as declared in the NSD)')
1928 @click.option('--vdu', prompt=True,
1929 help='VDU name (VDU name as declared in the VNFD)')
1930 @click.option('--metric', prompt=True,
1931 help='Name of the metric (e.g. cpu_utilization)')
1932 @click.option('--severity', default='WARNING',
1933 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
1934 @click.option('--threshold_value', prompt=True,
1935 help='threshold value that, when crossed, an alarm is triggered')
1936 @click.option('--threshold_operator', prompt=True,
1937 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
1938 @click.option('--statistic', default='AVERAGE',
1939 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
1940 @click.pass_context
1941 def ns_alarm_create(ctx, name, ns, vnf, vdu, metric, severity,
1942 threshold_value, threshold_operator, statistic):
1943 '''creates a new alarm for a NS instance'''
1944 ns_instance = ctx.obj.ns.get(ns)
1945 alarm = {}
1946 alarm['alarm_name'] = name
1947 alarm['ns_id'] = ns_instance['_id']
1948 alarm['correlation_id'] = ns_instance['_id']
1949 alarm['vnf_member_index'] = vnf
1950 alarm['vdu_name'] = vdu
1951 alarm['metric_name'] = metric
1952 alarm['severity'] = severity
1953 alarm['threshold_value'] = int(threshold_value)
1954 alarm['operation'] = threshold_operator
1955 alarm['statistic'] = statistic
1956 try:
1957 check_client_version(ctx.obj, ctx.command.name)
1958 ctx.obj.ns.create_alarm(alarm)
1959 except ClientException as inst:
1960 print((inst.message))
1961 exit(1)
1962
1963
1964 #@cli.command(name='ns-alarm-delete')
1965 #@click.argument('name')
1966 #@click.pass_context
1967 #def ns_alarm_delete(ctx, name):
1968 # '''deletes an alarm
1969 #
1970 # NAME: name of the alarm to be deleted
1971 # '''
1972 # try:
1973 # check_client_version(ctx.obj, ctx.command.name)
1974 # ctx.obj.ns.delete_alarm(name)
1975 # except ClientException as inst:
1976 # print(inst.message)
1977 # exit(1)
1978
1979
1980 ####################
1981 # Performance Management operations
1982 ####################
1983
1984 @cli.command(name='ns-metric-export')
1985 @click.option('--ns', prompt=True, help='NS instance id or name')
1986 @click.option('--vnf', prompt=True,
1987 help='VNF name (VNF member index as declared in the NSD)')
1988 @click.option('--vdu', prompt=True,
1989 help='VDU name (VDU name as declared in the VNFD)')
1990 @click.option('--metric', prompt=True,
1991 help='name of the metric (e.g. cpu_utilization)')
1992 #@click.option('--period', default='1w',
1993 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
1994 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
1995 @click.pass_context
1996 def ns_metric_export(ctx, ns, vnf, vdu, metric, interval):
1997 '''exports a metric to the internal OSM bus, which can be read by other apps
1998 '''
1999 ns_instance = ctx.obj.ns.get(ns)
2000 metric_data = {}
2001 metric_data['ns_id'] = ns_instance['_id']
2002 metric_data['correlation_id'] = ns_instance['_id']
2003 metric_data['vnf_member_index'] = vnf
2004 metric_data['vdu_name'] = vdu
2005 metric_data['metric_name'] = metric
2006 metric_data['collection_unit'] = 'WEEK'
2007 metric_data['collection_period'] = 1
2008 try:
2009 check_client_version(ctx.obj, ctx.command.name)
2010 if not interval:
2011 print('{}'.format(ctx.obj.ns.export_metric(metric_data)))
2012 else:
2013 i = 1
2014 while True:
2015 print('{} {}'.format(ctx.obj.ns.export_metric(metric_data),i))
2016 time.sleep(int(interval))
2017 i+=1
2018 except ClientException as inst:
2019 print((inst.message))
2020 exit(1)
2021
2022
2023 ####################
2024 # Other operations
2025 ####################
2026
2027 @cli.command(name='upload-package')
2028 @click.argument('filename')
2029 @click.pass_context
2030 def upload_package(ctx, filename):
2031 '''uploads a VNF package or NS package
2032
2033 FILENAME: VNF or NS package file (tar.gz)
2034 '''
2035 try:
2036 ctx.obj.package.upload(filename)
2037 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
2038 if fullclassname != 'osmclient.sol005.client.Client':
2039 ctx.obj.package.wait_for_upload(filename)
2040 except ClientException as inst:
2041 print((inst.message))
2042 exit(1)
2043
2044
2045 @cli.command(name='ns-scaling-show')
2046 @click.argument('ns_name')
2047 @click.pass_context
2048 def show_ns_scaling(ctx, ns_name):
2049 '''shows the status of a NS scaling operation
2050
2051 NS_NAME: name of the NS instance being scaled
2052 '''
2053 try:
2054 check_client_version(ctx.obj, ctx.command.name, 'v1')
2055 resp = ctx.obj.ns.list()
2056 except ClientException as inst:
2057 print((inst.message))
2058 exit(1)
2059
2060 table = PrettyTable(
2061 ['group-name',
2062 'instance-id',
2063 'operational status',
2064 'create-time',
2065 'vnfr ids'])
2066
2067 for ns in resp:
2068 if ns_name == ns['name']:
2069 nsopdata = ctx.obj.ns.get_opdata(ns['id'])
2070 scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
2071 for record in scaling_records:
2072 if 'instance' in record:
2073 instances = record['instance']
2074 for inst in instances:
2075 table.add_row(
2076 [record['scaling-group-name-ref'],
2077 inst['instance-id'],
2078 inst['op-status'],
2079 time.strftime('%Y-%m-%d %H:%M:%S',
2080 time.localtime(
2081 inst['create-time'])),
2082 inst['vnfrs']])
2083 table.align = 'l'
2084 print(table)
2085
2086
2087 @cli.command(name='ns-scale')
2088 @click.argument('ns_name')
2089 @click.option('--ns_scale_group', prompt=True)
2090 @click.option('--index', prompt=True)
2091 @click.pass_context
2092 def ns_scale(ctx, ns_name, ns_scale_group, index):
2093 '''scales NS
2094
2095 NS_NAME: name of the NS instance to be scaled
2096 '''
2097 try:
2098 check_client_version(ctx.obj, ctx.command.name, 'v1')
2099 ctx.obj.ns.scale(ns_name, ns_scale_group, index)
2100 except ClientException as inst:
2101 print((inst.message))
2102 exit(1)
2103
2104
2105 @cli.command(name='config-agent-list')
2106 @click.pass_context
2107 def config_agent_list(ctx):
2108 '''list config agents'''
2109 try:
2110 check_client_version(ctx.obj, ctx.command.name, 'v1')
2111 except ClientException as inst:
2112 print((inst.message))
2113 exit(1)
2114 table = PrettyTable(['name', 'account-type', 'details'])
2115 for account in ctx.obj.vca.list():
2116 table.add_row(
2117 [account['name'],
2118 account['account-type'],
2119 account['juju']])
2120 table.align = 'l'
2121 print(table)
2122
2123
2124 @cli.command(name='config-agent-delete')
2125 @click.argument('name')
2126 @click.pass_context
2127 def config_agent_delete(ctx, name):
2128 '''deletes a config agent
2129
2130 NAME: name of the config agent to be deleted
2131 '''
2132 try:
2133 check_client_version(ctx.obj, ctx.command.name, 'v1')
2134 ctx.obj.vca.delete(name)
2135 except ClientException as inst:
2136 print((inst.message))
2137 exit(1)
2138
2139
2140 @cli.command(name='config-agent-add')
2141 @click.option('--name',
2142 prompt=True)
2143 @click.option('--account_type',
2144 prompt=True)
2145 @click.option('--server',
2146 prompt=True)
2147 @click.option('--user',
2148 prompt=True)
2149 @click.option('--secret',
2150 prompt=True,
2151 hide_input=True,
2152 confirmation_prompt=True)
2153 @click.pass_context
2154 def config_agent_add(ctx, name, account_type, server, user, secret):
2155 '''adds a config agent'''
2156 try:
2157 check_client_version(ctx.obj, ctx.command.name, 'v1')
2158 ctx.obj.vca.create(name, account_type, server, user, secret)
2159 except ClientException as inst:
2160 print((inst.message))
2161 exit(1)
2162
2163 @cli.command(name='ro-dump')
2164 @click.pass_context
2165 def ro_dump(ctx):
2166 '''shows RO agent information'''
2167 check_client_version(ctx.obj, ctx.command.name, 'v1')
2168 resp = ctx.obj.vim.get_resource_orchestrator()
2169 table = PrettyTable(['key', 'attribute'])
2170 for k, v in list(resp.items()):
2171 table.add_row([k, json.dumps(v, indent=2)])
2172 table.align = 'l'
2173 print(table)
2174
2175
2176 @cli.command(name='vcs-list')
2177 @click.pass_context
2178 def vcs_list(ctx):
2179 check_client_version(ctx.obj, ctx.command.name, 'v1')
2180 resp = ctx.obj.utils.get_vcs_info()
2181 table = PrettyTable(['component name', 'state'])
2182 for component in resp:
2183 table.add_row([component['component_name'], component['state']])
2184 table.align = 'l'
2185 print(table)
2186
2187
2188 @cli.command(name='ns-action')
2189 @click.argument('ns_name')
2190 @click.option('--vnf_name', default=None)
2191 @click.option('--action_name', prompt=True)
2192 @click.option('--params', prompt=True)
2193 @click.pass_context
2194 def ns_action(ctx,
2195 ns_name,
2196 vnf_name,
2197 action_name,
2198 params):
2199 '''executes an action/primitive over a NS instance
2200
2201 NS_NAME: name or ID of the NS instance
2202 '''
2203 try:
2204 check_client_version(ctx.obj, ctx.command.name)
2205 op_data={}
2206 if vnf_name:
2207 op_data['vnf_member_index'] = vnf_name
2208 op_data['primitive'] = action_name
2209 op_data['primitive_params'] = yaml.load(params)
2210 ctx.obj.ns.exec_op(ns_name, op_name='action', op_data=op_data)
2211
2212 except ClientException as inst:
2213 print((inst.message))
2214 exit(1)
2215
2216
2217 @cli.command(name='vnf-scale')
2218 @click.argument('ns_name')
2219 @click.argument('vnf_name')
2220 @click.option('--scaling-group', prompt=True, help="scaling-group-descriptor name to use")
2221 @click.option('--scale-in', default=False, is_flag=True, help="performs a scale in operation")
2222 @click.option('--scale-out', default=False, is_flag=True, help="performs a scale out operation (by default)")
2223 @click.pass_context
2224 def vnf_scale(ctx,
2225 ns_name,
2226 vnf_name,
2227 scaling_group,
2228 scale_in,
2229 scale_out):
2230 '''executes a VNF scale (adding/removing VDUs)
2231
2232 \b
2233 NS_NAME: name or ID of the NS instance.
2234 VNF_NAME: member-vnf-index in the NS to be scaled.
2235 '''
2236 try:
2237 check_client_version(ctx.obj, ctx.command.name)
2238 if not scale_in and not scale_out:
2239 scale_out = True
2240 ctx.obj.ns.scale_vnf(ns_name, vnf_name, scaling_group, scale_in, scale_out)
2241 except ClientException as inst:
2242 print((inst.message))
2243 exit(1)
2244
2245
2246 if __name__ == '__main__':
2247 try:
2248 cli()
2249 except pycurl.error as e:
2250 print(e)
2251 print('Maybe "--hostname" option or OSM_HOSTNAME' +
2252 'environment variable needs to be specified')
2253 exit(1)
2254