26327fcb266189471f9f7bf0b71feed7fd733a8d
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,
1106 help='overwrite 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,
1122 help='overwrite 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,
1163 help='overwrite 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,
1179 help='overwrite 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,
1259 help='overwrites 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,
1275 help='overwrites 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, help='PDU descriptor file (as an alternative to using the other arguments')
1377 def pdu_create(ctx
, name
, pdu_type
, interface
, description
, vim_account
, descriptor_file
):
1378 """creates a new Physical Deployment Unit (PDU)"""
1380 check_client_version(ctx
.obj
, ctx
.command
.name
)
1382 if not descriptor_file
:
1384 raise ClientException('in absence of descriptor file, option "--name" is mandatory')
1386 raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory')
1388 raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)')
1390 raise ClientException('in absence of descriptor file, option "--vim_account" is mandatory (at least once)')
1392 with
open(descriptor_file
, 'r') as df
:
1393 pdu
= yaml
.safe_load(df
.read())
1394 if name
: pdu
["name"] = name
1395 if pdu_type
: pdu
["type"] = pdu_type
1396 if description
: pdu
["description"] = description
1397 if vim_account
: pdu
["vim_accounts"] = vim_account
1400 for iface
in interface
:
1401 new_iface
={k
:v
for k
,v
in [i
.split('=') for i
in iface
.split(',')]}
1402 new_iface
["mgmt"] = (new_iface
.get("mgmt","false").lower() == "true")
1403 ifaces_list
.append(new_iface
)
1404 pdu
["interfaces"] = ifaces_list
1405 ctx
.obj
.pdu
.create(pdu
)
1406 except ClientException
as e
:
1410 ####################
1412 ####################
1414 def nsd_update(ctx
, name
, content
):
1416 check_client_version(ctx
.obj
, ctx
.command
.name
)
1417 ctx
.obj
.nsd
.update(name
, content
)
1418 except ClientException
as e
:
1423 @cli.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
1424 @click.argument('name')
1425 @click.option('--content', default
=None,
1426 help='filename with the NSD/NSpkg replacing the current one')
1428 def nsd_update1(ctx
, name
, content
):
1429 """updates a NSD/NSpkg
1431 NAME: name or ID of the NSD/NSpkg
1433 nsd_update(ctx
, name
, content
)
1436 @cli.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
1437 @click.argument('name')
1438 @click.option('--content', default
=None,
1439 help='filename with the NSD/NSpkg replacing the current one')
1441 def nsd_update2(ctx
, name
, content
):
1442 """updates a NSD/NSpkg
1444 NAME: name or ID of the NSD/NSpkg
1446 nsd_update(ctx
, name
, content
)
1449 def vnfd_update(ctx
, name
, content
):
1451 check_client_version(ctx
.obj
, ctx
.command
.name
)
1452 ctx
.obj
.vnfd
.update(name
, content
)
1453 except ClientException
as e
:
1458 @cli.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
1459 @click.argument('name')
1460 @click.option('--content', default
=None,
1461 help='filename with the VNFD/VNFpkg replacing the current one')
1463 def vnfd_update1(ctx
, name
, content
):
1464 """updates a VNFD/VNFpkg
1466 NAME: name or ID of the VNFD/VNFpkg
1468 vnfd_update(ctx
, name
, content
)
1471 @cli.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
1472 @click.argument('name')
1473 @click.option('--content', default
=None,
1474 help='filename with the VNFD/VNFpkg replacing the current one')
1476 def vnfd_update2(ctx
, name
, content
):
1477 """updates a VNFD/VNFpkg
1479 NAME: VNFD yaml file or VNFpkg tar.gz file
1481 vnfd_update(ctx
, name
, content
)
1484 @cli.command(name
='nfpkg-update', short_help
='updates a NFpkg')
1485 @click.argument('name')
1486 @click.option('--content', default
=None,
1487 help='filename with the NFpkg replacing the current one')
1489 def nfpkg_update(ctx
, name
, content
):
1492 NAME: NF Descriptor yaml file or NFpkg tar.gz file
1494 vnfd_update(ctx
, name
, content
)
1497 def nst_update(ctx
, name
, content
):
1499 check_client_version(ctx
.obj
, ctx
.command
.name
)
1500 ctx
.obj
.nst
.update(name
, content
)
1501 except ClientException
as e
:
1506 @cli.command(name
='nst-update', short_help
='updates a Network Slice Template (NST)')
1507 @click.argument('name')
1508 @click.option('--content', default
=None,
1509 help='filename with the NST/NSTpkg replacing the current one')
1511 def nst_update1(ctx
, name
, content
):
1512 """updates a Network Slice Template (NST)
1514 NAME: name or ID of the NSD/NSpkg
1516 nst_update(ctx
, name
, content
)
1519 @cli.command(name
='netslice-template-update', short_help
='updates a Network Slice Template (NST)')
1520 @click.argument('name')
1521 @click.option('--content', default
=None,
1522 help='filename with the NST/NSTpkg replacing the current one')
1524 def nst_update2(ctx
, name
, content
):
1525 """updates a Network Slice Template (NST)
1527 NAME: name or ID of the NSD/NSpkg
1529 nst_update(ctx
, name
, content
)
1532 ####################
1534 ####################
1536 def nsd_delete(ctx
, name
, force
):
1539 ctx
.obj
.nsd
.delete(name
)
1541 check_client_version(ctx
.obj
, '--force')
1542 ctx
.obj
.nsd
.delete(name
, force
)
1543 except ClientException
as e
:
1548 @cli.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
1549 @click.argument('name')
1550 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1552 def nsd_delete1(ctx
, name
, force
):
1553 """deletes a NSD/NSpkg
1555 NAME: name or ID of the NSD/NSpkg to be deleted
1557 nsd_delete(ctx
, name
, force
)
1560 @cli.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
1561 @click.argument('name')
1562 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1564 def nsd_delete2(ctx
, name
, force
):
1565 """deletes a NSD/NSpkg
1567 NAME: name or ID of the NSD/NSpkg to be deleted
1569 nsd_delete(ctx
, name
, force
)
1572 def vnfd_delete(ctx
, name
, force
):
1575 ctx
.obj
.vnfd
.delete(name
)
1577 check_client_version(ctx
.obj
, '--force')
1578 ctx
.obj
.vnfd
.delete(name
, force
)
1579 except ClientException
as e
:
1584 @cli.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
1585 @click.argument('name')
1586 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1588 def vnfd_delete1(ctx
, name
, force
):
1589 """deletes a VNFD/VNFpkg
1591 NAME: name or ID of the VNFD/VNFpkg to be deleted
1593 vnfd_delete(ctx
, name
, force
)
1596 @cli.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
1597 @click.argument('name')
1598 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1600 def vnfd_delete2(ctx
, name
, force
):
1601 """deletes a VNFD/VNFpkg
1603 NAME: name or ID of the VNFD/VNFpkg to be deleted
1605 vnfd_delete(ctx
, name
, force
)
1608 @cli.command(name
='nfpkg-delete', short_help
='deletes a NFpkg')
1609 @click.argument('name')
1610 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1612 def nfpkg_delete(ctx
, name
, force
):
1615 NAME: name or ID of the NFpkg to be deleted
1617 vnfd_delete(ctx
, name
, force
)
1620 @cli.command(name
='ns-delete', short_help
='deletes a NS instance')
1621 @click.argument('name')
1622 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1623 @click.option('--wait',
1627 help='do not return the control immediately, but keep it \
1628 until the operation is completed, or timeout')
1630 def ns_delete(ctx
, name
, force
, wait
):
1631 """deletes a NS instance
1633 NAME: name or ID of the NS instance to be deleted
1637 ctx
.obj
.ns
.delete(name
, wait
=wait
)
1639 check_client_version(ctx
.obj
, '--force')
1640 ctx
.obj
.ns
.delete(name
, force
, wait
=wait
)
1641 except ClientException
as e
:
1646 def nst_delete(ctx
, name
, force
):
1648 check_client_version(ctx
.obj
, ctx
.command
.name
)
1649 ctx
.obj
.nst
.delete(name
, force
)
1650 except ClientException
as e
:
1655 @cli.command(name
='nst-delete', short_help
='deletes a Network Slice Template (NST)')
1656 @click.argument('name')
1657 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1659 def nst_delete1(ctx
, name
, force
):
1660 """deletes a Network Slice Template (NST)
1662 NAME: name or ID of the NST/NSTpkg to be deleted
1664 nst_delete(ctx
, name
, force
)
1667 @cli.command(name
='netslice-template-delete', short_help
='deletes a Network Slice Template (NST)')
1668 @click.argument('name')
1669 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1671 def nst_delete2(ctx
, name
, force
):
1672 """deletes a Network Slice Template (NST)
1674 NAME: name or ID of the NST/NSTpkg to be deleted
1676 nst_delete(ctx
, name
, force
)
1679 def nsi_delete(ctx
, name
, force
, wait
):
1681 check_client_version(ctx
.obj
, ctx
.command
.name
)
1682 ctx
.obj
.nsi
.delete(name
, force
, wait
=wait
)
1683 except ClientException
as e
:
1688 @cli.command(name
='nsi-delete', short_help
='deletes a Network Slice Instance (NSI)')
1689 @click.argument('name')
1690 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1691 @click.option('--wait',
1695 help='do not return the control immediately, but keep it \
1696 until the operation is completed, or timeout')
1698 def nsi_delete1(ctx
, name
, force
, wait
):
1699 """deletes a Network Slice Instance (NSI)
1701 NAME: name or ID of the Network Slice instance to be deleted
1703 nsi_delete(ctx
, name
, force
, wait
=wait
)
1706 @cli.command(name
='netslice-instance-delete', short_help
='deletes a Network Slice Instance (NSI)')
1707 @click.argument('name')
1708 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1710 def nsi_delete2(ctx
, name
, force
, wait
):
1711 """deletes a Network Slice Instance (NSI)
1713 NAME: name or ID of the Network Slice instance to be deleted
1715 nsi_delete(ctx
, name
, force
, wait
=wait
)
1718 @cli.command(name
='pdu-delete', short_help
='deletes a Physical Deployment Unit (PDU)')
1719 @click.argument('name')
1720 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1722 def pdu_delete(ctx
, name
, force
):
1723 """deletes a Physical Deployment Unit (PDU)
1725 NAME: name or ID of the PDU to be deleted
1728 check_client_version(ctx
.obj
, ctx
.command
.name
)
1729 ctx
.obj
.pdu
.delete(name
, force
)
1730 except ClientException
as e
:
1739 @cli.command(name
='vim-create', short_help
='creates a new VIM account')
1740 @click.option('--name',
1742 help='Name to create datacenter')
1743 @click.option('--user',
1745 help='VIM username')
1746 @click.option('--password',
1749 confirmation_prompt
=True,
1750 help='VIM password')
1751 @click.option('--auth_url',
1754 @click.option('--tenant',
1756 help='VIM tenant name')
1757 @click.option('--config',
1759 help='VIM specific config parameters')
1760 @click.option('--account_type',
1761 default
='openstack',
1763 @click.option('--description',
1764 default
='no description',
1765 help='human readable description')
1766 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
1767 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1768 @click.option('--wait',
1772 help='do not return the control immediately, but keep it \
1773 until the operation is completed, or timeout')
1787 """creates a new VIM account"""
1790 check_client_version(ctx
.obj
, '--sdn_controller')
1791 if sdn_port_mapping
:
1792 check_client_version(ctx
.obj
, '--sdn_port_mapping')
1794 vim
['vim-username'] = user
1795 vim
['vim-password'] = password
1796 vim
['vim-url'] = auth_url
1797 vim
['vim-tenant-name'] = tenant
1798 vim
['vim-type'] = account_type
1799 vim
['description'] = description
1800 vim
['config'] = config
1801 if sdn_controller
or sdn_port_mapping
:
1802 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
1804 ctx
.obj
.vim
.create(name
, vim
, wait
=wait
)
1805 except ClientException
as e
:
1810 @cli.command(name
='vim-update', short_help
='updates a VIM account')
1811 @click.argument('name')
1812 @click.option('--newname', help='New name for the VIM account')
1813 @click.option('--user', help='VIM username')
1814 @click.option('--password', help='VIM password')
1815 @click.option('--auth_url', help='VIM url')
1816 @click.option('--tenant', help='VIM tenant name')
1817 @click.option('--config', help='VIM specific config parameters')
1818 @click.option('--account_type', help='VIM type')
1819 @click.option('--description', help='human readable description')
1820 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
1821 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1822 @click.option('--wait',
1826 help='do not return the control immediately, but keep it \
1827 until the operation is completed, or timeout')
1842 """updates a VIM account
1844 NAME: name or ID of the VIM account
1847 check_client_version(ctx
.obj
, ctx
.command
.name
)
1849 if newname
: vim
['name'] = newname
1850 if user
: vim
['vim_user'] = user
1851 if password
: vim
['vim_password'] = password
1852 if auth_url
: vim
['vim_url'] = auth_url
1853 if tenant
: vim
['vim-tenant-name'] = tenant
1854 if account_type
: vim
['vim_type'] = account_type
1855 if description
: vim
['description'] = description
1856 if config
: vim
['config'] = config
1857 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
1858 except ClientException
as e
:
1863 @cli.command(name
='vim-delete', short_help
='deletes a VIM account')
1864 @click.argument('name')
1865 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1866 @click.option('--wait',
1870 help='do not return the control immediately, but keep it \
1871 until the operation is completed, or timeout')
1873 def vim_delete(ctx
, name
, force
, wait
):
1874 """deletes a VIM account
1876 NAME: name or ID of the VIM account to be deleted
1880 ctx
.obj
.vim
.delete(name
, wait
=wait
)
1882 check_client_version(ctx
.obj
, '--force')
1883 ctx
.obj
.vim
.delete(name
, force
, wait
=wait
)
1884 except ClientException
as e
:
1889 @cli.command(name
='vim-list', short_help
='list all VIM accounts')
1890 #@click.option('--ro_update/--no_ro_update',
1892 # help='update list from RO')
1893 @click.option('--filter', default
=None,
1894 help='restricts the list to the VIM accounts matching the filter')
1896 def vim_list(ctx
, filter):
1897 """list all VIM accounts"""
1899 check_client_version(ctx
.obj
, '--filter')
1901 # check_client_version(ctx.obj, '--ro_update', 'v1')
1902 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1903 if fullclassname
== 'osmclient.sol005.client.Client':
1904 resp
= ctx
.obj
.vim
.list(filter)
1906 # resp = ctx.obj.vim.list(ro_update)
1907 table
= PrettyTable(['vim name', 'uuid'])
1909 table
.add_row([vim
['name'], vim
['uuid']])
1914 @cli.command(name
='vim-show', short_help
='shows the details of a VIM account')
1915 @click.argument('name')
1917 def vim_show(ctx
, name
):
1918 """shows the details of a VIM account
1920 NAME: name or ID of the VIM account
1923 resp
= ctx
.obj
.vim
.get(name
)
1924 if 'vim_password' in resp
:
1925 resp
['vim_password']='********'
1926 except ClientException
as e
:
1930 table
= PrettyTable(['key', 'attribute'])
1931 for k
, v
in list(resp
.items()):
1932 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
1937 ####################
1939 ####################
1941 @cli.command(name
='wim-create', short_help
='creates a new WIM account')
1942 @click.option('--name',
1944 help='Name for the WIM account')
1945 @click.option('--user',
1946 help='WIM username')
1947 @click.option('--password',
1948 help='WIM password')
1949 @click.option('--url',
1952 # @click.option('--tenant',
1953 # help='wIM tenant name')
1954 @click.option('--config',
1956 help='WIM specific config parameters')
1957 @click.option('--wim_type',
1959 @click.option('--description',
1960 default
='no description',
1961 help='human readable description')
1962 @click.option('--wim_port_mapping', default
=None, help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge (WAN service endpoint id and info)")
1963 @click.option('--wait',
1967 help='do not return the control immediately, but keep it \
1968 until the operation is completed, or timeout')
1981 """creates a new WIM account"""
1983 check_client_version(ctx
.obj
, ctx
.command
.name
)
1984 # if sdn_controller:
1985 # check_client_version(ctx.obj, '--sdn_controller')
1986 # if sdn_port_mapping:
1987 # check_client_version(ctx.obj, '--sdn_port_mapping')
1989 if user
: wim
['user'] = user
1990 if password
: wim
['password'] = password
1991 if url
: wim
['wim_url'] = url
1992 # if tenant: wim['tenant'] = tenant
1993 wim
['wim_type'] = wim_type
1994 if description
: wim
['description'] = description
1995 if config
: wim
['config'] = config
1996 ctx
.obj
.wim
.create(name
, wim
, wim_port_mapping
, wait
=wait
)
1997 except ClientException
as e
:
2002 @cli.command(name
='wim-update', short_help
='updates a WIM account')
2003 @click.argument('name')
2004 @click.option('--newname', help='New name for the WIM account')
2005 @click.option('--user', help='WIM username')
2006 @click.option('--password', help='WIM password')
2007 @click.option('--url', help='WIM url')
2008 @click.option('--config', help='WIM specific config parameters')
2009 @click.option('--wim_type', help='WIM type')
2010 @click.option('--description', help='human readable description')
2011 @click.option('--wim_port_mapping', default
=None, help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge (WAN service endpoint id and info)")
2012 @click.option('--wait',
2016 help='do not return the control immediately, but keep it \
2017 until the operation is completed, or timeout')
2030 """updates a WIM account
2032 NAME: name or ID of the WIM account
2035 check_client_version(ctx
.obj
, ctx
.command
.name
)
2037 if newname
: wim
['name'] = newname
2038 if user
: wim
['user'] = user
2039 if password
: wim
['password'] = password
2040 if url
: wim
['url'] = url
2041 # if tenant: wim['tenant'] = tenant
2042 if wim_type
: wim
['wim_type'] = wim_type
2043 if description
: wim
['description'] = description
2044 if config
: wim
['config'] = config
2045 ctx
.obj
.wim
.update(name
, wim
, wim_port_mapping
, wait
=wait
)
2046 except ClientException
as e
:
2051 @cli.command(name
='wim-delete', short_help
='deletes a WIM account')
2052 @click.argument('name')
2053 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2054 @click.option('--wait',
2058 help='do not return the control immediately, but keep it \
2059 until the operation is completed, or timeout')
2061 def wim_delete(ctx
, name
, force
, wait
):
2062 """deletes a WIM account
2064 NAME: name or ID of the WIM account to be deleted
2067 check_client_version(ctx
.obj
, ctx
.command
.name
)
2068 ctx
.obj
.wim
.delete(name
, force
, wait
=wait
)
2069 except ClientException
as e
:
2074 @cli.command(name
='wim-list', short_help
='list all WIM accounts')
2075 @click.option('--filter', default
=None,
2076 help='restricts the list to the WIM accounts matching the filter')
2078 def wim_list(ctx
, filter):
2079 """list all WIM accounts"""
2081 check_client_version(ctx
.obj
, ctx
.command
.name
)
2082 resp
= ctx
.obj
.wim
.list(filter)
2083 table
= PrettyTable(['wim name', 'uuid'])
2085 table
.add_row([wim
['name'], wim
['uuid']])
2088 except ClientException
as e
:
2093 @cli.command(name
='wim-show', short_help
='shows the details of a WIM account')
2094 @click.argument('name')
2096 def wim_show(ctx
, name
):
2097 """shows the details of a WIM account
2099 NAME: name or ID of the WIM account
2102 check_client_version(ctx
.obj
, ctx
.command
.name
)
2103 resp
= ctx
.obj
.wim
.get(name
)
2104 if 'password' in resp
:
2105 resp
['wim_password']='********'
2106 except ClientException
as e
:
2110 table
= PrettyTable(['key', 'attribute'])
2111 for k
, v
in list(resp
.items()):
2112 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2117 ####################
2118 # SDN controller operations
2119 ####################
2121 @cli.command(name
='sdnc-create', short_help
='creates a new SDN controller')
2122 @click.option('--name',
2124 help='Name to create sdn controller')
2125 @click.option('--type',
2127 help='SDN controller type')
2128 @click.option('--sdn_controller_version',
2129 help='SDN controller version')
2130 @click.option('--ip_address',
2132 help='SDN controller IP address')
2133 @click.option('--port',
2135 help='SDN controller port')
2136 @click.option('--switch_dpid',
2138 help='Switch DPID (Openflow Datapath ID)')
2139 @click.option('--user',
2140 help='SDN controller username')
2141 @click.option('--password',
2143 confirmation_prompt
=True,
2144 help='SDN controller password')
2145 #@click.option('--description',
2146 # default='no description',
2147 # help='human readable description')
2148 @click.option('--wait',
2152 help='do not return the control immediately, but keep it \
2153 until the operation is completed, or timeout')
2155 def sdnc_create(ctx
,
2158 sdn_controller_version
,
2165 """creates a new SDN controller"""
2167 sdncontroller
['name'] = name
2168 sdncontroller
['type'] = type
2169 sdncontroller
['ip'] = ip_address
2170 sdncontroller
['port'] = int(port
)
2171 sdncontroller
['dpid'] = switch_dpid
2172 if sdn_controller_version
:
2173 sdncontroller
['version'] = sdn_controller_version
2175 sdncontroller
['user'] = user
2177 sdncontroller
['password'] = password
2178 # sdncontroller['description'] = description
2180 check_client_version(ctx
.obj
, ctx
.command
.name
)
2181 ctx
.obj
.sdnc
.create(name
, sdncontroller
, wait
=wait
)
2182 except ClientException
as e
:
2186 @cli.command(name
='sdnc-update', short_help
='updates an SDN controller')
2187 @click.argument('name')
2188 @click.option('--newname', help='New name for the SDN controller')
2189 @click.option('--type', help='SDN controller type')
2190 @click.option('--sdn_controller_version', help='SDN controller username')
2191 @click.option('--ip_address', help='SDN controller IP address')
2192 @click.option('--port', help='SDN controller port')
2193 @click.option('--switch_dpid', help='Switch DPID (Openflow Datapath ID)')
2194 @click.option('--user', help='SDN controller username')
2195 @click.option('--password', help='SDN controller password')
2196 #@click.option('--description', default=None, help='human readable description')
2197 @click.option('--wait',
2201 help='do not return the control immediately, but keep it \
2202 until the operation is completed, or timeout')
2204 def sdnc_update(ctx
,
2208 sdn_controller_version
,
2215 """updates an SDN controller
2217 NAME: name or ID of the SDN controller
2220 if newname
: sdncontroller
['name'] = newname
2221 if type: sdncontroller
['type'] = type
2222 if ip_address
: sdncontroller
['ip'] = ip_address
2223 if port
: sdncontroller
['port'] = int(port
)
2224 if switch_dpid
: sdncontroller
['dpid'] = switch_dpid
2225 # sdncontroller['description'] = description
2226 if sdn_controller_version
is not None:
2227 if sdn_controller_version
=="":
2228 sdncontroller
['version'] = None
2230 sdncontroller
['version'] = sdn_controller_version
2231 if user
is not None:
2233 sdncontroller
['user'] = None
2235 sdncontroller
['user'] = user
2236 if password
is not None:
2238 sdncontroller
['password'] = None
2240 sdncontroller
['password'] = user
2242 check_client_version(ctx
.obj
, ctx
.command
.name
)
2243 ctx
.obj
.sdnc
.update(name
, sdncontroller
, wait
=wait
)
2244 except ClientException
as e
:
2249 @cli.command(name
='sdnc-delete', short_help
='deletes an SDN controller')
2250 @click.argument('name')
2251 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2252 @click.option('--wait',
2256 help='do not return the control immediately, but keep it \
2257 until the operation is completed, or timeout')
2259 def sdnc_delete(ctx
, name
, force
, wait
):
2260 """deletes an SDN controller
2262 NAME: name or ID of the SDN controller to be deleted
2265 check_client_version(ctx
.obj
, ctx
.command
.name
)
2266 ctx
.obj
.sdnc
.delete(name
, force
, wait
=wait
)
2267 except ClientException
as e
:
2272 @cli.command(name
='sdnc-list', short_help
='list all SDN controllers')
2273 @click.option('--filter', default
=None,
2274 help='restricts the list to the SDN controllers matching the filter')
2276 def sdnc_list(ctx
, filter):
2277 """list all SDN controllers"""
2279 check_client_version(ctx
.obj
, ctx
.command
.name
)
2280 resp
= ctx
.obj
.sdnc
.list(filter)
2281 except ClientException
as e
:
2284 table
= PrettyTable(['sdnc name', 'id'])
2286 table
.add_row([sdnc
['name'], sdnc
['_id']])
2291 @cli.command(name
='sdnc-show', short_help
='shows the details of an SDN controller')
2292 @click.argument('name')
2294 def sdnc_show(ctx
, name
):
2295 """shows the details of an SDN controller
2297 NAME: name or ID of the SDN controller
2300 check_client_version(ctx
.obj
, ctx
.command
.name
)
2301 resp
= ctx
.obj
.sdnc
.get(name
)
2302 except ClientException
as e
:
2306 table
= PrettyTable(['key', 'attribute'])
2307 for k
, v
in list(resp
.items()):
2308 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2313 ###########################
2314 # K8s cluster operations
2315 ###########################
2317 @cli.command(name
='k8scluster-add')
2318 @click.argument('name')
2319 @click.option('--creds',
2321 help='credentials file, i.e. a valid `.kube/config` file')
2322 @click.option('--version',
2324 help='Kubernetes version')
2325 @click.option('--vim',
2327 help='VIM target, the VIM where the cluster resides')
2328 @click.option('--k8s-nets',
2330 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) ...]}"')
2331 @click.option('--description',
2333 help='human readable description')
2334 @click.option('--namespace',
2335 default
='kube-system',
2336 help='namespace to be used for its operation, defaults to `kube-system`')
2337 @click.option('--cni',
2339 help='list of CNI plugins, in JSON inline format, used in the cluster')
2340 #@click.option('--skip-init',
2342 # help='If set, K8s cluster is assumed to be ready for its use with OSM')
2343 #@click.option('--wait',
2345 # help='do not return the control immediately, but keep it \
2346 # until the operation is completed, or timeout')
2348 def k8scluster_add(ctx
,
2357 """adds a K8s cluster to OSM
2359 NAME: name of the K8s cluster
2362 check_client_version(ctx
.obj
, ctx
.command
.name
)
2364 cluster
['name'] = name
2365 with
open(creds
, 'r') as cf
:
2366 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2367 cluster
['k8s_version'] = version
2368 cluster
['vim_account'] = vim
2369 cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2370 cluster
['description'] = description
2371 if namespace
: cluster
['namespace'] = namespace
2372 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2373 ctx
.obj
.k8scluster
.create(name
, cluster
)
2374 except ClientException
as e
:
2379 @cli.command(name
='k8scluster-update', short_help
='updates a K8s cluster')
2380 @click.argument('name')
2381 @click.option('--newname', help='New name for the K8s cluster')
2382 @click.option('--creds', help='credentials file, i.e. a valid `.kube/config` file')
2383 @click.option('--version', help='Kubernetes version')
2384 @click.option('--vim', help='VIM target, the VIM where the cluster resides')
2385 @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) ...]}"')
2386 @click.option('--description', help='human readable description')
2387 @click.option('--namespace', help='namespace to be used for its operation, defaults to `kube-system`')
2388 @click.option('--cni', help='list of CNI plugins, in JSON inline format, used in the cluster')
2390 def k8scluster_update(ctx
,
2400 """updates a K8s cluster
2402 NAME: name or ID of the K8s cluster
2405 check_client_version(ctx
.obj
, ctx
.command
.name
)
2407 if newname
: cluster
['name'] = newname
2409 with
open(creds
, 'r') as cf
:
2410 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2411 if version
: cluster
['k8s_version'] = version
2412 if vim
: cluster
['vim_account'] = vim
2413 if k8s_nets
: cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2414 if description
: cluster
['description'] = description
2415 if namespace
: cluster
['namespace'] = namespace
2416 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2417 ctx
.obj
.k8scluster
.update(name
, cluster
)
2418 except ClientException
as e
:
2423 @cli.command(name
='k8scluster-delete')
2424 @click.argument('name')
2425 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2426 #@click.option('--wait',
2428 # help='do not return the control immediately, but keep it \
2429 # until the operation is completed, or timeout')
2431 def k8scluster_delete(ctx
, name
, force
):
2432 """deletes a K8s cluster
2434 NAME: name or ID of the K8s cluster to be deleted
2437 check_client_version(ctx
.obj
, ctx
.command
.name
)
2438 ctx
.obj
.k8scluster
.delete(name
, force
=force
)
2439 except ClientException
as e
:
2444 @cli.command(name
='k8scluster-list')
2445 @click.option('--filter', default
=None,
2446 help='restricts the list to the K8s clusters matching the filter')
2447 @click.option('--literal', is_flag
=True,
2448 help='print literally, no pretty table')
2450 def k8scluster_list(ctx
, filter, literal
):
2451 """list all K8s clusters"""
2453 check_client_version(ctx
.obj
, ctx
.command
.name
)
2454 resp
= ctx
.obj
.k8scluster
.list(filter)
2456 print(yaml
.safe_dump(resp
))
2458 table
= PrettyTable(['Name', 'Id', 'Version', 'VIM', 'K8s-nets', 'Operational State', 'Description'])
2459 for cluster
in resp
:
2460 table
.add_row([cluster
['name'], cluster
['_id'], cluster
['k8s_version'], cluster
['vim_account'],
2461 json
.dumps(cluster
['nets']), cluster
["_admin"]["operationalState"],
2462 trunc_text(cluster
.get('description',''),40)])
2465 except ClientException
as e
:
2470 @cli.command(name
='k8scluster-show')
2471 @click.argument('name')
2472 @click.option('--literal', is_flag
=True,
2473 help='print literally, no pretty table')
2475 def k8scluster_show(ctx
, name
, literal
):
2476 """shows the details of a K8s cluster
2478 NAME: name or ID of the K8s cluster
2481 resp
= ctx
.obj
.k8scluster
.get(name
)
2483 print(yaml
.safe_dump(resp
))
2485 table
= PrettyTable(['key', 'attribute'])
2486 for k
, v
in list(resp
.items()):
2487 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2490 except ClientException
as e
:
2496 ###########################
2498 ###########################
2500 @cli.command(name
='repo-add')
2501 @click.argument('name')
2502 @click.argument('uri')
2503 @click.option('--type',
2504 type=click
.Choice(['helm-chart', 'juju-bundle']),
2506 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2507 @click.option('--description',
2509 help='human readable description')
2510 #@click.option('--wait',
2512 # help='do not return the control immediately, but keep it \
2513 # until the operation is completed, or timeout')
2520 """adds a repo to OSM
2522 NAME: name of the repo
2523 URI: URI of the repo
2526 check_client_version(ctx
.obj
, ctx
.command
.name
)
2531 repo
['description'] = description
2532 ctx
.obj
.repo
.create(name
, repo
)
2533 except ClientException
as e
:
2538 @cli.command(name
='repo-update')
2539 @click.argument('name')
2540 @click.option('--newname', help='New name for the repo')
2541 @click.option('--uri', help='URI of the repo')
2542 @click.option('--type', type=click
.Choice(['helm-chart', 'juju-bundle']),
2543 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2544 @click.option('--description', help='human readable description')
2545 #@click.option('--wait',
2547 # help='do not return the control immediately, but keep it \
2548 # until the operation is completed, or timeout')
2550 def repo_update(ctx
,
2556 """updates a repo in OSM
2558 NAME: name of the repo
2561 check_client_version(ctx
.obj
, ctx
.command
.name
)
2563 if newname
: repo
['name'] = newname
2564 if uri
: repo
['uri'] = uri
2565 if type: repo
['type'] = type
2566 if description
: repo
['description'] = description
2567 ctx
.obj
.repo
.update(name
, repo
)
2568 except ClientException
as e
:
2573 @cli.command(name
='repo-delete')
2574 @click.argument('name')
2575 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2576 #@click.option('--wait',
2578 # help='do not return the control immediately, but keep it \
2579 # until the operation is completed, or timeout')
2581 def repo_delete(ctx
, name
, force
):
2584 NAME: name or ID of the repo to be deleted
2587 check_client_version(ctx
.obj
, ctx
.command
.name
)
2588 ctx
.obj
.repo
.delete(name
, force
=force
)
2589 except ClientException
as e
:
2594 @cli.command(name
='repo-list')
2595 @click.option('--filter', default
=None,
2596 help='restricts the list to the repos matching the filter')
2597 @click.option('--literal', is_flag
=True,
2598 help='print literally, no pretty table')
2600 def repo_list(ctx
, filter, literal
):
2601 """list all repos"""
2603 check_client_version(ctx
.obj
, ctx
.command
.name
)
2604 resp
= ctx
.obj
.repo
.list(filter)
2606 print(yaml
.safe_dump(resp
))
2608 table
= PrettyTable(['Name', 'Id', 'Type', 'URI', 'Description'])
2610 #cluster['k8s-nets'] = json.dumps(yaml.safe_load(cluster['k8s-nets']))
2611 table
.add_row([repo
['name'], repo
['_id'], repo
['type'], repo
['url'], trunc_text(repo
.get('description',''),40)])
2614 except ClientException
as e
:
2619 @cli.command(name
='repo-show')
2620 @click.argument('name')
2621 @click.option('--literal', is_flag
=True,
2622 help='print literally, no pretty table')
2624 def repo_show(ctx
, name
, literal
):
2625 """shows the details of a repo
2627 NAME: name or ID of the repo
2630 resp
= ctx
.obj
.repo
.get(name
)
2632 print(yaml
.safe_dump(resp
))
2634 table
= PrettyTable(['key', 'attribute'])
2635 for k
, v
in list(resp
.items()):
2636 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2639 except ClientException
as e
:
2645 ####################
2646 # Project mgmt operations
2647 ####################
2649 @cli.command(name
='project-create', short_help
='creates a new project')
2650 @click.argument('name')
2651 #@click.option('--description',
2652 # default='no description',
2653 # help='human readable description')
2655 def project_create(ctx
, name
):
2656 """Creates a new project
2658 NAME: name of the project
2661 project
['name'] = name
2663 check_client_version(ctx
.obj
, ctx
.command
.name
)
2664 ctx
.obj
.project
.create(name
, project
)
2665 except ClientException
as e
:
2670 @cli.command(name
='project-delete', short_help
='deletes a project')
2671 @click.argument('name')
2672 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2674 def project_delete(ctx
, name
):
2675 """deletes a project
2677 NAME: name or ID of the project to be deleted
2680 check_client_version(ctx
.obj
, ctx
.command
.name
)
2681 ctx
.obj
.project
.delete(name
)
2682 except ClientException
as e
:
2687 @cli.command(name
='project-list', short_help
='list all projects')
2688 @click.option('--filter', default
=None,
2689 help='restricts the list to the projects matching the filter')
2691 def project_list(ctx
, filter):
2692 """list all projects"""
2694 check_client_version(ctx
.obj
, ctx
.command
.name
)
2695 resp
= ctx
.obj
.project
.list(filter)
2696 except ClientException
as e
:
2699 table
= PrettyTable(['name', 'id'])
2701 table
.add_row([proj
['name'], proj
['_id']])
2706 @cli.command(name
='project-show', short_help
='shows the details of a project')
2707 @click.argument('name')
2709 def project_show(ctx
, name
):
2710 """shows the details of a project
2712 NAME: name or ID of the project
2715 check_client_version(ctx
.obj
, ctx
.command
.name
)
2716 resp
= ctx
.obj
.project
.get(name
)
2717 except ClientException
as e
:
2721 table
= PrettyTable(['key', 'attribute'])
2722 for k
, v
in resp
.items():
2723 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2728 @cli.command(name
='project-update', short_help
='updates a project (only the name can be updated)')
2729 @click.argument('project')
2730 @click.option('--name',
2732 help='new name for the project')
2735 def project_update(ctx
, project
, name
):
2737 Update a project name
2740 :param project: id or name of the project to modify
2741 :param name: new name for the project
2745 project_changes
= {}
2746 project_changes
['name'] = name
2749 check_client_version(ctx
.obj
, ctx
.command
.name
)
2750 ctx
.obj
.project
.update(project
, project_changes
)
2751 except ClientException
as e
:
2755 ####################
2756 # User mgmt operations
2757 ####################
2759 @cli.command(name
='user-create', short_help
='creates a new user')
2760 @click.argument('username')
2761 @click.option('--password',
2764 confirmation_prompt
=True,
2765 help='user password')
2766 @click.option('--projects',
2767 # prompt="Comma separate list of projects",
2769 callback
=lambda ctx
, param
, value
: ''.join(value
).split(',') if all(len(x
)==1 for x
in value
) else value
,
2770 help='list of project ids that the user belongs to')
2771 @click.option('--project-role-mappings', 'project_role_mappings',
2772 default
=None, multiple
=True,
2773 help='creating user project/role(s) mapping')
2775 def user_create(ctx
, username
, password
, projects
, project_role_mappings
):
2776 """Creates a new user
2779 USERNAME: name of the user
2780 PASSWORD: password of the user
2781 PROJECTS: projects assigned to user (internal only)
2782 PROJECT_ROLE_MAPPING: roles in projects assigned to user (keystone)
2785 user
['username'] = username
2786 user
['password'] = password
2787 user
['projects'] = projects
2788 user
['project_role_mappings'] = project_role_mappings
2791 check_client_version(ctx
.obj
, ctx
.command
.name
)
2792 ctx
.obj
.user
.create(username
, user
)
2793 except ClientException
as e
:
2798 @cli.command(name
='user-update', short_help
='updates user information')
2799 @click.argument('username')
2800 @click.option('--password',
2803 # confirmation_prompt=True,
2804 help='user password')
2805 @click.option('--set-username', 'set_username',
2807 help='change username')
2808 @click.option('--set-project', 'set_project',
2809 default
=None, multiple
=True,
2810 help='create/replace the project,role(s) mapping for this project: \'project,role1,role2,...\'')
2811 @click.option('--remove-project', 'remove_project',
2812 default
=None, multiple
=True,
2813 help='removes project from user: \'project\'')
2814 @click.option('--add-project-role', 'add_project_role',
2815 default
=None, multiple
=True,
2816 help='adds project,role(s) mapping: \'project,role1,role2,...\'')
2817 @click.option('--remove-project-role', 'remove_project_role',
2818 default
=None, multiple
=True,
2819 help='removes project,role(s) mapping: \'project,role1,role2,...\'')
2821 def user_update(ctx
, username
, password
, set_username
, set_project
, remove_project
,
2822 add_project_role
, remove_project_role
):
2823 """Update a user information
2826 USERNAME: name of the user
2827 PASSWORD: new password
2828 SET_USERNAME: new username
2829 SET_PROJECT: creating mappings for project/role(s)
2830 REMOVE_PROJECT: deleting mappings for project/role(s)
2831 ADD_PROJECT_ROLE: adding mappings for project/role(s)
2832 REMOVE_PROJECT_ROLE: removing mappings for project/role(s)
2835 user
['password'] = password
2836 user
['username'] = set_username
2837 user
['set-project'] = set_project
2838 user
['remove-project'] = remove_project
2839 user
['add-project-role'] = add_project_role
2840 user
['remove-project-role'] = remove_project_role
2843 check_client_version(ctx
.obj
, ctx
.command
.name
)
2844 ctx
.obj
.user
.update(username
, user
)
2845 except ClientException
as e
:
2850 @cli.command(name
='user-delete', short_help
='deletes a user')
2851 @click.argument('name')
2852 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2854 def user_delete(ctx
, name
):
2858 NAME: name or ID of the user to be deleted
2861 check_client_version(ctx
.obj
, ctx
.command
.name
)
2862 ctx
.obj
.user
.delete(name
)
2863 except ClientException
as e
:
2868 @cli.command(name
='user-list', short_help
='list all users')
2869 @click.option('--filter', default
=None,
2870 help='restricts the list to the users matching the filter')
2872 def user_list(ctx
, filter):
2873 """list all users"""
2875 check_client_version(ctx
.obj
, ctx
.command
.name
)
2876 resp
= ctx
.obj
.user
.list(filter)
2877 except ClientException
as e
:
2880 table
= PrettyTable(['name', 'id'])
2882 table
.add_row([user
['username'], user
['_id']])
2887 @cli.command(name
='user-show', short_help
='shows the details of a user')
2888 @click.argument('name')
2890 def user_show(ctx
, name
):
2891 """shows the details of a user
2893 NAME: name or ID of the user
2896 check_client_version(ctx
.obj
, ctx
.command
.name
)
2897 resp
= ctx
.obj
.user
.get(name
)
2898 if 'password' in resp
:
2899 resp
['password']='********'
2900 except ClientException
as e
:
2904 table
= PrettyTable(['key', 'attribute'])
2905 for k
, v
in resp
.items():
2906 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2911 ####################
2912 # Fault Management operations
2913 ####################
2915 @cli.command(name
='ns-alarm-create')
2916 @click.argument('name')
2917 @click.option('--ns', prompt
=True, help='NS instance id or name')
2918 @click.option('--vnf', prompt
=True,
2919 help='VNF name (VNF member index as declared in the NSD)')
2920 @click.option('--vdu', prompt
=True,
2921 help='VDU name (VDU name as declared in the VNFD)')
2922 @click.option('--metric', prompt
=True,
2923 help='Name of the metric (e.g. cpu_utilization)')
2924 @click.option('--severity', default
='WARNING',
2925 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
2926 @click.option('--threshold_value', prompt
=True,
2927 help='threshold value that, when crossed, an alarm is triggered')
2928 @click.option('--threshold_operator', prompt
=True,
2929 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
2930 @click.option('--statistic', default
='AVERAGE',
2931 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
2933 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
2934 threshold_value
, threshold_operator
, statistic
):
2935 """creates a new alarm for a NS instance"""
2936 # TODO: Check how to validate threshold_value.
2937 # Should it be an integer (1-100), percentage, or decimal (0.01-1.00)?
2939 ns_instance
= ctx
.obj
.ns
.get(ns
)
2941 alarm
['alarm_name'] = name
2942 alarm
['ns_id'] = ns_instance
['_id']
2943 alarm
['correlation_id'] = ns_instance
['_id']
2944 alarm
['vnf_member_index'] = vnf
2945 alarm
['vdu_name'] = vdu
2946 alarm
['metric_name'] = metric
2947 alarm
['severity'] = severity
2948 alarm
['threshold_value'] = int(threshold_value
)
2949 alarm
['operation'] = threshold_operator
2950 alarm
['statistic'] = statistic
2951 check_client_version(ctx
.obj
, ctx
.command
.name
)
2952 ctx
.obj
.ns
.create_alarm(alarm
)
2953 except ClientException
as e
:
2958 #@cli.command(name='ns-alarm-delete')
2959 #@click.argument('name')
2960 #@click.pass_context
2961 #def ns_alarm_delete(ctx, name):
2962 # """deletes an alarm
2964 # NAME: name of the alarm to be deleted
2967 # check_client_version(ctx.obj, ctx.command.name)
2968 # ctx.obj.ns.delete_alarm(name)
2969 # except ClientException as e:
2974 ####################
2975 # Performance Management operations
2976 ####################
2978 @cli.command(name
='ns-metric-export', short_help
='exports a metric to the internal OSM bus, which can be read by other apps')
2979 @click.option('--ns', prompt
=True, help='NS instance id or name')
2980 @click.option('--vnf', prompt
=True,
2981 help='VNF name (VNF member index as declared in the NSD)')
2982 @click.option('--vdu', prompt
=True,
2983 help='VDU name (VDU name as declared in the VNFD)')
2984 @click.option('--metric', prompt
=True,
2985 help='name of the metric (e.g. cpu_utilization)')
2986 #@click.option('--period', default='1w',
2987 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
2988 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
2990 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
2991 """exports a metric to the internal OSM bus, which can be read by other apps"""
2992 # TODO: Check how to validate interval.
2993 # Should it be an integer (seconds), or should a suffix (s,m,h,d,w) also be permitted?
2995 ns_instance
= ctx
.obj
.ns
.get(ns
)
2997 metric_data
['ns_id'] = ns_instance
['_id']
2998 metric_data
['correlation_id'] = ns_instance
['_id']
2999 metric_data
['vnf_member_index'] = vnf
3000 metric_data
['vdu_name'] = vdu
3001 metric_data
['metric_name'] = metric
3002 metric_data
['collection_unit'] = 'WEEK'
3003 metric_data
['collection_period'] = 1
3004 check_client_version(ctx
.obj
, ctx
.command
.name
)
3006 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
3010 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
3011 time
.sleep(int(interval
))
3013 except ClientException
as e
:
3018 ####################
3020 ####################
3022 @cli.command(name
='version')
3024 def get_version(ctx
):
3026 check_client_version(ctx
.obj
, "version")
3027 print ("Server version: {}".format(ctx
.obj
.get_version()))
3028 print ("Client version: {}".format(pkg_resources
.get_distribution("osmclient").version
))
3029 except ClientException
as e
:
3033 @cli.command(name
='upload-package', short_help
='uploads a VNF package or NS package')
3034 @click.argument('filename')
3036 def upload_package(ctx
, filename
):
3037 """uploads a VNF package or NS package
3039 FILENAME: VNF or NS package file (tar.gz)
3042 ctx
.obj
.package
.upload(filename
)
3043 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
3044 if fullclassname
!= 'osmclient.sol005.client.Client':
3045 ctx
.obj
.package
.wait_for_upload(filename
)
3046 except ClientException
as e
:
3051 #@cli.command(name='ns-scaling-show')
3052 #@click.argument('ns_name')
3053 #@click.pass_context
3054 #def show_ns_scaling(ctx, ns_name):
3055 # """shows the status of a NS scaling operation
3057 # NS_NAME: name of the NS instance being scaled
3060 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3061 # resp = ctx.obj.ns.list()
3062 # except ClientException as e:
3066 # table = PrettyTable(
3069 # 'operational status',
3074 # if ns_name == ns['name']:
3075 # nsopdata = ctx.obj.ns.get_opdata(ns['id'])
3076 # scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
3077 # for record in scaling_records:
3078 # if 'instance' in record:
3079 # instances = record['instance']
3080 # for inst in instances:
3082 # [record['scaling-group-name-ref'],
3083 # inst['instance-id'],
3084 # inst['op-status'],
3085 # time.strftime('%Y-%m-%d %H:%M:%S',
3087 # inst['create-time'])),
3093 #@cli.command(name='ns-scale')
3094 #@click.argument('ns_name')
3095 #@click.option('--ns_scale_group', prompt=True)
3096 #@click.option('--index', prompt=True)
3097 #@click.option('--wait',
3101 # help='do not return the control immediately, but keep it \
3102 # until the operation is completed, or timeout')
3103 #@click.pass_context
3104 #def ns_scale(ctx, ns_name, ns_scale_group, index, wait):
3107 # NS_NAME: name of the NS instance to be scaled
3110 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3111 # ctx.obj.ns.scale(ns_name, ns_scale_group, index, wait=wait)
3112 # except ClientException as e:
3117 #@cli.command(name='config-agent-list')
3118 #@click.pass_context
3119 #def config_agent_list(ctx):
3120 # """list config agents"""
3122 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3123 # except ClientException as e:
3126 # table = PrettyTable(['name', 'account-type', 'details'])
3127 # for account in ctx.obj.vca.list():
3130 # account['account-type'],
3136 #@cli.command(name='config-agent-delete')
3137 #@click.argument('name')
3138 #@click.pass_context
3139 #def config_agent_delete(ctx, name):
3140 # """deletes a config agent
3142 # NAME: name of the config agent to be deleted
3145 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3146 # ctx.obj.vca.delete(name)
3147 # except ClientException as e:
3152 #@cli.command(name='config-agent-add')
3153 #@click.option('--name',
3155 #@click.option('--account_type',
3157 #@click.option('--server',
3159 #@click.option('--user',
3161 #@click.option('--secret',
3164 # confirmation_prompt=True)
3165 #@click.pass_context
3166 #def config_agent_add(ctx, name, account_type, server, user, secret):
3167 # """adds a config agent"""
3169 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3170 # ctx.obj.vca.create(name, account_type, server, user, secret)
3171 # except ClientException as e:
3176 #@cli.command(name='ro-dump')
3177 #@click.pass_context
3179 # """shows RO agent information"""
3180 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3181 # resp = ctx.obj.vim.get_resource_orchestrator()
3182 # table = PrettyTable(['key', 'attribute'])
3183 # for k, v in list(resp.items()):
3184 # table.add_row([k, json.dumps(v, indent=2)])
3189 #@cli.command(name='vcs-list')
3190 #@click.pass_context
3192 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3193 # resp = ctx.obj.utils.get_vcs_info()
3194 # table = PrettyTable(['component name', 'state'])
3195 # for component in resp:
3196 # table.add_row([component['component_name'], component['state']])
3201 @cli.command(name
='ns-action', short_help
='executes an action/primitive over a NS instance')
3202 @click.argument('ns_name')
3203 @click.option('--vnf_name', default
=None, help='member-vnf-index if the target is a vnf instead of a ns)')
3204 @click.option('--kdu_name', default
=None, help='kdu-name if the target is a kdu)')
3205 @click.option('--vdu_id', default
=None, help='vdu-id if the target is a vdu')
3206 @click.option('--vdu_count', default
=None, help='number of vdu instance of this vdu_id')
3207 @click.option('--action_name', prompt
=True, help='action name')
3208 @click.option('--params', default
=None, help='action params in YAML/JSON inline string')
3209 @click.option('--params_file', default
=None, help='YAML/JSON file with action params')
3210 @click.option('--wait',
3214 help='do not return the control immediately, but keep it \
3215 until the operation is completed, or timeout')
3227 """executes an action/primitive over a NS instance
3229 NS_NAME: name or ID of the NS instance
3232 check_client_version(ctx
.obj
, ctx
.command
.name
)
3235 op_data
['member_vnf_index'] = vnf_name
3237 op_data
['kdu_name'] = kdu_name
3239 op_data
['vdu_id'] = vdu_id
3241 op_data
['vdu_count_index'] = vdu_count
3242 op_data
['primitive'] = action_name
3244 with
open(params_file
, 'r') as pf
:
3247 op_data
['primitive_params'] = yaml
.safe_load(params
)
3249 op_data
['primitive_params'] = {}
3250 print(ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
, wait
=wait
))
3252 except ClientException
as e
:
3257 @cli.command(name
='vnf-scale', short_help
='executes a VNF scale (adding/removing VDUs)')
3258 @click.argument('ns_name')
3259 @click.argument('vnf_name')
3260 @click.option('--scaling-group', prompt
=True, help="scaling-group-descriptor name to use")
3261 @click.option('--scale-in', default
=False, is_flag
=True, help="performs a scale in operation")
3262 @click.option('--scale-out', default
=False, is_flag
=True, help="performs a scale out operation (by default)")
3271 Executes a VNF scale (adding/removing VDUs)
3274 NS_NAME: name or ID of the NS instance.
3275 VNF_NAME: member-vnf-index in the NS to be scaled.
3278 check_client_version(ctx
.obj
, ctx
.command
.name
)
3279 if not scale_in
and not scale_out
:
3281 ctx
.obj
.ns
.scale_vnf(ns_name
, vnf_name
, scaling_group
, scale_in
, scale_out
)
3282 except ClientException
as e
:
3287 ##############################
3288 # Role Management Operations #
3289 ##############################
3291 @cli.command(name
='role-create', short_help
='creates a new role')
3292 @click.argument('name')
3293 @click.option('--permissions',
3295 help='role permissions using a dictionary')
3297 def role_create(ctx
, name
, permissions
):
3302 NAME: Name or ID of the role.
3303 DEFINITION: Definition of grant/denial of access to resources.
3306 check_client_version(ctx
.obj
, ctx
.command
.name
)
3307 ctx
.obj
.role
.create(name
, permissions
)
3308 except ClientException
as e
:
3313 @cli.command(name
='role-update', short_help
='updates a role')
3314 @click.argument('name')
3315 @click.option('--set-name',
3317 help='change name of rle')
3318 # @click.option('--permissions',
3320 # help='provide a yaml format dictionary with incremental changes. Values can be bool or None to delete')
3321 @click.option('--add',
3323 help='yaml format dictionary with permission: True/False to access grant/denial')
3324 @click.option('--remove',
3326 help='yaml format list to remove a permission')
3328 def role_update(ctx
, name
, set_name
, add
, remove
):
3333 NAME: Name or ID of the role.
3334 DEFINITION: Definition overwrites the old definition.
3335 ADD: Grant/denial of access to resource to add.
3336 REMOVE: Grant/denial of access to resource to remove.
3339 check_client_version(ctx
.obj
, ctx
.command
.name
)
3340 ctx
.obj
.role
.update(name
, set_name
, None, add
, remove
)
3341 except ClientException
as e
:
3346 @cli.command(name
='role-delete', short_help
='deletes a role')
3347 @click.argument('name')
3348 # @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3350 def role_delete(ctx
, name
):
3355 NAME: Name or ID of the role.
3358 check_client_version(ctx
.obj
, ctx
.command
.name
)
3359 ctx
.obj
.role
.delete(name
)
3360 except ClientException
as e
:
3365 @cli.command(name
='role-list', short_help
='list all roles')
3366 @click.option('--filter', default
=None,
3367 help='restricts the list to the projects matching the filter')
3369 def role_list(ctx
, filter):
3374 check_client_version(ctx
.obj
, ctx
.command
.name
)
3375 resp
= ctx
.obj
.role
.list(filter)
3376 except ClientException
as e
:
3379 table
= PrettyTable(['name', 'id'])
3381 table
.add_row([role
['name'], role
['_id']])
3386 @cli.command(name
='role-show', short_help
='show specific role')
3387 @click.argument('name')
3389 def role_show(ctx
, name
):
3391 Shows the details of a role.
3394 NAME: Name or ID of the role.
3397 check_client_version(ctx
.obj
, ctx
.command
.name
)
3398 resp
= ctx
.obj
.role
.get(name
)
3399 except ClientException
as e
:
3403 table
= PrettyTable(['key', 'attribute'])
3404 for k
, v
in resp
.items():
3405 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3410 @cli.command(name
='package-create',
3411 short_help
='Create a package descriptor')
3412 @click.argument('package-type')
3413 @click.argument('package-name')
3414 @click.option('--base-directory',
3416 help=('(NS/VNF/NST) Set the location for package creation. Default: "."'))
3417 @click.option('--image',
3418 default
="image-name",
3419 help='(VNF) Set the name of the vdu image. Default "image-name"')
3420 @click.option('--vdus',
3422 help='(VNF) Set the number of vdus in a VNF. Default 1')
3423 @click.option('--vcpu',
3425 help='(VNF) Set the number of virtual CPUs in a vdu. Default 1')
3426 @click.option('--memory',
3428 help='(VNF) Set the memory size (MB) of the vdu. Default 1024')
3429 @click.option('--storage',
3431 help='(VNF) Set the disk size (GB) of the vdu. Default 10')
3432 @click.option('--interfaces',
3434 help='(VNF) Set the number of additional interfaces apart from the management interface. Default 0')
3435 @click.option('--vendor',
3437 help='(NS/VNF) Set the descriptor vendor. Default "OSM"')
3438 @click.option('--override',
3441 help='(NS/VNF/NST) Flag for overriding the package if exists.')
3442 @click.option('--detailed',
3445 help='(NS/VNF/NST) Flag for generating descriptor .yaml with all possible commented options')
3446 @click.option('--netslice-subnets',
3448 help='(NST) Number of netslice subnets. Default 1')
3449 @click.option('--netslice-vlds',
3451 help='(NST) Number of netslice vlds. Default 1')
3453 def package_create(ctx
,
3469 Creates an OSM NS, VNF, NST package
3472 PACKAGE_TYPE: Package to be created: NS, VNF or NST.
3473 PACKAGE_NAME: Name of the package to create the folder with the content.
3477 check_client_version(ctx
.obj
, ctx
.command
.name
)
3478 print("Creating the {} structure: {}/{}".format(package_type
.upper(), base_directory
, package_name
))
3479 resp
= ctx
.obj
.package_tool
.create(package_type
,
3488 interfaces
=interfaces
,
3491 netslice_subnets
=netslice_subnets
,
3492 netslice_vlds
=netslice_vlds
)
3494 except ClientException
as inst
:
3495 print("ERROR: {}".format(inst
))
3498 @cli.command(name
='package-validate',
3499 short_help
='Validate a package descriptor')
3500 @click.argument('base-directory',
3504 def package_validate(ctx
,
3507 Validate descriptors given a base directory.
3510 BASE_DIRECTORY: Stub folder for NS, VNF or NST package.
3513 check_client_version(ctx
.obj
, ctx
.command
.name
)
3514 results
= ctx
.obj
.package_tool
.validate(base_directory
)
3515 table
= PrettyTable()
3516 table
.field_names
= ["TYPE", "PATH", "VALID", "ERROR"]
3517 # Print the dictionary generated by the validation function
3518 for result
in results
:
3519 table
.add_row([result
["type"], result
["path"], result
["valid"], result
["error"]])
3520 table
.sortby
= "VALID"
3521 table
.align
["PATH"] = "l"
3522 table
.align
["TYPE"] = "l"
3523 table
.align
["ERROR"] = "l"
3525 except ClientException
as inst
:
3526 print("ERROR: {}".format(inst
))
3529 @cli.command(name
='package-build',
3530 short_help
='Build the tar.gz of the package')
3531 @click.argument('package-folder')
3532 @click.option('--skip-validation',
3535 help='skip package validation')
3537 def package_build(ctx
,
3541 Build the package NS, VNF given the package_folder.
3544 PACKAGE_FOLDER: Folder of the NS, VNF or NST to be packaged
3547 check_client_version(ctx
.obj
, ctx
.command
.name
)
3548 results
= ctx
.obj
.package_tool
.build(package_folder
, skip_validation
)
3550 except ClientException
as inst
:
3551 print("ERROR: {}".format(inst
))
3555 if __name__
== '__main__':
3558 except pycurl
.error
as e
:
3560 print('Maybe "--hostname" option or OSM_HOSTNAME' +
3561 'environment variable needs to be specified')