1 # Copyright 2017-2018 Sandvine
2 # Copyright 2018 Telefonica
6 # Licensed under the Apache License, Version 2.0 (the "License"); you may
7 # not use this file except in compliance with the License. You may obtain
8 # a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 # License for the specific language governing permissions and limitations
22 from osmclient
import client
23 from osmclient
.common
.exceptions
import ClientException
24 from prettytable
import PrettyTable
33 from datetime
import datetime
38 CONTEXT_SETTINGS
= dict(help_option_names
=['-h', '--help'], max_content_width
=160)
40 def wrap_text(text
, width
):
41 wrapper
= textwrap
.TextWrapper(width
=width
)
42 lines
= text
.splitlines()
43 return "\n".join(map(wrapper
.fill
, lines
))
46 def trunc_text(text
, length
):
47 if len(text
) > length
:
48 return text
[:(length
- 3)] + '...'
53 def check_client_version(obj
, what
, version
='sol005'):
55 Checks the version of the client object and raises error if it not the expected.
57 :param obj: the client object
58 :what: the function or command under evaluation (used when an error is raised)
60 :raises ClientError: if the specified version does not match the client version
63 fullclassname
= obj
.__module
__ + "." + obj
.__class
__.__name
__
64 message
= 'The following commands or options are only supported with the option "--sol005": {}'.format(what
)
66 message
= 'The following commands or options are not supported when using option "--sol005": {}'.format(what
)
67 if fullclassname
!= 'osmclient.{}.client.Client'.format(version
):
68 raise ClientException(message
)
72 @click.group(context_settings
=dict(help_option_names
=['-h', '--help'], max_content_width
=160))
73 @click.option('--hostname',
75 envvar
='OSM_HOSTNAME',
76 help='hostname of server. ' +
77 'Also can set OSM_HOSTNAME in environment')
78 #@click.option('--sol005/--no-sol005',
80 # envvar='OSM_SOL005',
81 # help='Use ETSI NFV SOL005 API (default) or the previous SO API. ' +
82 # 'Also can set OSM_SOL005 in environment')
83 @click.option('--user',
86 help='user (defaults to admin). ' +
87 'Also can set OSM_USER in environment')
88 @click.option('--password',
90 envvar
='OSM_PASSWORD',
91 help='password (defaults to admin). ' +
92 'Also can set OSM_PASSWORD in environment')
93 @click.option('--project',
96 help='project (defaults to admin). ' +
97 'Also can set OSM_PROJECT in environment')
98 @click.option('-v', '--verbose', count
=True,
99 help='increase verbosity (-v INFO, -vv VERBOSE, -vvv DEBUG)')
100 #@click.option('--so-port',
102 # envvar='OSM_SO_PORT',
103 # help='hostname of server. ' +
104 # 'Also can set OSM_SO_PORT in environment')
105 #@click.option('--so-project',
107 # envvar='OSM_SO_PROJECT',
108 # help='Project Name in SO. ' +
109 # 'Also can set OSM_SO_PROJECT in environment')
110 #@click.option('--ro-hostname',
112 # envvar='OSM_RO_HOSTNAME',
113 # help='hostname of RO server. ' +
114 # 'Also can set OSM_RO_HOSTNAME in environment')
115 #@click.option('--ro-port',
117 # envvar='OSM_RO_PORT',
118 # help='hostname of RO server. ' +
119 # 'Also can set OSM_RO_PORT in environment')
121 def cli_osm(ctx
, hostname
, user
, password
, project
, verbose
):
125 "either hostname option or OSM_HOSTNAME " +
126 "environment variable needs to be specified"))
128 kwargs
= {'verbose': verbose
}
129 # if so_port is not None:
130 # kwargs['so_port']=so_port
131 # if so_project is not None:
132 # kwargs['so_project']=so_project
133 # if ro_hostname is not None:
134 # kwargs['ro_host']=ro_hostname
135 # if ro_port is not None:
136 # kwargs['ro_port']=ro_port
137 sol005
= os
.getenv('OSM_SOL005', True)
140 if password
is not None:
141 kwargs
['password']=password
142 if project
is not None:
143 kwargs
['project']=project
144 ctx
.obj
= client
.Client(host
=hostname
, sol005
=sol005
, **kwargs
)
145 logger
= logging
.getLogger('osmclient')
152 @cli_osm.command(name
='ns-list', short_help
='list all NS instances')
153 @click.option('--filter', default
=None,
154 help='restricts the list to the NS instances matching the filter.')
156 def ns_list(ctx
, filter):
157 """list all NS instances
161 --filter filterExpr Restricts the list to the NS instances matching the filter
164 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
165 concatenated using the "&" character:
168 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
169 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
170 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
172 value := scalar value
176 * zero or more occurrences
177 ? zero or one occurrence
178 [] grouping of expressions to be used with ? and *
179 "" quotation marks for marking string constants
183 "AttrName" is the name of one attribute in the data type that defines the representation
184 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
185 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
186 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
187 entries, it means that the operator "op" is applied to the attribute addressed by the last
188 <attrName> entry included in the concatenation. All simple filter expressions are combined
189 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
190 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
191 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
192 prefix". If an attribute referenced in an expression is an array, an object that contains a
193 corresponding array shall be considered to match the expression if any of the elements in the
194 array matches all expressions that have the same attribute prefix.
198 --filter admin-status=ENABLED
199 --filter nsd-ref=<NSD_NAME>
200 --filter nsd.vendor=<VENDOR>
201 --filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME>
202 --filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME>
206 check_client_version(ctx
.obj
, '--filter')
207 resp
= ctx
.obj
.ns
.list(filter)
209 resp
= ctx
.obj
.ns
.list()
213 'operational status',
217 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
218 if fullclassname
== 'osmclient.sol005.client.Client':
220 nsr_name
= nsr
['name']
223 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
224 nsr
= nsopdata
['nsr:nsr']
225 nsr_name
= nsr
['name-ref']
226 nsr_id
= nsr
['ns-instance-config-ref']
227 opstatus
= nsr
['operational-status'] if 'operational-status' in nsr
else 'Not found'
228 configstatus
= nsr
['config-status'] if 'config-status' in nsr
else 'Not found'
229 detailed_status
= nsr
['detailed-status'] if 'detailed-status' in nsr
else 'Not found'
230 detailed_status
= wrap_text(text
=detailed_status
,width
=50)
231 if configstatus
== "config_not_needed":
232 configstatus
= "configured (no charms)"
244 def nsd_list(ctx
, filter):
247 check_client_version(ctx
.obj
, '--filter')
248 resp
= ctx
.obj
.nsd
.list(filter)
250 resp
= ctx
.obj
.nsd
.list()
251 # print(yaml.safe_dump(resp))
252 table
= PrettyTable(['nsd name', 'id'])
253 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
254 if fullclassname
== 'osmclient.sol005.client.Client':
256 name
= ns
['name'] if 'name' in ns
else '-'
257 table
.add_row([name
, ns
['_id']])
260 table
.add_row([ns
['name'], ns
['id']])
265 @cli_osm.command(name
='nsd-list', short_help
='list all NS packages')
266 @click.option('--filter', default
=None,
267 help='restricts the list to the NSD/NSpkg matching the filter')
269 def nsd_list1(ctx
, filter):
270 """list all NSD/NS pkg in the system"""
272 nsd_list(ctx
, filter)
275 @cli_osm.command(name
='nspkg-list', short_help
='list all NS packages')
276 @click.option('--filter', default
=None,
277 help='restricts the list to the NSD/NSpkg matching the filter')
279 def nsd_list2(ctx
, filter):
280 """list all NS packages"""
282 nsd_list(ctx
, filter)
285 def vnfd_list(ctx
, nf_type
, filter):
288 check_client_version(ctx
.obj
, '--nf_type')
290 check_client_version(ctx
.obj
, '--filter')
293 nf_filter
= "_admin.type=vnfd"
294 elif nf_type
== "pnf":
295 nf_filter
= "_admin.type=pnfd"
296 elif nf_type
== "hnf":
297 nf_filter
= "_admin.type=hnfd"
299 raise ClientException('wrong value for "--nf_type" option, allowed values: vnf, pnf, hnf')
301 filter = '{}&{}'.format(nf_filter
, filter)
305 resp
= ctx
.obj
.vnfd
.list(filter)
307 resp
= ctx
.obj
.vnfd
.list()
308 # print(yaml.safe_dump(resp))
309 table
= PrettyTable(['nfpkg name', 'id'])
310 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
311 if fullclassname
== 'osmclient.sol005.client.Client':
313 name
= vnfd
['name'] if 'name' in vnfd
else '-'
314 table
.add_row([name
, vnfd
['_id']])
317 table
.add_row([vnfd
['name'], vnfd
['id']])
322 @cli_osm.command(name
='vnfd-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
323 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
324 @click.option('--filter', default
=None,
325 help='restricts the list to the NF pkg matching the filter')
327 def vnfd_list1(ctx
, nf_type
, filter):
328 """list all xNF packages (VNF, HNF, PNF)"""
330 vnfd_list(ctx
, nf_type
, filter)
333 @cli_osm.command(name
='vnfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
334 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
335 @click.option('--filter', default
=None,
336 help='restricts the list to the NFpkg matching the filter')
338 def vnfd_list2(ctx
, nf_type
, filter):
339 """list all xNF packages (VNF, HNF, PNF)"""
341 vnfd_list(ctx
, nf_type
, filter)
344 @cli_osm.command(name
='nfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
345 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
346 @click.option('--filter', default
=None,
347 help='restricts the list to the NFpkg matching the filter')
349 def nfpkg_list(ctx
, nf_type
, filter):
350 """list all xNF packages (VNF, HNF, PNF)"""
353 check_client_version(ctx
.obj
, ctx
.command
.name
)
354 vnfd_list(ctx
, nf_type
, filter)
355 # except ClientException as e:
360 def vnf_list(ctx
, ns
, filter):
364 check_client_version(ctx
.obj
, '--ns')
366 check_client_version(ctx
.obj
, '--filter')
367 resp
= ctx
.obj
.vnf
.list(ns
, filter)
369 resp
= ctx
.obj
.vnf
.list()
370 # except ClientException as e:
373 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
374 if fullclassname
== 'osmclient.sol005.client.Client':
384 name
= vnfr
['name'] if 'name' in vnfr
else '-'
389 vnfr
['member-vnf-index-ref'],
391 vnfr
['vim-account-id'],
397 'operational status',
400 if 'mgmt-interface' not in vnfr
:
401 vnfr
['mgmt-interface'] = {}
402 vnfr
['mgmt-interface']['ip-address'] = None
406 vnfr
['operational-status'],
407 vnfr
['config-status']])
412 @cli_osm.command(name
='vnf-list', short_help
='list all NF instances')
413 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
414 @click.option('--filter', default
=None,
415 help='restricts the list to the NF instances matching the filter.')
417 def vnf_list1(ctx
, ns
, filter):
418 """list all NF instances"""
420 vnf_list(ctx
, ns
, filter)
423 @cli_osm.command(name
='nf-list', short_help
='list all NF instances')
424 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
425 @click.option('--filter', default
=None,
426 help='restricts the list to the NF instances matching the filter.')
428 def nf_list(ctx
, ns
, filter):
429 """list all NF instances
433 --ns TEXT NS instance id or name to restrict the VNF list
434 --filter filterExpr Restricts the list to the VNF instances matching the filter
437 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
438 concatenated using the "&" character:
441 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
442 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
443 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
445 value := scalar value
449 * zero or more occurrences
450 ? zero or one occurrence
451 [] grouping of expressions to be used with ? and *
452 "" quotation marks for marking string constants
456 "AttrName" is the name of one attribute in the data type that defines the representation
457 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
458 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
459 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
460 entries, it means that the operator "op" is applied to the attribute addressed by the last
461 <attrName> entry included in the concatenation. All simple filter expressions are combined
462 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
463 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
464 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
465 prefix". If an attribute referenced in an expression is an array, an object that contains a
466 corresponding array shall be considered to match the expression if any of the elements in the
467 array matches all expressions that have the same attribute prefix.
471 --filter vim-account-id=<VIM_ACCOUNT_ID>
472 --filter vnfd-ref=<VNFD_NAME>
473 --filter vdur.ip-address=<IP_ADDRESS>
474 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
477 vnf_list(ctx
, ns
, filter)
480 @cli_osm.command(name
='ns-op-list', short_help
='shows the history of operations over a NS instance')
481 @click.argument('name')
483 def ns_op_list(ctx
, name
):
484 """shows the history of operations over a NS instance
486 NAME: name or ID of the NS instance
490 check_client_version(ctx
.obj
, ctx
.command
.name
)
491 resp
= ctx
.obj
.ns
.list_op(name
)
492 # except ClientException as e:
496 table
= PrettyTable(['id', 'operation', 'action_name', 'status'])
497 #print(yaml.safe_dump(resp))
500 if op
['lcmOperationType']=='action':
501 action_name
= op
['operationParams']['primitive']
502 table
.add_row([op
['id'], op
['lcmOperationType'], action_name
,
503 op
['operationState']])
508 def nsi_list(ctx
, filter):
509 """list all Network Slice Instances"""
512 check_client_version(ctx
.obj
, ctx
.command
.name
)
513 resp
= ctx
.obj
.nsi
.list(filter)
514 # except ClientException as e:
518 ['netslice instance name',
520 'operational status',
524 nsi_name
= nsi
['name']
526 opstatus
= nsi
['operational-status'] if 'operational-status' in nsi
else 'Not found'
527 configstatus
= nsi
['config-status'] if 'config-status' in nsi
else 'Not found'
528 detailed_status
= nsi
['detailed-status'] if 'detailed-status' in nsi
else 'Not found'
529 if configstatus
== "config_not_needed":
530 configstatus
= "configured (no charms)"
541 @cli_osm.command(name
='nsi-list', short_help
='list all Network Slice Instances (NSI)')
542 @click.option('--filter', default
=None,
543 help='restricts the list to the Network Slice Instances matching the filter')
545 def nsi_list1(ctx
, filter):
546 """list all Network Slice Instances (NSI)"""
548 nsi_list(ctx
, filter)
551 @cli_osm.command(name
='netslice-instance-list', short_help
='list all Network Slice Instances (NSI)')
552 @click.option('--filter', default
=None,
553 help='restricts the list to the Network Slice Instances matching the filter')
555 def nsi_list2(ctx
, filter):
556 """list all Network Slice Instances (NSI)"""
558 nsi_list(ctx
, filter)
561 def nst_list(ctx
, filter):
564 check_client_version(ctx
.obj
, ctx
.command
.name
)
565 resp
= ctx
.obj
.nst
.list(filter)
566 # except ClientException as e:
569 # print(yaml.safe_dump(resp))
570 table
= PrettyTable(['nst name', 'id'])
572 name
= nst
['name'] if 'name' in nst
else '-'
573 table
.add_row([name
, nst
['_id']])
578 @cli_osm.command(name
='nst-list', short_help
='list all Network Slice Templates (NST)')
579 @click.option('--filter', default
=None,
580 help='restricts the list to the NST matching the filter')
582 def nst_list1(ctx
, filter):
583 """list all Network Slice Templates (NST) in the system"""
585 nst_list(ctx
, filter)
588 @cli_osm.command(name
='netslice-template-list', short_help
='list all Network Slice Templates (NST)')
589 @click.option('--filter', default
=None,
590 help='restricts the list to the NST matching the filter')
592 def nst_list2(ctx
, filter):
593 """list all Network Slice Templates (NST) in the system"""
595 nst_list(ctx
, filter)
598 def nsi_op_list(ctx
, name
):
601 check_client_version(ctx
.obj
, ctx
.command
.name
)
602 resp
= ctx
.obj
.nsi
.list_op(name
)
603 # except ClientException as e:
606 table
= PrettyTable(['id', 'operation', 'status'])
608 table
.add_row([op
['id'], op
['lcmOperationType'],
609 op
['operationState']])
614 @cli_osm.command(name
='nsi-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
615 @click.argument('name')
617 def nsi_op_list1(ctx
, name
):
618 """shows the history of operations over a Network Slice Instance (NSI)
620 NAME: name or ID of the Network Slice Instance
623 nsi_op_list(ctx
, name
)
626 @cli_osm.command(name
='netslice-instance-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
627 @click.argument('name')
629 def nsi_op_list2(ctx
, name
):
630 """shows the history of operations over a Network Slice Instance (NSI)
632 NAME: name or ID of the Network Slice Instance
635 nsi_op_list(ctx
, name
)
638 @cli_osm.command(name
='pdu-list', short_help
='list all Physical Deployment Units (PDU)')
639 @click.option('--filter', default
=None,
640 help='restricts the list to the Physical Deployment Units matching the filter')
642 def pdu_list(ctx
, filter):
643 """list all Physical Deployment Units (PDU)"""
646 check_client_version(ctx
.obj
, ctx
.command
.name
)
647 resp
= ctx
.obj
.pdu
.list(filter)
648 # except ClientException as e:
657 pdu_name
= pdu
['name']
659 pdu_type
= pdu
['type']
660 pdu_ipaddress
= "None"
661 for iface
in pdu
['interfaces']:
663 pdu_ipaddress
= iface
['ip-address']
678 def nsd_show(ctx
, name
, literal
):
681 resp
= ctx
.obj
.nsd
.get(name
)
682 # resp = ctx.obj.nsd.get_individual(name)
683 # except ClientException as e:
688 print(yaml
.safe_dump(resp
))
691 table
= PrettyTable(['field', 'value'])
692 for k
, v
in list(resp
.items()):
693 table
.add_row([k
, json
.dumps(v
, indent
=2)])
698 @cli_osm.command(name
='nsd-show', short_help
='shows the content of a NSD')
699 @click.option('--literal', is_flag
=True,
700 help='print literally, no pretty table')
701 @click.argument('name')
703 def nsd_show1(ctx
, name
, literal
):
704 """shows the content of a NSD
706 NAME: name or ID of the NSD/NSpkg
709 nsd_show(ctx
, name
, literal
)
712 @cli_osm.command(name
='nspkg-show', short_help
='shows the content of a NSD')
713 @click.option('--literal', is_flag
=True,
714 help='print literally, no pretty table')
715 @click.argument('name')
717 def nsd_show2(ctx
, name
, literal
):
718 """shows the content of a NSD
720 NAME: name or ID of the NSD/NSpkg
723 nsd_show(ctx
, name
, literal
)
726 def vnfd_show(ctx
, name
, literal
):
729 resp
= ctx
.obj
.vnfd
.get(name
)
730 # resp = ctx.obj.vnfd.get_individual(name)
731 # except ClientException as e:
736 print(yaml
.safe_dump(resp
))
739 table
= PrettyTable(['field', 'value'])
740 for k
, v
in list(resp
.items()):
741 table
.add_row([k
, json
.dumps(v
, indent
=2)])
746 @cli_osm.command(name
='vnfd-show', short_help
='shows the content of a VNFD')
747 @click.option('--literal', is_flag
=True,
748 help='print literally, no pretty table')
749 @click.argument('name')
751 def vnfd_show1(ctx
, name
, literal
):
752 """shows the content of a VNFD
754 NAME: name or ID of the VNFD/VNFpkg
757 vnfd_show(ctx
, name
, literal
)
760 @cli_osm.command(name
='vnfpkg-show', short_help
='shows the content of a VNFD')
761 @click.option('--literal', is_flag
=True,
762 help='print literally, no pretty table')
763 @click.argument('name')
765 def vnfd_show2(ctx
, name
, literal
):
766 """shows the content of a VNFD
768 NAME: name or ID of the VNFD/VNFpkg
771 vnfd_show(ctx
, name
, literal
)
774 @cli_osm.command(name
='nfpkg-show', short_help
='shows the content of a NF Descriptor')
775 @click.option('--literal', is_flag
=True,
776 help='print literally, no pretty table')
777 @click.argument('name')
779 def nfpkg_show(ctx
, name
, literal
):
780 """shows the content of a NF Descriptor
782 NAME: name or ID of the NFpkg
785 vnfd_show(ctx
, name
, literal
)
788 @cli_osm.command(name
='ns-show', short_help
='shows the info of a NS instance')
789 @click.argument('name')
790 @click.option('--literal', is_flag
=True,
791 help='print literally, no pretty table')
792 @click.option('--filter', default
=None)
794 def ns_show(ctx
, name
, literal
, filter):
795 """shows the info of a NS instance
797 NAME: name or ID of the NS instance
801 ns
= ctx
.obj
.ns
.get(name
)
802 # except ClientException as e:
807 print(yaml
.safe_dump(ns
))
810 table
= PrettyTable(['field', 'value'])
812 for k
, v
in list(ns
.items()):
813 if filter is None or filter in k
:
814 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
816 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
817 if fullclassname
!= 'osmclient.sol005.client.Client':
818 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
819 nsr_optdata
= nsopdata
['nsr:nsr']
820 for k
, v
in list(nsr_optdata
.items()):
821 if filter is None or filter in k
:
822 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2),width
=100)])
827 @cli_osm.command(name
='vnf-show', short_help
='shows the info of a VNF instance')
828 @click.argument('name')
829 @click.option('--literal', is_flag
=True,
830 help='print literally, no pretty table')
831 @click.option('--filter', default
=None, help='restricts the information to the fields in the filter')
832 @click.option('--kdu', default
=None, help='KDU name (whose status will be shown)')
834 def vnf_show(ctx
, name
, literal
, filter, kdu
):
835 """shows the info of a VNF instance
837 NAME: name or ID of the VNF instance
839 def print_kdu_status(op_info_status
):
840 """print KDU status properly formatted
843 op_status
= yaml
.safe_load(op_info_status
)
844 if "namespace" in op_status
and "info" in op_status
and \
845 "last_deployed" in op_status
["info"] and "status" in op_status
["info"] and \
846 "code" in op_status
["info"]["status"] and "resources" in op_status
["info"]["status"] and \
847 "notes" in op_status
["info"]["status"] and "seconds" in op_status
["info"]["last_deployed"]:
848 last_deployed_time
= datetime
.fromtimestamp(op_status
["info"]["last_deployed"]["seconds"]).strftime("%a %b %d %I:%M:%S %Y")
849 print("LAST DEPLOYED: {}".format(last_deployed_time
))
850 print("NAMESPACE: {}".format(op_status
["namespace"]))
851 status_code
= "UNKNOWN"
852 if op_status
["info"]["status"]["code"]==1:
853 status_code
= "DEPLOYED"
854 print("STATUS: {}".format(status_code
))
857 print(op_status
["info"]["status"]["resources"])
859 print(op_status
["info"]["status"]["notes"])
861 print(op_info_status
)
863 print(op_info_status
)
868 raise ClientException('"--literal" option is incompatible with "--kdu" option')
870 raise ClientException('"--filter" option is incompatible with "--kdu" option')
873 check_client_version(ctx
.obj
, ctx
.command
.name
)
874 resp
= ctx
.obj
.vnf
.get(name
)
877 ns_id
= resp
['nsr-id-ref']
879 op_data
['member_vnf_index'] = resp
['member-vnf-index-ref']
880 op_data
['kdu_name'] = kdu
881 op_data
['primitive'] = 'status'
882 op_data
['primitive_params'] = {}
883 op_id
= ctx
.obj
.ns
.exec_op(ns_id
, op_name
='action', op_data
=op_data
, wait
=False)
886 op_info
= ctx
.obj
.ns
.get_op(op_id
)
887 if op_info
['operationState'] == 'COMPLETED':
888 print_kdu_status(op_info
['detailed-status'])
892 print ("Could not determine KDU status")
895 print(yaml
.safe_dump(resp
))
898 table
= PrettyTable(['field', 'value'])
900 for k
, v
in list(resp
.items()):
901 if filter is None or filter in k
:
902 table
.add_row([k
, wrap_text(text
=json
.dumps(v
,indent
=2),width
=100)])
905 # except ClientException as e:
910 #@cli_osm.command(name='vnf-monitoring-show')
911 #@click.argument('vnf_name')
913 #def vnf_monitoring_show(ctx, vnf_name):
915 # check_client_version(ctx.obj, ctx.command.name, 'v1')
916 # resp = ctx.obj.vnf.get_monitoring(vnf_name)
917 # except ClientException as e:
921 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
922 # if resp is not None:
923 # for monitor in resp:
927 # monitor['value-integer'],
933 #@cli_osm.command(name='ns-monitoring-show')
934 #@click.argument('ns_name')
936 #def ns_monitoring_show(ctx, ns_name):
938 # check_client_version(ctx.obj, ctx.command.name, 'v1')
939 # resp = ctx.obj.ns.get_monitoring(ns_name)
940 # except ClientException as e:
944 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
945 # for key, val in list(resp.items()):
946 # for monitor in val:
950 # monitor['value-integer'],
956 @cli_osm.command(name
='ns-op-show', short_help
='shows the info of a NS operation')
957 @click.argument('id')
958 @click.option('--filter', default
=None)
959 @click.option('--literal', is_flag
=True,
960 help='print literally, no pretty table')
962 def ns_op_show(ctx
, id, filter, literal
):
963 """shows the detailed info of a NS operation
965 ID: operation identifier
969 check_client_version(ctx
.obj
, ctx
.command
.name
)
970 op_info
= ctx
.obj
.ns
.get_op(id)
971 # except ClientException as e:
976 print(yaml
.safe_dump(op_info
))
979 table
= PrettyTable(['field', 'value'])
980 for k
, v
in list(op_info
.items()):
981 if filter is None or filter in k
:
982 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
987 def nst_show(ctx
, name
, literal
):
990 check_client_version(ctx
.obj
, ctx
.command
.name
)
991 resp
= ctx
.obj
.nst
.get(name
)
992 #resp = ctx.obj.nst.get_individual(name)
993 # except ClientException as e:
998 print(yaml
.safe_dump(resp
))
1001 table
= PrettyTable(['field', 'value'])
1002 for k
, v
in list(resp
.items()):
1003 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
1008 @cli_osm.command(name
='nst-show', short_help
='shows the content of a Network Slice Template (NST)')
1009 @click.option('--literal', is_flag
=True,
1010 help='print literally, no pretty table')
1011 @click.argument('name')
1013 def nst_show1(ctx
, name
, literal
):
1014 """shows the content of a Network Slice Template (NST)
1016 NAME: name or ID of the NST
1019 nst_show(ctx
, name
, literal
)
1022 @cli_osm.command(name
='netslice-template-show', short_help
='shows the content of a Network Slice Template (NST)')
1023 @click.option('--literal', is_flag
=True,
1024 help='print literally, no pretty table')
1025 @click.argument('name')
1027 def nst_show2(ctx
, name
, literal
):
1028 """shows the content of a Network Slice Template (NST)
1030 NAME: name or ID of the NST
1033 nst_show(ctx
, name
, literal
)
1036 def nsi_show(ctx
, name
, literal
, filter):
1039 check_client_version(ctx
.obj
, ctx
.command
.name
)
1040 nsi
= ctx
.obj
.nsi
.get(name
)
1041 # except ClientException as e:
1046 print(yaml
.safe_dump(nsi
))
1049 table
= PrettyTable(['field', 'value'])
1051 for k
, v
in list(nsi
.items()):
1052 if filter is None or filter in k
:
1053 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1059 @cli_osm.command(name
='nsi-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1060 @click.argument('name')
1061 @click.option('--literal', is_flag
=True,
1062 help='print literally, no pretty table')
1063 @click.option('--filter', default
=None)
1065 def nsi_show1(ctx
, name
, literal
, filter):
1066 """shows the content of a Network Slice Instance (NSI)
1068 NAME: name or ID of the Network Slice Instance
1071 nsi_show(ctx
, name
, literal
, filter)
1074 @cli_osm.command(name
='netslice-instance-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1075 @click.argument('name')
1076 @click.option('--literal', is_flag
=True,
1077 help='print literally, no pretty table')
1078 @click.option('--filter', default
=None)
1080 def nsi_show2(ctx
, name
, literal
, filter):
1081 """shows the content of a Network Slice Instance (NSI)
1083 NAME: name or ID of the Network Slice Instance
1086 nsi_show(ctx
, name
, literal
, filter)
1089 def nsi_op_show(ctx
, id, filter):
1092 check_client_version(ctx
.obj
, ctx
.command
.name
)
1093 op_info
= ctx
.obj
.nsi
.get_op(id)
1094 # except ClientException as e:
1098 table
= PrettyTable(['field', 'value'])
1099 for k
, v
in list(op_info
.items()):
1100 if filter is None or filter in k
:
1101 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1106 @cli_osm.command(name
='nsi-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1107 @click.argument('id')
1108 @click.option('--filter', default
=None)
1110 def nsi_op_show1(ctx
, id, filter):
1111 """shows the info of an operation over a Network Slice Instance(NSI)
1113 ID: operation identifier
1116 nsi_op_show(ctx
, id, filter)
1119 @cli_osm.command(name
='netslice-instance-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1120 @click.argument('id')
1121 @click.option('--filter', default
=None)
1123 def nsi_op_show2(ctx
, id, filter):
1124 """shows the info of an operation over a Network Slice Instance(NSI)
1126 ID: operation identifier
1129 nsi_op_show(ctx
, id, filter)
1132 @cli_osm.command(name
='pdu-show', short_help
='shows the content of a Physical Deployment Unit (PDU)')
1133 @click.argument('name')
1134 @click.option('--literal', is_flag
=True,
1135 help='print literally, no pretty table')
1136 @click.option('--filter', default
=None)
1138 def pdu_show(ctx
, name
, literal
, filter):
1139 """shows the content of a Physical Deployment Unit (PDU)
1141 NAME: name or ID of the PDU
1145 check_client_version(ctx
.obj
, ctx
.command
.name
)
1146 pdu
= ctx
.obj
.pdu
.get(name
)
1147 # except ClientException as e:
1152 print(yaml
.safe_dump(pdu
))
1155 table
= PrettyTable(['field', 'value'])
1157 for k
, v
in list(pdu
.items()):
1158 if filter is None or filter in k
:
1159 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1165 ####################
1167 ####################
1169 def nsd_create(ctx
, filename
, overwrite
):
1172 check_client_version(ctx
.obj
, ctx
.command
.name
)
1173 ctx
.obj
.nsd
.create(filename
, overwrite
)
1174 # except ClientException as e:
1179 @cli_osm.command(name
='nsd-create', short_help
='creates a new NSD/NSpkg')
1180 @click.argument('filename')
1181 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1182 help='Deprecated. Use override')
1183 @click.option('--override', 'overwrite', default
=None,
1184 help='overrides fields in descriptor, format: '
1185 '"key1.key2...=value[;key3...=value;...]"')
1187 def nsd_create1(ctx
, filename
, overwrite
):
1188 """creates a new NSD/NSpkg
1190 FILENAME: NSD yaml file or NSpkg tar.gz file
1193 nsd_create(ctx
, filename
, overwrite
)
1196 @cli_osm.command(name
='nspkg-create', short_help
='creates a new NSD/NSpkg')
1197 @click.argument('filename')
1198 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1199 help='Deprecated. Use override')
1200 @click.option('--override', 'overwrite', default
=None,
1201 help='overrides fields in descriptor, format: '
1202 '"key1.key2...=value[;key3...=value;...]"')
1204 def nsd_create2(ctx
, filename
, overwrite
):
1205 """creates a new NSD/NSpkg
1207 FILENAME: NSD yaml file or NSpkg tar.gz file
1210 nsd_create(ctx
, filename
, overwrite
)
1213 def vnfd_create(ctx
, filename
, overwrite
):
1216 check_client_version(ctx
.obj
, ctx
.command
.name
)
1217 ctx
.obj
.vnfd
.create(filename
, overwrite
)
1218 # except ClientException as e:
1223 @cli_osm.command(name
='vnfd-create', short_help
='creates a new VNFD/VNFpkg')
1224 @click.argument('filename')
1225 @click.option('--overwrite', 'overwrite', default
=None,
1226 help='overwrite deprecated, use override')
1227 @click.option('--override', 'overwrite', default
=None,
1228 help='overrides fields in descriptor, format: '
1229 '"key1.key2...=value[;key3...=value;...]"')
1231 def vnfd_create1(ctx
, filename
, overwrite
):
1232 """creates a new VNFD/VNFpkg
1234 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1237 vnfd_create(ctx
, filename
, overwrite
)
1240 @cli_osm.command(name
='vnfpkg-create', short_help
='creates a new VNFD/VNFpkg')
1241 @click.argument('filename')
1242 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1243 help='Deprecated. Use override')
1244 @click.option('--override', 'overwrite', default
=None,
1245 help='overrides fields in descriptor, format: '
1246 '"key1.key2...=value[;key3...=value;...]"')
1248 def vnfd_create2(ctx
, filename
, overwrite
):
1249 """creates a new VNFD/VNFpkg
1251 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1254 vnfd_create(ctx
, filename
, overwrite
)
1257 @cli_osm.command(name
='nfpkg-create', short_help
='creates a new NFpkg')
1258 @click.argument('filename')
1259 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1260 help='Deprecated. Use override')
1261 @click.option('--override', 'overwrite', default
=None,
1262 help='overrides fields in descriptor, format: '
1263 '"key1.key2...=value[;key3...=value;...]"')
1265 def nfpkg_create(ctx
, filename
, overwrite
):
1266 """creates a new NFpkg
1268 FILENAME: NF Descriptor yaml file or NFpkg tar.gz file
1271 vnfd_create(ctx
, filename
, overwrite
)
1274 @cli_osm.command(name
='ns-create', short_help
='creates a new Network Service instance')
1275 @click.option('--ns_name',
1276 prompt
=True, help='name of the NS instance')
1277 @click.option('--nsd_name',
1278 prompt
=True, help='name of the NS descriptor')
1279 @click.option('--vim_account',
1280 prompt
=True, help='default VIM account id or name for the deployment')
1281 @click.option('--admin_status',
1283 help='administration status')
1284 @click.option('--ssh_keys',
1286 help='comma separated list of public key files to inject to vnfs')
1287 @click.option('--config',
1289 help='ns specific yaml configuration')
1290 @click.option('--config_file',
1292 help='ns specific yaml configuration file')
1293 @click.option('--wait',
1297 help='do not return the control immediately, but keep it '
1298 'until the operation is completed, or timeout')
1309 """creates a new NS instance"""
1313 check_client_version(ctx
.obj
, '--config_file')
1315 raise ClientException('"--config" option is incompatible with "--config_file" option')
1316 with
open(config_file
, 'r') as cf
:
1323 account
=vim_account
,
1325 # except ClientException as e:
1330 def nst_create(ctx
, filename
, overwrite
):
1333 check_client_version(ctx
.obj
, ctx
.command
.name
)
1334 ctx
.obj
.nst
.create(filename
, overwrite
)
1335 # except ClientException as e:
1340 @cli_osm.command(name
='nst-create', short_help
='creates a new Network Slice Template (NST)')
1341 @click.argument('filename')
1342 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1343 help='Deprecated. Use override')
1344 @click.option('--override', 'overwrite', default
=None,
1345 help='overrides fields in descriptor, format: '
1346 '"key1.key2...=value[;key3...=value;...]"')
1348 def nst_create1(ctx
, filename
, overwrite
):
1349 """creates a new Network Slice Template (NST)
1351 FILENAME: NST yaml file or NSTpkg tar.gz file
1354 nst_create(ctx
, filename
, overwrite
)
1357 @cli_osm.command(name
='netslice-template-create', short_help
='creates a new Network Slice Template (NST)')
1358 @click.argument('filename')
1359 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1360 help='Deprecated. Use override')
1361 @click.option('--override', 'overwrite', default
=None,
1362 help='overrides fields in descriptor, format: '
1363 '"key1.key2...=value[;key3...=value;...]"')
1365 def nst_create2(ctx
, filename
, overwrite
):
1366 """creates a new Network Slice Template (NST)
1368 FILENAME: NST yaml file or NSTpkg tar.gz file
1371 nst_create(ctx
, filename
, overwrite
)
1374 def nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1375 """creates a new Network Slice Instance (NSI)"""
1378 check_client_version(ctx
.obj
, ctx
.command
.name
)
1381 raise ClientException('"--config" option is incompatible with "--config_file" option')
1382 with
open(config_file
, 'r') as cf
:
1384 ctx
.obj
.nsi
.create(nst_name
, nsi_name
, config
=config
, ssh_keys
=ssh_keys
,
1385 account
=vim_account
, wait
=wait
)
1386 # except ClientException as e:
1391 @cli_osm.command(name
='nsi-create', short_help
='creates a new Network Slice Instance')
1392 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1393 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1394 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1395 @click.option('--ssh_keys', default
=None,
1396 help='comma separated list of keys to inject to vnfs')
1397 @click.option('--config', default
=None,
1398 help='Netslice specific yaml configuration:\n'
1399 'netslice_subnet: [\n'
1400 'id: TEXT, vim_account: TEXT,\n'
1401 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1402 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]\n'
1403 'additionalParamsForNsi: {param: value, ...}\n'
1404 'additionalParamsForsubnet: [{id: SUBNET_ID, additionalParamsForNs: {}, additionalParamsForVnf: {}}]\n'
1406 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1408 @click.option('--config_file',
1410 help='nsi specific yaml configuration file')
1411 @click.option('--wait',
1415 help='do not return the control immediately, but keep it '
1416 'until the operation is completed, or timeout')
1418 def nsi_create1(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1419 """creates a new Network Slice Instance (NSI)"""
1421 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1424 @cli_osm.command(name
='netslice-instance-create', short_help
='creates a new Network Slice Instance')
1425 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1426 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1427 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1428 @click.option('--ssh_keys', default
=None,
1429 help='comma separated list of keys to inject to vnfs')
1430 @click.option('--config', default
=None,
1431 help='Netslice specific yaml configuration:\n'
1432 'netslice_subnet: [\n'
1433 'id: TEXT, vim_account: TEXT,\n'
1434 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1435 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1437 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1439 @click.option('--config_file',
1441 help='nsi specific yaml configuration file')
1442 @click.option('--wait',
1446 help='do not return the control immediately, but keep it '
1447 'until the operation is completed, or timeout')
1449 def nsi_create2(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1450 """creates a new Network Slice Instance (NSI)"""
1452 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1455 @cli_osm.command(name
='pdu-create', short_help
='adds a new Physical Deployment Unit to the catalog')
1456 @click.option('--name', help='name of the Physical Deployment Unit')
1457 @click.option('--pdu_type', help='type of PDU (e.g. router, firewall, FW001)')
1458 @click.option('--interface',
1459 help='interface(s) of the PDU: name=<NAME>,mgmt=<true|false>,ip-address=<IP_ADDRESS>'+
1460 '[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]',
1462 @click.option('--description', help='human readable description')
1463 @click.option('--vim_account', help='list of VIM accounts (in the same VIM) that can reach this PDU', multiple
=True)
1464 @click.option('--descriptor_file', default
=None,
1465 help='PDU descriptor file (as an alternative to using the other arguments')
1467 def pdu_create(ctx
, name
, pdu_type
, interface
, description
, vim_account
, descriptor_file
):
1468 """creates a new Physical Deployment Unit (PDU)"""
1471 check_client_version(ctx
.obj
, ctx
.command
.name
)
1473 if not descriptor_file
:
1475 raise ClientException('in absence of descriptor file, option "--name" is mandatory')
1477 raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory')
1479 raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)')
1481 raise ClientException('in absence of descriptor file, option "--vim_account" is mandatory (at least once)')
1483 with
open(descriptor_file
, 'r') as df
:
1484 pdu
= yaml
.safe_load(df
.read())
1485 if name
: pdu
["name"] = name
1486 if pdu_type
: pdu
["type"] = pdu_type
1487 if description
: pdu
["description"] = description
1488 if vim_account
: pdu
["vim_accounts"] = vim_account
1491 for iface
in interface
:
1492 new_iface
={k
:v
for k
,v
in [i
.split('=') for i
in iface
.split(',')]}
1493 new_iface
["mgmt"] = (new_iface
.get("mgmt","false").lower() == "true")
1494 ifaces_list
.append(new_iface
)
1495 pdu
["interfaces"] = ifaces_list
1496 ctx
.obj
.pdu
.create(pdu
)
1497 # except ClientException as e:
1502 ####################
1504 ####################
1506 def nsd_update(ctx
, name
, content
):
1509 check_client_version(ctx
.obj
, ctx
.command
.name
)
1510 ctx
.obj
.nsd
.update(name
, content
)
1511 # except ClientException as e:
1516 @cli_osm.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
1517 @click.argument('name')
1518 @click.option('--content', default
=None,
1519 help='filename with the NSD/NSpkg replacing the current one')
1521 def nsd_update1(ctx
, name
, content
):
1522 """updates a NSD/NSpkg
1524 NAME: name or ID of the NSD/NSpkg
1527 nsd_update(ctx
, name
, content
)
1530 @cli_osm.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
1531 @click.argument('name')
1532 @click.option('--content', default
=None,
1533 help='filename with the NSD/NSpkg replacing the current one')
1535 def nsd_update2(ctx
, name
, content
):
1536 """updates a NSD/NSpkg
1538 NAME: name or ID of the NSD/NSpkg
1541 nsd_update(ctx
, name
, content
)
1544 def vnfd_update(ctx
, name
, content
):
1547 check_client_version(ctx
.obj
, ctx
.command
.name
)
1548 ctx
.obj
.vnfd
.update(name
, content
)
1549 # except ClientException as e:
1554 @cli_osm.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
1555 @click.argument('name')
1556 @click.option('--content', default
=None,
1557 help='filename with the VNFD/VNFpkg replacing the current one')
1559 def vnfd_update1(ctx
, name
, content
):
1560 """updates a VNFD/VNFpkg
1562 NAME: name or ID of the VNFD/VNFpkg
1565 vnfd_update(ctx
, name
, content
)
1568 @cli_osm.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
1569 @click.argument('name')
1570 @click.option('--content', default
=None,
1571 help='filename with the VNFD/VNFpkg replacing the current one')
1573 def vnfd_update2(ctx
, name
, content
):
1574 """updates a VNFD/VNFpkg
1576 NAME: VNFD yaml file or VNFpkg tar.gz file
1579 vnfd_update(ctx
, name
, content
)
1582 @cli_osm.command(name
='nfpkg-update', short_help
='updates a NFpkg')
1583 @click.argument('name')
1584 @click.option('--content', default
=None,
1585 help='filename with the NFpkg replacing the current one')
1587 def nfpkg_update(ctx
, name
, content
):
1590 NAME: NF Descriptor yaml file or NFpkg tar.gz file
1593 vnfd_update(ctx
, name
, content
)
1596 def nst_update(ctx
, name
, content
):
1599 check_client_version(ctx
.obj
, ctx
.command
.name
)
1600 ctx
.obj
.nst
.update(name
, content
)
1601 # except ClientException as e:
1606 @cli_osm.command(name
='nst-update', short_help
='updates a Network Slice Template (NST)')
1607 @click.argument('name')
1608 @click.option('--content', default
=None,
1609 help='filename with the NST/NSTpkg replacing the current one')
1611 def nst_update1(ctx
, name
, content
):
1612 """updates a Network Slice Template (NST)
1614 NAME: name or ID of the NSD/NSpkg
1617 nst_update(ctx
, name
, content
)
1620 @cli_osm.command(name
='netslice-template-update', short_help
='updates a Network Slice Template (NST)')
1621 @click.argument('name')
1622 @click.option('--content', default
=None,
1623 help='filename with the NST/NSTpkg replacing the current one')
1625 def nst_update2(ctx
, name
, content
):
1626 """updates a Network Slice Template (NST)
1628 NAME: name or ID of the NSD/NSpkg
1631 nst_update(ctx
, name
, content
)
1634 ####################
1636 ####################
1638 def nsd_delete(ctx
, name
, force
):
1642 ctx
.obj
.nsd
.delete(name
)
1644 check_client_version(ctx
.obj
, '--force')
1645 ctx
.obj
.nsd
.delete(name
, force
)
1646 # except ClientException as e:
1651 @cli_osm.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
1652 @click.argument('name')
1653 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1655 def nsd_delete1(ctx
, name
, force
):
1656 """deletes a NSD/NSpkg
1658 NAME: name or ID of the NSD/NSpkg to be deleted
1661 nsd_delete(ctx
, name
, force
)
1664 @cli_osm.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
1665 @click.argument('name')
1666 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1668 def nsd_delete2(ctx
, name
, force
):
1669 """deletes a NSD/NSpkg
1671 NAME: name or ID of the NSD/NSpkg to be deleted
1674 nsd_delete(ctx
, name
, force
)
1677 def vnfd_delete(ctx
, name
, force
):
1681 ctx
.obj
.vnfd
.delete(name
)
1683 check_client_version(ctx
.obj
, '--force')
1684 ctx
.obj
.vnfd
.delete(name
, force
)
1685 # except ClientException as e:
1690 @cli_osm.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
1691 @click.argument('name')
1692 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1694 def vnfd_delete1(ctx
, name
, force
):
1695 """deletes a VNFD/VNFpkg
1697 NAME: name or ID of the VNFD/VNFpkg to be deleted
1700 vnfd_delete(ctx
, name
, force
)
1703 @cli_osm.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
1704 @click.argument('name')
1705 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1707 def vnfd_delete2(ctx
, name
, force
):
1708 """deletes a VNFD/VNFpkg
1710 NAME: name or ID of the VNFD/VNFpkg to be deleted
1713 vnfd_delete(ctx
, name
, force
)
1716 @cli_osm.command(name
='nfpkg-delete', short_help
='deletes a NFpkg')
1717 @click.argument('name')
1718 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1720 def nfpkg_delete(ctx
, name
, force
):
1723 NAME: name or ID of the NFpkg to be deleted
1726 vnfd_delete(ctx
, name
, force
)
1729 @cli_osm.command(name
='ns-delete', short_help
='deletes a NS instance')
1730 @click.argument('name')
1731 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1732 @click.option('--wait',
1736 help='do not return the control immediately, but keep it '
1737 'until the operation is completed, or timeout')
1739 def ns_delete(ctx
, name
, force
, wait
):
1740 """deletes a NS instance
1742 NAME: name or ID of the NS instance to be deleted
1747 ctx
.obj
.ns
.delete(name
, wait
=wait
)
1749 check_client_version(ctx
.obj
, '--force')
1750 ctx
.obj
.ns
.delete(name
, force
, wait
=wait
)
1751 # except ClientException as e:
1756 def nst_delete(ctx
, name
, force
):
1759 check_client_version(ctx
.obj
, ctx
.command
.name
)
1760 ctx
.obj
.nst
.delete(name
, force
)
1761 # except ClientException as e:
1766 @cli_osm.command(name
='nst-delete', short_help
='deletes a Network Slice Template (NST)')
1767 @click.argument('name')
1768 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1770 def nst_delete1(ctx
, name
, force
):
1771 """deletes a Network Slice Template (NST)
1773 NAME: name or ID of the NST/NSTpkg to be deleted
1776 nst_delete(ctx
, name
, force
)
1779 @cli_osm.command(name
='netslice-template-delete', short_help
='deletes a Network Slice Template (NST)')
1780 @click.argument('name')
1781 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1783 def nst_delete2(ctx
, name
, force
):
1784 """deletes a Network Slice Template (NST)
1786 NAME: name or ID of the NST/NSTpkg to be deleted
1789 nst_delete(ctx
, name
, force
)
1792 def nsi_delete(ctx
, name
, force
, wait
):
1795 check_client_version(ctx
.obj
, ctx
.command
.name
)
1796 ctx
.obj
.nsi
.delete(name
, force
, wait
=wait
)
1797 # except ClientException as e:
1802 @cli_osm.command(name
='nsi-delete', short_help
='deletes a Network Slice Instance (NSI)')
1803 @click.argument('name')
1804 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1805 @click.option('--wait',
1809 help='do not return the control immediately, but keep it '
1810 'until the operation is completed, or timeout')
1812 def nsi_delete1(ctx
, name
, force
, wait
):
1813 """deletes a Network Slice Instance (NSI)
1815 NAME: name or ID of the Network Slice instance to be deleted
1818 nsi_delete(ctx
, name
, force
, wait
=wait
)
1821 @cli_osm.command(name
='netslice-instance-delete', short_help
='deletes a Network Slice Instance (NSI)')
1822 @click.argument('name')
1823 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1825 def nsi_delete2(ctx
, name
, force
, wait
):
1826 """deletes a Network Slice Instance (NSI)
1828 NAME: name or ID of the Network Slice instance to be deleted
1831 nsi_delete(ctx
, name
, force
, wait
=wait
)
1834 @cli_osm.command(name
='pdu-delete', short_help
='deletes a Physical Deployment Unit (PDU)')
1835 @click.argument('name')
1836 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1838 def pdu_delete(ctx
, name
, force
):
1839 """deletes a Physical Deployment Unit (PDU)
1841 NAME: name or ID of the PDU to be deleted
1845 check_client_version(ctx
.obj
, ctx
.command
.name
)
1846 ctx
.obj
.pdu
.delete(name
, force
)
1847 # except ClientException as e:
1856 @cli_osm.command(name
='vim-create', short_help
='creates a new VIM account')
1857 @click.option('--name',
1859 help='Name to create datacenter')
1860 @click.option('--user',
1862 help='VIM username')
1863 @click.option('--password',
1866 confirmation_prompt
=True,
1867 help='VIM password')
1868 @click.option('--auth_url',
1871 @click.option('--tenant',
1873 help='VIM tenant name')
1874 @click.option('--config',
1876 help='VIM specific config parameters')
1877 @click.option('--account_type',
1878 default
='openstack',
1880 @click.option('--description',
1881 default
='no description',
1882 help='human readable description')
1883 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
1884 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1885 @click.option('--wait',
1889 help='do not return the control immediately, but keep it '
1890 'until the operation is completed, or timeout')
1904 """creates a new VIM account"""
1908 check_client_version(ctx
.obj
, '--sdn_controller')
1909 if sdn_port_mapping
:
1910 check_client_version(ctx
.obj
, '--sdn_port_mapping')
1912 vim
['vim-username'] = user
1913 vim
['vim-password'] = password
1914 vim
['vim-url'] = auth_url
1915 vim
['vim-tenant-name'] = tenant
1916 vim
['vim-type'] = account_type
1917 vim
['description'] = description
1918 vim
['config'] = config
1919 if sdn_controller
or sdn_port_mapping
:
1920 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
1922 ctx
.obj
.vim
.create(name
, vim
, wait
=wait
)
1923 # except ClientException as e:
1928 @cli_osm.command(name
='vim-update', short_help
='updates a VIM account')
1929 @click.argument('name')
1930 @click.option('--newname', help='New name for the VIM account')
1931 @click.option('--user', help='VIM username')
1932 @click.option('--password', help='VIM password')
1933 @click.option('--auth_url', help='VIM url')
1934 @click.option('--tenant', help='VIM tenant name')
1935 @click.option('--config', help='VIM specific config parameters')
1936 @click.option('--account_type', help='VIM type')
1937 @click.option('--description', help='human readable description')
1938 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
1939 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1940 @click.option('--wait',
1944 help='do not return the control immediately, but keep it '
1945 'until the operation is completed, or timeout')
1960 """updates a VIM account
1962 NAME: name or ID of the VIM account
1966 check_client_version(ctx
.obj
, ctx
.command
.name
)
1968 if newname
: vim
['name'] = newname
1969 if user
: vim
['vim_user'] = user
1970 if password
: vim
['vim_password'] = password
1971 if auth_url
: vim
['vim_url'] = auth_url
1972 if tenant
: vim
['vim-tenant-name'] = tenant
1973 if account_type
: vim
['vim_type'] = account_type
1974 if description
: vim
['description'] = description
1975 if config
: vim
['config'] = config
1976 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
1977 # except ClientException as e:
1982 @cli_osm.command(name
='vim-delete', short_help
='deletes a VIM account')
1983 @click.argument('name')
1984 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1985 @click.option('--wait',
1989 help='do not return the control immediately, but keep it '
1990 'until the operation is completed, or timeout')
1992 def vim_delete(ctx
, name
, force
, wait
):
1993 """deletes a VIM account
1995 NAME: name or ID of the VIM account to be deleted
2000 ctx
.obj
.vim
.delete(name
, wait
=wait
)
2002 check_client_version(ctx
.obj
, '--force')
2003 ctx
.obj
.vim
.delete(name
, force
, wait
=wait
)
2004 # except ClientException as e:
2009 @cli_osm.command(name
='vim-list', short_help
='list all VIM accounts')
2010 #@click.option('--ro_update/--no_ro_update',
2012 # help='update list from RO')
2013 @click.option('--filter', default
=None,
2014 help='restricts the list to the VIM accounts matching the filter')
2016 def vim_list(ctx
, filter):
2017 """list all VIM accounts"""
2020 check_client_version(ctx
.obj
, '--filter')
2022 # check_client_version(ctx.obj, '--ro_update', 'v1')
2023 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
2024 if fullclassname
== 'osmclient.sol005.client.Client':
2025 resp
= ctx
.obj
.vim
.list(filter)
2027 # resp = ctx.obj.vim.list(ro_update)
2028 table
= PrettyTable(['vim name', 'uuid'])
2030 table
.add_row([vim
['name'], vim
['uuid']])
2035 @cli_osm.command(name
='vim-show', short_help
='shows the details of a VIM account')
2036 @click.argument('name')
2038 def vim_show(ctx
, name
):
2039 """shows the details of a VIM account
2041 NAME: name or ID of the VIM account
2045 resp
= ctx
.obj
.vim
.get(name
)
2046 if 'vim_password' in resp
:
2047 resp
['vim_password']='********'
2048 # except ClientException as e:
2052 table
= PrettyTable(['key', 'attribute'])
2053 for k
, v
in list(resp
.items()):
2054 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2059 ####################
2061 ####################
2063 @cli_osm.command(name
='wim-create', short_help
='creates a new WIM account')
2064 @click.option('--name',
2066 help='Name for the WIM account')
2067 @click.option('--user',
2068 help='WIM username')
2069 @click.option('--password',
2070 help='WIM password')
2071 @click.option('--url',
2074 # @click.option('--tenant',
2075 # help='wIM tenant name')
2076 @click.option('--config',
2078 help='WIM specific config parameters')
2079 @click.option('--wim_type',
2081 @click.option('--description',
2082 default
='no description',
2083 help='human readable description')
2084 @click.option('--wim_port_mapping', default
=None,
2085 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2086 "(WAN service endpoint id and info)")
2087 @click.option('--wait',
2091 help='do not return the control immediately, but keep it '
2092 'until the operation is completed, or timeout')
2105 """creates a new WIM account"""
2108 check_client_version(ctx
.obj
, ctx
.command
.name
)
2109 # if sdn_controller:
2110 # check_client_version(ctx.obj, '--sdn_controller')
2111 # if sdn_port_mapping:
2112 # check_client_version(ctx.obj, '--sdn_port_mapping')
2114 if user
: wim
['user'] = user
2115 if password
: wim
['password'] = password
2116 if url
: wim
['wim_url'] = url
2117 # if tenant: wim['tenant'] = tenant
2118 wim
['wim_type'] = wim_type
2119 if description
: wim
['description'] = description
2120 if config
: wim
['config'] = config
2121 ctx
.obj
.wim
.create(name
, wim
, wim_port_mapping
, wait
=wait
)
2122 # except ClientException as e:
2127 @cli_osm.command(name
='wim-update', short_help
='updates a WIM account')
2128 @click.argument('name')
2129 @click.option('--newname', help='New name for the WIM account')
2130 @click.option('--user', help='WIM username')
2131 @click.option('--password', help='WIM password')
2132 @click.option('--url', help='WIM url')
2133 @click.option('--config', help='WIM specific config parameters')
2134 @click.option('--wim_type', help='WIM type')
2135 @click.option('--description', help='human readable description')
2136 @click.option('--wim_port_mapping', default
=None,
2137 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2138 "(WAN service endpoint id and info)")
2139 @click.option('--wait',
2143 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2156 """updates a WIM account
2158 NAME: name or ID of the WIM account
2162 check_client_version(ctx
.obj
, ctx
.command
.name
)
2164 if newname
: wim
['name'] = newname
2165 if user
: wim
['user'] = user
2166 if password
: wim
['password'] = password
2167 if url
: wim
['url'] = url
2168 # if tenant: wim['tenant'] = tenant
2169 if wim_type
: wim
['wim_type'] = wim_type
2170 if description
: wim
['description'] = description
2171 if config
: wim
['config'] = config
2172 ctx
.obj
.wim
.update(name
, wim
, wim_port_mapping
, wait
=wait
)
2173 # except ClientException as e:
2178 @cli_osm.command(name
='wim-delete', short_help
='deletes a WIM account')
2179 @click.argument('name')
2180 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2181 @click.option('--wait',
2185 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2187 def wim_delete(ctx
, name
, force
, wait
):
2188 """deletes a WIM account
2190 NAME: name or ID of the WIM account to be deleted
2194 check_client_version(ctx
.obj
, ctx
.command
.name
)
2195 ctx
.obj
.wim
.delete(name
, force
, wait
=wait
)
2196 # except ClientException as e:
2201 @cli_osm.command(name
='wim-list', short_help
='list all WIM accounts')
2202 @click.option('--filter', default
=None,
2203 help='restricts the list to the WIM accounts matching the filter')
2205 def wim_list(ctx
, filter):
2206 """list all WIM accounts"""
2209 check_client_version(ctx
.obj
, ctx
.command
.name
)
2210 resp
= ctx
.obj
.wim
.list(filter)
2211 table
= PrettyTable(['wim name', 'uuid'])
2213 table
.add_row([wim
['name'], wim
['uuid']])
2216 # except ClientException as e:
2221 @cli_osm.command(name
='wim-show', short_help
='shows the details of a WIM account')
2222 @click.argument('name')
2224 def wim_show(ctx
, name
):
2225 """shows the details of a WIM account
2227 NAME: name or ID of the WIM account
2231 check_client_version(ctx
.obj
, ctx
.command
.name
)
2232 resp
= ctx
.obj
.wim
.get(name
)
2233 if 'password' in resp
:
2234 resp
['wim_password']='********'
2235 # except ClientException as e:
2239 table
= PrettyTable(['key', 'attribute'])
2240 for k
, v
in list(resp
.items()):
2241 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2246 ####################
2247 # SDN controller operations
2248 ####################
2250 @cli_osm.command(name
='sdnc-create', short_help
='creates a new SDN controller')
2251 @click.option('--name',
2253 help='Name to create sdn controller')
2254 @click.option('--type',
2256 help='SDN controller type')
2257 @click.option('--sdn_controller_version', # hidden=True,
2258 help='Deprecated. Use --config {version: sdn_controller_version}')
2259 @click.option('--url',
2260 help='URL in format http[s]://HOST:IP/')
2261 @click.option('--ip_address', # hidden=True,
2262 help='Deprecated. Use --url')
2263 @click.option('--port', # hidden=True,
2264 help='Deprecated. Use --url')
2265 @click.option('--switch_dpid', # hidden=True,
2266 help='Deprecated. Use --config {dpid: DPID}')
2267 @click.option('--config',
2268 help='Extra information for SDN in yaml format, as {dpid: (Openflow Datapath ID), version: version}')
2269 @click.option('--user',
2270 help='SDN controller username')
2271 @click.option('--password',
2273 confirmation_prompt
=True,
2274 help='SDN controller password')
2275 @click.option('--description', default
=None, help='human readable description')
2276 @click.option('--wait',
2280 help="do not return the control immediately, but keep it until the operation is completed, or timeout")
2282 def sdnc_create(ctx
, **kwargs
):
2283 """creates a new SDN controller"""
2285 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2286 x
not in ("wait", "ip_address", "port", "switch_dpid")}
2287 if kwargs
.get("port"):
2288 print("option '--port' is deprecated, use '-url' instead")
2289 sdncontroller
["port"] = int(kwargs
["port"])
2290 if kwargs
.get("ip_address"):
2291 print("option '--ip_address' is deprecated, use '-url' instead")
2292 sdncontroller
["ip"] = kwargs
["ip_address"]
2293 if kwargs
.get("switch_dpid"):
2294 print("option '--switch_dpid' is deprecated, use '---config={dpid: DPID}' instead")
2295 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2296 if kwargs
.get("sdn_controller_version"):
2297 print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'"
2300 check_client_version(ctx
.obj
, ctx
.command
.name
)
2301 ctx
.obj
.sdnc
.create(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2302 # except ClientException as e:
2306 @cli_osm.command(name
='sdnc-update', short_help
='updates an SDN controller')
2307 @click.argument('name')
2308 @click.option('--newname', help='New name for the SDN controller')
2309 @click.option('--description', default
=None, help='human readable description')
2310 @click.option('--type', help='SDN controller type')
2311 @click.option('--url', help='URL in format http[s]://HOST:IP/')
2312 @click.option('--config', help='Extra information for SDN in yaml format, as '
2313 '{dpid: (Openflow Datapath ID), version: version}')
2314 @click.option('--user', help='SDN controller username')
2315 @click.option('--password', help='SDN controller password')
2316 @click.option('--ip_address', help='Deprecated. Use --url') # hidden=True
2317 @click.option('--port', help='Deprecated. Use --url') # hidden=True
2318 @click.option('--switch_dpid', help='Deprecated. Use --config {switch_dpid: DPID}') # hidden=True
2319 @click.option('--sdn_controller_version', help='Deprecated. Use --config {version: VERSION}') # hidden=True
2320 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2321 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2323 def sdnc_update(ctx
, **kwargs
):
2324 """updates an SDN controller
2326 NAME: name or ID of the SDN controller
2329 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2330 x
not in ("wait", "ip_address", "port", "switch_dpid", "new_name")}
2331 if kwargs
.get("newname"):
2332 sdncontroller
["name"] = kwargs
["newname"]
2333 if kwargs
.get("port"):
2334 print("option '--port' is deprecated, use '-url' instead")
2335 sdncontroller
["port"] = int(kwargs
["port"])
2336 if kwargs
.get("ip_address"):
2337 print("option '--ip_address' is deprecated, use '-url' instead")
2338 sdncontroller
["ip"] = kwargs
["ip_address"]
2339 if kwargs
.get("switch_dpid"):
2340 print("option '--switch_dpid' is deprecated, use '---config={dpid: DPID}' instead")
2341 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2342 if kwargs
.get("sdn_controller_version"):
2343 print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'"
2347 check_client_version(ctx
.obj
, ctx
.command
.name
)
2348 ctx
.obj
.sdnc
.update(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2349 # except ClientException as e:
2354 @cli_osm.command(name
='sdnc-delete', short_help
='deletes an SDN controller')
2355 @click.argument('name')
2356 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2357 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2358 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2360 def sdnc_delete(ctx
, name
, force
, wait
):
2361 """deletes an SDN controller
2363 NAME: name or ID of the SDN controller to be deleted
2367 check_client_version(ctx
.obj
, ctx
.command
.name
)
2368 ctx
.obj
.sdnc
.delete(name
, force
, wait
=wait
)
2369 # except ClientException as e:
2374 @cli_osm.command(name
='sdnc-list', short_help
='list all SDN controllers')
2375 @click.option('--filter', default
=None,
2376 help="restricts the list to the SDN controllers matching the filter with format: 'k[.k..]=v[&k[.k]=v2]'")
2378 def sdnc_list(ctx
, filter):
2379 """list all SDN controllers"""
2382 check_client_version(ctx
.obj
, ctx
.command
.name
)
2383 resp
= ctx
.obj
.sdnc
.list(filter)
2384 # except ClientException as e:
2387 table
= PrettyTable(['sdnc name', 'id'])
2389 table
.add_row([sdnc
['name'], sdnc
['_id']])
2394 @cli_osm.command(name
='sdnc-show', short_help
='shows the details of an SDN controller')
2395 @click.argument('name')
2397 def sdnc_show(ctx
, name
):
2398 """shows the details of an SDN controller
2400 NAME: name or ID of the SDN controller
2404 check_client_version(ctx
.obj
, ctx
.command
.name
)
2405 resp
= ctx
.obj
.sdnc
.get(name
)
2406 # except ClientException as e:
2410 table
= PrettyTable(['key', 'attribute'])
2411 for k
, v
in list(resp
.items()):
2412 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2417 ###########################
2418 # K8s cluster operations
2419 ###########################
2421 @cli_osm.command(name
='k8scluster-add')
2422 @click.argument('name')
2423 @click.option('--creds',
2425 help='credentials file, i.e. a valid `.kube/config` file')
2426 @click.option('--version',
2428 help='Kubernetes version')
2429 @click.option('--vim',
2431 help='VIM target, the VIM where the cluster resides')
2432 @click.option('--k8s-nets',
2434 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) ...]}"')
2435 @click.option('--description',
2437 help='human readable description')
2438 @click.option('--namespace',
2439 default
='kube-system',
2440 help='namespace to be used for its operation, defaults to `kube-system`')
2441 @click.option('--cni',
2443 help='list of CNI plugins, in JSON inline format, used in the cluster')
2444 #@click.option('--skip-init',
2446 # help='If set, K8s cluster is assumed to be ready for its use with OSM')
2447 #@click.option('--wait',
2449 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2451 def k8scluster_add(ctx
,
2460 """adds a K8s cluster to OSM
2462 NAME: name of the K8s cluster
2465 check_client_version(ctx
.obj
, ctx
.command
.name
)
2467 cluster
['name'] = name
2468 with
open(creds
, 'r') as cf
:
2469 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2470 cluster
['k8s_version'] = version
2471 cluster
['vim_account'] = vim
2472 cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2473 cluster
['description'] = description
2474 if namespace
: cluster
['namespace'] = namespace
2475 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2476 ctx
.obj
.k8scluster
.create(name
, cluster
)
2477 # except ClientException as e:
2482 @cli_osm.command(name
='k8scluster-update', short_help
='updates a K8s cluster')
2483 @click.argument('name')
2484 @click.option('--newname', help='New name for the K8s cluster')
2485 @click.option('--creds', help='credentials file, i.e. a valid `.kube/config` file')
2486 @click.option('--version', help='Kubernetes version')
2487 @click.option('--vim', help='VIM target, the VIM where the cluster resides')
2488 @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) ...]}"')
2489 @click.option('--description', help='human readable description')
2490 @click.option('--namespace', help='namespace to be used for its operation, defaults to `kube-system`')
2491 @click.option('--cni', help='list of CNI plugins, in JSON inline format, used in the cluster')
2493 def k8scluster_update(ctx
,
2503 """updates a K8s cluster
2505 NAME: name or ID of the K8s cluster
2508 check_client_version(ctx
.obj
, ctx
.command
.name
)
2510 if newname
: cluster
['name'] = newname
2512 with
open(creds
, 'r') as cf
:
2513 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2514 if version
: cluster
['k8s_version'] = version
2515 if vim
: cluster
['vim_account'] = vim
2516 if k8s_nets
: cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2517 if description
: cluster
['description'] = description
2518 if namespace
: cluster
['namespace'] = namespace
2519 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2520 ctx
.obj
.k8scluster
.update(name
, cluster
)
2521 # except ClientException as e:
2526 @cli_osm.command(name
='k8scluster-delete')
2527 @click.argument('name')
2528 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2529 #@click.option('--wait',
2531 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2533 def k8scluster_delete(ctx
, name
, force
):
2534 """deletes a K8s cluster
2536 NAME: name or ID of the K8s cluster to be deleted
2539 check_client_version(ctx
.obj
, ctx
.command
.name
)
2540 ctx
.obj
.k8scluster
.delete(name
, force
=force
)
2541 # except ClientException as e:
2546 @cli_osm.command(name
='k8scluster-list')
2547 @click.option('--filter', default
=None,
2548 help='restricts the list to the K8s clusters matching the filter')
2549 @click.option('--literal', is_flag
=True,
2550 help='print literally, no pretty table')
2552 def k8scluster_list(ctx
, filter, literal
):
2553 """list all K8s clusters"""
2555 check_client_version(ctx
.obj
, ctx
.command
.name
)
2556 resp
= ctx
.obj
.k8scluster
.list(filter)
2558 print(yaml
.safe_dump(resp
))
2560 table
= PrettyTable(['Name', 'Id', 'Version', 'VIM', 'K8s-nets', 'Operational State', 'Description'])
2561 for cluster
in resp
:
2562 table
.add_row([cluster
['name'], cluster
['_id'], cluster
['k8s_version'], cluster
['vim_account'],
2563 json
.dumps(cluster
['nets']), cluster
["_admin"]["operationalState"],
2564 trunc_text(cluster
.get('description',''),40)])
2567 # except ClientException as e:
2572 @cli_osm.command(name
='k8scluster-show')
2573 @click.argument('name')
2574 @click.option('--literal', is_flag
=True,
2575 help='print literally, no pretty table')
2577 def k8scluster_show(ctx
, name
, literal
):
2578 """shows the details of a K8s cluster
2580 NAME: name or ID of the K8s cluster
2583 resp
= ctx
.obj
.k8scluster
.get(name
)
2585 print(yaml
.safe_dump(resp
))
2587 table
= PrettyTable(['key', 'attribute'])
2588 for k
, v
in list(resp
.items()):
2589 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2592 # except ClientException as e:
2598 ###########################
2600 ###########################
2602 @cli_osm.command(name
='repo-add')
2603 @click.argument('name')
2604 @click.argument('uri')
2605 @click.option('--type',
2606 type=click
.Choice(['helm-chart', 'juju-bundle']),
2608 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2609 @click.option('--description',
2611 help='human readable description')
2612 #@click.option('--wait',
2614 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2621 """adds a repo to OSM
2623 NAME: name of the repo
2624 URI: URI of the repo
2627 check_client_version(ctx
.obj
, ctx
.command
.name
)
2632 repo
['description'] = description
2633 ctx
.obj
.repo
.create(name
, repo
)
2634 # except ClientException as e:
2639 @cli_osm.command(name
='repo-update')
2640 @click.argument('name')
2641 @click.option('--newname', help='New name for the repo')
2642 @click.option('--uri', help='URI of the repo')
2643 @click.option('--type', type=click
.Choice(['helm-chart', 'juju-bundle']),
2644 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2645 @click.option('--description', help='human readable description')
2646 #@click.option('--wait',
2648 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2650 def repo_update(ctx
,
2656 """updates a repo in OSM
2658 NAME: name of the repo
2661 check_client_version(ctx
.obj
, ctx
.command
.name
)
2663 if newname
: repo
['name'] = newname
2664 if uri
: repo
['uri'] = uri
2665 if type: repo
['type'] = type
2666 if description
: repo
['description'] = description
2667 ctx
.obj
.repo
.update(name
, repo
)
2668 # except ClientException as e:
2673 @cli_osm.command(name
='repo-delete')
2674 @click.argument('name')
2675 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2676 #@click.option('--wait',
2678 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2680 def repo_delete(ctx
, name
, force
):
2683 NAME: name or ID of the repo to be deleted
2686 check_client_version(ctx
.obj
, ctx
.command
.name
)
2687 ctx
.obj
.repo
.delete(name
, force
=force
)
2688 # except ClientException as e:
2693 @cli_osm.command(name
='repo-list')
2694 @click.option('--filter', default
=None,
2695 help='restricts the list to the repos matching the filter')
2696 @click.option('--literal', is_flag
=True,
2697 help='print literally, no pretty table')
2699 def repo_list(ctx
, filter, literal
):
2700 """list all repos"""
2702 check_client_version(ctx
.obj
, ctx
.command
.name
)
2703 resp
= ctx
.obj
.repo
.list(filter)
2705 print(yaml
.safe_dump(resp
))
2707 table
= PrettyTable(['Name', 'Id', 'Type', 'URI', 'Description'])
2709 #cluster['k8s-nets'] = json.dumps(yaml.safe_load(cluster['k8s-nets']))
2710 table
.add_row([repo
['name'], repo
['_id'], repo
['type'], repo
['url'], trunc_text(repo
.get('description',''),40)])
2713 # except ClientException as e:
2718 @cli_osm.command(name
='repo-show')
2719 @click.argument('name')
2720 @click.option('--literal', is_flag
=True,
2721 help='print literally, no pretty table')
2723 def repo_show(ctx
, name
, literal
):
2724 """shows the details of a repo
2726 NAME: name or ID of the repo
2729 resp
= ctx
.obj
.repo
.get(name
)
2731 print(yaml
.safe_dump(resp
))
2733 table
= PrettyTable(['key', 'attribute'])
2734 for k
, v
in list(resp
.items()):
2735 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2738 # except ClientException as e:
2744 ####################
2745 # Project mgmt operations
2746 ####################
2748 @cli_osm.command(name
='project-create', short_help
='creates a new project')
2749 @click.argument('name')
2750 #@click.option('--description',
2751 # default='no description',
2752 # help='human readable description')
2754 def project_create(ctx
, name
):
2755 """Creates a new project
2757 NAME: name of the project
2761 project
['name'] = name
2763 check_client_version(ctx
.obj
, ctx
.command
.name
)
2764 ctx
.obj
.project
.create(name
, project
)
2765 # except ClientException as e:
2770 @cli_osm.command(name
='project-delete', short_help
='deletes a project')
2771 @click.argument('name')
2772 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2774 def project_delete(ctx
, name
):
2775 """deletes a project
2777 NAME: name or ID of the project to be deleted
2781 check_client_version(ctx
.obj
, ctx
.command
.name
)
2782 ctx
.obj
.project
.delete(name
)
2783 # except ClientException as e:
2788 @cli_osm.command(name
='project-list', short_help
='list all projects')
2789 @click.option('--filter', default
=None,
2790 help='restricts the list to the projects matching the filter')
2792 def project_list(ctx
, filter):
2793 """list all projects"""
2796 check_client_version(ctx
.obj
, ctx
.command
.name
)
2797 resp
= ctx
.obj
.project
.list(filter)
2798 # except ClientException as e:
2801 table
= PrettyTable(['name', 'id'])
2803 table
.add_row([proj
['name'], proj
['_id']])
2808 @cli_osm.command(name
='project-show', short_help
='shows the details of a project')
2809 @click.argument('name')
2811 def project_show(ctx
, name
):
2812 """shows the details of a project
2814 NAME: name or ID of the project
2818 check_client_version(ctx
.obj
, ctx
.command
.name
)
2819 resp
= ctx
.obj
.project
.get(name
)
2820 # except ClientException as e:
2824 table
= PrettyTable(['key', 'attribute'])
2825 for k
, v
in resp
.items():
2826 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2831 @cli_osm.command(name
='project-update', short_help
='updates a project (only the name can be updated)')
2832 @click.argument('project')
2833 @click.option('--name',
2835 help='new name for the project')
2838 def project_update(ctx
, project
, name
):
2840 Update a project name
2843 :param project: id or name of the project to modify
2844 :param name: new name for the project
2848 project_changes
= {}
2849 project_changes
['name'] = name
2852 check_client_version(ctx
.obj
, ctx
.command
.name
)
2853 ctx
.obj
.project
.update(project
, project_changes
)
2854 # except ClientException as e:
2858 ####################
2859 # User mgmt operations
2860 ####################
2862 @cli_osm.command(name
='user-create', short_help
='creates a new user')
2863 @click.argument('username')
2864 @click.option('--password',
2867 confirmation_prompt
=True,
2868 help='user password')
2869 @click.option('--projects',
2870 # prompt="Comma separate list of projects",
2872 callback
=lambda ctx
, param
, value
: ''.join(value
).split(',') if all(len(x
)==1 for x
in value
) else value
,
2873 help='list of project ids that the user belongs to')
2874 @click.option('--project-role-mappings', 'project_role_mappings',
2875 default
=None, multiple
=True,
2876 help='creating user project/role(s) mapping')
2878 def user_create(ctx
, username
, password
, projects
, project_role_mappings
):
2879 """Creates a new user
2882 USERNAME: name of the user
2883 PASSWORD: password of the user
2884 PROJECTS: projects assigned to user (internal only)
2885 PROJECT_ROLE_MAPPING: roles in projects assigned to user (keystone)
2889 user
['username'] = username
2890 user
['password'] = password
2891 user
['projects'] = projects
2892 user
['project_role_mappings'] = project_role_mappings
2895 check_client_version(ctx
.obj
, ctx
.command
.name
)
2896 ctx
.obj
.user
.create(username
, user
)
2897 # except ClientException as e:
2902 @cli_osm.command(name
='user-update', short_help
='updates user information')
2903 @click.argument('username')
2904 @click.option('--password',
2907 # confirmation_prompt=True,
2908 help='user password')
2909 @click.option('--set-username', 'set_username',
2911 help='change username')
2912 @click.option('--set-project', 'set_project',
2913 default
=None, multiple
=True,
2914 help='create/replace the project,role(s) mapping for this project: \'project,role1,role2,...\'')
2915 @click.option('--remove-project', 'remove_project',
2916 default
=None, multiple
=True,
2917 help='removes project from user: \'project\'')
2918 @click.option('--add-project-role', 'add_project_role',
2919 default
=None, multiple
=True,
2920 help='adds project,role(s) mapping: \'project,role1,role2,...\'')
2921 @click.option('--remove-project-role', 'remove_project_role',
2922 default
=None, multiple
=True,
2923 help='removes project,role(s) mapping: \'project,role1,role2,...\'')
2925 def user_update(ctx
, username
, password
, set_username
, set_project
, remove_project
,
2926 add_project_role
, remove_project_role
):
2927 """Update a user information
2930 USERNAME: name of the user
2931 PASSWORD: new password
2932 SET_USERNAME: new username
2933 SET_PROJECT: creating mappings for project/role(s)
2934 REMOVE_PROJECT: deleting mappings for project/role(s)
2935 ADD_PROJECT_ROLE: adding mappings for project/role(s)
2936 REMOVE_PROJECT_ROLE: removing mappings for project/role(s)
2940 user
['password'] = password
2941 user
['username'] = set_username
2942 user
['set-project'] = set_project
2943 user
['remove-project'] = remove_project
2944 user
['add-project-role'] = add_project_role
2945 user
['remove-project-role'] = remove_project_role
2948 check_client_version(ctx
.obj
, ctx
.command
.name
)
2949 ctx
.obj
.user
.update(username
, user
)
2950 # except ClientException as e:
2955 @cli_osm.command(name
='user-delete', short_help
='deletes a user')
2956 @click.argument('name')
2957 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2959 def user_delete(ctx
, name
):
2963 NAME: name or ID of the user to be deleted
2967 check_client_version(ctx
.obj
, ctx
.command
.name
)
2968 ctx
.obj
.user
.delete(name
)
2969 # except ClientException as e:
2974 @cli_osm.command(name
='user-list', short_help
='list all users')
2975 @click.option('--filter', default
=None,
2976 help='restricts the list to the users matching the filter')
2978 def user_list(ctx
, filter):
2979 """list all users"""
2981 check_client_version(ctx
.obj
, ctx
.command
.name
)
2982 resp
= ctx
.obj
.user
.list(filter)
2983 # except ClientException as e:
2986 table
= PrettyTable(['name', 'id'])
2988 table
.add_row([user
['username'], user
['_id']])
2993 @cli_osm.command(name
='user-show', short_help
='shows the details of a user')
2994 @click.argument('name')
2996 def user_show(ctx
, name
):
2997 """shows the details of a user
2999 NAME: name or ID of the user
3003 check_client_version(ctx
.obj
, ctx
.command
.name
)
3004 resp
= ctx
.obj
.user
.get(name
)
3005 if 'password' in resp
:
3006 resp
['password']='********'
3007 # except ClientException as e:
3011 table
= PrettyTable(['key', 'attribute'])
3012 for k
, v
in resp
.items():
3013 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3018 ####################
3019 # Fault Management operations
3020 ####################
3022 @cli_osm.command(name
='ns-alarm-create')
3023 @click.argument('name')
3024 @click.option('--ns', prompt
=True, help='NS instance id or name')
3025 @click.option('--vnf', prompt
=True,
3026 help='VNF name (VNF member index as declared in the NSD)')
3027 @click.option('--vdu', prompt
=True,
3028 help='VDU name (VDU name as declared in the VNFD)')
3029 @click.option('--metric', prompt
=True,
3030 help='Name of the metric (e.g. cpu_utilization)')
3031 @click.option('--severity', default
='WARNING',
3032 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
3033 @click.option('--threshold_value', prompt
=True,
3034 help='threshold value that, when crossed, an alarm is triggered')
3035 @click.option('--threshold_operator', prompt
=True,
3036 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
3037 @click.option('--statistic', default
='AVERAGE',
3038 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
3040 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
3041 threshold_value
, threshold_operator
, statistic
):
3042 """creates a new alarm for a NS instance"""
3043 # TODO: Check how to validate threshold_value.
3044 # Should it be an integer (1-100), percentage, or decimal (0.01-1.00)?
3047 ns_instance
= ctx
.obj
.ns
.get(ns
)
3049 alarm
['alarm_name'] = name
3050 alarm
['ns_id'] = ns_instance
['_id']
3051 alarm
['correlation_id'] = ns_instance
['_id']
3052 alarm
['vnf_member_index'] = vnf
3053 alarm
['vdu_name'] = vdu
3054 alarm
['metric_name'] = metric
3055 alarm
['severity'] = severity
3056 alarm
['threshold_value'] = int(threshold_value
)
3057 alarm
['operation'] = threshold_operator
3058 alarm
['statistic'] = statistic
3059 check_client_version(ctx
.obj
, ctx
.command
.name
)
3060 ctx
.obj
.ns
.create_alarm(alarm
)
3061 # except ClientException as e:
3066 #@cli_osm.command(name='ns-alarm-delete')
3067 #@click.argument('name')
3068 #@click.pass_context
3069 #def ns_alarm_delete(ctx, name):
3070 # """deletes an alarm
3072 # NAME: name of the alarm to be deleted
3075 # check_client_version(ctx.obj, ctx.command.name)
3076 # ctx.obj.ns.delete_alarm(name)
3077 # except ClientException as e:
3082 ####################
3083 # Performance Management operations
3084 ####################
3086 @cli_osm.command(name
='ns-metric-export', short_help
='exports a metric to the internal OSM bus, which can be read by other apps')
3087 @click.option('--ns', prompt
=True, help='NS instance id or name')
3088 @click.option('--vnf', prompt
=True,
3089 help='VNF name (VNF member index as declared in the NSD)')
3090 @click.option('--vdu', prompt
=True,
3091 help='VDU name (VDU name as declared in the VNFD)')
3092 @click.option('--metric', prompt
=True,
3093 help='name of the metric (e.g. cpu_utilization)')
3094 #@click.option('--period', default='1w',
3095 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
3096 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
3098 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
3099 """exports a metric to the internal OSM bus, which can be read by other apps"""
3100 # TODO: Check how to validate interval.
3101 # Should it be an integer (seconds), or should a suffix (s,m,h,d,w) also be permitted?
3104 ns_instance
= ctx
.obj
.ns
.get(ns
)
3106 metric_data
['ns_id'] = ns_instance
['_id']
3107 metric_data
['correlation_id'] = ns_instance
['_id']
3108 metric_data
['vnf_member_index'] = vnf
3109 metric_data
['vdu_name'] = vdu
3110 metric_data
['metric_name'] = metric
3111 metric_data
['collection_unit'] = 'WEEK'
3112 metric_data
['collection_period'] = 1
3113 check_client_version(ctx
.obj
, ctx
.command
.name
)
3115 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
3119 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
3120 time
.sleep(int(interval
))
3122 # except ClientException as e:
3127 ####################
3129 ####################
3131 @cli_osm.command(name
='version')
3133 def get_version(ctx
):
3135 check_client_version(ctx
.obj
, "version")
3136 print ("Server version: {}".format(ctx
.obj
.get_version()))
3137 print ("Client version: {}".format(pkg_resources
.get_distribution("osmclient").version
))
3138 # except ClientException as e:
3142 @cli_osm.command(name
='upload-package', short_help
='uploads a VNF package or NS package')
3143 @click.argument('filename')
3145 def upload_package(ctx
, filename
):
3146 """uploads a VNF package or NS package
3148 FILENAME: VNF or NS package file (tar.gz)
3152 ctx
.obj
.package
.upload(filename
)
3153 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
3154 if fullclassname
!= 'osmclient.sol005.client.Client':
3155 ctx
.obj
.package
.wait_for_upload(filename
)
3156 # except ClientException as e:
3161 #@cli_osm.command(name='ns-scaling-show')
3162 #@click.argument('ns_name')
3163 #@click.pass_context
3164 #def show_ns_scaling(ctx, ns_name):
3165 # """shows the status of a NS scaling operation
3167 # NS_NAME: name of the NS instance being scaled
3170 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3171 # resp = ctx.obj.ns.list()
3172 # except ClientException as e:
3176 # table = PrettyTable(
3179 # 'operational status',
3184 # if ns_name == ns['name']:
3185 # nsopdata = ctx.obj.ns.get_opdata(ns['id'])
3186 # scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
3187 # for record in scaling_records:
3188 # if 'instance' in record:
3189 # instances = record['instance']
3190 # for inst in instances:
3192 # [record['scaling-group-name-ref'],
3193 # inst['instance-id'],
3194 # inst['op-status'],
3195 # time.strftime('%Y-%m-%d %H:%M:%S',
3197 # inst['create-time'])),
3203 #@cli_osm.command(name='ns-scale')
3204 #@click.argument('ns_name')
3205 #@click.option('--ns_scale_group', prompt=True)
3206 #@click.option('--index', prompt=True)
3207 #@click.option('--wait',
3211 # help='do not return the control immediately, but keep it \
3212 # until the operation is completed, or timeout')
3213 #@click.pass_context
3214 #def ns_scale(ctx, ns_name, ns_scale_group, index, wait):
3217 # NS_NAME: name of the NS instance to be scaled
3220 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3221 # ctx.obj.ns.scale(ns_name, ns_scale_group, index, wait=wait)
3222 # except ClientException as e:
3227 #@cli_osm.command(name='config-agent-list')
3228 #@click.pass_context
3229 #def config_agent_list(ctx):
3230 # """list config agents"""
3232 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3233 # except ClientException as e:
3236 # table = PrettyTable(['name', 'account-type', 'details'])
3237 # for account in ctx.obj.vca.list():
3240 # account['account-type'],
3246 #@cli_osm.command(name='config-agent-delete')
3247 #@click.argument('name')
3248 #@click.pass_context
3249 #def config_agent_delete(ctx, name):
3250 # """deletes a config agent
3252 # NAME: name of the config agent to be deleted
3255 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3256 # ctx.obj.vca.delete(name)
3257 # except ClientException as e:
3262 #@cli_osm.command(name='config-agent-add')
3263 #@click.option('--name',
3265 #@click.option('--account_type',
3267 #@click.option('--server',
3269 #@click.option('--user',
3271 #@click.option('--secret',
3274 # confirmation_prompt=True)
3275 #@click.pass_context
3276 #def config_agent_add(ctx, name, account_type, server, user, secret):
3277 # """adds a config agent"""
3279 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3280 # ctx.obj.vca.create(name, account_type, server, user, secret)
3281 # except ClientException as e:
3286 #@cli_osm.command(name='ro-dump')
3287 #@click.pass_context
3289 # """shows RO agent information"""
3290 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3291 # resp = ctx.obj.vim.get_resource_orchestrator()
3292 # table = PrettyTable(['key', 'attribute'])
3293 # for k, v in list(resp.items()):
3294 # table.add_row([k, json.dumps(v, indent=2)])
3299 #@cli_osm.command(name='vcs-list')
3300 #@click.pass_context
3302 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3303 # resp = ctx.obj.utils.get_vcs_info()
3304 # table = PrettyTable(['component name', 'state'])
3305 # for component in resp:
3306 # table.add_row([component['component_name'], component['state']])
3311 @cli_osm.command(name
='ns-action', short_help
='executes an action/primitive over a NS instance')
3312 @click.argument('ns_name')
3313 @click.option('--vnf_name', default
=None, help='member-vnf-index if the target is a vnf instead of a ns)')
3314 @click.option('--kdu_name', default
=None, help='kdu-name if the target is a kdu)')
3315 @click.option('--vdu_id', default
=None, help='vdu-id if the target is a vdu')
3316 @click.option('--vdu_count', default
=None, help='number of vdu instance of this vdu_id')
3317 @click.option('--action_name', prompt
=True, help='action name')
3318 @click.option('--params', default
=None, help='action params in YAML/JSON inline string')
3319 @click.option('--params_file', default
=None, help='YAML/JSON file with action params')
3320 @click.option('--wait',
3324 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3336 """executes an action/primitive over a NS instance
3338 NS_NAME: name or ID of the NS instance
3342 check_client_version(ctx
.obj
, ctx
.command
.name
)
3345 op_data
['member_vnf_index'] = vnf_name
3347 op_data
['kdu_name'] = kdu_name
3349 op_data
['vdu_id'] = vdu_id
3351 op_data
['vdu_count_index'] = vdu_count
3352 op_data
['primitive'] = action_name
3354 with
open(params_file
, 'r') as pf
:
3357 op_data
['primitive_params'] = yaml
.safe_load(params
)
3359 op_data
['primitive_params'] = {}
3360 print(ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
, wait
=wait
))
3362 # except ClientException as e:
3367 @cli_osm.command(name
='vnf-scale', short_help
='executes a VNF scale (adding/removing VDUs)')
3368 @click.argument('ns_name')
3369 @click.argument('vnf_name')
3370 @click.option('--scaling-group', prompt
=True, help="scaling-group-descriptor name to use")
3371 @click.option('--scale-in', default
=False, is_flag
=True, help="performs a scale in operation")
3372 @click.option('--scale-out', default
=False, is_flag
=True, help="performs a scale out operation (by default)")
3381 Executes a VNF scale (adding/removing VDUs)
3384 NS_NAME: name or ID of the NS instance.
3385 VNF_NAME: member-vnf-index in the NS to be scaled.
3389 check_client_version(ctx
.obj
, ctx
.command
.name
)
3390 if not scale_in
and not scale_out
:
3392 ctx
.obj
.ns
.scale_vnf(ns_name
, vnf_name
, scaling_group
, scale_in
, scale_out
)
3393 # except ClientException as e:
3398 ##############################
3399 # Role Management Operations #
3400 ##############################
3402 @cli_osm.command(name
='role-create', short_help
='creates a new role')
3403 @click.argument('name')
3404 @click.option('--permissions',
3406 help='role permissions using a dictionary')
3408 def role_create(ctx
, name
, permissions
):
3413 NAME: Name or ID of the role.
3414 DEFINITION: Definition of grant/denial of access to resources.
3418 check_client_version(ctx
.obj
, ctx
.command
.name
)
3419 ctx
.obj
.role
.create(name
, permissions
)
3420 # except ClientException as e:
3425 @cli_osm.command(name
='role-update', short_help
='updates a role')
3426 @click.argument('name')
3427 @click.option('--set-name',
3429 help='change name of rle')
3430 # @click.option('--permissions',
3432 # help='provide a yaml format dictionary with incremental changes. Values can be bool or None to delete')
3433 @click.option('--add',
3435 help='yaml format dictionary with permission: True/False to access grant/denial')
3436 @click.option('--remove',
3438 help='yaml format list to remove a permission')
3440 def role_update(ctx
, name
, set_name
, add
, remove
):
3445 NAME: Name or ID of the role.
3446 DEFINITION: Definition overwrites the old definition.
3447 ADD: Grant/denial of access to resource to add.
3448 REMOVE: Grant/denial of access to resource to remove.
3452 check_client_version(ctx
.obj
, ctx
.command
.name
)
3453 ctx
.obj
.role
.update(name
, set_name
, None, add
, remove
)
3454 # except ClientException as e:
3459 @cli_osm.command(name
='role-delete', short_help
='deletes a role')
3460 @click.argument('name')
3461 # @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3463 def role_delete(ctx
, name
):
3468 NAME: Name or ID of the role.
3472 check_client_version(ctx
.obj
, ctx
.command
.name
)
3473 ctx
.obj
.role
.delete(name
)
3474 # except ClientException as e:
3479 @cli_osm.command(name
='role-list', short_help
='list all roles')
3480 @click.option('--filter', default
=None,
3481 help='restricts the list to the projects matching the filter')
3483 def role_list(ctx
, filter):
3489 check_client_version(ctx
.obj
, ctx
.command
.name
)
3490 resp
= ctx
.obj
.role
.list(filter)
3491 # except ClientException as e:
3494 table
= PrettyTable(['name', 'id'])
3496 table
.add_row([role
['name'], role
['_id']])
3501 @cli_osm.command(name
='role-show', short_help
='show specific role')
3502 @click.argument('name')
3504 def role_show(ctx
, name
):
3506 Shows the details of a role.
3509 NAME: Name or ID of the role.
3513 check_client_version(ctx
.obj
, ctx
.command
.name
)
3514 resp
= ctx
.obj
.role
.get(name
)
3515 # except ClientException as e:
3519 table
= PrettyTable(['key', 'attribute'])
3520 for k
, v
in resp
.items():
3521 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3526 @cli_osm.command(name
='package-create',
3527 short_help
='Create a package descriptor')
3528 @click.argument('package-type')
3529 @click.argument('package-name')
3530 @click.option('--base-directory',
3532 help=('(NS/VNF/NST) Set the location for package creation. Default: "."'))
3533 @click.option('--image',
3534 default
="image-name",
3535 help='(VNF) Set the name of the vdu image. Default "image-name"')
3536 @click.option('--vdus',
3538 help='(VNF) Set the number of vdus in a VNF. Default 1')
3539 @click.option('--vcpu',
3541 help='(VNF) Set the number of virtual CPUs in a vdu. Default 1')
3542 @click.option('--memory',
3544 help='(VNF) Set the memory size (MB) of the vdu. Default 1024')
3545 @click.option('--storage',
3547 help='(VNF) Set the disk size (GB) of the vdu. Default 10')
3548 @click.option('--interfaces',
3550 help='(VNF) Set the number of additional interfaces apart from the management interface. Default 0')
3551 @click.option('--vendor',
3553 help='(NS/VNF) Set the descriptor vendor. Default "OSM"')
3554 @click.option('--override',
3557 help='(NS/VNF/NST) Flag for overriding the package if exists.')
3558 @click.option('--detailed',
3561 help='(NS/VNF/NST) Flag for generating descriptor .yaml with all possible commented options')
3562 @click.option('--netslice-subnets',
3564 help='(NST) Number of netslice subnets. Default 1')
3565 @click.option('--netslice-vlds',
3567 help='(NST) Number of netslice vlds. Default 1')
3569 def package_create(ctx
,
3585 Creates an OSM NS, VNF, NST package
3588 PACKAGE_TYPE: Package to be created: NS, VNF or NST.
3589 PACKAGE_NAME: Name of the package to create the folder with the content.
3593 check_client_version(ctx
.obj
, ctx
.command
.name
)
3594 print("Creating the {} structure: {}/{}".format(package_type
.upper(), base_directory
, package_name
))
3595 resp
= ctx
.obj
.package_tool
.create(package_type
,
3604 interfaces
=interfaces
,
3607 netslice_subnets
=netslice_subnets
,
3608 netslice_vlds
=netslice_vlds
)
3610 # except ClientException as inst:
3611 # print("ERROR: {}".format(inst))
3614 @cli_osm.command(name
='package-validate',
3615 short_help
='Validate a package descriptor')
3616 @click.argument('base-directory',
3620 def package_validate(ctx
,
3623 Validate descriptors given a base directory.
3626 BASE_DIRECTORY: Stub folder for NS, VNF or NST package.
3629 check_client_version(ctx
.obj
, ctx
.command
.name
)
3630 results
= ctx
.obj
.package_tool
.validate(base_directory
)
3631 table
= PrettyTable()
3632 table
.field_names
= ["TYPE", "PATH", "VALID", "ERROR"]
3633 # Print the dictionary generated by the validation function
3634 for result
in results
:
3635 table
.add_row([result
["type"], result
["path"], result
["valid"], result
["error"]])
3636 table
.sortby
= "VALID"
3637 table
.align
["PATH"] = "l"
3638 table
.align
["TYPE"] = "l"
3639 table
.align
["ERROR"] = "l"
3641 # except ClientException as inst:
3642 # print("ERROR: {}".format(inst))
3645 @cli_osm.command(name
='package-build',
3646 short_help
='Build the tar.gz of the package')
3647 @click.argument('package-folder')
3648 @click.option('--skip-validation',
3651 help='skip package validation')
3653 def package_build(ctx
,
3657 Build the package NS, VNF given the package_folder.
3660 PACKAGE_FOLDER: Folder of the NS, VNF or NST to be packaged
3663 check_client_version(ctx
.obj
, ctx
.command
.name
)
3664 results
= ctx
.obj
.package_tool
.build(package_folder
, skip_validation
)
3666 # except ClientException as inst:
3667 # print("ERROR: {}".format(inst))
3674 except pycurl
.error
as exc
:
3676 print('Maybe "--hostname" option or OSM_HOSTNAME environment variable needs to be specified')
3678 except ClientException
as exc
:
3679 print("ERROR: {}".format(exc
))
3681 # TODO capture other controlled exceptions here
3682 # TODO remove the ClientException captures from all places, unless they do something different
3685 if __name__
== '__main__':