664ac629b576990559ab3c8aed517e5b7997fdb2
1 # Copyright 2017-2018 Sandvine
2 # Copyright 2018 Telefonica
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
10 # http://www.apache.org/licenses/LICENSE-2.0
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
22 from osmclient
import client
23 from osmclient
.common
.exceptions
import ClientException
24 from prettytable
import PrettyTable
34 def wrap_text(text
, width
):
35 wrapper
= textwrap
.TextWrapper(width
=width
)
36 lines
= text
.splitlines()
37 return "\n".join(map(wrapper
.fill
, lines
))
40 def trunc_text(text
, length
):
41 if len(text
) > length
:
42 return text
[:(length
- 3)] + '...'
47 def check_client_version(obj
, what
, version
='sol005'):
49 Checks the version of the client object and raises error if it not the expected.
51 :param obj: the client object
52 :what: the function or command under evaluation (used when an error is raised)
54 :raises ClientError: if the specified version does not match the client version
56 fullclassname
= obj
.__module
__ + "." + obj
.__class
__.__name
__
57 message
= 'The following commands or options are only supported with the option "--sol005": {}'.format(what
)
59 message
= 'The following commands or options are not supported when using option "--sol005": {}'.format(what
)
60 if fullclassname
!= 'osmclient.{}.client.Client'.format(version
):
61 raise ClientException(message
)
65 CONTEXT_SETTINGS
= dict(help_option_names
=['-h', '--help'], max_content_width
=160)
67 @click.group(context_settings
=CONTEXT_SETTINGS
)
68 @click.option('--hostname',
70 envvar
='OSM_HOSTNAME',
71 help='hostname of server. ' +
72 'Also can set OSM_HOSTNAME in environment')
73 #@click.option('--sol005/--no-sol005',
75 # envvar='OSM_SOL005',
76 # help='Use ETSI NFV SOL005 API (default) or the previous SO API. ' +
77 # 'Also can set OSM_SOL005 in environment')
78 @click.option('--user',
81 help='user (defaults to admin). ' +
82 'Also can set OSM_USER in environment')
83 @click.option('--password',
85 envvar
='OSM_PASSWORD',
86 help='password (defaults to admin). ' +
87 'Also can set OSM_PASSWORD in environment')
88 @click.option('--project',
91 help='project (defaults to admin). ' +
92 'Also can set OSM_PROJECT in environment')
93 #@click.option('--so-port',
95 # envvar='OSM_SO_PORT',
96 # help='hostname of server. ' +
97 # 'Also can set OSM_SO_PORT in environment')
98 #@click.option('--so-project',
100 # envvar='OSM_SO_PROJECT',
101 # help='Project Name in SO. ' +
102 # 'Also can set OSM_SO_PROJECT in environment')
103 #@click.option('--ro-hostname',
105 # envvar='OSM_RO_HOSTNAME',
106 # help='hostname of RO server. ' +
107 # 'Also can set OSM_RO_HOSTNAME in environment')
108 #@click.option('--ro-port',
110 # envvar='OSM_RO_PORT',
111 # help='hostname of RO server. ' +
112 # 'Also can set OSM_RO_PORT in environment')
114 def cli(ctx
, hostname
, user
, password
, project
):
117 "either hostname option or OSM_HOSTNAME " +
118 "environment variable needs to be specified"))
121 # if so_port is not None:
122 # kwargs['so_port']=so_port
123 # if so_project is not None:
124 # kwargs['so_project']=so_project
125 # if ro_hostname is not None:
126 # kwargs['ro_host']=ro_hostname
127 # if ro_port is not None:
128 # kwargs['ro_port']=ro_port
129 sol005
= os
.getenv('OSM_SOL005', True)
132 if password
is not None:
133 kwargs
['password']=password
134 if project
is not None:
135 kwargs
['project']=project
137 ctx
.obj
= client
.Client(host
=hostname
, sol005
=sol005
, **kwargs
)
144 @cli.command(name
='ns-list', short_help
='list all NS instances')
145 @click.option('--filter', default
=None,
146 help='restricts the list to the NS instances matching the filter.')
148 def ns_list(ctx
, filter):
149 """list all NS instances
153 --filter filterExpr Restricts the list to the NS instances matching the filter
156 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
157 concatenated using the "&" character:
160 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
161 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
162 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
164 value := scalar value
168 * zero or more occurrences
169 ? zero or one occurrence
170 [] grouping of expressions to be used with ? and *
171 "" quotation marks for marking string constants
175 "AttrName" is the name of one attribute in the data type that defines the representation
176 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
177 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
178 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
179 entries, it means that the operator "op" is applied to the attribute addressed by the last
180 <attrName> entry included in the concatenation. All simple filter expressions are combined
181 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
182 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
183 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
184 prefix". If an attribute referenced in an expression is an array, an object that contains a
185 corresponding array shall be considered to match the expression if any of the elements in the
186 array matches all expressions that have the same attribute prefix.
190 --filter admin-status=ENABLED
191 --filter nsd-ref=<NSD_NAME>
192 --filter nsd.vendor=<VENDOR>
193 --filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME>
194 --filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME>
197 check_client_version(ctx
.obj
, '--filter')
198 resp
= ctx
.obj
.ns
.list(filter)
200 resp
= ctx
.obj
.ns
.list()
204 'operational status',
208 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
209 if fullclassname
== 'osmclient.sol005.client.Client':
211 nsr_name
= nsr
['name']
214 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
215 nsr
= nsopdata
['nsr:nsr']
216 nsr_name
= nsr
['name-ref']
217 nsr_id
= nsr
['ns-instance-config-ref']
218 opstatus
= nsr
['operational-status'] if 'operational-status' in nsr
else 'Not found'
219 configstatus
= nsr
['config-status'] if 'config-status' in nsr
else 'Not found'
220 detailed_status
= nsr
['detailed-status'] if 'detailed-status' in nsr
else 'Not found'
221 detailed_status
= wrap_text(text
=detailed_status
,width
=50)
222 if configstatus
== "config_not_needed":
223 configstatus
= "configured (no charms)"
235 def nsd_list(ctx
, filter):
237 check_client_version(ctx
.obj
, '--filter')
238 resp
= ctx
.obj
.nsd
.list(filter)
240 resp
= ctx
.obj
.nsd
.list()
241 # print(yaml.safe_dump(resp))
242 table
= PrettyTable(['nsd name', 'id'])
243 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
244 if fullclassname
== 'osmclient.sol005.client.Client':
246 name
= ns
['name'] if 'name' in ns
else '-'
247 table
.add_row([name
, ns
['_id']])
250 table
.add_row([ns
['name'], ns
['id']])
255 @cli.command(name
='nsd-list', short_help
='list all NS packages')
256 @click.option('--filter', default
=None,
257 help='restricts the list to the NSD/NSpkg matching the filter')
259 def nsd_list1(ctx
, filter):
260 """list all NSD/NS pkg in the system"""
261 nsd_list(ctx
, filter)
264 @cli.command(name
='nspkg-list', short_help
='list all NS packages')
265 @click.option('--filter', default
=None,
266 help='restricts the list to the NSD/NSpkg matching the filter')
268 def nsd_list2(ctx
, filter):
269 """list all NS packages"""
270 nsd_list(ctx
, filter)
273 def vnfd_list(ctx
, nf_type
, filter):
275 check_client_version(ctx
.obj
, '--nf_type')
277 check_client_version(ctx
.obj
, '--filter')
280 nf_filter
= "_admin.type=vnfd"
281 elif nf_type
== "pnf":
282 nf_filter
= "_admin.type=pnfd"
283 elif nf_type
== "hnf":
284 nf_filter
= "_admin.type=hnfd"
286 raise ClientException('wrong value for "--nf_type" option, allowed values: vnf, pnf, hnf')
288 filter = '{}&{}'.format(nf_filter
, filter)
292 resp
= ctx
.obj
.vnfd
.list(filter)
294 resp
= ctx
.obj
.vnfd
.list()
295 # print(yaml.safe_dump(resp))
296 table
= PrettyTable(['nfpkg name', 'id'])
297 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
298 if fullclassname
== 'osmclient.sol005.client.Client':
300 name
= vnfd
['name'] if 'name' in vnfd
else '-'
301 table
.add_row([name
, vnfd
['_id']])
304 table
.add_row([vnfd
['name'], vnfd
['id']])
309 @cli.command(name
='vnfd-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
310 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
311 @click.option('--filter', default
=None,
312 help='restricts the list to the NF pkg matching the filter')
314 def vnfd_list1(ctx
, nf_type
, filter):
315 """list all xNF packages (VNF, HNF, PNF)"""
316 vnfd_list(ctx
, nf_type
, filter)
319 @cli.command(name
='vnfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
320 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
321 @click.option('--filter', default
=None,
322 help='restricts the list to the NFpkg matching the filter')
324 def vnfd_list2(ctx
, nf_type
, filter):
325 """list all xNF packages (VNF, HNF, PNF)"""
326 vnfd_list(ctx
, nf_type
, filter)
329 @cli.command(name
='nfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
330 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
331 @click.option('--filter', default
=None,
332 help='restricts the list to the NFpkg matching the filter')
334 def nfpkg_list(ctx
, nf_type
, filter):
335 """list all xNF packages (VNF, HNF, PNF)"""
337 check_client_version(ctx
.obj
, ctx
.command
.name
)
338 vnfd_list(ctx
, nf_type
, filter)
339 except ClientException
as e
:
344 def vnf_list(ctx
, ns
, filter):
348 check_client_version(ctx
.obj
, '--ns')
350 check_client_version(ctx
.obj
, '--filter')
351 resp
= ctx
.obj
.vnf
.list(ns
, filter)
353 resp
= ctx
.obj
.vnf
.list()
354 except ClientException
as e
:
357 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
358 if fullclassname
== 'osmclient.sol005.client.Client':
368 name
= vnfr
['name'] if 'name' in vnfr
else '-'
373 vnfr
['member-vnf-index-ref'],
375 vnfr
['vim-account-id'],
381 'operational status',
384 if 'mgmt-interface' not in vnfr
:
385 vnfr
['mgmt-interface'] = {}
386 vnfr
['mgmt-interface']['ip-address'] = None
390 vnfr
['operational-status'],
391 vnfr
['config-status']])
396 @cli.command(name
='vnf-list', short_help
='list all NF instances')
397 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
398 @click.option('--filter', default
=None,
399 help='restricts the list to the NF instances matching the filter.')
401 def vnf_list1(ctx
, ns
, filter):
402 """list all NF instances"""
403 vnf_list(ctx
, ns
, filter)
406 @cli.command(name
='nf-list', short_help
='list all NF instances')
407 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
408 @click.option('--filter', default
=None,
409 help='restricts the list to the NF instances matching the filter.')
411 def nf_list(ctx
, ns
, filter):
412 """list all NF instances
416 --ns TEXT NS instance id or name to restrict the VNF list
417 --filter filterExpr Restricts the list to the VNF instances matching the filter
420 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
421 concatenated using the "&" character:
424 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
425 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
426 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
428 value := scalar value
432 * zero or more occurrences
433 ? zero or one occurrence
434 [] grouping of expressions to be used with ? and *
435 "" quotation marks for marking string constants
439 "AttrName" is the name of one attribute in the data type that defines the representation
440 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
441 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
442 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
443 entries, it means that the operator "op" is applied to the attribute addressed by the last
444 <attrName> entry included in the concatenation. All simple filter expressions are combined
445 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
446 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
447 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
448 prefix". If an attribute referenced in an expression is an array, an object that contains a
449 corresponding array shall be considered to match the expression if any of the elements in the
450 array matches all expressions that have the same attribute prefix.
454 --filter vim-account-id=<VIM_ACCOUNT_ID>
455 --filter vnfd-ref=<VNFD_NAME>
456 --filter vdur.ip-address=<IP_ADDRESS>
457 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
459 vnf_list(ctx
, ns
, filter)
462 @cli.command(name
='ns-op-list', short_help
='shows the history of operations over a NS instance')
463 @click.argument('name')
465 def ns_op_list(ctx
, name
):
466 """shows the history of operations over a NS instance
468 NAME: name or ID of the NS instance
471 check_client_version(ctx
.obj
, ctx
.command
.name
)
472 resp
= ctx
.obj
.ns
.list_op(name
)
473 except ClientException
as e
:
477 table
= PrettyTable(['id', 'operation', 'action_name', 'status'])
478 #print(yaml.safe_dump(resp))
481 if op
['lcmOperationType']=='action':
482 action_name
= op
['operationParams']['primitive']
483 table
.add_row([op
['id'], op
['lcmOperationType'], action_name
,
484 op
['operationState']])
489 def nsi_list(ctx
, filter):
490 """list all Network Slice Instances"""
492 check_client_version(ctx
.obj
, ctx
.command
.name
)
493 resp
= ctx
.obj
.nsi
.list(filter)
494 except ClientException
as e
:
498 ['netslice instance name',
500 'operational status',
504 nsi_name
= nsi
['name']
506 opstatus
= nsi
['operational-status'] if 'operational-status' in nsi
else 'Not found'
507 configstatus
= nsi
['config-status'] if 'config-status' in nsi
else 'Not found'
508 detailed_status
= nsi
['detailed-status'] if 'detailed-status' in nsi
else 'Not found'
509 if configstatus
== "config_not_needed":
510 configstatus
= "configured (no charms)"
521 @cli.command(name
='nsi-list', short_help
='list all Network Slice Instances (NSI)')
522 @click.option('--filter', default
=None,
523 help='restricts the list to the Network Slice Instances matching the filter')
525 def nsi_list1(ctx
, filter):
526 """list all Network Slice Instances (NSI)"""
527 nsi_list(ctx
, filter)
530 @cli.command(name
='netslice-instance-list', short_help
='list all Network Slice Instances (NSI)')
531 @click.option('--filter', default
=None,
532 help='restricts the list to the Network Slice Instances matching the filter')
534 def nsi_list2(ctx
, filter):
535 """list all Network Slice Instances (NSI)"""
536 nsi_list(ctx
, filter)
539 def nst_list(ctx
, filter):
541 check_client_version(ctx
.obj
, ctx
.command
.name
)
542 resp
= ctx
.obj
.nst
.list(filter)
543 except ClientException
as e
:
546 # print(yaml.safe_dump(resp))
547 table
= PrettyTable(['nst name', 'id'])
549 name
= nst
['name'] if 'name' in nst
else '-'
550 table
.add_row([name
, nst
['_id']])
555 @cli.command(name
='nst-list', short_help
='list all Network Slice Templates (NST)')
556 @click.option('--filter', default
=None,
557 help='restricts the list to the NST matching the filter')
559 def nst_list1(ctx
, filter):
560 """list all Network Slice Templates (NST) in the system"""
561 nst_list(ctx
, filter)
564 @cli.command(name
='netslice-template-list', short_help
='list all Network Slice Templates (NST)')
565 @click.option('--filter', default
=None,
566 help='restricts the list to the NST matching the filter')
568 def nst_list2(ctx
, filter):
569 """list all Network Slice Templates (NST) in the system"""
570 nst_list(ctx
, filter)
573 def nsi_op_list(ctx
, name
):
575 check_client_version(ctx
.obj
, ctx
.command
.name
)
576 resp
= ctx
.obj
.nsi
.list_op(name
)
577 except ClientException
as e
:
580 table
= PrettyTable(['id', 'operation', 'status'])
582 table
.add_row([op
['id'], op
['lcmOperationType'],
583 op
['operationState']])
588 @cli.command(name
='nsi-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
589 @click.argument('name')
591 def nsi_op_list1(ctx
, name
):
592 """shows the history of operations over a Network Slice Instance (NSI)
594 NAME: name or ID of the Network Slice Instance
596 nsi_op_list(ctx
, name
)
599 @cli.command(name
='netslice-instance-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
600 @click.argument('name')
602 def nsi_op_list2(ctx
, name
):
603 """shows the history of operations over a Network Slice Instance (NSI)
605 NAME: name or ID of the Network Slice Instance
607 nsi_op_list(ctx
, name
)
610 @cli.command(name
='pdu-list', short_help
='list all Physical Deployment Units (PDU)')
611 @click.option('--filter', default
=None,
612 help='restricts the list to the Physical Deployment Units matching the filter')
614 def pdu_list(ctx
, filter):
615 """list all Physical Deployment Units (PDU)"""
617 check_client_version(ctx
.obj
, ctx
.command
.name
)
618 resp
= ctx
.obj
.pdu
.list(filter)
619 except ClientException
as e
:
628 pdu_name
= pdu
['name']
630 pdu_type
= pdu
['type']
631 pdu_ipaddress
= "None"
632 for iface
in pdu
['interfaces']:
634 pdu_ipaddress
= iface
['ip-address']
649 def nsd_show(ctx
, name
, literal
):
651 resp
= ctx
.obj
.nsd
.get(name
)
652 # resp = ctx.obj.nsd.get_individual(name)
653 except ClientException
as e
:
658 print(yaml
.safe_dump(resp
))
661 table
= PrettyTable(['field', 'value'])
662 for k
, v
in list(resp
.items()):
663 table
.add_row([k
, json
.dumps(v
, indent
=2)])
668 @cli.command(name
='nsd-show', short_help
='shows the content of a NSD')
669 @click.option('--literal', is_flag
=True,
670 help='print literally, no pretty table')
671 @click.argument('name')
673 def nsd_show1(ctx
, name
, literal
):
674 """shows the content of a NSD
676 NAME: name or ID of the NSD/NSpkg
678 nsd_show(ctx
, name
, literal
)
681 @cli.command(name
='nspkg-show', short_help
='shows the content of a NSD')
682 @click.option('--literal', is_flag
=True,
683 help='print literally, no pretty table')
684 @click.argument('name')
686 def nsd_show2(ctx
, name
, literal
):
687 """shows the content of a NSD
689 NAME: name or ID of the NSD/NSpkg
691 nsd_show(ctx
, name
, literal
)
694 def vnfd_show(ctx
, name
, literal
):
696 resp
= ctx
.obj
.vnfd
.get(name
)
697 # resp = ctx.obj.vnfd.get_individual(name)
698 except ClientException
as e
:
703 print(yaml
.safe_dump(resp
))
706 table
= PrettyTable(['field', 'value'])
707 for k
, v
in list(resp
.items()):
708 table
.add_row([k
, json
.dumps(v
, indent
=2)])
713 @cli.command(name
='vnfd-show', short_help
='shows the content of a VNFD')
714 @click.option('--literal', is_flag
=True,
715 help='print literally, no pretty table')
716 @click.argument('name')
718 def vnfd_show1(ctx
, name
, literal
):
719 """shows the content of a VNFD
721 NAME: name or ID of the VNFD/VNFpkg
723 vnfd_show(ctx
, name
, literal
)
726 @cli.command(name
='vnfpkg-show', short_help
='shows the content of a VNFD')
727 @click.option('--literal', is_flag
=True,
728 help='print literally, no pretty table')
729 @click.argument('name')
731 def vnfd_show2(ctx
, name
, literal
):
732 """shows the content of a VNFD
734 NAME: name or ID of the VNFD/VNFpkg
736 vnfd_show(ctx
, name
, literal
)
739 @cli.command(name
='nfpkg-show', short_help
='shows the content of a NF Descriptor')
740 @click.option('--literal', is_flag
=True,
741 help='print literally, no pretty table')
742 @click.argument('name')
744 def nfpkg_show(ctx
, name
, literal
):
745 """shows the content of a NF Descriptor
747 NAME: name or ID of the NFpkg
749 vnfd_show(ctx
, name
, literal
)
752 @cli.command(name
='ns-show', short_help
='shows the info of a NS instance')
753 @click.argument('name')
754 @click.option('--literal', is_flag
=True,
755 help='print literally, no pretty table')
756 @click.option('--filter', default
=None)
758 def ns_show(ctx
, name
, literal
, filter):
759 """shows the info of a NS instance
761 NAME: name or ID of the NS instance
764 ns
= ctx
.obj
.ns
.get(name
)
765 except ClientException
as e
:
770 print(yaml
.safe_dump(ns
))
773 table
= PrettyTable(['field', 'value'])
775 for k
, v
in list(ns
.items()):
776 if filter is None or filter in k
:
777 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
779 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
780 if fullclassname
!= 'osmclient.sol005.client.Client':
781 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
782 nsr_optdata
= nsopdata
['nsr:nsr']
783 for k
, v
in list(nsr_optdata
.items()):
784 if filter is None or filter in k
:
785 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2),width
=100)])
790 @cli.command(name
='vnf-show', short_help
='shows the info of a VNF instance')
791 @click.argument('name')
792 @click.option('--literal', is_flag
=True,
793 help='print literally, no pretty table')
794 @click.option('--filter', default
=None, help='restricts the information to the fields in the filter')
795 @click.option('--kdu', default
=None, help='KDU name (whose status will be shown)')
797 def vnf_show(ctx
, name
, literal
, filter, kdu
):
798 """shows the info of a VNF instance
800 NAME: name or ID of the VNF instance
804 raise ClientException('"--literal" option is incompatible with "--kdu" option')
806 raise ClientException('"--filter" option is incompatible with "--kdu" option')
809 check_client_version(ctx
.obj
, ctx
.command
.name
)
810 resp
= ctx
.obj
.vnf
.get(name
)
813 ns_id
= resp
['nsr-id-ref']
815 op_data
['member_vnf_index'] = resp
['member-vnf-index-ref']
816 op_data
['kdu_name'] = kdu
817 op_data
['primitive'] = 'status'
818 op_data
['primitive_params'] = {}
819 op_id
= ctx
.obj
.ns
.exec_op(ns_id
, op_name
='action', op_data
=op_data
, wait
=False)
822 op_info
= ctx
.obj
.ns
.get_op(op_id
)
823 if op_info
['operationState'] == 'COMPLETED':
824 print(op_info
['detailed-status'])
828 print ("Could not determine KDU status")
831 print(yaml
.safe_dump(resp
))
834 table
= PrettyTable(['field', 'value'])
836 for k
, v
in list(resp
.items()):
837 if filter is None or filter in k
:
838 table
.add_row([k
, wrap_text(text
=json
.dumps(v
,indent
=2),width
=100)])
841 except ClientException
as e
:
846 #@cli.command(name='vnf-monitoring-show')
847 #@click.argument('vnf_name')
849 #def vnf_monitoring_show(ctx, vnf_name):
851 # check_client_version(ctx.obj, ctx.command.name, 'v1')
852 # resp = ctx.obj.vnf.get_monitoring(vnf_name)
853 # except ClientException as e:
857 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
858 # if resp is not None:
859 # for monitor in resp:
863 # monitor['value-integer'],
869 #@cli.command(name='ns-monitoring-show')
870 #@click.argument('ns_name')
872 #def ns_monitoring_show(ctx, ns_name):
874 # check_client_version(ctx.obj, ctx.command.name, 'v1')
875 # resp = ctx.obj.ns.get_monitoring(ns_name)
876 # except ClientException as e:
880 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
881 # for key, val in list(resp.items()):
882 # for monitor in val:
886 # monitor['value-integer'],
892 @cli.command(name
='ns-op-show', short_help
='shows the info of a NS operation')
893 @click.argument('id')
894 @click.option('--filter', default
=None)
895 @click.option('--literal', is_flag
=True,
896 help='print literally, no pretty table')
898 def ns_op_show(ctx
, id, filter, literal
):
899 """shows the detailed info of a NS operation
901 ID: operation identifier
904 check_client_version(ctx
.obj
, ctx
.command
.name
)
905 op_info
= ctx
.obj
.ns
.get_op(id)
906 except ClientException
as e
:
911 print(yaml
.safe_dump(op_info
))
914 table
= PrettyTable(['field', 'value'])
915 for k
, v
in list(op_info
.items()):
916 if filter is None or filter in k
:
917 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
922 def nst_show(ctx
, name
, literal
):
924 check_client_version(ctx
.obj
, ctx
.command
.name
)
925 resp
= ctx
.obj
.nst
.get(name
)
926 #resp = ctx.obj.nst.get_individual(name)
927 except ClientException
as e
:
932 print(yaml
.safe_dump(resp
))
935 table
= PrettyTable(['field', 'value'])
936 for k
, v
in list(resp
.items()):
937 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
942 @cli.command(name
='nst-show', short_help
='shows the content of a Network Slice Template (NST)')
943 @click.option('--literal', is_flag
=True,
944 help='print literally, no pretty table')
945 @click.argument('name')
947 def nst_show1(ctx
, name
, literal
):
948 """shows the content of a Network Slice Template (NST)
950 NAME: name or ID of the NST
952 nst_show(ctx
, name
, literal
)
955 @cli.command(name
='netslice-template-show', short_help
='shows the content of a Network Slice Template (NST)')
956 @click.option('--literal', is_flag
=True,
957 help='print literally, no pretty table')
958 @click.argument('name')
960 def nst_show2(ctx
, name
, literal
):
961 """shows the content of a Network Slice Template (NST)
963 NAME: name or ID of the NST
965 nst_show(ctx
, name
, literal
)
968 def nsi_show(ctx
, name
, literal
, filter):
970 check_client_version(ctx
.obj
, ctx
.command
.name
)
971 nsi
= ctx
.obj
.nsi
.get(name
)
972 except ClientException
as e
:
977 print(yaml
.safe_dump(nsi
))
980 table
= PrettyTable(['field', 'value'])
982 for k
, v
in list(nsi
.items()):
983 if filter is None or filter in k
:
984 table
.add_row([k
, json
.dumps(v
, indent
=2)])
990 @cli.command(name
='nsi-show', short_help
='shows the content of a Network Slice Instance (NSI)')
991 @click.argument('name')
992 @click.option('--literal', is_flag
=True,
993 help='print literally, no pretty table')
994 @click.option('--filter', default
=None)
996 def nsi_show1(ctx
, name
, literal
, filter):
997 """shows the content of a Network Slice Instance (NSI)
999 NAME: name or ID of the Network Slice Instance
1001 nsi_show(ctx
, name
, literal
, filter)
1004 @cli.command(name
='netslice-instance-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1005 @click.argument('name')
1006 @click.option('--literal', is_flag
=True,
1007 help='print literally, no pretty table')
1008 @click.option('--filter', default
=None)
1010 def nsi_show2(ctx
, name
, literal
, filter):
1011 """shows the content of a Network Slice Instance (NSI)
1013 NAME: name or ID of the Network Slice Instance
1015 nsi_show(ctx
, name
, literal
, filter)
1018 def nsi_op_show(ctx
, id, filter):
1020 check_client_version(ctx
.obj
, ctx
.command
.name
)
1021 op_info
= ctx
.obj
.nsi
.get_op(id)
1022 except ClientException
as e
:
1026 table
= PrettyTable(['field', 'value'])
1027 for k
, v
in list(op_info
.items()):
1028 if filter is None or filter in k
:
1029 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1034 @cli.command(name
='nsi-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1035 @click.argument('id')
1036 @click.option('--filter', default
=None)
1038 def nsi_op_show1(ctx
, id, filter):
1039 """shows the info of an operation over a Network Slice Instance(NSI)
1041 ID: operation identifier
1043 nsi_op_show(ctx
, id, filter)
1046 @cli.command(name
='netslice-instance-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1047 @click.argument('id')
1048 @click.option('--filter', default
=None)
1050 def nsi_op_show2(ctx
, id, filter):
1051 """shows the info of an operation over a Network Slice Instance(NSI)
1053 ID: operation identifier
1055 nsi_op_show(ctx
, id, filter)
1058 @cli.command(name
='pdu-show', short_help
='shows the content of a Physical Deployment Unit (PDU)')
1059 @click.argument('name')
1060 @click.option('--literal', is_flag
=True,
1061 help='print literally, no pretty table')
1062 @click.option('--filter', default
=None)
1064 def pdu_show(ctx
, name
, literal
, filter):
1065 """shows the content of a Physical Deployment Unit (PDU)
1067 NAME: name or ID of the PDU
1070 check_client_version(ctx
.obj
, ctx
.command
.name
)
1071 pdu
= ctx
.obj
.pdu
.get(name
)
1072 except ClientException
as e
:
1077 print(yaml
.safe_dump(pdu
))
1080 table
= PrettyTable(['field', 'value'])
1082 for k
, v
in list(pdu
.items()):
1083 if filter is None or filter in k
:
1084 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1090 ####################
1092 ####################
1094 def nsd_create(ctx
, filename
, overwrite
):
1096 check_client_version(ctx
.obj
, ctx
.command
.name
)
1097 ctx
.obj
.nsd
.create(filename
, overwrite
)
1098 except ClientException
as e
:
1103 @cli.command(name
='nsd-create', short_help
='creates a new NSD/NSpkg')
1104 @click.argument('filename')
1105 @click.option('--overwrite', 'overwrite', default
=None, hidden
=True,
1106 help='Deprecated. Use override')
1107 @click.option('--override', 'overwrite', default
=None,
1108 help='overrides fields in descriptor, format: '
1109 '"key1.key2...=value[;key3...=value;...]"')
1111 def nsd_create1(ctx
, filename
, overwrite
):
1112 """creates a new NSD/NSpkg
1114 FILENAME: NSD yaml file or NSpkg tar.gz file
1116 nsd_create(ctx
, filename
, overwrite
)
1119 @cli.command(name
='nspkg-create', short_help
='creates a new NSD/NSpkg')
1120 @click.argument('filename')
1121 @click.option('--overwrite', 'overwrite', default
=None, hidden
=True,
1122 help='Deprecated. Use override')
1123 @click.option('--override', 'overwrite', default
=None,
1124 help='overrides fields in descriptor, format: '
1125 '"key1.key2...=value[;key3...=value;...]"')
1127 def nsd_create2(ctx
, filename
, overwrite
):
1128 """creates a new NSD/NSpkg
1130 FILENAME: NSD yaml file or NSpkg tar.gz file
1132 nsd_create(ctx
, filename
, overwrite
)
1135 def vnfd_create(ctx
, filename
, overwrite
):
1137 check_client_version(ctx
.obj
, ctx
.command
.name
)
1138 ctx
.obj
.vnfd
.create(filename
, overwrite
)
1139 except ClientException
as e
:
1144 @cli.command(name
='vnfd-create', short_help
='creates a new VNFD/VNFpkg')
1145 @click.argument('filename')
1146 @click.option('--overwrite', 'overwrite', default
=None,
1147 help='overwrite deprecated, use override')
1148 @click.option('--override', 'overwrite', default
=None,
1149 help='overrides fields in descriptor, format: '
1150 '"key1.key2...=value[;key3...=value;...]"')
1152 def vnfd_create1(ctx
, filename
, overwrite
):
1153 """creates a new VNFD/VNFpkg
1155 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1157 vnfd_create(ctx
, filename
, overwrite
)
1160 @cli.command(name
='vnfpkg-create', short_help
='creates a new VNFD/VNFpkg')
1161 @click.argument('filename')
1162 @click.option('--overwrite', 'overwrite', default
=None, hidden
=True,
1163 help='Deprecated. Use override')
1164 @click.option('--override', 'overwrite', default
=None,
1165 help='overrides fields in descriptor, format: '
1166 '"key1.key2...=value[;key3...=value;...]"')
1168 def vnfd_create2(ctx
, filename
, overwrite
):
1169 """creates a new VNFD/VNFpkg
1171 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1173 vnfd_create(ctx
, filename
, overwrite
)
1176 @cli.command(name
='nfpkg-create', short_help
='creates a new NFpkg')
1177 @click.argument('filename')
1178 @click.option('--overwrite', 'overwrite', default
=None, hidden
=True,
1179 help='Deprecated. Use override')
1180 @click.option('--override', 'overwrite', default
=None,
1181 help='overrides fields in descriptor, format: '
1182 '"key1.key2...=value[;key3...=value;...]"')
1184 def nfpkg_create(ctx
, filename
, overwrite
):
1185 """creates a new NFpkg
1187 FILENAME: NF Descriptor yaml file or NFpkg tar.gz file
1189 vnfd_create(ctx
, filename
, overwrite
)
1192 @cli.command(name
='ns-create', short_help
='creates a new Network Service instance')
1193 @click.option('--ns_name',
1194 prompt
=True, help='name of the NS instance')
1195 @click.option('--nsd_name',
1196 prompt
=True, help='name of the NS descriptor')
1197 @click.option('--vim_account',
1198 prompt
=True, help='default VIM account id or name for the deployment')
1199 @click.option('--admin_status',
1201 help='administration status')
1202 @click.option('--ssh_keys',
1204 help='comma separated list of public key files to inject to vnfs')
1205 @click.option('--config',
1207 help='ns specific yaml configuration')
1208 @click.option('--config_file',
1210 help='ns specific yaml configuration file')
1211 @click.option('--wait',
1215 help='do not return the control immediately, but keep it '
1216 'until the operation is completed, or timeout')
1227 """creates a new NS instance"""
1230 check_client_version(ctx
.obj
, '--config_file')
1232 raise ClientException('"--config" option is incompatible with "--config_file" option')
1233 with
open(config_file
, 'r') as cf
:
1240 account
=vim_account
,
1242 except ClientException
as e
:
1247 def nst_create(ctx
, filename
, overwrite
):
1249 check_client_version(ctx
.obj
, ctx
.command
.name
)
1250 ctx
.obj
.nst
.create(filename
, overwrite
)
1251 except ClientException
as e
:
1256 @cli.command(name
='nst-create', short_help
='creates a new Network Slice Template (NST)')
1257 @click.argument('filename')
1258 @click.option('--overwrite', 'overwrite', default
=None, hidden
=True,
1259 help='Deprecated. Use override')
1260 @click.option('--override', 'overwrite', default
=None,
1261 help='overrides fields in descriptor, format: '
1262 '"key1.key2...=value[;key3...=value;...]"')
1264 def nst_create1(ctx
, filename
, overwrite
):
1265 """creates a new Network Slice Template (NST)
1267 FILENAME: NST yaml file or NSTpkg tar.gz file
1269 nst_create(ctx
, filename
, overwrite
)
1272 @cli.command(name
='netslice-template-create', short_help
='creates a new Network Slice Template (NST)')
1273 @click.argument('filename')
1274 @click.option('--overwrite', 'overwrite', default
=None, hidden
=True,
1275 help='Deprecated. Use override')
1276 @click.option('--override', 'overwrite', default
=None,
1277 help='overrides fields in descriptor, format: '
1278 '"key1.key2...=value[;key3...=value;...]"')
1280 def nst_create2(ctx
, filename
, overwrite
):
1281 """creates a new Network Slice Template (NST)
1283 FILENAME: NST yaml file or NSTpkg tar.gz file
1285 nst_create(ctx
, filename
, overwrite
)
1288 def nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1289 """creates a new Network Slice Instance (NSI)"""
1291 check_client_version(ctx
.obj
, ctx
.command
.name
)
1294 raise ClientException('"--config" option is incompatible with "--config_file" option')
1295 with
open(config_file
, 'r') as cf
:
1297 ctx
.obj
.nsi
.create(nst_name
, nsi_name
, config
=config
, ssh_keys
=ssh_keys
,
1298 account
=vim_account
, wait
=wait
)
1299 except ClientException
as e
:
1304 @cli.command(name
='nsi-create', short_help
='creates a new Network Slice Instance')
1305 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1306 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1307 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1308 @click.option('--ssh_keys', default
=None,
1309 help='comma separated list of keys to inject to vnfs')
1310 @click.option('--config', default
=None,
1311 help='Netslice specific yaml configuration:\n'
1312 'netslice_subnet: [\n'
1313 'id: TEXT, vim_account: TEXT,\n'
1314 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1315 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]\n'
1316 'additionalParamsForNsi: {param: value, ...}\n'
1317 'additionalParamsForsubnet: [{id: SUBNET_ID, additionalParamsForNs: {}, additionalParamsForVnf: {}}]\n'
1319 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1321 @click.option('--config_file',
1323 help='nsi specific yaml configuration file')
1324 @click.option('--wait',
1328 help='do not return the control immediately, but keep it '
1329 'until the operation is completed, or timeout')
1331 def nsi_create1(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1332 """creates a new Network Slice Instance (NSI)"""
1333 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1336 @cli.command(name
='netslice-instance-create', short_help
='creates a new Network Slice Instance')
1337 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1338 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1339 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1340 @click.option('--ssh_keys', default
=None,
1341 help='comma separated list of keys to inject to vnfs')
1342 @click.option('--config', default
=None,
1343 help='Netslice specific yaml configuration:\n'
1344 'netslice_subnet: [\n'
1345 'id: TEXT, vim_account: TEXT,\n'
1346 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1347 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1349 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1351 @click.option('--config_file',
1353 help='nsi specific yaml configuration file')
1354 @click.option('--wait',
1358 help='do not return the control immediately, but keep it '
1359 'until the operation is completed, or timeout')
1361 def nsi_create2(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1362 """creates a new Network Slice Instance (NSI)"""
1363 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1366 @cli.command(name
='pdu-create', short_help
='adds a new Physical Deployment Unit to the catalog')
1367 @click.option('--name', help='name of the Physical Deployment Unit')
1368 @click.option('--pdu_type', help='type of PDU (e.g. router, firewall, FW001)')
1369 @click.option('--interface',
1370 help='interface(s) of the PDU: name=<NAME>,mgmt=<true|false>,ip-address=<IP_ADDRESS>'+
1371 '[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]',
1373 @click.option('--description', help='human readable description')
1374 @click.option('--vim_account', help='list of VIM accounts (in the same VIM) that can reach this PDU', multiple
=True)
1375 @click.option('--descriptor_file', default
=None,
1376 help='PDU descriptor file (as an alternative to using the other arguments')
1378 def pdu_create(ctx
, name
, pdu_type
, interface
, description
, vim_account
, descriptor_file
):
1379 """creates a new Physical Deployment Unit (PDU)"""
1381 check_client_version(ctx
.obj
, ctx
.command
.name
)
1383 if not descriptor_file
:
1385 raise ClientException('in absence of descriptor file, option "--name" is mandatory')
1387 raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory')
1389 raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)')
1391 raise ClientException('in absence of descriptor file, option "--vim_account" is mandatory (at least once)')
1393 with
open(descriptor_file
, 'r') as df
:
1394 pdu
= yaml
.safe_load(df
.read())
1395 if name
: pdu
["name"] = name
1396 if pdu_type
: pdu
["type"] = pdu_type
1397 if description
: pdu
["description"] = description
1398 if vim_account
: pdu
["vim_accounts"] = vim_account
1401 for iface
in interface
:
1402 new_iface
={k
:v
for k
,v
in [i
.split('=') for i
in iface
.split(',')]}
1403 new_iface
["mgmt"] = (new_iface
.get("mgmt","false").lower() == "true")
1404 ifaces_list
.append(new_iface
)
1405 pdu
["interfaces"] = ifaces_list
1406 ctx
.obj
.pdu
.create(pdu
)
1407 except ClientException
as e
:
1411 ####################
1413 ####################
1415 def nsd_update(ctx
, name
, content
):
1417 check_client_version(ctx
.obj
, ctx
.command
.name
)
1418 ctx
.obj
.nsd
.update(name
, content
)
1419 except ClientException
as e
:
1424 @cli.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
1425 @click.argument('name')
1426 @click.option('--content', default
=None,
1427 help='filename with the NSD/NSpkg replacing the current one')
1429 def nsd_update1(ctx
, name
, content
):
1430 """updates a NSD/NSpkg
1432 NAME: name or ID of the NSD/NSpkg
1434 nsd_update(ctx
, name
, content
)
1437 @cli.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
1438 @click.argument('name')
1439 @click.option('--content', default
=None,
1440 help='filename with the NSD/NSpkg replacing the current one')
1442 def nsd_update2(ctx
, name
, content
):
1443 """updates a NSD/NSpkg
1445 NAME: name or ID of the NSD/NSpkg
1447 nsd_update(ctx
, name
, content
)
1450 def vnfd_update(ctx
, name
, content
):
1452 check_client_version(ctx
.obj
, ctx
.command
.name
)
1453 ctx
.obj
.vnfd
.update(name
, content
)
1454 except ClientException
as e
:
1459 @cli.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
1460 @click.argument('name')
1461 @click.option('--content', default
=None,
1462 help='filename with the VNFD/VNFpkg replacing the current one')
1464 def vnfd_update1(ctx
, name
, content
):
1465 """updates a VNFD/VNFpkg
1467 NAME: name or ID of the VNFD/VNFpkg
1469 vnfd_update(ctx
, name
, content
)
1472 @cli.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
1473 @click.argument('name')
1474 @click.option('--content', default
=None,
1475 help='filename with the VNFD/VNFpkg replacing the current one')
1477 def vnfd_update2(ctx
, name
, content
):
1478 """updates a VNFD/VNFpkg
1480 NAME: VNFD yaml file or VNFpkg tar.gz file
1482 vnfd_update(ctx
, name
, content
)
1485 @cli.command(name
='nfpkg-update', short_help
='updates a NFpkg')
1486 @click.argument('name')
1487 @click.option('--content', default
=None,
1488 help='filename with the NFpkg replacing the current one')
1490 def nfpkg_update(ctx
, name
, content
):
1493 NAME: NF Descriptor yaml file or NFpkg tar.gz file
1495 vnfd_update(ctx
, name
, content
)
1498 def nst_update(ctx
, name
, content
):
1500 check_client_version(ctx
.obj
, ctx
.command
.name
)
1501 ctx
.obj
.nst
.update(name
, content
)
1502 except ClientException
as e
:
1507 @cli.command(name
='nst-update', short_help
='updates a Network Slice Template (NST)')
1508 @click.argument('name')
1509 @click.option('--content', default
=None,
1510 help='filename with the NST/NSTpkg replacing the current one')
1512 def nst_update1(ctx
, name
, content
):
1513 """updates a Network Slice Template (NST)
1515 NAME: name or ID of the NSD/NSpkg
1517 nst_update(ctx
, name
, content
)
1520 @cli.command(name
='netslice-template-update', short_help
='updates a Network Slice Template (NST)')
1521 @click.argument('name')
1522 @click.option('--content', default
=None,
1523 help='filename with the NST/NSTpkg replacing the current one')
1525 def nst_update2(ctx
, name
, content
):
1526 """updates a Network Slice Template (NST)
1528 NAME: name or ID of the NSD/NSpkg
1530 nst_update(ctx
, name
, content
)
1533 ####################
1535 ####################
1537 def nsd_delete(ctx
, name
, force
):
1540 ctx
.obj
.nsd
.delete(name
)
1542 check_client_version(ctx
.obj
, '--force')
1543 ctx
.obj
.nsd
.delete(name
, force
)
1544 except ClientException
as e
:
1549 @cli.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
1550 @click.argument('name')
1551 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1553 def nsd_delete1(ctx
, name
, force
):
1554 """deletes a NSD/NSpkg
1556 NAME: name or ID of the NSD/NSpkg to be deleted
1558 nsd_delete(ctx
, name
, force
)
1561 @cli.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
1562 @click.argument('name')
1563 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1565 def nsd_delete2(ctx
, name
, force
):
1566 """deletes a NSD/NSpkg
1568 NAME: name or ID of the NSD/NSpkg to be deleted
1570 nsd_delete(ctx
, name
, force
)
1573 def vnfd_delete(ctx
, name
, force
):
1576 ctx
.obj
.vnfd
.delete(name
)
1578 check_client_version(ctx
.obj
, '--force')
1579 ctx
.obj
.vnfd
.delete(name
, force
)
1580 except ClientException
as e
:
1585 @cli.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
1586 @click.argument('name')
1587 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1589 def vnfd_delete1(ctx
, name
, force
):
1590 """deletes a VNFD/VNFpkg
1592 NAME: name or ID of the VNFD/VNFpkg to be deleted
1594 vnfd_delete(ctx
, name
, force
)
1597 @cli.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
1598 @click.argument('name')
1599 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1601 def vnfd_delete2(ctx
, name
, force
):
1602 """deletes a VNFD/VNFpkg
1604 NAME: name or ID of the VNFD/VNFpkg to be deleted
1606 vnfd_delete(ctx
, name
, force
)
1609 @cli.command(name
='nfpkg-delete', short_help
='deletes a NFpkg')
1610 @click.argument('name')
1611 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1613 def nfpkg_delete(ctx
, name
, force
):
1616 NAME: name or ID of the NFpkg to be deleted
1618 vnfd_delete(ctx
, name
, force
)
1621 @cli.command(name
='ns-delete', short_help
='deletes a NS instance')
1622 @click.argument('name')
1623 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1624 @click.option('--wait',
1628 help='do not return the control immediately, but keep it '
1629 'until the operation is completed, or timeout')
1631 def ns_delete(ctx
, name
, force
, wait
):
1632 """deletes a NS instance
1634 NAME: name or ID of the NS instance to be deleted
1638 ctx
.obj
.ns
.delete(name
, wait
=wait
)
1640 check_client_version(ctx
.obj
, '--force')
1641 ctx
.obj
.ns
.delete(name
, force
, wait
=wait
)
1642 except ClientException
as e
:
1647 def nst_delete(ctx
, name
, force
):
1649 check_client_version(ctx
.obj
, ctx
.command
.name
)
1650 ctx
.obj
.nst
.delete(name
, force
)
1651 except ClientException
as e
:
1656 @cli.command(name
='nst-delete', short_help
='deletes a Network Slice Template (NST)')
1657 @click.argument('name')
1658 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1660 def nst_delete1(ctx
, name
, force
):
1661 """deletes a Network Slice Template (NST)
1663 NAME: name or ID of the NST/NSTpkg to be deleted
1665 nst_delete(ctx
, name
, force
)
1668 @cli.command(name
='netslice-template-delete', short_help
='deletes a Network Slice Template (NST)')
1669 @click.argument('name')
1670 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1672 def nst_delete2(ctx
, name
, force
):
1673 """deletes a Network Slice Template (NST)
1675 NAME: name or ID of the NST/NSTpkg to be deleted
1677 nst_delete(ctx
, name
, force
)
1680 def nsi_delete(ctx
, name
, force
, wait
):
1682 check_client_version(ctx
.obj
, ctx
.command
.name
)
1683 ctx
.obj
.nsi
.delete(name
, force
, wait
=wait
)
1684 except ClientException
as e
:
1689 @cli.command(name
='nsi-delete', short_help
='deletes a Network Slice Instance (NSI)')
1690 @click.argument('name')
1691 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1692 @click.option('--wait',
1696 help='do not return the control immediately, but keep it '
1697 'until the operation is completed, or timeout')
1699 def nsi_delete1(ctx
, name
, force
, wait
):
1700 """deletes a Network Slice Instance (NSI)
1702 NAME: name or ID of the Network Slice instance to be deleted
1704 nsi_delete(ctx
, name
, force
, wait
=wait
)
1707 @cli.command(name
='netslice-instance-delete', short_help
='deletes a Network Slice Instance (NSI)')
1708 @click.argument('name')
1709 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1711 def nsi_delete2(ctx
, name
, force
, wait
):
1712 """deletes a Network Slice Instance (NSI)
1714 NAME: name or ID of the Network Slice instance to be deleted
1716 nsi_delete(ctx
, name
, force
, wait
=wait
)
1719 @cli.command(name
='pdu-delete', short_help
='deletes a Physical Deployment Unit (PDU)')
1720 @click.argument('name')
1721 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1723 def pdu_delete(ctx
, name
, force
):
1724 """deletes a Physical Deployment Unit (PDU)
1726 NAME: name or ID of the PDU to be deleted
1729 check_client_version(ctx
.obj
, ctx
.command
.name
)
1730 ctx
.obj
.pdu
.delete(name
, force
)
1731 except ClientException
as e
:
1740 @cli.command(name
='vim-create', short_help
='creates a new VIM account')
1741 @click.option('--name',
1743 help='Name to create datacenter')
1744 @click.option('--user',
1746 help='VIM username')
1747 @click.option('--password',
1750 confirmation_prompt
=True,
1751 help='VIM password')
1752 @click.option('--auth_url',
1755 @click.option('--tenant',
1757 help='VIM tenant name')
1758 @click.option('--config',
1760 help='VIM specific config parameters')
1761 @click.option('--account_type',
1762 default
='openstack',
1764 @click.option('--description',
1765 default
='no description',
1766 help='human readable description')
1767 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
1768 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1769 @click.option('--wait',
1773 help='do not return the control immediately, but keep it '
1774 'until the operation is completed, or timeout')
1788 """creates a new VIM account"""
1791 check_client_version(ctx
.obj
, '--sdn_controller')
1792 if sdn_port_mapping
:
1793 check_client_version(ctx
.obj
, '--sdn_port_mapping')
1795 vim
['vim-username'] = user
1796 vim
['vim-password'] = password
1797 vim
['vim-url'] = auth_url
1798 vim
['vim-tenant-name'] = tenant
1799 vim
['vim-type'] = account_type
1800 vim
['description'] = description
1801 vim
['config'] = config
1802 if sdn_controller
or sdn_port_mapping
:
1803 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
1805 ctx
.obj
.vim
.create(name
, vim
, wait
=wait
)
1806 except ClientException
as e
:
1811 @cli.command(name
='vim-update', short_help
='updates a VIM account')
1812 @click.argument('name')
1813 @click.option('--newname', help='New name for the VIM account')
1814 @click.option('--user', help='VIM username')
1815 @click.option('--password', help='VIM password')
1816 @click.option('--auth_url', help='VIM url')
1817 @click.option('--tenant', help='VIM tenant name')
1818 @click.option('--config', help='VIM specific config parameters')
1819 @click.option('--account_type', help='VIM type')
1820 @click.option('--description', help='human readable description')
1821 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
1822 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1823 @click.option('--wait',
1827 help='do not return the control immediately, but keep it '
1828 'until the operation is completed, or timeout')
1843 """updates a VIM account
1845 NAME: name or ID of the VIM account
1848 check_client_version(ctx
.obj
, ctx
.command
.name
)
1850 if newname
: vim
['name'] = newname
1851 if user
: vim
['vim_user'] = user
1852 if password
: vim
['vim_password'] = password
1853 if auth_url
: vim
['vim_url'] = auth_url
1854 if tenant
: vim
['vim-tenant-name'] = tenant
1855 if account_type
: vim
['vim_type'] = account_type
1856 if description
: vim
['description'] = description
1857 if config
: vim
['config'] = config
1858 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
1859 except ClientException
as e
:
1864 @cli.command(name
='vim-delete', short_help
='deletes a VIM account')
1865 @click.argument('name')
1866 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1867 @click.option('--wait',
1871 help='do not return the control immediately, but keep it '
1872 'until the operation is completed, or timeout')
1874 def vim_delete(ctx
, name
, force
, wait
):
1875 """deletes a VIM account
1877 NAME: name or ID of the VIM account to be deleted
1881 ctx
.obj
.vim
.delete(name
, wait
=wait
)
1883 check_client_version(ctx
.obj
, '--force')
1884 ctx
.obj
.vim
.delete(name
, force
, wait
=wait
)
1885 except ClientException
as e
:
1890 @cli.command(name
='vim-list', short_help
='list all VIM accounts')
1891 #@click.option('--ro_update/--no_ro_update',
1893 # help='update list from RO')
1894 @click.option('--filter', default
=None,
1895 help='restricts the list to the VIM accounts matching the filter')
1897 def vim_list(ctx
, filter):
1898 """list all VIM accounts"""
1900 check_client_version(ctx
.obj
, '--filter')
1902 # check_client_version(ctx.obj, '--ro_update', 'v1')
1903 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1904 if fullclassname
== 'osmclient.sol005.client.Client':
1905 resp
= ctx
.obj
.vim
.list(filter)
1907 # resp = ctx.obj.vim.list(ro_update)
1908 table
= PrettyTable(['vim name', 'uuid'])
1910 table
.add_row([vim
['name'], vim
['uuid']])
1915 @cli.command(name
='vim-show', short_help
='shows the details of a VIM account')
1916 @click.argument('name')
1918 def vim_show(ctx
, name
):
1919 """shows the details of a VIM account
1921 NAME: name or ID of the VIM account
1924 resp
= ctx
.obj
.vim
.get(name
)
1925 if 'vim_password' in resp
:
1926 resp
['vim_password']='********'
1927 except ClientException
as e
:
1931 table
= PrettyTable(['key', 'attribute'])
1932 for k
, v
in list(resp
.items()):
1933 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
1938 ####################
1940 ####################
1942 @cli.command(name
='wim-create', short_help
='creates a new WIM account')
1943 @click.option('--name',
1945 help='Name for the WIM account')
1946 @click.option('--user',
1947 help='WIM username')
1948 @click.option('--password',
1949 help='WIM password')
1950 @click.option('--url',
1953 # @click.option('--tenant',
1954 # help='wIM tenant name')
1955 @click.option('--config',
1957 help='WIM specific config parameters')
1958 @click.option('--wim_type',
1960 @click.option('--description',
1961 default
='no description',
1962 help='human readable description')
1963 @click.option('--wim_port_mapping', default
=None,
1964 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
1965 "(WAN service endpoint id and info)")
1966 @click.option('--wait',
1970 help='do not return the control immediately, but keep it '
1971 'until the operation is completed, or timeout')
1984 """creates a new WIM account"""
1986 check_client_version(ctx
.obj
, ctx
.command
.name
)
1987 # if sdn_controller:
1988 # check_client_version(ctx.obj, '--sdn_controller')
1989 # if sdn_port_mapping:
1990 # check_client_version(ctx.obj, '--sdn_port_mapping')
1992 if user
: wim
['user'] = user
1993 if password
: wim
['password'] = password
1994 if url
: wim
['wim_url'] = url
1995 # if tenant: wim['tenant'] = tenant
1996 wim
['wim_type'] = wim_type
1997 if description
: wim
['description'] = description
1998 if config
: wim
['config'] = config
1999 ctx
.obj
.wim
.create(name
, wim
, wim_port_mapping
, wait
=wait
)
2000 except ClientException
as e
:
2005 @cli.command(name
='wim-update', short_help
='updates a WIM account')
2006 @click.argument('name')
2007 @click.option('--newname', help='New name for the WIM account')
2008 @click.option('--user', help='WIM username')
2009 @click.option('--password', help='WIM password')
2010 @click.option('--url', help='WIM url')
2011 @click.option('--config', help='WIM specific config parameters')
2012 @click.option('--wim_type', help='WIM type')
2013 @click.option('--description', help='human readable description')
2014 @click.option('--wim_port_mapping', default
=None,
2015 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2016 "(WAN service endpoint id and info)")
2017 @click.option('--wait',
2021 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2034 """updates a WIM account
2036 NAME: name or ID of the WIM account
2039 check_client_version(ctx
.obj
, ctx
.command
.name
)
2041 if newname
: wim
['name'] = newname
2042 if user
: wim
['user'] = user
2043 if password
: wim
['password'] = password
2044 if url
: wim
['url'] = url
2045 # if tenant: wim['tenant'] = tenant
2046 if wim_type
: wim
['wim_type'] = wim_type
2047 if description
: wim
['description'] = description
2048 if config
: wim
['config'] = config
2049 ctx
.obj
.wim
.update(name
, wim
, wim_port_mapping
, wait
=wait
)
2050 except ClientException
as e
:
2055 @cli.command(name
='wim-delete', short_help
='deletes a WIM account')
2056 @click.argument('name')
2057 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2058 @click.option('--wait',
2062 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2064 def wim_delete(ctx
, name
, force
, wait
):
2065 """deletes a WIM account
2067 NAME: name or ID of the WIM account to be deleted
2070 check_client_version(ctx
.obj
, ctx
.command
.name
)
2071 ctx
.obj
.wim
.delete(name
, force
, wait
=wait
)
2072 except ClientException
as e
:
2077 @cli.command(name
='wim-list', short_help
='list all WIM accounts')
2078 @click.option('--filter', default
=None,
2079 help='restricts the list to the WIM accounts matching the filter')
2081 def wim_list(ctx
, filter):
2082 """list all WIM accounts"""
2084 check_client_version(ctx
.obj
, ctx
.command
.name
)
2085 resp
= ctx
.obj
.wim
.list(filter)
2086 table
= PrettyTable(['wim name', 'uuid'])
2088 table
.add_row([wim
['name'], wim
['uuid']])
2091 except ClientException
as e
:
2096 @cli.command(name
='wim-show', short_help
='shows the details of a WIM account')
2097 @click.argument('name')
2099 def wim_show(ctx
, name
):
2100 """shows the details of a WIM account
2102 NAME: name or ID of the WIM account
2105 check_client_version(ctx
.obj
, ctx
.command
.name
)
2106 resp
= ctx
.obj
.wim
.get(name
)
2107 if 'password' in resp
:
2108 resp
['wim_password']='********'
2109 except ClientException
as e
:
2113 table
= PrettyTable(['key', 'attribute'])
2114 for k
, v
in list(resp
.items()):
2115 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2120 ####################
2121 # SDN controller operations
2122 ####################
2124 @cli.command(name
='sdnc-create', short_help
='creates a new SDN controller')
2125 @click.option('--name',
2127 help='Name to create sdn controller')
2128 @click.option('--type',
2130 help='SDN controller type')
2131 @click.option('--sdn_controller_version', hidden
=True,
2132 help='Deprecated. Use --config {version: sdn_controller_version}')
2133 @click.option('--url',
2134 help='URL in format http[s]://HOST:IP/')
2135 @click.option('--ip_address', hidden
=True,
2136 help='Deprecated. Use --url')
2137 @click.option('--port', hidden
=True,
2138 help='Deprecated. Use --url')
2139 @click.option('--switch_dpid', hidden
=True,
2140 help='Deprecated. Use --config {dpid: DPID}')
2141 @click.option('--config',
2142 help='Extra information for SDN in yaml format, as {dpid: (Openflow Datapath ID), version: version}')
2143 @click.option('--user',
2144 help='SDN controller username')
2145 @click.option('--password',
2147 confirmation_prompt
=True,
2148 help='SDN controller password')
2149 @click.option('--description', default
=None, help='human readable description')
2150 @click.option('--wait',
2154 help="do not return the control immediately, but keep it until the operation is completed, or timeout")
2156 def sdnc_create(ctx
, **kwargs
):
2157 """creates a new SDN controller"""
2158 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2159 x
not in ("wait", "ip_address", "port", "switch_dpid")}
2160 if kwargs
.get("port"):
2161 print("option '--port' is deprecated, use '-url' instead")
2162 sdncontroller
["port"] = int(kwargs
["port"])
2163 if kwargs
.get("ip_address"):
2164 print("option '--ip_address' is deprecated, use '-url' instead")
2165 sdncontroller
["ip"] = kwargs
["ip_address"]
2166 if kwargs
.get("switch_dpid"):
2167 print("option '--switch_dpid' is deprecated, use '---config={dpid: DPID}' instead")
2168 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2169 if kwargs
.get("sdn_controller_version"):
2170 print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'"
2173 check_client_version(ctx
.obj
, ctx
.command
.name
)
2174 ctx
.obj
.sdnc
.create(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2175 except ClientException
as e
:
2179 @cli.command(name
='sdnc-update', short_help
='updates an SDN controller')
2180 @click.argument('name')
2181 @click.option('--newname', help='New name for the SDN controller')
2182 @click.option('--description', default
=None, help='human readable description')
2183 @click.option('--type', help='SDN controller type')
2184 @click.option('--url', help='URL in format http[s]://HOST:IP/')
2185 @click.option('--config', help='Extra information for SDN in yaml format, as '
2186 '{dpid: (Openflow Datapath ID), version: version}')
2187 @click.option('--user', help='SDN controller username')
2188 @click.option('--password', help='SDN controller password')
2189 @click.option('--ip_address', hidden
=True, help='Deprecated. Use --url')
2190 @click.option('--port', hidden
=True, help='Deprecated. Use --url')
2191 @click.option('--switch_dpid', hidden
=True, help='Deprecated. Use --config {switch_dpid: DPID}')
2192 @click.option('--sdn_controller_version', hidden
=True, help='Deprecated. Use --config {version: VERSION}')
2193 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2194 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2196 def sdnc_update(ctx
, **kwargs
):
2197 """updates an SDN controller
2199 NAME: name or ID of the SDN controller
2201 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2202 x
not in ("wait", "ip_address", "port", "switch_dpid", "new_name")}
2203 if kwargs
.get("newname"):
2204 sdncontroller
["name"] = kwargs
["newname"]
2205 if kwargs
.get("port"):
2206 print("option '--port' is deprecated, use '-url' instead")
2207 sdncontroller
["port"] = int(kwargs
["port"])
2208 if kwargs
.get("ip_address"):
2209 print("option '--ip_address' is deprecated, use '-url' instead")
2210 sdncontroller
["ip"] = kwargs
["ip_address"]
2211 if kwargs
.get("switch_dpid"):
2212 print("option '--switch_dpid' is deprecated, use '---config={dpid: DPID}' instead")
2213 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2214 if kwargs
.get("sdn_controller_version"):
2215 print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'"
2219 check_client_version(ctx
.obj
, ctx
.command
.name
)
2220 ctx
.obj
.sdnc
.update(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2221 except ClientException
as e
:
2226 @cli.command(name
='sdnc-delete', short_help
='deletes an SDN controller')
2227 @click.argument('name')
2228 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2229 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2230 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2232 def sdnc_delete(ctx
, name
, force
, wait
):
2233 """deletes an SDN controller
2235 NAME: name or ID of the SDN controller to be deleted
2238 check_client_version(ctx
.obj
, ctx
.command
.name
)
2239 ctx
.obj
.sdnc
.delete(name
, force
, wait
=wait
)
2240 except ClientException
as e
:
2245 @cli.command(name
='sdnc-list', short_help
='list all SDN controllers')
2246 @click.option('--filter', default
=None,
2247 help="restricts the list to the SDN controllers matching the filter with format: 'k[.k..]=v[&k[.k]=v2]'")
2249 def sdnc_list(ctx
, filter):
2250 """list all SDN controllers"""
2252 check_client_version(ctx
.obj
, ctx
.command
.name
)
2253 resp
= ctx
.obj
.sdnc
.list(filter)
2254 except ClientException
as e
:
2257 table
= PrettyTable(['sdnc name', 'id'])
2259 table
.add_row([sdnc
['name'], sdnc
['_id']])
2264 @cli.command(name
='sdnc-show', short_help
='shows the details of an SDN controller')
2265 @click.argument('name')
2267 def sdnc_show(ctx
, name
):
2268 """shows the details of an SDN controller
2270 NAME: name or ID of the SDN controller
2273 check_client_version(ctx
.obj
, ctx
.command
.name
)
2274 resp
= ctx
.obj
.sdnc
.get(name
)
2275 except ClientException
as e
:
2279 table
= PrettyTable(['key', 'attribute'])
2280 for k
, v
in list(resp
.items()):
2281 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2286 ###########################
2287 # K8s cluster operations
2288 ###########################
2290 @cli.command(name
='k8scluster-add')
2291 @click.argument('name')
2292 @click.option('--creds',
2294 help='credentials file, i.e. a valid `.kube/config` file')
2295 @click.option('--version',
2297 help='Kubernetes version')
2298 @click.option('--vim',
2300 help='VIM target, the VIM where the cluster resides')
2301 @click.option('--k8s-nets',
2303 help='list of VIM networks, in JSON inline format, where the cluster is accessible via L3 routing, e.g. "{(k8s_net1:vim_network1) [,(k8s_net2:vim_network2) ...]}"')
2304 @click.option('--description',
2306 help='human readable description')
2307 @click.option('--namespace',
2308 default
='kube-system',
2309 help='namespace to be used for its operation, defaults to `kube-system`')
2310 @click.option('--cni',
2312 help='list of CNI plugins, in JSON inline format, used in the cluster')
2313 #@click.option('--skip-init',
2315 # help='If set, K8s cluster is assumed to be ready for its use with OSM')
2316 #@click.option('--wait',
2318 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2320 def k8scluster_add(ctx
,
2329 """adds a K8s cluster to OSM
2331 NAME: name of the K8s cluster
2334 check_client_version(ctx
.obj
, ctx
.command
.name
)
2336 cluster
['name'] = name
2337 with
open(creds
, 'r') as cf
:
2338 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2339 cluster
['k8s_version'] = version
2340 cluster
['vim_account'] = vim
2341 cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2342 cluster
['description'] = description
2343 if namespace
: cluster
['namespace'] = namespace
2344 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2345 ctx
.obj
.k8scluster
.create(name
, cluster
)
2346 except ClientException
as e
:
2351 @cli.command(name
='k8scluster-update', short_help
='updates a K8s cluster')
2352 @click.argument('name')
2353 @click.option('--newname', help='New name for the K8s cluster')
2354 @click.option('--creds', help='credentials file, i.e. a valid `.kube/config` file')
2355 @click.option('--version', help='Kubernetes version')
2356 @click.option('--vim', help='VIM target, the VIM where the cluster resides')
2357 @click.option('--k8s-nets', help='list of VIM networks, in JSON inline format, where the cluster is accessible via L3 routing, e.g. "{(k8s_net1:vim_network1) [,(k8s_net2:vim_network2) ...]}"')
2358 @click.option('--description', help='human readable description')
2359 @click.option('--namespace', help='namespace to be used for its operation, defaults to `kube-system`')
2360 @click.option('--cni', help='list of CNI plugins, in JSON inline format, used in the cluster')
2362 def k8scluster_update(ctx
,
2372 """updates a K8s cluster
2374 NAME: name or ID of the K8s cluster
2377 check_client_version(ctx
.obj
, ctx
.command
.name
)
2379 if newname
: cluster
['name'] = newname
2381 with
open(creds
, 'r') as cf
:
2382 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2383 if version
: cluster
['k8s_version'] = version
2384 if vim
: cluster
['vim_account'] = vim
2385 if k8s_nets
: cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2386 if description
: cluster
['description'] = description
2387 if namespace
: cluster
['namespace'] = namespace
2388 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2389 ctx
.obj
.k8scluster
.update(name
, cluster
)
2390 except ClientException
as e
:
2395 @cli.command(name
='k8scluster-delete')
2396 @click.argument('name')
2397 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2398 #@click.option('--wait',
2400 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2402 def k8scluster_delete(ctx
, name
, force
):
2403 """deletes a K8s cluster
2405 NAME: name or ID of the K8s cluster to be deleted
2408 check_client_version(ctx
.obj
, ctx
.command
.name
)
2409 ctx
.obj
.k8scluster
.delete(name
, force
=force
)
2410 except ClientException
as e
:
2415 @cli.command(name
='k8scluster-list')
2416 @click.option('--filter', default
=None,
2417 help='restricts the list to the K8s clusters matching the filter')
2418 @click.option('--literal', is_flag
=True,
2419 help='print literally, no pretty table')
2421 def k8scluster_list(ctx
, filter, literal
):
2422 """list all K8s clusters"""
2424 check_client_version(ctx
.obj
, ctx
.command
.name
)
2425 resp
= ctx
.obj
.k8scluster
.list(filter)
2427 print(yaml
.safe_dump(resp
))
2429 table
= PrettyTable(['Name', 'Id', 'Version', 'VIM', 'K8s-nets', 'Operational State', 'Description'])
2430 for cluster
in resp
:
2431 table
.add_row([cluster
['name'], cluster
['_id'], cluster
['k8s_version'], cluster
['vim_account'],
2432 json
.dumps(cluster
['nets']), cluster
["_admin"]["operationalState"],
2433 trunc_text(cluster
.get('description',''),40)])
2436 except ClientException
as e
:
2441 @cli.command(name
='k8scluster-show')
2442 @click.argument('name')
2443 @click.option('--literal', is_flag
=True,
2444 help='print literally, no pretty table')
2446 def k8scluster_show(ctx
, name
, literal
):
2447 """shows the details of a K8s cluster
2449 NAME: name or ID of the K8s cluster
2452 resp
= ctx
.obj
.k8scluster
.get(name
)
2454 print(yaml
.safe_dump(resp
))
2456 table
= PrettyTable(['key', 'attribute'])
2457 for k
, v
in list(resp
.items()):
2458 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2461 except ClientException
as e
:
2467 ###########################
2469 ###########################
2471 @cli.command(name
='repo-add')
2472 @click.argument('name')
2473 @click.argument('uri')
2474 @click.option('--type',
2475 type=click
.Choice(['helm-chart', 'juju-bundle']),
2477 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2478 @click.option('--description',
2480 help='human readable description')
2481 #@click.option('--wait',
2483 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2490 """adds a repo to OSM
2492 NAME: name of the repo
2493 URI: URI of the repo
2496 check_client_version(ctx
.obj
, ctx
.command
.name
)
2501 repo
['description'] = description
2502 ctx
.obj
.repo
.create(name
, repo
)
2503 except ClientException
as e
:
2508 @cli.command(name
='repo-update')
2509 @click.argument('name')
2510 @click.option('--newname', help='New name for the repo')
2511 @click.option('--uri', help='URI of the repo')
2512 @click.option('--type', type=click
.Choice(['helm-chart', 'juju-bundle']),
2513 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2514 @click.option('--description', help='human readable description')
2515 #@click.option('--wait',
2517 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2519 def repo_update(ctx
,
2525 """updates a repo in OSM
2527 NAME: name of the repo
2530 check_client_version(ctx
.obj
, ctx
.command
.name
)
2532 if newname
: repo
['name'] = newname
2533 if uri
: repo
['uri'] = uri
2534 if type: repo
['type'] = type
2535 if description
: repo
['description'] = description
2536 ctx
.obj
.repo
.update(name
, repo
)
2537 except ClientException
as e
:
2542 @cli.command(name
='repo-delete')
2543 @click.argument('name')
2544 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2545 #@click.option('--wait',
2547 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2549 def repo_delete(ctx
, name
, force
):
2552 NAME: name or ID of the repo to be deleted
2555 check_client_version(ctx
.obj
, ctx
.command
.name
)
2556 ctx
.obj
.repo
.delete(name
, force
=force
)
2557 except ClientException
as e
:
2562 @cli.command(name
='repo-list')
2563 @click.option('--filter', default
=None,
2564 help='restricts the list to the repos matching the filter')
2565 @click.option('--literal', is_flag
=True,
2566 help='print literally, no pretty table')
2568 def repo_list(ctx
, filter, literal
):
2569 """list all repos"""
2571 check_client_version(ctx
.obj
, ctx
.command
.name
)
2572 resp
= ctx
.obj
.repo
.list(filter)
2574 print(yaml
.safe_dump(resp
))
2576 table
= PrettyTable(['Name', 'Id', 'Type', 'URI', 'Description'])
2578 #cluster['k8s-nets'] = json.dumps(yaml.safe_load(cluster['k8s-nets']))
2579 table
.add_row([repo
['name'], repo
['_id'], repo
['type'], repo
['url'], trunc_text(repo
.get('description',''),40)])
2582 except ClientException
as e
:
2587 @cli.command(name
='repo-show')
2588 @click.argument('name')
2589 @click.option('--literal', is_flag
=True,
2590 help='print literally, no pretty table')
2592 def repo_show(ctx
, name
, literal
):
2593 """shows the details of a repo
2595 NAME: name or ID of the repo
2598 resp
= ctx
.obj
.repo
.get(name
)
2600 print(yaml
.safe_dump(resp
))
2602 table
= PrettyTable(['key', 'attribute'])
2603 for k
, v
in list(resp
.items()):
2604 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2607 except ClientException
as e
:
2613 ####################
2614 # Project mgmt operations
2615 ####################
2617 @cli.command(name
='project-create', short_help
='creates a new project')
2618 @click.argument('name')
2619 #@click.option('--description',
2620 # default='no description',
2621 # help='human readable description')
2623 def project_create(ctx
, name
):
2624 """Creates a new project
2626 NAME: name of the project
2629 project
['name'] = name
2631 check_client_version(ctx
.obj
, ctx
.command
.name
)
2632 ctx
.obj
.project
.create(name
, project
)
2633 except ClientException
as e
:
2638 @cli.command(name
='project-delete', short_help
='deletes a project')
2639 @click.argument('name')
2640 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2642 def project_delete(ctx
, name
):
2643 """deletes a project
2645 NAME: name or ID of the project to be deleted
2648 check_client_version(ctx
.obj
, ctx
.command
.name
)
2649 ctx
.obj
.project
.delete(name
)
2650 except ClientException
as e
:
2655 @cli.command(name
='project-list', short_help
='list all projects')
2656 @click.option('--filter', default
=None,
2657 help='restricts the list to the projects matching the filter')
2659 def project_list(ctx
, filter):
2660 """list all projects"""
2662 check_client_version(ctx
.obj
, ctx
.command
.name
)
2663 resp
= ctx
.obj
.project
.list(filter)
2664 except ClientException
as e
:
2667 table
= PrettyTable(['name', 'id'])
2669 table
.add_row([proj
['name'], proj
['_id']])
2674 @cli.command(name
='project-show', short_help
='shows the details of a project')
2675 @click.argument('name')
2677 def project_show(ctx
, name
):
2678 """shows the details of a project
2680 NAME: name or ID of the project
2683 check_client_version(ctx
.obj
, ctx
.command
.name
)
2684 resp
= ctx
.obj
.project
.get(name
)
2685 except ClientException
as e
:
2689 table
= PrettyTable(['key', 'attribute'])
2690 for k
, v
in resp
.items():
2691 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2696 @cli.command(name
='project-update', short_help
='updates a project (only the name can be updated)')
2697 @click.argument('project')
2698 @click.option('--name',
2700 help='new name for the project')
2703 def project_update(ctx
, project
, name
):
2705 Update a project name
2708 :param project: id or name of the project to modify
2709 :param name: new name for the project
2713 project_changes
= {}
2714 project_changes
['name'] = name
2717 check_client_version(ctx
.obj
, ctx
.command
.name
)
2718 ctx
.obj
.project
.update(project
, project_changes
)
2719 except ClientException
as e
:
2723 ####################
2724 # User mgmt operations
2725 ####################
2727 @cli.command(name
='user-create', short_help
='creates a new user')
2728 @click.argument('username')
2729 @click.option('--password',
2732 confirmation_prompt
=True,
2733 help='user password')
2734 @click.option('--projects',
2735 # prompt="Comma separate list of projects",
2737 callback
=lambda ctx
, param
, value
: ''.join(value
).split(',') if all(len(x
)==1 for x
in value
) else value
,
2738 help='list of project ids that the user belongs to')
2739 @click.option('--project-role-mappings', 'project_role_mappings',
2740 default
=None, multiple
=True,
2741 help='creating user project/role(s) mapping')
2743 def user_create(ctx
, username
, password
, projects
, project_role_mappings
):
2744 """Creates a new user
2747 USERNAME: name of the user
2748 PASSWORD: password of the user
2749 PROJECTS: projects assigned to user (internal only)
2750 PROJECT_ROLE_MAPPING: roles in projects assigned to user (keystone)
2753 user
['username'] = username
2754 user
['password'] = password
2755 user
['projects'] = projects
2756 user
['project_role_mappings'] = project_role_mappings
2759 check_client_version(ctx
.obj
, ctx
.command
.name
)
2760 ctx
.obj
.user
.create(username
, user
)
2761 except ClientException
as e
:
2766 @cli.command(name
='user-update', short_help
='updates user information')
2767 @click.argument('username')
2768 @click.option('--password',
2771 # confirmation_prompt=True,
2772 help='user password')
2773 @click.option('--set-username', 'set_username',
2775 help='change username')
2776 @click.option('--set-project', 'set_project',
2777 default
=None, multiple
=True,
2778 help='create/replace the project,role(s) mapping for this project: \'project,role1,role2,...\'')
2779 @click.option('--remove-project', 'remove_project',
2780 default
=None, multiple
=True,
2781 help='removes project from user: \'project\'')
2782 @click.option('--add-project-role', 'add_project_role',
2783 default
=None, multiple
=True,
2784 help='adds project,role(s) mapping: \'project,role1,role2,...\'')
2785 @click.option('--remove-project-role', 'remove_project_role',
2786 default
=None, multiple
=True,
2787 help='removes project,role(s) mapping: \'project,role1,role2,...\'')
2789 def user_update(ctx
, username
, password
, set_username
, set_project
, remove_project
,
2790 add_project_role
, remove_project_role
):
2791 """Update a user information
2794 USERNAME: name of the user
2795 PASSWORD: new password
2796 SET_USERNAME: new username
2797 SET_PROJECT: creating mappings for project/role(s)
2798 REMOVE_PROJECT: deleting mappings for project/role(s)
2799 ADD_PROJECT_ROLE: adding mappings for project/role(s)
2800 REMOVE_PROJECT_ROLE: removing mappings for project/role(s)
2803 user
['password'] = password
2804 user
['username'] = set_username
2805 user
['set-project'] = set_project
2806 user
['remove-project'] = remove_project
2807 user
['add-project-role'] = add_project_role
2808 user
['remove-project-role'] = remove_project_role
2811 check_client_version(ctx
.obj
, ctx
.command
.name
)
2812 ctx
.obj
.user
.update(username
, user
)
2813 except ClientException
as e
:
2818 @cli.command(name
='user-delete', short_help
='deletes a user')
2819 @click.argument('name')
2820 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2822 def user_delete(ctx
, name
):
2826 NAME: name or ID of the user to be deleted
2829 check_client_version(ctx
.obj
, ctx
.command
.name
)
2830 ctx
.obj
.user
.delete(name
)
2831 except ClientException
as e
:
2836 @cli.command(name
='user-list', short_help
='list all users')
2837 @click.option('--filter', default
=None,
2838 help='restricts the list to the users matching the filter')
2840 def user_list(ctx
, filter):
2841 """list all users"""
2843 check_client_version(ctx
.obj
, ctx
.command
.name
)
2844 resp
= ctx
.obj
.user
.list(filter)
2845 except ClientException
as e
:
2848 table
= PrettyTable(['name', 'id'])
2850 table
.add_row([user
['username'], user
['_id']])
2855 @cli.command(name
='user-show', short_help
='shows the details of a user')
2856 @click.argument('name')
2858 def user_show(ctx
, name
):
2859 """shows the details of a user
2861 NAME: name or ID of the user
2864 check_client_version(ctx
.obj
, ctx
.command
.name
)
2865 resp
= ctx
.obj
.user
.get(name
)
2866 if 'password' in resp
:
2867 resp
['password']='********'
2868 except ClientException
as e
:
2872 table
= PrettyTable(['key', 'attribute'])
2873 for k
, v
in resp
.items():
2874 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2879 ####################
2880 # Fault Management operations
2881 ####################
2883 @cli.command(name
='ns-alarm-create')
2884 @click.argument('name')
2885 @click.option('--ns', prompt
=True, help='NS instance id or name')
2886 @click.option('--vnf', prompt
=True,
2887 help='VNF name (VNF member index as declared in the NSD)')
2888 @click.option('--vdu', prompt
=True,
2889 help='VDU name (VDU name as declared in the VNFD)')
2890 @click.option('--metric', prompt
=True,
2891 help='Name of the metric (e.g. cpu_utilization)')
2892 @click.option('--severity', default
='WARNING',
2893 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
2894 @click.option('--threshold_value', prompt
=True,
2895 help='threshold value that, when crossed, an alarm is triggered')
2896 @click.option('--threshold_operator', prompt
=True,
2897 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
2898 @click.option('--statistic', default
='AVERAGE',
2899 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
2901 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
2902 threshold_value
, threshold_operator
, statistic
):
2903 """creates a new alarm for a NS instance"""
2904 # TODO: Check how to validate threshold_value.
2905 # Should it be an integer (1-100), percentage, or decimal (0.01-1.00)?
2907 ns_instance
= ctx
.obj
.ns
.get(ns
)
2909 alarm
['alarm_name'] = name
2910 alarm
['ns_id'] = ns_instance
['_id']
2911 alarm
['correlation_id'] = ns_instance
['_id']
2912 alarm
['vnf_member_index'] = vnf
2913 alarm
['vdu_name'] = vdu
2914 alarm
['metric_name'] = metric
2915 alarm
['severity'] = severity
2916 alarm
['threshold_value'] = int(threshold_value
)
2917 alarm
['operation'] = threshold_operator
2918 alarm
['statistic'] = statistic
2919 check_client_version(ctx
.obj
, ctx
.command
.name
)
2920 ctx
.obj
.ns
.create_alarm(alarm
)
2921 except ClientException
as e
:
2926 #@cli.command(name='ns-alarm-delete')
2927 #@click.argument('name')
2928 #@click.pass_context
2929 #def ns_alarm_delete(ctx, name):
2930 # """deletes an alarm
2932 # NAME: name of the alarm to be deleted
2935 # check_client_version(ctx.obj, ctx.command.name)
2936 # ctx.obj.ns.delete_alarm(name)
2937 # except ClientException as e:
2942 ####################
2943 # Performance Management operations
2944 ####################
2946 @cli.command(name
='ns-metric-export', short_help
='exports a metric to the internal OSM bus, which can be read by other apps')
2947 @click.option('--ns', prompt
=True, help='NS instance id or name')
2948 @click.option('--vnf', prompt
=True,
2949 help='VNF name (VNF member index as declared in the NSD)')
2950 @click.option('--vdu', prompt
=True,
2951 help='VDU name (VDU name as declared in the VNFD)')
2952 @click.option('--metric', prompt
=True,
2953 help='name of the metric (e.g. cpu_utilization)')
2954 #@click.option('--period', default='1w',
2955 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
2956 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
2958 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
2959 """exports a metric to the internal OSM bus, which can be read by other apps"""
2960 # TODO: Check how to validate interval.
2961 # Should it be an integer (seconds), or should a suffix (s,m,h,d,w) also be permitted?
2963 ns_instance
= ctx
.obj
.ns
.get(ns
)
2965 metric_data
['ns_id'] = ns_instance
['_id']
2966 metric_data
['correlation_id'] = ns_instance
['_id']
2967 metric_data
['vnf_member_index'] = vnf
2968 metric_data
['vdu_name'] = vdu
2969 metric_data
['metric_name'] = metric
2970 metric_data
['collection_unit'] = 'WEEK'
2971 metric_data
['collection_period'] = 1
2972 check_client_version(ctx
.obj
, ctx
.command
.name
)
2974 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
2978 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
2979 time
.sleep(int(interval
))
2981 except ClientException
as e
:
2986 ####################
2988 ####################
2990 @cli.command(name
='version')
2992 def get_version(ctx
):
2994 check_client_version(ctx
.obj
, "version")
2995 print ("Server version: {}".format(ctx
.obj
.get_version()))
2996 print ("Client version: {}".format(pkg_resources
.get_distribution("osmclient").version
))
2997 except ClientException
as e
:
3001 @cli.command(name
='upload-package', short_help
='uploads a VNF package or NS package')
3002 @click.argument('filename')
3004 def upload_package(ctx
, filename
):
3005 """uploads a VNF package or NS package
3007 FILENAME: VNF or NS package file (tar.gz)
3010 ctx
.obj
.package
.upload(filename
)
3011 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
3012 if fullclassname
!= 'osmclient.sol005.client.Client':
3013 ctx
.obj
.package
.wait_for_upload(filename
)
3014 except ClientException
as e
:
3019 #@cli.command(name='ns-scaling-show')
3020 #@click.argument('ns_name')
3021 #@click.pass_context
3022 #def show_ns_scaling(ctx, ns_name):
3023 # """shows the status of a NS scaling operation
3025 # NS_NAME: name of the NS instance being scaled
3028 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3029 # resp = ctx.obj.ns.list()
3030 # except ClientException as e:
3034 # table = PrettyTable(
3037 # 'operational status',
3042 # if ns_name == ns['name']:
3043 # nsopdata = ctx.obj.ns.get_opdata(ns['id'])
3044 # scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
3045 # for record in scaling_records:
3046 # if 'instance' in record:
3047 # instances = record['instance']
3048 # for inst in instances:
3050 # [record['scaling-group-name-ref'],
3051 # inst['instance-id'],
3052 # inst['op-status'],
3053 # time.strftime('%Y-%m-%d %H:%M:%S',
3055 # inst['create-time'])),
3061 #@cli.command(name='ns-scale')
3062 #@click.argument('ns_name')
3063 #@click.option('--ns_scale_group', prompt=True)
3064 #@click.option('--index', prompt=True)
3065 #@click.option('--wait',
3069 # help='do not return the control immediately, but keep it \
3070 # until the operation is completed, or timeout')
3071 #@click.pass_context
3072 #def ns_scale(ctx, ns_name, ns_scale_group, index, wait):
3075 # NS_NAME: name of the NS instance to be scaled
3078 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3079 # ctx.obj.ns.scale(ns_name, ns_scale_group, index, wait=wait)
3080 # except ClientException as e:
3085 #@cli.command(name='config-agent-list')
3086 #@click.pass_context
3087 #def config_agent_list(ctx):
3088 # """list config agents"""
3090 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3091 # except ClientException as e:
3094 # table = PrettyTable(['name', 'account-type', 'details'])
3095 # for account in ctx.obj.vca.list():
3098 # account['account-type'],
3104 #@cli.command(name='config-agent-delete')
3105 #@click.argument('name')
3106 #@click.pass_context
3107 #def config_agent_delete(ctx, name):
3108 # """deletes a config agent
3110 # NAME: name of the config agent to be deleted
3113 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3114 # ctx.obj.vca.delete(name)
3115 # except ClientException as e:
3120 #@cli.command(name='config-agent-add')
3121 #@click.option('--name',
3123 #@click.option('--account_type',
3125 #@click.option('--server',
3127 #@click.option('--user',
3129 #@click.option('--secret',
3132 # confirmation_prompt=True)
3133 #@click.pass_context
3134 #def config_agent_add(ctx, name, account_type, server, user, secret):
3135 # """adds a config agent"""
3137 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3138 # ctx.obj.vca.create(name, account_type, server, user, secret)
3139 # except ClientException as e:
3144 #@cli.command(name='ro-dump')
3145 #@click.pass_context
3147 # """shows RO agent information"""
3148 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3149 # resp = ctx.obj.vim.get_resource_orchestrator()
3150 # table = PrettyTable(['key', 'attribute'])
3151 # for k, v in list(resp.items()):
3152 # table.add_row([k, json.dumps(v, indent=2)])
3157 #@cli.command(name='vcs-list')
3158 #@click.pass_context
3160 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3161 # resp = ctx.obj.utils.get_vcs_info()
3162 # table = PrettyTable(['component name', 'state'])
3163 # for component in resp:
3164 # table.add_row([component['component_name'], component['state']])
3169 @cli.command(name
='ns-action', short_help
='executes an action/primitive over a NS instance')
3170 @click.argument('ns_name')
3171 @click.option('--vnf_name', default
=None, help='member-vnf-index if the target is a vnf instead of a ns)')
3172 @click.option('--kdu_name', default
=None, help='kdu-name if the target is a kdu)')
3173 @click.option('--vdu_id', default
=None, help='vdu-id if the target is a vdu')
3174 @click.option('--vdu_count', default
=None, help='number of vdu instance of this vdu_id')
3175 @click.option('--action_name', prompt
=True, help='action name')
3176 @click.option('--params', default
=None, help='action params in YAML/JSON inline string')
3177 @click.option('--params_file', default
=None, help='YAML/JSON file with action params')
3178 @click.option('--wait',
3182 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3194 """executes an action/primitive over a NS instance
3196 NS_NAME: name or ID of the NS instance
3199 check_client_version(ctx
.obj
, ctx
.command
.name
)
3202 op_data
['member_vnf_index'] = vnf_name
3204 op_data
['kdu_name'] = kdu_name
3206 op_data
['vdu_id'] = vdu_id
3208 op_data
['vdu_count_index'] = vdu_count
3209 op_data
['primitive'] = action_name
3211 with
open(params_file
, 'r') as pf
:
3214 op_data
['primitive_params'] = yaml
.safe_load(params
)
3216 op_data
['primitive_params'] = {}
3217 print(ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
, wait
=wait
))
3219 except ClientException
as e
:
3224 @cli.command(name
='vnf-scale', short_help
='executes a VNF scale (adding/removing VDUs)')
3225 @click.argument('ns_name')
3226 @click.argument('vnf_name')
3227 @click.option('--scaling-group', prompt
=True, help="scaling-group-descriptor name to use")
3228 @click.option('--scale-in', default
=False, is_flag
=True, help="performs a scale in operation")
3229 @click.option('--scale-out', default
=False, is_flag
=True, help="performs a scale out operation (by default)")
3238 Executes a VNF scale (adding/removing VDUs)
3241 NS_NAME: name or ID of the NS instance.
3242 VNF_NAME: member-vnf-index in the NS to be scaled.
3245 check_client_version(ctx
.obj
, ctx
.command
.name
)
3246 if not scale_in
and not scale_out
:
3248 ctx
.obj
.ns
.scale_vnf(ns_name
, vnf_name
, scaling_group
, scale_in
, scale_out
)
3249 except ClientException
as e
:
3254 ##############################
3255 # Role Management Operations #
3256 ##############################
3258 @cli.command(name
='role-create', short_help
='creates a new role')
3259 @click.argument('name')
3260 @click.option('--permissions',
3262 help='role permissions using a dictionary')
3264 def role_create(ctx
, name
, permissions
):
3269 NAME: Name or ID of the role.
3270 DEFINITION: Definition of grant/denial of access to resources.
3273 check_client_version(ctx
.obj
, ctx
.command
.name
)
3274 ctx
.obj
.role
.create(name
, permissions
)
3275 except ClientException
as e
:
3280 @cli.command(name
='role-update', short_help
='updates a role')
3281 @click.argument('name')
3282 @click.option('--set-name',
3284 help='change name of rle')
3285 # @click.option('--permissions',
3287 # help='provide a yaml format dictionary with incremental changes. Values can be bool or None to delete')
3288 @click.option('--add',
3290 help='yaml format dictionary with permission: True/False to access grant/denial')
3291 @click.option('--remove',
3293 help='yaml format list to remove a permission')
3295 def role_update(ctx
, name
, set_name
, add
, remove
):
3300 NAME: Name or ID of the role.
3301 DEFINITION: Definition overwrites the old definition.
3302 ADD: Grant/denial of access to resource to add.
3303 REMOVE: Grant/denial of access to resource to remove.
3306 check_client_version(ctx
.obj
, ctx
.command
.name
)
3307 ctx
.obj
.role
.update(name
, set_name
, None, add
, remove
)
3308 except ClientException
as e
:
3313 @cli.command(name
='role-delete', short_help
='deletes a role')
3314 @click.argument('name')
3315 # @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3317 def role_delete(ctx
, name
):
3322 NAME: Name or ID of the role.
3325 check_client_version(ctx
.obj
, ctx
.command
.name
)
3326 ctx
.obj
.role
.delete(name
)
3327 except ClientException
as e
:
3332 @cli.command(name
='role-list', short_help
='list all roles')
3333 @click.option('--filter', default
=None,
3334 help='restricts the list to the projects matching the filter')
3336 def role_list(ctx
, filter):
3341 check_client_version(ctx
.obj
, ctx
.command
.name
)
3342 resp
= ctx
.obj
.role
.list(filter)
3343 except ClientException
as e
:
3346 table
= PrettyTable(['name', 'id'])
3348 table
.add_row([role
['name'], role
['_id']])
3353 @cli.command(name
='role-show', short_help
='show specific role')
3354 @click.argument('name')
3356 def role_show(ctx
, name
):
3358 Shows the details of a role.
3361 NAME: Name or ID of the role.
3364 check_client_version(ctx
.obj
, ctx
.command
.name
)
3365 resp
= ctx
.obj
.role
.get(name
)
3366 except ClientException
as e
:
3370 table
= PrettyTable(['key', 'attribute'])
3371 for k
, v
in resp
.items():
3372 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3377 @cli.command(name
='package-create',
3378 short_help
='Create a package descriptor')
3379 @click.argument('package-type')
3380 @click.argument('package-name')
3381 @click.option('--base-directory',
3383 help=('(NS/VNF/NST) Set the location for package creation. Default: "."'))
3384 @click.option('--image',
3385 default
="image-name",
3386 help='(VNF) Set the name of the vdu image. Default "image-name"')
3387 @click.option('--vdus',
3389 help='(VNF) Set the number of vdus in a VNF. Default 1')
3390 @click.option('--vcpu',
3392 help='(VNF) Set the number of virtual CPUs in a vdu. Default 1')
3393 @click.option('--memory',
3395 help='(VNF) Set the memory size (MB) of the vdu. Default 1024')
3396 @click.option('--storage',
3398 help='(VNF) Set the disk size (GB) of the vdu. Default 10')
3399 @click.option('--interfaces',
3401 help='(VNF) Set the number of additional interfaces apart from the management interface. Default 0')
3402 @click.option('--vendor',
3404 help='(NS/VNF) Set the descriptor vendor. Default "OSM"')
3405 @click.option('--override',
3408 help='(NS/VNF/NST) Flag for overriding the package if exists.')
3409 @click.option('--detailed',
3412 help='(NS/VNF/NST) Flag for generating descriptor .yaml with all possible commented options')
3413 @click.option('--netslice-subnets',
3415 help='(NST) Number of netslice subnets. Default 1')
3416 @click.option('--netslice-vlds',
3418 help='(NST) Number of netslice vlds. Default 1')
3420 def package_create(ctx
,
3436 Creates an OSM NS, VNF, NST package
3439 PACKAGE_TYPE: Package to be created: NS, VNF or NST.
3440 PACKAGE_NAME: Name of the package to create the folder with the content.
3444 check_client_version(ctx
.obj
, ctx
.command
.name
)
3445 print("Creating the {} structure: {}/{}".format(package_type
.upper(), base_directory
, package_name
))
3446 resp
= ctx
.obj
.package_tool
.create(package_type
,
3455 interfaces
=interfaces
,
3458 netslice_subnets
=netslice_subnets
,
3459 netslice_vlds
=netslice_vlds
)
3461 except ClientException
as inst
:
3462 print("ERROR: {}".format(inst
))
3465 @cli.command(name
='package-validate',
3466 short_help
='Validate a package descriptor')
3467 @click.argument('base-directory',
3471 def package_validate(ctx
,
3474 Validate descriptors given a base directory.
3477 BASE_DIRECTORY: Stub folder for NS, VNF or NST package.
3480 check_client_version(ctx
.obj
, ctx
.command
.name
)
3481 results
= ctx
.obj
.package_tool
.validate(base_directory
)
3482 table
= PrettyTable()
3483 table
.field_names
= ["TYPE", "PATH", "VALID", "ERROR"]
3484 # Print the dictionary generated by the validation function
3485 for result
in results
:
3486 table
.add_row([result
["type"], result
["path"], result
["valid"], result
["error"]])
3487 table
.sortby
= "VALID"
3488 table
.align
["PATH"] = "l"
3489 table
.align
["TYPE"] = "l"
3490 table
.align
["ERROR"] = "l"
3492 except ClientException
as inst
:
3493 print("ERROR: {}".format(inst
))
3496 @cli.command(name
='package-build',
3497 short_help
='Build the tar.gz of the package')
3498 @click.argument('package-folder')
3499 @click.option('--skip-validation',
3502 help='skip package validation')
3504 def package_build(ctx
,
3508 Build the package NS, VNF given the package_folder.
3511 PACKAGE_FOLDER: Folder of the NS, VNF or NST to be packaged
3514 check_client_version(ctx
.obj
, ctx
.command
.name
)
3515 results
= ctx
.obj
.package_tool
.build(package_folder
, skip_validation
)
3517 except ClientException
as inst
:
3518 print("ERROR: {}".format(inst
))
3522 if __name__
== '__main__':
3525 except pycurl
.error
as e
:
3527 print('Maybe "--hostname" option or OSM_HOSTNAME' +
3528 'environment variable needs to be specified')