1 # Copyright 2017-2018 Sandvine
2 # Copyright 2018 Telefonica
6 # Licensed under the Apache License, Version 2.0 (the "License"); you may
7 # not use this file except in compliance with the License. You may obtain
8 # a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 # License for the specific language governing permissions and limitations
22 from osmclient
import client
23 from osmclient
.common
.exceptions
import ClientException
24 from prettytable
import PrettyTable
34 def wrap_text(text
, width
):
35 wrapper
= textwrap
.TextWrapper(width
=width
)
36 lines
= text
.splitlines()
37 return "\n".join(map(wrapper
.fill
, lines
))
40 def trunc_text(text
, length
):
41 if len(text
) > length
:
42 return text
[:(length
- 3)] + '...'
47 def check_client_version(obj
, what
, version
='sol005'):
49 Checks the version of the client object and raises error if it not the expected.
51 :param obj: the client object
52 :what: the function or command under evaluation (used when an error is raised)
54 :raises ClientError: if the specified version does not match the client version
56 fullclassname
= obj
.__module
__ + "." + obj
.__class
__.__name
__
57 message
= 'The following commands or options are only supported with the option "--sol005": {}'.format(what
)
59 message
= 'The following commands or options are not supported when using option "--sol005": {}'.format(what
)
60 if fullclassname
!= 'osmclient.{}.client.Client'.format(version
):
61 raise ClientException(message
)
65 CONTEXT_SETTINGS
= dict(help_option_names
=['-h', '--help'], max_content_width
=160)
67 @click.group(context_settings
=CONTEXT_SETTINGS
)
68 @click.option('--hostname',
70 envvar
='OSM_HOSTNAME',
71 help='hostname of server. ' +
72 'Also can set OSM_HOSTNAME in environment')
73 #@click.option('--sol005/--no-sol005',
75 # envvar='OSM_SOL005',
76 # help='Use ETSI NFV SOL005 API (default) or the previous SO API. ' +
77 # 'Also can set OSM_SOL005 in environment')
78 @click.option('--user',
81 help='user (defaults to admin). ' +
82 'Also can set OSM_USER in environment')
83 @click.option('--password',
85 envvar
='OSM_PASSWORD',
86 help='password (defaults to admin). ' +
87 'Also can set OSM_PASSWORD in environment')
88 @click.option('--project',
91 help='project (defaults to admin). ' +
92 'Also can set OSM_PROJECT in environment')
93 #@click.option('--so-port',
95 # envvar='OSM_SO_PORT',
96 # help='hostname of server. ' +
97 # 'Also can set OSM_SO_PORT in environment')
98 #@click.option('--so-project',
100 # envvar='OSM_SO_PROJECT',
101 # help='Project Name in SO. ' +
102 # 'Also can set OSM_SO_PROJECT in environment')
103 #@click.option('--ro-hostname',
105 # envvar='OSM_RO_HOSTNAME',
106 # help='hostname of RO server. ' +
107 # 'Also can set OSM_RO_HOSTNAME in environment')
108 #@click.option('--ro-port',
110 # envvar='OSM_RO_PORT',
111 # help='hostname of RO server. ' +
112 # 'Also can set OSM_RO_PORT in environment')
114 def cli_osm(ctx
, hostname
, user
, password
, project
):
117 "either hostname option or OSM_HOSTNAME " +
118 "environment variable needs to be specified"))
121 # if so_port is not None:
122 # kwargs['so_port']=so_port
123 # if so_project is not None:
124 # kwargs['so_project']=so_project
125 # if ro_hostname is not None:
126 # kwargs['ro_host']=ro_hostname
127 # if ro_port is not None:
128 # kwargs['ro_port']=ro_port
129 sol005
= os
.getenv('OSM_SOL005', True)
132 if password
is not None:
133 kwargs
['password']=password
134 if project
is not None:
135 kwargs
['project']=project
136 ctx
.obj
= client
.Client(host
=hostname
, sol005
=sol005
, **kwargs
)
143 @cli_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.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_osm.command(name
='nsd-create', short_help
='creates a new NSD/NSpkg')
1103 @click.argument('filename')
1104 @click.option('--overwrite', 'overwrite', default
=None, hidden
=True,
1105 help='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_osm.command(name
='nspkg-create', short_help
='creates a new NSD/NSpkg')
1119 @click.argument('filename')
1120 @click.option('--overwrite', 'overwrite', default
=None, hidden
=True,
1121 help='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_osm.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_osm.command(name
='vnfpkg-create', short_help
='creates a new VNFD/VNFpkg')
1160 @click.argument('filename')
1161 @click.option('--overwrite', 'overwrite', default
=None, hidden
=True,
1162 help='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_osm.command(name
='nfpkg-create', short_help
='creates a new NFpkg')
1176 @click.argument('filename')
1177 @click.option('--overwrite', 'overwrite', default
=None, hidden
=True,
1178 help='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_osm.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_osm.command(name
='nst-create', short_help
='creates a new Network Slice Template (NST)')
1256 @click.argument('filename')
1257 @click.option('--overwrite', 'overwrite', default
=None, hidden
=True,
1258 help='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_osm.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, hidden
=True,
1274 help='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_osm.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_osm.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_osm.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,
1375 help='PDU descriptor file (as an alternative to using the other arguments')
1377 def pdu_create(ctx
, name
, pdu_type
, interface
, description
, vim_account
, descriptor_file
):
1378 """creates a new Physical Deployment Unit (PDU)"""
1380 check_client_version(ctx
.obj
, ctx
.command
.name
)
1382 if not descriptor_file
:
1384 raise ClientException('in absence of descriptor file, option "--name" is mandatory')
1386 raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory')
1388 raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)')
1390 raise ClientException('in absence of descriptor file, option "--vim_account" is mandatory (at least once)')
1392 with
open(descriptor_file
, 'r') as df
:
1393 pdu
= yaml
.safe_load(df
.read())
1394 if name
: pdu
["name"] = name
1395 if pdu_type
: pdu
["type"] = pdu_type
1396 if description
: pdu
["description"] = description
1397 if vim_account
: pdu
["vim_accounts"] = vim_account
1400 for iface
in interface
:
1401 new_iface
={k
:v
for k
,v
in [i
.split('=') for i
in iface
.split(',')]}
1402 new_iface
["mgmt"] = (new_iface
.get("mgmt","false").lower() == "true")
1403 ifaces_list
.append(new_iface
)
1404 pdu
["interfaces"] = ifaces_list
1405 ctx
.obj
.pdu
.create(pdu
)
1406 # except ClientException as e:
1410 ####################
1412 ####################
1414 def nsd_update(ctx
, name
, content
):
1416 check_client_version(ctx
.obj
, ctx
.command
.name
)
1417 ctx
.obj
.nsd
.update(name
, content
)
1418 # except ClientException as e:
1423 @cli_osm.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
1424 @click.argument('name')
1425 @click.option('--content', default
=None,
1426 help='filename with the NSD/NSpkg replacing the current one')
1428 def nsd_update1(ctx
, name
, content
):
1429 """updates a NSD/NSpkg
1431 NAME: name or ID of the NSD/NSpkg
1433 nsd_update(ctx
, name
, content
)
1436 @cli_osm.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
1437 @click.argument('name')
1438 @click.option('--content', default
=None,
1439 help='filename with the NSD/NSpkg replacing the current one')
1441 def nsd_update2(ctx
, name
, content
):
1442 """updates a NSD/NSpkg
1444 NAME: name or ID of the NSD/NSpkg
1446 nsd_update(ctx
, name
, content
)
1449 def vnfd_update(ctx
, name
, content
):
1451 check_client_version(ctx
.obj
, ctx
.command
.name
)
1452 ctx
.obj
.vnfd
.update(name
, content
)
1453 # except ClientException as e:
1458 @cli_osm.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
1459 @click.argument('name')
1460 @click.option('--content', default
=None,
1461 help='filename with the VNFD/VNFpkg replacing the current one')
1463 def vnfd_update1(ctx
, name
, content
):
1464 """updates a VNFD/VNFpkg
1466 NAME: name or ID of the VNFD/VNFpkg
1468 vnfd_update(ctx
, name
, content
)
1471 @cli_osm.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
1472 @click.argument('name')
1473 @click.option('--content', default
=None,
1474 help='filename with the VNFD/VNFpkg replacing the current one')
1476 def vnfd_update2(ctx
, name
, content
):
1477 """updates a VNFD/VNFpkg
1479 NAME: VNFD yaml file or VNFpkg tar.gz file
1481 vnfd_update(ctx
, name
, content
)
1484 @cli_osm.command(name
='nfpkg-update', short_help
='updates a NFpkg')
1485 @click.argument('name')
1486 @click.option('--content', default
=None,
1487 help='filename with the NFpkg replacing the current one')
1489 def nfpkg_update(ctx
, name
, content
):
1492 NAME: NF Descriptor yaml file or NFpkg tar.gz file
1494 vnfd_update(ctx
, name
, content
)
1497 def nst_update(ctx
, name
, content
):
1499 check_client_version(ctx
.obj
, ctx
.command
.name
)
1500 ctx
.obj
.nst
.update(name
, content
)
1501 # except ClientException as e:
1506 @cli_osm.command(name
='nst-update', short_help
='updates a Network Slice Template (NST)')
1507 @click.argument('name')
1508 @click.option('--content', default
=None,
1509 help='filename with the NST/NSTpkg replacing the current one')
1511 def nst_update1(ctx
, name
, content
):
1512 """updates a Network Slice Template (NST)
1514 NAME: name or ID of the NSD/NSpkg
1516 nst_update(ctx
, name
, content
)
1519 @cli_osm.command(name
='netslice-template-update', short_help
='updates a Network Slice Template (NST)')
1520 @click.argument('name')
1521 @click.option('--content', default
=None,
1522 help='filename with the NST/NSTpkg replacing the current one')
1524 def nst_update2(ctx
, name
, content
):
1525 """updates a Network Slice Template (NST)
1527 NAME: name or ID of the NSD/NSpkg
1529 nst_update(ctx
, name
, content
)
1532 ####################
1534 ####################
1536 def nsd_delete(ctx
, name
, force
):
1539 ctx
.obj
.nsd
.delete(name
)
1541 check_client_version(ctx
.obj
, '--force')
1542 ctx
.obj
.nsd
.delete(name
, force
)
1543 # except ClientException as e:
1548 @cli_osm.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
1549 @click.argument('name')
1550 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1552 def nsd_delete1(ctx
, name
, force
):
1553 """deletes a NSD/NSpkg
1555 NAME: name or ID of the NSD/NSpkg to be deleted
1557 nsd_delete(ctx
, name
, force
)
1560 @cli_osm.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
1561 @click.argument('name')
1562 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1564 def nsd_delete2(ctx
, name
, force
):
1565 """deletes a NSD/NSpkg
1567 NAME: name or ID of the NSD/NSpkg to be deleted
1569 nsd_delete(ctx
, name
, force
)
1572 def vnfd_delete(ctx
, name
, force
):
1575 ctx
.obj
.vnfd
.delete(name
)
1577 check_client_version(ctx
.obj
, '--force')
1578 ctx
.obj
.vnfd
.delete(name
, force
)
1579 # except ClientException as e:
1584 @cli_osm.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
1585 @click.argument('name')
1586 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1588 def vnfd_delete1(ctx
, name
, force
):
1589 """deletes a VNFD/VNFpkg
1591 NAME: name or ID of the VNFD/VNFpkg to be deleted
1593 vnfd_delete(ctx
, name
, force
)
1596 @cli_osm.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
1597 @click.argument('name')
1598 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1600 def vnfd_delete2(ctx
, name
, force
):
1601 """deletes a VNFD/VNFpkg
1603 NAME: name or ID of the VNFD/VNFpkg to be deleted
1605 vnfd_delete(ctx
, name
, force
)
1608 @cli_osm.command(name
='nfpkg-delete', short_help
='deletes a NFpkg')
1609 @click.argument('name')
1610 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1612 def nfpkg_delete(ctx
, name
, force
):
1615 NAME: name or ID of the NFpkg to be deleted
1617 vnfd_delete(ctx
, name
, force
)
1620 @cli_osm.command(name
='ns-delete', short_help
='deletes a NS instance')
1621 @click.argument('name')
1622 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1623 @click.option('--wait',
1627 help='do not return the control immediately, but keep it '
1628 'until the operation is completed, or timeout')
1630 def ns_delete(ctx
, name
, force
, wait
):
1631 """deletes a NS instance
1633 NAME: name or ID of the NS instance to be deleted
1637 ctx
.obj
.ns
.delete(name
, wait
=wait
)
1639 check_client_version(ctx
.obj
, '--force')
1640 ctx
.obj
.ns
.delete(name
, force
, wait
=wait
)
1641 # except ClientException as e:
1646 def nst_delete(ctx
, name
, force
):
1648 check_client_version(ctx
.obj
, ctx
.command
.name
)
1649 ctx
.obj
.nst
.delete(name
, force
)
1650 # except ClientException as e:
1655 @cli_osm.command(name
='nst-delete', short_help
='deletes a Network Slice Template (NST)')
1656 @click.argument('name')
1657 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1659 def nst_delete1(ctx
, name
, force
):
1660 """deletes a Network Slice Template (NST)
1662 NAME: name or ID of the NST/NSTpkg to be deleted
1664 nst_delete(ctx
, name
, force
)
1667 @cli_osm.command(name
='netslice-template-delete', short_help
='deletes a Network Slice Template (NST)')
1668 @click.argument('name')
1669 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1671 def nst_delete2(ctx
, name
, force
):
1672 """deletes a Network Slice Template (NST)
1674 NAME: name or ID of the NST/NSTpkg to be deleted
1676 nst_delete(ctx
, name
, force
)
1679 def nsi_delete(ctx
, name
, force
, wait
):
1681 check_client_version(ctx
.obj
, ctx
.command
.name
)
1682 ctx
.obj
.nsi
.delete(name
, force
, wait
=wait
)
1683 # except ClientException as e:
1688 @cli_osm.command(name
='nsi-delete', short_help
='deletes a Network Slice Instance (NSI)')
1689 @click.argument('name')
1690 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1691 @click.option('--wait',
1695 help='do not return the control immediately, but keep it '
1696 'until the operation is completed, or timeout')
1698 def nsi_delete1(ctx
, name
, force
, wait
):
1699 """deletes a Network Slice Instance (NSI)
1701 NAME: name or ID of the Network Slice instance to be deleted
1703 nsi_delete(ctx
, name
, force
, wait
=wait
)
1706 @cli_osm.command(name
='netslice-instance-delete', short_help
='deletes a Network Slice Instance (NSI)')
1707 @click.argument('name')
1708 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1710 def nsi_delete2(ctx
, name
, force
, wait
):
1711 """deletes a Network Slice Instance (NSI)
1713 NAME: name or ID of the Network Slice instance to be deleted
1715 nsi_delete(ctx
, name
, force
, wait
=wait
)
1718 @cli_osm.command(name
='pdu-delete', short_help
='deletes a Physical Deployment Unit (PDU)')
1719 @click.argument('name')
1720 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1722 def pdu_delete(ctx
, name
, force
):
1723 """deletes a Physical Deployment Unit (PDU)
1725 NAME: name or ID of the PDU to be deleted
1728 check_client_version(ctx
.obj
, ctx
.command
.name
)
1729 ctx
.obj
.pdu
.delete(name
, force
)
1730 # except ClientException as e:
1739 @cli_osm.command(name
='vim-create', short_help
='creates a new VIM account')
1740 @click.option('--name',
1742 help='Name to create datacenter')
1743 @click.option('--user',
1745 help='VIM username')
1746 @click.option('--password',
1749 confirmation_prompt
=True,
1750 help='VIM password')
1751 @click.option('--auth_url',
1754 @click.option('--tenant',
1756 help='VIM tenant name')
1757 @click.option('--config',
1759 help='VIM specific config parameters')
1760 @click.option('--account_type',
1761 default
='openstack',
1763 @click.option('--description',
1764 default
='no description',
1765 help='human readable description')
1766 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
1767 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1768 @click.option('--wait',
1772 help='do not return the control immediately, but keep it '
1773 'until the operation is completed, or timeout')
1787 """creates a new VIM account"""
1790 check_client_version(ctx
.obj
, '--sdn_controller')
1791 if sdn_port_mapping
:
1792 check_client_version(ctx
.obj
, '--sdn_port_mapping')
1794 vim
['vim-username'] = user
1795 vim
['vim-password'] = password
1796 vim
['vim-url'] = auth_url
1797 vim
['vim-tenant-name'] = tenant
1798 vim
['vim-type'] = account_type
1799 vim
['description'] = description
1800 vim
['config'] = config
1801 if sdn_controller
or sdn_port_mapping
:
1802 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
1804 ctx
.obj
.vim
.create(name
, vim
, wait
=wait
)
1805 # except ClientException as e:
1810 @cli_osm.command(name
='vim-update', short_help
='updates a VIM account')
1811 @click.argument('name')
1812 @click.option('--newname', help='New name for the VIM account')
1813 @click.option('--user', help='VIM username')
1814 @click.option('--password', help='VIM password')
1815 @click.option('--auth_url', help='VIM url')
1816 @click.option('--tenant', help='VIM tenant name')
1817 @click.option('--config', help='VIM specific config parameters')
1818 @click.option('--account_type', help='VIM type')
1819 @click.option('--description', help='human readable description')
1820 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
1821 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1822 @click.option('--wait',
1826 help='do not return the control immediately, but keep it '
1827 'until the operation is completed, or timeout')
1842 """updates a VIM account
1844 NAME: name or ID of the VIM account
1847 check_client_version(ctx
.obj
, ctx
.command
.name
)
1849 if newname
: vim
['name'] = newname
1850 if user
: vim
['vim_user'] = user
1851 if password
: vim
['vim_password'] = password
1852 if auth_url
: vim
['vim_url'] = auth_url
1853 if tenant
: vim
['vim-tenant-name'] = tenant
1854 if account_type
: vim
['vim_type'] = account_type
1855 if description
: vim
['description'] = description
1856 if config
: vim
['config'] = config
1857 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
1858 # except ClientException as e:
1863 @cli_osm.command(name
='vim-delete', short_help
='deletes a VIM account')
1864 @click.argument('name')
1865 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1866 @click.option('--wait',
1870 help='do not return the control immediately, but keep it '
1871 'until the operation is completed, or timeout')
1873 def vim_delete(ctx
, name
, force
, wait
):
1874 """deletes a VIM account
1876 NAME: name or ID of the VIM account to be deleted
1880 ctx
.obj
.vim
.delete(name
, wait
=wait
)
1882 check_client_version(ctx
.obj
, '--force')
1883 ctx
.obj
.vim
.delete(name
, force
, wait
=wait
)
1884 # except ClientException as e:
1889 @cli_osm.command(name
='vim-list', short_help
='list all VIM accounts')
1890 #@click.option('--ro_update/--no_ro_update',
1892 # help='update list from RO')
1893 @click.option('--filter', default
=None,
1894 help='restricts the list to the VIM accounts matching the filter')
1896 def vim_list(ctx
, filter):
1897 """list all VIM accounts"""
1899 check_client_version(ctx
.obj
, '--filter')
1901 # check_client_version(ctx.obj, '--ro_update', 'v1')
1902 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1903 if fullclassname
== 'osmclient.sol005.client.Client':
1904 resp
= ctx
.obj
.vim
.list(filter)
1906 # resp = ctx.obj.vim.list(ro_update)
1907 table
= PrettyTable(['vim name', 'uuid'])
1909 table
.add_row([vim
['name'], vim
['uuid']])
1914 @cli_osm.command(name
='vim-show', short_help
='shows the details of a VIM account')
1915 @click.argument('name')
1917 def vim_show(ctx
, name
):
1918 """shows the details of a VIM account
1920 NAME: name or ID of the VIM account
1923 resp
= ctx
.obj
.vim
.get(name
)
1924 if 'vim_password' in resp
:
1925 resp
['vim_password']='********'
1926 # except ClientException as e:
1930 table
= PrettyTable(['key', 'attribute'])
1931 for k
, v
in list(resp
.items()):
1932 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
1937 ####################
1939 ####################
1941 @cli_osm.command(name
='wim-create', short_help
='creates a new WIM account')
1942 @click.option('--name',
1944 help='Name for the WIM account')
1945 @click.option('--user',
1946 help='WIM username')
1947 @click.option('--password',
1948 help='WIM password')
1949 @click.option('--url',
1952 # @click.option('--tenant',
1953 # help='wIM tenant name')
1954 @click.option('--config',
1956 help='WIM specific config parameters')
1957 @click.option('--wim_type',
1959 @click.option('--description',
1960 default
='no description',
1961 help='human readable description')
1962 @click.option('--wim_port_mapping', default
=None,
1963 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
1964 "(WAN service endpoint id and info)")
1965 @click.option('--wait',
1969 help='do not return the control immediately, but keep it '
1970 'until the operation is completed, or timeout')
1983 """creates a new WIM account"""
1985 check_client_version(ctx
.obj
, ctx
.command
.name
)
1986 # if sdn_controller:
1987 # check_client_version(ctx.obj, '--sdn_controller')
1988 # if sdn_port_mapping:
1989 # check_client_version(ctx.obj, '--sdn_port_mapping')
1991 if user
: wim
['user'] = user
1992 if password
: wim
['password'] = password
1993 if url
: wim
['wim_url'] = url
1994 # if tenant: wim['tenant'] = tenant
1995 wim
['wim_type'] = wim_type
1996 if description
: wim
['description'] = description
1997 if config
: wim
['config'] = config
1998 ctx
.obj
.wim
.create(name
, wim
, wim_port_mapping
, wait
=wait
)
1999 # except ClientException as e:
2004 @cli_osm.command(name
='wim-update', short_help
='updates a WIM account')
2005 @click.argument('name')
2006 @click.option('--newname', help='New name for the WIM account')
2007 @click.option('--user', help='WIM username')
2008 @click.option('--password', help='WIM password')
2009 @click.option('--url', help='WIM url')
2010 @click.option('--config', help='WIM specific config parameters')
2011 @click.option('--wim_type', help='WIM type')
2012 @click.option('--description', help='human readable description')
2013 @click.option('--wim_port_mapping', default
=None,
2014 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2015 "(WAN service endpoint id and info)")
2016 @click.option('--wait',
2020 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2033 """updates a WIM account
2035 NAME: name or ID of the WIM account
2038 check_client_version(ctx
.obj
, ctx
.command
.name
)
2040 if newname
: wim
['name'] = newname
2041 if user
: wim
['user'] = user
2042 if password
: wim
['password'] = password
2043 if url
: wim
['url'] = url
2044 # if tenant: wim['tenant'] = tenant
2045 if wim_type
: wim
['wim_type'] = wim_type
2046 if description
: wim
['description'] = description
2047 if config
: wim
['config'] = config
2048 ctx
.obj
.wim
.update(name
, wim
, wim_port_mapping
, wait
=wait
)
2049 # except ClientException as e:
2054 @cli_osm.command(name
='wim-delete', short_help
='deletes a WIM account')
2055 @click.argument('name')
2056 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2057 @click.option('--wait',
2061 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2063 def wim_delete(ctx
, name
, force
, wait
):
2064 """deletes a WIM account
2066 NAME: name or ID of the WIM account to be deleted
2069 check_client_version(ctx
.obj
, ctx
.command
.name
)
2070 ctx
.obj
.wim
.delete(name
, force
, wait
=wait
)
2071 # except ClientException as e:
2076 @cli_osm.command(name
='wim-list', short_help
='list all WIM accounts')
2077 @click.option('--filter', default
=None,
2078 help='restricts the list to the WIM accounts matching the filter')
2080 def wim_list(ctx
, filter):
2081 """list all WIM accounts"""
2083 check_client_version(ctx
.obj
, ctx
.command
.name
)
2084 resp
= ctx
.obj
.wim
.list(filter)
2085 table
= PrettyTable(['wim name', 'uuid'])
2087 table
.add_row([wim
['name'], wim
['uuid']])
2090 # except ClientException as e:
2095 @cli_osm.command(name
='wim-show', short_help
='shows the details of a WIM account')
2096 @click.argument('name')
2098 def wim_show(ctx
, name
):
2099 """shows the details of a WIM account
2101 NAME: name or ID of the WIM account
2104 check_client_version(ctx
.obj
, ctx
.command
.name
)
2105 resp
= ctx
.obj
.wim
.get(name
)
2106 if 'password' in resp
:
2107 resp
['wim_password']='********'
2108 # except ClientException as e:
2112 table
= PrettyTable(['key', 'attribute'])
2113 for k
, v
in list(resp
.items()):
2114 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2119 ####################
2120 # SDN controller operations
2121 ####################
2123 @cli_osm.command(name
='sdnc-create', short_help
='creates a new SDN controller')
2124 @click.option('--name',
2126 help='Name to create sdn controller')
2127 @click.option('--type',
2129 help='SDN controller type')
2130 @click.option('--sdn_controller_version', hidden
=True,
2131 help='Deprecated. Use --config {version: sdn_controller_version}')
2132 @click.option('--url',
2133 help='URL in format http[s]://HOST:IP/')
2134 @click.option('--ip_address', hidden
=True,
2135 help='Deprecated. Use --url')
2136 @click.option('--port', hidden
=True,
2137 help='Deprecated. Use --url')
2138 @click.option('--switch_dpid', hidden
=True,
2139 help='Deprecated. Use --config {dpid: DPID}')
2140 @click.option('--config',
2141 help='Extra information for SDN in yaml format, as {dpid: (Openflow Datapath ID), version: version}')
2142 @click.option('--user',
2143 help='SDN controller username')
2144 @click.option('--password',
2146 confirmation_prompt
=True,
2147 help='SDN controller password')
2148 @click.option('--description', default
=None, help='human readable description')
2149 @click.option('--wait',
2153 help="do not return the control immediately, but keep it until the operation is completed, or timeout")
2155 def sdnc_create(ctx
, **kwargs
):
2156 """creates a new SDN controller"""
2157 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2158 x
not in ("wait", "ip_address", "port", "switch_dpid")}
2159 if kwargs
.get("port"):
2160 print("option '--port' is deprecated, use '-url' instead")
2161 sdncontroller
["port"] = int(kwargs
["port"])
2162 if kwargs
.get("ip_address"):
2163 print("option '--ip_address' is deprecated, use '-url' instead")
2164 sdncontroller
["ip"] = kwargs
["ip_address"]
2165 if kwargs
.get("switch_dpid"):
2166 print("option '--switch_dpid' is deprecated, use '---config={dpid: DPID}' instead")
2167 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2168 if kwargs
.get("sdn_controller_version"):
2169 print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'"
2172 check_client_version(ctx
.obj
, ctx
.command
.name
)
2173 ctx
.obj
.sdnc
.create(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2174 # except ClientException as e:
2178 @cli_osm.command(name
='sdnc-update', short_help
='updates an SDN controller')
2179 @click.argument('name')
2180 @click.option('--newname', help='New name for the SDN controller')
2181 @click.option('--description', default
=None, help='human readable description')
2182 @click.option('--type', help='SDN controller type')
2183 @click.option('--url', help='URL in format http[s]://HOST:IP/')
2184 @click.option('--config', help='Extra information for SDN in yaml format, as '
2185 '{dpid: (Openflow Datapath ID), version: version}')
2186 @click.option('--user', help='SDN controller username')
2187 @click.option('--password', help='SDN controller password')
2188 @click.option('--ip_address', hidden
=True, help='Deprecated. Use --url')
2189 @click.option('--port', hidden
=True, help='Deprecated. Use --url')
2190 @click.option('--switch_dpid', hidden
=True, help='Deprecated. Use --config {switch_dpid: DPID}')
2191 @click.option('--sdn_controller_version', hidden
=True, help='Deprecated. Use --config {version: VERSION}')
2192 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2193 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2195 def sdnc_update(ctx
, **kwargs
):
2196 """updates an SDN controller
2198 NAME: name or ID of the SDN controller
2200 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2201 x
not in ("wait", "ip_address", "port", "switch_dpid", "new_name")}
2202 if kwargs
.get("newname"):
2203 sdncontroller
["name"] = kwargs
["newname"]
2204 if kwargs
.get("port"):
2205 print("option '--port' is deprecated, use '-url' instead")
2206 sdncontroller
["port"] = int(kwargs
["port"])
2207 if kwargs
.get("ip_address"):
2208 print("option '--ip_address' is deprecated, use '-url' instead")
2209 sdncontroller
["ip"] = kwargs
["ip_address"]
2210 if kwargs
.get("switch_dpid"):
2211 print("option '--switch_dpid' is deprecated, use '---config={dpid: DPID}' instead")
2212 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2213 if kwargs
.get("sdn_controller_version"):
2214 print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'"
2218 check_client_version(ctx
.obj
, ctx
.command
.name
)
2219 ctx
.obj
.sdnc
.update(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2220 # except ClientException as e:
2225 @cli_osm.command(name
='sdnc-delete', short_help
='deletes an SDN controller')
2226 @click.argument('name')
2227 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2228 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2229 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2231 def sdnc_delete(ctx
, name
, force
, wait
):
2232 """deletes an SDN controller
2234 NAME: name or ID of the SDN controller to be deleted
2237 check_client_version(ctx
.obj
, ctx
.command
.name
)
2238 ctx
.obj
.sdnc
.delete(name
, force
, wait
=wait
)
2239 # except ClientException as e:
2244 @cli_osm.command(name
='sdnc-list', short_help
='list all SDN controllers')
2245 @click.option('--filter', default
=None,
2246 help="restricts the list to the SDN controllers matching the filter with format: 'k[.k..]=v[&k[.k]=v2]'")
2248 def sdnc_list(ctx
, filter):
2249 """list all SDN controllers"""
2251 check_client_version(ctx
.obj
, ctx
.command
.name
)
2252 resp
= ctx
.obj
.sdnc
.list(filter)
2253 # except ClientException as e:
2256 table
= PrettyTable(['sdnc name', 'id'])
2258 table
.add_row([sdnc
['name'], sdnc
['_id']])
2263 @cli_osm.command(name
='sdnc-show', short_help
='shows the details of an SDN controller')
2264 @click.argument('name')
2266 def sdnc_show(ctx
, name
):
2267 """shows the details of an SDN controller
2269 NAME: name or ID of the SDN controller
2272 check_client_version(ctx
.obj
, ctx
.command
.name
)
2273 resp
= ctx
.obj
.sdnc
.get(name
)
2274 # except ClientException as e:
2278 table
= PrettyTable(['key', 'attribute'])
2279 for k
, v
in list(resp
.items()):
2280 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2285 ###########################
2286 # K8s cluster operations
2287 ###########################
2289 @cli_osm.command(name
='k8scluster-add')
2290 @click.argument('name')
2291 @click.option('--creds',
2293 help='credentials file, i.e. a valid `.kube/config` file')
2294 @click.option('--version',
2296 help='Kubernetes version')
2297 @click.option('--vim',
2299 help='VIM target, the VIM where the cluster resides')
2300 @click.option('--k8s-nets',
2302 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) ...]}"')
2303 @click.option('--description',
2305 help='human readable description')
2306 @click.option('--namespace',
2307 default
='kube-system',
2308 help='namespace to be used for its operation, defaults to `kube-system`')
2309 @click.option('--cni',
2311 help='list of CNI plugins, in JSON inline format, used in the cluster')
2312 #@click.option('--skip-init',
2314 # help='If set, K8s cluster is assumed to be ready for its use with OSM')
2315 #@click.option('--wait',
2317 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2319 def k8scluster_add(ctx
,
2328 """adds a K8s cluster to OSM
2330 NAME: name of the K8s cluster
2333 check_client_version(ctx
.obj
, ctx
.command
.name
)
2335 cluster
['name'] = name
2336 with
open(creds
, 'r') as cf
:
2337 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2338 cluster
['k8s_version'] = version
2339 cluster
['vim_account'] = vim
2340 cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2341 cluster
['description'] = description
2342 if namespace
: cluster
['namespace'] = namespace
2343 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2344 ctx
.obj
.k8scluster
.create(name
, cluster
)
2345 # except ClientException as e:
2350 @cli_osm.command(name
='k8scluster-update', short_help
='updates a K8s cluster')
2351 @click.argument('name')
2352 @click.option('--newname', help='New name for the K8s cluster')
2353 @click.option('--creds', help='credentials file, i.e. a valid `.kube/config` file')
2354 @click.option('--version', help='Kubernetes version')
2355 @click.option('--vim', help='VIM target, the VIM where the cluster resides')
2356 @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) ...]}"')
2357 @click.option('--description', help='human readable description')
2358 @click.option('--namespace', help='namespace to be used for its operation, defaults to `kube-system`')
2359 @click.option('--cni', help='list of CNI plugins, in JSON inline format, used in the cluster')
2361 def k8scluster_update(ctx
,
2371 """updates a K8s cluster
2373 NAME: name or ID of the K8s cluster
2376 check_client_version(ctx
.obj
, ctx
.command
.name
)
2378 if newname
: cluster
['name'] = newname
2380 with
open(creds
, 'r') as cf
:
2381 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2382 if version
: cluster
['k8s_version'] = version
2383 if vim
: cluster
['vim_account'] = vim
2384 if k8s_nets
: cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2385 if description
: cluster
['description'] = description
2386 if namespace
: cluster
['namespace'] = namespace
2387 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2388 ctx
.obj
.k8scluster
.update(name
, cluster
)
2389 # except ClientException as e:
2394 @cli_osm.command(name
='k8scluster-delete')
2395 @click.argument('name')
2396 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2397 #@click.option('--wait',
2399 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2401 def k8scluster_delete(ctx
, name
, force
):
2402 """deletes a K8s cluster
2404 NAME: name or ID of the K8s cluster to be deleted
2407 check_client_version(ctx
.obj
, ctx
.command
.name
)
2408 ctx
.obj
.k8scluster
.delete(name
, force
=force
)
2409 # except ClientException as e:
2414 @cli_osm.command(name
='k8scluster-list')
2415 @click.option('--filter', default
=None,
2416 help='restricts the list to the K8s clusters matching the filter')
2417 @click.option('--literal', is_flag
=True,
2418 help='print literally, no pretty table')
2420 def k8scluster_list(ctx
, filter, literal
):
2421 """list all K8s clusters"""
2423 check_client_version(ctx
.obj
, ctx
.command
.name
)
2424 resp
= ctx
.obj
.k8scluster
.list(filter)
2426 print(yaml
.safe_dump(resp
))
2428 table
= PrettyTable(['Name', 'Id', 'Version', 'VIM', 'K8s-nets', 'Operational State', 'Description'])
2429 for cluster
in resp
:
2430 table
.add_row([cluster
['name'], cluster
['_id'], cluster
['k8s_version'], cluster
['vim_account'],
2431 json
.dumps(cluster
['nets']), cluster
["_admin"]["operationalState"],
2432 trunc_text(cluster
.get('description',''),40)])
2435 # except ClientException as e:
2440 @cli_osm.command(name
='k8scluster-show')
2441 @click.argument('name')
2442 @click.option('--literal', is_flag
=True,
2443 help='print literally, no pretty table')
2445 def k8scluster_show(ctx
, name
, literal
):
2446 """shows the details of a K8s cluster
2448 NAME: name or ID of the K8s cluster
2451 resp
= ctx
.obj
.k8scluster
.get(name
)
2453 print(yaml
.safe_dump(resp
))
2455 table
= PrettyTable(['key', 'attribute'])
2456 for k
, v
in list(resp
.items()):
2457 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2460 # except ClientException as e:
2466 ###########################
2468 ###########################
2470 @cli_osm.command(name
='repo-add')
2471 @click.argument('name')
2472 @click.argument('uri')
2473 @click.option('--type',
2474 type=click
.Choice(['helm-chart', 'juju-bundle']),
2476 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2477 @click.option('--description',
2479 help='human readable description')
2480 #@click.option('--wait',
2482 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2489 """adds a repo to OSM
2491 NAME: name of the repo
2492 URI: URI of the repo
2495 check_client_version(ctx
.obj
, ctx
.command
.name
)
2500 repo
['description'] = description
2501 ctx
.obj
.repo
.create(name
, repo
)
2502 # except ClientException as e:
2507 @cli_osm.command(name
='repo-update')
2508 @click.argument('name')
2509 @click.option('--newname', help='New name for the repo')
2510 @click.option('--uri', help='URI of the repo')
2511 @click.option('--type', type=click
.Choice(['helm-chart', 'juju-bundle']),
2512 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2513 @click.option('--description', help='human readable description')
2514 #@click.option('--wait',
2516 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2518 def repo_update(ctx
,
2524 """updates a repo in OSM
2526 NAME: name of the repo
2529 check_client_version(ctx
.obj
, ctx
.command
.name
)
2531 if newname
: repo
['name'] = newname
2532 if uri
: repo
['uri'] = uri
2533 if type: repo
['type'] = type
2534 if description
: repo
['description'] = description
2535 ctx
.obj
.repo
.update(name
, repo
)
2536 # except ClientException as e:
2541 @cli_osm.command(name
='repo-delete')
2542 @click.argument('name')
2543 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2544 #@click.option('--wait',
2546 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2548 def repo_delete(ctx
, name
, force
):
2551 NAME: name or ID of the repo to be deleted
2554 check_client_version(ctx
.obj
, ctx
.command
.name
)
2555 ctx
.obj
.repo
.delete(name
, force
=force
)
2556 # except ClientException as e:
2561 @cli_osm.command(name
='repo-list')
2562 @click.option('--filter', default
=None,
2563 help='restricts the list to the repos matching the filter')
2564 @click.option('--literal', is_flag
=True,
2565 help='print literally, no pretty table')
2567 def repo_list(ctx
, filter, literal
):
2568 """list all repos"""
2570 check_client_version(ctx
.obj
, ctx
.command
.name
)
2571 resp
= ctx
.obj
.repo
.list(filter)
2573 print(yaml
.safe_dump(resp
))
2575 table
= PrettyTable(['Name', 'Id', 'Type', 'URI', 'Description'])
2577 #cluster['k8s-nets'] = json.dumps(yaml.safe_load(cluster['k8s-nets']))
2578 table
.add_row([repo
['name'], repo
['_id'], repo
['type'], repo
['url'], trunc_text(repo
.get('description',''),40)])
2581 # except ClientException as e:
2586 @cli_osm.command(name
='repo-show')
2587 @click.argument('name')
2588 @click.option('--literal', is_flag
=True,
2589 help='print literally, no pretty table')
2591 def repo_show(ctx
, name
, literal
):
2592 """shows the details of a repo
2594 NAME: name or ID of the repo
2597 resp
= ctx
.obj
.repo
.get(name
)
2599 print(yaml
.safe_dump(resp
))
2601 table
= PrettyTable(['key', 'attribute'])
2602 for k
, v
in list(resp
.items()):
2603 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2606 # except ClientException as e:
2612 ####################
2613 # Project mgmt operations
2614 ####################
2616 @cli_osm.command(name
='project-create', short_help
='creates a new project')
2617 @click.argument('name')
2618 #@click.option('--description',
2619 # default='no description',
2620 # help='human readable description')
2622 def project_create(ctx
, name
):
2623 """Creates a new project
2625 NAME: name of the project
2628 project
['name'] = name
2630 check_client_version(ctx
.obj
, ctx
.command
.name
)
2631 ctx
.obj
.project
.create(name
, project
)
2632 # except ClientException as e:
2637 @cli_osm.command(name
='project-delete', short_help
='deletes a project')
2638 @click.argument('name')
2639 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2641 def project_delete(ctx
, name
):
2642 """deletes a project
2644 NAME: name or ID of the project to be deleted
2647 check_client_version(ctx
.obj
, ctx
.command
.name
)
2648 ctx
.obj
.project
.delete(name
)
2649 # except ClientException as e:
2654 @cli_osm.command(name
='project-list', short_help
='list all projects')
2655 @click.option('--filter', default
=None,
2656 help='restricts the list to the projects matching the filter')
2658 def project_list(ctx
, filter):
2659 """list all projects"""
2661 check_client_version(ctx
.obj
, ctx
.command
.name
)
2662 resp
= ctx
.obj
.project
.list(filter)
2663 # except ClientException as e:
2666 table
= PrettyTable(['name', 'id'])
2668 table
.add_row([proj
['name'], proj
['_id']])
2673 @cli_osm.command(name
='project-show', short_help
='shows the details of a project')
2674 @click.argument('name')
2676 def project_show(ctx
, name
):
2677 """shows the details of a project
2679 NAME: name or ID of the project
2682 check_client_version(ctx
.obj
, ctx
.command
.name
)
2683 resp
= ctx
.obj
.project
.get(name
)
2684 # except ClientException as e:
2688 table
= PrettyTable(['key', 'attribute'])
2689 for k
, v
in resp
.items():
2690 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2695 @cli_osm.command(name
='project-update', short_help
='updates a project (only the name can be updated)')
2696 @click.argument('project')
2697 @click.option('--name',
2699 help='new name for the project')
2702 def project_update(ctx
, project
, name
):
2704 Update a project name
2707 :param project: id or name of the project to modify
2708 :param name: new name for the project
2712 project_changes
= {}
2713 project_changes
['name'] = name
2716 check_client_version(ctx
.obj
, ctx
.command
.name
)
2717 ctx
.obj
.project
.update(project
, project_changes
)
2718 # except ClientException as e:
2722 ####################
2723 # User mgmt operations
2724 ####################
2726 @cli_osm.command(name
='user-create', short_help
='creates a new user')
2727 @click.argument('username')
2728 @click.option('--password',
2731 confirmation_prompt
=True,
2732 help='user password')
2733 @click.option('--projects',
2734 # prompt="Comma separate list of projects",
2736 callback
=lambda ctx
, param
, value
: ''.join(value
).split(',') if all(len(x
)==1 for x
in value
) else value
,
2737 help='list of project ids that the user belongs to')
2738 @click.option('--project-role-mappings', 'project_role_mappings',
2739 default
=None, multiple
=True,
2740 help='creating user project/role(s) mapping')
2742 def user_create(ctx
, username
, password
, projects
, project_role_mappings
):
2743 """Creates a new user
2746 USERNAME: name of the user
2747 PASSWORD: password of the user
2748 PROJECTS: projects assigned to user (internal only)
2749 PROJECT_ROLE_MAPPING: roles in projects assigned to user (keystone)
2752 user
['username'] = username
2753 user
['password'] = password
2754 user
['projects'] = projects
2755 user
['project_role_mappings'] = project_role_mappings
2758 check_client_version(ctx
.obj
, ctx
.command
.name
)
2759 ctx
.obj
.user
.create(username
, user
)
2760 # except ClientException as e:
2765 @cli_osm.command(name
='user-update', short_help
='updates user information')
2766 @click.argument('username')
2767 @click.option('--password',
2770 # confirmation_prompt=True,
2771 help='user password')
2772 @click.option('--set-username', 'set_username',
2774 help='change username')
2775 @click.option('--set-project', 'set_project',
2776 default
=None, multiple
=True,
2777 help='create/replace the project,role(s) mapping for this project: \'project,role1,role2,...\'')
2778 @click.option('--remove-project', 'remove_project',
2779 default
=None, multiple
=True,
2780 help='removes project from user: \'project\'')
2781 @click.option('--add-project-role', 'add_project_role',
2782 default
=None, multiple
=True,
2783 help='adds project,role(s) mapping: \'project,role1,role2,...\'')
2784 @click.option('--remove-project-role', 'remove_project_role',
2785 default
=None, multiple
=True,
2786 help='removes project,role(s) mapping: \'project,role1,role2,...\'')
2788 def user_update(ctx
, username
, password
, set_username
, set_project
, remove_project
,
2789 add_project_role
, remove_project_role
):
2790 """Update a user information
2793 USERNAME: name of the user
2794 PASSWORD: new password
2795 SET_USERNAME: new username
2796 SET_PROJECT: creating mappings for project/role(s)
2797 REMOVE_PROJECT: deleting mappings for project/role(s)
2798 ADD_PROJECT_ROLE: adding mappings for project/role(s)
2799 REMOVE_PROJECT_ROLE: removing mappings for project/role(s)
2802 user
['password'] = password
2803 user
['username'] = set_username
2804 user
['set-project'] = set_project
2805 user
['remove-project'] = remove_project
2806 user
['add-project-role'] = add_project_role
2807 user
['remove-project-role'] = remove_project_role
2810 check_client_version(ctx
.obj
, ctx
.command
.name
)
2811 ctx
.obj
.user
.update(username
, user
)
2812 # except ClientException as e:
2817 @cli_osm.command(name
='user-delete', short_help
='deletes a user')
2818 @click.argument('name')
2819 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2821 def user_delete(ctx
, name
):
2825 NAME: name or ID of the user to be deleted
2828 check_client_version(ctx
.obj
, ctx
.command
.name
)
2829 ctx
.obj
.user
.delete(name
)
2830 # except ClientException as e:
2835 @cli_osm.command(name
='user-list', short_help
='list all users')
2836 @click.option('--filter', default
=None,
2837 help='restricts the list to the users matching the filter')
2839 def user_list(ctx
, filter):
2840 """list all users"""
2842 check_client_version(ctx
.obj
, ctx
.command
.name
)
2843 resp
= ctx
.obj
.user
.list(filter)
2844 # except ClientException as e:
2847 table
= PrettyTable(['name', 'id'])
2849 table
.add_row([user
['username'], user
['_id']])
2854 @cli_osm.command(name
='user-show', short_help
='shows the details of a user')
2855 @click.argument('name')
2857 def user_show(ctx
, name
):
2858 """shows the details of a user
2860 NAME: name or ID of the user
2863 check_client_version(ctx
.obj
, ctx
.command
.name
)
2864 resp
= ctx
.obj
.user
.get(name
)
2865 if 'password' in resp
:
2866 resp
['password']='********'
2867 # except ClientException as e:
2871 table
= PrettyTable(['key', 'attribute'])
2872 for k
, v
in resp
.items():
2873 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2878 ####################
2879 # Fault Management operations
2880 ####################
2882 @cli_osm.command(name
='ns-alarm-create')
2883 @click.argument('name')
2884 @click.option('--ns', prompt
=True, help='NS instance id or name')
2885 @click.option('--vnf', prompt
=True,
2886 help='VNF name (VNF member index as declared in the NSD)')
2887 @click.option('--vdu', prompt
=True,
2888 help='VDU name (VDU name as declared in the VNFD)')
2889 @click.option('--metric', prompt
=True,
2890 help='Name of the metric (e.g. cpu_utilization)')
2891 @click.option('--severity', default
='WARNING',
2892 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
2893 @click.option('--threshold_value', prompt
=True,
2894 help='threshold value that, when crossed, an alarm is triggered')
2895 @click.option('--threshold_operator', prompt
=True,
2896 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
2897 @click.option('--statistic', default
='AVERAGE',
2898 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
2900 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
2901 threshold_value
, threshold_operator
, statistic
):
2902 """creates a new alarm for a NS instance"""
2903 # TODO: Check how to validate threshold_value.
2904 # Should it be an integer (1-100), percentage, or decimal (0.01-1.00)?
2906 ns_instance
= ctx
.obj
.ns
.get(ns
)
2908 alarm
['alarm_name'] = name
2909 alarm
['ns_id'] = ns_instance
['_id']
2910 alarm
['correlation_id'] = ns_instance
['_id']
2911 alarm
['vnf_member_index'] = vnf
2912 alarm
['vdu_name'] = vdu
2913 alarm
['metric_name'] = metric
2914 alarm
['severity'] = severity
2915 alarm
['threshold_value'] = int(threshold_value
)
2916 alarm
['operation'] = threshold_operator
2917 alarm
['statistic'] = statistic
2918 check_client_version(ctx
.obj
, ctx
.command
.name
)
2919 ctx
.obj
.ns
.create_alarm(alarm
)
2920 # except ClientException as e:
2925 #@cli_osm.command(name='ns-alarm-delete')
2926 #@click.argument('name')
2927 #@click.pass_context
2928 #def ns_alarm_delete(ctx, name):
2929 # """deletes an alarm
2931 # NAME: name of the alarm to be deleted
2934 # check_client_version(ctx.obj, ctx.command.name)
2935 # ctx.obj.ns.delete_alarm(name)
2936 # except ClientException as e:
2941 ####################
2942 # Performance Management operations
2943 ####################
2945 @cli_osm.command(name
='ns-metric-export', short_help
='exports a metric to the internal OSM bus, which can be read by other apps')
2946 @click.option('--ns', prompt
=True, help='NS instance id or name')
2947 @click.option('--vnf', prompt
=True,
2948 help='VNF name (VNF member index as declared in the NSD)')
2949 @click.option('--vdu', prompt
=True,
2950 help='VDU name (VDU name as declared in the VNFD)')
2951 @click.option('--metric', prompt
=True,
2952 help='name of the metric (e.g. cpu_utilization)')
2953 #@click.option('--period', default='1w',
2954 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
2955 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
2957 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
2958 """exports a metric to the internal OSM bus, which can be read by other apps"""
2959 # TODO: Check how to validate interval.
2960 # Should it be an integer (seconds), or should a suffix (s,m,h,d,w) also be permitted?
2962 ns_instance
= ctx
.obj
.ns
.get(ns
)
2964 metric_data
['ns_id'] = ns_instance
['_id']
2965 metric_data
['correlation_id'] = ns_instance
['_id']
2966 metric_data
['vnf_member_index'] = vnf
2967 metric_data
['vdu_name'] = vdu
2968 metric_data
['metric_name'] = metric
2969 metric_data
['collection_unit'] = 'WEEK'
2970 metric_data
['collection_period'] = 1
2971 check_client_version(ctx
.obj
, ctx
.command
.name
)
2973 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
2977 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
2978 time
.sleep(int(interval
))
2980 # except ClientException as e:
2985 ####################
2987 ####################
2989 @cli_osm.command(name
='version')
2991 def get_version(ctx
):
2993 check_client_version(ctx
.obj
, "version")
2994 print ("Server version: {}".format(ctx
.obj
.get_version()))
2995 print ("Client version: {}".format(pkg_resources
.get_distribution("osmclient").version
))
2996 # except ClientException as e:
3000 @cli_osm.command(name
='upload-package', short_help
='uploads a VNF package or NS package')
3001 @click.argument('filename')
3003 def upload_package(ctx
, filename
):
3004 """uploads a VNF package or NS package
3006 FILENAME: VNF or NS package file (tar.gz)
3009 ctx
.obj
.package
.upload(filename
)
3010 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
3011 if fullclassname
!= 'osmclient.sol005.client.Client':
3012 ctx
.obj
.package
.wait_for_upload(filename
)
3013 # except ClientException as e:
3018 #@cli_osm.command(name='ns-scaling-show')
3019 #@click.argument('ns_name')
3020 #@click.pass_context
3021 #def show_ns_scaling(ctx, ns_name):
3022 # """shows the status of a NS scaling operation
3024 # NS_NAME: name of the NS instance being scaled
3027 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3028 # resp = ctx.obj.ns.list()
3029 # except ClientException as e:
3033 # table = PrettyTable(
3036 # 'operational status',
3041 # if ns_name == ns['name']:
3042 # nsopdata = ctx.obj.ns.get_opdata(ns['id'])
3043 # scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
3044 # for record in scaling_records:
3045 # if 'instance' in record:
3046 # instances = record['instance']
3047 # for inst in instances:
3049 # [record['scaling-group-name-ref'],
3050 # inst['instance-id'],
3051 # inst['op-status'],
3052 # time.strftime('%Y-%m-%d %H:%M:%S',
3054 # inst['create-time'])),
3060 #@cli_osm.command(name='ns-scale')
3061 #@click.argument('ns_name')
3062 #@click.option('--ns_scale_group', prompt=True)
3063 #@click.option('--index', prompt=True)
3064 #@click.option('--wait',
3068 # help='do not return the control immediately, but keep it \
3069 # until the operation is completed, or timeout')
3070 #@click.pass_context
3071 #def ns_scale(ctx, ns_name, ns_scale_group, index, wait):
3074 # NS_NAME: name of the NS instance to be scaled
3077 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3078 # ctx.obj.ns.scale(ns_name, ns_scale_group, index, wait=wait)
3079 # except ClientException as e:
3084 #@cli_osm.command(name='config-agent-list')
3085 #@click.pass_context
3086 #def config_agent_list(ctx):
3087 # """list config agents"""
3089 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3090 # except ClientException as e:
3093 # table = PrettyTable(['name', 'account-type', 'details'])
3094 # for account in ctx.obj.vca.list():
3097 # account['account-type'],
3103 #@cli_osm.command(name='config-agent-delete')
3104 #@click.argument('name')
3105 #@click.pass_context
3106 #def config_agent_delete(ctx, name):
3107 # """deletes a config agent
3109 # NAME: name of the config agent to be deleted
3112 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3113 # ctx.obj.vca.delete(name)
3114 # except ClientException as e:
3119 #@cli_osm.command(name='config-agent-add')
3120 #@click.option('--name',
3122 #@click.option('--account_type',
3124 #@click.option('--server',
3126 #@click.option('--user',
3128 #@click.option('--secret',
3131 # confirmation_prompt=True)
3132 #@click.pass_context
3133 #def config_agent_add(ctx, name, account_type, server, user, secret):
3134 # """adds a config agent"""
3136 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3137 # ctx.obj.vca.create(name, account_type, server, user, secret)
3138 # except ClientException as e:
3143 #@cli_osm.command(name='ro-dump')
3144 #@click.pass_context
3146 # """shows RO agent information"""
3147 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3148 # resp = ctx.obj.vim.get_resource_orchestrator()
3149 # table = PrettyTable(['key', 'attribute'])
3150 # for k, v in list(resp.items()):
3151 # table.add_row([k, json.dumps(v, indent=2)])
3156 #@cli_osm.command(name='vcs-list')
3157 #@click.pass_context
3159 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3160 # resp = ctx.obj.utils.get_vcs_info()
3161 # table = PrettyTable(['component name', 'state'])
3162 # for component in resp:
3163 # table.add_row([component['component_name'], component['state']])
3168 @cli_osm.command(name
='ns-action', short_help
='executes an action/primitive over a NS instance')
3169 @click.argument('ns_name')
3170 @click.option('--vnf_name', default
=None, help='member-vnf-index if the target is a vnf instead of a ns)')
3171 @click.option('--kdu_name', default
=None, help='kdu-name if the target is a kdu)')
3172 @click.option('--vdu_id', default
=None, help='vdu-id if the target is a vdu')
3173 @click.option('--vdu_count', default
=None, help='number of vdu instance of this vdu_id')
3174 @click.option('--action_name', prompt
=True, help='action name')
3175 @click.option('--params', default
=None, help='action params in YAML/JSON inline string')
3176 @click.option('--params_file', default
=None, help='YAML/JSON file with action params')
3177 @click.option('--wait',
3181 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3193 """executes an action/primitive over a NS instance
3195 NS_NAME: name or ID of the NS instance
3198 check_client_version(ctx
.obj
, ctx
.command
.name
)
3201 op_data
['member_vnf_index'] = vnf_name
3203 op_data
['kdu_name'] = kdu_name
3205 op_data
['vdu_id'] = vdu_id
3207 op_data
['vdu_count_index'] = vdu_count
3208 op_data
['primitive'] = action_name
3210 with
open(params_file
, 'r') as pf
:
3213 op_data
['primitive_params'] = yaml
.safe_load(params
)
3215 op_data
['primitive_params'] = {}
3216 print(ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
, wait
=wait
))
3218 # except ClientException as e:
3223 @cli_osm.command(name
='vnf-scale', short_help
='executes a VNF scale (adding/removing VDUs)')
3224 @click.argument('ns_name')
3225 @click.argument('vnf_name')
3226 @click.option('--scaling-group', prompt
=True, help="scaling-group-descriptor name to use")
3227 @click.option('--scale-in', default
=False, is_flag
=True, help="performs a scale in operation")
3228 @click.option('--scale-out', default
=False, is_flag
=True, help="performs a scale out operation (by default)")
3237 Executes a VNF scale (adding/removing VDUs)
3240 NS_NAME: name or ID of the NS instance.
3241 VNF_NAME: member-vnf-index in the NS to be scaled.
3244 check_client_version(ctx
.obj
, ctx
.command
.name
)
3245 if not scale_in
and not scale_out
:
3247 ctx
.obj
.ns
.scale_vnf(ns_name
, vnf_name
, scaling_group
, scale_in
, scale_out
)
3248 # except ClientException as e:
3253 ##############################
3254 # Role Management Operations #
3255 ##############################
3257 @cli_osm.command(name
='role-create', short_help
='creates a new role')
3258 @click.argument('name')
3259 @click.option('--permissions',
3261 help='role permissions using a dictionary')
3263 def role_create(ctx
, name
, permissions
):
3268 NAME: Name or ID of the role.
3269 DEFINITION: Definition of grant/denial of access to resources.
3272 check_client_version(ctx
.obj
, ctx
.command
.name
)
3273 ctx
.obj
.role
.create(name
, permissions
)
3274 # except ClientException as e:
3279 @cli_osm.command(name
='role-update', short_help
='updates a role')
3280 @click.argument('name')
3281 @click.option('--set-name',
3283 help='change name of rle')
3284 # @click.option('--permissions',
3286 # help='provide a yaml format dictionary with incremental changes. Values can be bool or None to delete')
3287 @click.option('--add',
3289 help='yaml format dictionary with permission: True/False to access grant/denial')
3290 @click.option('--remove',
3292 help='yaml format list to remove a permission')
3294 def role_update(ctx
, name
, set_name
, add
, remove
):
3299 NAME: Name or ID of the role.
3300 DEFINITION: Definition overwrites the old definition.
3301 ADD: Grant/denial of access to resource to add.
3302 REMOVE: Grant/denial of access to resource to remove.
3305 check_client_version(ctx
.obj
, ctx
.command
.name
)
3306 ctx
.obj
.role
.update(name
, set_name
, None, add
, remove
)
3307 # except ClientException as e:
3312 @cli_osm.command(name
='role-delete', short_help
='deletes a role')
3313 @click.argument('name')
3314 # @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3316 def role_delete(ctx
, name
):
3321 NAME: Name or ID of the role.
3324 check_client_version(ctx
.obj
, ctx
.command
.name
)
3325 ctx
.obj
.role
.delete(name
)
3326 # except ClientException as e:
3331 @cli_osm.command(name
='role-list', short_help
='list all roles')
3332 @click.option('--filter', default
=None,
3333 help='restricts the list to the projects matching the filter')
3335 def role_list(ctx
, filter):
3340 check_client_version(ctx
.obj
, ctx
.command
.name
)
3341 resp
= ctx
.obj
.role
.list(filter)
3342 # except ClientException as e:
3345 table
= PrettyTable(['name', 'id'])
3347 table
.add_row([role
['name'], role
['_id']])
3352 @cli_osm.command(name
='role-show', short_help
='show specific role')
3353 @click.argument('name')
3355 def role_show(ctx
, name
):
3357 Shows the details of a role.
3360 NAME: Name or ID of the role.
3363 check_client_version(ctx
.obj
, ctx
.command
.name
)
3364 resp
= ctx
.obj
.role
.get(name
)
3365 # except ClientException as e:
3369 table
= PrettyTable(['key', 'attribute'])
3370 for k
, v
in resp
.items():
3371 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3376 @cli_osm.command(name
='package-create',
3377 short_help
='Create a package descriptor')
3378 @click.argument('package-type')
3379 @click.argument('package-name')
3380 @click.option('--base-directory',
3382 help=('(NS/VNF/NST) Set the location for package creation. Default: "."'))
3383 @click.option('--image',
3384 default
="image-name",
3385 help='(VNF) Set the name of the vdu image. Default "image-name"')
3386 @click.option('--vdus',
3388 help='(VNF) Set the number of vdus in a VNF. Default 1')
3389 @click.option('--vcpu',
3391 help='(VNF) Set the number of virtual CPUs in a vdu. Default 1')
3392 @click.option('--memory',
3394 help='(VNF) Set the memory size (MB) of the vdu. Default 1024')
3395 @click.option('--storage',
3397 help='(VNF) Set the disk size (GB) of the vdu. Default 10')
3398 @click.option('--interfaces',
3400 help='(VNF) Set the number of additional interfaces apart from the management interface. Default 0')
3401 @click.option('--vendor',
3403 help='(NS/VNF) Set the descriptor vendor. Default "OSM"')
3404 @click.option('--override',
3407 help='(NS/VNF/NST) Flag for overriding the package if exists.')
3408 @click.option('--detailed',
3411 help='(NS/VNF/NST) Flag for generating descriptor .yaml with all possible commented options')
3412 @click.option('--netslice-subnets',
3414 help='(NST) Number of netslice subnets. Default 1')
3415 @click.option('--netslice-vlds',
3417 help='(NST) Number of netslice vlds. Default 1')
3419 def package_create(ctx
,
3435 Creates an OSM NS, VNF, NST package
3438 PACKAGE_TYPE: Package to be created: NS, VNF or NST.
3439 PACKAGE_NAME: Name of the package to create the folder with the content.
3443 check_client_version(ctx
.obj
, ctx
.command
.name
)
3444 print("Creating the {} structure: {}/{}".format(package_type
.upper(), base_directory
, package_name
))
3445 resp
= ctx
.obj
.package_tool
.create(package_type
,
3454 interfaces
=interfaces
,
3457 netslice_subnets
=netslice_subnets
,
3458 netslice_vlds
=netslice_vlds
)
3460 # except ClientException as inst:
3461 # print("ERROR: {}".format(inst))
3464 @cli_osm.command(name
='package-validate',
3465 short_help
='Validate a package descriptor')
3466 @click.argument('base-directory',
3470 def package_validate(ctx
,
3473 Validate descriptors given a base directory.
3476 BASE_DIRECTORY: Stub folder for NS, VNF or NST package.
3479 check_client_version(ctx
.obj
, ctx
.command
.name
)
3480 results
= ctx
.obj
.package_tool
.validate(base_directory
)
3481 table
= PrettyTable()
3482 table
.field_names
= ["TYPE", "PATH", "VALID", "ERROR"]
3483 # Print the dictionary generated by the validation function
3484 for result
in results
:
3485 table
.add_row([result
["type"], result
["path"], result
["valid"], result
["error"]])
3486 table
.sortby
= "VALID"
3487 table
.align
["PATH"] = "l"
3488 table
.align
["TYPE"] = "l"
3489 table
.align
["ERROR"] = "l"
3491 # except ClientException as inst:
3492 # print("ERROR: {}".format(inst))
3495 @cli_osm.command(name
='package-build',
3496 short_help
='Build the tar.gz of the package')
3497 @click.argument('package-folder')
3498 @click.option('--skip-validation',
3501 help='skip package validation')
3503 def package_build(ctx
,
3507 Build the package NS, VNF given the package_folder.
3510 PACKAGE_FOLDER: Folder of the NS, VNF or NST to be packaged
3513 check_client_version(ctx
.obj
, ctx
.command
.name
)
3514 results
= ctx
.obj
.package_tool
.build(package_folder
, skip_validation
)
3516 # except ClientException as inst:
3517 # print("ERROR: {}".format(inst))
3524 except pycurl
.error
as exc
:
3526 print('Maybe "--hostname" option or OSM_HOSTNAME environment variable needs to be specified')
3528 except ClientException
as exc
:
3529 print("ERROR: {}".format(exc
))
3531 # TODO capture other controlled exceptions here
3532 # TODO remove the ClientException captures from all places, unless they do something different
3535 if __name__
== '__main__':