f61373ecd2db309acfde7d6c8581de28a67fd0a0
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.')
155 @click.option('--details', is_flag
=True,
156 help='get more details of current operation in the NS.')
158 def ns_list(ctx
, filter,details
):
159 """list all NS instances
163 --filter filterExpr Restricts the list to the NS instances matching the filter
166 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
167 concatenated using the "&" character:
170 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
171 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
172 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
174 value := scalar value
178 * zero or more occurrences
179 ? zero or one occurrence
180 [] grouping of expressions to be used with ? and *
181 "" quotation marks for marking string constants
185 "AttrName" is the name of one attribute in the data type that defines the representation
186 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
187 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
188 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
189 entries, it means that the operator "op" is applied to the attribute addressed by the last
190 <attrName> entry included in the concatenation. All simple filter expressions are combined
191 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
192 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
193 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
194 prefix". If an attribute referenced in an expression is an array, an object that contains a
195 corresponding array shall be considered to match the expression if any of the elements in the
196 array matches all expressions that have the same attribute prefix.
200 --filter admin-status=ENABLED
201 --filter nsd-ref=<NSD_NAME>
202 --filter nsd.vendor=<VENDOR>
203 --filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME>
204 --filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME>
206 def summarize_deployment_status(status_dict
):
211 net_list
= status_dict
['nets']
214 if net
['status'] not in status_nets
:
215 status_nets
[net
['status']] = 1
217 status_nets
[net
['status']] +=1
219 for k
,v
in status_nets
.items():
220 message
+= "{}:{},".format(k
,v
)
221 message
+= "TOTAL:{}".format(n_nets
)
222 summary
+= "{}".format(message
)
227 vnf_list
= status_dict
['vnfs']
229 member_vnf_index
= vnf
['member_vnf_index']
230 if member_vnf_index
not in status_vnfs
:
231 status_vnfs
[member_vnf_index
] = {}
232 for vm
in vnf
['vms']:
234 if vm
['status'] not in status_vms
:
235 status_vms
[vm
['status']] = 1
237 status_vms
[vm
['status']] +=1
238 if vm
['status'] not in status_vnfs
[member_vnf_index
]:
239 status_vnfs
[member_vnf_index
][vm
['status']] = 1
241 status_vnfs
[member_vnf_index
][vm
['status']] += 1
243 for k
,v
in status_vms
.items():
244 message
+= "{}:{},".format(k
,v
)
245 message
+= "TOTAL:{}".format(n_vms
)
246 summary
+= "\n{}".format(message
)
248 for k
,v
in status_vnfs
.items():
250 message
= "\n {} VMs: ".format(k
)
251 for k2
,v2
in v
.items():
252 message
+= "{}:{},".format(k2
,v2
)
254 message
+= "TOTAL:{}".format(total
)
258 def summarize_config_status(ee_list
):
263 if ee
['elementType'] not in status_ee
:
264 status_ee
[ee
['elementType']] = {}
265 status_ee
[ee
['elementType']][ee
['status']] = 1
267 if ee
['status'] in status_ee
[ee
['elementType']]:
268 status_ee
[ee
['elementType']][ee
['status']] += 1
270 status_ee
[ee
['elementType']][ee
['status']] = 1
272 for elementType
in ["KDU", "VDU", "PDU", "VNF", "NS"]:
273 if elementType
in status_ee
:
276 for k
,v
in status_ee
[elementType
].items():
277 message
+= "{}:{},".format(k
,v
)
279 message
+= "TOTAL:{}\n".format(total
)
280 summary
+= "{}: {}".format(elementType
, message
)
281 summary
+= "TOTAL Exec. Env.: {}".format(n_ee
)
285 check_client_version(ctx
.obj
, '--filter')
286 resp
= ctx
.obj
.ns
.list(filter)
288 resp
= ctx
.obj
.ns
.list()
297 'configuration status'])
306 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
307 if fullclassname
== 'osmclient.sol005.client.Client':
309 nsr_name
= nsr
['name']
311 ns_state
= nsr
['nsState']
313 deployment_status
= summarize_deployment_status(nsr
['deploymentStatus'])
314 config_status
= summarize_config_status(nsr
['configurationStatus'])
315 current_operation
= "{} ({})".format(nsr
['currentOperation'],nsr
['currentOperationID'])
316 error_details
= "N/A"
317 if ns_state
== "BROKEN" or ns_state
== "DEGRADED":
318 error_details
= "{}\nDetail: {}".format(nsr
['errorDescription'],nsr
['errorDetail'])
320 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
321 nsr
= nsopdata
['nsr:nsr']
322 nsr_name
= nsr
['name-ref']
323 nsr_id
= nsr
['ns-instance-config-ref']
324 deployment_status
= nsr
['operational-status'] if 'operational-status' in nsr
else 'Not found'
325 ns_state
= deployment_status
326 config_status
= nsr
['config-status'] if 'config-status' in nsr
else 'Not found'
327 current_operation
= "Unknown"
328 error_details
= nsr
['detailed-status'] if 'detailed-status' in nsr
else 'Not found'
329 if config_status
== "config_not_needed":
330 config_status
= "configured (no charms)"
338 wrap_text(text
=error_details
,width
=40),
347 wrap_text(text
=error_details
,width
=40)])
350 print('To get the history of all operations over a NS, run "osm ns-op-list NS_ID"')
351 print('For more details on the current operation, run "osm ns-op-show OPERATION_ID"')
353 def nsd_list(ctx
, filter):
356 check_client_version(ctx
.obj
, '--filter')
357 resp
= ctx
.obj
.nsd
.list(filter)
359 resp
= ctx
.obj
.nsd
.list()
360 # print(yaml.safe_dump(resp))
361 table
= PrettyTable(['nsd name', 'id'])
362 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
363 if fullclassname
== 'osmclient.sol005.client.Client':
365 name
= ns
['name'] if 'name' in ns
else '-'
366 table
.add_row([name
, ns
['_id']])
369 table
.add_row([ns
['name'], ns
['id']])
374 @cli_osm.command(name
='nsd-list', short_help
='list all NS packages')
375 @click.option('--filter', default
=None,
376 help='restricts the list to the NSD/NSpkg matching the filter')
378 def nsd_list1(ctx
, filter):
379 """list all NSD/NS pkg in the system"""
381 nsd_list(ctx
, filter)
384 @cli_osm.command(name
='nspkg-list', short_help
='list all NS packages')
385 @click.option('--filter', default
=None,
386 help='restricts the list to the NSD/NSpkg matching the filter')
388 def nsd_list2(ctx
, filter):
389 """list all NS packages"""
391 nsd_list(ctx
, filter)
394 def vnfd_list(ctx
, nf_type
, filter):
397 check_client_version(ctx
.obj
, '--nf_type')
399 check_client_version(ctx
.obj
, '--filter')
402 nf_filter
= "_admin.type=vnfd"
403 elif nf_type
== "pnf":
404 nf_filter
= "_admin.type=pnfd"
405 elif nf_type
== "hnf":
406 nf_filter
= "_admin.type=hnfd"
408 raise ClientException('wrong value for "--nf_type" option, allowed values: vnf, pnf, hnf')
410 filter = '{}&{}'.format(nf_filter
, filter)
414 resp
= ctx
.obj
.vnfd
.list(filter)
416 resp
= ctx
.obj
.vnfd
.list()
417 # print(yaml.safe_dump(resp))
418 table
= PrettyTable(['nfpkg name', 'id'])
419 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
420 if fullclassname
== 'osmclient.sol005.client.Client':
422 name
= vnfd
['name'] if 'name' in vnfd
else '-'
423 table
.add_row([name
, vnfd
['_id']])
426 table
.add_row([vnfd
['name'], vnfd
['id']])
431 @cli_osm.command(name
='vnfd-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
432 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
433 @click.option('--filter', default
=None,
434 help='restricts the list to the NF pkg matching the filter')
436 def vnfd_list1(ctx
, nf_type
, filter):
437 """list all xNF packages (VNF, HNF, PNF)"""
439 vnfd_list(ctx
, nf_type
, filter)
442 @cli_osm.command(name
='vnfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
443 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
444 @click.option('--filter', default
=None,
445 help='restricts the list to the NFpkg matching the filter')
447 def vnfd_list2(ctx
, nf_type
, filter):
448 """list all xNF packages (VNF, HNF, PNF)"""
450 vnfd_list(ctx
, nf_type
, filter)
453 @cli_osm.command(name
='nfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
454 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
455 @click.option('--filter', default
=None,
456 help='restricts the list to the NFpkg matching the filter')
458 def nfpkg_list(ctx
, nf_type
, filter):
459 """list all xNF packages (VNF, HNF, PNF)"""
462 check_client_version(ctx
.obj
, ctx
.command
.name
)
463 vnfd_list(ctx
, nf_type
, filter)
464 # except ClientException as e:
469 def vnf_list(ctx
, ns
, filter):
473 check_client_version(ctx
.obj
, '--ns')
475 check_client_version(ctx
.obj
, '--filter')
476 resp
= ctx
.obj
.vnf
.list(ns
, filter)
478 resp
= ctx
.obj
.vnf
.list()
479 # except ClientException as e:
482 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
483 if fullclassname
== 'osmclient.sol005.client.Client':
493 name
= vnfr
['name'] if 'name' in vnfr
else '-'
498 vnfr
['member-vnf-index-ref'],
500 vnfr
['vim-account-id'],
506 'operational status',
509 if 'mgmt-interface' not in vnfr
:
510 vnfr
['mgmt-interface'] = {}
511 vnfr
['mgmt-interface']['ip-address'] = None
515 vnfr
['operational-status'],
516 vnfr
['config-status']])
521 @cli_osm.command(name
='vnf-list', short_help
='list all NF instances')
522 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
523 @click.option('--filter', default
=None,
524 help='restricts the list to the NF instances matching the filter.')
526 def vnf_list1(ctx
, ns
, filter):
527 """list all NF instances"""
529 vnf_list(ctx
, ns
, filter)
532 @cli_osm.command(name
='nf-list', short_help
='list all NF instances')
533 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
534 @click.option('--filter', default
=None,
535 help='restricts the list to the NF instances matching the filter.')
537 def nf_list(ctx
, ns
, filter):
538 """list all NF instances
542 --ns TEXT NS instance id or name to restrict the VNF list
543 --filter filterExpr Restricts the list to the VNF instances matching the filter
546 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
547 concatenated using the "&" character:
550 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
551 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
552 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
554 value := scalar value
558 * zero or more occurrences
559 ? zero or one occurrence
560 [] grouping of expressions to be used with ? and *
561 "" quotation marks for marking string constants
565 "AttrName" is the name of one attribute in the data type that defines the representation
566 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
567 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
568 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
569 entries, it means that the operator "op" is applied to the attribute addressed by the last
570 <attrName> entry included in the concatenation. All simple filter expressions are combined
571 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
572 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
573 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
574 prefix". If an attribute referenced in an expression is an array, an object that contains a
575 corresponding array shall be considered to match the expression if any of the elements in the
576 array matches all expressions that have the same attribute prefix.
580 --filter vim-account-id=<VIM_ACCOUNT_ID>
581 --filter vnfd-ref=<VNFD_NAME>
582 --filter vdur.ip-address=<IP_ADDRESS>
583 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
586 vnf_list(ctx
, ns
, filter)
589 @cli_osm.command(name
='ns-op-list', short_help
='shows the history of operations over a NS instance')
590 @click.argument('name')
592 def ns_op_list(ctx
, name
):
593 """shows the history of operations over a NS instance
595 NAME: name or ID of the NS instance
597 def formatParams(params
):
598 if params
['lcmOperationType']=='instantiate':
599 params
.pop('nsDescription')
603 elif params
['lcmOperationType']=='action':
604 params
.pop('primitive')
605 params
.pop('lcmOperationType')
606 params
.pop('nsInstanceId')
611 check_client_version(ctx
.obj
, ctx
.command
.name
)
612 resp
= ctx
.obj
.ns
.list_op(name
)
613 # except ClientException as e:
617 table
= PrettyTable(['id', 'operation', 'action_name', 'operation_params', 'status', 'detail'])
618 #print(yaml.safe_dump(resp))
621 if op
['lcmOperationType']=='action':
622 action_name
= op
['operationParams']['primitive']
624 if op
['operationState']=='PROCESSING':
625 if op
['lcmOperationType']=='instantiate':
629 detail
= "In queue. Current position: {}".format(op
['queuePosition'])
630 elif op
['operationState']=='FAILED' or op
['operationState']=='FAILED_TEMP':
631 detail
= op
['errorMessage']
632 table
.add_row([op
['id'],
633 op
['lcmOperationType'],
635 wrap_text(text
=json
.dumps(formatParams(op
['operationParams']),indent
=2),width
=70),
636 op
['operationState'],
637 wrap_text(text
=detail
,width
=50)])
642 def nsi_list(ctx
, filter):
643 """list all Network Slice Instances"""
646 check_client_version(ctx
.obj
, ctx
.command
.name
)
647 resp
= ctx
.obj
.nsi
.list(filter)
648 # except ClientException as e:
652 ['netslice instance name',
654 'operational status',
658 nsi_name
= nsi
['name']
660 opstatus
= nsi
['operational-status'] if 'operational-status' in nsi
else 'Not found'
661 configstatus
= nsi
['config-status'] if 'config-status' in nsi
else 'Not found'
662 detailed_status
= nsi
['detailed-status'] if 'detailed-status' in nsi
else 'Not found'
663 if configstatus
== "config_not_needed":
664 configstatus
= "configured (no charms)"
675 @cli_osm.command(name
='nsi-list', short_help
='list all Network Slice Instances (NSI)')
676 @click.option('--filter', default
=None,
677 help='restricts the list to the Network Slice Instances matching the filter')
679 def nsi_list1(ctx
, filter):
680 """list all Network Slice Instances (NSI)"""
682 nsi_list(ctx
, filter)
685 @cli_osm.command(name
='netslice-instance-list', short_help
='list all Network Slice Instances (NSI)')
686 @click.option('--filter', default
=None,
687 help='restricts the list to the Network Slice Instances matching the filter')
689 def nsi_list2(ctx
, filter):
690 """list all Network Slice Instances (NSI)"""
692 nsi_list(ctx
, filter)
695 def nst_list(ctx
, filter):
698 check_client_version(ctx
.obj
, ctx
.command
.name
)
699 resp
= ctx
.obj
.nst
.list(filter)
700 # except ClientException as e:
703 # print(yaml.safe_dump(resp))
704 table
= PrettyTable(['nst name', 'id'])
706 name
= nst
['name'] if 'name' in nst
else '-'
707 table
.add_row([name
, nst
['_id']])
712 @cli_osm.command(name
='nst-list', short_help
='list all Network Slice Templates (NST)')
713 @click.option('--filter', default
=None,
714 help='restricts the list to the NST matching the filter')
716 def nst_list1(ctx
, filter):
717 """list all Network Slice Templates (NST) in the system"""
719 nst_list(ctx
, filter)
722 @cli_osm.command(name
='netslice-template-list', short_help
='list all Network Slice Templates (NST)')
723 @click.option('--filter', default
=None,
724 help='restricts the list to the NST matching the filter')
726 def nst_list2(ctx
, filter):
727 """list all Network Slice Templates (NST) in the system"""
729 nst_list(ctx
, filter)
732 def nsi_op_list(ctx
, name
):
735 check_client_version(ctx
.obj
, ctx
.command
.name
)
736 resp
= ctx
.obj
.nsi
.list_op(name
)
737 # except ClientException as e:
740 table
= PrettyTable(['id', 'operation', 'status'])
742 table
.add_row([op
['id'], op
['lcmOperationType'],
743 op
['operationState']])
748 @cli_osm.command(name
='nsi-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
749 @click.argument('name')
751 def nsi_op_list1(ctx
, name
):
752 """shows the history of operations over a Network Slice Instance (NSI)
754 NAME: name or ID of the Network Slice Instance
757 nsi_op_list(ctx
, name
)
760 @cli_osm.command(name
='netslice-instance-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
761 @click.argument('name')
763 def nsi_op_list2(ctx
, name
):
764 """shows the history of operations over a Network Slice Instance (NSI)
766 NAME: name or ID of the Network Slice Instance
769 nsi_op_list(ctx
, name
)
772 @cli_osm.command(name
='pdu-list', short_help
='list all Physical Deployment Units (PDU)')
773 @click.option('--filter', default
=None,
774 help='restricts the list to the Physical Deployment Units matching the filter')
776 def pdu_list(ctx
, filter):
777 """list all Physical Deployment Units (PDU)"""
780 check_client_version(ctx
.obj
, ctx
.command
.name
)
781 resp
= ctx
.obj
.pdu
.list(filter)
782 # except ClientException as e:
791 pdu_name
= pdu
['name']
793 pdu_type
= pdu
['type']
794 pdu_ipaddress
= "None"
795 for iface
in pdu
['interfaces']:
797 pdu_ipaddress
= iface
['ip-address']
812 def nsd_show(ctx
, name
, literal
):
815 resp
= ctx
.obj
.nsd
.get(name
)
816 # resp = ctx.obj.nsd.get_individual(name)
817 # except ClientException as e:
822 print(yaml
.safe_dump(resp
))
825 table
= PrettyTable(['field', 'value'])
826 for k
, v
in list(resp
.items()):
827 table
.add_row([k
, json
.dumps(v
, indent
=2)])
832 @cli_osm.command(name
='nsd-show', short_help
='shows the content of a NSD')
833 @click.option('--literal', is_flag
=True,
834 help='print literally, no pretty table')
835 @click.argument('name')
837 def nsd_show1(ctx
, name
, literal
):
838 """shows the content of a NSD
840 NAME: name or ID of the NSD/NSpkg
843 nsd_show(ctx
, name
, literal
)
846 @cli_osm.command(name
='nspkg-show', short_help
='shows the content of a NSD')
847 @click.option('--literal', is_flag
=True,
848 help='print literally, no pretty table')
849 @click.argument('name')
851 def nsd_show2(ctx
, name
, literal
):
852 """shows the content of a NSD
854 NAME: name or ID of the NSD/NSpkg
857 nsd_show(ctx
, name
, literal
)
860 def vnfd_show(ctx
, name
, literal
):
863 resp
= ctx
.obj
.vnfd
.get(name
)
864 # resp = ctx.obj.vnfd.get_individual(name)
865 # except ClientException as e:
870 print(yaml
.safe_dump(resp
))
873 table
= PrettyTable(['field', 'value'])
874 for k
, v
in list(resp
.items()):
875 table
.add_row([k
, json
.dumps(v
, indent
=2)])
880 @cli_osm.command(name
='vnfd-show', short_help
='shows the content of a VNFD')
881 @click.option('--literal', is_flag
=True,
882 help='print literally, no pretty table')
883 @click.argument('name')
885 def vnfd_show1(ctx
, name
, literal
):
886 """shows the content of a VNFD
888 NAME: name or ID of the VNFD/VNFpkg
891 vnfd_show(ctx
, name
, literal
)
894 @cli_osm.command(name
='vnfpkg-show', short_help
='shows the content of a VNFD')
895 @click.option('--literal', is_flag
=True,
896 help='print literally, no pretty table')
897 @click.argument('name')
899 def vnfd_show2(ctx
, name
, literal
):
900 """shows the content of a VNFD
902 NAME: name or ID of the VNFD/VNFpkg
905 vnfd_show(ctx
, name
, literal
)
908 @cli_osm.command(name
='nfpkg-show', short_help
='shows the content of a NF Descriptor')
909 @click.option('--literal', is_flag
=True,
910 help='print literally, no pretty table')
911 @click.argument('name')
913 def nfpkg_show(ctx
, name
, literal
):
914 """shows the content of a NF Descriptor
916 NAME: name or ID of the NFpkg
919 vnfd_show(ctx
, name
, literal
)
922 @cli_osm.command(name
='ns-show', short_help
='shows the info of a NS instance')
923 @click.argument('name')
924 @click.option('--literal', is_flag
=True,
925 help='print literally, no pretty table')
926 @click.option('--filter', default
=None)
928 def ns_show(ctx
, name
, literal
, filter):
929 """shows the info of a NS instance
931 NAME: name or ID of the NS instance
935 ns
= ctx
.obj
.ns
.get(name
)
936 # except ClientException as e:
941 print(yaml
.safe_dump(ns
))
944 table
= PrettyTable(['field', 'value'])
946 for k
, v
in list(ns
.items()):
947 if filter is None or filter in k
:
948 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
950 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
951 if fullclassname
!= 'osmclient.sol005.client.Client':
952 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
953 nsr_optdata
= nsopdata
['nsr:nsr']
954 for k
, v
in list(nsr_optdata
.items()):
955 if filter is None or filter in k
:
956 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2),width
=100)])
961 @cli_osm.command(name
='vnf-show', short_help
='shows the info of a VNF instance')
962 @click.argument('name')
963 @click.option('--literal', is_flag
=True,
964 help='print literally, no pretty table')
965 @click.option('--filter', default
=None, help='restricts the information to the fields in the filter')
966 @click.option('--kdu', default
=None, help='KDU name (whose status will be shown)')
968 def vnf_show(ctx
, name
, literal
, filter, kdu
):
969 """shows the info of a VNF instance
971 NAME: name or ID of the VNF instance
973 def print_kdu_status(op_info_status
):
974 """print KDU status properly formatted
977 op_status
= yaml
.safe_load(op_info_status
)
978 if "namespace" in op_status
and "info" in op_status
and \
979 "last_deployed" in op_status
["info"] and "status" in op_status
["info"] and \
980 "code" in op_status
["info"]["status"] and "resources" in op_status
["info"]["status"] and \
981 "notes" in op_status
["info"]["status"] and "seconds" in op_status
["info"]["last_deployed"]:
982 last_deployed_time
= datetime
.fromtimestamp(op_status
["info"]["last_deployed"]["seconds"]).strftime("%a %b %d %I:%M:%S %Y")
983 print("LAST DEPLOYED: {}".format(last_deployed_time
))
984 print("NAMESPACE: {}".format(op_status
["namespace"]))
985 status_code
= "UNKNOWN"
986 if op_status
["info"]["status"]["code"]==1:
987 status_code
= "DEPLOYED"
988 print("STATUS: {}".format(status_code
))
991 print(op_status
["info"]["status"]["resources"])
993 print(op_status
["info"]["status"]["notes"])
995 print(op_info_status
)
997 print(op_info_status
)
1002 raise ClientException('"--literal" option is incompatible with "--kdu" option')
1004 raise ClientException('"--filter" option is incompatible with "--kdu" option')
1007 check_client_version(ctx
.obj
, ctx
.command
.name
)
1008 resp
= ctx
.obj
.vnf
.get(name
)
1011 ns_id
= resp
['nsr-id-ref']
1013 op_data
['member_vnf_index'] = resp
['member-vnf-index-ref']
1014 op_data
['kdu_name'] = kdu
1015 op_data
['primitive'] = 'status'
1016 op_data
['primitive_params'] = {}
1017 op_id
= ctx
.obj
.ns
.exec_op(ns_id
, op_name
='action', op_data
=op_data
, wait
=False)
1020 op_info
= ctx
.obj
.ns
.get_op(op_id
)
1021 if op_info
['operationState'] == 'COMPLETED':
1022 print_kdu_status(op_info
['detailed-status'])
1026 print ("Could not determine KDU status")
1029 print(yaml
.safe_dump(resp
))
1032 table
= PrettyTable(['field', 'value'])
1034 for k
, v
in list(resp
.items()):
1035 if filter is None or filter in k
:
1036 table
.add_row([k
, wrap_text(text
=json
.dumps(v
,indent
=2),width
=100)])
1039 # except ClientException as e:
1044 #@cli_osm.command(name='vnf-monitoring-show')
1045 #@click.argument('vnf_name')
1046 #@click.pass_context
1047 #def vnf_monitoring_show(ctx, vnf_name):
1049 # check_client_version(ctx.obj, ctx.command.name, 'v1')
1050 # resp = ctx.obj.vnf.get_monitoring(vnf_name)
1051 # except ClientException as e:
1055 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
1056 # if resp is not None:
1057 # for monitor in resp:
1061 # monitor['value-integer'],
1062 # monitor['units']])
1067 #@cli_osm.command(name='ns-monitoring-show')
1068 #@click.argument('ns_name')
1069 #@click.pass_context
1070 #def ns_monitoring_show(ctx, ns_name):
1072 # check_client_version(ctx.obj, ctx.command.name, 'v1')
1073 # resp = ctx.obj.ns.get_monitoring(ns_name)
1074 # except ClientException as e:
1078 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
1079 # for key, val in list(resp.items()):
1080 # for monitor in val:
1084 # monitor['value-integer'],
1085 # monitor['units']])
1090 @cli_osm.command(name
='ns-op-show', short_help
='shows the info of a NS operation')
1091 @click.argument('id')
1092 @click.option('--filter', default
=None)
1093 @click.option('--literal', is_flag
=True,
1094 help='print literally, no pretty table')
1096 def ns_op_show(ctx
, id, filter, literal
):
1097 """shows the detailed info of a NS operation
1099 ID: operation identifier
1103 check_client_version(ctx
.obj
, ctx
.command
.name
)
1104 op_info
= ctx
.obj
.ns
.get_op(id)
1105 # except ClientException as e:
1110 print(yaml
.safe_dump(op_info
))
1113 table
= PrettyTable(['field', 'value'])
1114 for k
, v
in list(op_info
.items()):
1115 if filter is None or filter in k
:
1116 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
1121 def nst_show(ctx
, name
, literal
):
1124 check_client_version(ctx
.obj
, ctx
.command
.name
)
1125 resp
= ctx
.obj
.nst
.get(name
)
1126 #resp = ctx.obj.nst.get_individual(name)
1127 # except ClientException as e:
1132 print(yaml
.safe_dump(resp
))
1135 table
= PrettyTable(['field', 'value'])
1136 for k
, v
in list(resp
.items()):
1137 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
1142 @cli_osm.command(name
='nst-show', short_help
='shows the content of a Network Slice Template (NST)')
1143 @click.option('--literal', is_flag
=True,
1144 help='print literally, no pretty table')
1145 @click.argument('name')
1147 def nst_show1(ctx
, name
, literal
):
1148 """shows the content of a Network Slice Template (NST)
1150 NAME: name or ID of the NST
1153 nst_show(ctx
, name
, literal
)
1156 @cli_osm.command(name
='netslice-template-show', short_help
='shows the content of a Network Slice Template (NST)')
1157 @click.option('--literal', is_flag
=True,
1158 help='print literally, no pretty table')
1159 @click.argument('name')
1161 def nst_show2(ctx
, name
, literal
):
1162 """shows the content of a Network Slice Template (NST)
1164 NAME: name or ID of the NST
1167 nst_show(ctx
, name
, literal
)
1170 def nsi_show(ctx
, name
, literal
, filter):
1173 check_client_version(ctx
.obj
, ctx
.command
.name
)
1174 nsi
= ctx
.obj
.nsi
.get(name
)
1175 # except ClientException as e:
1180 print(yaml
.safe_dump(nsi
))
1183 table
= PrettyTable(['field', 'value'])
1185 for k
, v
in list(nsi
.items()):
1186 if filter is None or filter in k
:
1187 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1193 @cli_osm.command(name
='nsi-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1194 @click.argument('name')
1195 @click.option('--literal', is_flag
=True,
1196 help='print literally, no pretty table')
1197 @click.option('--filter', default
=None)
1199 def nsi_show1(ctx
, name
, literal
, filter):
1200 """shows the content of a Network Slice Instance (NSI)
1202 NAME: name or ID of the Network Slice Instance
1205 nsi_show(ctx
, name
, literal
, filter)
1208 @cli_osm.command(name
='netslice-instance-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1209 @click.argument('name')
1210 @click.option('--literal', is_flag
=True,
1211 help='print literally, no pretty table')
1212 @click.option('--filter', default
=None)
1214 def nsi_show2(ctx
, name
, literal
, filter):
1215 """shows the content of a Network Slice Instance (NSI)
1217 NAME: name or ID of the Network Slice Instance
1220 nsi_show(ctx
, name
, literal
, filter)
1223 def nsi_op_show(ctx
, id, filter):
1226 check_client_version(ctx
.obj
, ctx
.command
.name
)
1227 op_info
= ctx
.obj
.nsi
.get_op(id)
1228 # except ClientException as e:
1232 table
= PrettyTable(['field', 'value'])
1233 for k
, v
in list(op_info
.items()):
1234 if filter is None or filter in k
:
1235 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1240 @cli_osm.command(name
='nsi-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1241 @click.argument('id')
1242 @click.option('--filter', default
=None)
1244 def nsi_op_show1(ctx
, id, filter):
1245 """shows the info of an operation over a Network Slice Instance(NSI)
1247 ID: operation identifier
1250 nsi_op_show(ctx
, id, filter)
1253 @cli_osm.command(name
='netslice-instance-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1254 @click.argument('id')
1255 @click.option('--filter', default
=None)
1257 def nsi_op_show2(ctx
, id, filter):
1258 """shows the info of an operation over a Network Slice Instance(NSI)
1260 ID: operation identifier
1263 nsi_op_show(ctx
, id, filter)
1266 @cli_osm.command(name
='pdu-show', short_help
='shows the content of a Physical Deployment Unit (PDU)')
1267 @click.argument('name')
1268 @click.option('--literal', is_flag
=True,
1269 help='print literally, no pretty table')
1270 @click.option('--filter', default
=None)
1272 def pdu_show(ctx
, name
, literal
, filter):
1273 """shows the content of a Physical Deployment Unit (PDU)
1275 NAME: name or ID of the PDU
1279 check_client_version(ctx
.obj
, ctx
.command
.name
)
1280 pdu
= ctx
.obj
.pdu
.get(name
)
1281 # except ClientException as e:
1286 print(yaml
.safe_dump(pdu
))
1289 table
= PrettyTable(['field', 'value'])
1291 for k
, v
in list(pdu
.items()):
1292 if filter is None or filter in k
:
1293 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1299 ####################
1301 ####################
1303 def nsd_create(ctx
, filename
, overwrite
):
1306 check_client_version(ctx
.obj
, ctx
.command
.name
)
1307 ctx
.obj
.nsd
.create(filename
, overwrite
)
1308 # except ClientException as e:
1313 @cli_osm.command(name
='nsd-create', short_help
='creates a new NSD/NSpkg')
1314 @click.argument('filename')
1315 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1316 help='Deprecated. Use override')
1317 @click.option('--override', 'overwrite', default
=None,
1318 help='overrides fields in descriptor, format: '
1319 '"key1.key2...=value[;key3...=value;...]"')
1321 def nsd_create1(ctx
, filename
, overwrite
):
1322 """creates a new NSD/NSpkg
1324 FILENAME: NSD yaml file or NSpkg tar.gz file
1327 nsd_create(ctx
, filename
, overwrite
)
1330 @cli_osm.command(name
='nspkg-create', short_help
='creates a new NSD/NSpkg')
1331 @click.argument('filename')
1332 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1333 help='Deprecated. Use override')
1334 @click.option('--override', 'overwrite', default
=None,
1335 help='overrides fields in descriptor, format: '
1336 '"key1.key2...=value[;key3...=value;...]"')
1338 def nsd_create2(ctx
, filename
, overwrite
):
1339 """creates a new NSD/NSpkg
1341 FILENAME: NSD yaml file or NSpkg tar.gz file
1344 nsd_create(ctx
, filename
, overwrite
)
1347 def vnfd_create(ctx
, filename
, overwrite
):
1350 check_client_version(ctx
.obj
, ctx
.command
.name
)
1351 ctx
.obj
.vnfd
.create(filename
, overwrite
)
1352 # except ClientException as e:
1357 @cli_osm.command(name
='vnfd-create', short_help
='creates a new VNFD/VNFpkg')
1358 @click.argument('filename')
1359 @click.option('--overwrite', 'overwrite', default
=None,
1360 help='overwrite 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 vnfd_create1(ctx
, filename
, overwrite
):
1366 """creates a new VNFD/VNFpkg
1368 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1371 vnfd_create(ctx
, filename
, overwrite
)
1374 @cli_osm.command(name
='vnfpkg-create', short_help
='creates a new VNFD/VNFpkg')
1375 @click.argument('filename')
1376 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1377 help='Deprecated. Use override')
1378 @click.option('--override', 'overwrite', default
=None,
1379 help='overrides fields in descriptor, format: '
1380 '"key1.key2...=value[;key3...=value;...]"')
1382 def vnfd_create2(ctx
, filename
, overwrite
):
1383 """creates a new VNFD/VNFpkg
1385 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1388 vnfd_create(ctx
, filename
, overwrite
)
1391 @cli_osm.command(name
='nfpkg-create', short_help
='creates a new NFpkg')
1392 @click.argument('filename')
1393 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1394 help='Deprecated. Use override')
1395 @click.option('--override', 'overwrite', default
=None,
1396 help='overrides fields in descriptor, format: '
1397 '"key1.key2...=value[;key3...=value;...]"')
1399 def nfpkg_create(ctx
, filename
, overwrite
):
1400 """creates a new NFpkg
1402 FILENAME: NF Descriptor yaml file or NFpkg tar.gz file
1405 vnfd_create(ctx
, filename
, overwrite
)
1408 @cli_osm.command(name
='ns-create', short_help
='creates a new Network Service instance')
1409 @click.option('--ns_name',
1410 prompt
=True, help='name of the NS instance')
1411 @click.option('--nsd_name',
1412 prompt
=True, help='name of the NS descriptor')
1413 @click.option('--vim_account',
1414 prompt
=True, help='default VIM account id or name for the deployment')
1415 @click.option('--admin_status',
1417 help='administration status')
1418 @click.option('--ssh_keys',
1420 help='comma separated list of public key files to inject to vnfs')
1421 @click.option('--config',
1423 help='ns specific yaml configuration')
1424 @click.option('--config_file',
1426 help='ns specific yaml configuration file')
1427 @click.option('--wait',
1431 help='do not return the control immediately, but keep it '
1432 'until the operation is completed, or timeout')
1443 """creates a new NS instance"""
1447 check_client_version(ctx
.obj
, '--config_file')
1449 raise ClientException('"--config" option is incompatible with "--config_file" option')
1450 with
open(config_file
, 'r') as cf
:
1457 account
=vim_account
,
1459 # except ClientException as e:
1464 def nst_create(ctx
, filename
, overwrite
):
1467 check_client_version(ctx
.obj
, ctx
.command
.name
)
1468 ctx
.obj
.nst
.create(filename
, overwrite
)
1469 # except ClientException as e:
1474 @cli_osm.command(name
='nst-create', short_help
='creates a new Network Slice Template (NST)')
1475 @click.argument('filename')
1476 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1477 help='Deprecated. Use override')
1478 @click.option('--override', 'overwrite', default
=None,
1479 help='overrides fields in descriptor, format: '
1480 '"key1.key2...=value[;key3...=value;...]"')
1482 def nst_create1(ctx
, filename
, overwrite
):
1483 """creates a new Network Slice Template (NST)
1485 FILENAME: NST yaml file or NSTpkg tar.gz file
1488 nst_create(ctx
, filename
, overwrite
)
1491 @cli_osm.command(name
='netslice-template-create', short_help
='creates a new Network Slice Template (NST)')
1492 @click.argument('filename')
1493 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1494 help='Deprecated. Use override')
1495 @click.option('--override', 'overwrite', default
=None,
1496 help='overrides fields in descriptor, format: '
1497 '"key1.key2...=value[;key3...=value;...]"')
1499 def nst_create2(ctx
, filename
, overwrite
):
1500 """creates a new Network Slice Template (NST)
1502 FILENAME: NST yaml file or NSTpkg tar.gz file
1505 nst_create(ctx
, filename
, overwrite
)
1508 def nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1509 """creates a new Network Slice Instance (NSI)"""
1512 check_client_version(ctx
.obj
, ctx
.command
.name
)
1515 raise ClientException('"--config" option is incompatible with "--config_file" option')
1516 with
open(config_file
, 'r') as cf
:
1518 ctx
.obj
.nsi
.create(nst_name
, nsi_name
, config
=config
, ssh_keys
=ssh_keys
,
1519 account
=vim_account
, wait
=wait
)
1520 # except ClientException as e:
1525 @cli_osm.command(name
='nsi-create', short_help
='creates a new Network Slice Instance')
1526 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1527 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1528 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1529 @click.option('--ssh_keys', default
=None,
1530 help='comma separated list of keys to inject to vnfs')
1531 @click.option('--config', default
=None,
1532 help='Netslice specific yaml configuration:\n'
1533 'netslice_subnet: [\n'
1534 'id: TEXT, vim_account: TEXT,\n'
1535 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1536 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]\n'
1537 'additionalParamsForNsi: {param: value, ...}\n'
1538 'additionalParamsForsubnet: [{id: SUBNET_ID, additionalParamsForNs: {}, additionalParamsForVnf: {}}]\n'
1540 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1542 @click.option('--config_file',
1544 help='nsi specific yaml configuration file')
1545 @click.option('--wait',
1549 help='do not return the control immediately, but keep it '
1550 'until the operation is completed, or timeout')
1552 def nsi_create1(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1553 """creates a new Network Slice Instance (NSI)"""
1555 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1558 @cli_osm.command(name
='netslice-instance-create', short_help
='creates a new Network Slice Instance')
1559 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1560 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1561 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1562 @click.option('--ssh_keys', default
=None,
1563 help='comma separated list of keys to inject to vnfs')
1564 @click.option('--config', default
=None,
1565 help='Netslice specific yaml configuration:\n'
1566 'netslice_subnet: [\n'
1567 'id: TEXT, vim_account: TEXT,\n'
1568 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1569 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1571 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1573 @click.option('--config_file',
1575 help='nsi specific yaml configuration file')
1576 @click.option('--wait',
1580 help='do not return the control immediately, but keep it '
1581 'until the operation is completed, or timeout')
1583 def nsi_create2(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1584 """creates a new Network Slice Instance (NSI)"""
1586 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1589 @cli_osm.command(name
='pdu-create', short_help
='adds a new Physical Deployment Unit to the catalog')
1590 @click.option('--name', help='name of the Physical Deployment Unit')
1591 @click.option('--pdu_type', help='type of PDU (e.g. router, firewall, FW001)')
1592 @click.option('--interface',
1593 help='interface(s) of the PDU: name=<NAME>,mgmt=<true|false>,ip-address=<IP_ADDRESS>'+
1594 '[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]',
1596 @click.option('--description', help='human readable description')
1597 @click.option('--vim_account', help='list of VIM accounts (in the same VIM) that can reach this PDU', multiple
=True)
1598 @click.option('--descriptor_file', default
=None,
1599 help='PDU descriptor file (as an alternative to using the other arguments')
1601 def pdu_create(ctx
, name
, pdu_type
, interface
, description
, vim_account
, descriptor_file
):
1602 """creates a new Physical Deployment Unit (PDU)"""
1605 check_client_version(ctx
.obj
, ctx
.command
.name
)
1607 if not descriptor_file
:
1609 raise ClientException('in absence of descriptor file, option "--name" is mandatory')
1611 raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory')
1613 raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)')
1615 raise ClientException('in absence of descriptor file, option "--vim_account" is mandatory (at least once)')
1617 with
open(descriptor_file
, 'r') as df
:
1618 pdu
= yaml
.safe_load(df
.read())
1619 if name
: pdu
["name"] = name
1620 if pdu_type
: pdu
["type"] = pdu_type
1621 if description
: pdu
["description"] = description
1622 if vim_account
: pdu
["vim_accounts"] = vim_account
1625 for iface
in interface
:
1626 new_iface
={k
:v
for k
,v
in [i
.split('=') for i
in iface
.split(',')]}
1627 new_iface
["mgmt"] = (new_iface
.get("mgmt","false").lower() == "true")
1628 ifaces_list
.append(new_iface
)
1629 pdu
["interfaces"] = ifaces_list
1630 ctx
.obj
.pdu
.create(pdu
)
1631 # except ClientException as e:
1636 ####################
1638 ####################
1640 def nsd_update(ctx
, name
, content
):
1643 check_client_version(ctx
.obj
, ctx
.command
.name
)
1644 ctx
.obj
.nsd
.update(name
, content
)
1645 # except ClientException as e:
1650 @cli_osm.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
1651 @click.argument('name')
1652 @click.option('--content', default
=None,
1653 help='filename with the NSD/NSpkg replacing the current one')
1655 def nsd_update1(ctx
, name
, content
):
1656 """updates a NSD/NSpkg
1658 NAME: name or ID of the NSD/NSpkg
1661 nsd_update(ctx
, name
, content
)
1664 @cli_osm.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
1665 @click.argument('name')
1666 @click.option('--content', default
=None,
1667 help='filename with the NSD/NSpkg replacing the current one')
1669 def nsd_update2(ctx
, name
, content
):
1670 """updates a NSD/NSpkg
1672 NAME: name or ID of the NSD/NSpkg
1675 nsd_update(ctx
, name
, content
)
1678 def vnfd_update(ctx
, name
, content
):
1681 check_client_version(ctx
.obj
, ctx
.command
.name
)
1682 ctx
.obj
.vnfd
.update(name
, content
)
1683 # except ClientException as e:
1688 @cli_osm.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
1689 @click.argument('name')
1690 @click.option('--content', default
=None,
1691 help='filename with the VNFD/VNFpkg replacing the current one')
1693 def vnfd_update1(ctx
, name
, content
):
1694 """updates a VNFD/VNFpkg
1696 NAME: name or ID of the VNFD/VNFpkg
1699 vnfd_update(ctx
, name
, content
)
1702 @cli_osm.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
1703 @click.argument('name')
1704 @click.option('--content', default
=None,
1705 help='filename with the VNFD/VNFpkg replacing the current one')
1707 def vnfd_update2(ctx
, name
, content
):
1708 """updates a VNFD/VNFpkg
1710 NAME: VNFD yaml file or VNFpkg tar.gz file
1713 vnfd_update(ctx
, name
, content
)
1716 @cli_osm.command(name
='nfpkg-update', short_help
='updates a NFpkg')
1717 @click.argument('name')
1718 @click.option('--content', default
=None,
1719 help='filename with the NFpkg replacing the current one')
1721 def nfpkg_update(ctx
, name
, content
):
1724 NAME: NF Descriptor yaml file or NFpkg tar.gz file
1727 vnfd_update(ctx
, name
, content
)
1730 def nst_update(ctx
, name
, content
):
1733 check_client_version(ctx
.obj
, ctx
.command
.name
)
1734 ctx
.obj
.nst
.update(name
, content
)
1735 # except ClientException as e:
1740 @cli_osm.command(name
='nst-update', short_help
='updates a Network Slice Template (NST)')
1741 @click.argument('name')
1742 @click.option('--content', default
=None,
1743 help='filename with the NST/NSTpkg replacing the current one')
1745 def nst_update1(ctx
, name
, content
):
1746 """updates a Network Slice Template (NST)
1748 NAME: name or ID of the NSD/NSpkg
1751 nst_update(ctx
, name
, content
)
1754 @cli_osm.command(name
='netslice-template-update', short_help
='updates a Network Slice Template (NST)')
1755 @click.argument('name')
1756 @click.option('--content', default
=None,
1757 help='filename with the NST/NSTpkg replacing the current one')
1759 def nst_update2(ctx
, name
, content
):
1760 """updates a Network Slice Template (NST)
1762 NAME: name or ID of the NSD/NSpkg
1765 nst_update(ctx
, name
, content
)
1768 ####################
1770 ####################
1772 def nsd_delete(ctx
, name
, force
):
1776 ctx
.obj
.nsd
.delete(name
)
1778 check_client_version(ctx
.obj
, '--force')
1779 ctx
.obj
.nsd
.delete(name
, force
)
1780 # except ClientException as e:
1785 @cli_osm.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
1786 @click.argument('name')
1787 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1789 def nsd_delete1(ctx
, name
, force
):
1790 """deletes a NSD/NSpkg
1792 NAME: name or ID of the NSD/NSpkg to be deleted
1795 nsd_delete(ctx
, name
, force
)
1798 @cli_osm.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
1799 @click.argument('name')
1800 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1802 def nsd_delete2(ctx
, name
, force
):
1803 """deletes a NSD/NSpkg
1805 NAME: name or ID of the NSD/NSpkg to be deleted
1808 nsd_delete(ctx
, name
, force
)
1811 def vnfd_delete(ctx
, name
, force
):
1815 ctx
.obj
.vnfd
.delete(name
)
1817 check_client_version(ctx
.obj
, '--force')
1818 ctx
.obj
.vnfd
.delete(name
, force
)
1819 # except ClientException as e:
1824 @cli_osm.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
1825 @click.argument('name')
1826 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1828 def vnfd_delete1(ctx
, name
, force
):
1829 """deletes a VNFD/VNFpkg
1831 NAME: name or ID of the VNFD/VNFpkg to be deleted
1834 vnfd_delete(ctx
, name
, force
)
1837 @cli_osm.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
1838 @click.argument('name')
1839 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1841 def vnfd_delete2(ctx
, name
, force
):
1842 """deletes a VNFD/VNFpkg
1844 NAME: name or ID of the VNFD/VNFpkg to be deleted
1847 vnfd_delete(ctx
, name
, force
)
1850 @cli_osm.command(name
='nfpkg-delete', short_help
='deletes a NFpkg')
1851 @click.argument('name')
1852 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1854 def nfpkg_delete(ctx
, name
, force
):
1857 NAME: name or ID of the NFpkg to be deleted
1860 vnfd_delete(ctx
, name
, force
)
1863 @cli_osm.command(name
='ns-delete', short_help
='deletes a NS instance')
1864 @click.argument('name')
1865 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1866 @click.option('--wait',
1870 help='do not return the control immediately, but keep it '
1871 'until the operation is completed, or timeout')
1873 def ns_delete(ctx
, name
, force
, wait
):
1874 """deletes a NS instance
1876 NAME: name or ID of the NS instance to be deleted
1881 ctx
.obj
.ns
.delete(name
, wait
=wait
)
1883 check_client_version(ctx
.obj
, '--force')
1884 ctx
.obj
.ns
.delete(name
, force
, wait
=wait
)
1885 # except ClientException as e:
1890 def nst_delete(ctx
, name
, force
):
1893 check_client_version(ctx
.obj
, ctx
.command
.name
)
1894 ctx
.obj
.nst
.delete(name
, force
)
1895 # except ClientException as e:
1900 @cli_osm.command(name
='nst-delete', short_help
='deletes a Network Slice Template (NST)')
1901 @click.argument('name')
1902 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1904 def nst_delete1(ctx
, name
, force
):
1905 """deletes a Network Slice Template (NST)
1907 NAME: name or ID of the NST/NSTpkg to be deleted
1910 nst_delete(ctx
, name
, force
)
1913 @cli_osm.command(name
='netslice-template-delete', short_help
='deletes a Network Slice Template (NST)')
1914 @click.argument('name')
1915 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1917 def nst_delete2(ctx
, name
, force
):
1918 """deletes a Network Slice Template (NST)
1920 NAME: name or ID of the NST/NSTpkg to be deleted
1923 nst_delete(ctx
, name
, force
)
1926 def nsi_delete(ctx
, name
, force
, wait
):
1929 check_client_version(ctx
.obj
, ctx
.command
.name
)
1930 ctx
.obj
.nsi
.delete(name
, force
, wait
=wait
)
1931 # except ClientException as e:
1936 @cli_osm.command(name
='nsi-delete', short_help
='deletes a Network Slice Instance (NSI)')
1937 @click.argument('name')
1938 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1939 @click.option('--wait',
1943 help='do not return the control immediately, but keep it '
1944 'until the operation is completed, or timeout')
1946 def nsi_delete1(ctx
, name
, force
, wait
):
1947 """deletes a Network Slice Instance (NSI)
1949 NAME: name or ID of the Network Slice instance to be deleted
1952 nsi_delete(ctx
, name
, force
, wait
=wait
)
1955 @cli_osm.command(name
='netslice-instance-delete', short_help
='deletes a Network Slice Instance (NSI)')
1956 @click.argument('name')
1957 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1959 def nsi_delete2(ctx
, name
, force
, wait
):
1960 """deletes a Network Slice Instance (NSI)
1962 NAME: name or ID of the Network Slice instance to be deleted
1965 nsi_delete(ctx
, name
, force
, wait
=wait
)
1968 @cli_osm.command(name
='pdu-delete', short_help
='deletes a Physical Deployment Unit (PDU)')
1969 @click.argument('name')
1970 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1972 def pdu_delete(ctx
, name
, force
):
1973 """deletes a Physical Deployment Unit (PDU)
1975 NAME: name or ID of the PDU to be deleted
1979 check_client_version(ctx
.obj
, ctx
.command
.name
)
1980 ctx
.obj
.pdu
.delete(name
, force
)
1981 # except ClientException as e:
1990 @cli_osm.command(name
='vim-create', short_help
='creates a new VIM account')
1991 @click.option('--name',
1993 help='Name to create datacenter')
1994 @click.option('--user',
1996 help='VIM username')
1997 @click.option('--password',
2000 confirmation_prompt
=True,
2001 help='VIM password')
2002 @click.option('--auth_url',
2005 @click.option('--tenant',
2007 help='VIM tenant name')
2008 @click.option('--config',
2010 help='VIM specific config parameters')
2011 @click.option('--account_type',
2012 default
='openstack',
2014 @click.option('--description',
2015 default
='no description',
2016 help='human readable description')
2017 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
2018 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
2019 @click.option('--wait',
2023 help='do not return the control immediately, but keep it '
2024 'until the operation is completed, or timeout')
2038 """creates a new VIM account"""
2042 check_client_version(ctx
.obj
, '--sdn_controller')
2043 if sdn_port_mapping
:
2044 check_client_version(ctx
.obj
, '--sdn_port_mapping')
2046 vim
['vim-username'] = user
2047 vim
['vim-password'] = password
2048 vim
['vim-url'] = auth_url
2049 vim
['vim-tenant-name'] = tenant
2050 vim
['vim-type'] = account_type
2051 vim
['description'] = description
2052 vim
['config'] = config
2053 if sdn_controller
or sdn_port_mapping
:
2054 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
2056 ctx
.obj
.vim
.create(name
, vim
, wait
=wait
)
2057 # except ClientException as e:
2062 @cli_osm.command(name
='vim-update', short_help
='updates a VIM account')
2063 @click.argument('name')
2064 @click.option('--newname', help='New name for the VIM account')
2065 @click.option('--user', help='VIM username')
2066 @click.option('--password', help='VIM password')
2067 @click.option('--auth_url', help='VIM url')
2068 @click.option('--tenant', help='VIM tenant name')
2069 @click.option('--config', help='VIM specific config parameters')
2070 @click.option('--account_type', help='VIM type')
2071 @click.option('--description', help='human readable description')
2072 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
2073 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
2074 @click.option('--wait',
2078 help='do not return the control immediately, but keep it '
2079 'until the operation is completed, or timeout')
2094 """updates a VIM account
2096 NAME: name or ID of the VIM account
2100 check_client_version(ctx
.obj
, ctx
.command
.name
)
2102 if newname
: vim
['name'] = newname
2103 if user
: vim
['vim_user'] = user
2104 if password
: vim
['vim_password'] = password
2105 if auth_url
: vim
['vim_url'] = auth_url
2106 if tenant
: vim
['vim-tenant-name'] = tenant
2107 if account_type
: vim
['vim_type'] = account_type
2108 if description
: vim
['description'] = description
2109 if config
: vim
['config'] = config
2110 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
2111 # except ClientException as e:
2116 @cli_osm.command(name
='vim-delete', short_help
='deletes a VIM account')
2117 @click.argument('name')
2118 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2119 @click.option('--wait',
2123 help='do not return the control immediately, but keep it '
2124 'until the operation is completed, or timeout')
2126 def vim_delete(ctx
, name
, force
, wait
):
2127 """deletes a VIM account
2129 NAME: name or ID of the VIM account to be deleted
2134 ctx
.obj
.vim
.delete(name
, wait
=wait
)
2136 check_client_version(ctx
.obj
, '--force')
2137 ctx
.obj
.vim
.delete(name
, force
, wait
=wait
)
2138 # except ClientException as e:
2143 @cli_osm.command(name
='vim-list', short_help
='list all VIM accounts')
2144 #@click.option('--ro_update/--no_ro_update',
2146 # help='update list from RO')
2147 @click.option('--filter', default
=None,
2148 help='restricts the list to the VIM accounts matching the filter')
2150 def vim_list(ctx
, filter):
2151 """list all VIM accounts"""
2154 check_client_version(ctx
.obj
, '--filter')
2156 # check_client_version(ctx.obj, '--ro_update', 'v1')
2157 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
2158 if fullclassname
== 'osmclient.sol005.client.Client':
2159 resp
= ctx
.obj
.vim
.list(filter)
2161 # resp = ctx.obj.vim.list(ro_update)
2162 table
= PrettyTable(['vim name', 'uuid'])
2164 table
.add_row([vim
['name'], vim
['uuid']])
2169 @cli_osm.command(name
='vim-show', short_help
='shows the details of a VIM account')
2170 @click.argument('name')
2172 def vim_show(ctx
, name
):
2173 """shows the details of a VIM account
2175 NAME: name or ID of the VIM account
2179 resp
= ctx
.obj
.vim
.get(name
)
2180 if 'vim_password' in resp
:
2181 resp
['vim_password']='********'
2182 # except ClientException as e:
2186 table
= PrettyTable(['key', 'attribute'])
2187 for k
, v
in list(resp
.items()):
2188 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2193 ####################
2195 ####################
2197 @cli_osm.command(name
='wim-create', short_help
='creates a new WIM account')
2198 @click.option('--name',
2200 help='Name for the WIM account')
2201 @click.option('--user',
2202 help='WIM username')
2203 @click.option('--password',
2204 help='WIM password')
2205 @click.option('--url',
2208 # @click.option('--tenant',
2209 # help='wIM tenant name')
2210 @click.option('--config',
2212 help='WIM specific config parameters')
2213 @click.option('--wim_type',
2215 @click.option('--description',
2216 default
='no description',
2217 help='human readable description')
2218 @click.option('--wim_port_mapping', default
=None,
2219 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2220 "(WAN service endpoint id and info)")
2221 @click.option('--wait',
2225 help='do not return the control immediately, but keep it '
2226 'until the operation is completed, or timeout')
2239 """creates a new WIM account"""
2242 check_client_version(ctx
.obj
, ctx
.command
.name
)
2243 # if sdn_controller:
2244 # check_client_version(ctx.obj, '--sdn_controller')
2245 # if sdn_port_mapping:
2246 # check_client_version(ctx.obj, '--sdn_port_mapping')
2248 if user
: wim
['user'] = user
2249 if password
: wim
['password'] = password
2250 if url
: wim
['wim_url'] = url
2251 # if tenant: wim['tenant'] = tenant
2252 wim
['wim_type'] = wim_type
2253 if description
: wim
['description'] = description
2254 if config
: wim
['config'] = config
2255 ctx
.obj
.wim
.create(name
, wim
, wim_port_mapping
, wait
=wait
)
2256 # except ClientException as e:
2261 @cli_osm.command(name
='wim-update', short_help
='updates a WIM account')
2262 @click.argument('name')
2263 @click.option('--newname', help='New name for the WIM account')
2264 @click.option('--user', help='WIM username')
2265 @click.option('--password', help='WIM password')
2266 @click.option('--url', help='WIM url')
2267 @click.option('--config', help='WIM specific config parameters')
2268 @click.option('--wim_type', help='WIM type')
2269 @click.option('--description', help='human readable description')
2270 @click.option('--wim_port_mapping', default
=None,
2271 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2272 "(WAN service endpoint id and info)")
2273 @click.option('--wait',
2277 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2290 """updates a WIM account
2292 NAME: name or ID of the WIM account
2296 check_client_version(ctx
.obj
, ctx
.command
.name
)
2298 if newname
: wim
['name'] = newname
2299 if user
: wim
['user'] = user
2300 if password
: wim
['password'] = password
2301 if url
: wim
['url'] = url
2302 # if tenant: wim['tenant'] = tenant
2303 if wim_type
: wim
['wim_type'] = wim_type
2304 if description
: wim
['description'] = description
2305 if config
: wim
['config'] = config
2306 ctx
.obj
.wim
.update(name
, wim
, wim_port_mapping
, wait
=wait
)
2307 # except ClientException as e:
2312 @cli_osm.command(name
='wim-delete', short_help
='deletes a WIM account')
2313 @click.argument('name')
2314 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2315 @click.option('--wait',
2319 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2321 def wim_delete(ctx
, name
, force
, wait
):
2322 """deletes a WIM account
2324 NAME: name or ID of the WIM account to be deleted
2328 check_client_version(ctx
.obj
, ctx
.command
.name
)
2329 ctx
.obj
.wim
.delete(name
, force
, wait
=wait
)
2330 # except ClientException as e:
2335 @cli_osm.command(name
='wim-list', short_help
='list all WIM accounts')
2336 @click.option('--filter', default
=None,
2337 help='restricts the list to the WIM accounts matching the filter')
2339 def wim_list(ctx
, filter):
2340 """list all WIM accounts"""
2343 check_client_version(ctx
.obj
, ctx
.command
.name
)
2344 resp
= ctx
.obj
.wim
.list(filter)
2345 table
= PrettyTable(['wim name', 'uuid'])
2347 table
.add_row([wim
['name'], wim
['uuid']])
2350 # except ClientException as e:
2355 @cli_osm.command(name
='wim-show', short_help
='shows the details of a WIM account')
2356 @click.argument('name')
2358 def wim_show(ctx
, name
):
2359 """shows the details of a WIM account
2361 NAME: name or ID of the WIM account
2365 check_client_version(ctx
.obj
, ctx
.command
.name
)
2366 resp
= ctx
.obj
.wim
.get(name
)
2367 if 'password' in resp
:
2368 resp
['wim_password']='********'
2369 # except ClientException as e:
2373 table
= PrettyTable(['key', 'attribute'])
2374 for k
, v
in list(resp
.items()):
2375 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2380 ####################
2381 # SDN controller operations
2382 ####################
2384 @cli_osm.command(name
='sdnc-create', short_help
='creates a new SDN controller')
2385 @click.option('--name',
2387 help='Name to create sdn controller')
2388 @click.option('--type',
2390 help='SDN controller type')
2391 @click.option('--sdn_controller_version', # hidden=True,
2392 help='Deprecated. Use --config {version: sdn_controller_version}')
2393 @click.option('--url',
2394 help='URL in format http[s]://HOST:IP/')
2395 @click.option('--ip_address', # hidden=True,
2396 help='Deprecated. Use --url')
2397 @click.option('--port', # hidden=True,
2398 help='Deprecated. Use --url')
2399 @click.option('--switch_dpid', # hidden=True,
2400 help='Deprecated. Use --config {dpid: DPID}')
2401 @click.option('--config',
2402 help='Extra information for SDN in yaml format, as {dpid: (Openflow Datapath ID), version: version}')
2403 @click.option('--user',
2404 help='SDN controller username')
2405 @click.option('--password',
2407 confirmation_prompt
=True,
2408 help='SDN controller password')
2409 @click.option('--description', default
=None, help='human readable description')
2410 @click.option('--wait',
2414 help="do not return the control immediately, but keep it until the operation is completed, or timeout")
2416 def sdnc_create(ctx
, **kwargs
):
2417 """creates a new SDN controller"""
2419 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2420 x
not in ("wait", "ip_address", "port", "switch_dpid")}
2421 if kwargs
.get("port"):
2422 print("option '--port' is deprecated, use '-url' instead")
2423 sdncontroller
["port"] = int(kwargs
["port"])
2424 if kwargs
.get("ip_address"):
2425 print("option '--ip_address' is deprecated, use '-url' instead")
2426 sdncontroller
["ip"] = kwargs
["ip_address"]
2427 if kwargs
.get("switch_dpid"):
2428 print("option '--switch_dpid' is deprecated, use '---config={dpid: DPID}' instead")
2429 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2430 if kwargs
.get("sdn_controller_version"):
2431 print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'"
2434 check_client_version(ctx
.obj
, ctx
.command
.name
)
2435 ctx
.obj
.sdnc
.create(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2436 # except ClientException as e:
2440 @cli_osm.command(name
='sdnc-update', short_help
='updates an SDN controller')
2441 @click.argument('name')
2442 @click.option('--newname', help='New name for the SDN controller')
2443 @click.option('--description', default
=None, help='human readable description')
2444 @click.option('--type', help='SDN controller type')
2445 @click.option('--url', help='URL in format http[s]://HOST:IP/')
2446 @click.option('--config', help='Extra information for SDN in yaml format, as '
2447 '{dpid: (Openflow Datapath ID), version: version}')
2448 @click.option('--user', help='SDN controller username')
2449 @click.option('--password', help='SDN controller password')
2450 @click.option('--ip_address', help='Deprecated. Use --url') # hidden=True
2451 @click.option('--port', help='Deprecated. Use --url') # hidden=True
2452 @click.option('--switch_dpid', help='Deprecated. Use --config {switch_dpid: DPID}') # hidden=True
2453 @click.option('--sdn_controller_version', help='Deprecated. Use --config {version: VERSION}') # hidden=True
2454 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2455 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2457 def sdnc_update(ctx
, **kwargs
):
2458 """updates an SDN controller
2460 NAME: name or ID of the SDN controller
2463 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2464 x
not in ("wait", "ip_address", "port", "switch_dpid", "new_name")}
2465 if kwargs
.get("newname"):
2466 sdncontroller
["name"] = kwargs
["newname"]
2467 if kwargs
.get("port"):
2468 print("option '--port' is deprecated, use '-url' instead")
2469 sdncontroller
["port"] = int(kwargs
["port"])
2470 if kwargs
.get("ip_address"):
2471 print("option '--ip_address' is deprecated, use '-url' instead")
2472 sdncontroller
["ip"] = kwargs
["ip_address"]
2473 if kwargs
.get("switch_dpid"):
2474 print("option '--switch_dpid' is deprecated, use '---config={dpid: DPID}' instead")
2475 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2476 if kwargs
.get("sdn_controller_version"):
2477 print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'"
2481 check_client_version(ctx
.obj
, ctx
.command
.name
)
2482 ctx
.obj
.sdnc
.update(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2483 # except ClientException as e:
2488 @cli_osm.command(name
='sdnc-delete', short_help
='deletes an SDN controller')
2489 @click.argument('name')
2490 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2491 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2492 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2494 def sdnc_delete(ctx
, name
, force
, wait
):
2495 """deletes an SDN controller
2497 NAME: name or ID of the SDN controller to be deleted
2501 check_client_version(ctx
.obj
, ctx
.command
.name
)
2502 ctx
.obj
.sdnc
.delete(name
, force
, wait
=wait
)
2503 # except ClientException as e:
2508 @cli_osm.command(name
='sdnc-list', short_help
='list all SDN controllers')
2509 @click.option('--filter', default
=None,
2510 help="restricts the list to the SDN controllers matching the filter with format: 'k[.k..]=v[&k[.k]=v2]'")
2512 def sdnc_list(ctx
, filter):
2513 """list all SDN controllers"""
2516 check_client_version(ctx
.obj
, ctx
.command
.name
)
2517 resp
= ctx
.obj
.sdnc
.list(filter)
2518 # except ClientException as e:
2521 table
= PrettyTable(['sdnc name', 'id'])
2523 table
.add_row([sdnc
['name'], sdnc
['_id']])
2528 @cli_osm.command(name
='sdnc-show', short_help
='shows the details of an SDN controller')
2529 @click.argument('name')
2531 def sdnc_show(ctx
, name
):
2532 """shows the details of an SDN controller
2534 NAME: name or ID of the SDN controller
2538 check_client_version(ctx
.obj
, ctx
.command
.name
)
2539 resp
= ctx
.obj
.sdnc
.get(name
)
2540 # except ClientException as e:
2544 table
= PrettyTable(['key', 'attribute'])
2545 for k
, v
in list(resp
.items()):
2546 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2551 ###########################
2552 # K8s cluster operations
2553 ###########################
2555 @cli_osm.command(name
='k8scluster-add')
2556 @click.argument('name')
2557 @click.option('--creds',
2559 help='credentials file, i.e. a valid `.kube/config` file')
2560 @click.option('--version',
2562 help='Kubernetes version')
2563 @click.option('--vim',
2565 help='VIM target, the VIM where the cluster resides')
2566 @click.option('--k8s-nets',
2568 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) ...]}"')
2569 @click.option('--description',
2571 help='human readable description')
2572 @click.option('--namespace',
2573 default
='kube-system',
2574 help='namespace to be used for its operation, defaults to `kube-system`')
2575 @click.option('--cni',
2577 help='list of CNI plugins, in JSON inline format, used in the cluster')
2578 #@click.option('--skip-init',
2580 # help='If set, K8s cluster is assumed to be ready for its use with OSM')
2581 #@click.option('--wait',
2583 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2585 def k8scluster_add(ctx
,
2594 """adds a K8s cluster to OSM
2596 NAME: name of the K8s cluster
2599 check_client_version(ctx
.obj
, ctx
.command
.name
)
2601 cluster
['name'] = name
2602 with
open(creds
, 'r') as cf
:
2603 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2604 cluster
['k8s_version'] = version
2605 cluster
['vim_account'] = vim
2606 cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2607 cluster
['description'] = description
2608 if namespace
: cluster
['namespace'] = namespace
2609 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2610 ctx
.obj
.k8scluster
.create(name
, cluster
)
2611 # except ClientException as e:
2616 @cli_osm.command(name
='k8scluster-update', short_help
='updates a K8s cluster')
2617 @click.argument('name')
2618 @click.option('--newname', help='New name for the K8s cluster')
2619 @click.option('--creds', help='credentials file, i.e. a valid `.kube/config` file')
2620 @click.option('--version', help='Kubernetes version')
2621 @click.option('--vim', help='VIM target, the VIM where the cluster resides')
2622 @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) ...]}"')
2623 @click.option('--description', help='human readable description')
2624 @click.option('--namespace', help='namespace to be used for its operation, defaults to `kube-system`')
2625 @click.option('--cni', help='list of CNI plugins, in JSON inline format, used in the cluster')
2627 def k8scluster_update(ctx
,
2637 """updates a K8s cluster
2639 NAME: name or ID of the K8s cluster
2642 check_client_version(ctx
.obj
, ctx
.command
.name
)
2644 if newname
: cluster
['name'] = newname
2646 with
open(creds
, 'r') as cf
:
2647 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2648 if version
: cluster
['k8s_version'] = version
2649 if vim
: cluster
['vim_account'] = vim
2650 if k8s_nets
: cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2651 if description
: cluster
['description'] = description
2652 if namespace
: cluster
['namespace'] = namespace
2653 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2654 ctx
.obj
.k8scluster
.update(name
, cluster
)
2655 # except ClientException as e:
2660 @cli_osm.command(name
='k8scluster-delete')
2661 @click.argument('name')
2662 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2663 #@click.option('--wait',
2665 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2667 def k8scluster_delete(ctx
, name
, force
):
2668 """deletes a K8s cluster
2670 NAME: name or ID of the K8s cluster to be deleted
2673 check_client_version(ctx
.obj
, ctx
.command
.name
)
2674 ctx
.obj
.k8scluster
.delete(name
, force
=force
)
2675 # except ClientException as e:
2680 @cli_osm.command(name
='k8scluster-list')
2681 @click.option('--filter', default
=None,
2682 help='restricts the list to the K8s clusters matching the filter')
2683 @click.option('--literal', is_flag
=True,
2684 help='print literally, no pretty table')
2686 def k8scluster_list(ctx
, filter, literal
):
2687 """list all K8s clusters"""
2689 check_client_version(ctx
.obj
, ctx
.command
.name
)
2690 resp
= ctx
.obj
.k8scluster
.list(filter)
2692 print(yaml
.safe_dump(resp
))
2694 table
= PrettyTable(['Name', 'Id', 'Version', 'VIM', 'K8s-nets', 'Operational State', 'Description'])
2695 for cluster
in resp
:
2696 table
.add_row([cluster
['name'], cluster
['_id'], cluster
['k8s_version'], cluster
['vim_account'],
2697 json
.dumps(cluster
['nets']), cluster
["_admin"]["operationalState"],
2698 trunc_text(cluster
.get('description',''),40)])
2701 # except ClientException as e:
2706 @cli_osm.command(name
='k8scluster-show')
2707 @click.argument('name')
2708 @click.option('--literal', is_flag
=True,
2709 help='print literally, no pretty table')
2711 def k8scluster_show(ctx
, name
, literal
):
2712 """shows the details of a K8s cluster
2714 NAME: name or ID of the K8s cluster
2717 resp
= ctx
.obj
.k8scluster
.get(name
)
2719 print(yaml
.safe_dump(resp
))
2721 table
= PrettyTable(['key', 'attribute'])
2722 for k
, v
in list(resp
.items()):
2723 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2726 # except ClientException as e:
2732 ###########################
2734 ###########################
2736 @cli_osm.command(name
='repo-add')
2737 @click.argument('name')
2738 @click.argument('uri')
2739 @click.option('--type',
2740 type=click
.Choice(['helm-chart', 'juju-bundle']),
2742 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2743 @click.option('--description',
2745 help='human readable description')
2746 #@click.option('--wait',
2748 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2755 """adds a repo to OSM
2757 NAME: name of the repo
2758 URI: URI of the repo
2761 check_client_version(ctx
.obj
, ctx
.command
.name
)
2766 repo
['description'] = description
2767 ctx
.obj
.repo
.create(name
, repo
)
2768 # except ClientException as e:
2773 @cli_osm.command(name
='repo-update')
2774 @click.argument('name')
2775 @click.option('--newname', help='New name for the repo')
2776 @click.option('--uri', help='URI of the repo')
2777 @click.option('--type', type=click
.Choice(['helm-chart', 'juju-bundle']),
2778 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2779 @click.option('--description', help='human readable description')
2780 #@click.option('--wait',
2782 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2784 def repo_update(ctx
,
2790 """updates a repo in OSM
2792 NAME: name of the repo
2795 check_client_version(ctx
.obj
, ctx
.command
.name
)
2797 if newname
: repo
['name'] = newname
2798 if uri
: repo
['uri'] = uri
2799 if type: repo
['type'] = type
2800 if description
: repo
['description'] = description
2801 ctx
.obj
.repo
.update(name
, repo
)
2802 # except ClientException as e:
2807 @cli_osm.command(name
='repo-delete')
2808 @click.argument('name')
2809 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2810 #@click.option('--wait',
2812 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2814 def repo_delete(ctx
, name
, force
):
2817 NAME: name or ID of the repo to be deleted
2820 check_client_version(ctx
.obj
, ctx
.command
.name
)
2821 ctx
.obj
.repo
.delete(name
, force
=force
)
2822 # except ClientException as e:
2827 @cli_osm.command(name
='repo-list')
2828 @click.option('--filter', default
=None,
2829 help='restricts the list to the repos matching the filter')
2830 @click.option('--literal', is_flag
=True,
2831 help='print literally, no pretty table')
2833 def repo_list(ctx
, filter, literal
):
2834 """list all repos"""
2836 check_client_version(ctx
.obj
, ctx
.command
.name
)
2837 resp
= ctx
.obj
.repo
.list(filter)
2839 print(yaml
.safe_dump(resp
))
2841 table
= PrettyTable(['Name', 'Id', 'Type', 'URI', 'Description'])
2843 #cluster['k8s-nets'] = json.dumps(yaml.safe_load(cluster['k8s-nets']))
2844 table
.add_row([repo
['name'], repo
['_id'], repo
['type'], repo
['url'], trunc_text(repo
.get('description',''),40)])
2847 # except ClientException as e:
2852 @cli_osm.command(name
='repo-show')
2853 @click.argument('name')
2854 @click.option('--literal', is_flag
=True,
2855 help='print literally, no pretty table')
2857 def repo_show(ctx
, name
, literal
):
2858 """shows the details of a repo
2860 NAME: name or ID of the repo
2863 resp
= ctx
.obj
.repo
.get(name
)
2865 print(yaml
.safe_dump(resp
))
2867 table
= PrettyTable(['key', 'attribute'])
2868 for k
, v
in list(resp
.items()):
2869 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2872 # except ClientException as e:
2878 ####################
2879 # Project mgmt operations
2880 ####################
2882 @cli_osm.command(name
='project-create', short_help
='creates a new project')
2883 @click.argument('name')
2884 #@click.option('--description',
2885 # default='no description',
2886 # help='human readable description')
2888 def project_create(ctx
, name
):
2889 """Creates a new project
2891 NAME: name of the project
2895 project
['name'] = name
2897 check_client_version(ctx
.obj
, ctx
.command
.name
)
2898 ctx
.obj
.project
.create(name
, project
)
2899 # except ClientException as e:
2904 @cli_osm.command(name
='project-delete', short_help
='deletes a project')
2905 @click.argument('name')
2906 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2908 def project_delete(ctx
, name
):
2909 """deletes a project
2911 NAME: name or ID of the project to be deleted
2915 check_client_version(ctx
.obj
, ctx
.command
.name
)
2916 ctx
.obj
.project
.delete(name
)
2917 # except ClientException as e:
2922 @cli_osm.command(name
='project-list', short_help
='list all projects')
2923 @click.option('--filter', default
=None,
2924 help='restricts the list to the projects matching the filter')
2926 def project_list(ctx
, filter):
2927 """list all projects"""
2930 check_client_version(ctx
.obj
, ctx
.command
.name
)
2931 resp
= ctx
.obj
.project
.list(filter)
2932 # except ClientException as e:
2935 table
= PrettyTable(['name', 'id'])
2937 table
.add_row([proj
['name'], proj
['_id']])
2942 @cli_osm.command(name
='project-show', short_help
='shows the details of a project')
2943 @click.argument('name')
2945 def project_show(ctx
, name
):
2946 """shows the details of a project
2948 NAME: name or ID of the project
2952 check_client_version(ctx
.obj
, ctx
.command
.name
)
2953 resp
= ctx
.obj
.project
.get(name
)
2954 # except ClientException as e:
2958 table
= PrettyTable(['key', 'attribute'])
2959 for k
, v
in resp
.items():
2960 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2965 @cli_osm.command(name
='project-update', short_help
='updates a project (only the name can be updated)')
2966 @click.argument('project')
2967 @click.option('--name',
2969 help='new name for the project')
2972 def project_update(ctx
, project
, name
):
2974 Update a project name
2977 :param project: id or name of the project to modify
2978 :param name: new name for the project
2982 project_changes
= {}
2983 project_changes
['name'] = name
2986 check_client_version(ctx
.obj
, ctx
.command
.name
)
2987 ctx
.obj
.project
.update(project
, project_changes
)
2988 # except ClientException as e:
2992 ####################
2993 # User mgmt operations
2994 ####################
2996 @cli_osm.command(name
='user-create', short_help
='creates a new user')
2997 @click.argument('username')
2998 @click.option('--password',
3001 confirmation_prompt
=True,
3002 help='user password')
3003 @click.option('--projects',
3004 # prompt="Comma separate list of projects",
3006 callback
=lambda ctx
, param
, value
: ''.join(value
).split(',') if all(len(x
)==1 for x
in value
) else value
,
3007 help='list of project ids that the user belongs to')
3008 @click.option('--project-role-mappings', 'project_role_mappings',
3009 default
=None, multiple
=True,
3010 help='creating user project/role(s) mapping')
3012 def user_create(ctx
, username
, password
, projects
, project_role_mappings
):
3013 """Creates a new user
3016 USERNAME: name of the user
3017 PASSWORD: password of the user
3018 PROJECTS: projects assigned to user (internal only)
3019 PROJECT_ROLE_MAPPING: roles in projects assigned to user (keystone)
3023 user
['username'] = username
3024 user
['password'] = password
3025 user
['projects'] = projects
3026 user
['project_role_mappings'] = project_role_mappings
3029 check_client_version(ctx
.obj
, ctx
.command
.name
)
3030 ctx
.obj
.user
.create(username
, user
)
3031 # except ClientException as e:
3036 @cli_osm.command(name
='user-update', short_help
='updates user information')
3037 @click.argument('username')
3038 @click.option('--password',
3041 # confirmation_prompt=True,
3042 help='user password')
3043 @click.option('--set-username', 'set_username',
3045 help='change username')
3046 @click.option('--set-project', 'set_project',
3047 default
=None, multiple
=True,
3048 help='create/replace the project,role(s) mapping for this project: \'project,role1,role2,...\'')
3049 @click.option('--remove-project', 'remove_project',
3050 default
=None, multiple
=True,
3051 help='removes project from user: \'project\'')
3052 @click.option('--add-project-role', 'add_project_role',
3053 default
=None, multiple
=True,
3054 help='adds project,role(s) mapping: \'project,role1,role2,...\'')
3055 @click.option('--remove-project-role', 'remove_project_role',
3056 default
=None, multiple
=True,
3057 help='removes project,role(s) mapping: \'project,role1,role2,...\'')
3059 def user_update(ctx
, username
, password
, set_username
, set_project
, remove_project
,
3060 add_project_role
, remove_project_role
):
3061 """Update a user information
3064 USERNAME: name of the user
3065 PASSWORD: new password
3066 SET_USERNAME: new username
3067 SET_PROJECT: creating mappings for project/role(s)
3068 REMOVE_PROJECT: deleting mappings for project/role(s)
3069 ADD_PROJECT_ROLE: adding mappings for project/role(s)
3070 REMOVE_PROJECT_ROLE: removing mappings for project/role(s)
3074 user
['password'] = password
3075 user
['username'] = set_username
3076 user
['set-project'] = set_project
3077 user
['remove-project'] = remove_project
3078 user
['add-project-role'] = add_project_role
3079 user
['remove-project-role'] = remove_project_role
3082 check_client_version(ctx
.obj
, ctx
.command
.name
)
3083 ctx
.obj
.user
.update(username
, user
)
3084 # except ClientException as e:
3089 @cli_osm.command(name
='user-delete', short_help
='deletes a user')
3090 @click.argument('name')
3091 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3093 def user_delete(ctx
, name
):
3097 NAME: name or ID of the user to be deleted
3101 check_client_version(ctx
.obj
, ctx
.command
.name
)
3102 ctx
.obj
.user
.delete(name
)
3103 # except ClientException as e:
3108 @cli_osm.command(name
='user-list', short_help
='list all users')
3109 @click.option('--filter', default
=None,
3110 help='restricts the list to the users matching the filter')
3112 def user_list(ctx
, filter):
3113 """list all users"""
3115 check_client_version(ctx
.obj
, ctx
.command
.name
)
3116 resp
= ctx
.obj
.user
.list(filter)
3117 # except ClientException as e:
3120 table
= PrettyTable(['name', 'id'])
3122 table
.add_row([user
['username'], user
['_id']])
3127 @cli_osm.command(name
='user-show', short_help
='shows the details of a user')
3128 @click.argument('name')
3130 def user_show(ctx
, name
):
3131 """shows the details of a user
3133 NAME: name or ID of the user
3137 check_client_version(ctx
.obj
, ctx
.command
.name
)
3138 resp
= ctx
.obj
.user
.get(name
)
3139 if 'password' in resp
:
3140 resp
['password']='********'
3141 # except ClientException as e:
3145 table
= PrettyTable(['key', 'attribute'])
3146 for k
, v
in resp
.items():
3147 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3152 ####################
3153 # Fault Management operations
3154 ####################
3156 @cli_osm.command(name
='ns-alarm-create')
3157 @click.argument('name')
3158 @click.option('--ns', prompt
=True, help='NS instance id or name')
3159 @click.option('--vnf', prompt
=True,
3160 help='VNF name (VNF member index as declared in the NSD)')
3161 @click.option('--vdu', prompt
=True,
3162 help='VDU name (VDU name as declared in the VNFD)')
3163 @click.option('--metric', prompt
=True,
3164 help='Name of the metric (e.g. cpu_utilization)')
3165 @click.option('--severity', default
='WARNING',
3166 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
3167 @click.option('--threshold_value', prompt
=True,
3168 help='threshold value that, when crossed, an alarm is triggered')
3169 @click.option('--threshold_operator', prompt
=True,
3170 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
3171 @click.option('--statistic', default
='AVERAGE',
3172 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
3174 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
3175 threshold_value
, threshold_operator
, statistic
):
3176 """creates a new alarm for a NS instance"""
3177 # TODO: Check how to validate threshold_value.
3178 # Should it be an integer (1-100), percentage, or decimal (0.01-1.00)?
3181 ns_instance
= ctx
.obj
.ns
.get(ns
)
3183 alarm
['alarm_name'] = name
3184 alarm
['ns_id'] = ns_instance
['_id']
3185 alarm
['correlation_id'] = ns_instance
['_id']
3186 alarm
['vnf_member_index'] = vnf
3187 alarm
['vdu_name'] = vdu
3188 alarm
['metric_name'] = metric
3189 alarm
['severity'] = severity
3190 alarm
['threshold_value'] = int(threshold_value
)
3191 alarm
['operation'] = threshold_operator
3192 alarm
['statistic'] = statistic
3193 check_client_version(ctx
.obj
, ctx
.command
.name
)
3194 ctx
.obj
.ns
.create_alarm(alarm
)
3195 # except ClientException as e:
3200 #@cli_osm.command(name='ns-alarm-delete')
3201 #@click.argument('name')
3202 #@click.pass_context
3203 #def ns_alarm_delete(ctx, name):
3204 # """deletes an alarm
3206 # NAME: name of the alarm to be deleted
3209 # check_client_version(ctx.obj, ctx.command.name)
3210 # ctx.obj.ns.delete_alarm(name)
3211 # except ClientException as e:
3216 ####################
3217 # Performance Management operations
3218 ####################
3220 @cli_osm.command(name
='ns-metric-export', short_help
='exports a metric to the internal OSM bus, which can be read by other apps')
3221 @click.option('--ns', prompt
=True, help='NS instance id or name')
3222 @click.option('--vnf', prompt
=True,
3223 help='VNF name (VNF member index as declared in the NSD)')
3224 @click.option('--vdu', prompt
=True,
3225 help='VDU name (VDU name as declared in the VNFD)')
3226 @click.option('--metric', prompt
=True,
3227 help='name of the metric (e.g. cpu_utilization)')
3228 #@click.option('--period', default='1w',
3229 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
3230 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
3232 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
3233 """exports a metric to the internal OSM bus, which can be read by other apps"""
3234 # TODO: Check how to validate interval.
3235 # Should it be an integer (seconds), or should a suffix (s,m,h,d,w) also be permitted?
3238 ns_instance
= ctx
.obj
.ns
.get(ns
)
3240 metric_data
['ns_id'] = ns_instance
['_id']
3241 metric_data
['correlation_id'] = ns_instance
['_id']
3242 metric_data
['vnf_member_index'] = vnf
3243 metric_data
['vdu_name'] = vdu
3244 metric_data
['metric_name'] = metric
3245 metric_data
['collection_unit'] = 'WEEK'
3246 metric_data
['collection_period'] = 1
3247 check_client_version(ctx
.obj
, ctx
.command
.name
)
3249 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
3253 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
3254 time
.sleep(int(interval
))
3256 # except ClientException as e:
3261 ####################
3263 ####################
3265 @cli_osm.command(name
='version')
3267 def get_version(ctx
):
3269 check_client_version(ctx
.obj
, "version")
3270 print ("Server version: {}".format(ctx
.obj
.get_version()))
3271 print ("Client version: {}".format(pkg_resources
.get_distribution("osmclient").version
))
3272 # except ClientException as e:
3276 @cli_osm.command(name
='upload-package', short_help
='uploads a VNF package or NS package')
3277 @click.argument('filename')
3279 def upload_package(ctx
, filename
):
3280 """uploads a VNF package or NS package
3282 FILENAME: VNF or NS package file (tar.gz)
3286 ctx
.obj
.package
.upload(filename
)
3287 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
3288 if fullclassname
!= 'osmclient.sol005.client.Client':
3289 ctx
.obj
.package
.wait_for_upload(filename
)
3290 # except ClientException as e:
3295 #@cli_osm.command(name='ns-scaling-show')
3296 #@click.argument('ns_name')
3297 #@click.pass_context
3298 #def show_ns_scaling(ctx, ns_name):
3299 # """shows the status of a NS scaling operation
3301 # NS_NAME: name of the NS instance being scaled
3304 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3305 # resp = ctx.obj.ns.list()
3306 # except ClientException as e:
3310 # table = PrettyTable(
3313 # 'operational status',
3318 # if ns_name == ns['name']:
3319 # nsopdata = ctx.obj.ns.get_opdata(ns['id'])
3320 # scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
3321 # for record in scaling_records:
3322 # if 'instance' in record:
3323 # instances = record['instance']
3324 # for inst in instances:
3326 # [record['scaling-group-name-ref'],
3327 # inst['instance-id'],
3328 # inst['op-status'],
3329 # time.strftime('%Y-%m-%d %H:%M:%S',
3331 # inst['create-time'])),
3337 #@cli_osm.command(name='ns-scale')
3338 #@click.argument('ns_name')
3339 #@click.option('--ns_scale_group', prompt=True)
3340 #@click.option('--index', prompt=True)
3341 #@click.option('--wait',
3345 # help='do not return the control immediately, but keep it \
3346 # until the operation is completed, or timeout')
3347 #@click.pass_context
3348 #def ns_scale(ctx, ns_name, ns_scale_group, index, wait):
3351 # NS_NAME: name of the NS instance to be scaled
3354 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3355 # ctx.obj.ns.scale(ns_name, ns_scale_group, index, wait=wait)
3356 # except ClientException as e:
3361 #@cli_osm.command(name='config-agent-list')
3362 #@click.pass_context
3363 #def config_agent_list(ctx):
3364 # """list config agents"""
3366 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3367 # except ClientException as e:
3370 # table = PrettyTable(['name', 'account-type', 'details'])
3371 # for account in ctx.obj.vca.list():
3374 # account['account-type'],
3380 #@cli_osm.command(name='config-agent-delete')
3381 #@click.argument('name')
3382 #@click.pass_context
3383 #def config_agent_delete(ctx, name):
3384 # """deletes a config agent
3386 # NAME: name of the config agent to be deleted
3389 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3390 # ctx.obj.vca.delete(name)
3391 # except ClientException as e:
3396 #@cli_osm.command(name='config-agent-add')
3397 #@click.option('--name',
3399 #@click.option('--account_type',
3401 #@click.option('--server',
3403 #@click.option('--user',
3405 #@click.option('--secret',
3408 # confirmation_prompt=True)
3409 #@click.pass_context
3410 #def config_agent_add(ctx, name, account_type, server, user, secret):
3411 # """adds a config agent"""
3413 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3414 # ctx.obj.vca.create(name, account_type, server, user, secret)
3415 # except ClientException as e:
3420 #@cli_osm.command(name='ro-dump')
3421 #@click.pass_context
3423 # """shows RO agent information"""
3424 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3425 # resp = ctx.obj.vim.get_resource_orchestrator()
3426 # table = PrettyTable(['key', 'attribute'])
3427 # for k, v in list(resp.items()):
3428 # table.add_row([k, json.dumps(v, indent=2)])
3433 #@cli_osm.command(name='vcs-list')
3434 #@click.pass_context
3436 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3437 # resp = ctx.obj.utils.get_vcs_info()
3438 # table = PrettyTable(['component name', 'state'])
3439 # for component in resp:
3440 # table.add_row([component['component_name'], component['state']])
3445 @cli_osm.command(name
='ns-action', short_help
='executes an action/primitive over a NS instance')
3446 @click.argument('ns_name')
3447 @click.option('--vnf_name', default
=None, help='member-vnf-index if the target is a vnf instead of a ns)')
3448 @click.option('--kdu_name', default
=None, help='kdu-name if the target is a kdu)')
3449 @click.option('--vdu_id', default
=None, help='vdu-id if the target is a vdu')
3450 @click.option('--vdu_count', default
=None, help='number of vdu instance of this vdu_id')
3451 @click.option('--action_name', prompt
=True, help='action name')
3452 @click.option('--params', default
=None, help='action params in YAML/JSON inline string')
3453 @click.option('--params_file', default
=None, help='YAML/JSON file with action params')
3454 @click.option('--wait',
3458 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3470 """executes an action/primitive over a NS instance
3472 NS_NAME: name or ID of the NS instance
3476 check_client_version(ctx
.obj
, ctx
.command
.name
)
3479 op_data
['member_vnf_index'] = vnf_name
3481 op_data
['kdu_name'] = kdu_name
3483 op_data
['vdu_id'] = vdu_id
3485 op_data
['vdu_count_index'] = vdu_count
3486 op_data
['primitive'] = action_name
3488 with
open(params_file
, 'r') as pf
:
3491 op_data
['primitive_params'] = yaml
.safe_load(params
)
3493 op_data
['primitive_params'] = {}
3494 print(ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
, wait
=wait
))
3496 # except ClientException as e:
3501 @cli_osm.command(name
='vnf-scale', short_help
='executes a VNF scale (adding/removing VDUs)')
3502 @click.argument('ns_name')
3503 @click.argument('vnf_name')
3504 @click.option('--scaling-group', prompt
=True, help="scaling-group-descriptor name to use")
3505 @click.option('--scale-in', default
=False, is_flag
=True, help="performs a scale in operation")
3506 @click.option('--scale-out', default
=False, is_flag
=True, help="performs a scale out operation (by default)")
3515 Executes a VNF scale (adding/removing VDUs)
3518 NS_NAME: name or ID of the NS instance.
3519 VNF_NAME: member-vnf-index in the NS to be scaled.
3523 check_client_version(ctx
.obj
, ctx
.command
.name
)
3524 if not scale_in
and not scale_out
:
3526 ctx
.obj
.ns
.scale_vnf(ns_name
, vnf_name
, scaling_group
, scale_in
, scale_out
)
3527 # except ClientException as e:
3532 ##############################
3533 # Role Management Operations #
3534 ##############################
3536 @cli_osm.command(name
='role-create', short_help
='creates a new role')
3537 @click.argument('name')
3538 @click.option('--permissions',
3540 help='role permissions using a dictionary')
3542 def role_create(ctx
, name
, permissions
):
3547 NAME: Name or ID of the role.
3548 DEFINITION: Definition of grant/denial of access to resources.
3552 check_client_version(ctx
.obj
, ctx
.command
.name
)
3553 ctx
.obj
.role
.create(name
, permissions
)
3554 # except ClientException as e:
3559 @cli_osm.command(name
='role-update', short_help
='updates a role')
3560 @click.argument('name')
3561 @click.option('--set-name',
3563 help='change name of rle')
3564 # @click.option('--permissions',
3566 # help='provide a yaml format dictionary with incremental changes. Values can be bool or None to delete')
3567 @click.option('--add',
3569 help='yaml format dictionary with permission: True/False to access grant/denial')
3570 @click.option('--remove',
3572 help='yaml format list to remove a permission')
3574 def role_update(ctx
, name
, set_name
, add
, remove
):
3579 NAME: Name or ID of the role.
3580 DEFINITION: Definition overwrites the old definition.
3581 ADD: Grant/denial of access to resource to add.
3582 REMOVE: Grant/denial of access to resource to remove.
3586 check_client_version(ctx
.obj
, ctx
.command
.name
)
3587 ctx
.obj
.role
.update(name
, set_name
, None, add
, remove
)
3588 # except ClientException as e:
3593 @cli_osm.command(name
='role-delete', short_help
='deletes a role')
3594 @click.argument('name')
3595 # @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3597 def role_delete(ctx
, name
):
3602 NAME: Name or ID of the role.
3606 check_client_version(ctx
.obj
, ctx
.command
.name
)
3607 ctx
.obj
.role
.delete(name
)
3608 # except ClientException as e:
3613 @cli_osm.command(name
='role-list', short_help
='list all roles')
3614 @click.option('--filter', default
=None,
3615 help='restricts the list to the projects matching the filter')
3617 def role_list(ctx
, filter):
3623 check_client_version(ctx
.obj
, ctx
.command
.name
)
3624 resp
= ctx
.obj
.role
.list(filter)
3625 # except ClientException as e:
3628 table
= PrettyTable(['name', 'id'])
3630 table
.add_row([role
['name'], role
['_id']])
3635 @cli_osm.command(name
='role-show', short_help
='show specific role')
3636 @click.argument('name')
3638 def role_show(ctx
, name
):
3640 Shows the details of a role.
3643 NAME: Name or ID of the role.
3647 check_client_version(ctx
.obj
, ctx
.command
.name
)
3648 resp
= ctx
.obj
.role
.get(name
)
3649 # except ClientException as e:
3653 table
= PrettyTable(['key', 'attribute'])
3654 for k
, v
in resp
.items():
3655 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3660 @cli_osm.command(name
='package-create',
3661 short_help
='Create a package descriptor')
3662 @click.argument('package-type')
3663 @click.argument('package-name')
3664 @click.option('--base-directory',
3666 help=('(NS/VNF/NST) Set the location for package creation. Default: "."'))
3667 @click.option('--image',
3668 default
="image-name",
3669 help='(VNF) Set the name of the vdu image. Default "image-name"')
3670 @click.option('--vdus',
3672 help='(VNF) Set the number of vdus in a VNF. Default 1')
3673 @click.option('--vcpu',
3675 help='(VNF) Set the number of virtual CPUs in a vdu. Default 1')
3676 @click.option('--memory',
3678 help='(VNF) Set the memory size (MB) of the vdu. Default 1024')
3679 @click.option('--storage',
3681 help='(VNF) Set the disk size (GB) of the vdu. Default 10')
3682 @click.option('--interfaces',
3684 help='(VNF) Set the number of additional interfaces apart from the management interface. Default 0')
3685 @click.option('--vendor',
3687 help='(NS/VNF) Set the descriptor vendor. Default "OSM"')
3688 @click.option('--override',
3691 help='(NS/VNF/NST) Flag for overriding the package if exists.')
3692 @click.option('--detailed',
3695 help='(NS/VNF/NST) Flag for generating descriptor .yaml with all possible commented options')
3696 @click.option('--netslice-subnets',
3698 help='(NST) Number of netslice subnets. Default 1')
3699 @click.option('--netslice-vlds',
3701 help='(NST) Number of netslice vlds. Default 1')
3703 def package_create(ctx
,
3719 Creates an OSM NS, VNF, NST package
3722 PACKAGE_TYPE: Package to be created: NS, VNF or NST.
3723 PACKAGE_NAME: Name of the package to create the folder with the content.
3727 check_client_version(ctx
.obj
, ctx
.command
.name
)
3728 print("Creating the {} structure: {}/{}".format(package_type
.upper(), base_directory
, package_name
))
3729 resp
= ctx
.obj
.package_tool
.create(package_type
,
3738 interfaces
=interfaces
,
3741 netslice_subnets
=netslice_subnets
,
3742 netslice_vlds
=netslice_vlds
)
3744 # except ClientException as inst:
3745 # print("ERROR: {}".format(inst))
3748 @cli_osm.command(name
='package-validate',
3749 short_help
='Validate a package descriptor')
3750 @click.argument('base-directory',
3754 def package_validate(ctx
,
3757 Validate descriptors given a base directory.
3760 BASE_DIRECTORY: Stub folder for NS, VNF or NST package.
3763 check_client_version(ctx
.obj
, ctx
.command
.name
)
3764 results
= ctx
.obj
.package_tool
.validate(base_directory
)
3765 table
= PrettyTable()
3766 table
.field_names
= ["TYPE", "PATH", "VALID", "ERROR"]
3767 # Print the dictionary generated by the validation function
3768 for result
in results
:
3769 table
.add_row([result
["type"], result
["path"], result
["valid"], result
["error"]])
3770 table
.sortby
= "VALID"
3771 table
.align
["PATH"] = "l"
3772 table
.align
["TYPE"] = "l"
3773 table
.align
["ERROR"] = "l"
3775 # except ClientException as inst:
3776 # print("ERROR: {}".format(inst))
3779 @cli_osm.command(name
='package-build',
3780 short_help
='Build the tar.gz of the package')
3781 @click.argument('package-folder')
3782 @click.option('--skip-validation',
3785 help='skip package validation')
3787 def package_build(ctx
,
3791 Build the package NS, VNF given the package_folder.
3794 PACKAGE_FOLDER: Folder of the NS, VNF or NST to be packaged
3797 check_client_version(ctx
.obj
, ctx
.command
.name
)
3798 results
= ctx
.obj
.package_tool
.build(package_folder
, skip_validation
)
3800 # except ClientException as inst:
3801 # print("ERROR: {}".format(inst))
3809 except pycurl
.error
as exc
:
3811 print('Maybe "--hostname" option or OSM_HOSTNAME environment variable needs to be specified')
3812 except ClientException
as exc
:
3813 print("ERROR: {}".format(exc
))
3814 except (FileNotFoundError
, PermissionError
) as exc
:
3815 print("Cannot open file: {}".format(exc
))
3816 except yaml
.YAMLError
as exc
:
3817 print("Invalid YAML format: {}".format(exc
))
3819 # TODO capture other controlled exceptions here
3820 # TODO remove the ClientException captures from all places, unless they do something different
3823 if __name__
== '__main__':