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
30 def check_client_version(obj
, what
, version
='sol005'):
32 Checks the version of the client object and raises error if it not the expected.
34 :param obj: the client object
35 :what: the function or command under evaluation (used when an error is raised)
37 :raises ClientError: if the specified version does not match the client version
39 fullclassname
= obj
.__module
__ + "." + obj
.__class
__.__name
__
40 message
= 'The following commands or options are only supported with the option "--sol005": {}'.format(what
)
42 message
= 'The following commands or options are not supported when using option "--sol005": {}'.format(what
)
43 if fullclassname
!= 'osmclient.{}.client.Client'.format(version
):
44 raise ClientException(message
)
48 @click.option('--hostname',
50 envvar
='OSM_HOSTNAME',
51 help='hostname of server. ' +
52 'Also can set OSM_HOSTNAME in environment')
53 @click.option('--sol005/--no-sol005',
56 help='Use ETSI NFV SOL005 API (default) or the previous SO API. ' +
57 'Also can set OSM_SOL005 in environment')
58 @click.option('--user',
61 help='user (only from Release FOUR, defaults to admin). ' +
62 'Also can set OSM_USER in environment')
63 @click.option('--password',
65 envvar
='OSM_PASSWORD',
66 help='password (only from Release FOUR, defaults to admin). ' +
67 'Also can set OSM_PASSWORD in environment')
68 @click.option('--project',
71 help='project (only from Release FOUR, defaults to admin). ' +
72 'Also can set OSM_PROJECT in environment')
73 @click.option('--so-port',
76 help='hostname of server. ' +
77 'Also can set OSM_SO_PORT in environment')
78 @click.option('--so-project',
80 envvar
='OSM_SO_PROJECT',
81 help='Project Name in SO. ' +
82 'Also can set OSM_SO_PROJECT in environment')
83 @click.option('--ro-hostname',
85 envvar
='OSM_RO_HOSTNAME',
86 help='hostname of RO server. ' +
87 'Also can set OSM_RO_HOSTNAME in environment')
88 @click.option('--ro-port',
91 help='hostname of RO server. ' +
92 'Also can set OSM_RO_PORT in environment')
94 def cli(ctx
, hostname
, sol005
, user
, password
, project
, so_port
, so_project
, ro_hostname
, ro_port
):
97 "either hostname option or OSM_HOSTNAME " +
98 "environment variable needs to be specified"))
101 if so_port
is not None:
102 kwargs
['so_port']=so_port
103 if so_project
is not None:
104 kwargs
['so_project']=so_project
105 if ro_hostname
is not None:
106 kwargs
['ro_host']=ro_hostname
107 if ro_port
is not None:
108 kwargs
['ro_port']=ro_port
111 if password
is not None:
112 kwargs
['password']=password
113 if project
is not None:
114 kwargs
['project']=project
116 ctx
.obj
= client
.Client(host
=hostname
, sol005
=sol005
, **kwargs
)
123 @cli.command(name
='ns-list')
124 @click.option('--filter', default
=None,
125 help='restricts the list to the NS instances matching the filter.')
127 def ns_list(ctx
, filter):
128 '''list all NS instances
132 --filter filterExpr Restricts the list to the NS instances matching the filter
135 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
136 concatenated using the "&" character:
139 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
140 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
141 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
143 value := scalar value
147 * zero or more occurrences
148 ? zero or one occurrence
149 [] grouping of expressions to be used with ? and *
150 "" quotation marks for marking string constants
154 "AttrName" is the name of one attribute in the data type that defines the representation
155 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
156 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
157 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
158 entries, it means that the operator "op" is applied to the attribute addressed by the last
159 <attrName> entry included in the concatenation. All simple filter expressions are combined
160 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
161 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
162 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
163 prefix". If an attribute referenced in an expression is an array, an object that contains a
164 corresponding array shall be considered to match the expression if any of the elements in the
165 array matches all expressions that have the same attribute prefix.
169 --filter admin-status=ENABLED
170 --filter nsd-ref=<NSD_NAME>
171 --filter nsd.vendor=<VENDOR>
172 --filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME>
173 --filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME>
176 check_client_version(ctx
.obj
, '--filter')
177 resp
= ctx
.obj
.ns
.list(filter)
179 resp
= ctx
.obj
.ns
.list()
183 'operational status',
187 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
188 if fullclassname
== 'osmclient.sol005.client.Client':
190 nsr_name
= nsr
['name']
193 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
194 nsr
= nsopdata
['nsr:nsr']
195 nsr_name
= nsr
['name-ref']
196 nsr_id
= nsr
['ns-instance-config-ref']
197 opstatus
= nsr
['operational-status'] if 'operational-status' in nsr
else 'Not found'
198 configstatus
= nsr
['config-status'] if 'config-status' in nsr
else 'Not found'
199 detailed_status
= nsr
['detailed-status'] if 'detailed-status' in nsr
else 'Not found'
200 if configstatus
== "config_not_needed":
201 configstatus
= "configured (no charms)"
212 def nsd_list(ctx
, filter):
214 check_client_version(ctx
.obj
, '--filter')
215 resp
= ctx
.obj
.nsd
.list(filter)
217 resp
= ctx
.obj
.nsd
.list()
218 #print yaml.safe_dump(resp)
219 table
= PrettyTable(['nsd name', 'id'])
220 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
221 if fullclassname
== 'osmclient.sol005.client.Client':
223 name
= ns
['name'] if 'name' in ns
else '-'
224 table
.add_row([name
, ns
['_id']])
227 table
.add_row([ns
['name'], ns
['id']])
232 @cli.command(name
='nsd-list')
233 @click.option('--filter', default
=None,
234 help='restricts the list to the NSD/NSpkg matching the filter')
236 def nsd_list1(ctx
, filter):
237 '''list all NSD/NSpkg in the system'''
241 @cli.command(name
='nspkg-list')
242 @click.option('--filter', default
=None,
243 help='restricts the list to the NSD/NSpkg matching the filter')
245 def nsd_list2(ctx
, filter):
246 '''list all NSD/NSpkg in the system'''
250 def vnfd_list(ctx
, filter):
252 check_client_version(ctx
.obj
, '--filter')
253 resp
= ctx
.obj
.vnfd
.list(filter)
255 resp
= ctx
.obj
.vnfd
.list()
256 #print yaml.safe_dump(resp)
257 table
= PrettyTable(['vnfd name', 'id'])
258 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
259 if fullclassname
== 'osmclient.sol005.client.Client':
261 name
= vnfd
['name'] if 'name' in vnfd
else '-'
262 table
.add_row([name
, vnfd
['_id']])
265 table
.add_row([vnfd
['name'], vnfd
['id']])
270 @cli.command(name
='vnfd-list')
271 @click.option('--filter', default
=None,
272 help='restricts the list to the VNFD/VNFpkg matching the filter')
274 def vnfd_list1(ctx
, filter):
275 '''list all VNFD/VNFpkg in the system'''
276 vnfd_list(ctx
,filter)
279 @cli.command(name
='vnfpkg-list')
280 @click.option('--filter', default
=None,
281 help='restricts the list to the VNFD/VNFpkg matching the filter')
283 def vnfd_list2(ctx
, filter):
284 '''list all VNFD/VNFpkg in the system'''
285 vnfd_list(ctx
,filter)
288 @cli.command(name
='vnf-list')
289 @click.option('--ns', default
=None, help='NS instance id or name to restrict the VNF list')
290 @click.option('--filter', default
=None,
291 help='restricts the list to the VNF instances matching the filter.')
293 def vnf_list(ctx
, ns
, filter):
294 '''list all VNF instances
298 --ns TEXT NS instance id or name to restrict the VNF list
299 --filter filterExpr Restricts the list to the VNF instances matching the filter
302 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
303 concatenated using the "&" character:
306 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
307 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
308 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
310 value := scalar value
314 * zero or more occurrences
315 ? zero or one occurrence
316 [] grouping of expressions to be used with ? and *
317 "" quotation marks for marking string constants
321 "AttrName" is the name of one attribute in the data type that defines the representation
322 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
323 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
324 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
325 entries, it means that the operator "op" is applied to the attribute addressed by the last
326 <attrName> entry included in the concatenation. All simple filter expressions are combined
327 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
328 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
329 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
330 prefix". If an attribute referenced in an expression is an array, an object that contains a
331 corresponding array shall be considered to match the expression if any of the elements in the
332 array matches all expressions that have the same attribute prefix.
336 --filter vim-account-id=<VIM_ACCOUNT_ID>
337 --filter vnfd-ref=<VNFD_NAME>
338 --filter vdur.ip-address=<IP_ADDRESS>
339 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
344 check_client_version(ctx
.obj
, '--ns')
346 check_client_version(ctx
.obj
, '--filter')
347 resp
= ctx
.obj
.vnf
.list(ns
, filter)
349 resp
= ctx
.obj
.vnf
.list()
350 except ClientException
as inst
:
351 print((inst
.message
))
353 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
354 if fullclassname
== 'osmclient.sol005.client.Client':
364 name
= vnfr
['name'] if 'name' in vnfr
else '-'
369 vnfr
['member-vnf-index-ref'],
371 vnfr
['vim-account-id'],
377 'operational status',
380 if 'mgmt-interface' not in vnfr
:
381 vnfr
['mgmt-interface'] = {}
382 vnfr
['mgmt-interface']['ip-address'] = None
386 vnfr
['operational-status'],
387 vnfr
['config-status']])
391 @cli.command(name
='ns-op-list')
392 @click.argument('name')
394 def ns_op_list(ctx
, name
):
395 '''shows the history of operations over a NS instance
397 NAME: name or ID of the NS instance
400 check_client_version(ctx
.obj
, ctx
.command
.name
)
401 resp
= ctx
.obj
.ns
.list_op(name
)
402 except ClientException
as inst
:
403 print((inst
.message
))
406 table
= PrettyTable(['id', 'operation', 'status'])
408 table
.add_row([op
['id'], op
['lcmOperationType'],
409 op
['operationState']])
414 def nsi_list(ctx
, filter):
415 '''list all Network Slice Instances'''
417 check_client_version(ctx
.obj
, ctx
.command
.name
)
418 resp
= ctx
.obj
.nsi
.list(filter)
419 except ClientException
as inst
:
420 print((inst
.message
))
423 ['netslice instance name',
425 'operational status',
429 nsi_name
= nsi
['name']
431 opstatus
= nsi
['operational-status'] if 'operational-status' in nsi
else 'Not found'
432 configstatus
= nsi
['config-status'] if 'config-status' in nsi
else 'Not found'
433 detailed_status
= nsi
['detailed-status'] if 'detailed-status' in nsi
else 'Not found'
434 if configstatus
== "config_not_needed":
435 configstatus
= "configured (no charms)"
446 @cli.command(name
='nsi-list')
447 @click.option('--filter', default
=None,
448 help='restricts the list to the Network Slice Instances matching the filter')
450 def nsi_list1(ctx
, filter):
451 '''list all Network Slice Instances (NSI)'''
455 @cli.command(name
='netslice-instance-list')
456 @click.option('--filter', default
=None,
457 help='restricts the list to the Network Slice Instances matching the filter')
459 def nsi_list2(ctx
, filter):
460 '''list all Network Slice Instances (NSI)'''
464 def nst_list(ctx
, filter):
466 check_client_version(ctx
.obj
, ctx
.command
.name
)
467 resp
= ctx
.obj
.nst
.list(filter)
468 except ClientException
as inst
:
469 print((inst
.message
))
471 #print yaml.safe_dump(resp)
472 table
= PrettyTable(['nst name', 'id'])
474 name
= nst
['name'] if 'name' in nst
else '-'
475 table
.add_row([name
, nst
['_id']])
480 @cli.command(name
='nst-list')
481 @click.option('--filter', default
=None,
482 help='restricts the list to the NST matching the filter')
484 def nst_list1(ctx
, filter):
485 '''list all Network Slice Templates (NST) in the system'''
489 @cli.command(name
='netslice-template-list')
490 @click.option('--filter', default
=None,
491 help='restricts the list to the NST matching the filter')
493 def nst_list2(ctx
, filter):
494 '''list all Network Slice Templates (NST) in the system'''
498 def nsi_op_list(ctx
, name
):
500 check_client_version(ctx
.obj
, ctx
.command
.name
)
501 resp
= ctx
.obj
.nsi
.list_op(name
)
502 except ClientException
as inst
:
503 print((inst
.message
))
505 table
= PrettyTable(['id', 'operation', 'status'])
507 table
.add_row([op
['id'], op
['lcmOperationType'],
508 op
['operationState']])
513 @cli.command(name
='nsi-op-list')
514 @click.argument('name')
516 def nsi_op_list1(ctx
, name
):
517 '''shows the history of operations over a Network Slice Instance (NSI)
519 NAME: name or ID of the Network Slice Instance
521 nsi_op_list(ctx
,name
)
524 @cli.command(name
='netslice-instance-op-list')
525 @click.argument('name')
527 def nsi_op_list2(ctx
, name
):
528 '''shows the history of operations over a Network Slice Instance (NSI)
530 NAME: name or ID of the Network Slice Instance
532 nsi_op_list(ctx
,name
)
535 @cli.command(name
='pdu-list')
536 @click.option('--filter', default
=None,
537 help='restricts the list to the Physical Deployment Units matching the filter')
539 def pdu_list(ctx
, filter):
540 '''list all Physical Deployment Units (PDU)'''
542 check_client_version(ctx
.obj
, ctx
.command
.name
)
543 resp
= ctx
.obj
.pdu
.list(filter)
544 except ClientException
as inst
:
545 print((inst
.message
))
554 pdu_name
= pdu
['name']
556 pdu_type
= pdu
['type']
557 pdu_shared
= pdu
['shared']
558 pdu_ipaddress
= "None"
559 for iface
in pdu
['interfaces']:
561 pdu_ipaddress
= iface
['ip-address']
577 def nsd_show(ctx
, name
, literal
):
579 resp
= ctx
.obj
.nsd
.get(name
)
580 #resp = ctx.obj.nsd.get_individual(name)
581 except ClientException
as inst
:
582 print((inst
.message
))
586 print(yaml
.safe_dump(resp
))
589 table
= PrettyTable(['field', 'value'])
590 for k
, v
in list(resp
.items()):
591 table
.add_row([k
, json
.dumps(v
, indent
=2)])
596 @cli.command(name
='nsd-show', short_help
='shows the content of a NSD')
597 @click.option('--literal', is_flag
=True,
598 help='print literally, no pretty table')
599 @click.argument('name')
601 def nsd_show1(ctx
, name
, literal
):
602 '''shows the content of a NSD
604 NAME: name or ID of the NSD/NSpkg
606 nsd_show(ctx
, name
, literal
)
609 @cli.command(name
='nspkg-show', short_help
='shows the content of a NSD')
610 @click.option('--literal', is_flag
=True,
611 help='print literally, no pretty table')
612 @click.argument('name')
614 def nsd_show2(ctx
, name
, literal
):
615 '''shows the content of a NSD
617 NAME: name or ID of the NSD/NSpkg
619 nsd_show(ctx
, name
, literal
)
622 def vnfd_show(ctx
, name
, literal
):
624 resp
= ctx
.obj
.vnfd
.get(name
)
625 #resp = ctx.obj.vnfd.get_individual(name)
626 except ClientException
as inst
:
627 print((inst
.message
))
631 print(yaml
.safe_dump(resp
))
634 table
= PrettyTable(['field', 'value'])
635 for k
, v
in list(resp
.items()):
636 table
.add_row([k
, json
.dumps(v
, indent
=2)])
641 @cli.command(name
='vnfd-show', short_help
='shows the content of a VNFD')
642 @click.option('--literal', is_flag
=True,
643 help='print literally, no pretty table')
644 @click.argument('name')
646 def vnfd_show1(ctx
, name
, literal
):
647 '''shows the content of a VNFD
649 NAME: name or ID of the VNFD/VNFpkg
651 vnfd_show(ctx
, name
, literal
)
654 @cli.command(name
='vnfpkg-show', short_help
='shows the content of a VNFD')
655 @click.option('--literal', is_flag
=True,
656 help='print literally, no pretty table')
657 @click.argument('name')
659 def vnfd_show2(ctx
, name
, literal
):
660 '''shows the content of a VNFD
662 NAME: name or ID of the VNFD/VNFpkg
664 vnfd_show(ctx
, name
, literal
)
667 @cli.command(name
='ns-show', short_help
='shows the info of a NS instance')
668 @click.argument('name')
669 @click.option('--literal', is_flag
=True,
670 help='print literally, no pretty table')
671 @click.option('--filter', default
=None)
673 def ns_show(ctx
, name
, literal
, filter):
674 '''shows the info of a NS instance
676 NAME: name or ID of the NS instance
679 ns
= ctx
.obj
.ns
.get(name
)
680 except ClientException
as inst
:
681 print((inst
.message
))
685 print(yaml
.safe_dump(ns
))
688 table
= PrettyTable(['field', 'value'])
690 for k
, v
in list(ns
.items()):
691 if filter is None or filter in k
:
692 table
.add_row([k
, json
.dumps(v
, indent
=2)])
694 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
695 if fullclassname
!= 'osmclient.sol005.client.Client':
696 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
697 nsr_optdata
= nsopdata
['nsr:nsr']
698 for k
, v
in list(nsr_optdata
.items()):
699 if filter is None or filter in k
:
700 table
.add_row([k
, json
.dumps(v
, indent
=2)])
705 @cli.command(name
='vnf-show', short_help
='shows the info of a VNF instance')
706 @click.argument('name')
707 @click.option('--literal', is_flag
=True,
708 help='print literally, no pretty table')
709 @click.option('--filter', default
=None)
711 def vnf_show(ctx
, name
, literal
, filter):
712 '''shows the info of a VNF instance
714 NAME: name or ID of the VNF instance
717 check_client_version(ctx
.obj
, ctx
.command
.name
)
718 resp
= ctx
.obj
.vnf
.get(name
)
719 except ClientException
as inst
:
720 print((inst
.message
))
724 print(yaml
.safe_dump(resp
))
727 table
= PrettyTable(['field', 'value'])
728 for k
, v
in list(resp
.items()):
729 if filter is None or filter in k
:
730 table
.add_row([k
, json
.dumps(v
, indent
=2)])
735 @cli.command(name
='vnf-monitoring-show')
736 @click.argument('vnf_name')
738 def vnf_monitoring_show(ctx
, vnf_name
):
740 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
741 resp
= ctx
.obj
.vnf
.get_monitoring(vnf_name
)
742 except ClientException
as inst
:
743 print((inst
.message
))
746 table
= PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
752 monitor
['value-integer'],
758 @cli.command(name
='ns-monitoring-show')
759 @click.argument('ns_name')
761 def ns_monitoring_show(ctx
, ns_name
):
763 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
764 resp
= ctx
.obj
.ns
.get_monitoring(ns_name
)
765 except ClientException
as inst
:
766 print((inst
.message
))
769 table
= PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
770 for key
, val
in list(resp
.items()):
775 monitor
['value-integer'],
781 @cli.command(name
='ns-op-show', short_help
='shows the info of an operation')
782 @click.argument('id')
783 @click.option('--filter', default
=None)
785 def ns_op_show(ctx
, id, filter):
786 '''shows the detailed info of an operation
788 ID: operation identifier
791 check_client_version(ctx
.obj
, ctx
.command
.name
)
792 op_info
= ctx
.obj
.ns
.get_op(id)
793 except ClientException
as inst
:
794 print((inst
.message
))
797 table
= PrettyTable(['field', 'value'])
798 for k
, v
in list(op_info
.items()):
799 if filter is None or filter in k
:
800 table
.add_row([k
, json
.dumps(v
, indent
=2)])
805 def nst_show(ctx
, name
, literal
):
807 check_client_version(ctx
.obj
, ctx
.command
.name
)
808 resp
= ctx
.obj
.nst
.get(name
)
809 #resp = ctx.obj.nst.get_individual(name)
810 except ClientException
as inst
:
811 print((inst
.message
))
815 print(yaml
.safe_dump(resp
))
818 table
= PrettyTable(['field', 'value'])
819 for k
, v
in list(resp
.items()):
820 table
.add_row([k
, json
.dumps(v
, indent
=2)])
825 @cli.command(name
='nst-show', short_help
='shows the content of a Network Slice Template (NST)')
826 @click.option('--literal', is_flag
=True,
827 help='print literally, no pretty table')
828 @click.argument('name')
830 def nst_show1(ctx
, name
, literal
):
831 '''shows the content of a Network Slice Template (NST)
833 NAME: name or ID of the NST
835 nst_show(ctx
, name
, literal
)
838 @cli.command(name
='netslice-template-show', short_help
='shows the content of a Network Slice Template (NST)')
839 @click.option('--literal', is_flag
=True,
840 help='print literally, no pretty table')
841 @click.argument('name')
843 def nst_show2(ctx
, name
, literal
):
844 '''shows the content of a Network Slice Template (NST)
846 NAME: name or ID of the NST
848 nst_show(ctx
, name
, literal
)
851 def nsi_show(ctx
, name
, literal
, filter):
853 check_client_version(ctx
.obj
, ctx
.command
.name
)
854 nsi
= ctx
.obj
.nsi
.get(name
)
855 except ClientException
as inst
:
856 print((inst
.message
))
860 print(yaml
.safe_dump(nsi
))
863 table
= PrettyTable(['field', 'value'])
865 for k
, v
in list(nsi
.items()):
866 if filter is None or filter in k
:
867 table
.add_row([k
, json
.dumps(v
, indent
=2)])
873 @cli.command(name
='nsi-show', short_help
='shows the content of a Network Slice Instance (NSI)')
874 @click.argument('name')
875 @click.option('--literal', is_flag
=True,
876 help='print literally, no pretty table')
877 @click.option('--filter', default
=None)
879 def nsi_show1(ctx
, name
, literal
, filter):
880 '''shows the content of a Network Slice Instance (NSI)
882 NAME: name or ID of the Network Slice Instance
884 nsi_show(ctx
, name
, literal
, filter)
887 @cli.command(name
='netslice-instance-show', short_help
='shows the content of a Network Slice Instance (NSI)')
888 @click.argument('name')
889 @click.option('--literal', is_flag
=True,
890 help='print literally, no pretty table')
891 @click.option('--filter', default
=None)
893 def nsi_show2(ctx
, name
, literal
, filter):
894 '''shows the content of a Network Slice Instance (NSI)
896 NAME: name or ID of the Network Slice Instance
898 nsi_show(ctx
, name
, literal
, filter)
901 def nsi_op_show(ctx
, id, filter):
903 check_client_version(ctx
.obj
, ctx
.command
.name
)
904 op_info
= ctx
.obj
.nsi
.get_op(id)
905 except ClientException
as inst
:
906 print((inst
.message
))
909 table
= PrettyTable(['field', 'value'])
910 for k
, v
in list(op_info
.items()):
911 if filter is None or filter in k
:
912 table
.add_row([k
, json
.dumps(v
, indent
=2)])
917 @cli.command(name
='nsi-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
918 @click.argument('id')
919 @click.option('--filter', default
=None)
921 def nsi_op_show1(ctx
, id, filter):
922 '''shows the info of an operation over a Network Slice Instance(NSI)
924 ID: operation identifier
926 nsi_op_show(ctx
, id, filter)
929 @cli.command(name
='netslice-instance-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
930 @click.argument('id')
931 @click.option('--filter', default
=None)
933 def nsi_op_show2(ctx
, id, filter):
934 '''shows the info of an operation over a Network Slice Instance(NSI)
936 ID: operation identifier
938 nsi_op_show(ctx
, id, filter)
941 @cli.command(name
='pdu-show', short_help
='shows the content of a Physical Deployment Unit (PDU)')
942 @click.argument('name')
943 @click.option('--literal', is_flag
=True,
944 help='print literally, no pretty table')
945 @click.option('--filter', default
=None)
947 def pdu_show(ctx
, name
, literal
, filter):
948 '''shows the content of a Physical Deployment Unit (PDU)
950 NAME: name or ID of the PDU
953 check_client_version(ctx
.obj
, ctx
.command
.name
)
954 pdu
= ctx
.obj
.pdu
.get(name
)
955 except ClientException
as inst
:
956 print((inst
.message
))
960 print(yaml
.safe_dump(pdu
))
963 table
= PrettyTable(['field', 'value'])
965 for k
, v
in list(pdu
.items()):
966 if filter is None or filter in k
:
967 table
.add_row([k
, json
.dumps(v
, indent
=2)])
977 def nsd_create(ctx
, filename
, overwrite
):
979 check_client_version(ctx
.obj
, ctx
.command
.name
)
980 ctx
.obj
.nsd
.create(filename
, overwrite
)
981 except ClientException
as inst
:
982 print((inst
.message
))
986 @cli.command(name
='nsd-create', short_help
='creates a new NSD/NSpkg')
987 @click.argument('filename')
988 @click.option('--overwrite', default
=None,
989 help='overwrites some fields in NSD')
991 def nsd_create1(ctx
, filename
, overwrite
):
992 '''creates a new NSD/NSpkg
994 FILENAME: NSD yaml file or NSpkg tar.gz file
996 nsd_create(ctx
, filename
, overwrite
)
999 @cli.command(name
='nspkg-create', short_help
='creates a new NSD/NSpkg')
1000 @click.argument('filename')
1001 @click.option('--overwrite', default
=None,
1002 help='overwrites some fields in NSD')
1004 def nsd_create2(ctx
, filename
, overwrite
):
1005 '''creates a new NSD/NSpkg
1007 FILENAME: NSD yaml file or NSpkg tar.gz file
1009 nsd_create(ctx
, filename
, overwrite
)
1012 def vnfd_create(ctx
, filename
, overwrite
):
1014 check_client_version(ctx
.obj
, ctx
.command
.name
)
1015 ctx
.obj
.vnfd
.create(filename
, overwrite
)
1016 except ClientException
as inst
:
1017 print((inst
.message
))
1021 @cli.command(name
='vnfd-create', short_help
='creates a new VNFD/VNFpkg')
1022 @click.argument('filename')
1023 @click.option('--overwrite', default
=None,
1024 help='overwrites some fields in VNFD')
1026 def vnfd_create1(ctx
, filename
, overwrite
):
1027 '''creates a new VNFD/VNFpkg
1029 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1031 vnfd_create(ctx
, filename
, overwrite
)
1034 @cli.command(name
='vnfpkg-create', short_help
='creates a new VNFD/VNFpkg')
1035 @click.argument('filename')
1036 @click.option('--overwrite', default
=None,
1037 help='overwrites some fields in VNFD')
1039 def vnfd_create2(ctx
, filename
, overwrite
):
1040 '''creates a new VNFD/VNFpkg
1042 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1044 vnfd_create(ctx
, filename
, overwrite
)
1047 @cli.command(name
='ns-create', short_help
='creates a new Network Service instance')
1048 @click.option('--ns_name',
1049 prompt
=True, help='name of the NS instance')
1050 @click.option('--nsd_name',
1051 prompt
=True, help='name of the NS descriptor')
1052 @click.option('--vim_account',
1053 prompt
=True, help='default VIM account id or name for the deployment')
1054 @click.option('--admin_status',
1056 help='administration status')
1057 @click.option('--ssh_keys',
1059 help='comma separated list of public key files to inject to vnfs')
1060 @click.option('--config',
1062 help='ns specific yaml configuration')
1063 @click.option('--config_file',
1065 help='ns specific yaml configuration file')
1075 '''creates a new NS instance'''
1078 check_client_version(ctx
.obj
, '--config_file')
1080 raise ClientException('"--config" option is incompatible with "--config_file" option')
1081 with
open(config_file
, 'r') as cf
:
1088 account
=vim_account
)
1089 except ClientException
as inst
:
1090 print((inst
.message
))
1094 def nst_create(ctx
, filename
, overwrite
):
1096 check_client_version(ctx
.obj
, ctx
.command
.name
)
1097 ctx
.obj
.nst
.create(filename
, overwrite
)
1098 except ClientException
as inst
:
1099 print((inst
.message
))
1103 @cli.command(name
='nst-create', short_help
='creates a new Network Slice Template (NST)')
1104 @click.argument('filename')
1105 @click.option('--overwrite', default
=None,
1106 help='overwrites some fields in NST')
1108 def nst_create1(ctx
, filename
, overwrite
):
1109 '''creates a new Network Slice Template (NST)
1111 FILENAME: NST yaml file or NSTpkg tar.gz file
1113 nst_create(ctx
, filename
, overwrite
)
1116 @cli.command(name
='netslice-template-create', short_help
='creates a new Network Slice Template (NST)')
1117 @click.argument('filename')
1118 @click.option('--overwrite', default
=None,
1119 help='overwrites some fields in NST')
1121 def nst_create2(ctx
, filename
, overwrite
):
1122 '''creates a new Network Slice Template (NST)
1124 FILENAME: NST yaml file or NSTpkg tar.gz file
1126 nst_create(ctx
, filename
, overwrite
)
1129 def nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
):
1130 '''creates a new Network Slice Instance (NSI)'''
1132 check_client_version(ctx
.obj
, ctx
.command
.name
)
1135 raise ClientException('"--config" option is incompatible with "--config_file" option')
1136 with
open(config_file
, 'r') as cf
:
1138 ctx
.obj
.nsi
.create(nst_name
, nsi_name
, config
=config
, ssh_keys
=ssh_keys
,
1139 account
=vim_account
)
1140 except ClientException
as inst
:
1141 print((inst
.message
))
1145 @cli.command(name
='nsi-create', short_help
='creates a new Network Slice Instance')
1146 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1147 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1148 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1149 @click.option('--ssh_keys', default
=None,
1150 help='comma separated list of keys to inject to vnfs')
1151 @click.option('--config', default
=None,
1152 help='Netslice specific yaml configuration:\n'
1153 'netslice_subnet: [\n'
1154 'id: TEXT, vim_account: TEXT,\n'
1155 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1156 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1158 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1160 @click.option('--config_file',
1162 help='nsi specific yaml configuration file')
1164 def nsi_create1(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
):
1165 '''creates a new Network Slice Instance (NSI)'''
1166 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
)
1169 @cli.command(name
='netslice-instance-create', short_help
='creates a new Network Slice Instance')
1170 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1171 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1172 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1173 @click.option('--ssh_keys', default
=None,
1174 help='comma separated list of keys to inject to vnfs')
1175 @click.option('--config', default
=None,
1176 help='Netslice specific yaml configuration:\n'
1177 'netslice_subnet: [\n'
1178 'id: TEXT, vim_account: TEXT,\n'
1179 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1180 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1182 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1184 @click.option('--config_file',
1186 help='nsi specific yaml configuration file')
1188 def nsi_create2(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
):
1189 '''creates a new Network Slice Instance (NSI)'''
1190 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
)
1193 @cli.command(name
='pdu-create', short_help
='adds a new Physical Deployment Unit to the catalog')
1194 @click.option('--name', help='name of the Physical Deployment Unit')
1195 @click.option('--pdu_type', help='type of PDU (e.g. router, firewall, FW001)')
1196 @click.option('--interface',
1197 help='interface(s) of the PDU: name=<NAME>,mgmt=<true|false>,ip-address=<IP_ADDRESS>'+
1198 '[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]',
1200 @click.option('--description', help='human readable description')
1201 @click.option('--shared', is_flag
=True, help='flag to indicate if the PDU is shared')
1202 @click.option('--vimAccounts', help='list of VIM accounts where this PDU is physically connected')
1203 @click.option('--descriptor_file', default
=None, help='PDU descriptor file (as an alternative to using the other arguments')
1206 def pdu_create(ctx
, name
, pdu_type
, interface
, description
, shared
, vimAccounts
, descriptor_file
):
1207 '''creates a new Physical Deployment Unit (PDU)'''
1209 check_client_version(ctx
.obj
, ctx
.command
.name
)
1211 if not descriptor_file
:
1213 raise ClientException('in absence of descriptor file, option "--name" is mandatory')
1215 raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory')
1217 raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)')
1219 with
open(descriptor_file
, 'r') as df
:
1220 pdu
= yaml
.load(df
.read())
1221 if name
: pdu
["name"] = name
1222 if pdu_type
: pdu
["type"] = pdu_type
1223 if description
: pdu
["description"] = description
1224 if shared
: pdu
["shared"] = shared
1225 if vimAccounts
: pdu
["vim_accounts"] = yaml
.load(vimAccounts
)
1228 for iface
in interface
:
1229 ifaces_list
.append({k
:v
for k
,v
in [i
.split('=') for i
in iface
.split(',')]})
1230 pdu
["interfaces"] = ifaces_list
1231 ctx
.obj
.pdu
.create(pdu
)
1232 except ClientException
as inst
:
1233 print((inst
.message
))
1237 ####################
1239 ####################
1241 def nsd_update(ctx
, name
, content
):
1243 check_client_version(ctx
.obj
, ctx
.command
.name
)
1244 ctx
.obj
.nsd
.update(name
, content
)
1245 except ClientException
as inst
:
1246 print((inst
.message
))
1250 @cli.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
1251 @click.argument('name')
1252 @click.option('--content', default
=None,
1253 help='filename with the NSD/NSpkg replacing the current one')
1255 def nsd_update1(ctx
, name
, content
):
1256 '''updates a NSD/NSpkg
1258 NAME: name or ID of the NSD/NSpkg
1260 nsd_update(ctx
, name
, content
)
1263 @cli.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
1264 @click.argument('name')
1265 @click.option('--content', default
=None,
1266 help='filename with the NSD/NSpkg replacing the current one')
1268 def nsd_update2(ctx
, name
, content
):
1269 '''updates a NSD/NSpkg
1271 NAME: name or ID of the NSD/NSpkg
1273 nsd_update(ctx
, name
, content
)
1276 def vnfd_update(ctx
, name
, content
):
1278 check_client_version(ctx
.obj
, ctx
.command
.name
)
1279 ctx
.obj
.vnfd
.update(name
, content
)
1280 except ClientException
as inst
:
1281 print((inst
.message
))
1285 @cli.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
1286 @click.argument('name')
1287 @click.option('--content', default
=None,
1288 help='filename with the VNFD/VNFpkg replacing the current one')
1290 def vnfd_update1(ctx
, name
, content
):
1291 '''updates a VNFD/VNFpkg
1293 NAME: name or ID of the VNFD/VNFpkg
1295 vnfd_update(ctx
, name
, content
)
1298 @cli.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
1299 @click.argument('name')
1300 @click.option('--content', default
=None,
1301 help='filename with the VNFD/VNFpkg replacing the current one')
1303 def vnfd_update2(ctx
, name
, content
):
1304 '''updates a VNFD/VNFpkg
1306 NAME: VNFD yaml file or VNFpkg tar.gz file
1308 vnfd_update(ctx
, name
, content
)
1311 def nst_update(ctx
, name
, content
):
1313 check_client_version(ctx
.obj
, ctx
.command
.name
)
1314 ctx
.obj
.nst
.update(name
, content
)
1315 except ClientException
as inst
:
1316 print((inst
.message
))
1320 @cli.command(name
='nst-update', short_help
='updates a Network Slice Template (NST)')
1321 @click.argument('name')
1322 @click.option('--content', default
=None,
1323 help='filename with the NST/NSTpkg replacing the current one')
1325 def nst_update1(ctx
, name
, content
):
1326 '''updates a Network Slice Template (NST)
1328 NAME: name or ID of the NSD/NSpkg
1330 nst_update(ctx
, name
, content
)
1333 @cli.command(name
='netslice-template-update', short_help
='updates a Network Slice Template (NST)')
1334 @click.argument('name')
1335 @click.option('--content', default
=None,
1336 help='filename with the NST/NSTpkg replacing the current one')
1338 def nst_update2(ctx
, name
, content
):
1339 '''updates a Network Slice Template (NST)
1341 NAME: name or ID of the NSD/NSpkg
1343 nst_update(ctx
, name
, content
)
1346 ####################
1348 ####################
1350 def nsd_delete(ctx
, name
, force
):
1353 ctx
.obj
.nsd
.delete(name
)
1355 check_client_version(ctx
.obj
, '--force')
1356 ctx
.obj
.nsd
.delete(name
, force
)
1357 except ClientException
as inst
:
1358 print((inst
.message
))
1362 @cli.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
1363 @click.argument('name')
1364 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1366 def nsd_delete1(ctx
, name
, force
):
1367 '''deletes a NSD/NSpkg
1369 NAME: name or ID of the NSD/NSpkg to be deleted
1371 nsd_delete(ctx
, name
, force
)
1374 @cli.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
1375 @click.argument('name')
1376 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1378 def nsd_delete2(ctx
, name
, force
):
1379 '''deletes a NSD/NSpkg
1381 NAME: name or ID of the NSD/NSpkg to be deleted
1383 nsd_delete(ctx
, name
, force
)
1386 def vnfd_delete(ctx
, name
, force
):
1389 ctx
.obj
.vnfd
.delete(name
)
1391 check_client_version(ctx
.obj
, '--force')
1392 ctx
.obj
.vnfd
.delete(name
, force
)
1393 except ClientException
as inst
:
1394 print((inst
.message
))
1398 @cli.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
1399 @click.argument('name')
1400 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1402 def vnfd_delete1(ctx
, name
, force
):
1403 '''deletes a VNFD/VNFpkg
1405 NAME: name or ID of the VNFD/VNFpkg to be deleted
1407 vnfd_delete(ctx
, name
, force
)
1410 @cli.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
1411 @click.argument('name')
1412 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1414 def vnfd_delete2(ctx
, name
, force
):
1415 '''deletes a VNFD/VNFpkg
1417 NAME: name or ID of the VNFD/VNFpkg to be deleted
1419 vnfd_delete(ctx
, name
, force
)
1422 @cli.command(name
='ns-delete', short_help
='deletes a NS instance')
1423 @click.argument('name')
1424 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1426 def ns_delete(ctx
, name
, force
):
1427 '''deletes a NS instance
1429 NAME: name or ID of the NS instance to be deleted
1433 ctx
.obj
.ns
.delete(name
)
1435 check_client_version(ctx
.obj
, '--force')
1436 ctx
.obj
.ns
.delete(name
, force
)
1437 except ClientException
as inst
:
1438 print((inst
.message
))
1442 def nst_delete(ctx
, name
, force
):
1444 check_client_version(ctx
.obj
, ctx
.command
.name
)
1445 ctx
.obj
.nst
.delete(name
, force
)
1446 except ClientException
as inst
:
1447 print((inst
.message
))
1451 @cli.command(name
='nst-delete', short_help
='deletes a Network Slice Template (NST)')
1452 @click.argument('name')
1453 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1455 def nst_delete1(ctx
, name
, force
):
1456 '''deletes a Network Slice Template (NST)
1458 NAME: name or ID of the NST/NSTpkg to be deleted
1460 nst_delete(ctx
, name
, force
)
1463 @cli.command(name
='netslice-template-delete', short_help
='deletes a Network Slice Template (NST)')
1464 @click.argument('name')
1465 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1467 def nst_delete2(ctx
, name
, force
):
1468 '''deletes a Network Slice Template (NST)
1470 NAME: name or ID of the NST/NSTpkg to be deleted
1472 nst_delete(ctx
, name
, force
)
1475 def nsi_delete(ctx
, name
, force
):
1477 check_client_version(ctx
.obj
, ctx
.command
.name
)
1478 ctx
.obj
.nsi
.delete(name
, force
)
1479 except ClientException
as inst
:
1480 print((inst
.message
))
1484 @cli.command(name
='nsi-delete', short_help
='deletes a Network Slice Instance (NSI)')
1485 @click.argument('name')
1486 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1488 def nsi_delete1(ctx
, name
, force
):
1489 '''deletes a Network Slice Instance (NSI)
1491 NAME: name or ID of the Network Slice instance to be deleted
1493 nsi_delete(ctx
, name
, force
)
1496 @cli.command(name
='netslice-instance-delete', short_help
='deletes a Network Slice Instance (NSI)')
1497 @click.argument('name')
1498 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1500 def nsi_delete2(ctx
, name
, force
):
1501 '''deletes a Network Slice Instance (NSI)
1503 NAME: name or ID of the Network Slice instance to be deleted
1505 nsi_delete(ctx
, name
, force
)
1508 @cli.command(name
='pdu-delete', short_help
='deletes a Physical Deployment Unit (PDU)')
1509 @click.argument('name')
1510 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1512 def pdu_delete(ctx
, name
, force
):
1513 '''deletes a Physical Deployment Unit (PDU)
1515 NAME: name or ID of the PDU to be deleted
1518 check_client_version(ctx
.obj
, ctx
.command
.name
)
1519 ctx
.obj
.pdu
.delete(name
, force
)
1520 except ClientException
as inst
:
1521 print((inst
.message
))
1525 ####################
1527 ####################
1529 @cli.command(name
='vim-create')
1530 @click.option('--name',
1532 help='Name to create datacenter')
1533 @click.option('--user',
1535 help='VIM username')
1536 @click.option('--password',
1539 confirmation_prompt
=True,
1540 help='VIM password')
1541 @click.option('--auth_url',
1544 @click.option('--tenant',
1546 help='VIM tenant name')
1547 @click.option('--config',
1549 help='VIM specific config parameters')
1550 @click.option('--account_type',
1551 default
='openstack',
1553 @click.option('--description',
1554 default
='no description',
1555 help='human readable description')
1556 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
1557 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1570 '''creates a new VIM account
1574 check_client_version(ctx
.obj
, '--sdn_controller')
1575 if sdn_port_mapping
:
1576 check_client_version(ctx
.obj
, '--sdn_port_mapping')
1578 vim
['vim-username'] = user
1579 vim
['vim-password'] = password
1580 vim
['vim-url'] = auth_url
1581 vim
['vim-tenant-name'] = tenant
1582 vim
['vim-type'] = account_type
1583 vim
['description'] = description
1584 vim
['config'] = config
1585 if sdn_controller
or sdn_port_mapping
:
1586 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
)
1588 ctx
.obj
.vim
.create(name
, vim
)
1589 except ClientException
as inst
:
1590 print((inst
.message
))
1594 @cli.command(name
='vim-update', short_help
='updates a VIM account')
1595 @click.argument('name')
1596 @click.option('--newname', help='New name for the VIM account')
1597 @click.option('--user', help='VIM username')
1598 @click.option('--password', help='VIM password')
1599 @click.option('--auth_url', help='VIM url')
1600 @click.option('--tenant', help='VIM tenant name')
1601 @click.option('--config', help='VIM specific config parameters')
1602 @click.option('--account_type', help='VIM type')
1603 @click.option('--description', help='human readable description')
1604 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
1605 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1619 '''updates a VIM account
1621 NAME: name or ID of the VIM account
1624 check_client_version(ctx
.obj
, ctx
.command
.name
)
1626 if newname
: vim
['name'] = newname
1627 if user
: vim
['vim_user'] = user
1628 if password
: vim
['vim_password'] = password
1629 if auth_url
: vim
['vim_url'] = auth_url
1630 if tenant
: vim
['vim-tenant-name'] = tenant
1631 if account_type
: vim
['vim_type'] = account_type
1632 if description
: vim
['description'] = description
1633 if config
: vim
['config'] = config
1634 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
)
1635 except ClientException
as inst
:
1636 print((inst
.message
))
1640 @cli.command(name
='vim-delete')
1641 @click.argument('name')
1642 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1644 def vim_delete(ctx
, name
, force
):
1645 '''deletes a VIM account
1647 NAME: name or ID of the VIM account to be deleted
1651 ctx
.obj
.vim
.delete(name
)
1653 check_client_version(ctx
.obj
, '--force')
1654 ctx
.obj
.vim
.delete(name
, force
)
1655 except ClientException
as inst
:
1656 print((inst
.message
))
1660 @cli.command(name
='vim-list')
1661 @click.option('--ro_update/--no_ro_update',
1663 help='update list from RO')
1664 @click.option('--filter', default
=None,
1665 help='restricts the list to the VIM accounts matching the filter')
1667 def vim_list(ctx
, ro_update
, filter):
1668 '''list all VIM accounts'''
1670 check_client_version(ctx
.obj
, '--filter')
1672 check_client_version(ctx
.obj
, '--ro_update', 'v1')
1673 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1674 if fullclassname
== 'osmclient.sol005.client.Client':
1675 resp
= ctx
.obj
.vim
.list(filter)
1677 resp
= ctx
.obj
.vim
.list(ro_update
)
1678 table
= PrettyTable(['vim name', 'uuid'])
1680 table
.add_row([vim
['name'], vim
['uuid']])
1685 @cli.command(name
='vim-show')
1686 @click.argument('name')
1688 def vim_show(ctx
, name
):
1689 '''shows the details of a VIM account
1691 NAME: name or ID of the VIM account
1694 resp
= ctx
.obj
.vim
.get(name
)
1695 if 'vim_password' in resp
:
1696 resp
['vim_password']='********'
1697 except ClientException
as inst
:
1698 print((inst
.message
))
1701 table
= PrettyTable(['key', 'attribute'])
1702 for k
, v
in list(resp
.items()):
1703 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1708 ####################
1709 # SDN controller operations
1710 ####################
1712 @cli.command(name
='sdnc-create')
1713 @click.option('--name',
1715 help='Name to create sdn controller')
1716 @click.option('--type',
1718 help='SDN controller type')
1719 @click.option('--sdn_controller_version',
1720 help='SDN controller username')
1721 @click.option('--ip_address',
1723 help='SDN controller IP address')
1724 @click.option('--port',
1726 help='SDN controller port')
1727 @click.option('--switch_dpid',
1729 help='Switch DPID (Openflow Datapath ID)')
1730 @click.option('--user',
1731 help='SDN controller username')
1732 @click.option('--password',
1734 confirmation_prompt
=True,
1735 help='SDN controller password')
1736 #@click.option('--description',
1737 # default='no description',
1738 # help='human readable description')
1740 def sdnc_create(ctx
,
1743 sdn_controller_version
,
1749 '''creates a new SDN controller
1752 sdncontroller
['name'] = name
1753 sdncontroller
['type'] = type
1754 sdncontroller
['ip'] = ip_address
1755 sdncontroller
['port'] = int(port
)
1756 sdncontroller
['dpid'] = switch_dpid
1757 if sdn_controller_version
:
1758 sdncontroller
['version'] = sdn_controller_version
1760 sdncontroller
['user'] = user
1762 sdncontroller
['password'] = password
1763 # sdncontroller['description'] = description
1765 check_client_version(ctx
.obj
, ctx
.command
.name
)
1766 ctx
.obj
.sdnc
.create(name
, sdncontroller
)
1767 except ClientException
as inst
:
1768 print((inst
.message
))
1771 @cli.command(name
='sdnc-update', short_help
='updates an SDN controller')
1772 @click.argument('name')
1773 @click.option('--newname', help='New name for the SDN controller')
1774 @click.option('--type', help='SDN controller type')
1775 @click.option('--sdn_controller_version', help='SDN controller username')
1776 @click.option('--ip_address', help='SDN controller IP address')
1777 @click.option('--port', help='SDN controller port')
1778 @click.option('--switch_dpid', help='Switch DPID (Openflow Datapath ID)')
1779 @click.option('--user', help='SDN controller username')
1780 @click.option('--password', help='SDN controller password')
1781 #@click.option('--description', default=None, help='human readable description')
1783 def sdnc_update(ctx
,
1787 sdn_controller_version
,
1793 '''updates an SDN controller
1795 NAME: name or ID of the SDN controller
1798 if newname
: sdncontroller
['name'] = newname
1799 if type: sdncontroller
['type'] = type
1800 if ip_address
: sdncontroller
['ip'] = ip_address
1801 if port
: sdncontroller
['port'] = int(port
)
1802 if switch_dpid
: sdncontroller
['dpid'] = switch_dpid
1803 # sdncontroller['description'] = description
1804 if sdn_controller_version
is not None:
1805 if sdn_controller_version
=="":
1806 sdncontroller
['version'] = None
1808 sdncontroller
['version'] = sdn_controller_version
1809 if user
is not None:
1811 sdncontroller
['user'] = None
1813 sdncontroller
['user'] = user
1814 if password
is not None:
1816 sdncontroller
['password'] = None
1818 sdncontroller
['password'] = user
1820 check_client_version(ctx
.obj
, ctx
.command
.name
)
1821 ctx
.obj
.sdnc
.update(name
, sdncontroller
)
1822 except ClientException
as inst
:
1823 print((inst
.message
))
1827 @cli.command(name
='sdnc-delete')
1828 @click.argument('name')
1829 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1831 def sdnc_delete(ctx
, name
, force
):
1832 '''deletes an SDN controller
1834 NAME: name or ID of the SDN controller to be deleted
1837 check_client_version(ctx
.obj
, ctx
.command
.name
)
1838 ctx
.obj
.sdnc
.delete(name
, force
)
1839 except ClientException
as inst
:
1840 print((inst
.message
))
1844 @cli.command(name
='sdnc-list')
1845 @click.option('--filter', default
=None,
1846 help='restricts the list to the SDN controllers matching the filter')
1848 def sdnc_list(ctx
, filter):
1849 '''list all SDN controllers'''
1851 check_client_version(ctx
.obj
, ctx
.command
.name
)
1852 resp
= ctx
.obj
.sdnc
.list(filter)
1853 except ClientException
as inst
:
1854 print((inst
.message
))
1856 table
= PrettyTable(['name', 'id'])
1858 table
.add_row([sdnc
['name'], sdnc
['_id']])
1863 @cli.command(name
='sdnc-show')
1864 @click.argument('name')
1866 def sdnc_show(ctx
, name
):
1867 '''shows the details of an SDN controller
1869 NAME: name or ID of the SDN controller
1872 check_client_version(ctx
.obj
, ctx
.command
.name
)
1873 resp
= ctx
.obj
.sdnc
.get(name
)
1874 except ClientException
as inst
:
1875 print((inst
.message
))
1878 table
= PrettyTable(['key', 'attribute'])
1879 for k
, v
in list(resp
.items()):
1880 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1885 ####################
1886 # Project mgmt operations
1887 ####################
1889 @cli.command(name
='project-create')
1890 @click.argument('name')
1891 #@click.option('--description',
1892 # default='no description',
1893 # help='human readable description')
1895 def project_create(ctx
, name
):
1896 '''Creates a new project
1898 NAME: name of the project
1901 project
['name'] = name
1903 check_client_version(ctx
.obj
, ctx
.command
.name
)
1904 ctx
.obj
.project
.create(name
, project
)
1905 except ClientException
as inst
:
1909 @cli.command(name
='project-delete')
1910 @click.argument('name')
1911 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1913 def project_delete(ctx
, name
):
1914 '''deletes a project
1916 NAME: name or ID of the project to be deleted
1919 check_client_version(ctx
.obj
, ctx
.command
.name
)
1920 ctx
.obj
.project
.delete(name
)
1921 except ClientException
as inst
:
1926 @cli.command(name
='project-list')
1927 @click.option('--filter', default
=None,
1928 help='restricts the list to the projects matching the filter')
1930 def project_list(ctx
, filter):
1931 '''list all projects'''
1933 check_client_version(ctx
.obj
, ctx
.command
.name
)
1934 resp
= ctx
.obj
.project
.list(filter)
1935 except ClientException
as inst
:
1938 table
= PrettyTable(['name', 'id'])
1940 table
.add_row([proj
['name'], proj
['_id']])
1945 @cli.command(name
='project-show')
1946 @click.argument('name')
1948 def project_show(ctx
, name
):
1949 '''shows the details of a project
1951 NAME: name or ID of the project
1954 check_client_version(ctx
.obj
, ctx
.command
.name
)
1955 resp
= ctx
.obj
.project
.get(name
)
1956 except ClientException
as inst
:
1960 table
= PrettyTable(['key', 'attribute'])
1961 for k
, v
in resp
.items():
1962 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1967 ####################
1968 # User mgmt operations
1969 ####################
1971 @cli.command(name
='user-create')
1972 @click.argument('username')
1973 @click.option('--password',
1976 confirmation_prompt
=True,
1977 help='user password')
1978 @click.option('--projects',
1980 help='list of project ids that the user belongs to')
1981 #@click.option('--description',
1982 # default='no description',
1983 # help='human readable description')
1985 def user_create(ctx
, username
, password
, projects
):
1986 '''Creates a new user
1988 USERNAME: name of the user
1991 user
['username'] = username
1992 user
['password'] = password
1993 user
['projects'] = projects
1995 check_client_version(ctx
.obj
, ctx
.command
.name
)
1996 ctx
.obj
.user
.create(username
, user
)
1997 except ClientException
as inst
:
2001 @cli.command(name
='user-delete')
2002 @click.argument('name')
2003 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2005 def user_delete(ctx
, name
):
2008 NAME: name or ID of the user to be deleted
2011 check_client_version(ctx
.obj
, ctx
.command
.name
)
2012 ctx
.obj
.user
.delete(name
)
2013 except ClientException
as inst
:
2018 @cli.command(name
='user-list')
2019 @click.option('--filter', default
=None,
2020 help='restricts the list to the users matching the filter')
2022 def user_list(ctx
, filter):
2023 '''list all users'''
2025 check_client_version(ctx
.obj
, ctx
.command
.name
)
2026 resp
= ctx
.obj
.user
.list(filter)
2027 except ClientException
as inst
:
2030 table
= PrettyTable(['name', 'id'])
2032 table
.add_row([user
['name'], user
['_id']])
2037 @cli.command(name
='user-show')
2038 @click.argument('name')
2040 def user_show(ctx
, name
):
2041 '''shows the details of a user
2043 NAME: name or ID of the user
2046 check_client_version(ctx
.obj
, ctx
.command
.name
)
2047 resp
= ctx
.obj
.user
.get(name
)
2048 if 'password' in resp
:
2049 resp
['password']='********'
2050 except ClientException
as inst
:
2054 table
= PrettyTable(['key', 'attribute'])
2055 for k
, v
in resp
.items():
2056 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2061 ####################
2062 # Fault Management operations
2063 ####################
2065 @cli.command(name
='ns-alarm-create')
2066 @click.argument('name')
2067 @click.option('--ns', prompt
=True, help='NS instance id or name')
2068 @click.option('--vnf', prompt
=True,
2069 help='VNF name (VNF member index as declared in the NSD)')
2070 @click.option('--vdu', prompt
=True,
2071 help='VDU name (VDU name as declared in the VNFD)')
2072 @click.option('--metric', prompt
=True,
2073 help='Name of the metric (e.g. cpu_utilization)')
2074 @click.option('--severity', default
='WARNING',
2075 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
2076 @click.option('--threshold_value', prompt
=True,
2077 help='threshold value that, when crossed, an alarm is triggered')
2078 @click.option('--threshold_operator', prompt
=True,
2079 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
2080 @click.option('--statistic', default
='AVERAGE',
2081 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
2083 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
2084 threshold_value
, threshold_operator
, statistic
):
2085 '''creates a new alarm for a NS instance'''
2086 ns_instance
= ctx
.obj
.ns
.get(ns
)
2088 alarm
['alarm_name'] = name
2089 alarm
['ns_id'] = ns_instance
['_id']
2090 alarm
['correlation_id'] = ns_instance
['_id']
2091 alarm
['vnf_member_index'] = vnf
2092 alarm
['vdu_name'] = vdu
2093 alarm
['metric_name'] = metric
2094 alarm
['severity'] = severity
2095 alarm
['threshold_value'] = int(threshold_value
)
2096 alarm
['operation'] = threshold_operator
2097 alarm
['statistic'] = statistic
2099 check_client_version(ctx
.obj
, ctx
.command
.name
)
2100 ctx
.obj
.ns
.create_alarm(alarm
)
2101 except ClientException
as inst
:
2102 print((inst
.message
))
2106 #@cli.command(name='ns-alarm-delete')
2107 #@click.argument('name')
2108 #@click.pass_context
2109 #def ns_alarm_delete(ctx, name):
2110 # '''deletes an alarm
2112 # NAME: name of the alarm to be deleted
2115 # check_client_version(ctx.obj, ctx.command.name)
2116 # ctx.obj.ns.delete_alarm(name)
2117 # except ClientException as inst:
2118 # print(inst.message)
2122 ####################
2123 # Performance Management operations
2124 ####################
2126 @cli.command(name
='ns-metric-export')
2127 @click.option('--ns', prompt
=True, help='NS instance id or name')
2128 @click.option('--vnf', prompt
=True,
2129 help='VNF name (VNF member index as declared in the NSD)')
2130 @click.option('--vdu', prompt
=True,
2131 help='VDU name (VDU name as declared in the VNFD)')
2132 @click.option('--metric', prompt
=True,
2133 help='name of the metric (e.g. cpu_utilization)')
2134 #@click.option('--period', default='1w',
2135 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
2136 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
2138 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
2139 '''exports a metric to the internal OSM bus, which can be read by other apps
2141 ns_instance
= ctx
.obj
.ns
.get(ns
)
2143 metric_data
['ns_id'] = ns_instance
['_id']
2144 metric_data
['correlation_id'] = ns_instance
['_id']
2145 metric_data
['vnf_member_index'] = vnf
2146 metric_data
['vdu_name'] = vdu
2147 metric_data
['metric_name'] = metric
2148 metric_data
['collection_unit'] = 'WEEK'
2149 metric_data
['collection_period'] = 1
2151 check_client_version(ctx
.obj
, ctx
.command
.name
)
2153 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
2157 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
2158 time
.sleep(int(interval
))
2160 except ClientException
as inst
:
2161 print((inst
.message
))
2165 ####################
2167 ####################
2169 @cli.command(name
='upload-package')
2170 @click.argument('filename')
2172 def upload_package(ctx
, filename
):
2173 '''uploads a VNF package or NS package
2175 FILENAME: VNF or NS package file (tar.gz)
2178 ctx
.obj
.package
.upload(filename
)
2179 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
2180 if fullclassname
!= 'osmclient.sol005.client.Client':
2181 ctx
.obj
.package
.wait_for_upload(filename
)
2182 except ClientException
as inst
:
2183 print((inst
.message
))
2187 @cli.command(name
='ns-scaling-show')
2188 @click.argument('ns_name')
2190 def show_ns_scaling(ctx
, ns_name
):
2191 '''shows the status of a NS scaling operation
2193 NS_NAME: name of the NS instance being scaled
2196 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
2197 resp
= ctx
.obj
.ns
.list()
2198 except ClientException
as inst
:
2199 print((inst
.message
))
2202 table
= PrettyTable(
2205 'operational status',
2210 if ns_name
== ns
['name']:
2211 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
2212 scaling_records
= nsopdata
['nsr:nsr']['scaling-group-record']
2213 for record
in scaling_records
:
2214 if 'instance' in record
:
2215 instances
= record
['instance']
2216 for inst
in instances
:
2218 [record
['scaling-group-name-ref'],
2219 inst
['instance-id'],
2221 time
.strftime('%Y-%m-%d %H:%M:%S',
2223 inst
['create-time'])),
2229 @cli.command(name
='ns-scale')
2230 @click.argument('ns_name')
2231 @click.option('--ns_scale_group', prompt
=True)
2232 @click.option('--index', prompt
=True)
2234 def ns_scale(ctx
, ns_name
, ns_scale_group
, index
):
2237 NS_NAME: name of the NS instance to be scaled
2240 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
2241 ctx
.obj
.ns
.scale(ns_name
, ns_scale_group
, index
)
2242 except ClientException
as inst
:
2243 print((inst
.message
))
2247 @cli.command(name
='config-agent-list')
2249 def config_agent_list(ctx
):
2250 '''list config agents'''
2252 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
2253 except ClientException
as inst
:
2254 print((inst
.message
))
2256 table
= PrettyTable(['name', 'account-type', 'details'])
2257 for account
in ctx
.obj
.vca
.list():
2260 account
['account-type'],
2266 @cli.command(name
='config-agent-delete')
2267 @click.argument('name')
2269 def config_agent_delete(ctx
, name
):
2270 '''deletes a config agent
2272 NAME: name of the config agent to be deleted
2275 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
2276 ctx
.obj
.vca
.delete(name
)
2277 except ClientException
as inst
:
2278 print((inst
.message
))
2282 @cli.command(name
='config-agent-add')
2283 @click.option('--name',
2285 @click.option('--account_type',
2287 @click.option('--server',
2289 @click.option('--user',
2291 @click.option('--secret',
2294 confirmation_prompt
=True)
2296 def config_agent_add(ctx
, name
, account_type
, server
, user
, secret
):
2297 '''adds a config agent'''
2299 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
2300 ctx
.obj
.vca
.create(name
, account_type
, server
, user
, secret
)
2301 except ClientException
as inst
:
2302 print((inst
.message
))
2305 @cli.command(name
='ro-dump')
2308 '''shows RO agent information'''
2309 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
2310 resp
= ctx
.obj
.vim
.get_resource_orchestrator()
2311 table
= PrettyTable(['key', 'attribute'])
2312 for k
, v
in list(resp
.items()):
2313 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2318 @cli.command(name
='vcs-list')
2321 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
2322 resp
= ctx
.obj
.utils
.get_vcs_info()
2323 table
= PrettyTable(['component name', 'state'])
2324 for component
in resp
:
2325 table
.add_row([component
['component_name'], component
['state']])
2330 @cli.command(name
='ns-action')
2331 @click.argument('ns_name')
2332 @click.option('--vnf_name', default
=None)
2333 @click.option('--action_name', prompt
=True)
2334 @click.option('--params', prompt
=True)
2341 '''executes an action/primitive over a NS instance
2343 NS_NAME: name or ID of the NS instance
2346 check_client_version(ctx
.obj
, ctx
.command
.name
)
2349 op_data
['vnf_member_index'] = vnf_name
2350 op_data
['primitive'] = action_name
2351 op_data
['primitive_params'] = yaml
.load(params
)
2352 ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
)
2354 except ClientException
as inst
:
2355 print((inst
.message
))
2359 @cli.command(name
='vnf-scale')
2360 @click.argument('ns_name')
2361 @click.argument('vnf_name')
2362 @click.option('--scaling-group', prompt
=True, help="scaling-group-descriptor name to use")
2363 @click.option('--scale-in', default
=False, is_flag
=True, help="performs a scale in operation")
2364 @click.option('--scale-out', default
=False, is_flag
=True, help="performs a scale out operation (by default)")
2372 '''executes a VNF scale (adding/removing VDUs)
2375 NS_NAME: name or ID of the NS instance.
2376 VNF_NAME: member-vnf-index in the NS to be scaled.
2379 check_client_version(ctx
.obj
, ctx
.command
.name
)
2380 if not scale_in
and not scale_out
:
2382 ctx
.obj
.ns
.scale_vnf(ns_name
, vnf_name
, scaling_group
, scale_in
, scale_out
)
2383 except ClientException
as inst
:
2384 print((inst
.message
))
2388 if __name__
== '__main__':
2391 except pycurl
.error
as e
:
2393 print('Maybe "--hostname" option or OSM_HOSTNAME' +
2394 'environment variable needs to be specified')