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
33 def wrap_text(text
, width
):
34 wrapper
= textwrap
.TextWrapper(width
=width
)
35 lines
= text
.splitlines()
36 return "\n".join(map(wrapper
.fill
, lines
))
39 def trunc_text(text
, length
):
40 if len(text
) > length
:
41 return text
[:(length
- 3)] + '...'
46 def check_client_version(obj
, what
, version
='sol005'):
48 Checks the version of the client object and raises error if it not the expected.
50 :param obj: the client object
51 :what: the function or command under evaluation (used when an error is raised)
53 :raises ClientError: if the specified version does not match the client version
55 fullclassname
= obj
.__module
__ + "." + obj
.__class
__.__name
__
56 message
= 'The following commands or options are only supported with the option "--sol005": {}'.format(what
)
58 message
= 'The following commands or options are not supported when using option "--sol005": {}'.format(what
)
59 if fullclassname
!= 'osmclient.{}.client.Client'.format(version
):
60 raise ClientException(message
)
64 CONTEXT_SETTINGS
= dict(help_option_names
=['-h', '--help'], max_content_width
=160)
66 @click.group(context_settings
=CONTEXT_SETTINGS
)
67 @click.option('--hostname',
69 envvar
='OSM_HOSTNAME',
70 help='hostname of server. ' +
71 'Also can set OSM_HOSTNAME in environment')
72 #@click.option('--sol005/--no-sol005',
74 # envvar='OSM_SOL005',
75 # help='Use ETSI NFV SOL005 API (default) or the previous SO API. ' +
76 # 'Also can set OSM_SOL005 in environment')
77 @click.option('--user',
80 help='user (defaults to admin). ' +
81 'Also can set OSM_USER in environment')
82 @click.option('--password',
84 envvar
='OSM_PASSWORD',
85 help='password (defaults to admin). ' +
86 'Also can set OSM_PASSWORD in environment')
87 @click.option('--project',
90 help='project (defaults to admin). ' +
91 'Also can set OSM_PROJECT in environment')
92 #@click.option('--so-port',
94 # envvar='OSM_SO_PORT',
95 # help='hostname of server. ' +
96 # 'Also can set OSM_SO_PORT in environment')
97 #@click.option('--so-project',
99 # envvar='OSM_SO_PROJECT',
100 # help='Project Name in SO. ' +
101 # 'Also can set OSM_SO_PROJECT in environment')
102 #@click.option('--ro-hostname',
104 # envvar='OSM_RO_HOSTNAME',
105 # help='hostname of RO server. ' +
106 # 'Also can set OSM_RO_HOSTNAME in environment')
107 #@click.option('--ro-port',
109 # envvar='OSM_RO_PORT',
110 # help='hostname of RO server. ' +
111 # 'Also can set OSM_RO_PORT in environment')
113 def cli(ctx
, hostname
, user
, password
, project
):
116 "either hostname option or OSM_HOSTNAME " +
117 "environment variable needs to be specified"))
120 # if so_port is not None:
121 # kwargs['so_port']=so_port
122 # if so_project is not None:
123 # kwargs['so_project']=so_project
124 # if ro_hostname is not None:
125 # kwargs['ro_host']=ro_hostname
126 # if ro_port is not None:
127 # kwargs['ro_port']=ro_port
128 sol005
= os
.getenv('OSM_SOL005', True)
131 if password
is not None:
132 kwargs
['password']=password
133 if project
is not None:
134 kwargs
['project']=project
136 ctx
.obj
= client
.Client(host
=hostname
, sol005
=sol005
, **kwargs
)
143 @cli.command(name
='ns-list', short_help
='list all NS instances')
144 @click.option('--filter', default
=None,
145 help='restricts the list to the NS instances matching the filter.')
147 def ns_list(ctx
, filter):
148 """list all NS instances
152 --filter filterExpr Restricts the list to the NS instances matching the filter
155 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
156 concatenated using the "&" character:
159 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
160 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
161 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
163 value := scalar value
167 * zero or more occurrences
168 ? zero or one occurrence
169 [] grouping of expressions to be used with ? and *
170 "" quotation marks for marking string constants
174 "AttrName" is the name of one attribute in the data type that defines the representation
175 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
176 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
177 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
178 entries, it means that the operator "op" is applied to the attribute addressed by the last
179 <attrName> entry included in the concatenation. All simple filter expressions are combined
180 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
181 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
182 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
183 prefix". If an attribute referenced in an expression is an array, an object that contains a
184 corresponding array shall be considered to match the expression if any of the elements in the
185 array matches all expressions that have the same attribute prefix.
189 --filter admin-status=ENABLED
190 --filter nsd-ref=<NSD_NAME>
191 --filter nsd.vendor=<VENDOR>
192 --filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME>
193 --filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME>
196 check_client_version(ctx
.obj
, '--filter')
197 resp
= ctx
.obj
.ns
.list(filter)
199 resp
= ctx
.obj
.ns
.list()
203 'operational status',
207 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
208 if fullclassname
== 'osmclient.sol005.client.Client':
210 nsr_name
= nsr
['name']
213 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
214 nsr
= nsopdata
['nsr:nsr']
215 nsr_name
= nsr
['name-ref']
216 nsr_id
= nsr
['ns-instance-config-ref']
217 opstatus
= nsr
['operational-status'] if 'operational-status' in nsr
else 'Not found'
218 configstatus
= nsr
['config-status'] if 'config-status' in nsr
else 'Not found'
219 detailed_status
= nsr
['detailed-status'] if 'detailed-status' in nsr
else 'Not found'
220 detailed_status
= wrap_text(text
=detailed_status
,width
=50)
221 if configstatus
== "config_not_needed":
222 configstatus
= "configured (no charms)"
234 def nsd_list(ctx
, filter):
236 check_client_version(ctx
.obj
, '--filter')
237 resp
= ctx
.obj
.nsd
.list(filter)
239 resp
= ctx
.obj
.nsd
.list()
240 # print(yaml.safe_dump(resp))
241 table
= PrettyTable(['nsd name', 'id'])
242 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
243 if fullclassname
== 'osmclient.sol005.client.Client':
245 name
= ns
['name'] if 'name' in ns
else '-'
246 table
.add_row([name
, ns
['_id']])
249 table
.add_row([ns
['name'], ns
['id']])
254 @cli.command(name
='nsd-list', short_help
='list all NS packages')
255 @click.option('--filter', default
=None,
256 help='restricts the list to the NSD/NSpkg matching the filter')
258 def nsd_list1(ctx
, filter):
259 """list all NSD/NS pkg in the system"""
260 nsd_list(ctx
, filter)
263 @cli.command(name
='nspkg-list', short_help
='list all NS packages')
264 @click.option('--filter', default
=None,
265 help='restricts the list to the NSD/NSpkg matching the filter')
267 def nsd_list2(ctx
, filter):
268 """list all NS packages"""
269 nsd_list(ctx
, filter)
272 def vnfd_list(ctx
, nf_type
, filter):
274 check_client_version(ctx
.obj
, '--nf_type')
276 check_client_version(ctx
.obj
, '--filter')
279 nf_filter
= "_admin.type=vnfd"
280 elif nf_type
== "pnf":
281 nf_filter
= "_admin.type=pnfd"
282 elif nf_type
== "hnf":
283 nf_filter
= "_admin.type=hnfd"
285 raise ClientException('wrong value for "--nf_type" option, allowed values: vnf, pnf, hnf')
287 filter = '{}&{}'.format(nf_filter
, filter)
291 resp
= ctx
.obj
.vnfd
.list(filter)
293 resp
= ctx
.obj
.vnfd
.list()
294 # print(yaml.safe_dump(resp))
295 table
= PrettyTable(['nfpkg name', 'id'])
296 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
297 if fullclassname
== 'osmclient.sol005.client.Client':
299 name
= vnfd
['name'] if 'name' in vnfd
else '-'
300 table
.add_row([name
, vnfd
['_id']])
303 table
.add_row([vnfd
['name'], vnfd
['id']])
308 @cli.command(name
='vnfd-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
309 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
310 @click.option('--filter', default
=None,
311 help='restricts the list to the NF pkg matching the filter')
313 def vnfd_list1(ctx
, nf_type
, filter):
314 """list all xNF packages (VNF, HNF, PNF)"""
315 vnfd_list(ctx
, nf_type
, filter)
318 @cli.command(name
='vnfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
319 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
320 @click.option('--filter', default
=None,
321 help='restricts the list to the NFpkg matching the filter')
323 def vnfd_list2(ctx
, nf_type
, filter):
324 """list all xNF packages (VNF, HNF, PNF)"""
325 vnfd_list(ctx
, nf_type
, filter)
328 @cli.command(name
='nfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
329 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
330 @click.option('--filter', default
=None,
331 help='restricts the list to the NFpkg matching the filter')
333 def nfpkg_list(ctx
, nf_type
, filter):
334 """list all xNF packages (VNF, HNF, PNF)"""
336 check_client_version(ctx
.obj
, ctx
.command
.name
)
337 vnfd_list(ctx
, nf_type
, filter)
338 except ClientException
as e
:
343 def vnf_list(ctx
, ns
, filter):
347 check_client_version(ctx
.obj
, '--ns')
349 check_client_version(ctx
.obj
, '--filter')
350 resp
= ctx
.obj
.vnf
.list(ns
, filter)
352 resp
= ctx
.obj
.vnf
.list()
353 except ClientException
as e
:
356 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
357 if fullclassname
== 'osmclient.sol005.client.Client':
367 name
= vnfr
['name'] if 'name' in vnfr
else '-'
372 vnfr
['member-vnf-index-ref'],
374 vnfr
['vim-account-id'],
380 'operational status',
383 if 'mgmt-interface' not in vnfr
:
384 vnfr
['mgmt-interface'] = {}
385 vnfr
['mgmt-interface']['ip-address'] = None
389 vnfr
['operational-status'],
390 vnfr
['config-status']])
395 @cli.command(name
='vnf-list', short_help
='list all NF instances')
396 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
397 @click.option('--filter', default
=None,
398 help='restricts the list to the NF instances matching the filter.')
400 def vnf_list1(ctx
, ns
, filter):
401 """list all NF instances"""
402 vnf_list(ctx
, ns
, filter)
405 @cli.command(name
='nf-list', short_help
='list all NF instances')
406 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
407 @click.option('--filter', default
=None,
408 help='restricts the list to the NF instances matching the filter.')
410 def nf_list(ctx
, ns
, filter):
411 """list all NF instances
415 --ns TEXT NS instance id or name to restrict the VNF list
416 --filter filterExpr Restricts the list to the VNF instances matching the filter
419 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
420 concatenated using the "&" character:
423 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
424 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
425 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
427 value := scalar value
431 * zero or more occurrences
432 ? zero or one occurrence
433 [] grouping of expressions to be used with ? and *
434 "" quotation marks for marking string constants
438 "AttrName" is the name of one attribute in the data type that defines the representation
439 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
440 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
441 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
442 entries, it means that the operator "op" is applied to the attribute addressed by the last
443 <attrName> entry included in the concatenation. All simple filter expressions are combined
444 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
445 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
446 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
447 prefix". If an attribute referenced in an expression is an array, an object that contains a
448 corresponding array shall be considered to match the expression if any of the elements in the
449 array matches all expressions that have the same attribute prefix.
453 --filter vim-account-id=<VIM_ACCOUNT_ID>
454 --filter vnfd-ref=<VNFD_NAME>
455 --filter vdur.ip-address=<IP_ADDRESS>
456 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
458 vnf_list(ctx
, ns
, filter)
461 @cli.command(name
='ns-op-list', short_help
='shows the history of operations over a NS instance')
462 @click.argument('name')
464 def ns_op_list(ctx
, name
):
465 """shows the history of operations over a NS instance
467 NAME: name or ID of the NS instance
470 check_client_version(ctx
.obj
, ctx
.command
.name
)
471 resp
= ctx
.obj
.ns
.list_op(name
)
472 except ClientException
as e
:
476 table
= PrettyTable(['id', 'operation', 'action_name', 'status'])
477 #print(yaml.safe_dump(resp))
480 if op
['lcmOperationType']=='action':
481 action_name
= op
['operationParams']['primitive']
482 table
.add_row([op
['id'], op
['lcmOperationType'], action_name
,
483 op
['operationState']])
488 def nsi_list(ctx
, filter):
489 """list all Network Slice Instances"""
491 check_client_version(ctx
.obj
, ctx
.command
.name
)
492 resp
= ctx
.obj
.nsi
.list(filter)
493 except ClientException
as e
:
497 ['netslice instance name',
499 'operational status',
503 nsi_name
= nsi
['name']
505 opstatus
= nsi
['operational-status'] if 'operational-status' in nsi
else 'Not found'
506 configstatus
= nsi
['config-status'] if 'config-status' in nsi
else 'Not found'
507 detailed_status
= nsi
['detailed-status'] if 'detailed-status' in nsi
else 'Not found'
508 if configstatus
== "config_not_needed":
509 configstatus
= "configured (no charms)"
520 @cli.command(name
='nsi-list', short_help
='list all Network Slice Instances (NSI)')
521 @click.option('--filter', default
=None,
522 help='restricts the list to the Network Slice Instances matching the filter')
524 def nsi_list1(ctx
, filter):
525 """list all Network Slice Instances (NSI)"""
526 nsi_list(ctx
, filter)
529 @cli.command(name
='netslice-instance-list', short_help
='list all Network Slice Instances (NSI)')
530 @click.option('--filter', default
=None,
531 help='restricts the list to the Network Slice Instances matching the filter')
533 def nsi_list2(ctx
, filter):
534 """list all Network Slice Instances (NSI)"""
535 nsi_list(ctx
, filter)
538 def nst_list(ctx
, filter):
540 check_client_version(ctx
.obj
, ctx
.command
.name
)
541 resp
= ctx
.obj
.nst
.list(filter)
542 except ClientException
as e
:
545 # print(yaml.safe_dump(resp))
546 table
= PrettyTable(['nst name', 'id'])
548 name
= nst
['name'] if 'name' in nst
else '-'
549 table
.add_row([name
, nst
['_id']])
554 @cli.command(name
='nst-list', short_help
='list all Network Slice Templates (NST)')
555 @click.option('--filter', default
=None,
556 help='restricts the list to the NST matching the filter')
558 def nst_list1(ctx
, filter):
559 """list all Network Slice Templates (NST) in the system"""
560 nst_list(ctx
, filter)
563 @cli.command(name
='netslice-template-list', short_help
='list all Network Slice Templates (NST)')
564 @click.option('--filter', default
=None,
565 help='restricts the list to the NST matching the filter')
567 def nst_list2(ctx
, filter):
568 """list all Network Slice Templates (NST) in the system"""
569 nst_list(ctx
, filter)
572 def nsi_op_list(ctx
, name
):
574 check_client_version(ctx
.obj
, ctx
.command
.name
)
575 resp
= ctx
.obj
.nsi
.list_op(name
)
576 except ClientException
as e
:
579 table
= PrettyTable(['id', 'operation', 'status'])
581 table
.add_row([op
['id'], op
['lcmOperationType'],
582 op
['operationState']])
587 @cli.command(name
='nsi-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
588 @click.argument('name')
590 def nsi_op_list1(ctx
, name
):
591 """shows the history of operations over a Network Slice Instance (NSI)
593 NAME: name or ID of the Network Slice Instance
595 nsi_op_list(ctx
, name
)
598 @cli.command(name
='netslice-instance-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
599 @click.argument('name')
601 def nsi_op_list2(ctx
, name
):
602 """shows the history of operations over a Network Slice Instance (NSI)
604 NAME: name or ID of the Network Slice Instance
606 nsi_op_list(ctx
, name
)
609 @cli.command(name
='pdu-list', short_help
='list all Physical Deployment Units (PDU)')
610 @click.option('--filter', default
=None,
611 help='restricts the list to the Physical Deployment Units matching the filter')
613 def pdu_list(ctx
, filter):
614 """list all Physical Deployment Units (PDU)"""
616 check_client_version(ctx
.obj
, ctx
.command
.name
)
617 resp
= ctx
.obj
.pdu
.list(filter)
618 except ClientException
as e
:
627 pdu_name
= pdu
['name']
629 pdu_type
= pdu
['type']
630 pdu_ipaddress
= "None"
631 for iface
in pdu
['interfaces']:
633 pdu_ipaddress
= iface
['ip-address']
648 def nsd_show(ctx
, name
, literal
):
650 resp
= ctx
.obj
.nsd
.get(name
)
651 # resp = ctx.obj.nsd.get_individual(name)
652 except ClientException
as e
:
657 print(yaml
.safe_dump(resp
))
660 table
= PrettyTable(['field', 'value'])
661 for k
, v
in list(resp
.items()):
662 table
.add_row([k
, json
.dumps(v
, indent
=2)])
667 @cli.command(name
='nsd-show', short_help
='shows the content of a NSD')
668 @click.option('--literal', is_flag
=True,
669 help='print literally, no pretty table')
670 @click.argument('name')
672 def nsd_show1(ctx
, name
, literal
):
673 """shows the content of a NSD
675 NAME: name or ID of the NSD/NSpkg
677 nsd_show(ctx
, name
, literal
)
680 @cli.command(name
='nspkg-show', short_help
='shows the content of a NSD')
681 @click.option('--literal', is_flag
=True,
682 help='print literally, no pretty table')
683 @click.argument('name')
685 def nsd_show2(ctx
, name
, literal
):
686 """shows the content of a NSD
688 NAME: name or ID of the NSD/NSpkg
690 nsd_show(ctx
, name
, literal
)
693 def vnfd_show(ctx
, name
, literal
):
695 resp
= ctx
.obj
.vnfd
.get(name
)
696 # resp = ctx.obj.vnfd.get_individual(name)
697 except ClientException
as e
:
702 print(yaml
.safe_dump(resp
))
705 table
= PrettyTable(['field', 'value'])
706 for k
, v
in list(resp
.items()):
707 table
.add_row([k
, json
.dumps(v
, indent
=2)])
712 @cli.command(name
='vnfd-show', short_help
='shows the content of a VNFD')
713 @click.option('--literal', is_flag
=True,
714 help='print literally, no pretty table')
715 @click.argument('name')
717 def vnfd_show1(ctx
, name
, literal
):
718 """shows the content of a VNFD
720 NAME: name or ID of the VNFD/VNFpkg
722 vnfd_show(ctx
, name
, literal
)
725 @cli.command(name
='vnfpkg-show', short_help
='shows the content of a VNFD')
726 @click.option('--literal', is_flag
=True,
727 help='print literally, no pretty table')
728 @click.argument('name')
730 def vnfd_show2(ctx
, name
, literal
):
731 """shows the content of a VNFD
733 NAME: name or ID of the VNFD/VNFpkg
735 vnfd_show(ctx
, name
, literal
)
738 @cli.command(name
='nfpkg-show', short_help
='shows the content of a NF Descriptor')
739 @click.option('--literal', is_flag
=True,
740 help='print literally, no pretty table')
741 @click.argument('name')
743 def nfpkg_show(ctx
, name
, literal
):
744 """shows the content of a NF Descriptor
746 NAME: name or ID of the NFpkg
748 vnfd_show(ctx
, name
, literal
)
751 @cli.command(name
='ns-show', short_help
='shows the info of a NS instance')
752 @click.argument('name')
753 @click.option('--literal', is_flag
=True,
754 help='print literally, no pretty table')
755 @click.option('--filter', default
=None)
757 def ns_show(ctx
, name
, literal
, filter):
758 """shows the info of a NS instance
760 NAME: name or ID of the NS instance
763 ns
= ctx
.obj
.ns
.get(name
)
764 except ClientException
as e
:
769 print(yaml
.safe_dump(ns
))
772 table
= PrettyTable(['field', 'value'])
774 for k
, v
in list(ns
.items()):
775 if filter is None or filter in k
:
776 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
778 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
779 if fullclassname
!= 'osmclient.sol005.client.Client':
780 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
781 nsr_optdata
= nsopdata
['nsr:nsr']
782 for k
, v
in list(nsr_optdata
.items()):
783 if filter is None or filter in k
:
784 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2),width
=100)])
789 @cli.command(name
='vnf-show', short_help
='shows the info of a VNF instance')
790 @click.argument('name')
791 @click.option('--literal', is_flag
=True,
792 help='print literally, no pretty table')
793 @click.option('--filter', default
=None, help='restricts the information to the fields in the filter')
794 @click.option('--kdu', default
=None, help='KDU name (whose status will be shown)')
796 def vnf_show(ctx
, name
, literal
, filter, kdu
):
797 """shows the info of a VNF instance
799 NAME: name or ID of the VNF instance
803 raise ClientException('"--literal" option is incompatible with "--kdu" option')
805 raise ClientException('"--filter" option is incompatible with "--kdu" option')
808 check_client_version(ctx
.obj
, ctx
.command
.name
)
809 resp
= ctx
.obj
.vnf
.get(name
)
812 ns_id
= resp
['nsr-id-ref']
814 op_data
['member_vnf_index'] = resp
['member-vnf-index-ref']
815 op_data
['kdu_name'] = kdu
816 op_data
['primitive'] = 'status'
817 op_data
['primitive_params'] = {}
818 op_id
= ctx
.obj
.ns
.exec_op(ns_id
, op_name
='action', op_data
=op_data
, wait
=False)
821 op_info
= ctx
.obj
.ns
.get_op(op_id
)
822 if op_info
['operationState'] == 'COMPLETED':
823 print(op_info
['detailed-status'])
827 print ("Could not determine KDU status")
830 print(yaml
.safe_dump(resp
))
833 table
= PrettyTable(['field', 'value'])
835 for k
, v
in list(resp
.items()):
836 if filter is None or filter in k
:
837 table
.add_row([k
, wrap_text(text
=json
.dumps(v
,indent
=2),width
=100)])
840 except ClientException
as e
:
845 #@cli.command(name='vnf-monitoring-show')
846 #@click.argument('vnf_name')
848 #def vnf_monitoring_show(ctx, vnf_name):
850 # check_client_version(ctx.obj, ctx.command.name, 'v1')
851 # resp = ctx.obj.vnf.get_monitoring(vnf_name)
852 # except ClientException as e:
856 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
857 # if resp is not None:
858 # for monitor in resp:
862 # monitor['value-integer'],
868 #@cli.command(name='ns-monitoring-show')
869 #@click.argument('ns_name')
871 #def ns_monitoring_show(ctx, ns_name):
873 # check_client_version(ctx.obj, ctx.command.name, 'v1')
874 # resp = ctx.obj.ns.get_monitoring(ns_name)
875 # except ClientException as e:
879 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
880 # for key, val in list(resp.items()):
881 # for monitor in val:
885 # monitor['value-integer'],
891 @cli.command(name
='ns-op-show', short_help
='shows the info of a NS operation')
892 @click.argument('id')
893 @click.option('--filter', default
=None)
894 @click.option('--literal', is_flag
=True,
895 help='print literally, no pretty table')
897 def ns_op_show(ctx
, id, filter, literal
):
898 """shows the detailed info of a NS operation
900 ID: operation identifier
903 check_client_version(ctx
.obj
, ctx
.command
.name
)
904 op_info
= ctx
.obj
.ns
.get_op(id)
905 except ClientException
as e
:
910 print(yaml
.safe_dump(op_info
))
913 table
= PrettyTable(['field', 'value'])
914 for k
, v
in list(op_info
.items()):
915 if filter is None or filter in k
:
916 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
921 def nst_show(ctx
, name
, literal
):
923 check_client_version(ctx
.obj
, ctx
.command
.name
)
924 resp
= ctx
.obj
.nst
.get(name
)
925 #resp = ctx.obj.nst.get_individual(name)
926 except ClientException
as e
:
931 print(yaml
.safe_dump(resp
))
934 table
= PrettyTable(['field', 'value'])
935 for k
, v
in list(resp
.items()):
936 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
941 @cli.command(name
='nst-show', short_help
='shows the content of a Network Slice Template (NST)')
942 @click.option('--literal', is_flag
=True,
943 help='print literally, no pretty table')
944 @click.argument('name')
946 def nst_show1(ctx
, name
, literal
):
947 """shows the content of a Network Slice Template (NST)
949 NAME: name or ID of the NST
951 nst_show(ctx
, name
, literal
)
954 @cli.command(name
='netslice-template-show', short_help
='shows the content of a Network Slice Template (NST)')
955 @click.option('--literal', is_flag
=True,
956 help='print literally, no pretty table')
957 @click.argument('name')
959 def nst_show2(ctx
, name
, literal
):
960 """shows the content of a Network Slice Template (NST)
962 NAME: name or ID of the NST
964 nst_show(ctx
, name
, literal
)
967 def nsi_show(ctx
, name
, literal
, filter):
969 check_client_version(ctx
.obj
, ctx
.command
.name
)
970 nsi
= ctx
.obj
.nsi
.get(name
)
971 except ClientException
as e
:
976 print(yaml
.safe_dump(nsi
))
979 table
= PrettyTable(['field', 'value'])
981 for k
, v
in list(nsi
.items()):
982 if filter is None or filter in k
:
983 table
.add_row([k
, json
.dumps(v
, indent
=2)])
989 @cli.command(name
='nsi-show', short_help
='shows the content of a Network Slice Instance (NSI)')
990 @click.argument('name')
991 @click.option('--literal', is_flag
=True,
992 help='print literally, no pretty table')
993 @click.option('--filter', default
=None)
995 def nsi_show1(ctx
, name
, literal
, filter):
996 """shows the content of a Network Slice Instance (NSI)
998 NAME: name or ID of the Network Slice Instance
1000 nsi_show(ctx
, name
, literal
, filter)
1003 @cli.command(name
='netslice-instance-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1004 @click.argument('name')
1005 @click.option('--literal', is_flag
=True,
1006 help='print literally, no pretty table')
1007 @click.option('--filter', default
=None)
1009 def nsi_show2(ctx
, name
, literal
, filter):
1010 """shows the content of a Network Slice Instance (NSI)
1012 NAME: name or ID of the Network Slice Instance
1014 nsi_show(ctx
, name
, literal
, filter)
1017 def nsi_op_show(ctx
, id, filter):
1019 check_client_version(ctx
.obj
, ctx
.command
.name
)
1020 op_info
= ctx
.obj
.nsi
.get_op(id)
1021 except ClientException
as e
:
1025 table
= PrettyTable(['field', 'value'])
1026 for k
, v
in list(op_info
.items()):
1027 if filter is None or filter in k
:
1028 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1033 @cli.command(name
='nsi-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1034 @click.argument('id')
1035 @click.option('--filter', default
=None)
1037 def nsi_op_show1(ctx
, id, filter):
1038 """shows the info of an operation over a Network Slice Instance(NSI)
1040 ID: operation identifier
1042 nsi_op_show(ctx
, id, filter)
1045 @cli.command(name
='netslice-instance-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1046 @click.argument('id')
1047 @click.option('--filter', default
=None)
1049 def nsi_op_show2(ctx
, id, filter):
1050 """shows the info of an operation over a Network Slice Instance(NSI)
1052 ID: operation identifier
1054 nsi_op_show(ctx
, id, filter)
1057 @cli.command(name
='pdu-show', short_help
='shows the content of a Physical Deployment Unit (PDU)')
1058 @click.argument('name')
1059 @click.option('--literal', is_flag
=True,
1060 help='print literally, no pretty table')
1061 @click.option('--filter', default
=None)
1063 def pdu_show(ctx
, name
, literal
, filter):
1064 """shows the content of a Physical Deployment Unit (PDU)
1066 NAME: name or ID of the PDU
1069 check_client_version(ctx
.obj
, ctx
.command
.name
)
1070 pdu
= ctx
.obj
.pdu
.get(name
)
1071 except ClientException
as e
:
1076 print(yaml
.safe_dump(pdu
))
1079 table
= PrettyTable(['field', 'value'])
1081 for k
, v
in list(pdu
.items()):
1082 if filter is None or filter in k
:
1083 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1089 ####################
1091 ####################
1093 def nsd_create(ctx
, filename
, overwrite
):
1095 check_client_version(ctx
.obj
, ctx
.command
.name
)
1096 ctx
.obj
.nsd
.create(filename
, overwrite
)
1097 except ClientException
as e
:
1102 @cli.command(name
='nsd-create', short_help
='creates a new NSD/NSpkg')
1103 @click.argument('filename')
1104 @click.option('--overwrite', 'overwrite', default
=None,
1105 help='overwrite deprecated, use override')
1106 @click.option('--override', 'overwrite', default
=None,
1107 help='overrides fields in descriptor, format: '
1108 '"key1.key2...=value[;key3...=value;...]"')
1110 def nsd_create1(ctx
, filename
, overwrite
):
1111 """creates a new NSD/NSpkg
1113 FILENAME: NSD yaml file or NSpkg tar.gz file
1115 nsd_create(ctx
, filename
, overwrite
)
1118 @cli.command(name
='nspkg-create', short_help
='creates a new NSD/NSpkg')
1119 @click.argument('filename')
1120 @click.option('--overwrite', 'overwrite', default
=None,
1121 help='overwrite deprecated, use override')
1122 @click.option('--override', 'overwrite', default
=None,
1123 help='overrides fields in descriptor, format: '
1124 '"key1.key2...=value[;key3...=value;...]"')
1126 def nsd_create2(ctx
, filename
, overwrite
):
1127 """creates a new NSD/NSpkg
1129 FILENAME: NSD yaml file or NSpkg tar.gz file
1131 nsd_create(ctx
, filename
, overwrite
)
1134 def vnfd_create(ctx
, filename
, overwrite
):
1136 check_client_version(ctx
.obj
, ctx
.command
.name
)
1137 ctx
.obj
.vnfd
.create(filename
, overwrite
)
1138 except ClientException
as e
:
1143 @cli.command(name
='vnfd-create', short_help
='creates a new VNFD/VNFpkg')
1144 @click.argument('filename')
1145 @click.option('--overwrite', 'overwrite', default
=None,
1146 help='overwrite deprecated, use override')
1147 @click.option('--override', 'overwrite', default
=None,
1148 help='overrides fields in descriptor, format: '
1149 '"key1.key2...=value[;key3...=value;...]"')
1151 def vnfd_create1(ctx
, filename
, overwrite
):
1152 """creates a new VNFD/VNFpkg
1154 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1156 vnfd_create(ctx
, filename
, overwrite
)
1159 @cli.command(name
='vnfpkg-create', short_help
='creates a new VNFD/VNFpkg')
1160 @click.argument('filename')
1161 @click.option('--overwrite', 'overwrite', default
=None,
1162 help='overwrite deprecated, use override')
1163 @click.option('--override', 'overwrite', default
=None,
1164 help='overrides fields in descriptor, format: '
1165 '"key1.key2...=value[;key3...=value;...]"')
1167 def vnfd_create2(ctx
, filename
, overwrite
):
1168 """creates a new VNFD/VNFpkg
1170 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1172 vnfd_create(ctx
, filename
, overwrite
)
1175 @cli.command(name
='nfpkg-create', short_help
='creates a new NFpkg')
1176 @click.argument('filename')
1177 @click.option('--overwrite', 'overwrite', default
=None,
1178 help='overwrite deprecated, use override')
1179 @click.option('--override', 'overwrite', default
=None,
1180 help='overrides fields in descriptor, format: '
1181 '"key1.key2...=value[;key3...=value;...]"')
1183 def nfpkg_create(ctx
, filename
, overwrite
):
1184 """creates a new NFpkg
1186 FILENAME: NF Descriptor yaml file or NFpkg tar.gz file
1188 vnfd_create(ctx
, filename
, overwrite
)
1191 @cli.command(name
='ns-create', short_help
='creates a new Network Service instance')
1192 @click.option('--ns_name',
1193 prompt
=True, help='name of the NS instance')
1194 @click.option('--nsd_name',
1195 prompt
=True, help='name of the NS descriptor')
1196 @click.option('--vim_account',
1197 prompt
=True, help='default VIM account id or name for the deployment')
1198 @click.option('--admin_status',
1200 help='administration status')
1201 @click.option('--ssh_keys',
1203 help='comma separated list of public key files to inject to vnfs')
1204 @click.option('--config',
1206 help='ns specific yaml configuration')
1207 @click.option('--config_file',
1209 help='ns specific yaml configuration file')
1210 @click.option('--wait',
1214 help='do not return the control immediately, but keep it \
1215 until the operation is completed, or timeout')
1226 """creates a new NS instance"""
1229 check_client_version(ctx
.obj
, '--config_file')
1231 raise ClientException('"--config" option is incompatible with "--config_file" option')
1232 with
open(config_file
, 'r') as cf
:
1239 account
=vim_account
,
1241 except ClientException
as e
:
1246 def nst_create(ctx
, filename
, overwrite
):
1248 check_client_version(ctx
.obj
, ctx
.command
.name
)
1249 ctx
.obj
.nst
.create(filename
, overwrite
)
1250 except ClientException
as e
:
1255 @cli.command(name
='nst-create', short_help
='creates a new Network Slice Template (NST)')
1256 @click.argument('filename')
1257 @click.option('--overwrite', 'overwrite', default
=None,
1258 help='overwrites deprecated use override')
1259 @click.option('--override', 'overwrite' ,default
=None,
1260 help='overrides fields in descriptor, format: '
1261 '"key1.key2...=value[;key3...=value;...]"')
1263 def nst_create1(ctx
, filename
, overwrite
):
1264 """creates a new Network Slice Template (NST)
1266 FILENAME: NST yaml file or NSTpkg tar.gz file
1268 nst_create(ctx
, filename
, overwrite
)
1271 @cli.command(name
='netslice-template-create', short_help
='creates a new Network Slice Template (NST)')
1272 @click.argument('filename')
1273 @click.option('--overwrite', 'overwrite', default
=None,
1274 help='overwrites deprecated use override')
1275 @click.option('--override', 'overwrite', default
=None,
1276 help='overrides fields in descriptor, format: '
1277 '"key1.key2...=value[;key3...=value;...]"')
1279 def nst_create2(ctx
, filename
, overwrite
):
1280 """creates a new Network Slice Template (NST)
1282 FILENAME: NST yaml file or NSTpkg tar.gz file
1284 nst_create(ctx
, filename
, overwrite
)
1287 def nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1288 """creates a new Network Slice Instance (NSI)"""
1290 check_client_version(ctx
.obj
, ctx
.command
.name
)
1293 raise ClientException('"--config" option is incompatible with "--config_file" option')
1294 with
open(config_file
, 'r') as cf
:
1296 ctx
.obj
.nsi
.create(nst_name
, nsi_name
, config
=config
, ssh_keys
=ssh_keys
,
1297 account
=vim_account
, wait
=wait
)
1298 except ClientException
as e
:
1303 @cli.command(name
='nsi-create', short_help
='creates a new Network Slice Instance')
1304 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1305 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1306 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1307 @click.option('--ssh_keys', default
=None,
1308 help='comma separated list of keys to inject to vnfs')
1309 @click.option('--config', default
=None,
1310 help='Netslice specific yaml configuration:\n'
1311 'netslice_subnet: [\n'
1312 'id: TEXT, vim_account: TEXT,\n'
1313 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1314 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]\n'
1315 'additionalParamsForNsi: {param: value, ...}\n'
1316 'additionalParamsForsubnet: [{id: SUBNET_ID, additionalParamsForNs: {}, additionalParamsForVnf: {}}]\n'
1318 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1320 @click.option('--config_file',
1322 help='nsi specific yaml configuration file')
1323 @click.option('--wait',
1327 help='do not return the control immediately, but keep it \
1328 until the operation is completed, or timeout')
1330 def nsi_create1(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1331 """creates a new Network Slice Instance (NSI)"""
1332 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1335 @cli.command(name
='netslice-instance-create', short_help
='creates a new Network Slice Instance')
1336 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1337 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1338 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1339 @click.option('--ssh_keys', default
=None,
1340 help='comma separated list of keys to inject to vnfs')
1341 @click.option('--config', default
=None,
1342 help='Netslice specific yaml configuration:\n'
1343 'netslice_subnet: [\n'
1344 'id: TEXT, vim_account: TEXT,\n'
1345 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1346 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1348 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1350 @click.option('--config_file',
1352 help='nsi specific yaml configuration file')
1353 @click.option('--wait',
1357 help='do not return the control immediately, but keep it \
1358 until the operation is completed, or timeout')
1360 def nsi_create2(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1361 """creates a new Network Slice Instance (NSI)"""
1362 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1365 @cli.command(name
='pdu-create', short_help
='adds a new Physical Deployment Unit to the catalog')
1366 @click.option('--name', help='name of the Physical Deployment Unit')
1367 @click.option('--pdu_type', help='type of PDU (e.g. router, firewall, FW001)')
1368 @click.option('--interface',
1369 help='interface(s) of the PDU: name=<NAME>,mgmt=<true|false>,ip-address=<IP_ADDRESS>'+
1370 '[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]',
1372 @click.option('--description', help='human readable description')
1373 @click.option('--vim_account', help='list of VIM accounts (in the same VIM) that can reach this PDU', multiple
=True)
1374 @click.option('--descriptor_file', default
=None, help='PDU descriptor file (as an alternative to using the other arguments')
1376 def pdu_create(ctx
, name
, pdu_type
, interface
, description
, vim_account
, descriptor_file
):
1377 """creates a new Physical Deployment Unit (PDU)"""
1379 check_client_version(ctx
.obj
, ctx
.command
.name
)
1381 if not descriptor_file
:
1383 raise ClientException('in absence of descriptor file, option "--name" is mandatory')
1385 raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory')
1387 raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)')
1389 raise ClientException('in absence of descriptor file, option "--vim_account" is mandatory (at least once)')
1391 with
open(descriptor_file
, 'r') as df
:
1392 pdu
= yaml
.safe_load(df
.read())
1393 if name
: pdu
["name"] = name
1394 if pdu_type
: pdu
["type"] = pdu_type
1395 if description
: pdu
["description"] = description
1396 if vim_account
: pdu
["vim_accounts"] = vim_account
1399 for iface
in interface
:
1400 new_iface
={k
:v
for k
,v
in [i
.split('=') for i
in iface
.split(',')]}
1401 new_iface
["mgmt"] = (new_iface
.get("mgmt","false").lower() == "true")
1402 ifaces_list
.append(new_iface
)
1403 pdu
["interfaces"] = ifaces_list
1404 ctx
.obj
.pdu
.create(pdu
)
1405 except ClientException
as e
:
1409 ####################
1411 ####################
1413 def nsd_update(ctx
, name
, content
):
1415 check_client_version(ctx
.obj
, ctx
.command
.name
)
1416 ctx
.obj
.nsd
.update(name
, content
)
1417 except ClientException
as e
:
1422 @cli.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
1423 @click.argument('name')
1424 @click.option('--content', default
=None,
1425 help='filename with the NSD/NSpkg replacing the current one')
1427 def nsd_update1(ctx
, name
, content
):
1428 """updates a NSD/NSpkg
1430 NAME: name or ID of the NSD/NSpkg
1432 nsd_update(ctx
, name
, content
)
1435 @cli.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
1436 @click.argument('name')
1437 @click.option('--content', default
=None,
1438 help='filename with the NSD/NSpkg replacing the current one')
1440 def nsd_update2(ctx
, name
, content
):
1441 """updates a NSD/NSpkg
1443 NAME: name or ID of the NSD/NSpkg
1445 nsd_update(ctx
, name
, content
)
1448 def vnfd_update(ctx
, name
, content
):
1450 check_client_version(ctx
.obj
, ctx
.command
.name
)
1451 ctx
.obj
.vnfd
.update(name
, content
)
1452 except ClientException
as e
:
1457 @cli.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
1458 @click.argument('name')
1459 @click.option('--content', default
=None,
1460 help='filename with the VNFD/VNFpkg replacing the current one')
1462 def vnfd_update1(ctx
, name
, content
):
1463 """updates a VNFD/VNFpkg
1465 NAME: name or ID of the VNFD/VNFpkg
1467 vnfd_update(ctx
, name
, content
)
1470 @cli.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
1471 @click.argument('name')
1472 @click.option('--content', default
=None,
1473 help='filename with the VNFD/VNFpkg replacing the current one')
1475 def vnfd_update2(ctx
, name
, content
):
1476 """updates a VNFD/VNFpkg
1478 NAME: VNFD yaml file or VNFpkg tar.gz file
1480 vnfd_update(ctx
, name
, content
)
1483 @cli.command(name
='nfpkg-update', short_help
='updates a NFpkg')
1484 @click.argument('name')
1485 @click.option('--content', default
=None,
1486 help='filename with the NFpkg replacing the current one')
1488 def nfpkg_update(ctx
, name
, content
):
1491 NAME: NF Descriptor yaml file or NFpkg tar.gz file
1493 vnfd_update(ctx
, name
, content
)
1496 def nst_update(ctx
, name
, content
):
1498 check_client_version(ctx
.obj
, ctx
.command
.name
)
1499 ctx
.obj
.nst
.update(name
, content
)
1500 except ClientException
as e
:
1505 @cli.command(name
='nst-update', short_help
='updates a Network Slice Template (NST)')
1506 @click.argument('name')
1507 @click.option('--content', default
=None,
1508 help='filename with the NST/NSTpkg replacing the current one')
1510 def nst_update1(ctx
, name
, content
):
1511 """updates a Network Slice Template (NST)
1513 NAME: name or ID of the NSD/NSpkg
1515 nst_update(ctx
, name
, content
)
1518 @cli.command(name
='netslice-template-update', short_help
='updates a Network Slice Template (NST)')
1519 @click.argument('name')
1520 @click.option('--content', default
=None,
1521 help='filename with the NST/NSTpkg replacing the current one')
1523 def nst_update2(ctx
, name
, content
):
1524 """updates a Network Slice Template (NST)
1526 NAME: name or ID of the NSD/NSpkg
1528 nst_update(ctx
, name
, content
)
1531 ####################
1533 ####################
1535 def nsd_delete(ctx
, name
, force
):
1538 ctx
.obj
.nsd
.delete(name
)
1540 check_client_version(ctx
.obj
, '--force')
1541 ctx
.obj
.nsd
.delete(name
, force
)
1542 except ClientException
as e
:
1547 @cli.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
1548 @click.argument('name')
1549 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1551 def nsd_delete1(ctx
, name
, force
):
1552 """deletes a NSD/NSpkg
1554 NAME: name or ID of the NSD/NSpkg to be deleted
1556 nsd_delete(ctx
, name
, force
)
1559 @cli.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
1560 @click.argument('name')
1561 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1563 def nsd_delete2(ctx
, name
, force
):
1564 """deletes a NSD/NSpkg
1566 NAME: name or ID of the NSD/NSpkg to be deleted
1568 nsd_delete(ctx
, name
, force
)
1571 def vnfd_delete(ctx
, name
, force
):
1574 ctx
.obj
.vnfd
.delete(name
)
1576 check_client_version(ctx
.obj
, '--force')
1577 ctx
.obj
.vnfd
.delete(name
, force
)
1578 except ClientException
as e
:
1583 @cli.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
1584 @click.argument('name')
1585 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1587 def vnfd_delete1(ctx
, name
, force
):
1588 """deletes a VNFD/VNFpkg
1590 NAME: name or ID of the VNFD/VNFpkg to be deleted
1592 vnfd_delete(ctx
, name
, force
)
1595 @cli.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
1596 @click.argument('name')
1597 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1599 def vnfd_delete2(ctx
, name
, force
):
1600 """deletes a VNFD/VNFpkg
1602 NAME: name or ID of the VNFD/VNFpkg to be deleted
1604 vnfd_delete(ctx
, name
, force
)
1607 @cli.command(name
='nfpkg-delete', short_help
='deletes a NFpkg')
1608 @click.argument('name')
1609 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1611 def nfpkg_delete(ctx
, name
, force
):
1614 NAME: name or ID of the NFpkg to be deleted
1616 vnfd_delete(ctx
, name
, force
)
1619 @cli.command(name
='ns-delete', short_help
='deletes a NS instance')
1620 @click.argument('name')
1621 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1622 @click.option('--wait',
1626 help='do not return the control immediately, but keep it \
1627 until the operation is completed, or timeout')
1629 def ns_delete(ctx
, name
, force
, wait
):
1630 """deletes a NS instance
1632 NAME: name or ID of the NS instance to be deleted
1636 ctx
.obj
.ns
.delete(name
, wait
=wait
)
1638 check_client_version(ctx
.obj
, '--force')
1639 ctx
.obj
.ns
.delete(name
, force
, wait
=wait
)
1640 except ClientException
as e
:
1645 def nst_delete(ctx
, name
, force
):
1647 check_client_version(ctx
.obj
, ctx
.command
.name
)
1648 ctx
.obj
.nst
.delete(name
, force
)
1649 except ClientException
as e
:
1654 @cli.command(name
='nst-delete', short_help
='deletes a Network Slice Template (NST)')
1655 @click.argument('name')
1656 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1658 def nst_delete1(ctx
, name
, force
):
1659 """deletes a Network Slice Template (NST)
1661 NAME: name or ID of the NST/NSTpkg to be deleted
1663 nst_delete(ctx
, name
, force
)
1666 @cli.command(name
='netslice-template-delete', short_help
='deletes a Network Slice Template (NST)')
1667 @click.argument('name')
1668 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1670 def nst_delete2(ctx
, name
, force
):
1671 """deletes a Network Slice Template (NST)
1673 NAME: name or ID of the NST/NSTpkg to be deleted
1675 nst_delete(ctx
, name
, force
)
1678 def nsi_delete(ctx
, name
, force
, wait
):
1680 check_client_version(ctx
.obj
, ctx
.command
.name
)
1681 ctx
.obj
.nsi
.delete(name
, force
, wait
=wait
)
1682 except ClientException
as e
:
1687 @cli.command(name
='nsi-delete', short_help
='deletes a Network Slice Instance (NSI)')
1688 @click.argument('name')
1689 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1690 @click.option('--wait',
1694 help='do not return the control immediately, but keep it \
1695 until the operation is completed, or timeout')
1697 def nsi_delete1(ctx
, name
, force
, wait
):
1698 """deletes a Network Slice Instance (NSI)
1700 NAME: name or ID of the Network Slice instance to be deleted
1702 nsi_delete(ctx
, name
, force
, wait
=wait
)
1705 @cli.command(name
='netslice-instance-delete', short_help
='deletes a Network Slice Instance (NSI)')
1706 @click.argument('name')
1707 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1709 def nsi_delete2(ctx
, name
, force
, wait
):
1710 """deletes a Network Slice Instance (NSI)
1712 NAME: name or ID of the Network Slice instance to be deleted
1714 nsi_delete(ctx
, name
, force
, wait
=wait
)
1717 @cli.command(name
='pdu-delete', short_help
='deletes a Physical Deployment Unit (PDU)')
1718 @click.argument('name')
1719 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1721 def pdu_delete(ctx
, name
, force
):
1722 """deletes a Physical Deployment Unit (PDU)
1724 NAME: name or ID of the PDU to be deleted
1727 check_client_version(ctx
.obj
, ctx
.command
.name
)
1728 ctx
.obj
.pdu
.delete(name
, force
)
1729 except ClientException
as e
:
1738 @cli.command(name
='vim-create', short_help
='creates a new VIM account')
1739 @click.option('--name',
1741 help='Name to create datacenter')
1742 @click.option('--user',
1744 help='VIM username')
1745 @click.option('--password',
1748 confirmation_prompt
=True,
1749 help='VIM password')
1750 @click.option('--auth_url',
1753 @click.option('--tenant',
1755 help='VIM tenant name')
1756 @click.option('--config',
1758 help='VIM specific config parameters')
1759 @click.option('--account_type',
1760 default
='openstack',
1762 @click.option('--description',
1763 default
='no description',
1764 help='human readable description')
1765 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
1766 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1767 @click.option('--wait',
1771 help='do not return the control immediately, but keep it \
1772 until the operation is completed, or timeout')
1786 """creates a new VIM account"""
1789 check_client_version(ctx
.obj
, '--sdn_controller')
1790 if sdn_port_mapping
:
1791 check_client_version(ctx
.obj
, '--sdn_port_mapping')
1793 vim
['vim-username'] = user
1794 vim
['vim-password'] = password
1795 vim
['vim-url'] = auth_url
1796 vim
['vim-tenant-name'] = tenant
1797 vim
['vim-type'] = account_type
1798 vim
['description'] = description
1799 vim
['config'] = config
1800 if sdn_controller
or sdn_port_mapping
:
1801 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
1803 ctx
.obj
.vim
.create(name
, vim
, wait
=wait
)
1804 except ClientException
as e
:
1809 @cli.command(name
='vim-update', short_help
='updates a VIM account')
1810 @click.argument('name')
1811 @click.option('--newname', help='New name for the VIM account')
1812 @click.option('--user', help='VIM username')
1813 @click.option('--password', help='VIM password')
1814 @click.option('--auth_url', help='VIM url')
1815 @click.option('--tenant', help='VIM tenant name')
1816 @click.option('--config', help='VIM specific config parameters')
1817 @click.option('--account_type', help='VIM type')
1818 @click.option('--description', help='human readable description')
1819 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
1820 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1821 @click.option('--wait',
1825 help='do not return the control immediately, but keep it \
1826 until the operation is completed, or timeout')
1841 """updates a VIM account
1843 NAME: name or ID of the VIM account
1846 check_client_version(ctx
.obj
, ctx
.command
.name
)
1848 if newname
: vim
['name'] = newname
1849 if user
: vim
['vim_user'] = user
1850 if password
: vim
['vim_password'] = password
1851 if auth_url
: vim
['vim_url'] = auth_url
1852 if tenant
: vim
['vim-tenant-name'] = tenant
1853 if account_type
: vim
['vim_type'] = account_type
1854 if description
: vim
['description'] = description
1855 if config
: vim
['config'] = config
1856 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
1857 except ClientException
as e
:
1862 @cli.command(name
='vim-delete', short_help
='deletes a VIM account')
1863 @click.argument('name')
1864 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1865 @click.option('--wait',
1869 help='do not return the control immediately, but keep it \
1870 until the operation is completed, or timeout')
1872 def vim_delete(ctx
, name
, force
, wait
):
1873 """deletes a VIM account
1875 NAME: name or ID of the VIM account to be deleted
1879 ctx
.obj
.vim
.delete(name
, wait
=wait
)
1881 check_client_version(ctx
.obj
, '--force')
1882 ctx
.obj
.vim
.delete(name
, force
, wait
=wait
)
1883 except ClientException
as e
:
1888 @cli.command(name
='vim-list', short_help
='list all VIM accounts')
1889 #@click.option('--ro_update/--no_ro_update',
1891 # help='update list from RO')
1892 @click.option('--filter', default
=None,
1893 help='restricts the list to the VIM accounts matching the filter')
1895 def vim_list(ctx
, filter):
1896 """list all VIM accounts"""
1898 check_client_version(ctx
.obj
, '--filter')
1900 # check_client_version(ctx.obj, '--ro_update', 'v1')
1901 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1902 if fullclassname
== 'osmclient.sol005.client.Client':
1903 resp
= ctx
.obj
.vim
.list(filter)
1905 # resp = ctx.obj.vim.list(ro_update)
1906 table
= PrettyTable(['vim name', 'uuid'])
1908 table
.add_row([vim
['name'], vim
['uuid']])
1913 @cli.command(name
='vim-show', short_help
='shows the details of a VIM account')
1914 @click.argument('name')
1916 def vim_show(ctx
, name
):
1917 """shows the details of a VIM account
1919 NAME: name or ID of the VIM account
1922 resp
= ctx
.obj
.vim
.get(name
)
1923 if 'vim_password' in resp
:
1924 resp
['vim_password']='********'
1925 except ClientException
as e
:
1929 table
= PrettyTable(['key', 'attribute'])
1930 for k
, v
in list(resp
.items()):
1931 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
1936 ####################
1938 ####################
1940 @cli.command(name
='wim-create', short_help
='creates a new WIM account')
1941 @click.option('--name',
1943 help='Name for the WIM account')
1944 @click.option('--user',
1945 help='WIM username')
1946 @click.option('--password',
1947 help='WIM password')
1948 @click.option('--url',
1951 # @click.option('--tenant',
1952 # help='wIM tenant name')
1953 @click.option('--config',
1955 help='WIM specific config parameters')
1956 @click.option('--wim_type',
1958 @click.option('--description',
1959 default
='no description',
1960 help='human readable description')
1961 @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)")
1962 @click.option('--wait',
1966 help='do not return the control immediately, but keep it \
1967 until the operation is completed, or timeout')
1980 """creates a new WIM account"""
1982 check_client_version(ctx
.obj
, ctx
.command
.name
)
1983 # if sdn_controller:
1984 # check_client_version(ctx.obj, '--sdn_controller')
1985 # if sdn_port_mapping:
1986 # check_client_version(ctx.obj, '--sdn_port_mapping')
1988 if user
: wim
['user'] = user
1989 if password
: wim
['password'] = password
1990 if url
: wim
['wim_url'] = url
1991 # if tenant: wim['tenant'] = tenant
1992 wim
['wim_type'] = wim_type
1993 if description
: wim
['description'] = description
1994 if config
: wim
['config'] = config
1995 ctx
.obj
.wim
.create(name
, wim
, wim_port_mapping
, wait
=wait
)
1996 except ClientException
as e
:
2001 @cli.command(name
='wim-update', short_help
='updates a WIM account')
2002 @click.argument('name')
2003 @click.option('--newname', help='New name for the WIM account')
2004 @click.option('--user', help='WIM username')
2005 @click.option('--password', help='WIM password')
2006 @click.option('--url', help='WIM url')
2007 @click.option('--config', help='WIM specific config parameters')
2008 @click.option('--wim_type', help='WIM type')
2009 @click.option('--description', help='human readable description')
2010 @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)")
2011 @click.option('--wait',
2015 help='do not return the control immediately, but keep it \
2016 until the operation is completed, or timeout')
2029 """updates a WIM account
2031 NAME: name or ID of the WIM account
2034 check_client_version(ctx
.obj
, ctx
.command
.name
)
2036 if newname
: wim
['name'] = newname
2037 if user
: wim
['user'] = user
2038 if password
: wim
['password'] = password
2039 if url
: wim
['url'] = url
2040 # if tenant: wim['tenant'] = tenant
2041 if wim_type
: wim
['wim_type'] = wim_type
2042 if description
: wim
['description'] = description
2043 if config
: wim
['config'] = config
2044 ctx
.obj
.wim
.update(name
, wim
, wim_port_mapping
, wait
=wait
)
2045 except ClientException
as e
:
2050 @cli.command(name
='wim-delete', short_help
='deletes a WIM account')
2051 @click.argument('name')
2052 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2053 @click.option('--wait',
2057 help='do not return the control immediately, but keep it \
2058 until the operation is completed, or timeout')
2060 def wim_delete(ctx
, name
, force
, wait
):
2061 """deletes a WIM account
2063 NAME: name or ID of the WIM account to be deleted
2066 check_client_version(ctx
.obj
, ctx
.command
.name
)
2067 ctx
.obj
.wim
.delete(name
, force
, wait
=wait
)
2068 except ClientException
as e
:
2073 @cli.command(name
='wim-list', short_help
='list all WIM accounts')
2074 @click.option('--filter', default
=None,
2075 help='restricts the list to the WIM accounts matching the filter')
2077 def wim_list(ctx
, filter):
2078 """list all WIM accounts"""
2080 check_client_version(ctx
.obj
, ctx
.command
.name
)
2081 resp
= ctx
.obj
.wim
.list(filter)
2082 table
= PrettyTable(['wim name', 'uuid'])
2084 table
.add_row([wim
['name'], wim
['uuid']])
2087 except ClientException
as e
:
2092 @cli.command(name
='wim-show', short_help
='shows the details of a WIM account')
2093 @click.argument('name')
2095 def wim_show(ctx
, name
):
2096 """shows the details of a WIM account
2098 NAME: name or ID of the WIM account
2101 check_client_version(ctx
.obj
, ctx
.command
.name
)
2102 resp
= ctx
.obj
.wim
.get(name
)
2103 if 'password' in resp
:
2104 resp
['wim_password']='********'
2105 except ClientException
as e
:
2109 table
= PrettyTable(['key', 'attribute'])
2110 for k
, v
in list(resp
.items()):
2111 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2116 ####################
2117 # SDN controller operations
2118 ####################
2120 @cli.command(name
='sdnc-create', short_help
='creates a new SDN controller')
2121 @click.option('--name',
2123 help='Name to create sdn controller')
2124 @click.option('--type',
2126 help='SDN controller type')
2127 @click.option('--sdn_controller_version',
2128 help='SDN controller version')
2129 @click.option('--ip_address',
2131 help='SDN controller IP address')
2132 @click.option('--port',
2134 help='SDN controller port')
2135 @click.option('--switch_dpid',
2137 help='Switch DPID (Openflow Datapath ID)')
2138 @click.option('--user',
2139 help='SDN controller username')
2140 @click.option('--password',
2142 confirmation_prompt
=True,
2143 help='SDN controller password')
2144 #@click.option('--description',
2145 # default='no description',
2146 # help='human readable description')
2147 @click.option('--wait',
2151 help='do not return the control immediately, but keep it \
2152 until the operation is completed, or timeout')
2154 def sdnc_create(ctx
,
2157 sdn_controller_version
,
2164 """creates a new SDN controller"""
2166 sdncontroller
['name'] = name
2167 sdncontroller
['type'] = type
2168 sdncontroller
['ip'] = ip_address
2169 sdncontroller
['port'] = int(port
)
2170 sdncontroller
['dpid'] = switch_dpid
2171 if sdn_controller_version
:
2172 sdncontroller
['version'] = sdn_controller_version
2174 sdncontroller
['user'] = user
2176 sdncontroller
['password'] = password
2177 # sdncontroller['description'] = description
2179 check_client_version(ctx
.obj
, ctx
.command
.name
)
2180 ctx
.obj
.sdnc
.create(name
, sdncontroller
, wait
=wait
)
2181 except ClientException
as e
:
2185 @cli.command(name
='sdnc-update', short_help
='updates an SDN controller')
2186 @click.argument('name')
2187 @click.option('--newname', help='New name for the SDN controller')
2188 @click.option('--type', help='SDN controller type')
2189 @click.option('--sdn_controller_version', help='SDN controller username')
2190 @click.option('--ip_address', help='SDN controller IP address')
2191 @click.option('--port', help='SDN controller port')
2192 @click.option('--switch_dpid', help='Switch DPID (Openflow Datapath ID)')
2193 @click.option('--user', help='SDN controller username')
2194 @click.option('--password', help='SDN controller password')
2195 #@click.option('--description', default=None, help='human readable description')
2196 @click.option('--wait',
2200 help='do not return the control immediately, but keep it \
2201 until the operation is completed, or timeout')
2203 def sdnc_update(ctx
,
2207 sdn_controller_version
,
2214 """updates an SDN controller
2216 NAME: name or ID of the SDN controller
2219 if newname
: sdncontroller
['name'] = newname
2220 if type: sdncontroller
['type'] = type
2221 if ip_address
: sdncontroller
['ip'] = ip_address
2222 if port
: sdncontroller
['port'] = int(port
)
2223 if switch_dpid
: sdncontroller
['dpid'] = switch_dpid
2224 # sdncontroller['description'] = description
2225 if sdn_controller_version
is not None:
2226 if sdn_controller_version
=="":
2227 sdncontroller
['version'] = None
2229 sdncontroller
['version'] = sdn_controller_version
2230 if user
is not None:
2232 sdncontroller
['user'] = None
2234 sdncontroller
['user'] = user
2235 if password
is not None:
2237 sdncontroller
['password'] = None
2239 sdncontroller
['password'] = user
2241 check_client_version(ctx
.obj
, ctx
.command
.name
)
2242 ctx
.obj
.sdnc
.update(name
, sdncontroller
, wait
=wait
)
2243 except ClientException
as e
:
2248 @cli.command(name
='sdnc-delete', short_help
='deletes an SDN controller')
2249 @click.argument('name')
2250 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2251 @click.option('--wait',
2255 help='do not return the control immediately, but keep it \
2256 until the operation is completed, or timeout')
2258 def sdnc_delete(ctx
, name
, force
, wait
):
2259 """deletes an SDN controller
2261 NAME: name or ID of the SDN controller to be deleted
2264 check_client_version(ctx
.obj
, ctx
.command
.name
)
2265 ctx
.obj
.sdnc
.delete(name
, force
, wait
=wait
)
2266 except ClientException
as e
:
2271 @cli.command(name
='sdnc-list', short_help
='list all SDN controllers')
2272 @click.option('--filter', default
=None,
2273 help='restricts the list to the SDN controllers matching the filter')
2275 def sdnc_list(ctx
, filter):
2276 """list all SDN controllers"""
2278 check_client_version(ctx
.obj
, ctx
.command
.name
)
2279 resp
= ctx
.obj
.sdnc
.list(filter)
2280 except ClientException
as e
:
2283 table
= PrettyTable(['sdnc name', 'id'])
2285 table
.add_row([sdnc
['name'], sdnc
['_id']])
2290 @cli.command(name
='sdnc-show', short_help
='shows the details of an SDN controller')
2291 @click.argument('name')
2293 def sdnc_show(ctx
, name
):
2294 """shows the details of an SDN controller
2296 NAME: name or ID of the SDN controller
2299 check_client_version(ctx
.obj
, ctx
.command
.name
)
2300 resp
= ctx
.obj
.sdnc
.get(name
)
2301 except ClientException
as e
:
2305 table
= PrettyTable(['key', 'attribute'])
2306 for k
, v
in list(resp
.items()):
2307 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2312 ###########################
2313 # K8s cluster operations
2314 ###########################
2316 @cli.command(name
='k8scluster-add')
2317 @click.argument('name')
2318 @click.option('--creds',
2320 help='credentials file, i.e. a valid `.kube/config` file')
2321 @click.option('--version',
2323 help='Kubernetes version')
2324 @click.option('--vim',
2326 help='VIM target, the VIM where the cluster resides')
2327 @click.option('--k8s-nets',
2329 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) ...]}"')
2330 @click.option('--description',
2332 help='human readable description')
2333 @click.option('--namespace',
2334 default
='kube-system',
2335 help='namespace to be used for its operation, defaults to `kube-system`')
2336 @click.option('--cni',
2338 help='list of CNI plugins, in JSON inline format, used in the cluster')
2339 #@click.option('--skip-init',
2341 # help='If set, K8s cluster is assumed to be ready for its use with OSM')
2342 #@click.option('--wait',
2344 # help='do not return the control immediately, but keep it \
2345 # until the operation is completed, or timeout')
2347 def k8scluster_add(ctx
,
2356 """adds a K8s cluster to OSM
2358 NAME: name of the K8s cluster
2361 check_client_version(ctx
.obj
, ctx
.command
.name
)
2363 cluster
['name'] = name
2364 with
open(creds
, 'r') as cf
:
2365 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2366 cluster
['k8s_version'] = version
2367 cluster
['vim_account'] = vim
2368 cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2369 cluster
['description'] = description
2370 if namespace
: cluster
['namespace'] = namespace
2371 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2372 ctx
.obj
.k8scluster
.create(name
, cluster
)
2373 except ClientException
as e
:
2378 @cli.command(name
='k8scluster-update', short_help
='updates a K8s cluster')
2379 @click.argument('name')
2380 @click.option('--newname', help='New name for the K8s cluster')
2381 @click.option('--creds', help='credentials file, i.e. a valid `.kube/config` file')
2382 @click.option('--version', help='Kubernetes version')
2383 @click.option('--vim', help='VIM target, the VIM where the cluster resides')
2384 @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) ...]}"')
2385 @click.option('--description', help='human readable description')
2386 @click.option('--namespace', help='namespace to be used for its operation, defaults to `kube-system`')
2387 @click.option('--cni', help='list of CNI plugins, in JSON inline format, used in the cluster')
2389 def k8scluster_update(ctx
,
2399 """updates a K8s cluster
2401 NAME: name or ID of the K8s cluster
2404 check_client_version(ctx
.obj
, ctx
.command
.name
)
2406 if newname
: cluster
['name'] = newname
2408 with
open(creds
, 'r') as cf
:
2409 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2410 if version
: cluster
['k8s_version'] = version
2411 if vim
: cluster
['vim_account'] = vim
2412 if k8s_nets
: cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2413 if description
: cluster
['description'] = description
2414 if namespace
: cluster
['namespace'] = namespace
2415 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2416 ctx
.obj
.k8scluster
.update(name
, cluster
)
2417 except ClientException
as e
:
2422 @cli.command(name
='k8scluster-delete')
2423 @click.argument('name')
2424 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2425 #@click.option('--wait',
2427 # help='do not return the control immediately, but keep it \
2428 # until the operation is completed, or timeout')
2430 def k8scluster_delete(ctx
, name
, force
):
2431 """deletes a K8s cluster
2433 NAME: name or ID of the K8s cluster to be deleted
2436 check_client_version(ctx
.obj
, ctx
.command
.name
)
2437 ctx
.obj
.k8scluster
.delete(name
, force
=force
)
2438 except ClientException
as e
:
2443 @cli.command(name
='k8scluster-list')
2444 @click.option('--filter', default
=None,
2445 help='restricts the list to the K8s clusters matching the filter')
2446 @click.option('--literal', is_flag
=True,
2447 help='print literally, no pretty table')
2449 def k8scluster_list(ctx
, filter, literal
):
2450 """list all K8s clusters"""
2452 check_client_version(ctx
.obj
, ctx
.command
.name
)
2453 resp
= ctx
.obj
.k8scluster
.list(filter)
2455 print(yaml
.safe_dump(resp
))
2457 table
= PrettyTable(['Name', 'Id', 'Version', 'VIM', 'K8s-nets', 'Description'])
2458 for cluster
in resp
:
2459 table
.add_row([cluster
['name'], cluster
['_id'], cluster
['k8s_version'], cluster
['vim_account'],
2460 json
.dumps(cluster
['nets']), trunc_text(cluster
.get('description',''),40)
2464 except ClientException
as e
:
2469 @cli.command(name
='k8scluster-show')
2470 @click.argument('name')
2471 @click.option('--literal', is_flag
=True,
2472 help='print literally, no pretty table')
2474 def k8scluster_show(ctx
, name
, literal
):
2475 """shows the details of a K8s cluster
2477 NAME: name or ID of the K8s cluster
2480 resp
= ctx
.obj
.k8scluster
.get(name
)
2482 print(yaml
.safe_dump(resp
))
2484 table
= PrettyTable(['key', 'attribute'])
2485 for k
, v
in list(resp
.items()):
2486 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2489 except ClientException
as e
:
2495 ###########################
2497 ###########################
2499 @cli.command(name
='repo-add')
2500 @click.argument('name')
2501 @click.argument('uri')
2502 @click.option('--type',
2503 type=click
.Choice(['chart', 'bundle']),
2505 help='type of repo (chart for helm-charts, bundle for juju-bundles)')
2506 @click.option('--description',
2508 help='human readable description')
2509 #@click.option('--wait',
2511 # help='do not return the control immediately, but keep it \
2512 # until the operation is completed, or timeout')
2519 """adds a repo to OSM
2521 NAME: name of the repo
2522 URI: URI of the repo
2525 check_client_version(ctx
.obj
, ctx
.command
.name
)
2530 repo
['description'] = description
2531 ctx
.obj
.repo
.create(name
, repo
)
2532 except ClientException
as e
:
2537 @cli.command(name
='repo-update')
2538 @click.argument('name')
2539 @click.option('--newname', help='New name for the repo')
2540 @click.option('--uri', help='URI of the repo')
2541 @click.option('--type', type=click
.Choice(['chart', 'bundle']),
2542 help='type of repo (chart for helm-charts, bundle for juju-bundles)')
2543 @click.option('--description', help='human readable description')
2544 #@click.option('--wait',
2546 # help='do not return the control immediately, but keep it \
2547 # until the operation is completed, or timeout')
2549 def repo_update(ctx
,
2555 """updates a repo in OSM
2557 NAME: name of the repo
2560 check_client_version(ctx
.obj
, ctx
.command
.name
)
2562 if newname
: repo
['name'] = newname
2563 if uri
: repo
['uri'] = uri
2564 if type: repo
['type'] = type
2565 if description
: repo
['description'] = description
2566 ctx
.obj
.repo
.update(name
, repo
)
2567 except ClientException
as e
:
2572 @cli.command(name
='repo-delete')
2573 @click.argument('name')
2574 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2575 #@click.option('--wait',
2577 # help='do not return the control immediately, but keep it \
2578 # until the operation is completed, or timeout')
2580 def repo_delete(ctx
, name
, force
):
2583 NAME: name or ID of the repo to be deleted
2586 check_client_version(ctx
.obj
, ctx
.command
.name
)
2587 ctx
.obj
.repo
.delete(name
, force
=force
)
2588 except ClientException
as e
:
2593 @cli.command(name
='repo-list')
2594 @click.option('--filter', default
=None,
2595 help='restricts the list to the repos matching the filter')
2596 @click.option('--literal', is_flag
=True,
2597 help='print literally, no pretty table')
2599 def repo_list(ctx
, filter, literal
):
2600 """list all repos"""
2602 check_client_version(ctx
.obj
, ctx
.command
.name
)
2603 resp
= ctx
.obj
.repo
.list(filter)
2605 print(yaml
.safe_dump(resp
))
2607 table
= PrettyTable(['Name', 'Id', 'Type', 'URI', 'Description'])
2609 #cluster['k8s-nets'] = json.dumps(yaml.safe_load(cluster['k8s-nets']))
2610 table
.add_row([repo
['name'], repo
['_id'], repo
['type'], repo
['url'], trunc_text(repo
.get('description',''),40)])
2613 except ClientException
as e
:
2618 @cli.command(name
='repo-show')
2619 @click.argument('name')
2620 @click.option('--literal', is_flag
=True,
2621 help='print literally, no pretty table')
2623 def repo_show(ctx
, name
, literal
):
2624 """shows the details of a repo
2626 NAME: name or ID of the repo
2629 resp
= ctx
.obj
.repo
.get(name
)
2631 print(yaml
.safe_dump(resp
))
2633 table
= PrettyTable(['key', 'attribute'])
2634 for k
, v
in list(resp
.items()):
2635 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2638 except ClientException
as e
:
2644 ####################
2645 # Project mgmt operations
2646 ####################
2648 @cli.command(name
='project-create', short_help
='creates a new project')
2649 @click.argument('name')
2650 #@click.option('--description',
2651 # default='no description',
2652 # help='human readable description')
2654 def project_create(ctx
, name
):
2655 """Creates a new project
2657 NAME: name of the project
2660 project
['name'] = name
2662 check_client_version(ctx
.obj
, ctx
.command
.name
)
2663 ctx
.obj
.project
.create(name
, project
)
2664 except ClientException
as e
:
2669 @cli.command(name
='project-delete', short_help
='deletes a project')
2670 @click.argument('name')
2671 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2673 def project_delete(ctx
, name
):
2674 """deletes a project
2676 NAME: name or ID of the project to be deleted
2679 check_client_version(ctx
.obj
, ctx
.command
.name
)
2680 ctx
.obj
.project
.delete(name
)
2681 except ClientException
as e
:
2686 @cli.command(name
='project-list', short_help
='list all projects')
2687 @click.option('--filter', default
=None,
2688 help='restricts the list to the projects matching the filter')
2690 def project_list(ctx
, filter):
2691 """list all projects"""
2693 check_client_version(ctx
.obj
, ctx
.command
.name
)
2694 resp
= ctx
.obj
.project
.list(filter)
2695 except ClientException
as e
:
2698 table
= PrettyTable(['name', 'id'])
2700 table
.add_row([proj
['name'], proj
['_id']])
2705 @cli.command(name
='project-show', short_help
='shows the details of a project')
2706 @click.argument('name')
2708 def project_show(ctx
, name
):
2709 """shows the details of a project
2711 NAME: name or ID of the project
2714 check_client_version(ctx
.obj
, ctx
.command
.name
)
2715 resp
= ctx
.obj
.project
.get(name
)
2716 except ClientException
as e
:
2720 table
= PrettyTable(['key', 'attribute'])
2721 for k
, v
in resp
.items():
2722 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2727 @cli.command(name
='project-update', short_help
='updates a project (only the name can be updated)')
2728 @click.argument('project')
2729 @click.option('--name',
2731 help='new name for the project')
2734 def project_update(ctx
, project
, name
):
2736 Update a project name
2739 :param project: id or name of the project to modify
2740 :param name: new name for the project
2744 project_changes
= {}
2745 project_changes
['name'] = name
2748 check_client_version(ctx
.obj
, ctx
.command
.name
)
2749 ctx
.obj
.project
.update(project
, project_changes
)
2750 except ClientException
as e
:
2754 ####################
2755 # User mgmt operations
2756 ####################
2758 @cli.command(name
='user-create', short_help
='creates a new user')
2759 @click.argument('username')
2760 @click.option('--password',
2763 confirmation_prompt
=True,
2764 help='user password')
2765 @click.option('--projects',
2766 # prompt="Comma separate list of projects",
2768 callback
=lambda ctx
, param
, value
: ''.join(value
).split(',') if all(len(x
)==1 for x
in value
) else value
,
2769 help='list of project ids that the user belongs to')
2770 @click.option('--project-role-mappings', 'project_role_mappings',
2771 default
=None, multiple
=True,
2772 help='creating user project/role(s) mapping')
2774 def user_create(ctx
, username
, password
, projects
, project_role_mappings
):
2775 """Creates a new user
2778 USERNAME: name of the user
2779 PASSWORD: password of the user
2780 PROJECTS: projects assigned to user (internal only)
2781 PROJECT_ROLE_MAPPING: roles in projects assigned to user (keystone)
2784 user
['username'] = username
2785 user
['password'] = password
2786 user
['projects'] = projects
2787 user
['project_role_mappings'] = project_role_mappings
2790 check_client_version(ctx
.obj
, ctx
.command
.name
)
2791 ctx
.obj
.user
.create(username
, user
)
2792 except ClientException
as e
:
2797 @cli.command(name
='user-update', short_help
='updates user information')
2798 @click.argument('username')
2799 @click.option('--password',
2802 # confirmation_prompt=True,
2803 help='user password')
2804 @click.option('--set-username', 'set_username',
2806 help='change username')
2807 @click.option('--set-project', 'set_project',
2808 default
=None, multiple
=True,
2809 help='create/replace the project,role(s) mapping for this project: \'project,role1,role2,...\'')
2810 @click.option('--remove-project', 'remove_project',
2811 default
=None, multiple
=True,
2812 help='removes project from user: \'project\'')
2813 @click.option('--add-project-role', 'add_project_role',
2814 default
=None, multiple
=True,
2815 help='adds project,role(s) mapping: \'project,role1,role2,...\'')
2816 @click.option('--remove-project-role', 'remove_project_role',
2817 default
=None, multiple
=True,
2818 help='removes project,role(s) mapping: \'project,role1,role2,...\'')
2820 def user_update(ctx
, username
, password
, set_username
, set_project
, remove_project
,
2821 add_project_role
, remove_project_role
):
2822 """Update a user information
2825 USERNAME: name of the user
2826 PASSWORD: new password
2827 SET_USERNAME: new username
2828 SET_PROJECT: creating mappings for project/role(s)
2829 REMOVE_PROJECT: deleting mappings for project/role(s)
2830 ADD_PROJECT_ROLE: adding mappings for project/role(s)
2831 REMOVE_PROJECT_ROLE: removing mappings for project/role(s)
2834 user
['password'] = password
2835 user
['username'] = set_username
2836 user
['set-project'] = set_project
2837 user
['remove-project'] = remove_project
2838 user
['add-project-role'] = add_project_role
2839 user
['remove-project-role'] = remove_project_role
2842 check_client_version(ctx
.obj
, ctx
.command
.name
)
2843 ctx
.obj
.user
.update(username
, user
)
2844 except ClientException
as e
:
2849 @cli.command(name
='user-delete', short_help
='deletes a user')
2850 @click.argument('name')
2851 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2853 def user_delete(ctx
, name
):
2857 NAME: name or ID of the user to be deleted
2860 check_client_version(ctx
.obj
, ctx
.command
.name
)
2861 ctx
.obj
.user
.delete(name
)
2862 except ClientException
as e
:
2867 @cli.command(name
='user-list', short_help
='list all users')
2868 @click.option('--filter', default
=None,
2869 help='restricts the list to the users matching the filter')
2871 def user_list(ctx
, filter):
2872 """list all users"""
2874 check_client_version(ctx
.obj
, ctx
.command
.name
)
2875 resp
= ctx
.obj
.user
.list(filter)
2876 except ClientException
as e
:
2879 table
= PrettyTable(['name', 'id'])
2881 table
.add_row([user
['username'], user
['_id']])
2886 @cli.command(name
='user-show', short_help
='shows the details of a user')
2887 @click.argument('name')
2889 def user_show(ctx
, name
):
2890 """shows the details of a user
2892 NAME: name or ID of the user
2895 check_client_version(ctx
.obj
, ctx
.command
.name
)
2896 resp
= ctx
.obj
.user
.get(name
)
2897 if 'password' in resp
:
2898 resp
['password']='********'
2899 except ClientException
as e
:
2903 table
= PrettyTable(['key', 'attribute'])
2904 for k
, v
in resp
.items():
2905 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2910 ####################
2911 # Fault Management operations
2912 ####################
2914 @cli.command(name
='ns-alarm-create')
2915 @click.argument('name')
2916 @click.option('--ns', prompt
=True, help='NS instance id or name')
2917 @click.option('--vnf', prompt
=True,
2918 help='VNF name (VNF member index as declared in the NSD)')
2919 @click.option('--vdu', prompt
=True,
2920 help='VDU name (VDU name as declared in the VNFD)')
2921 @click.option('--metric', prompt
=True,
2922 help='Name of the metric (e.g. cpu_utilization)')
2923 @click.option('--severity', default
='WARNING',
2924 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
2925 @click.option('--threshold_value', prompt
=True,
2926 help='threshold value that, when crossed, an alarm is triggered')
2927 @click.option('--threshold_operator', prompt
=True,
2928 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
2929 @click.option('--statistic', default
='AVERAGE',
2930 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
2932 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
2933 threshold_value
, threshold_operator
, statistic
):
2934 """creates a new alarm for a NS instance"""
2935 # TODO: Check how to validate threshold_value.
2936 # Should it be an integer (1-100), percentage, or decimal (0.01-1.00)?
2938 ns_instance
= ctx
.obj
.ns
.get(ns
)
2940 alarm
['alarm_name'] = name
2941 alarm
['ns_id'] = ns_instance
['_id']
2942 alarm
['correlation_id'] = ns_instance
['_id']
2943 alarm
['vnf_member_index'] = vnf
2944 alarm
['vdu_name'] = vdu
2945 alarm
['metric_name'] = metric
2946 alarm
['severity'] = severity
2947 alarm
['threshold_value'] = int(threshold_value
)
2948 alarm
['operation'] = threshold_operator
2949 alarm
['statistic'] = statistic
2950 check_client_version(ctx
.obj
, ctx
.command
.name
)
2951 ctx
.obj
.ns
.create_alarm(alarm
)
2952 except ClientException
as e
:
2957 #@cli.command(name='ns-alarm-delete')
2958 #@click.argument('name')
2959 #@click.pass_context
2960 #def ns_alarm_delete(ctx, name):
2961 # """deletes an alarm
2963 # NAME: name of the alarm to be deleted
2966 # check_client_version(ctx.obj, ctx.command.name)
2967 # ctx.obj.ns.delete_alarm(name)
2968 # except ClientException as e:
2973 ####################
2974 # Performance Management operations
2975 ####################
2977 @cli.command(name
='ns-metric-export', short_help
='exports a metric to the internal OSM bus, which can be read by other apps')
2978 @click.option('--ns', prompt
=True, help='NS instance id or name')
2979 @click.option('--vnf', prompt
=True,
2980 help='VNF name (VNF member index as declared in the NSD)')
2981 @click.option('--vdu', prompt
=True,
2982 help='VDU name (VDU name as declared in the VNFD)')
2983 @click.option('--metric', prompt
=True,
2984 help='name of the metric (e.g. cpu_utilization)')
2985 #@click.option('--period', default='1w',
2986 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
2987 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
2989 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
2990 """exports a metric to the internal OSM bus, which can be read by other apps"""
2991 # TODO: Check how to validate interval.
2992 # Should it be an integer (seconds), or should a suffix (s,m,h,d,w) also be permitted?
2994 ns_instance
= ctx
.obj
.ns
.get(ns
)
2996 metric_data
['ns_id'] = ns_instance
['_id']
2997 metric_data
['correlation_id'] = ns_instance
['_id']
2998 metric_data
['vnf_member_index'] = vnf
2999 metric_data
['vdu_name'] = vdu
3000 metric_data
['metric_name'] = metric
3001 metric_data
['collection_unit'] = 'WEEK'
3002 metric_data
['collection_period'] = 1
3003 check_client_version(ctx
.obj
, ctx
.command
.name
)
3005 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
3009 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
3010 time
.sleep(int(interval
))
3012 except ClientException
as e
:
3017 ####################
3019 ####################
3021 @cli.command(name
='upload-package', short_help
='uploads a VNF package or NS package')
3022 @click.argument('filename')
3024 def upload_package(ctx
, filename
):
3025 """uploads a VNF package or NS package
3027 FILENAME: VNF or NS package file (tar.gz)
3030 ctx
.obj
.package
.upload(filename
)
3031 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
3032 if fullclassname
!= 'osmclient.sol005.client.Client':
3033 ctx
.obj
.package
.wait_for_upload(filename
)
3034 except ClientException
as e
:
3039 #@cli.command(name='ns-scaling-show')
3040 #@click.argument('ns_name')
3041 #@click.pass_context
3042 #def show_ns_scaling(ctx, ns_name):
3043 # """shows the status of a NS scaling operation
3045 # NS_NAME: name of the NS instance being scaled
3048 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3049 # resp = ctx.obj.ns.list()
3050 # except ClientException as e:
3054 # table = PrettyTable(
3057 # 'operational status',
3062 # if ns_name == ns['name']:
3063 # nsopdata = ctx.obj.ns.get_opdata(ns['id'])
3064 # scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
3065 # for record in scaling_records:
3066 # if 'instance' in record:
3067 # instances = record['instance']
3068 # for inst in instances:
3070 # [record['scaling-group-name-ref'],
3071 # inst['instance-id'],
3072 # inst['op-status'],
3073 # time.strftime('%Y-%m-%d %H:%M:%S',
3075 # inst['create-time'])),
3081 #@cli.command(name='ns-scale')
3082 #@click.argument('ns_name')
3083 #@click.option('--ns_scale_group', prompt=True)
3084 #@click.option('--index', prompt=True)
3085 #@click.option('--wait',
3089 # help='do not return the control immediately, but keep it \
3090 # until the operation is completed, or timeout')
3091 #@click.pass_context
3092 #def ns_scale(ctx, ns_name, ns_scale_group, index, wait):
3095 # NS_NAME: name of the NS instance to be scaled
3098 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3099 # ctx.obj.ns.scale(ns_name, ns_scale_group, index, wait=wait)
3100 # except ClientException as e:
3105 #@cli.command(name='config-agent-list')
3106 #@click.pass_context
3107 #def config_agent_list(ctx):
3108 # """list config agents"""
3110 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3111 # except ClientException as e:
3114 # table = PrettyTable(['name', 'account-type', 'details'])
3115 # for account in ctx.obj.vca.list():
3118 # account['account-type'],
3124 #@cli.command(name='config-agent-delete')
3125 #@click.argument('name')
3126 #@click.pass_context
3127 #def config_agent_delete(ctx, name):
3128 # """deletes a config agent
3130 # NAME: name of the config agent to be deleted
3133 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3134 # ctx.obj.vca.delete(name)
3135 # except ClientException as e:
3140 #@cli.command(name='config-agent-add')
3141 #@click.option('--name',
3143 #@click.option('--account_type',
3145 #@click.option('--server',
3147 #@click.option('--user',
3149 #@click.option('--secret',
3152 # confirmation_prompt=True)
3153 #@click.pass_context
3154 #def config_agent_add(ctx, name, account_type, server, user, secret):
3155 # """adds a config agent"""
3157 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3158 # ctx.obj.vca.create(name, account_type, server, user, secret)
3159 # except ClientException as e:
3164 #@cli.command(name='ro-dump')
3165 #@click.pass_context
3167 # """shows RO agent information"""
3168 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3169 # resp = ctx.obj.vim.get_resource_orchestrator()
3170 # table = PrettyTable(['key', 'attribute'])
3171 # for k, v in list(resp.items()):
3172 # table.add_row([k, json.dumps(v, indent=2)])
3177 #@cli.command(name='vcs-list')
3178 #@click.pass_context
3180 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3181 # resp = ctx.obj.utils.get_vcs_info()
3182 # table = PrettyTable(['component name', 'state'])
3183 # for component in resp:
3184 # table.add_row([component['component_name'], component['state']])
3189 @cli.command(name
='ns-action', short_help
='executes an action/primitive over a NS instance')
3190 @click.argument('ns_name')
3191 @click.option('--vnf_name', default
=None, help='member-vnf-index if the target is a vnf instead of a ns)')
3192 @click.option('--kdu_name', default
=None, help='kdu-name if the target is a kdu)')
3193 @click.option('--vdu_id', default
=None, help='vdu-id if the target is a vdu')
3194 @click.option('--vdu_count', default
=None, help='number of vdu instance of this vdu_id')
3195 @click.option('--action_name', prompt
=True, help='action name')
3196 @click.option('--params', default
=None, help='action params in YAML/JSON inline string')
3197 @click.option('--params_file', default
=None, help='YAML/JSON file with action params')
3198 @click.option('--wait',
3202 help='do not return the control immediately, but keep it \
3203 until the operation is completed, or timeout')
3215 """executes an action/primitive over a NS instance
3217 NS_NAME: name or ID of the NS instance
3220 check_client_version(ctx
.obj
, ctx
.command
.name
)
3223 op_data
['member_vnf_index'] = vnf_name
3225 op_data
['kdu_name'] = kdu_name
3227 op_data
['vdu_id'] = vdu_id
3229 op_data
['vdu_count_index'] = vdu_count
3230 op_data
['primitive'] = action_name
3232 with
open(params_file
, 'r') as pf
:
3235 op_data
['primitive_params'] = yaml
.safe_load(params
)
3237 op_data
['primitive_params'] = {}
3238 print(ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
, wait
=wait
))
3240 except ClientException
as e
:
3245 @cli.command(name
='vnf-scale', short_help
='executes a VNF scale (adding/removing VDUs)')
3246 @click.argument('ns_name')
3247 @click.argument('vnf_name')
3248 @click.option('--scaling-group', prompt
=True, help="scaling-group-descriptor name to use")
3249 @click.option('--scale-in', default
=False, is_flag
=True, help="performs a scale in operation")
3250 @click.option('--scale-out', default
=False, is_flag
=True, help="performs a scale out operation (by default)")
3259 Executes a VNF scale (adding/removing VDUs)
3262 NS_NAME: name or ID of the NS instance.
3263 VNF_NAME: member-vnf-index in the NS to be scaled.
3266 check_client_version(ctx
.obj
, ctx
.command
.name
)
3267 if not scale_in
and not scale_out
:
3269 ctx
.obj
.ns
.scale_vnf(ns_name
, vnf_name
, scaling_group
, scale_in
, scale_out
)
3270 except ClientException
as e
:
3275 ##############################
3276 # Role Management Operations #
3277 ##############################
3279 @cli.command(name
='role-create', short_help
='creates a new role')
3280 @click.argument('name')
3281 @click.option('--permissions',
3283 help='role permissions using a dictionary')
3285 def role_create(ctx
, name
, permissions
):
3290 NAME: Name or ID of the role.
3291 DEFINITION: Definition of grant/denial of access to resources.
3294 check_client_version(ctx
.obj
, ctx
.command
.name
)
3295 ctx
.obj
.role
.create(name
, permissions
)
3296 except ClientException
as e
:
3301 @cli.command(name
='role-update', short_help
='updates a role')
3302 @click.argument('name')
3303 @click.option('--set-name',
3305 help='change name of rle')
3306 # @click.option('--permissions',
3308 # help='provide a yaml format dictionary with incremental changes. Values can be bool or None to delete')
3309 @click.option('--add',
3311 help='yaml format dictionary with permission: True/False to access grant/denial')
3312 @click.option('--remove',
3314 help='yaml format list to remove a permission')
3316 def role_update(ctx
, name
, set_name
, add
, remove
):
3321 NAME: Name or ID of the role.
3322 DEFINITION: Definition overwrites the old definition.
3323 ADD: Grant/denial of access to resource to add.
3324 REMOVE: Grant/denial of access to resource to remove.
3327 check_client_version(ctx
.obj
, ctx
.command
.name
)
3328 ctx
.obj
.role
.update(name
, set_name
, None, add
, remove
)
3329 except ClientException
as e
:
3334 @cli.command(name
='role-delete', short_help
='deletes a role')
3335 @click.argument('name')
3336 # @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3338 def role_delete(ctx
, name
):
3343 NAME: Name or ID of the role.
3346 check_client_version(ctx
.obj
, ctx
.command
.name
)
3347 ctx
.obj
.role
.delete(name
)
3348 except ClientException
as e
:
3353 @cli.command(name
='role-list', short_help
='list all roles')
3354 @click.option('--filter', default
=None,
3355 help='restricts the list to the projects matching the filter')
3357 def role_list(ctx
, filter):
3362 check_client_version(ctx
.obj
, ctx
.command
.name
)
3363 resp
= ctx
.obj
.role
.list(filter)
3364 except ClientException
as e
:
3367 table
= PrettyTable(['name', 'id'])
3369 table
.add_row([role
['name'], role
['_id']])
3374 @cli.command(name
='role-show', short_help
='show specific role')
3375 @click.argument('name')
3377 def role_show(ctx
, name
):
3379 Shows the details of a role.
3382 NAME: Name or ID of the role.
3385 check_client_version(ctx
.obj
, ctx
.command
.name
)
3386 resp
= ctx
.obj
.role
.get(name
)
3387 except ClientException
as e
:
3391 table
= PrettyTable(['key', 'attribute'])
3392 for k
, v
in resp
.items():
3393 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3398 @cli.command(name
='package-create',
3399 short_help
='Create a package descriptor')
3400 @click.argument('package-type')
3401 @click.argument('package-name')
3402 @click.option('--base-directory',
3404 help=('(NS/VNF/NST) Set the location for package creation. Default: "."'))
3405 @click.option('--image',
3406 default
="image-name",
3407 help='(VNF) Set the name of the vdu image. Default "image-name"')
3408 @click.option('--vdus',
3410 help='(VNF) Set the number of vdus in a VNF. Default 1')
3411 @click.option('--vcpu',
3413 help='(VNF) Set the number of virtual CPUs in a vdu. Default 1')
3414 @click.option('--memory',
3416 help='(VNF) Set the memory size (MB) of the vdu. Default 1024')
3417 @click.option('--storage',
3419 help='(VNF) Set the disk size (GB) of the vdu. Default 10')
3420 @click.option('--interfaces',
3422 help='(VNF) Set the number of additional interfaces apart from the management interface. Default 0')
3423 @click.option('--vendor',
3425 help='(NS/VNF) Set the descriptor vendor. Default "OSM"')
3426 @click.option('--override',
3429 help='(NS/VNF/NST) Flag for overriding the package if exists.')
3430 @click.option('--detailed',
3433 help='(NS/VNF/NST) Flag for generating descriptor .yaml with all possible commented options')
3434 @click.option('--netslice-subnets',
3436 help='(NST) Number of netslice subnets. Default 1')
3437 @click.option('--netslice-vlds',
3439 help='(NST) Number of netslice vlds. Default 1')
3441 def package_create(ctx
,
3457 Creates an OSM NS, VNF, NST package
3460 PACKAGE_TYPE: Package to be created: NS, VNF or NST.
3461 PACKAGE_NAME: Name of the package to create the folder with the content.
3465 check_client_version(ctx
.obj
, ctx
.command
.name
)
3466 print("Creating the {} structure: {}/{}".format(package_type
.upper(), base_directory
, package_name
))
3467 resp
= ctx
.obj
.package_tool
.create(package_type
,
3476 interfaces
=interfaces
,
3479 netslice_subnets
=netslice_subnets
,
3480 netslice_vlds
=netslice_vlds
)
3482 except ClientException
as inst
:
3483 print("ERROR: {}".format(inst
))
3486 @cli.command(name
='package-validate',
3487 short_help
='Validate a package descriptor')
3488 @click.argument('base-directory',
3492 def package_validate(ctx
,
3495 Validate descriptors given a base directory.
3498 BASE_DIRECTORY: Stub folder for NS, VNF or NST package.
3501 check_client_version(ctx
.obj
, ctx
.command
.name
)
3502 results
= ctx
.obj
.package_tool
.validate(base_directory
)
3503 table
= PrettyTable()
3504 table
.field_names
= ["TYPE", "PATH", "VALID", "ERROR"]
3505 # Print the dictionary generated by the validation function
3506 for result
in results
:
3507 table
.add_row([result
["type"], result
["path"], result
["valid"], result
["error"]])
3508 table
.sortby
= "VALID"
3509 table
.align
["PATH"] = "l"
3510 table
.align
["TYPE"] = "l"
3511 table
.align
["ERROR"] = "l"
3513 except ClientException
as inst
:
3514 print("ERROR: {}".format(inst
))
3517 @cli.command(name
='package-build',
3518 short_help
='Build the tar.gz of the package')
3519 @click.argument('package-folder')
3520 @click.option('--skip-validation',
3523 help='skip package validation')
3525 def package_build(ctx
,
3529 Build the package NS, VNF given the package_folder.
3532 PACKAGE_FOLDER: Folder of the NS, VNF or NST to be packaged
3535 check_client_version(ctx
.obj
, ctx
.command
.name
)
3536 results
= ctx
.obj
.package_tool
.build(package_folder
, skip_validation
)
3538 except ClientException
as inst
:
3539 print("ERROR: {}".format(inst
))
3543 if __name__
== '__main__':
3546 except pycurl
.error
as e
:
3548 print('Maybe "--hostname" option or OSM_HOSTNAME' +
3549 'environment variable needs to be specified')