0523207fa4307283485c3edd5d31c95ff9838c9e
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
, NotFound
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('--all-projects',
103 help='include all projects')
104 @click.option('--public/--no-public', default
=None,
105 help='flag for public items (packages, instances, VIM accounts, etc.)')
106 @click.option('--project-domain-name', 'project_domain_name',
108 envvar
='OSM_PROJECT_DOMAIN_NAME',
109 help='project domain name for keystone authentication (default to None). ' +
110 'Also can set OSM_PROJECT_DOMAIN_NAME in environment')
111 @click.option('--user-domain-name', 'user_domain_name',
113 envvar
='OSM_USER_DOMAIN_NAME',
114 help='user domain name for keystone authentication (default to None). ' +
115 'Also can set OSM_USER_DOMAIN_NAME in environment')
116 #@click.option('--so-port',
118 # envvar='OSM_SO_PORT',
119 # help='hostname of server. ' +
120 # 'Also can set OSM_SO_PORT in environment')
121 #@click.option('--so-project',
123 # envvar='OSM_SO_PROJECT',
124 # help='Project Name in SO. ' +
125 # 'Also can set OSM_SO_PROJECT in environment')
126 #@click.option('--ro-hostname',
128 # envvar='OSM_RO_HOSTNAME',
129 # help='hostname of RO server. ' +
130 # 'Also can set OSM_RO_HOSTNAME in environment')
131 #@click.option('--ro-port',
133 # envvar='OSM_RO_PORT',
134 # help='hostname of RO server. ' +
135 # 'Also can set OSM_RO_PORT in environment')
137 def cli_osm(ctx
, **kwargs
):
139 hostname
= kwargs
.pop("hostname", None)
142 "either hostname option or OSM_HOSTNAME " +
143 "environment variable needs to be specified"))
146 kwargs
= {k
: v
for k
, v
in kwargs
.items() if v
is not None}
147 # if so_port is not None:
148 # kwargs['so_port']=so_port
149 # if so_project is not None:
150 # kwargs['so_project']=so_project
151 # if ro_hostname is not None:
152 # kwargs['ro_host']=ro_hostname
153 # if ro_port is not None:
154 # kwargs['ro_port']=ro_port
155 sol005
= os
.getenv('OSM_SOL005', True)
156 # if user is not None:
157 # kwargs['user']=user
158 # if password is not None:
159 # kwargs['password']=password
160 # if project is not None:
161 # kwargs['project']=project
163 # kwargs['all_projects']=all_projects
164 # if public is not None:
165 # kwargs['public']=public
166 ctx
.obj
= client
.Client(host
=hostname
, sol005
=sol005
, **kwargs
)
167 logger
= logging
.getLogger('osmclient')
174 @cli_osm.command(name
='ns-list', short_help
='list all NS instances')
175 @click.option('--filter', default
=None,
176 help='restricts the list to the NS instances matching the filter.')
177 @click.option('--long', is_flag
=True,
178 help='get more details of the NS (project, vim, deployment status, configuration status.')
180 def ns_list(ctx
, filter, long):
181 """list all NS instances
185 --filter filterExpr Restricts the list to the NS instances matching the filter
188 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
189 concatenated using the "&" character:
192 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
193 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
194 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
196 value := scalar value
200 * zero or more occurrences
201 ? zero or one occurrence
202 [] grouping of expressions to be used with ? and *
203 "" quotation marks for marking string constants
207 "AttrName" is the name of one attribute in the data type that defines the representation
208 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
209 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
210 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
211 entries, it means that the operator "op" is applied to the attribute addressed by the last
212 <attrName> entry included in the concatenation. All simple filter expressions are combined
213 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
214 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
215 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
216 prefix". If an attribute referenced in an expression is an array, an object that contains a
217 corresponding array shall be considered to match the expression if any of the elements in the
218 array matches all expressions that have the same attribute prefix.
222 --filter admin-status=ENABLED
223 --filter nsd-ref=<NSD_NAME>
224 --filter nsd.vendor=<VENDOR>
225 --filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME>
226 --filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME>
228 def summarize_deployment_status(status_dict
):
235 net_list
= status_dict
.get('nets',[])
238 if net
['status'] not in status_nets
:
239 status_nets
[net
['status']] = 1
241 status_nets
[net
['status']] +=1
243 for k
,v
in status_nets
.items():
244 message
+= "{}:{},".format(k
,v
)
245 message
+= "TOTAL:{}".format(n_nets
)
246 summary
+= "{}".format(message
)
251 vnf_list
= status_dict
['vnfs']
253 member_vnf_index
= vnf
['member_vnf_index']
254 if member_vnf_index
not in status_vnfs
:
255 status_vnfs
[member_vnf_index
] = {}
256 for vm
in vnf
['vms']:
258 if vm
['status'] not in status_vms
:
259 status_vms
[vm
['status']] = 1
261 status_vms
[vm
['status']] +=1
262 if vm
['status'] not in status_vnfs
[member_vnf_index
]:
263 status_vnfs
[member_vnf_index
][vm
['status']] = 1
265 status_vnfs
[member_vnf_index
][vm
['status']] += 1
267 for k
,v
in status_vms
.items():
268 message
+= "{}:{},".format(k
,v
)
269 message
+= "TOTAL:{}".format(n_vms
)
270 summary
+= "\n{}".format(message
)
272 for k
,v
in status_vnfs
.items():
274 message
= "\n {} VMs: ".format(k
)
275 for k2
,v2
in v
.items():
276 message
+= "{}:{},".format(k2
,v2
)
278 message
+= "TOTAL:{}".format(total
)
282 def summarize_config_status(ee_list
):
290 if ee
['elementType'] not in status_ee
:
291 status_ee
[ee
['elementType']] = {}
292 status_ee
[ee
['elementType']][ee
['status']] = 1
294 if ee
['status'] in status_ee
[ee
['elementType']]:
295 status_ee
[ee
['elementType']][ee
['status']] += 1
297 status_ee
[ee
['elementType']][ee
['status']] = 1
298 for elementType
in ["KDU", "VDU", "PDU", "VNF", "NS"]:
299 if elementType
in status_ee
:
302 for k
,v
in status_ee
[elementType
].items():
303 message
+= "{}:{},".format(k
,v
)
305 message
+= "TOTAL:{}\n".format(total
)
306 summary
+= "{}: {}".format(elementType
, message
)
307 summary
+= "TOTAL Exec. Env.: {}".format(n_ee
)
312 check_client_version(ctx
.obj
, '--filter')
313 resp
= ctx
.obj
.ns
.list(filter)
315 resp
= ctx
.obj
.ns
.list()
327 'configuration status'])
328 project_list
= ctx
.obj
.project
.list()
329 vim_list
= ctx
.obj
.vim
.list()
339 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
340 if fullclassname
== 'osmclient.sol005.client.Client':
342 logger
.debug('NS info: {}'.format(nsr
))
343 nsr_name
= nsr
['name']
345 date
= datetime
.fromtimestamp(nsr
['create-time']).strftime("%Y-%m-%dT%H:%M:%S")
346 ns_state
= nsr
.get('nsState', nsr
['_admin']['nsState'])
348 deployment_status
= summarize_deployment_status(nsr
.get('deploymentStatus'))
349 config_status
= summarize_config_status(nsr
.get('configurationStatus'))
350 project_id
= nsr
.get('_admin').get('projects_read')[0]
352 for p
in project_list
:
353 if p
['_id'] == project_id
:
354 project_name
= p
['name']
356 #project = '{} ({})'.format(project_name, project_id)
357 project
= project_name
358 vim_id
= nsr
.get('datacenter')
361 if v
['uuid'] == vim_id
:
364 #vim = '{} ({})'.format(vim_name, vim_id)
366 if 'currentOperation' in nsr
:
367 current_operation
= "{} ({})".format(nsr
['currentOperation'],nsr
['currentOperationID'])
369 current_operation
= "{} ({})".format(nsr
['_admin'].get('current-operation','-'), nsr
['_admin']['nslcmop'])
370 error_details
= "N/A"
371 if ns_state
== "BROKEN" or ns_state
== "DEGRADED" or nsr
.get('errorDescription'):
372 error_details
= "{}\nDetail: {}".format(nsr
['errorDescription'], nsr
['errorDetail'])
374 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
375 nsr
= nsopdata
['nsr:nsr']
376 nsr_name
= nsr
['name-ref']
377 nsr_id
= nsr
['ns-instance-config-ref']
380 deployment_status
= nsr
['operational-status'] if 'operational-status' in nsr
else 'Not found'
381 ns_state
= deployment_status
382 config_status
= nsr
.get('config-status', 'Not found')
383 current_operation
= "Unknown"
384 error_details
= nsr
.get('detailed-status', 'Not found')
385 if config_status
== "config_not_needed":
386 config_status
= "configured (no charms)"
395 wrap_text(text
=error_details
,width
=40),
407 wrap_text(text
=error_details
,width
=40)])
410 print('To get the history of all operations over a NS, run "osm ns-op-list NS_ID"')
411 print('For more details on the current operation, run "osm ns-op-show OPERATION_ID"')
413 def nsd_list(ctx
, filter, long):
416 check_client_version(ctx
.obj
, '--filter')
417 resp
= ctx
.obj
.nsd
.list(filter)
419 resp
= ctx
.obj
.nsd
.list()
420 # print(yaml.safe_dump(resp))
421 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
422 if fullclassname
== 'osmclient.sol005.client.Client':
424 table
= PrettyTable(['nsd name', 'id', 'onboarding state', 'operational state',
425 'usage state', 'date', 'last update'])
427 table
= PrettyTable(['nsd name', 'id'])
429 name
= nsd
.get('name','-')
431 onb_state
= nsd
['_admin'].get('onboardingState','-')
432 op_state
= nsd
['_admin'].get('operationalState','-')
433 usage_state
= nsd
['_admin'].get('usageState','-')
434 date
= datetime
.fromtimestamp(nsd
['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S")
435 last_update
= datetime
.fromtimestamp(nsd
['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S")
436 table
.add_row([name
, nsd
['_id'], onb_state
, op_state
, usage_state
, date
, last_update
])
438 table
.add_row([name
, nsd
['_id']])
440 table
= PrettyTable(['nsd name', 'id'])
442 table
.add_row([nsd
['name'], nsd
['id']])
447 @cli_osm.command(name
='nsd-list', short_help
='list all NS packages')
448 @click.option('--filter', default
=None,
449 help='restricts the list to the NSD/NSpkg matching the filter')
450 @click.option('--long', is_flag
=True, help='get more details')
452 def nsd_list1(ctx
, filter, long):
453 """list all NSD/NS pkg in the system"""
455 nsd_list(ctx
, filter, long)
458 @cli_osm.command(name
='nspkg-list', short_help
='list all NS packages')
459 @click.option('--filter', default
=None,
460 help='restricts the list to the NSD/NSpkg matching the filter')
461 @click.option('--long', is_flag
=True, help='get more details')
463 def nsd_list2(ctx
, filter, long):
464 """list all NS packages"""
466 nsd_list(ctx
, filter, long)
469 def pkg_repo_list(ctx
, pkgtype
, filter, repo
, long):
470 resp
= ctx
.obj
.osmrepo
.pkg_list(pkgtype
, filter, repo
)
472 table
= PrettyTable(['nfpkg name', 'vendor', 'version', 'latest', 'description', 'repository'])
474 table
= PrettyTable(['nfpkg name', 'repository'])
476 name
= vnfd
.get('name', '-')
477 repository
= vnfd
.get('repository')
479 vendor
= vnfd
.get('vendor')
480 version
= vnfd
.get('version')
481 description
= vnfd
.get('description')
482 latest
= vnfd
.get('latest')
483 table
.add_row([name
, vendor
, version
, latest
, description
, repository
])
485 table
.add_row([name
, repository
])
489 def vnfd_list(ctx
, nf_type
, filter, long):
492 check_client_version(ctx
.obj
, '--nf_type')
494 check_client_version(ctx
.obj
, '--filter')
497 nf_filter
= "_admin.type=vnfd"
498 elif nf_type
== "pnf":
499 nf_filter
= "_admin.type=pnfd"
500 elif nf_type
== "hnf":
501 nf_filter
= "_admin.type=hnfd"
503 raise ClientException('wrong value for "--nf_type" option, allowed values: vnf, pnf, hnf')
505 filter = '{}&{}'.format(nf_filter
, filter)
509 resp
= ctx
.obj
.vnfd
.list(filter)
511 resp
= ctx
.obj
.vnfd
.list()
512 # print(yaml.safe_dump(resp))
513 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
514 if fullclassname
== 'osmclient.sol005.client.Client':
516 table
= PrettyTable(['nfpkg name', 'id', 'vendor', 'version', 'onboarding state', 'operational state',
517 'usage state', 'date', 'last update'])
519 table
= PrettyTable(['nfpkg name', 'id'])
521 name
= vnfd
['name'] if 'name' in vnfd
else '-'
523 onb_state
= vnfd
['_admin'].get('onboardingState','-')
524 op_state
= vnfd
['_admin'].get('operationalState','-')
525 vendor
= vnfd
.get('vendor')
526 version
= vnfd
.get('version')
527 usage_state
= vnfd
['_admin'].get('usageState','-')
528 date
= datetime
.fromtimestamp(vnfd
['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S")
529 last_update
= datetime
.fromtimestamp(vnfd
['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S")
530 table
.add_row([name
, vnfd
['_id'], vendor
, version
, onb_state
, op_state
, usage_state
, date
, last_update
])
532 table
.add_row([name
, vnfd
['_id']])
534 table
= PrettyTable(['nfpkg name', 'id'])
536 table
.add_row([vnfd
['name'], vnfd
['id']])
541 @cli_osm.command(name
='vnfd-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
542 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
543 @click.option('--filter', default
=None,
544 help='restricts the list to the NF pkg matching the filter')
545 @click.option('--long', is_flag
=True, help='get more details')
547 def vnfd_list1(ctx
, nf_type
, filter, long):
548 """list all xNF packages (VNF, HNF, PNF)"""
550 vnfd_list(ctx
, nf_type
, filter, long)
553 @cli_osm.command(name
='vnfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
554 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
555 @click.option('--filter', default
=None,
556 help='restricts the list to the NFpkg matching the filter')
557 @click.option('--long', is_flag
=True, help='get more details')
559 def vnfd_list2(ctx
, nf_type
, filter, long):
560 """list all xNF packages (VNF, HNF, PNF)"""
562 vnfd_list(ctx
, nf_type
, filter, long)
564 @cli_osm.command(name
='vnfpkg-repo-list', short_help
='list all xNF from OSM repositories')
565 @click.option('--filter', default
=None,
566 help='restricts the list to the NFpkg matching the filter')
567 @click.option('--repo', default
=None,
568 help='restricts the list to a particular OSM repository')
569 @click.option('--long', is_flag
=True, help='get more details')
571 def vnfd_list3(ctx
, filter, repo
, long):
572 """list xNF packages from OSM repositories"""
574 pkg_repo_list(ctx
, pkgtype
, filter, repo
, long)
576 @cli_osm.command(name
='nfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
577 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
578 @click.option('--filter', default
=None,
579 help='restricts the list to the NFpkg matching the filter')
580 @click.option('--long', is_flag
=True, help='get more details')
582 def nfpkg_list(ctx
, nf_type
, filter, long):
583 """list all xNF packages (VNF, HNF, PNF)"""
586 check_client_version(ctx
.obj
, ctx
.command
.name
)
587 vnfd_list(ctx
, nf_type
, filter, long)
588 # except ClientException as e:
592 @cli_osm.command(name
='nfpkg-repo-list', short_help
='list all xNF from OSM repositories')
593 @click.option('--filter', default
=None,
594 help='restricts the list to the NFpkg matching the filter')
595 @click.option('--repo', default
=None,
596 help='restricts the list to a particular OSM repository')
597 @click.option('--long', is_flag
=True, help='get more details')
599 def vnfd_list4(ctx
, filter, repo
, long):
600 """list xNF packages from OSM repositories"""
602 pkg_repo_list(ctx
, pkgtype
, filter, repo
, long)
604 def vnf_list(ctx
, ns
, filter, long):
608 check_client_version(ctx
.obj
, '--ns')
610 check_client_version(ctx
.obj
, '--filter')
611 resp
= ctx
.obj
.vnf
.list(ns
, filter)
613 resp
= ctx
.obj
.vnf
.list()
614 # except ClientException as e:
617 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
618 if fullclassname
== 'osmclient.sol005.client.Client':
619 field_names
= ['vnf id', 'name', 'ns id', 'vnf member index',
620 'vnfd name', 'vim account id', 'ip address']
622 field_names
= ['vnf id', 'name', 'ns id', 'vnf member index',
623 'vnfd name', 'vim account id', 'ip address',
624 'date', 'last update']
625 table
= PrettyTable(field_names
)
627 name
= vnfr
['name'] if 'name' in vnfr
else '-'
628 new_row
= [vnfr
['_id'], name
, vnfr
['nsr-id-ref'],
629 vnfr
['member-vnf-index-ref'], vnfr
['vnfd-ref'],
630 vnfr
['vim-account-id'], vnfr
['ip-address']]
632 date
= datetime
.fromtimestamp(vnfr
['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S")
633 last_update
= datetime
.fromtimestamp(vnfr
['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S")
634 new_row
.extend([date
, last_update
])
635 table
.add_row(new_row
)
640 'operational status',
643 if 'mgmt-interface' not in vnfr
:
644 vnfr
['mgmt-interface'] = {}
645 vnfr
['mgmt-interface']['ip-address'] = None
649 vnfr
['operational-status'],
650 vnfr
['config-status']])
655 @cli_osm.command(name
='vnf-list', short_help
='list all NF instances')
656 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
657 @click.option('--filter', default
=None,
658 help='restricts the list to the NF instances matching the filter.')
659 @click.option('--long', is_flag
=True, help='get more details')
661 def vnf_list1(ctx
, ns
, filter, long):
662 """list all NF instances"""
664 vnf_list(ctx
, ns
, filter, long)
666 @cli_osm.command(name
='nsd-repo-list', short_help
='list all NS from OSM repositories')
667 @click.option('--filter', default
=None,
668 help='restricts the list to the NS matching the filter')
669 @click.option('--repo', default
=None,
670 help='restricts the list to a particular OSM repository')
671 @click.option('--long', is_flag
=True, help='get more details')
673 def nsd_list3(ctx
, filter, repo
, long):
674 """list xNF packages from OSM repositories"""
676 pkg_repo_list(ctx
, pkgtype
, filter, repo
, long)
678 @cli_osm.command(name
='nspkg-repo-list', short_help
='list all NS from OSM repositories')
679 @click.option('--filter', default
=None,
680 help='restricts the list to the NS matching the filter')
681 @click.option('--repo', default
=None,
682 help='restricts the list to a particular OSM repository')
683 @click.option('--long', is_flag
=True, help='get more details')
685 def nspkg_list(ctx
, filter, repo
, long):
686 """list xNF packages from OSM repositories"""
688 pkg_repo_list(ctx
, pkgtype
, filter, repo
, long)
690 @cli_osm.command(name
='nf-list', short_help
='list all NF instances')
691 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
692 @click.option('--filter', default
=None,
693 help='restricts the list to the NF instances matching the filter.')
694 @click.option('--long', is_flag
=True, help='get more details')
696 def nf_list(ctx
, ns
, filter, long):
697 """list all NF instances
701 --ns TEXT NS instance id or name to restrict the VNF list
702 --filter filterExpr Restricts the list to the VNF instances matching the filter
705 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
706 concatenated using the "&" character:
709 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
710 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
711 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
713 value := scalar value
717 * zero or more occurrences
718 ? zero or one occurrence
719 [] grouping of expressions to be used with ? and *
720 "" quotation marks for marking string constants
724 "AttrName" is the name of one attribute in the data type that defines the representation
725 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
726 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
727 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
728 entries, it means that the operator "op" is applied to the attribute addressed by the last
729 <attrName> entry included in the concatenation. All simple filter expressions are combined
730 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
731 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
732 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
733 prefix". If an attribute referenced in an expression is an array, an object that contains a
734 corresponding array shall be considered to match the expression if any of the elements in the
735 array matches all expressions that have the same attribute prefix.
739 --filter vim-account-id=<VIM_ACCOUNT_ID>
740 --filter vnfd-ref=<VNFD_NAME>
741 --filter vdur.ip-address=<IP_ADDRESS>
742 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
745 vnf_list(ctx
, ns
, filter, long)
748 @cli_osm.command(name
='ns-op-list', short_help
='shows the history of operations over a NS instance')
749 @click.argument('name')
750 @click.option('--long', is_flag
=True,
751 help='get more details of the NS operation (date, ).')
753 def ns_op_list(ctx
, name
, long):
754 """shows the history of operations over a NS instance
756 NAME: name or ID of the NS instance
758 def formatParams(params
):
759 if params
['lcmOperationType']=='instantiate':
760 params
.pop('nsDescription')
764 elif params
['lcmOperationType']=='action':
765 params
.pop('primitive')
766 params
.pop('lcmOperationType')
767 params
.pop('nsInstanceId')
772 check_client_version(ctx
.obj
, ctx
.command
.name
)
773 resp
= ctx
.obj
.ns
.list_op(name
)
774 # except ClientException as e:
779 table
= PrettyTable(['id', 'operation', 'action_name', 'operation_params', 'status', 'date', 'last update', 'detail'])
781 table
= PrettyTable(['id', 'operation', 'action_name', 'status', 'date', 'detail'])
783 #print(yaml.safe_dump(resp))
786 if op
['lcmOperationType']=='action':
787 action_name
= op
['operationParams']['primitive']
789 if op
['operationState']=='PROCESSING':
790 if op
['lcmOperationType'] in ('instantiate', 'terminate'):
794 detail
= "In queue. Current position: {}".format(op
['queuePosition'])
795 elif op
['operationState'] in ('FAILED', 'FAILED_TEMP'):
796 detail
= op
.get('errorMessage','-')
797 date
= datetime
.fromtimestamp(op
['startTime']).strftime("%Y-%m-%dT%H:%M:%S")
798 last_update
= datetime
.fromtimestamp(op
['statusEnteredTime']).strftime("%Y-%m-%dT%H:%M:%S")
800 table
.add_row([op
['id'],
801 op
['lcmOperationType'],
803 wrap_text(text
=json
.dumps(formatParams(op
['operationParams']),indent
=2),width
=50),
804 op
['operationState'],
807 wrap_text(text
=detail
,width
=50)])
809 table
.add_row([op
['id'], op
['lcmOperationType'], action_name
,
810 op
['operationState'], date
, wrap_text(text
=detail
or "",width
=50)])
815 def nsi_list(ctx
, filter):
816 """list all Network Slice Instances"""
819 check_client_version(ctx
.obj
, ctx
.command
.name
)
820 resp
= ctx
.obj
.nsi
.list(filter)
821 # except ClientException as e:
825 ['netslice instance name',
827 'operational status',
831 nsi_name
= nsi
['name']
833 opstatus
= nsi
['operational-status'] if 'operational-status' in nsi
else 'Not found'
834 configstatus
= nsi
['config-status'] if 'config-status' in nsi
else 'Not found'
835 detailed_status
= nsi
['detailed-status'] if 'detailed-status' in nsi
else 'Not found'
836 if configstatus
== "config_not_needed":
837 configstatus
= "configured (no charms)"
848 @cli_osm.command(name
='nsi-list', short_help
='list all Network Slice Instances (NSI)')
849 @click.option('--filter', default
=None,
850 help='restricts the list to the Network Slice Instances matching the filter')
852 def nsi_list1(ctx
, filter):
853 """list all Network Slice Instances (NSI)"""
855 nsi_list(ctx
, filter)
858 @cli_osm.command(name
='netslice-instance-list', short_help
='list all Network Slice Instances (NSI)')
859 @click.option('--filter', default
=None,
860 help='restricts the list to the Network Slice Instances matching the filter')
862 def nsi_list2(ctx
, filter):
863 """list all Network Slice Instances (NSI)"""
865 nsi_list(ctx
, filter)
868 def nst_list(ctx
, filter):
871 check_client_version(ctx
.obj
, ctx
.command
.name
)
872 resp
= ctx
.obj
.nst
.list(filter)
873 # except ClientException as e:
876 # print(yaml.safe_dump(resp))
877 table
= PrettyTable(['nst name', 'id'])
879 name
= nst
['name'] if 'name' in nst
else '-'
880 table
.add_row([name
, nst
['_id']])
885 @cli_osm.command(name
='nst-list', short_help
='list all Network Slice Templates (NST)')
886 @click.option('--filter', default
=None,
887 help='restricts the list to the NST matching the filter')
889 def nst_list1(ctx
, filter):
890 """list all Network Slice Templates (NST) in the system"""
892 nst_list(ctx
, filter)
895 @cli_osm.command(name
='netslice-template-list', short_help
='list all Network Slice Templates (NST)')
896 @click.option('--filter', default
=None,
897 help='restricts the list to the NST matching the filter')
899 def nst_list2(ctx
, filter):
900 """list all Network Slice Templates (NST) in the system"""
902 nst_list(ctx
, filter)
905 def nsi_op_list(ctx
, name
):
908 check_client_version(ctx
.obj
, ctx
.command
.name
)
909 resp
= ctx
.obj
.nsi
.list_op(name
)
910 # except ClientException as e:
913 table
= PrettyTable(['id', 'operation', 'status'])
915 table
.add_row([op
['id'], op
['lcmOperationType'],
916 op
['operationState']])
921 @cli_osm.command(name
='nsi-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
922 @click.argument('name')
924 def nsi_op_list1(ctx
, name
):
925 """shows the history of operations over a Network Slice Instance (NSI)
927 NAME: name or ID of the Network Slice Instance
930 nsi_op_list(ctx
, name
)
933 @cli_osm.command(name
='netslice-instance-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
934 @click.argument('name')
936 def nsi_op_list2(ctx
, name
):
937 """shows the history of operations over a Network Slice Instance (NSI)
939 NAME: name or ID of the Network Slice Instance
942 nsi_op_list(ctx
, name
)
945 @cli_osm.command(name
='pdu-list', short_help
='list all Physical Deployment Units (PDU)')
946 @click.option('--filter', default
=None,
947 help='restricts the list to the Physical Deployment Units matching the filter')
949 def pdu_list(ctx
, filter):
950 """list all Physical Deployment Units (PDU)"""
953 check_client_version(ctx
.obj
, ctx
.command
.name
)
954 resp
= ctx
.obj
.pdu
.list(filter)
955 # except ClientException as e:
964 pdu_name
= pdu
['name']
966 pdu_type
= pdu
['type']
967 pdu_ipaddress
= "None"
968 for iface
in pdu
['interfaces']:
970 pdu_ipaddress
= iface
['ip-address']
985 def nsd_show(ctx
, name
, literal
):
988 resp
= ctx
.obj
.nsd
.get(name
)
989 # resp = ctx.obj.nsd.get_individual(name)
990 # except ClientException as e:
995 print(yaml
.safe_dump(resp
))
998 table
= PrettyTable(['field', 'value'])
999 for k
, v
in list(resp
.items()):
1000 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
1005 @cli_osm.command(name
='nsd-show', short_help
='shows the content of a NSD')
1006 @click.option('--literal', is_flag
=True,
1007 help='print literally, no pretty table')
1008 @click.argument('name')
1010 def nsd_show1(ctx
, name
, literal
):
1011 """shows the content of a NSD
1013 NAME: name or ID of the NSD/NSpkg
1016 nsd_show(ctx
, name
, literal
)
1019 @cli_osm.command(name
='nspkg-show', short_help
='shows the content of a NSD')
1020 @click.option('--literal', is_flag
=True,
1021 help='print literally, no pretty table')
1022 @click.argument('name')
1024 def nsd_show2(ctx
, name
, literal
):
1025 """shows the content of a NSD
1027 NAME: name or ID of the NSD/NSpkg
1030 nsd_show(ctx
, name
, literal
)
1033 def vnfd_show(ctx
, name
, literal
):
1036 resp
= ctx
.obj
.vnfd
.get(name
)
1037 # resp = ctx.obj.vnfd.get_individual(name)
1038 # except ClientException as e:
1043 print(yaml
.safe_dump(resp
))
1046 table
= PrettyTable(['field', 'value'])
1047 for k
, v
in list(resp
.items()):
1048 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
1053 def pkg_repo_show(ctx
, pkgtype
, name
, repo
, version
, filter, literal
):
1056 resp
= ctx
.obj
.osmrepo
.pkg_get(pkgtype
, name
, repo
, version
, filter)
1059 print(yaml
.safe_dump(resp
))
1062 catalog
= pkgtype
+ '-catalog'
1063 full_catalog
= pkgtype
+ ':' + catalog
1064 if resp
.get(catalog
):
1065 resp
= resp
.pop(catalog
)[pkgtype
][0]
1066 elif resp
.get(full_catalog
):
1067 resp
= resp
.pop(full_catalog
)[pkgtype
][0]
1069 table
= PrettyTable(['field', 'value'])
1070 for k
, v
in list(resp
.items()):
1071 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2), width
=100)])
1075 @cli_osm.command(name
='vnfd-show', short_help
='shows the content of a VNFD')
1076 @click.option('--literal', is_flag
=True,
1077 help='print literally, no pretty table')
1078 @click.argument('name')
1080 def vnfd_show1(ctx
, name
, literal
):
1081 """shows the content of a VNFD
1083 NAME: name or ID of the VNFD/VNFpkg
1086 vnfd_show(ctx
, name
, literal
)
1089 @cli_osm.command(name
='vnfpkg-show', short_help
='shows the content of a VNFD')
1090 @click.option('--literal', is_flag
=True,
1091 help='print literally, no pretty table')
1092 @click.argument('name')
1094 def vnfd_show2(ctx
, name
, literal
):
1095 """shows the content of a VNFD
1097 NAME: name or ID of the VNFD/VNFpkg
1100 vnfd_show(ctx
, name
, literal
)
1102 @cli_osm.command(name
='vnfpkg-repo-show', short_help
='shows the content of a VNFD')
1103 @click.option('--literal', is_flag
=True,
1104 help='print literally, no pretty table')
1105 @click.option('--repo',
1107 help='Repository name')
1108 @click.argument('name')
1109 @click.option('--filter',
1110 help='filter by fields')
1111 @click.option('--version',
1113 help='package version')
1115 def vnfd_show3(ctx
, name
, repo
, version
, literal
=None, filter=None):
1116 """shows the content of a VNFD in a repository
1118 NAME: name or ID of the VNFD/VNFpkg
1121 pkg_repo_show(ctx
, pkgtype
, name
, repo
, version
, filter, literal
)
1124 @cli_osm.command(name
='nsd-repo-show', short_help
='shows the content of a NSD')
1125 @click.option('--literal', is_flag
=True,
1126 help='print literally, no pretty table')
1127 @click.option('--repo',
1129 help='Repository name')
1130 @click.argument('name')
1131 @click.option('--filter',
1132 help='filter by fields')
1133 @click.option('--version',
1135 help='package version')
1137 def nsd_repo_show(ctx
, name
, repo
, version
, literal
=None, filter=None):
1138 """shows the content of a VNFD in a repository
1140 NAME: name or ID of the VNFD/VNFpkg
1143 pkg_repo_show(ctx
, pkgtype
, name
, repo
, version
, filter, literal
)
1145 @cli_osm.command(name
='nspkg-repo-show', short_help
='shows the content of a NSD')
1146 @click.option('--literal', is_flag
=True,
1147 help='print literally, no pretty table')
1148 @click.option('--repo',
1150 help='Repository name')
1151 @click.argument('name')
1152 @click.option('--filter',
1153 help='filter by fields')
1154 @click.option('--version',
1156 help='package version')
1158 def nsd_repo_show2(ctx
, name
, repo
, version
, literal
=None, filter=None):
1159 """shows the content of a VNFD in a repository
1161 NAME: name or ID of the VNFD/VNFpkg
1164 pkg_repo_show(ctx
, pkgtype
, name
, repo
, version
, filter, literal
)
1166 @cli_osm.command(name
='nfpkg-show', short_help
='shows the content of a NF Descriptor')
1167 @click.option('--literal', is_flag
=True,
1168 help='print literally, no pretty table')
1169 @click.argument('name')
1171 def nfpkg_show(ctx
, name
, literal
):
1172 """shows the content of a NF Descriptor
1174 NAME: name or ID of the NFpkg
1177 vnfd_show(ctx
, name
, literal
)
1180 @cli_osm.command(name
='nfpkg-repo-show', short_help
='shows the content of a VNFD')
1181 @click.option('--literal', is_flag
=True,
1182 help='print literally, no pretty table')
1183 @click.option('--repo',
1185 help='Repository name')
1186 @click.argument('name')
1187 @click.option('--filter',
1188 help='filter by fields')
1189 @click.option('--version',
1191 help='package version')
1193 def vnfd_show4(ctx
, name
, repo
, version
, literal
=None, filter=None):
1194 """shows the content of a VNFD in a repository
1196 NAME: name or ID of the VNFD/VNFpkg
1199 pkg_repo_show(ctx
, pkgtype
, name
, repo
, version
, filter, literal
)
1202 @cli_osm.command(name
='ns-show', short_help
='shows the info of a NS instance')
1203 @click.argument('name')
1204 @click.option('--literal', is_flag
=True,
1205 help='print literally, no pretty table')
1206 @click.option('--filter', default
=None)
1208 def ns_show(ctx
, name
, literal
, filter):
1209 """shows the info of a NS instance
1211 NAME: name or ID of the NS instance
1215 ns
= ctx
.obj
.ns
.get(name
)
1216 # except ClientException as e:
1221 print(yaml
.safe_dump(ns
))
1224 table
= PrettyTable(['field', 'value'])
1226 for k
, v
in list(ns
.items()):
1227 if filter is None or filter in k
:
1228 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
1230 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1231 if fullclassname
!= 'osmclient.sol005.client.Client':
1232 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
1233 nsr_optdata
= nsopdata
['nsr:nsr']
1234 for k
, v
in list(nsr_optdata
.items()):
1235 if filter is None or filter in k
:
1236 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2),width
=100)])
1241 @cli_osm.command(name
='vnf-show', short_help
='shows the info of a VNF instance')
1242 @click.argument('name')
1243 @click.option('--literal', is_flag
=True,
1244 help='print literally, no pretty table')
1245 @click.option('--filter', default
=None, help='restricts the information to the fields in the filter')
1246 @click.option('--kdu', default
=None, help='KDU name (whose status will be shown)')
1248 def vnf_show(ctx
, name
, literal
, filter, kdu
):
1249 """shows the info of a VNF instance
1251 NAME: name or ID of the VNF instance
1253 def print_kdu_status(op_info_status
):
1254 """print KDU status properly formatted
1257 op_status
= yaml
.safe_load(op_info_status
)
1258 if "namespace" in op_status
and "info" in op_status
and \
1259 "last_deployed" in op_status
["info"] and "status" in op_status
["info"] and \
1260 "code" in op_status
["info"]["status"] and "resources" in op_status
["info"]["status"] and \
1261 "seconds" in op_status
["info"]["last_deployed"]:
1262 last_deployed_time
= datetime
.fromtimestamp(op_status
["info"]["last_deployed"]["seconds"]).strftime("%a %b %d %I:%M:%S %Y")
1263 print("LAST DEPLOYED: {}".format(last_deployed_time
))
1264 print("NAMESPACE: {}".format(op_status
["namespace"]))
1265 status_code
= "UNKNOWN"
1266 if op_status
["info"]["status"]["code"]==1:
1267 status_code
= "DEPLOYED"
1268 print("STATUS: {}".format(status_code
))
1271 print(op_status
["info"]["status"]["resources"])
1272 if "notes" in op_status
["info"]["status"]:
1274 print(op_status
["info"]["status"]["notes"])
1276 print(op_info_status
)
1278 print(op_info_status
)
1283 raise ClientException('"--literal" option is incompatible with "--kdu" option')
1285 raise ClientException('"--filter" option is incompatible with "--kdu" option')
1288 check_client_version(ctx
.obj
, ctx
.command
.name
)
1289 resp
= ctx
.obj
.vnf
.get(name
)
1292 ns_id
= resp
['nsr-id-ref']
1294 op_data
['member_vnf_index'] = resp
['member-vnf-index-ref']
1295 op_data
['kdu_name'] = kdu
1296 op_data
['primitive'] = 'status'
1297 op_data
['primitive_params'] = {}
1298 op_id
= ctx
.obj
.ns
.exec_op(ns_id
, op_name
='action', op_data
=op_data
, wait
=False)
1301 op_info
= ctx
.obj
.ns
.get_op(op_id
)
1302 if op_info
['operationState'] == 'COMPLETED':
1303 print_kdu_status(op_info
['detailed-status'])
1307 print ("Could not determine KDU status")
1310 print(yaml
.safe_dump(resp
))
1313 table
= PrettyTable(['field', 'value'])
1315 for k
, v
in list(resp
.items()):
1316 if filter is None or filter in k
:
1317 table
.add_row([k
, wrap_text(text
=json
.dumps(v
,indent
=2),width
=100)])
1320 # except ClientException as e:
1325 #@cli_osm.command(name='vnf-monitoring-show')
1326 #@click.argument('vnf_name')
1327 #@click.pass_context
1328 #def vnf_monitoring_show(ctx, vnf_name):
1330 # check_client_version(ctx.obj, ctx.command.name, 'v1')
1331 # resp = ctx.obj.vnf.get_monitoring(vnf_name)
1332 # except ClientException as e:
1336 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
1337 # if resp is not None:
1338 # for monitor in resp:
1342 # monitor['value-integer'],
1343 # monitor['units']])
1348 #@cli_osm.command(name='ns-monitoring-show')
1349 #@click.argument('ns_name')
1350 #@click.pass_context
1351 #def ns_monitoring_show(ctx, ns_name):
1353 # check_client_version(ctx.obj, ctx.command.name, 'v1')
1354 # resp = ctx.obj.ns.get_monitoring(ns_name)
1355 # except ClientException as e:
1359 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
1360 # for key, val in list(resp.items()):
1361 # for monitor in val:
1365 # monitor['value-integer'],
1366 # monitor['units']])
1371 @cli_osm.command(name
='ns-op-show', short_help
='shows the info of a NS operation')
1372 @click.argument('id')
1373 @click.option('--filter', default
=None)
1374 @click.option('--literal', is_flag
=True,
1375 help='print literally, no pretty table')
1377 def ns_op_show(ctx
, id, filter, literal
):
1378 """shows the detailed info of a NS operation
1380 ID: operation identifier
1384 check_client_version(ctx
.obj
, ctx
.command
.name
)
1385 op_info
= ctx
.obj
.ns
.get_op(id)
1386 # except ClientException as e:
1391 print(yaml
.safe_dump(op_info
))
1394 table
= PrettyTable(['field', 'value'])
1395 for k
, v
in list(op_info
.items()):
1396 if filter is None or filter in k
:
1397 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
1402 def nst_show(ctx
, name
, literal
):
1405 check_client_version(ctx
.obj
, ctx
.command
.name
)
1406 resp
= ctx
.obj
.nst
.get(name
)
1407 #resp = ctx.obj.nst.get_individual(name)
1408 # except ClientException as e:
1413 print(yaml
.safe_dump(resp
))
1416 table
= PrettyTable(['field', 'value'])
1417 for k
, v
in list(resp
.items()):
1418 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
1423 @cli_osm.command(name
='nst-show', short_help
='shows the content of a Network Slice Template (NST)')
1424 @click.option('--literal', is_flag
=True,
1425 help='print literally, no pretty table')
1426 @click.argument('name')
1428 def nst_show1(ctx
, name
, literal
):
1429 """shows the content of a Network Slice Template (NST)
1431 NAME: name or ID of the NST
1434 nst_show(ctx
, name
, literal
)
1437 @cli_osm.command(name
='netslice-template-show', short_help
='shows the content of a Network Slice Template (NST)')
1438 @click.option('--literal', is_flag
=True,
1439 help='print literally, no pretty table')
1440 @click.argument('name')
1442 def nst_show2(ctx
, name
, literal
):
1443 """shows the content of a Network Slice Template (NST)
1445 NAME: name or ID of the NST
1448 nst_show(ctx
, name
, literal
)
1451 def nsi_show(ctx
, name
, literal
, filter):
1454 check_client_version(ctx
.obj
, ctx
.command
.name
)
1455 nsi
= ctx
.obj
.nsi
.get(name
)
1456 # except ClientException as e:
1461 print(yaml
.safe_dump(nsi
))
1464 table
= PrettyTable(['field', 'value'])
1466 for k
, v
in list(nsi
.items()):
1467 if filter is None or filter in k
:
1468 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1474 @cli_osm.command(name
='nsi-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1475 @click.argument('name')
1476 @click.option('--literal', is_flag
=True,
1477 help='print literally, no pretty table')
1478 @click.option('--filter', default
=None)
1480 def nsi_show1(ctx
, name
, literal
, filter):
1481 """shows the content of a Network Slice Instance (NSI)
1483 NAME: name or ID of the Network Slice Instance
1486 nsi_show(ctx
, name
, literal
, filter)
1489 @cli_osm.command(name
='netslice-instance-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1490 @click.argument('name')
1491 @click.option('--literal', is_flag
=True,
1492 help='print literally, no pretty table')
1493 @click.option('--filter', default
=None)
1495 def nsi_show2(ctx
, name
, literal
, filter):
1496 """shows the content of a Network Slice Instance (NSI)
1498 NAME: name or ID of the Network Slice Instance
1501 nsi_show(ctx
, name
, literal
, filter)
1504 def nsi_op_show(ctx
, id, filter):
1507 check_client_version(ctx
.obj
, ctx
.command
.name
)
1508 op_info
= ctx
.obj
.nsi
.get_op(id)
1509 # except ClientException as e:
1513 table
= PrettyTable(['field', 'value'])
1514 for k
, v
in list(op_info
.items()):
1515 if filter is None or filter in k
:
1516 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1521 @cli_osm.command(name
='nsi-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1522 @click.argument('id')
1523 @click.option('--filter', default
=None)
1525 def nsi_op_show1(ctx
, id, filter):
1526 """shows the info of an operation over a Network Slice Instance(NSI)
1528 ID: operation identifier
1531 nsi_op_show(ctx
, id, filter)
1534 @cli_osm.command(name
='netslice-instance-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1535 @click.argument('id')
1536 @click.option('--filter', default
=None)
1538 def nsi_op_show2(ctx
, id, filter):
1539 """shows the info of an operation over a Network Slice Instance(NSI)
1541 ID: operation identifier
1544 nsi_op_show(ctx
, id, filter)
1547 @cli_osm.command(name
='pdu-show', short_help
='shows the content of a Physical Deployment Unit (PDU)')
1548 @click.argument('name')
1549 @click.option('--literal', is_flag
=True,
1550 help='print literally, no pretty table')
1551 @click.option('--filter', default
=None)
1553 def pdu_show(ctx
, name
, literal
, filter):
1554 """shows the content of a Physical Deployment Unit (PDU)
1556 NAME: name or ID of the PDU
1560 check_client_version(ctx
.obj
, ctx
.command
.name
)
1561 pdu
= ctx
.obj
.pdu
.get(name
)
1562 # except ClientException as e:
1567 print(yaml
.safe_dump(pdu
))
1570 table
= PrettyTable(['field', 'value'])
1572 for k
, v
in list(pdu
.items()):
1573 if filter is None or filter in k
:
1574 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1580 ####################
1582 ####################
1584 def nsd_create(ctx
, filename
, overwrite
, skip_charm_build
, repo
, vendor
, version
):
1587 check_client_version(ctx
.obj
, ctx
.command
.name
)
1589 filename
= ctx
.obj
.osmrepo
.get_pkg('ns', filename
, repo
, vendor
, version
)
1590 ctx
.obj
.nsd
.create(filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
)
1591 # except ClientException as e:
1596 @cli_osm.command(name
='nsd-create', short_help
='creates a new NSD/NSpkg')
1597 @click.argument('filename')
1598 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1599 help='Deprecated. Use override')
1600 @click.option('--override', 'overwrite', default
=None,
1601 help='overrides fields in descriptor, format: '
1602 '"key1.key2...=value[;key3...=value;...]"')
1603 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1604 help='The charm will not be compiled, it is assumed to already exist')
1605 @click.option('--repo', default
=None,
1606 help='[repository]: Repository name')
1607 @click.option('--vendor', default
=None,
1608 help='[repository]: filter by vendor]')
1609 @click.option('--version', default
='latest',
1610 help='[repository]: filter by version. Default: latest')
1612 def nsd_create1(ctx
, filename
, overwrite
, skip_charm_build
, repo
, vendor
, version
):
1613 """onboards a new NSpkg (alias of nspkg-create) (TO BE DEPRECATED)
1616 FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder
1617 If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded.
1618 If FILENAME is an NF Package folder, it is built and then onboarded.
1621 nsd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
, repo
=repo
, vendor
=vendor
,
1625 @cli_osm.command(name
='nspkg-create', short_help
='creates a new NSD/NSpkg')
1626 @click.argument('filename')
1627 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1628 help='Deprecated. Use override')
1629 @click.option('--override', 'overwrite', default
=None,
1630 help='overrides fields in descriptor, format: '
1631 '"key1.key2...=value[;key3...=value;...]"')
1632 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1633 help='The charm will not be compiled, it is assumed to already exist')
1634 @click.option('--repo', default
=None,
1635 help='[repository]: Repository name')
1636 @click.option('--vendor', default
=None,
1637 help='[repository]: filter by vendor]')
1638 @click.option('--version', default
='latest',
1639 help='[repository]: filter by version. Default: latest')
1641 def nsd_pkg_create(ctx
, filename
, overwrite
, skip_charm_build
, repo
, vendor
, version
):
1642 """onboards a new NSpkg
1644 FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder
1645 If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded.
1646 If FILENAME is an NF Package folder, it is built and then onboarded.
1649 nsd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
, repo
=repo
, vendor
=vendor
,
1653 def vnfd_create(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
,
1654 repo
, vendor
, version
):
1657 check_client_version(ctx
.obj
, ctx
.command
.name
)
1659 filename
= ctx
.obj
.osmrepo
.get_pkg('vnf', filename
, repo
, vendor
, version
)
1660 ctx
.obj
.vnfd
.create(filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1661 override_epa
=override_epa
, override_nonepa
=override_nonepa
,
1662 override_paravirt
=override_paravirt
)
1663 # except ClientException as e:
1668 @cli_osm.command(name
='vnfd-create', short_help
='creates a new VNFD/VNFpkg')
1669 @click.argument('filename')
1670 @click.option('--overwrite', 'overwrite', default
=None,
1671 help='overwrite deprecated, use override')
1672 @click.option('--override', 'overwrite', default
=None,
1673 help='overrides fields in descriptor, format: '
1674 '"key1.key2...=value[;key3...=value;...]"')
1675 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1676 help='The charm will not be compiled, it is assumed to already exist')
1677 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1678 help='adds guest-epa parameters to all VDU')
1679 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1680 help='removes all guest-epa parameters from all VDU')
1681 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1682 help='overrides all VDU interfaces to PARAVIRT')
1683 @click.option('--repo', default
=None,
1684 help='[repository]: Repository name')
1685 @click.option('--vendor', default
=None,
1686 help='[repository]: filter by vendor]')
1687 @click.option('--version', default
='latest',
1688 help='[repository]: filter by version. Default: latest')
1690 def vnfd_create1(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
,
1691 repo
,vendor
, version
):
1692 """creates a new VNFD/VNFpkg
1694 FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder
1695 If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded.
1696 If FILENAME is an NF Package folder, it is built and then onboarded.
1699 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1700 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
,
1701 repo
=repo
, vendor
=vendor
, version
=version
)
1704 @cli_osm.command(name
='vnfpkg-create', short_help
='creates a new VNFD/VNFpkg')
1705 @click.argument('filename')
1706 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1707 help='Deprecated. Use override')
1708 @click.option('--override', 'overwrite', default
=None,
1709 help='overrides fields in descriptor, format: '
1710 '"key1.key2...=value[;key3...=value;...]"')
1711 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1712 help='The charm will not be compiled, it is assumed to already exist')
1713 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1714 help='adds guest-epa parameters to all VDU')
1715 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1716 help='removes all guest-epa parameters from all VDU')
1717 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1718 help='overrides all VDU interfaces to PARAVIRT')
1719 @click.option('--repo', default
=None,
1720 help='[repository]: Repository name')
1721 @click.option('--vendor', default
=None,
1722 help='[repository]: filter by vendor]')
1723 @click.option('--version', default
='latest',
1724 help='[repository]: filter by version. Default: latest')
1726 def vnfd_create2(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
,
1727 repo
, vendor
, version
):
1728 """creates a new VNFD/VNFpkg
1730 FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder
1731 If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded.
1732 If FILENAME is an NF Package folder, it is built and then onboarded.
1735 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1736 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
,
1737 repo
=repo
, vendor
=vendor
, version
=version
)
1739 @cli_osm.command(name
='nfpkg-create', short_help
='creates a new NFpkg')
1740 @click.argument('filename')
1741 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1742 help='Deprecated. Use override')
1743 @click.option('--override', 'overwrite', default
=None,
1744 help='overrides fields in descriptor, format: '
1745 '"key1.key2...=value[;key3...=value;...]"')
1746 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1747 help='The charm will not be compiled, it is assumed to already exist')
1748 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1749 help='adds guest-epa parameters to all VDU')
1750 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1751 help='removes all guest-epa parameters from all VDU')
1752 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1753 help='overrides all VDU interfaces to PARAVIRT')
1754 @click.option('--repo', default
=None,
1755 help='[repository]: Repository name')
1756 @click.option('--vendor', default
=None,
1757 help='[repository]: filter by vendor]')
1758 @click.option('--version', default
='latest',
1759 help='[repository]: filter by version. Default: latest')
1761 def nfpkg_create(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
,
1762 repo
, vendor
, version
):
1763 """creates a new NFpkg
1766 FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder
1767 If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded.
1768 If FILENAME is an NF Package folder, it is built and then onboarded.
1771 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1772 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
,
1773 repo
=repo
, vendor
=vendor
, version
=version
)
1776 @cli_osm.command(name
='ns-create', short_help
='creates a new Network Service instance')
1777 @click.option('--ns_name',
1778 prompt
=True, help='name of the NS instance')
1779 @click.option('--nsd_name',
1780 prompt
=True, help='name of the NS descriptor')
1781 @click.option('--vim_account',
1782 prompt
=True, help='default VIM account id or name for the deployment')
1783 @click.option('--admin_status',
1785 help='administration status')
1786 @click.option('--ssh_keys',
1788 help='comma separated list of public key files to inject to vnfs')
1789 @click.option('--config',
1791 help='ns specific yaml configuration')
1792 @click.option('--config_file',
1794 help='ns specific yaml configuration file')
1795 @click.option('--wait',
1799 help='do not return the control immediately, but keep it '
1800 'until the operation is completed, or timeout')
1811 """creates a new NS instance"""
1815 check_client_version(ctx
.obj
, '--config_file')
1817 raise ClientException('"--config" option is incompatible with "--config_file" option')
1818 with
open(config_file
, 'r') as cf
:
1825 account
=vim_account
,
1827 # except ClientException as e:
1832 def nst_create(ctx
, filename
, overwrite
):
1835 check_client_version(ctx
.obj
, ctx
.command
.name
)
1836 ctx
.obj
.nst
.create(filename
, overwrite
)
1837 # except ClientException as e:
1842 @cli_osm.command(name
='nst-create', short_help
='creates a new Network Slice Template (NST)')
1843 @click.argument('filename')
1844 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1845 help='Deprecated. Use override')
1846 @click.option('--override', 'overwrite', default
=None,
1847 help='overrides fields in descriptor, format: '
1848 '"key1.key2...=value[;key3...=value;...]"')
1850 def nst_create1(ctx
, filename
, overwrite
):
1851 """creates a new Network Slice Template (NST)
1853 FILENAME: NST package folder, NST yaml file or NSTpkg tar.gz file
1856 nst_create(ctx
, filename
, overwrite
)
1859 @cli_osm.command(name
='netslice-template-create', short_help
='creates a new Network Slice Template (NST)')
1860 @click.argument('filename')
1861 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1862 help='Deprecated. Use override')
1863 @click.option('--override', 'overwrite', default
=None,
1864 help='overrides fields in descriptor, format: '
1865 '"key1.key2...=value[;key3...=value;...]"')
1867 def nst_create2(ctx
, filename
, overwrite
):
1868 """creates a new Network Slice Template (NST)
1870 FILENAME: NST yaml file or NSTpkg tar.gz file
1873 nst_create(ctx
, filename
, overwrite
)
1876 def nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1877 """creates a new Network Slice Instance (NSI)"""
1880 check_client_version(ctx
.obj
, ctx
.command
.name
)
1883 raise ClientException('"--config" option is incompatible with "--config_file" option')
1884 with
open(config_file
, 'r') as cf
:
1886 ctx
.obj
.nsi
.create(nst_name
, nsi_name
, config
=config
, ssh_keys
=ssh_keys
,
1887 account
=vim_account
, wait
=wait
)
1888 # except ClientException as e:
1893 @cli_osm.command(name
='nsi-create', short_help
='creates a new Network Slice Instance')
1894 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1895 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1896 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1897 @click.option('--ssh_keys', default
=None,
1898 help='comma separated list of keys to inject to vnfs')
1899 @click.option('--config', default
=None,
1900 help='Netslice specific yaml configuration:\n'
1901 'netslice_subnet: [\n'
1902 'id: TEXT, vim_account: TEXT,\n'
1903 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1904 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]\n'
1905 'additionalParamsForNsi: {param: value, ...}\n'
1906 'additionalParamsForsubnet: [{id: SUBNET_ID, additionalParamsForNs: {}, additionalParamsForVnf: {}}]\n'
1908 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1910 @click.option('--config_file',
1912 help='nsi specific yaml configuration file')
1913 @click.option('--wait',
1917 help='do not return the control immediately, but keep it '
1918 'until the operation is completed, or timeout')
1920 def nsi_create1(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1921 """creates a new Network Slice Instance (NSI)"""
1923 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1926 @cli_osm.command(name
='netslice-instance-create', short_help
='creates a new Network Slice Instance')
1927 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1928 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1929 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1930 @click.option('--ssh_keys', default
=None,
1931 help='comma separated list of keys to inject to vnfs')
1932 @click.option('--config', default
=None,
1933 help='Netslice specific yaml configuration:\n'
1934 'netslice_subnet: [\n'
1935 'id: TEXT, vim_account: TEXT,\n'
1936 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1937 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1939 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1941 @click.option('--config_file',
1943 help='nsi specific yaml configuration file')
1944 @click.option('--wait',
1948 help='do not return the control immediately, but keep it '
1949 'until the operation is completed, or timeout')
1951 def nsi_create2(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1952 """creates a new Network Slice Instance (NSI)"""
1954 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1957 @cli_osm.command(name
='pdu-create', short_help
='adds a new Physical Deployment Unit to the catalog')
1958 @click.option('--name', help='name of the Physical Deployment Unit')
1959 @click.option('--pdu_type', help='type of PDU (e.g. router, firewall, FW001)')
1960 @click.option('--interface',
1961 help='interface(s) of the PDU: name=<NAME>,mgmt=<true|false>,ip-address=<IP_ADDRESS>'+
1962 '[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]',
1964 @click.option('--description', help='human readable description')
1965 @click.option('--vim_account', help='list of VIM accounts (in the same VIM) that can reach this PDU', multiple
=True)
1966 @click.option('--descriptor_file', default
=None,
1967 help='PDU descriptor file (as an alternative to using the other arguments')
1969 def pdu_create(ctx
, name
, pdu_type
, interface
, description
, vim_account
, descriptor_file
):
1970 """creates a new Physical Deployment Unit (PDU)"""
1973 check_client_version(ctx
.obj
, ctx
.command
.name
)
1975 if not descriptor_file
:
1977 raise ClientException('in absence of descriptor file, option "--name" is mandatory')
1979 raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory')
1981 raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)')
1983 raise ClientException('in absence of descriptor file, option "--vim_account" is mandatory (at least once)')
1985 with
open(descriptor_file
, 'r') as df
:
1986 pdu
= yaml
.safe_load(df
.read())
1987 if name
: pdu
["name"] = name
1988 if pdu_type
: pdu
["type"] = pdu_type
1989 if description
: pdu
["description"] = description
1990 if vim_account
: pdu
["vim_accounts"] = vim_account
1993 for iface
in interface
:
1994 new_iface
={k
:v
for k
,v
in [i
.split('=') for i
in iface
.split(',')]}
1995 new_iface
["mgmt"] = (new_iface
.get("mgmt","false").lower() == "true")
1996 ifaces_list
.append(new_iface
)
1997 pdu
["interfaces"] = ifaces_list
1998 ctx
.obj
.pdu
.create(pdu
)
1999 # except ClientException as e:
2004 ####################
2006 ####################
2008 def nsd_update(ctx
, name
, content
):
2011 check_client_version(ctx
.obj
, ctx
.command
.name
)
2012 ctx
.obj
.nsd
.update(name
, content
)
2013 # except ClientException as e:
2018 @cli_osm.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
2019 @click.argument('name')
2020 @click.option('--content', default
=None,
2021 help='filename with the NSD/NSpkg replacing the current one')
2023 def nsd_update1(ctx
, name
, content
):
2024 """updates a NSD/NSpkg
2026 NAME: name or ID of the NSD/NSpkg
2029 nsd_update(ctx
, name
, content
)
2032 @cli_osm.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
2033 @click.argument('name')
2034 @click.option('--content', default
=None,
2035 help='filename with the NSD/NSpkg replacing the current one')
2037 def nsd_update2(ctx
, name
, content
):
2038 """updates a NSD/NSpkg
2040 NAME: name or ID of the NSD/NSpkg
2043 nsd_update(ctx
, name
, content
)
2046 def vnfd_update(ctx
, name
, content
):
2049 check_client_version(ctx
.obj
, ctx
.command
.name
)
2050 ctx
.obj
.vnfd
.update(name
, content
)
2051 # except ClientException as e:
2056 @cli_osm.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
2057 @click.argument('name')
2058 @click.option('--content', default
=None,
2059 help='filename with the VNFD/VNFpkg replacing the current one')
2061 def vnfd_update1(ctx
, name
, content
):
2062 """updates a VNFD/VNFpkg
2064 NAME: name or ID of the VNFD/VNFpkg
2067 vnfd_update(ctx
, name
, content
)
2070 @cli_osm.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
2071 @click.argument('name')
2072 @click.option('--content', default
=None,
2073 help='filename with the VNFD/VNFpkg replacing the current one')
2075 def vnfd_update2(ctx
, name
, content
):
2076 """updates a VNFD/VNFpkg
2078 NAME: VNFD yaml file or VNFpkg tar.gz file
2081 vnfd_update(ctx
, name
, content
)
2084 @cli_osm.command(name
='nfpkg-update', short_help
='updates a NFpkg')
2085 @click.argument('name')
2086 @click.option('--content', default
=None,
2087 help='filename with the NFpkg replacing the current one')
2089 def nfpkg_update(ctx
, name
, content
):
2092 NAME: NF Descriptor yaml file or NFpkg tar.gz file
2095 vnfd_update(ctx
, name
, content
)
2098 def nst_update(ctx
, name
, content
):
2101 check_client_version(ctx
.obj
, ctx
.command
.name
)
2102 ctx
.obj
.nst
.update(name
, content
)
2103 # except ClientException as e:
2108 @cli_osm.command(name
='nst-update', short_help
='updates a Network Slice Template (NST)')
2109 @click.argument('name')
2110 @click.option('--content', default
=None,
2111 help='filename with the NST/NSTpkg replacing the current one')
2113 def nst_update1(ctx
, name
, content
):
2114 """updates a Network Slice Template (NST)
2116 NAME: name or ID of the NSD/NSpkg
2119 nst_update(ctx
, name
, content
)
2122 @cli_osm.command(name
='netslice-template-update', short_help
='updates a Network Slice Template (NST)')
2123 @click.argument('name')
2124 @click.option('--content', default
=None,
2125 help='filename with the NST/NSTpkg replacing the current one')
2127 def nst_update2(ctx
, name
, content
):
2128 """updates a Network Slice Template (NST)
2130 NAME: name or ID of the NSD/NSpkg
2133 nst_update(ctx
, name
, content
)
2136 ####################
2138 ####################
2140 def nsd_delete(ctx
, name
, force
):
2144 ctx
.obj
.nsd
.delete(name
)
2146 check_client_version(ctx
.obj
, '--force')
2147 ctx
.obj
.nsd
.delete(name
, force
)
2148 # except ClientException as e:
2153 @cli_osm.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
2154 @click.argument('name')
2155 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2157 def nsd_delete1(ctx
, name
, force
):
2158 """deletes a NSD/NSpkg
2160 NAME: name or ID of the NSD/NSpkg to be deleted
2163 nsd_delete(ctx
, name
, force
)
2166 @cli_osm.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
2167 @click.argument('name')
2168 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2170 def nsd_delete2(ctx
, name
, force
):
2171 """deletes a NSD/NSpkg
2173 NAME: name or ID of the NSD/NSpkg to be deleted
2176 nsd_delete(ctx
, name
, force
)
2179 def vnfd_delete(ctx
, name
, force
):
2183 ctx
.obj
.vnfd
.delete(name
)
2185 check_client_version(ctx
.obj
, '--force')
2186 ctx
.obj
.vnfd
.delete(name
, force
)
2187 # except ClientException as e:
2192 @cli_osm.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
2193 @click.argument('name')
2194 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2196 def vnfd_delete1(ctx
, name
, force
):
2197 """deletes a VNFD/VNFpkg
2199 NAME: name or ID of the VNFD/VNFpkg to be deleted
2202 vnfd_delete(ctx
, name
, force
)
2205 @cli_osm.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
2206 @click.argument('name')
2207 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2209 def vnfd_delete2(ctx
, name
, force
):
2210 """deletes a VNFD/VNFpkg
2212 NAME: name or ID of the VNFD/VNFpkg to be deleted
2215 vnfd_delete(ctx
, name
, force
)
2218 @cli_osm.command(name
='nfpkg-delete', short_help
='deletes a NFpkg')
2219 @click.argument('name')
2220 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2222 def nfpkg_delete(ctx
, name
, force
):
2225 NAME: name or ID of the NFpkg to be deleted
2228 vnfd_delete(ctx
, name
, force
)
2231 @cli_osm.command(name
='ns-delete', short_help
='deletes a NS instance')
2232 @click.argument('name')
2233 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2234 @click.option('--config', default
=None,
2235 help="specific yaml configuration for the termination, e.g. '{autoremove: False, timeout_ns_terminate: "
2236 "600, skip_terminate_primitives: True}'")
2237 @click.option('--wait',
2241 help='do not return the control immediately, but keep it '
2242 'until the operation is completed, or timeout')
2244 def ns_delete(ctx
, name
, force
, config
, wait
):
2245 """deletes a NS instance
2247 NAME: name or ID of the NS instance to be deleted
2252 ctx
.obj
.ns
.delete(name
, config
=config
, wait
=wait
)
2254 check_client_version(ctx
.obj
, '--force')
2255 ctx
.obj
.ns
.delete(name
, force
, config
=config
, wait
=wait
)
2256 # except ClientException as e:
2261 def nst_delete(ctx
, name
, force
):
2264 check_client_version(ctx
.obj
, ctx
.command
.name
)
2265 ctx
.obj
.nst
.delete(name
, force
)
2266 # except ClientException as e:
2271 @cli_osm.command(name
='nst-delete', short_help
='deletes a Network Slice Template (NST)')
2272 @click.argument('name')
2273 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2275 def nst_delete1(ctx
, name
, force
):
2276 """deletes a Network Slice Template (NST)
2278 NAME: name or ID of the NST/NSTpkg to be deleted
2281 nst_delete(ctx
, name
, force
)
2284 @cli_osm.command(name
='netslice-template-delete', short_help
='deletes a Network Slice Template (NST)')
2285 @click.argument('name')
2286 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2288 def nst_delete2(ctx
, name
, force
):
2289 """deletes a Network Slice Template (NST)
2291 NAME: name or ID of the NST/NSTpkg to be deleted
2294 nst_delete(ctx
, name
, force
)
2297 def nsi_delete(ctx
, name
, force
, wait
):
2300 check_client_version(ctx
.obj
, ctx
.command
.name
)
2301 ctx
.obj
.nsi
.delete(name
, force
, wait
=wait
)
2302 # except ClientException as e:
2307 @cli_osm.command(name
='nsi-delete', short_help
='deletes a Network Slice Instance (NSI)')
2308 @click.argument('name')
2309 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2310 @click.option('--wait',
2314 help='do not return the control immediately, but keep it '
2315 'until the operation is completed, or timeout')
2317 def nsi_delete1(ctx
, name
, force
, wait
):
2318 """deletes a Network Slice Instance (NSI)
2320 NAME: name or ID of the Network Slice instance to be deleted
2323 nsi_delete(ctx
, name
, force
, wait
=wait
)
2326 @cli_osm.command(name
='netslice-instance-delete', short_help
='deletes a Network Slice Instance (NSI)')
2327 @click.argument('name')
2328 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2330 def nsi_delete2(ctx
, name
, force
, wait
):
2331 """deletes a Network Slice Instance (NSI)
2333 NAME: name or ID of the Network Slice instance to be deleted
2336 nsi_delete(ctx
, name
, force
, wait
=wait
)
2339 @cli_osm.command(name
='pdu-delete', short_help
='deletes a Physical Deployment Unit (PDU)')
2340 @click.argument('name')
2341 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2343 def pdu_delete(ctx
, name
, force
):
2344 """deletes a Physical Deployment Unit (PDU)
2346 NAME: name or ID of the PDU to be deleted
2350 check_client_version(ctx
.obj
, ctx
.command
.name
)
2351 ctx
.obj
.pdu
.delete(name
, force
)
2352 # except ClientException as e:
2361 @cli_osm.command(name
='vim-create', short_help
='creates a new VIM account')
2362 @click.option('--name',
2364 help='Name to create datacenter')
2365 @click.option('--user',
2367 help='VIM username')
2368 @click.option('--password',
2371 confirmation_prompt
=True,
2372 help='VIM password')
2373 @click.option('--auth_url',
2376 @click.option('--tenant',
2378 help='VIM tenant name')
2379 @click.option('--config',
2381 help='VIM specific config parameters')
2382 @click.option('--account_type',
2383 default
='openstack',
2385 @click.option('--description',
2387 help='human readable description')
2388 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
2389 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
2390 @click.option('--wait',
2394 help='do not return the control immediately, but keep it '
2395 'until the operation is completed, or timeout')
2409 """creates a new VIM account"""
2413 check_client_version(ctx
.obj
, '--sdn_controller')
2414 if sdn_port_mapping
:
2415 check_client_version(ctx
.obj
, '--sdn_port_mapping')
2417 vim
['vim-username'] = user
2418 vim
['vim-password'] = password
2419 vim
['vim-url'] = auth_url
2420 vim
['vim-tenant-name'] = tenant
2421 vim
['vim-type'] = account_type
2422 vim
['description'] = description
2423 vim
['config'] = config
2424 if sdn_controller
or sdn_port_mapping
:
2425 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
2427 ctx
.obj
.vim
.create(name
, vim
, wait
=wait
)
2428 # except ClientException as e:
2433 @cli_osm.command(name
='vim-update', short_help
='updates a VIM account')
2434 @click.argument('name')
2435 @click.option('--newname', help='New name for the VIM account')
2436 @click.option('--user', help='VIM username')
2437 @click.option('--password', help='VIM password')
2438 @click.option('--auth_url', help='VIM url')
2439 @click.option('--tenant', help='VIM tenant name')
2440 @click.option('--config', help='VIM specific config parameters')
2441 @click.option('--account_type', help='VIM type')
2442 @click.option('--description', help='human readable description')
2443 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller to be associated with this VIM'
2444 'account. Use empty string to disassociate')
2445 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
2446 @click.option('--wait',
2450 help='do not return the control immediately, but keep it '
2451 'until the operation is completed, or timeout')
2466 """updates a VIM account
2468 NAME: name or ID of the VIM account
2472 check_client_version(ctx
.obj
, ctx
.command
.name
)
2474 if newname
: vim
['name'] = newname
2475 if user
: vim
['vim_user'] = user
2476 if password
: vim
['vim_password'] = password
2477 if auth_url
: vim
['vim_url'] = auth_url
2478 if tenant
: vim
['vim-tenant-name'] = tenant
2479 if account_type
: vim
['vim_type'] = account_type
2480 if description
: vim
['description'] = description
2481 if config
: vim
['config'] = config
2482 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
2483 # except ClientException as e:
2488 @cli_osm.command(name
='vim-delete', short_help
='deletes a VIM account')
2489 @click.argument('name')
2490 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2491 @click.option('--wait',
2495 help='do not return the control immediately, but keep it '
2496 'until the operation is completed, or timeout')
2498 def vim_delete(ctx
, name
, force
, wait
):
2499 """deletes a VIM account
2501 NAME: name or ID of the VIM account to be deleted
2506 ctx
.obj
.vim
.delete(name
, wait
=wait
)
2508 check_client_version(ctx
.obj
, '--force')
2509 ctx
.obj
.vim
.delete(name
, force
, wait
=wait
)
2510 # except ClientException as e:
2515 @cli_osm.command(name
='vim-list', short_help
='list all VIM accounts')
2516 #@click.option('--ro_update/--no_ro_update',
2518 # help='update list from RO')
2519 @click.option('--filter', default
=None,
2520 help='restricts the list to the VIM accounts matching the filter')
2521 @click.option('--long', is_flag
=True,
2522 help='get more details of the NS (project, vim, deployment status, configuration status.')
2524 def vim_list(ctx
, filter, long):
2525 """list all VIM accounts"""
2528 check_client_version(ctx
.obj
, '--filter')
2530 # check_client_version(ctx.obj, '--ro_update', 'v1')
2531 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
2532 if fullclassname
== 'osmclient.sol005.client.Client':
2533 resp
= ctx
.obj
.vim
.list(filter)
2535 # resp = ctx.obj.vim.list(ro_update)
2537 table
= PrettyTable(['vim name', 'uuid', 'project', 'operational state', 'error details'])
2539 table
= PrettyTable(['vim name', 'uuid'])
2542 vim_details
= ctx
.obj
.vim
.get(vim
['uuid'])
2543 if 'vim_password' in vim_details
:
2544 vim_details
['vim_password']='********'
2545 logger
.debug('VIM details: {}'.format(yaml
.safe_dump(vim_details
)))
2546 vim_state
= vim_details
['_admin'].get('operationalState', '-')
2547 error_details
= 'N/A'
2548 if vim_state
== 'ERROR':
2549 error_details
= vim_details
['_admin'].get('detailed-status', 'Not found')
2550 project_list
= ctx
.obj
.project
.list()
2551 vim_project_list
= vim_details
.get('_admin').get('projects_read')
2553 project_name
= 'None'
2554 if vim_project_list
:
2555 project_id
= vim_project_list
[0]
2556 for p
in project_list
:
2557 if p
['_id'] == project_id
:
2558 project_name
= p
['name']
2560 table
.add_row([vim
['name'], vim
['uuid'], '{} ({})'.format(project_name
, project_id
),
2561 vim_state
, wrap_text(text
=error_details
, width
=80)])
2563 table
.add_row([vim
['name'], vim
['uuid']])
2568 @cli_osm.command(name
='vim-show', short_help
='shows the details of a VIM account')
2569 @click.argument('name')
2571 def vim_show(ctx
, name
):
2572 """shows the details of a VIM account
2574 NAME: name or ID of the VIM account
2578 resp
= ctx
.obj
.vim
.get(name
)
2579 if 'vim_password' in resp
:
2580 resp
['vim_password']='********'
2581 # except ClientException as e:
2585 table
= PrettyTable(['key', 'attribute'])
2586 for k
, v
in list(resp
.items()):
2587 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2592 ####################
2594 ####################
2596 @cli_osm.command(name
='wim-create', short_help
='creates a new WIM account')
2597 @click.option('--name',
2599 help='Name for the WIM account')
2600 @click.option('--user',
2601 help='WIM username')
2602 @click.option('--password',
2603 help='WIM password')
2604 @click.option('--url',
2607 # @click.option('--tenant',
2608 # help='wIM tenant name')
2609 @click.option('--config',
2611 help='WIM specific config parameters')
2612 @click.option('--wim_type',
2614 @click.option('--description',
2616 help='human readable description')
2617 @click.option('--wim_port_mapping', default
=None,
2618 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2619 "(WAN service endpoint id and info)")
2620 @click.option('--wait',
2624 help='do not return the control immediately, but keep it '
2625 'until the operation is completed, or timeout')
2638 """creates a new WIM account"""
2641 check_client_version(ctx
.obj
, ctx
.command
.name
)
2642 # if sdn_controller:
2643 # check_client_version(ctx.obj, '--sdn_controller')
2644 # if sdn_port_mapping:
2645 # check_client_version(ctx.obj, '--sdn_port_mapping')
2647 if user
: wim
['user'] = user
2648 if password
: wim
['password'] = password
2649 if url
: wim
['wim_url'] = url
2650 # if tenant: wim['tenant'] = tenant
2651 wim
['wim_type'] = wim_type
2652 if description
: wim
['description'] = description
2653 if config
: wim
['config'] = config
2654 ctx
.obj
.wim
.create(name
, wim
, wim_port_mapping
, wait
=wait
)
2655 # except ClientException as e:
2660 @cli_osm.command(name
='wim-update', short_help
='updates a WIM account')
2661 @click.argument('name')
2662 @click.option('--newname', help='New name for the WIM account')
2663 @click.option('--user', help='WIM username')
2664 @click.option('--password', help='WIM password')
2665 @click.option('--url', help='WIM url')
2666 @click.option('--config', help='WIM specific config parameters')
2667 @click.option('--wim_type', help='WIM type')
2668 @click.option('--description', help='human readable description')
2669 @click.option('--wim_port_mapping', default
=None,
2670 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2671 "(WAN service endpoint id and info)")
2672 @click.option('--wait',
2676 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2689 """updates a WIM account
2691 NAME: name or ID of the WIM account
2695 check_client_version(ctx
.obj
, ctx
.command
.name
)
2697 if newname
: wim
['name'] = newname
2698 if user
: wim
['user'] = user
2699 if password
: wim
['password'] = password
2700 if url
: wim
['url'] = url
2701 # if tenant: wim['tenant'] = tenant
2702 if wim_type
: wim
['wim_type'] = wim_type
2703 if description
: wim
['description'] = description
2704 if config
: wim
['config'] = config
2705 ctx
.obj
.wim
.update(name
, wim
, wim_port_mapping
, wait
=wait
)
2706 # except ClientException as e:
2711 @cli_osm.command(name
='wim-delete', short_help
='deletes a WIM account')
2712 @click.argument('name')
2713 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2714 @click.option('--wait',
2718 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2720 def wim_delete(ctx
, name
, force
, wait
):
2721 """deletes a WIM account
2723 NAME: name or ID of the WIM account to be deleted
2727 check_client_version(ctx
.obj
, ctx
.command
.name
)
2728 ctx
.obj
.wim
.delete(name
, force
, wait
=wait
)
2729 # except ClientException as e:
2734 @cli_osm.command(name
='wim-list', short_help
='list all WIM accounts')
2735 @click.option('--filter', default
=None,
2736 help='restricts the list to the WIM accounts matching the filter')
2738 def wim_list(ctx
, filter):
2739 """list all WIM accounts"""
2742 check_client_version(ctx
.obj
, ctx
.command
.name
)
2743 resp
= ctx
.obj
.wim
.list(filter)
2744 table
= PrettyTable(['wim name', 'uuid'])
2746 table
.add_row([wim
['name'], wim
['uuid']])
2749 # except ClientException as e:
2754 @cli_osm.command(name
='wim-show', short_help
='shows the details of a WIM account')
2755 @click.argument('name')
2757 def wim_show(ctx
, name
):
2758 """shows the details of a WIM account
2760 NAME: name or ID of the WIM account
2764 check_client_version(ctx
.obj
, ctx
.command
.name
)
2765 resp
= ctx
.obj
.wim
.get(name
)
2766 if 'password' in resp
:
2767 resp
['wim_password']='********'
2768 # except ClientException as e:
2772 table
= PrettyTable(['key', 'attribute'])
2773 for k
, v
in list(resp
.items()):
2774 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2779 ####################
2780 # SDN controller operations
2781 ####################
2783 @cli_osm.command(name
='sdnc-create', short_help
='creates a new SDN controller')
2784 @click.option('--name',
2786 help='Name to create sdn controller')
2787 @click.option('--type',
2789 help='SDN controller type')
2790 @click.option('--sdn_controller_version', # hidden=True,
2791 help='Deprecated. Use --config {version: sdn_controller_version}')
2792 @click.option('--url',
2793 help='URL in format http[s]://HOST:IP/')
2794 @click.option('--ip_address', # hidden=True,
2795 help='Deprecated. Use --url')
2796 @click.option('--port', # hidden=True,
2797 help='Deprecated. Use --url')
2798 @click.option('--switch_dpid', # hidden=True,
2799 help='Deprecated. Use --config {switch_id: DPID}')
2800 @click.option('--config',
2801 help='Extra information for SDN in yaml format, as {switch_id: identity used for the plugin (e.g. DPID: '
2802 'Openflow Datapath ID), version: version}')
2803 @click.option('--user',
2804 help='SDN controller username')
2805 @click.option('--password',
2807 confirmation_prompt
=True,
2808 help='SDN controller password')
2809 @click.option('--description', default
=None, help='human readable description')
2810 @click.option('--wait',
2814 help="do not return the control immediately, but keep it until the operation is completed, or timeout")
2816 def sdnc_create(ctx
, **kwargs
):
2817 """creates a new SDN controller"""
2819 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2820 x
not in ("wait", "ip_address", "port", "switch_dpid")}
2821 if kwargs
.get("port"):
2822 print("option '--port' is deprecated, use '--url' instead")
2823 sdncontroller
["port"] = int(kwargs
["port"])
2824 if kwargs
.get("ip_address"):
2825 print("option '--ip_address' is deprecated, use '--url' instead")
2826 sdncontroller
["ip"] = kwargs
["ip_address"]
2827 if kwargs
.get("switch_dpid"):
2828 print("option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead")
2829 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2830 if kwargs
.get("sdn_controller_version"):
2831 print("option '--sdn_controller_version' is deprecated, use '--config={version: SDN_CONTROLLER_VERSION}'"
2834 check_client_version(ctx
.obj
, ctx
.command
.name
)
2835 ctx
.obj
.sdnc
.create(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2836 # except ClientException as e:
2840 @cli_osm.command(name
='sdnc-update', short_help
='updates an SDN controller')
2841 @click.argument('name')
2842 @click.option('--newname', help='New name for the SDN controller')
2843 @click.option('--description', default
=None, help='human readable description')
2844 @click.option('--type', help='SDN controller type')
2845 @click.option('--url', help='URL in format http[s]://HOST:IP/')
2846 @click.option('--config', help='Extra information for SDN in yaml format, as '
2847 '{switch_id: identity used for the plugin (e.g. DPID: '
2848 'Openflow Datapath ID), version: version}')
2849 @click.option('--user', help='SDN controller username')
2850 @click.option('--password', help='SDN controller password')
2851 @click.option('--ip_address', help='Deprecated. Use --url') # hidden=True
2852 @click.option('--port', help='Deprecated. Use --url') # hidden=True
2853 @click.option('--switch_dpid', help='Deprecated. Use --config {switch_dpid: DPID}') # hidden=True
2854 @click.option('--sdn_controller_version', help='Deprecated. Use --config {version: VERSION}') # hidden=True
2855 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2856 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2858 def sdnc_update(ctx
, **kwargs
):
2859 """updates an SDN controller
2861 NAME: name or ID of the SDN controller
2864 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2865 x
not in ("wait", "ip_address", "port", "switch_dpid", "new_name")}
2866 if kwargs
.get("newname"):
2867 sdncontroller
["name"] = kwargs
["newname"]
2868 if kwargs
.get("port"):
2869 print("option '--port' is deprecated, use '--url' instead")
2870 sdncontroller
["port"] = int(kwargs
["port"])
2871 if kwargs
.get("ip_address"):
2872 print("option '--ip_address' is deprecated, use '--url' instead")
2873 sdncontroller
["ip"] = kwargs
["ip_address"]
2874 if kwargs
.get("switch_dpid"):
2875 print("option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead")
2876 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2877 if kwargs
.get("sdn_controller_version"):
2878 print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'"
2882 check_client_version(ctx
.obj
, ctx
.command
.name
)
2883 ctx
.obj
.sdnc
.update(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2884 # except ClientException as e:
2889 @cli_osm.command(name
='sdnc-delete', short_help
='deletes an SDN controller')
2890 @click.argument('name')
2891 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2892 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2893 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2895 def sdnc_delete(ctx
, name
, force
, wait
):
2896 """deletes an SDN controller
2898 NAME: name or ID of the SDN controller to be deleted
2902 check_client_version(ctx
.obj
, ctx
.command
.name
)
2903 ctx
.obj
.sdnc
.delete(name
, force
, wait
=wait
)
2904 # except ClientException as e:
2909 @cli_osm.command(name
='sdnc-list', short_help
='list all SDN controllers')
2910 @click.option('--filter', default
=None,
2911 help="restricts the list to the SDN controllers matching the filter with format: 'k[.k..]=v[&k[.k]=v2]'")
2913 def sdnc_list(ctx
, filter):
2914 """list all SDN controllers"""
2917 check_client_version(ctx
.obj
, ctx
.command
.name
)
2918 resp
= ctx
.obj
.sdnc
.list(filter)
2919 # except ClientException as e:
2922 table
= PrettyTable(['sdnc name', 'id'])
2924 table
.add_row([sdnc
['name'], sdnc
['_id']])
2929 @cli_osm.command(name
='sdnc-show', short_help
='shows the details of an SDN controller')
2930 @click.argument('name')
2932 def sdnc_show(ctx
, name
):
2933 """shows the details of an SDN controller
2935 NAME: name or ID of the SDN controller
2939 check_client_version(ctx
.obj
, ctx
.command
.name
)
2940 resp
= ctx
.obj
.sdnc
.get(name
)
2941 # except ClientException as e:
2945 table
= PrettyTable(['key', 'attribute'])
2946 for k
, v
in list(resp
.items()):
2947 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2952 ###########################
2953 # K8s cluster operations
2954 ###########################
2956 @cli_osm.command(name
='k8scluster-add', short_help
='adds a K8s cluster to OSM')
2957 @click.argument('name')
2958 @click.option('--creds',
2960 help='credentials file, i.e. a valid `.kube/config` file')
2961 @click.option('--version',
2963 help='Kubernetes version')
2964 @click.option('--vim',
2966 help='VIM target, the VIM where the cluster resides')
2967 @click.option('--k8s-nets',
2969 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) ...]}"')
2970 @click.option('--description',
2972 help='human readable description')
2973 @click.option('--namespace',
2974 default
='kube-system',
2975 help='namespace to be used for its operation, defaults to `kube-system`')
2976 @click.option('--cni',
2978 help='list of CNI plugins, in JSON inline format, used in the cluster')
2979 #@click.option('--skip-init',
2981 # help='If set, K8s cluster is assumed to be ready for its use with OSM')
2982 #@click.option('--wait',
2984 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2986 def k8scluster_add(ctx
,
2995 """adds a K8s cluster to OSM
2997 NAME: name of the K8s cluster
3000 check_client_version(ctx
.obj
, ctx
.command
.name
)
3002 cluster
['name'] = name
3003 with
open(creds
, 'r') as cf
:
3004 cluster
['credentials'] = yaml
.safe_load(cf
.read())
3005 cluster
['k8s_version'] = version
3006 cluster
['vim_account'] = vim
3007 cluster
['nets'] = yaml
.safe_load(k8s_nets
)
3009 cluster
['description'] = description
3010 if namespace
: cluster
['namespace'] = namespace
3011 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
3012 ctx
.obj
.k8scluster
.create(name
, cluster
)
3013 # except ClientException as e:
3018 @cli_osm.command(name
='k8scluster-update', short_help
='updates a K8s cluster')
3019 @click.argument('name')
3020 @click.option('--newname', help='New name for the K8s cluster')
3021 @click.option('--creds', help='credentials file, i.e. a valid `.kube/config` file')
3022 @click.option('--version', help='Kubernetes version')
3023 @click.option('--vim', help='VIM target, the VIM where the cluster resides')
3024 @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) ...]}"')
3025 @click.option('--description', help='human readable description')
3026 @click.option('--namespace', help='namespace to be used for its operation, defaults to `kube-system`')
3027 @click.option('--cni', help='list of CNI plugins, in JSON inline format, used in the cluster')
3029 def k8scluster_update(ctx
,
3039 """updates a K8s cluster
3041 NAME: name or ID of the K8s cluster
3044 check_client_version(ctx
.obj
, ctx
.command
.name
)
3046 if newname
: cluster
['name'] = newname
3048 with
open(creds
, 'r') as cf
:
3049 cluster
['credentials'] = yaml
.safe_load(cf
.read())
3050 if version
: cluster
['k8s_version'] = version
3051 if vim
: cluster
['vim_account'] = vim
3052 if k8s_nets
: cluster
['nets'] = yaml
.safe_load(k8s_nets
)
3053 if description
: cluster
['description'] = description
3054 if namespace
: cluster
['namespace'] = namespace
3055 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
3056 ctx
.obj
.k8scluster
.update(name
, cluster
)
3057 # except ClientException as e:
3062 @cli_osm.command(name
='k8scluster-delete', short_help
='deletes a K8s cluster')
3063 @click.argument('name')
3064 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
3065 #@click.option('--wait',
3067 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3069 def k8scluster_delete(ctx
, name
, force
):
3070 """deletes a K8s cluster
3072 NAME: name or ID of the K8s cluster to be deleted
3075 check_client_version(ctx
.obj
, ctx
.command
.name
)
3076 ctx
.obj
.k8scluster
.delete(name
, force
=force
)
3077 # except ClientException as e:
3082 @cli_osm.command(name
='k8scluster-list')
3083 @click.option('--filter', default
=None,
3084 help='restricts the list to the K8s clusters matching the filter')
3085 @click.option('--literal', is_flag
=True,
3086 help='print literally, no pretty table')
3088 def k8scluster_list(ctx
, filter, literal
):
3089 """list all K8s clusters"""
3091 check_client_version(ctx
.obj
, ctx
.command
.name
)
3092 resp
= ctx
.obj
.k8scluster
.list(filter)
3094 print(yaml
.safe_dump(resp
))
3096 table
= PrettyTable(['Name', 'Id', 'Version', 'VIM', 'K8s-nets', 'Operational State', 'Description'])
3097 for cluster
in resp
:
3098 table
.add_row([cluster
['name'], cluster
['_id'], cluster
['k8s_version'], cluster
['vim_account'],
3099 json
.dumps(cluster
['nets']), cluster
["_admin"]["operationalState"],
3100 trunc_text(cluster
.get('description') or '', 40)])
3103 # except ClientException as e:
3108 @cli_osm.command(name
='k8scluster-show', short_help
='shows the details of a K8s cluster')
3109 @click.argument('name')
3110 @click.option('--literal', is_flag
=True,
3111 help='print literally, no pretty table')
3113 def k8scluster_show(ctx
, name
, literal
):
3114 """shows the details of a K8s cluster
3116 NAME: name or ID of the K8s cluster
3119 resp
= ctx
.obj
.k8scluster
.get(name
)
3121 print(yaml
.safe_dump(resp
))
3123 table
= PrettyTable(['key', 'attribute'])
3124 for k
, v
in list(resp
.items()):
3125 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
3128 # except ClientException as e:
3134 ###########################
3136 ###########################
3138 @cli_osm.command(name
='repo-add', short_help
='adds a repo to OSM')
3139 @click.argument('name')
3140 @click.argument('uri')
3141 @click.option('--type',
3142 type=click
.Choice(['helm-chart', 'juju-bundle', 'osm']),
3144 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles, osm for OSM Repositories)')
3145 @click.option('--description',
3147 help='human readable description')
3148 @click.option('--user',
3150 help='OSM repository: The username of the OSM repository')
3151 @click.option('--password',
3153 help='OSM repository: The password of the OSM repository')
3154 #@click.option('--wait',
3156 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3158 def repo_add(ctx
, **kwargs
):
3159 """adds a repo to OSM
3161 NAME: name of the repo
3162 URI: URI of the repo
3165 kwargs
= {k
: v
for k
, v
in kwargs
.items() if v
is not None}
3167 repo
["url"] = repo
.pop("uri")
3168 if repo
["type"] in ['helm-chart', 'juju-bundle']:
3169 ctx
.obj
.repo
.create(repo
['name'], repo
)
3171 ctx
.obj
.osmrepo
.create(repo
['name'], repo
)
3172 # except ClientException as e:
3177 @cli_osm.command(name
='repo-update', short_help
='updates a repo in OSM')
3178 @click.argument('name')
3179 @click.option('--newname', help='New name for the repo')
3180 @click.option('--uri', help='URI of the repo')
3181 @click.option('--description', help='human readable description')
3182 #@click.option('--wait',
3184 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3186 def repo_update(ctx
,
3191 """updates a repo in OSM
3193 NAME: name of the repo
3196 check_client_version(ctx
.obj
, ctx
.command
.name
)
3199 repo
['name'] = newname
3202 if description
: repo
['description'] = description
3204 ctx
.obj
.repo
.update(name
, repo
)
3206 ctx
.obj
.osmrepo
.update(name
, repo
)
3208 # except ClientException as e:
3213 @cli_osm.command(name
='repo-index', short_help
='Index a repository from a folder with artifacts')
3214 @click.option('--origin', default
='.', help='origin path where the artifacts are located')
3215 @click.option('--destination', default
='.', help='destination path where the index is deployed')
3217 def repo_index(ctx
, origin
, destination
):
3218 """Index a repository
3220 NAME: name or ID of the repo to be deleted
3222 check_client_version(ctx
.obj
, ctx
.command
.name
)
3223 ctx
.obj
.osmrepo
.repo_index(origin
, destination
)
3226 @cli_osm.command(name
='repo-delete', short_help
='deletes a repo')
3227 @click.argument('name')
3228 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
3229 #@click.option('--wait',
3231 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3233 def repo_delete(ctx
, name
, force
):
3236 NAME: name or ID of the repo to be deleted
3240 ctx
.obj
.repo
.delete(name
, force
=force
)
3242 ctx
.obj
.osmrepo
.delete(name
, force
=force
)
3243 # except ClientException as e:
3248 @cli_osm.command(name
='repo-list')
3249 @click.option('--filter', default
=None,
3250 help='restricts the list to the repos matching the filter')
3251 @click.option('--literal', is_flag
=True,
3252 help='print literally, no pretty table')
3254 def repo_list(ctx
, filter, literal
):
3255 """list all repos"""
3258 check_client_version(ctx
.obj
, ctx
.command
.name
)
3259 resp
= ctx
.obj
.repo
.list(filter)
3260 resp
+= ctx
.obj
.osmrepo
.list(filter)
3262 print(yaml
.safe_dump(resp
))
3264 table
= PrettyTable(['Name', 'Id', 'Type', 'URI', 'Description'])
3266 #cluster['k8s-nets'] = json.dumps(yaml.safe_load(cluster['k8s-nets']))
3267 table
.add_row([repo
['name'], repo
['_id'], repo
['type'], repo
['url'], trunc_text(repo
.get('description') or '',40)])
3271 # except ClientException as e:
3276 @cli_osm.command(name
='repo-show', short_help
='shows the details of a repo')
3277 @click.argument('name')
3278 @click.option('--literal', is_flag
=True,
3279 help='print literally, no pretty table')
3281 def repo_show(ctx
, name
, literal
):
3282 """shows the details of a repo
3284 NAME: name or ID of the repo
3287 resp
= ctx
.obj
.repo
.get(name
)
3289 resp
= ctx
.obj
.osmrepo
.get(name
)
3293 print(yaml
.safe_dump(resp
))
3295 table
= PrettyTable(['key', 'attribute'])
3297 for k
, v
in list(resp
.items()):
3298 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3302 # except ClientException as e:
3308 ####################
3309 # Project mgmt operations
3310 ####################
3312 @cli_osm.command(name
='project-create', short_help
='creates a new project')
3313 @click.argument('name')
3314 #@click.option('--description',
3315 # default='no description',
3316 # help='human readable description')
3317 @click.option('--domain-name', 'domain_name',
3319 help='assign to a domain')
3321 def project_create(ctx
, name
, domain_name
):
3322 """Creates a new project
3324 NAME: name of the project
3325 DOMAIN_NAME: optional domain name for the project when keystone authentication is used
3329 project
['name'] = name
3331 project
['domain_name'] = domain_name
3333 check_client_version(ctx
.obj
, ctx
.command
.name
)
3334 ctx
.obj
.project
.create(name
, project
)
3335 # except ClientException as e:
3340 @cli_osm.command(name
='project-delete', short_help
='deletes a project')
3341 @click.argument('name')
3342 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3344 def project_delete(ctx
, name
):
3345 """deletes a project
3347 NAME: name or ID of the project to be deleted
3351 check_client_version(ctx
.obj
, ctx
.command
.name
)
3352 ctx
.obj
.project
.delete(name
)
3353 # except ClientException as e:
3358 @cli_osm.command(name
='project-list', short_help
='list all projects')
3359 @click.option('--filter', default
=None,
3360 help='restricts the list to the projects matching the filter')
3362 def project_list(ctx
, filter):
3363 """list all projects"""
3366 check_client_version(ctx
.obj
, ctx
.command
.name
)
3367 resp
= ctx
.obj
.project
.list(filter)
3368 # except ClientException as e:
3371 table
= PrettyTable(['name', 'id'])
3373 table
.add_row([proj
['name'], proj
['_id']])
3378 @cli_osm.command(name
='project-show', short_help
='shows the details of a project')
3379 @click.argument('name')
3381 def project_show(ctx
, name
):
3382 """shows the details of a project
3384 NAME: name or ID of the project
3388 check_client_version(ctx
.obj
, ctx
.command
.name
)
3389 resp
= ctx
.obj
.project
.get(name
)
3390 # except ClientException as e:
3394 table
= PrettyTable(['key', 'attribute'])
3395 for k
, v
in resp
.items():
3396 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3401 @cli_osm.command(name
='project-update', short_help
='updates a project (only the name can be updated)')
3402 @click.argument('project')
3403 @click.option('--name',
3405 help='new name for the project')
3408 def project_update(ctx
, project
, name
):
3410 Update a project name
3413 :param project: id or name of the project to modify
3414 :param name: new name for the project
3418 project_changes
= {}
3419 project_changes
['name'] = name
3422 check_client_version(ctx
.obj
, ctx
.command
.name
)
3423 ctx
.obj
.project
.update(project
, project_changes
)
3424 # except ClientException as e:
3428 ####################
3429 # User mgmt operations
3430 ####################
3432 @cli_osm.command(name
='user-create', short_help
='creates a new user')
3433 @click.argument('username')
3434 @click.option('--password',
3437 confirmation_prompt
=True,
3438 help='user password')
3439 @click.option('--projects',
3440 # prompt="Comma separate list of projects",
3442 callback
=lambda ctx
, param
, value
: ''.join(value
).split(',') if all(len(x
)==1 for x
in value
) else value
,
3443 help='list of project ids that the user belongs to')
3444 @click.option('--project-role-mappings', 'project_role_mappings',
3445 default
=None, multiple
=True,
3446 help="assign role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3447 @click.option('--domain-name', 'domain_name',
3449 help='assign to a domain')
3451 def user_create(ctx
, username
, password
, projects
, project_role_mappings
, domain_name
):
3452 """Creates a new user
3455 USERNAME: name of the user
3456 PASSWORD: password of the user
3457 PROJECTS: projects assigned to user (internal only)
3458 PROJECT_ROLE_MAPPING: roles in projects assigned to user (keystone)
3459 DOMAIN_NAME: optional domain name for the user when keystone authentication is used
3463 user
['username'] = username
3464 user
['password'] = password
3465 user
['projects'] = projects
3466 user
['project_role_mappings'] = project_role_mappings
3468 user
['domain_name'] = domain_name
3471 check_client_version(ctx
.obj
, ctx
.command
.name
)
3472 ctx
.obj
.user
.create(username
, user
)
3473 # except ClientException as e:
3478 @cli_osm.command(name
='user-update', short_help
='updates user information')
3479 @click.argument('username')
3480 @click.option('--password',
3483 # confirmation_prompt=True,
3484 help='user password')
3485 @click.option('--set-username', 'set_username',
3487 help='change username')
3488 @click.option('--set-project', 'set_project',
3489 default
=None, multiple
=True,
3490 help="create/replace the roles for this project: 'project,role1[,role2,...]'")
3491 @click.option('--remove-project', 'remove_project',
3492 default
=None, multiple
=True,
3493 help="removes project from user: 'project'")
3494 @click.option('--add-project-role', 'add_project_role',
3495 default
=None, multiple
=True,
3496 help="assign role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3497 @click.option('--remove-project-role', 'remove_project_role',
3498 default
=None, multiple
=True,
3499 help="remove role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3501 def user_update(ctx
, username
, password
, set_username
, set_project
, remove_project
,
3502 add_project_role
, remove_project_role
):
3503 """Update a user information
3506 USERNAME: name of the user
3507 PASSWORD: new password
3508 SET_USERNAME: new username
3509 SET_PROJECT: creating mappings for project/role(s)
3510 REMOVE_PROJECT: deleting mappings for project/role(s)
3511 ADD_PROJECT_ROLE: adding mappings for project/role(s)
3512 REMOVE_PROJECT_ROLE: removing mappings for project/role(s)
3516 user
['password'] = password
3517 user
['username'] = set_username
3518 user
['set-project'] = set_project
3519 user
['remove-project'] = remove_project
3520 user
['add-project-role'] = add_project_role
3521 user
['remove-project-role'] = remove_project_role
3524 check_client_version(ctx
.obj
, ctx
.command
.name
)
3525 ctx
.obj
.user
.update(username
, user
)
3526 # except ClientException as e:
3531 @cli_osm.command(name
='user-delete', short_help
='deletes a user')
3532 @click.argument('name')
3533 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3535 def user_delete(ctx
, name
):
3539 NAME: name or ID of the user to be deleted
3543 check_client_version(ctx
.obj
, ctx
.command
.name
)
3544 ctx
.obj
.user
.delete(name
)
3545 # except ClientException as e:
3550 @cli_osm.command(name
='user-list', short_help
='list all users')
3551 @click.option('--filter', default
=None,
3552 help='restricts the list to the users matching the filter')
3554 def user_list(ctx
, filter):
3555 """list all users"""
3557 check_client_version(ctx
.obj
, ctx
.command
.name
)
3558 resp
= ctx
.obj
.user
.list(filter)
3559 # except ClientException as e:
3562 table
= PrettyTable(['name', 'id'])
3564 table
.add_row([user
['username'], user
['_id']])
3569 @cli_osm.command(name
='user-show', short_help
='shows the details of a user')
3570 @click.argument('name')
3572 def user_show(ctx
, name
):
3573 """shows the details of a user
3575 NAME: name or ID of the user
3579 check_client_version(ctx
.obj
, ctx
.command
.name
)
3580 resp
= ctx
.obj
.user
.get(name
)
3581 if 'password' in resp
:
3582 resp
['password']='********'
3583 # except ClientException as e:
3587 table
= PrettyTable(['key', 'attribute'])
3588 for k
, v
in resp
.items():
3589 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3594 ####################
3595 # Fault Management operations
3596 ####################
3598 @cli_osm.command(name
='ns-alarm-create')
3599 @click.argument('name')
3600 @click.option('--ns', prompt
=True, help='NS instance id or name')
3601 @click.option('--vnf', prompt
=True,
3602 help='VNF name (VNF member index as declared in the NSD)')
3603 @click.option('--vdu', prompt
=True,
3604 help='VDU name (VDU name as declared in the VNFD)')
3605 @click.option('--metric', prompt
=True,
3606 help='Name of the metric (e.g. cpu_utilization)')
3607 @click.option('--severity', default
='WARNING',
3608 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
3609 @click.option('--threshold_value', prompt
=True,
3610 help='threshold value that, when crossed, an alarm is triggered')
3611 @click.option('--threshold_operator', prompt
=True,
3612 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
3613 @click.option('--statistic', default
='AVERAGE',
3614 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
3616 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
3617 threshold_value
, threshold_operator
, statistic
):
3618 """creates a new alarm for a NS instance"""
3619 # TODO: Check how to validate threshold_value.
3620 # Should it be an integer (1-100), percentage, or decimal (0.01-1.00)?
3623 ns_instance
= ctx
.obj
.ns
.get(ns
)
3625 alarm
['alarm_name'] = name
3626 alarm
['ns_id'] = ns_instance
['_id']
3627 alarm
['correlation_id'] = ns_instance
['_id']
3628 alarm
['vnf_member_index'] = vnf
3629 alarm
['vdu_name'] = vdu
3630 alarm
['metric_name'] = metric
3631 alarm
['severity'] = severity
3632 alarm
['threshold_value'] = int(threshold_value
)
3633 alarm
['operation'] = threshold_operator
3634 alarm
['statistic'] = statistic
3635 check_client_version(ctx
.obj
, ctx
.command
.name
)
3636 ctx
.obj
.ns
.create_alarm(alarm
)
3637 # except ClientException as e:
3642 #@cli_osm.command(name='ns-alarm-delete')
3643 #@click.argument('name')
3644 #@click.pass_context
3645 #def ns_alarm_delete(ctx, name):
3646 # """deletes an alarm
3648 # NAME: name of the alarm to be deleted
3651 # check_client_version(ctx.obj, ctx.command.name)
3652 # ctx.obj.ns.delete_alarm(name)
3653 # except ClientException as e:
3658 ####################
3659 # Performance Management operations
3660 ####################
3662 @cli_osm.command(name
='ns-metric-export', short_help
='exports a metric to the internal OSM bus, which can be read by other apps')
3663 @click.option('--ns', prompt
=True, help='NS instance id or name')
3664 @click.option('--vnf', prompt
=True,
3665 help='VNF name (VNF member index as declared in the NSD)')
3666 @click.option('--vdu', prompt
=True,
3667 help='VDU name (VDU name as declared in the VNFD)')
3668 @click.option('--metric', prompt
=True,
3669 help='name of the metric (e.g. cpu_utilization)')
3670 #@click.option('--period', default='1w',
3671 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
3672 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
3674 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
3675 """exports a metric to the internal OSM bus, which can be read by other apps"""
3676 # TODO: Check how to validate interval.
3677 # Should it be an integer (seconds), or should a suffix (s,m,h,d,w) also be permitted?
3680 ns_instance
= ctx
.obj
.ns
.get(ns
)
3682 metric_data
['ns_id'] = ns_instance
['_id']
3683 metric_data
['correlation_id'] = ns_instance
['_id']
3684 metric_data
['vnf_member_index'] = vnf
3685 metric_data
['vdu_name'] = vdu
3686 metric_data
['metric_name'] = metric
3687 metric_data
['collection_unit'] = 'WEEK'
3688 metric_data
['collection_period'] = 1
3689 check_client_version(ctx
.obj
, ctx
.command
.name
)
3691 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
3695 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
3696 time
.sleep(int(interval
))
3698 # except ClientException as e:
3703 ####################
3705 ####################
3707 @cli_osm.command(name
='version', short_help
='shows client and server versions')
3709 def get_version(ctx
):
3710 """shows client and server versions"""
3712 check_client_version(ctx
.obj
, "version")
3713 print ("Server version: {}".format(ctx
.obj
.get_version()))
3714 print ("Client version: {}".format(pkg_resources
.get_distribution("osmclient").version
))
3715 # except ClientException as e:
3719 @cli_osm.command(name
='upload-package', short_help
='uploads a VNF package or NS package')
3720 @click.argument('filename')
3721 @click.option('--skip-charm-build', default
=False, is_flag
=True,
3722 help='the charm will not be compiled, it is assumed to already exist')
3724 def upload_package(ctx
, filename
, skip_charm_build
):
3725 """uploads a vnf package or ns package
3727 filename: vnf or ns package folder, or vnf or ns package file (tar.gz)
3731 ctx
.obj
.package
.upload(filename
, skip_charm_build
=skip_charm_build
)
3732 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
3733 if fullclassname
!= 'osmclient.sol005.client.Client':
3734 ctx
.obj
.package
.wait_for_upload(filename
)
3735 # except ClientException as e:
3740 #@cli_osm.command(name='ns-scaling-show')
3741 #@click.argument('ns_name')
3742 #@click.pass_context
3743 #def show_ns_scaling(ctx, ns_name):
3744 # """shows the status of a NS scaling operation
3746 # NS_NAME: name of the NS instance being scaled
3749 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3750 # resp = ctx.obj.ns.list()
3751 # except ClientException as e:
3755 # table = PrettyTable(
3758 # 'operational status',
3763 # if ns_name == ns['name']:
3764 # nsopdata = ctx.obj.ns.get_opdata(ns['id'])
3765 # scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
3766 # for record in scaling_records:
3767 # if 'instance' in record:
3768 # instances = record['instance']
3769 # for inst in instances:
3771 # [record['scaling-group-name-ref'],
3772 # inst['instance-id'],
3773 # inst['op-status'],
3774 # time.strftime('%Y-%m-%d %H:%M:%S',
3776 # inst['create-time'])),
3782 #@cli_osm.command(name='ns-scale')
3783 #@click.argument('ns_name')
3784 #@click.option('--ns_scale_group', prompt=True)
3785 #@click.option('--index', prompt=True)
3786 #@click.option('--wait',
3790 # help='do not return the control immediately, but keep it \
3791 # until the operation is completed, or timeout')
3792 #@click.pass_context
3793 #def ns_scale(ctx, ns_name, ns_scale_group, index, wait):
3796 # NS_NAME: name of the NS instance to be scaled
3799 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3800 # ctx.obj.ns.scale(ns_name, ns_scale_group, index, wait=wait)
3801 # except ClientException as e:
3806 #@cli_osm.command(name='config-agent-list')
3807 #@click.pass_context
3808 #def config_agent_list(ctx):
3809 # """list config agents"""
3811 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3812 # except ClientException as e:
3815 # table = PrettyTable(['name', 'account-type', 'details'])
3816 # for account in ctx.obj.vca.list():
3819 # account['account-type'],
3825 #@cli_osm.command(name='config-agent-delete')
3826 #@click.argument('name')
3827 #@click.pass_context
3828 #def config_agent_delete(ctx, name):
3829 # """deletes a config agent
3831 # NAME: name of the config agent to be deleted
3834 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3835 # ctx.obj.vca.delete(name)
3836 # except ClientException as e:
3841 #@cli_osm.command(name='config-agent-add')
3842 #@click.option('--name',
3844 #@click.option('--account_type',
3846 #@click.option('--server',
3848 #@click.option('--user',
3850 #@click.option('--secret',
3853 # confirmation_prompt=True)
3854 #@click.pass_context
3855 #def config_agent_add(ctx, name, account_type, server, user, secret):
3856 # """adds a config agent"""
3858 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3859 # ctx.obj.vca.create(name, account_type, server, user, secret)
3860 # except ClientException as e:
3865 #@cli_osm.command(name='ro-dump')
3866 #@click.pass_context
3868 # """shows RO agent information"""
3869 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3870 # resp = ctx.obj.vim.get_resource_orchestrator()
3871 # table = PrettyTable(['key', 'attribute'])
3872 # for k, v in list(resp.items()):
3873 # table.add_row([k, json.dumps(v, indent=2)])
3878 #@cli_osm.command(name='vcs-list')
3879 #@click.pass_context
3881 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3882 # resp = ctx.obj.utils.get_vcs_info()
3883 # table = PrettyTable(['component name', 'state'])
3884 # for component in resp:
3885 # table.add_row([component['component_name'], component['state']])
3890 @cli_osm.command(name
='ns-action', short_help
='executes an action/primitive over a NS instance')
3891 @click.argument('ns_name')
3892 @click.option('--vnf_name', default
=None, help='member-vnf-index if the target is a vnf instead of a ns)')
3893 @click.option('--kdu_name', default
=None, help='kdu-name if the target is a kdu)')
3894 @click.option('--vdu_id', default
=None, help='vdu-id if the target is a vdu')
3895 @click.option('--vdu_count', default
=None, help='number of vdu instance of this vdu_id')
3896 @click.option('--action_name', prompt
=True, help='action name')
3897 @click.option('--params', default
=None, help='action params in YAML/JSON inline string')
3898 @click.option('--params_file', default
=None, help='YAML/JSON file with action params')
3899 @click.option('--timeout', required
=False, default
=None, type=int, help='timeout in seconds')
3900 @click.option('--wait',
3904 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3917 """executes an action/primitive over a NS instance
3919 NS_NAME: name or ID of the NS instance
3923 check_client_version(ctx
.obj
, ctx
.command
.name
)
3926 op_data
['member_vnf_index'] = vnf_name
3928 op_data
['kdu_name'] = kdu_name
3930 op_data
['vdu_id'] = vdu_id
3932 op_data
['vdu_count_index'] = vdu_count
3934 op_data
['timeout_ns_action'] = timeout
3935 op_data
['primitive'] = action_name
3937 with
open(params_file
, 'r') as pf
:
3940 op_data
['primitive_params'] = yaml
.safe_load(params
)
3942 op_data
['primitive_params'] = {}
3943 print(ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
, wait
=wait
))
3945 # except ClientException as e:
3950 @cli_osm.command(name
='vnf-scale', short_help
='executes a VNF scale (adding/removing VDUs)')
3951 @click.argument('ns_name')
3952 @click.argument('vnf_name')
3953 @click.option('--scaling-group', prompt
=True, help="scaling-group-descriptor name to use")
3954 @click.option('--scale-in', default
=False, is_flag
=True, help="performs a scale in operation")
3955 @click.option('--scale-out', default
=False, is_flag
=True, help="performs a scale out operation (by default)")
3956 @click.option('--timeout', required
=False, default
=None, type=int, help='timeout in seconds')
3957 @click.option('--wait', required
=False, default
=False, is_flag
=True,
3958 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3969 Executes a VNF scale (adding/removing VDUs)
3972 NS_NAME: name or ID of the NS instance.
3973 VNF_NAME: member-vnf-index in the NS to be scaled.
3977 check_client_version(ctx
.obj
, ctx
.command
.name
)
3978 if not scale_in
and not scale_out
:
3980 ctx
.obj
.ns
.scale_vnf(ns_name
, vnf_name
, scaling_group
, scale_in
, scale_out
, wait
, timeout
)
3981 # except ClientException as e:
3986 ##############################
3987 # Role Management Operations #
3988 ##############################
3990 @cli_osm.command(name
='role-create', short_help
='creates a new role')
3991 @click.argument('name')
3992 @click.option('--permissions',
3994 help='role permissions using a dictionary')
3996 def role_create(ctx
, name
, permissions
):
4001 NAME: Name or ID of the role.
4002 DEFINITION: Definition of grant/denial of access to resources.
4006 check_client_version(ctx
.obj
, ctx
.command
.name
)
4007 ctx
.obj
.role
.create(name
, permissions
)
4008 # except ClientException as e:
4013 @cli_osm.command(name
='role-update', short_help
='updates a role')
4014 @click.argument('name')
4015 @click.option('--set-name',
4017 help='change name of rle')
4018 # @click.option('--permissions',
4020 # help='provide a yaml format dictionary with incremental changes. Values can be bool or None to delete')
4021 @click.option('--add',
4023 help='yaml format dictionary with permission: True/False to access grant/denial')
4024 @click.option('--remove',
4026 help='yaml format list to remove a permission')
4028 def role_update(ctx
, name
, set_name
, add
, remove
):
4033 NAME: Name or ID of the role.
4034 DEFINITION: Definition overwrites the old definition.
4035 ADD: Grant/denial of access to resource to add.
4036 REMOVE: Grant/denial of access to resource to remove.
4040 check_client_version(ctx
.obj
, ctx
.command
.name
)
4041 ctx
.obj
.role
.update(name
, set_name
, None, add
, remove
)
4042 # except ClientException as e:
4047 @cli_osm.command(name
='role-delete', short_help
='deletes a role')
4048 @click.argument('name')
4049 # @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
4051 def role_delete(ctx
, name
):
4056 NAME: Name or ID of the role.
4060 check_client_version(ctx
.obj
, ctx
.command
.name
)
4061 ctx
.obj
.role
.delete(name
)
4062 # except ClientException as e:
4067 @cli_osm.command(name
='role-list', short_help
='list all roles')
4068 @click.option('--filter', default
=None,
4069 help='restricts the list to the projects matching the filter')
4071 def role_list(ctx
, filter):
4077 check_client_version(ctx
.obj
, ctx
.command
.name
)
4078 resp
= ctx
.obj
.role
.list(filter)
4079 # except ClientException as e:
4082 table
= PrettyTable(['name', 'id'])
4084 table
.add_row([role
['name'], role
['_id']])
4089 @cli_osm.command(name
='role-show', short_help
='show specific role')
4090 @click.argument('name')
4092 def role_show(ctx
, name
):
4094 Shows the details of a role.
4097 NAME: Name or ID of the role.
4101 check_client_version(ctx
.obj
, ctx
.command
.name
)
4102 resp
= ctx
.obj
.role
.get(name
)
4103 # except ClientException as e:
4107 table
= PrettyTable(['key', 'attribute'])
4108 for k
, v
in resp
.items():
4109 table
.add_row([k
, json
.dumps(v
, indent
=2)])
4114 @cli_osm.command(name
='package-create',
4115 short_help
='Create a package descriptor')
4116 @click.argument('package-type')
4117 @click.argument('package-name')
4118 @click.option('--base-directory',
4120 help=('(NS/VNF/NST) Set the location for package creation. Default: "."'))
4121 @click.option('--image',
4122 default
="image-name",
4123 help='(VNF) Set the name of the vdu image. Default "image-name"')
4124 @click.option('--vdus',
4126 help='(VNF) Set the number of vdus in a VNF. Default 1')
4127 @click.option('--vcpu',
4129 help='(VNF) Set the number of virtual CPUs in a vdu. Default 1')
4130 @click.option('--memory',
4132 help='(VNF) Set the memory size (MB) of the vdu. Default 1024')
4133 @click.option('--storage',
4135 help='(VNF) Set the disk size (GB) of the vdu. Default 10')
4136 @click.option('--interfaces',
4138 help='(VNF) Set the number of additional interfaces apart from the management interface. Default 0')
4139 @click.option('--vendor',
4141 help='(NS/VNF) Set the descriptor vendor. Default "OSM"')
4142 @click.option('--override',
4145 help='(NS/VNF/NST) Flag for overriding the package if exists.')
4146 @click.option('--detailed',
4149 help='(NS/VNF/NST) Flag for generating descriptor .yaml with all possible commented options')
4150 @click.option('--netslice-subnets',
4152 help='(NST) Number of netslice subnets. Default 1')
4153 @click.option('--netslice-vlds',
4155 help='(NST) Number of netslice vlds. Default 1')
4157 def package_create(ctx
,
4173 Creates an OSM NS, VNF, NST package
4176 PACKAGE_TYPE: Package to be created: NS, VNF or NST.
4177 PACKAGE_NAME: Name of the package to create the folder with the content.
4181 check_client_version(ctx
.obj
, ctx
.command
.name
)
4182 print("Creating the {} structure: {}/{}".format(package_type
.upper(), base_directory
, package_name
))
4183 resp
= ctx
.obj
.package_tool
.create(package_type
,
4192 interfaces
=interfaces
,
4195 netslice_subnets
=netslice_subnets
,
4196 netslice_vlds
=netslice_vlds
)
4198 # except ClientException as inst:
4199 # print("ERROR: {}".format(inst))
4202 @cli_osm.command(name
='package-validate',
4203 short_help
='Validate a package descriptor')
4204 @click.argument('base-directory',
4207 @click.option('--recursive/--no-recursive',
4209 help='The activated recursive option will validate the yaml files'
4210 ' within the indicated directory and in its subdirectories')
4212 def package_validate(ctx
,
4216 Validate descriptors given a base directory.
4219 BASE_DIRECTORY: Stub folder for NS, VNF or NST package.
4222 check_client_version(ctx
.obj
, ctx
.command
.name
)
4223 results
= ctx
.obj
.package_tool
.validate(base_directory
, recursive
)
4224 table
= PrettyTable()
4225 table
.field_names
= ["TYPE", "PATH", "VALID", "ERROR"]
4226 # Print the dictionary generated by the validation function
4227 for result
in results
:
4228 table
.add_row([result
["type"], result
["path"], result
["valid"], result
["error"]])
4229 table
.sortby
= "VALID"
4230 table
.align
["PATH"] = "l"
4231 table
.align
["TYPE"] = "l"
4232 table
.align
["ERROR"] = "l"
4234 # except ClientException as inst:
4235 # print("ERROR: {}".format(inst))
4238 @cli_osm.command(name
='package-build',
4239 short_help
='Build the tar.gz of the package')
4240 @click.argument('package-folder')
4241 @click.option('--skip-validation',
4244 help='skip package validation')
4245 @click.option('--skip-charm-build', default
=False, is_flag
=True,
4246 help='the charm will not be compiled, it is assumed to already exist')
4248 def package_build(ctx
,
4253 Build the package NS, VNF given the package_folder.
4256 PACKAGE_FOLDER: Folder of the NS, VNF or NST to be packaged
4259 check_client_version(ctx
.obj
, ctx
.command
.name
)
4260 results
= ctx
.obj
.package_tool
.build(package_folder
,
4261 skip_validation
=skip_validation
,
4262 skip_charm_build
=skip_charm_build
)
4264 # except ClientException as inst:
4265 # print("ERROR: {}".format(inst))
4273 except pycurl
.error
as exc
:
4275 print('Maybe "--hostname" option or OSM_HOSTNAME environment variable needs to be specified')
4276 except ClientException
as exc
:
4277 print("ERROR: {}".format(exc
))
4278 except (FileNotFoundError
, PermissionError
) as exc
:
4279 print("Cannot open file: {}".format(exc
))
4280 except yaml
.YAMLError
as exc
:
4281 print("Invalid YAML format: {}".format(exc
))
4283 # TODO capture other controlled exceptions here
4284 # TODO remove the ClientException captures from all places, unless they do something different
4287 if __name__
== '__main__':