1 # Copyright 2017-2018 Sandvine
2 # Copyright 2018 Telefonica
6 # Licensed under the Apache License, Version 2.0 (the "License"); you may
7 # not use this file except in compliance with the License. You may obtain
8 # a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 # License for the specific language governing permissions and limitations
22 from osmclient
import client
23 from osmclient
.common
.exceptions
import ClientException
24 from prettytable
import PrettyTable
33 from datetime
import datetime
38 CONTEXT_SETTINGS
= dict(help_option_names
=['-h', '--help'], max_content_width
=160)
40 def wrap_text(text
, width
):
41 wrapper
= textwrap
.TextWrapper(width
=width
)
42 lines
= text
.splitlines()
43 return "\n".join(map(wrapper
.fill
, lines
))
46 def trunc_text(text
, length
):
47 if len(text
) > length
:
48 return text
[:(length
- 3)] + '...'
53 def check_client_version(obj
, what
, version
='sol005'):
55 Checks the version of the client object and raises error if it not the expected.
57 :param obj: the client object
58 :what: the function or command under evaluation (used when an error is raised)
60 :raises ClientError: if the specified version does not match the client version
63 fullclassname
= obj
.__module
__ + "." + obj
.__class
__.__name
__
64 message
= 'The following commands or options are only supported with the option "--sol005": {}'.format(what
)
66 message
= 'The following commands or options are not supported when using option "--sol005": {}'.format(what
)
67 if fullclassname
!= 'osmclient.{}.client.Client'.format(version
):
68 raise ClientException(message
)
72 @click.group(context_settings
=dict(help_option_names
=['-h', '--help'], max_content_width
=160))
73 @click.option('--hostname',
75 envvar
='OSM_HOSTNAME',
76 help='hostname of server. ' +
77 'Also can set OSM_HOSTNAME in environment')
78 #@click.option('--sol005/--no-sol005',
80 # envvar='OSM_SOL005',
81 # help='Use ETSI NFV SOL005 API (default) or the previous SO API. ' +
82 # 'Also can set OSM_SOL005 in environment')
83 @click.option('--user',
86 help='user (defaults to admin). ' +
87 'Also can set OSM_USER in environment')
88 @click.option('--password',
90 envvar
='OSM_PASSWORD',
91 help='password (defaults to admin). ' +
92 'Also can set OSM_PASSWORD in environment')
93 @click.option('--project',
96 help='project (defaults to admin). ' +
97 'Also can set OSM_PROJECT in environment')
98 @click.option('-v', '--verbose', count
=True,
99 help='increase verbosity (-v INFO, -vv VERBOSE, -vvv DEBUG)')
100 @click.option('--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 vnfd_list(ctx
, nf_type
, filter, long):
472 check_client_version(ctx
.obj
, '--nf_type')
474 check_client_version(ctx
.obj
, '--filter')
477 nf_filter
= "_admin.type=vnfd"
478 elif nf_type
== "pnf":
479 nf_filter
= "_admin.type=pnfd"
480 elif nf_type
== "hnf":
481 nf_filter
= "_admin.type=hnfd"
483 raise ClientException('wrong value for "--nf_type" option, allowed values: vnf, pnf, hnf')
485 filter = '{}&{}'.format(nf_filter
, filter)
489 resp
= ctx
.obj
.vnfd
.list(filter)
491 resp
= ctx
.obj
.vnfd
.list()
492 # print(yaml.safe_dump(resp))
493 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
494 if fullclassname
== 'osmclient.sol005.client.Client':
496 table
= PrettyTable(['nfpkg name', 'id', 'onboarding state', 'operational state',
497 'usage state', 'date', 'last update'])
499 table
= PrettyTable(['nfpkg name', 'id'])
501 name
= vnfd
['name'] if 'name' in vnfd
else '-'
503 onb_state
= vnfd
['_admin'].get('onboardingState','-')
504 op_state
= vnfd
['_admin'].get('operationalState','-')
505 usage_state
= vnfd
['_admin'].get('usageState','-')
506 date
= datetime
.fromtimestamp(vnfd
['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S")
507 last_update
= datetime
.fromtimestamp(vnfd
['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S")
508 table
.add_row([name
, vnfd
['_id'], onb_state
, op_state
, usage_state
, date
, last_update
])
510 table
.add_row([name
, vnfd
['_id']])
512 table
= PrettyTable(['nfpkg name', 'id'])
514 table
.add_row([vnfd
['name'], vnfd
['id']])
519 @cli_osm.command(name
='vnfd-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
520 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
521 @click.option('--filter', default
=None,
522 help='restricts the list to the NF pkg matching the filter')
523 @click.option('--long', is_flag
=True, help='get more details')
525 def vnfd_list1(ctx
, nf_type
, filter, long):
526 """list all xNF packages (VNF, HNF, PNF)"""
528 vnfd_list(ctx
, nf_type
, filter, long)
531 @cli_osm.command(name
='vnfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
532 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
533 @click.option('--filter', default
=None,
534 help='restricts the list to the NFpkg matching the filter')
535 @click.option('--long', is_flag
=True, help='get more details')
537 def vnfd_list2(ctx
, nf_type
, filter, long):
538 """list all xNF packages (VNF, HNF, PNF)"""
540 vnfd_list(ctx
, nf_type
, filter, long)
543 @cli_osm.command(name
='nfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
544 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
545 @click.option('--filter', default
=None,
546 help='restricts the list to the NFpkg matching the filter')
547 @click.option('--long', is_flag
=True, help='get more details')
549 def nfpkg_list(ctx
, nf_type
, filter, long):
550 """list all xNF packages (VNF, HNF, PNF)"""
553 check_client_version(ctx
.obj
, ctx
.command
.name
)
554 vnfd_list(ctx
, nf_type
, filter, long)
555 # except ClientException as e:
560 def vnf_list(ctx
, ns
, filter, long):
564 check_client_version(ctx
.obj
, '--ns')
566 check_client_version(ctx
.obj
, '--filter')
567 resp
= ctx
.obj
.vnf
.list(ns
, filter)
569 resp
= ctx
.obj
.vnf
.list()
570 # except ClientException as e:
573 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
574 if fullclassname
== 'osmclient.sol005.client.Client':
575 field_names
= ['vnf id', 'name', 'ns id', 'vnf member index',
576 'vnfd name', 'vim account id', 'ip address']
578 field_names
= ['vnf id', 'name', 'ns id', 'vnf member index',
579 'vnfd name', 'vim account id', 'ip address',
580 'date', 'last update']
581 table
= PrettyTable(field_names
)
583 name
= vnfr
['name'] if 'name' in vnfr
else '-'
584 new_row
= [vnfr
['_id'], name
, vnfr
['nsr-id-ref'],
585 vnfr
['member-vnf-index-ref'], vnfr
['vnfd-ref'],
586 vnfr
['vim-account-id'], vnfr
['ip-address']]
588 date
= datetime
.fromtimestamp(vnfr
['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S")
589 last_update
= datetime
.fromtimestamp(vnfr
['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S")
590 new_row
.extend([date
, last_update
])
591 table
.add_row(new_row
)
596 'operational status',
599 if 'mgmt-interface' not in vnfr
:
600 vnfr
['mgmt-interface'] = {}
601 vnfr
['mgmt-interface']['ip-address'] = None
605 vnfr
['operational-status'],
606 vnfr
['config-status']])
611 @cli_osm.command(name
='vnf-list', short_help
='list all NF instances')
612 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
613 @click.option('--filter', default
=None,
614 help='restricts the list to the NF instances matching the filter.')
615 @click.option('--long', is_flag
=True, help='get more details')
617 def vnf_list1(ctx
, ns
, filter, long):
618 """list all NF instances"""
620 vnf_list(ctx
, ns
, filter, long)
623 @cli_osm.command(name
='nf-list', short_help
='list all NF instances')
624 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
625 @click.option('--filter', default
=None,
626 help='restricts the list to the NF instances matching the filter.')
627 @click.option('--long', is_flag
=True, help='get more details')
629 def nf_list(ctx
, ns
, filter, long):
630 """list all NF instances
634 --ns TEXT NS instance id or name to restrict the VNF list
635 --filter filterExpr Restricts the list to the VNF instances matching the filter
638 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
639 concatenated using the "&" character:
642 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
643 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
644 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
646 value := scalar value
650 * zero or more occurrences
651 ? zero or one occurrence
652 [] grouping of expressions to be used with ? and *
653 "" quotation marks for marking string constants
657 "AttrName" is the name of one attribute in the data type that defines the representation
658 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
659 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
660 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
661 entries, it means that the operator "op" is applied to the attribute addressed by the last
662 <attrName> entry included in the concatenation. All simple filter expressions are combined
663 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
664 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
665 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
666 prefix". If an attribute referenced in an expression is an array, an object that contains a
667 corresponding array shall be considered to match the expression if any of the elements in the
668 array matches all expressions that have the same attribute prefix.
672 --filter vim-account-id=<VIM_ACCOUNT_ID>
673 --filter vnfd-ref=<VNFD_NAME>
674 --filter vdur.ip-address=<IP_ADDRESS>
675 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
678 vnf_list(ctx
, ns
, filter)
681 @cli_osm.command(name
='ns-op-list', short_help
='shows the history of operations over a NS instance')
682 @click.argument('name')
683 @click.option('--long', is_flag
=True,
684 help='get more details of the NS operation (date, ).')
686 def ns_op_list(ctx
, name
, long):
687 """shows the history of operations over a NS instance
689 NAME: name or ID of the NS instance
691 def formatParams(params
):
692 if params
['lcmOperationType']=='instantiate':
693 params
.pop('nsDescription')
697 elif params
['lcmOperationType']=='action':
698 params
.pop('primitive')
699 params
.pop('lcmOperationType')
700 params
.pop('nsInstanceId')
705 check_client_version(ctx
.obj
, ctx
.command
.name
)
706 resp
= ctx
.obj
.ns
.list_op(name
)
707 # except ClientException as e:
712 table
= PrettyTable(['id', 'operation', 'action_name', 'operation_params', 'status', 'date', 'last update', 'detail'])
714 table
= PrettyTable(['id', 'operation', 'action_name', 'status', 'date', 'detail'])
716 #print(yaml.safe_dump(resp))
719 if op
['lcmOperationType']=='action':
720 action_name
= op
['operationParams']['primitive']
722 if op
['operationState']=='PROCESSING':
723 if op
['lcmOperationType'] in ('instantiate', 'terminate'):
727 detail
= "In queue. Current position: {}".format(op
['queuePosition'])
728 elif op
['operationState'] in ('FAILED', 'FAILED_TEMP'):
729 detail
= op
.get('errorMessage','-')
730 date
= datetime
.fromtimestamp(op
['startTime']).strftime("%Y-%m-%dT%H:%M:%S")
731 last_update
= datetime
.fromtimestamp(op
['statusEnteredTime']).strftime("%Y-%m-%dT%H:%M:%S")
733 table
.add_row([op
['id'],
734 op
['lcmOperationType'],
736 wrap_text(text
=json
.dumps(formatParams(op
['operationParams']),indent
=2),width
=50),
737 op
['operationState'],
740 wrap_text(text
=detail
,width
=50)])
742 table
.add_row([op
['id'], op
['lcmOperationType'], action_name
,
743 op
['operationState'], date
, wrap_text(text
=detail
or "",width
=50)])
748 def nsi_list(ctx
, filter):
749 """list all Network Slice Instances"""
752 check_client_version(ctx
.obj
, ctx
.command
.name
)
753 resp
= ctx
.obj
.nsi
.list(filter)
754 # except ClientException as e:
758 ['netslice instance name',
760 'operational status',
764 nsi_name
= nsi
['name']
766 opstatus
= nsi
['operational-status'] if 'operational-status' in nsi
else 'Not found'
767 configstatus
= nsi
['config-status'] if 'config-status' in nsi
else 'Not found'
768 detailed_status
= nsi
['detailed-status'] if 'detailed-status' in nsi
else 'Not found'
769 if configstatus
== "config_not_needed":
770 configstatus
= "configured (no charms)"
781 @cli_osm.command(name
='nsi-list', short_help
='list all Network Slice Instances (NSI)')
782 @click.option('--filter', default
=None,
783 help='restricts the list to the Network Slice Instances matching the filter')
785 def nsi_list1(ctx
, filter):
786 """list all Network Slice Instances (NSI)"""
788 nsi_list(ctx
, filter)
791 @cli_osm.command(name
='netslice-instance-list', short_help
='list all Network Slice Instances (NSI)')
792 @click.option('--filter', default
=None,
793 help='restricts the list to the Network Slice Instances matching the filter')
795 def nsi_list2(ctx
, filter):
796 """list all Network Slice Instances (NSI)"""
798 nsi_list(ctx
, filter)
801 def nst_list(ctx
, filter):
804 check_client_version(ctx
.obj
, ctx
.command
.name
)
805 resp
= ctx
.obj
.nst
.list(filter)
806 # except ClientException as e:
809 # print(yaml.safe_dump(resp))
810 table
= PrettyTable(['nst name', 'id'])
812 name
= nst
['name'] if 'name' in nst
else '-'
813 table
.add_row([name
, nst
['_id']])
818 @cli_osm.command(name
='nst-list', short_help
='list all Network Slice Templates (NST)')
819 @click.option('--filter', default
=None,
820 help='restricts the list to the NST matching the filter')
822 def nst_list1(ctx
, filter):
823 """list all Network Slice Templates (NST) in the system"""
825 nst_list(ctx
, filter)
828 @cli_osm.command(name
='netslice-template-list', short_help
='list all Network Slice Templates (NST)')
829 @click.option('--filter', default
=None,
830 help='restricts the list to the NST matching the filter')
832 def nst_list2(ctx
, filter):
833 """list all Network Slice Templates (NST) in the system"""
835 nst_list(ctx
, filter)
838 def nsi_op_list(ctx
, name
):
841 check_client_version(ctx
.obj
, ctx
.command
.name
)
842 resp
= ctx
.obj
.nsi
.list_op(name
)
843 # except ClientException as e:
846 table
= PrettyTable(['id', 'operation', 'status'])
848 table
.add_row([op
['id'], op
['lcmOperationType'],
849 op
['operationState']])
854 @cli_osm.command(name
='nsi-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
855 @click.argument('name')
857 def nsi_op_list1(ctx
, name
):
858 """shows the history of operations over a Network Slice Instance (NSI)
860 NAME: name or ID of the Network Slice Instance
863 nsi_op_list(ctx
, name
)
866 @cli_osm.command(name
='netslice-instance-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
867 @click.argument('name')
869 def nsi_op_list2(ctx
, name
):
870 """shows the history of operations over a Network Slice Instance (NSI)
872 NAME: name or ID of the Network Slice Instance
875 nsi_op_list(ctx
, name
)
878 @cli_osm.command(name
='pdu-list', short_help
='list all Physical Deployment Units (PDU)')
879 @click.option('--filter', default
=None,
880 help='restricts the list to the Physical Deployment Units matching the filter')
882 def pdu_list(ctx
, filter):
883 """list all Physical Deployment Units (PDU)"""
886 check_client_version(ctx
.obj
, ctx
.command
.name
)
887 resp
= ctx
.obj
.pdu
.list(filter)
888 # except ClientException as e:
897 pdu_name
= pdu
['name']
899 pdu_type
= pdu
['type']
900 pdu_ipaddress
= "None"
901 for iface
in pdu
['interfaces']:
903 pdu_ipaddress
= iface
['ip-address']
918 def nsd_show(ctx
, name
, literal
):
921 resp
= ctx
.obj
.nsd
.get(name
)
922 # resp = ctx.obj.nsd.get_individual(name)
923 # except ClientException as e:
928 print(yaml
.safe_dump(resp
))
931 table
= PrettyTable(['field', 'value'])
932 for k
, v
in list(resp
.items()):
933 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
938 @cli_osm.command(name
='nsd-show', short_help
='shows the content of a NSD')
939 @click.option('--literal', is_flag
=True,
940 help='print literally, no pretty table')
941 @click.argument('name')
943 def nsd_show1(ctx
, name
, literal
):
944 """shows the content of a NSD
946 NAME: name or ID of the NSD/NSpkg
949 nsd_show(ctx
, name
, literal
)
952 @cli_osm.command(name
='nspkg-show', short_help
='shows the content of a NSD')
953 @click.option('--literal', is_flag
=True,
954 help='print literally, no pretty table')
955 @click.argument('name')
957 def nsd_show2(ctx
, name
, literal
):
958 """shows the content of a NSD
960 NAME: name or ID of the NSD/NSpkg
963 nsd_show(ctx
, name
, literal
)
966 def vnfd_show(ctx
, name
, literal
):
969 resp
= ctx
.obj
.vnfd
.get(name
)
970 # resp = ctx.obj.vnfd.get_individual(name)
971 # except ClientException as e:
976 print(yaml
.safe_dump(resp
))
979 table
= PrettyTable(['field', 'value'])
980 for k
, v
in list(resp
.items()):
981 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
986 @cli_osm.command(name
='vnfd-show', short_help
='shows the content of a VNFD')
987 @click.option('--literal', is_flag
=True,
988 help='print literally, no pretty table')
989 @click.argument('name')
991 def vnfd_show1(ctx
, name
, literal
):
992 """shows the content of a VNFD
994 NAME: name or ID of the VNFD/VNFpkg
997 vnfd_show(ctx
, name
, literal
)
1000 @cli_osm.command(name
='vnfpkg-show', short_help
='shows the content of a VNFD')
1001 @click.option('--literal', is_flag
=True,
1002 help='print literally, no pretty table')
1003 @click.argument('name')
1005 def vnfd_show2(ctx
, name
, literal
):
1006 """shows the content of a VNFD
1008 NAME: name or ID of the VNFD/VNFpkg
1011 vnfd_show(ctx
, name
, literal
)
1014 @cli_osm.command(name
='nfpkg-show', short_help
='shows the content of a NF Descriptor')
1015 @click.option('--literal', is_flag
=True,
1016 help='print literally, no pretty table')
1017 @click.argument('name')
1019 def nfpkg_show(ctx
, name
, literal
):
1020 """shows the content of a NF Descriptor
1022 NAME: name or ID of the NFpkg
1025 vnfd_show(ctx
, name
, literal
)
1028 @cli_osm.command(name
='ns-show', short_help
='shows the info of a NS instance')
1029 @click.argument('name')
1030 @click.option('--literal', is_flag
=True,
1031 help='print literally, no pretty table')
1032 @click.option('--filter', default
=None)
1034 def ns_show(ctx
, name
, literal
, filter):
1035 """shows the info of a NS instance
1037 NAME: name or ID of the NS instance
1041 ns
= ctx
.obj
.ns
.get(name
)
1042 # except ClientException as e:
1047 print(yaml
.safe_dump(ns
))
1050 table
= PrettyTable(['field', 'value'])
1052 for k
, v
in list(ns
.items()):
1053 if filter is None or filter in k
:
1054 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
1056 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1057 if fullclassname
!= 'osmclient.sol005.client.Client':
1058 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
1059 nsr_optdata
= nsopdata
['nsr:nsr']
1060 for k
, v
in list(nsr_optdata
.items()):
1061 if filter is None or filter in k
:
1062 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2),width
=100)])
1067 @cli_osm.command(name
='vnf-show', short_help
='shows the info of a VNF instance')
1068 @click.argument('name')
1069 @click.option('--literal', is_flag
=True,
1070 help='print literally, no pretty table')
1071 @click.option('--filter', default
=None, help='restricts the information to the fields in the filter')
1072 @click.option('--kdu', default
=None, help='KDU name (whose status will be shown)')
1074 def vnf_show(ctx
, name
, literal
, filter, kdu
):
1075 """shows the info of a VNF instance
1077 NAME: name or ID of the VNF instance
1079 def print_kdu_status(op_info_status
):
1080 """print KDU status properly formatted
1083 op_status
= yaml
.safe_load(op_info_status
)
1084 if "namespace" in op_status
and "info" in op_status
and \
1085 "last_deployed" in op_status
["info"] and "status" in op_status
["info"] and \
1086 "code" in op_status
["info"]["status"] and "resources" in op_status
["info"]["status"] and \
1087 "seconds" in op_status
["info"]["last_deployed"]:
1088 last_deployed_time
= datetime
.fromtimestamp(op_status
["info"]["last_deployed"]["seconds"]).strftime("%a %b %d %I:%M:%S %Y")
1089 print("LAST DEPLOYED: {}".format(last_deployed_time
))
1090 print("NAMESPACE: {}".format(op_status
["namespace"]))
1091 status_code
= "UNKNOWN"
1092 if op_status
["info"]["status"]["code"]==1:
1093 status_code
= "DEPLOYED"
1094 print("STATUS: {}".format(status_code
))
1097 print(op_status
["info"]["status"]["resources"])
1098 if "notes" in op_status
["info"]["status"]:
1100 print(op_status
["info"]["status"]["notes"])
1102 print(op_info_status
)
1104 print(op_info_status
)
1109 raise ClientException('"--literal" option is incompatible with "--kdu" option')
1111 raise ClientException('"--filter" option is incompatible with "--kdu" option')
1114 check_client_version(ctx
.obj
, ctx
.command
.name
)
1115 resp
= ctx
.obj
.vnf
.get(name
)
1118 ns_id
= resp
['nsr-id-ref']
1120 op_data
['member_vnf_index'] = resp
['member-vnf-index-ref']
1121 op_data
['kdu_name'] = kdu
1122 op_data
['primitive'] = 'status'
1123 op_data
['primitive_params'] = {}
1124 op_id
= ctx
.obj
.ns
.exec_op(ns_id
, op_name
='action', op_data
=op_data
, wait
=False)
1127 op_info
= ctx
.obj
.ns
.get_op(op_id
)
1128 if op_info
['operationState'] == 'COMPLETED':
1129 print_kdu_status(op_info
['detailed-status'])
1133 print ("Could not determine KDU status")
1136 print(yaml
.safe_dump(resp
))
1139 table
= PrettyTable(['field', 'value'])
1141 for k
, v
in list(resp
.items()):
1142 if filter is None or filter in k
:
1143 table
.add_row([k
, wrap_text(text
=json
.dumps(v
,indent
=2),width
=100)])
1146 # except ClientException as e:
1151 #@cli_osm.command(name='vnf-monitoring-show')
1152 #@click.argument('vnf_name')
1153 #@click.pass_context
1154 #def vnf_monitoring_show(ctx, vnf_name):
1156 # check_client_version(ctx.obj, ctx.command.name, 'v1')
1157 # resp = ctx.obj.vnf.get_monitoring(vnf_name)
1158 # except ClientException as e:
1162 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
1163 # if resp is not None:
1164 # for monitor in resp:
1168 # monitor['value-integer'],
1169 # monitor['units']])
1174 #@cli_osm.command(name='ns-monitoring-show')
1175 #@click.argument('ns_name')
1176 #@click.pass_context
1177 #def ns_monitoring_show(ctx, ns_name):
1179 # check_client_version(ctx.obj, ctx.command.name, 'v1')
1180 # resp = ctx.obj.ns.get_monitoring(ns_name)
1181 # except ClientException as e:
1185 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
1186 # for key, val in list(resp.items()):
1187 # for monitor in val:
1191 # monitor['value-integer'],
1192 # monitor['units']])
1197 @cli_osm.command(name
='ns-op-show', short_help
='shows the info of a NS operation')
1198 @click.argument('id')
1199 @click.option('--filter', default
=None)
1200 @click.option('--literal', is_flag
=True,
1201 help='print literally, no pretty table')
1203 def ns_op_show(ctx
, id, filter, literal
):
1204 """shows the detailed info of a NS operation
1206 ID: operation identifier
1210 check_client_version(ctx
.obj
, ctx
.command
.name
)
1211 op_info
= ctx
.obj
.ns
.get_op(id)
1212 # except ClientException as e:
1217 print(yaml
.safe_dump(op_info
))
1220 table
= PrettyTable(['field', 'value'])
1221 for k
, v
in list(op_info
.items()):
1222 if filter is None or filter in k
:
1223 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
1228 def nst_show(ctx
, name
, literal
):
1231 check_client_version(ctx
.obj
, ctx
.command
.name
)
1232 resp
= ctx
.obj
.nst
.get(name
)
1233 #resp = ctx.obj.nst.get_individual(name)
1234 # except ClientException as e:
1239 print(yaml
.safe_dump(resp
))
1242 table
= PrettyTable(['field', 'value'])
1243 for k
, v
in list(resp
.items()):
1244 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
1249 @cli_osm.command(name
='nst-show', short_help
='shows the content of a Network Slice Template (NST)')
1250 @click.option('--literal', is_flag
=True,
1251 help='print literally, no pretty table')
1252 @click.argument('name')
1254 def nst_show1(ctx
, name
, literal
):
1255 """shows the content of a Network Slice Template (NST)
1257 NAME: name or ID of the NST
1260 nst_show(ctx
, name
, literal
)
1263 @cli_osm.command(name
='netslice-template-show', short_help
='shows the content of a Network Slice Template (NST)')
1264 @click.option('--literal', is_flag
=True,
1265 help='print literally, no pretty table')
1266 @click.argument('name')
1268 def nst_show2(ctx
, name
, literal
):
1269 """shows the content of a Network Slice Template (NST)
1271 NAME: name or ID of the NST
1274 nst_show(ctx
, name
, literal
)
1277 def nsi_show(ctx
, name
, literal
, filter):
1280 check_client_version(ctx
.obj
, ctx
.command
.name
)
1281 nsi
= ctx
.obj
.nsi
.get(name
)
1282 # except ClientException as e:
1287 print(yaml
.safe_dump(nsi
))
1290 table
= PrettyTable(['field', 'value'])
1292 for k
, v
in list(nsi
.items()):
1293 if filter is None or filter in k
:
1294 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1300 @cli_osm.command(name
='nsi-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1301 @click.argument('name')
1302 @click.option('--literal', is_flag
=True,
1303 help='print literally, no pretty table')
1304 @click.option('--filter', default
=None)
1306 def nsi_show1(ctx
, name
, literal
, filter):
1307 """shows the content of a Network Slice Instance (NSI)
1309 NAME: name or ID of the Network Slice Instance
1312 nsi_show(ctx
, name
, literal
, filter)
1315 @cli_osm.command(name
='netslice-instance-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1316 @click.argument('name')
1317 @click.option('--literal', is_flag
=True,
1318 help='print literally, no pretty table')
1319 @click.option('--filter', default
=None)
1321 def nsi_show2(ctx
, name
, literal
, filter):
1322 """shows the content of a Network Slice Instance (NSI)
1324 NAME: name or ID of the Network Slice Instance
1327 nsi_show(ctx
, name
, literal
, filter)
1330 def nsi_op_show(ctx
, id, filter):
1333 check_client_version(ctx
.obj
, ctx
.command
.name
)
1334 op_info
= ctx
.obj
.nsi
.get_op(id)
1335 # except ClientException as e:
1339 table
= PrettyTable(['field', 'value'])
1340 for k
, v
in list(op_info
.items()):
1341 if filter is None or filter in k
:
1342 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1347 @cli_osm.command(name
='nsi-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1348 @click.argument('id')
1349 @click.option('--filter', default
=None)
1351 def nsi_op_show1(ctx
, id, filter):
1352 """shows the info of an operation over a Network Slice Instance(NSI)
1354 ID: operation identifier
1357 nsi_op_show(ctx
, id, filter)
1360 @cli_osm.command(name
='netslice-instance-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1361 @click.argument('id')
1362 @click.option('--filter', default
=None)
1364 def nsi_op_show2(ctx
, id, filter):
1365 """shows the info of an operation over a Network Slice Instance(NSI)
1367 ID: operation identifier
1370 nsi_op_show(ctx
, id, filter)
1373 @cli_osm.command(name
='pdu-show', short_help
='shows the content of a Physical Deployment Unit (PDU)')
1374 @click.argument('name')
1375 @click.option('--literal', is_flag
=True,
1376 help='print literally, no pretty table')
1377 @click.option('--filter', default
=None)
1379 def pdu_show(ctx
, name
, literal
, filter):
1380 """shows the content of a Physical Deployment Unit (PDU)
1382 NAME: name or ID of the PDU
1386 check_client_version(ctx
.obj
, ctx
.command
.name
)
1387 pdu
= ctx
.obj
.pdu
.get(name
)
1388 # except ClientException as e:
1393 print(yaml
.safe_dump(pdu
))
1396 table
= PrettyTable(['field', 'value'])
1398 for k
, v
in list(pdu
.items()):
1399 if filter is None or filter in k
:
1400 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1406 ####################
1408 ####################
1410 def nsd_create(ctx
, filename
, overwrite
, skip_charm_build
):
1413 check_client_version(ctx
.obj
, ctx
.command
.name
)
1414 ctx
.obj
.nsd
.create(filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
)
1415 # except ClientException as e:
1420 @cli_osm.command(name
='nsd-create', short_help
='creates a new NSD/NSpkg')
1421 @click.argument('filename')
1422 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1423 help='Deprecated. Use override')
1424 @click.option('--override', 'overwrite', default
=None,
1425 help='overrides fields in descriptor, format: '
1426 '"key1.key2...=value[;key3...=value;...]"')
1427 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1428 help='The charm will not be compiled, it is assumed to already exist')
1430 def nsd_create1(ctx
, filename
, overwrite
, skip_charm_build
):
1431 """onboards a new NSpkg (alias of nspkg-create) (TO BE DEPRECATED)
1434 FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder
1435 If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded.
1436 If FILENAME is an NF Package folder, it is built and then onboarded.
1439 nsd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
)
1442 @cli_osm.command(name
='nspkg-create', short_help
='creates a new NSD/NSpkg')
1443 @click.argument('filename')
1444 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1445 help='Deprecated. Use override')
1446 @click.option('--override', 'overwrite', default
=None,
1447 help='overrides fields in descriptor, format: '
1448 '"key1.key2...=value[;key3...=value;...]"')
1449 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1450 help='The charm will not be compiled, it is assumed to already exist')
1452 def nsd_create2(ctx
, filename
, overwrite
, skip_charm_build
):
1453 """onboards a new NSpkg
1456 FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder
1457 If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded.
1458 If FILENAME is an NF Package folder, it is built and then onboarded.
1461 nsd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
)
1464 def vnfd_create(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1467 check_client_version(ctx
.obj
, ctx
.command
.name
)
1468 ctx
.obj
.vnfd
.create(filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1469 override_epa
=override_epa
, override_nonepa
=override_nonepa
,
1470 override_paravirt
=override_paravirt
)
1471 # except ClientException as e:
1476 @cli_osm.command(name
='vnfd-create', short_help
='creates a new VNFD/VNFpkg')
1477 @click.argument('filename')
1478 @click.option('--overwrite', 'overwrite', default
=None,
1479 help='overwrite deprecated, use override')
1480 @click.option('--override', 'overwrite', default
=None,
1481 help='overrides fields in descriptor, format: '
1482 '"key1.key2...=value[;key3...=value;...]"')
1483 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1484 help='The charm will not be compiled, it is assumed to already exist')
1485 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1486 help='adds guest-epa parameters to all VDU')
1487 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1488 help='removes all guest-epa parameters from all VDU')
1489 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1490 help='overrides all VDU interfaces to PARAVIRT')
1492 def vnfd_create1(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1493 """onboards a new NFpkg (alias of nfpkg-create) (TO BE DEPRECATED)
1496 FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder
1497 If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded.
1498 If FILENAME is an NF Package folder, it is built and then onboarded.
1501 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1502 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
)
1505 @cli_osm.command(name
='vnfpkg-create', short_help
='creates a new VNFD/VNFpkg')
1506 @click.argument('filename')
1507 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1508 help='Deprecated. Use override')
1509 @click.option('--override', 'overwrite', default
=None,
1510 help='overrides fields in descriptor, format: '
1511 '"key1.key2...=value[;key3...=value;...]"')
1512 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1513 help='The charm will not be compiled, it is assumed to already exist')
1514 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1515 help='adds guest-epa parameters to all VDU')
1516 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1517 help='removes all guest-epa parameters from all VDU')
1518 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1519 help='overrides all VDU interfaces to PARAVIRT')
1521 def vnfd_create2(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1522 """onboards a new NFpkg (alias of nfpkg-create)
1525 FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder
1526 If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded.
1527 If FILENAME is an NF Package folder, it is built and then onboarded.
1530 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1531 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
)
1534 @cli_osm.command(name
='nfpkg-create', short_help
='creates a new NFpkg')
1535 @click.argument('filename')
1536 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1537 help='Deprecated. Use override')
1538 @click.option('--override', 'overwrite', default
=None,
1539 help='overrides fields in descriptor, format: '
1540 '"key1.key2...=value[;key3...=value;...]"')
1541 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1542 help='The charm will not be compiled, it is assumed to already exist')
1543 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1544 help='adds guest-epa parameters to all VDU')
1545 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1546 help='removes all guest-epa parameters from all VDU')
1547 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1548 help='overrides all VDU interfaces to PARAVIRT')
1550 def nfpkg_create(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1551 """onboards a new NFpkg (alias of nfpkg-create)
1554 FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder
1555 If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded.
1556 If FILENAME is an NF Package folder, it is built and then onboarded.
1559 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1560 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
)
1563 @cli_osm.command(name
='ns-create', short_help
='creates a new Network Service instance')
1564 @click.option('--ns_name',
1565 prompt
=True, help='name of the NS instance')
1566 @click.option('--nsd_name',
1567 prompt
=True, help='name of the NS descriptor')
1568 @click.option('--vim_account',
1569 prompt
=True, help='default VIM account id or name for the deployment')
1570 @click.option('--admin_status',
1572 help='administration status')
1573 @click.option('--ssh_keys',
1575 help='comma separated list of public key files to inject to vnfs')
1576 @click.option('--config',
1578 help='ns specific yaml configuration')
1579 @click.option('--config_file',
1581 help='ns specific yaml configuration file')
1582 @click.option('--wait',
1586 help='do not return the control immediately, but keep it '
1587 'until the operation is completed, or timeout')
1598 """creates a new NS instance"""
1602 check_client_version(ctx
.obj
, '--config_file')
1604 raise ClientException('"--config" option is incompatible with "--config_file" option')
1605 with
open(config_file
, 'r') as cf
:
1612 account
=vim_account
,
1614 # except ClientException as e:
1619 def nst_create(ctx
, filename
, overwrite
):
1622 check_client_version(ctx
.obj
, ctx
.command
.name
)
1623 ctx
.obj
.nst
.create(filename
, overwrite
)
1624 # except ClientException as e:
1629 @cli_osm.command(name
='nst-create', short_help
='creates a new Network Slice Template (NST)')
1630 @click.argument('filename')
1631 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1632 help='Deprecated. Use override')
1633 @click.option('--override', 'overwrite', default
=None,
1634 help='overrides fields in descriptor, format: '
1635 '"key1.key2...=value[;key3...=value;...]"')
1637 def nst_create1(ctx
, filename
, overwrite
):
1638 """creates a new Network Slice Template (NST)
1640 FILENAME: NST package folder, NST yaml file or NSTpkg tar.gz file
1643 nst_create(ctx
, filename
, overwrite
)
1646 @cli_osm.command(name
='netslice-template-create', short_help
='creates a new Network Slice Template (NST)')
1647 @click.argument('filename')
1648 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1649 help='Deprecated. Use override')
1650 @click.option('--override', 'overwrite', default
=None,
1651 help='overrides fields in descriptor, format: '
1652 '"key1.key2...=value[;key3...=value;...]"')
1654 def nst_create2(ctx
, filename
, overwrite
):
1655 """creates a new Network Slice Template (NST)
1657 FILENAME: NST yaml file or NSTpkg tar.gz file
1660 nst_create(ctx
, filename
, overwrite
)
1663 def nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1664 """creates a new Network Slice Instance (NSI)"""
1667 check_client_version(ctx
.obj
, ctx
.command
.name
)
1670 raise ClientException('"--config" option is incompatible with "--config_file" option')
1671 with
open(config_file
, 'r') as cf
:
1673 ctx
.obj
.nsi
.create(nst_name
, nsi_name
, config
=config
, ssh_keys
=ssh_keys
,
1674 account
=vim_account
, wait
=wait
)
1675 # except ClientException as e:
1680 @cli_osm.command(name
='nsi-create', short_help
='creates a new Network Slice Instance')
1681 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1682 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1683 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1684 @click.option('--ssh_keys', default
=None,
1685 help='comma separated list of keys to inject to vnfs')
1686 @click.option('--config', default
=None,
1687 help='Netslice specific yaml configuration:\n'
1688 'netslice_subnet: [\n'
1689 'id: TEXT, vim_account: TEXT,\n'
1690 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1691 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]\n'
1692 'additionalParamsForNsi: {param: value, ...}\n'
1693 'additionalParamsForsubnet: [{id: SUBNET_ID, additionalParamsForNs: {}, additionalParamsForVnf: {}}]\n'
1695 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1697 @click.option('--config_file',
1699 help='nsi specific yaml configuration file')
1700 @click.option('--wait',
1704 help='do not return the control immediately, but keep it '
1705 'until the operation is completed, or timeout')
1707 def nsi_create1(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1708 """creates a new Network Slice Instance (NSI)"""
1710 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1713 @cli_osm.command(name
='netslice-instance-create', short_help
='creates a new Network Slice Instance')
1714 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1715 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1716 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1717 @click.option('--ssh_keys', default
=None,
1718 help='comma separated list of keys to inject to vnfs')
1719 @click.option('--config', default
=None,
1720 help='Netslice specific yaml configuration:\n'
1721 'netslice_subnet: [\n'
1722 'id: TEXT, vim_account: TEXT,\n'
1723 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1724 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1726 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1728 @click.option('--config_file',
1730 help='nsi specific yaml configuration file')
1731 @click.option('--wait',
1735 help='do not return the control immediately, but keep it '
1736 'until the operation is completed, or timeout')
1738 def nsi_create2(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1739 """creates a new Network Slice Instance (NSI)"""
1741 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1744 @cli_osm.command(name
='pdu-create', short_help
='adds a new Physical Deployment Unit to the catalog')
1745 @click.option('--name', help='name of the Physical Deployment Unit')
1746 @click.option('--pdu_type', help='type of PDU (e.g. router, firewall, FW001)')
1747 @click.option('--interface',
1748 help='interface(s) of the PDU: name=<NAME>,mgmt=<true|false>,ip-address=<IP_ADDRESS>'+
1749 '[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]',
1751 @click.option('--description', help='human readable description')
1752 @click.option('--vim_account', help='list of VIM accounts (in the same VIM) that can reach this PDU', multiple
=True)
1753 @click.option('--descriptor_file', default
=None,
1754 help='PDU descriptor file (as an alternative to using the other arguments')
1756 def pdu_create(ctx
, name
, pdu_type
, interface
, description
, vim_account
, descriptor_file
):
1757 """creates a new Physical Deployment Unit (PDU)"""
1760 check_client_version(ctx
.obj
, ctx
.command
.name
)
1762 if not descriptor_file
:
1764 raise ClientException('in absence of descriptor file, option "--name" is mandatory')
1766 raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory')
1768 raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)')
1770 raise ClientException('in absence of descriptor file, option "--vim_account" is mandatory (at least once)')
1772 with
open(descriptor_file
, 'r') as df
:
1773 pdu
= yaml
.safe_load(df
.read())
1774 if name
: pdu
["name"] = name
1775 if pdu_type
: pdu
["type"] = pdu_type
1776 if description
: pdu
["description"] = description
1777 if vim_account
: pdu
["vim_accounts"] = vim_account
1780 for iface
in interface
:
1781 new_iface
={k
:v
for k
,v
in [i
.split('=') for i
in iface
.split(',')]}
1782 new_iface
["mgmt"] = (new_iface
.get("mgmt","false").lower() == "true")
1783 ifaces_list
.append(new_iface
)
1784 pdu
["interfaces"] = ifaces_list
1785 ctx
.obj
.pdu
.create(pdu
)
1786 # except ClientException as e:
1791 ####################
1793 ####################
1795 def nsd_update(ctx
, name
, content
):
1798 check_client_version(ctx
.obj
, ctx
.command
.name
)
1799 ctx
.obj
.nsd
.update(name
, content
)
1800 # except ClientException as e:
1805 @cli_osm.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
1806 @click.argument('name')
1807 @click.option('--content', default
=None,
1808 help='filename with the NSD/NSpkg replacing the current one')
1810 def nsd_update1(ctx
, name
, content
):
1811 """updates a NSD/NSpkg
1813 NAME: name or ID of the NSD/NSpkg
1816 nsd_update(ctx
, name
, content
)
1819 @cli_osm.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
1820 @click.argument('name')
1821 @click.option('--content', default
=None,
1822 help='filename with the NSD/NSpkg replacing the current one')
1824 def nsd_update2(ctx
, name
, content
):
1825 """updates a NSD/NSpkg
1827 NAME: name or ID of the NSD/NSpkg
1830 nsd_update(ctx
, name
, content
)
1833 def vnfd_update(ctx
, name
, content
):
1836 check_client_version(ctx
.obj
, ctx
.command
.name
)
1837 ctx
.obj
.vnfd
.update(name
, content
)
1838 # except ClientException as e:
1843 @cli_osm.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
1844 @click.argument('name')
1845 @click.option('--content', default
=None,
1846 help='filename with the VNFD/VNFpkg replacing the current one')
1848 def vnfd_update1(ctx
, name
, content
):
1849 """updates a VNFD/VNFpkg
1851 NAME: name or ID of the VNFD/VNFpkg
1854 vnfd_update(ctx
, name
, content
)
1857 @cli_osm.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
1858 @click.argument('name')
1859 @click.option('--content', default
=None,
1860 help='filename with the VNFD/VNFpkg replacing the current one')
1862 def vnfd_update2(ctx
, name
, content
):
1863 """updates a VNFD/VNFpkg
1865 NAME: VNFD yaml file or VNFpkg tar.gz file
1868 vnfd_update(ctx
, name
, content
)
1871 @cli_osm.command(name
='nfpkg-update', short_help
='updates a NFpkg')
1872 @click.argument('name')
1873 @click.option('--content', default
=None,
1874 help='filename with the NFpkg replacing the current one')
1876 def nfpkg_update(ctx
, name
, content
):
1879 NAME: NF Descriptor yaml file or NFpkg tar.gz file
1882 vnfd_update(ctx
, name
, content
)
1885 def nst_update(ctx
, name
, content
):
1888 check_client_version(ctx
.obj
, ctx
.command
.name
)
1889 ctx
.obj
.nst
.update(name
, content
)
1890 # except ClientException as e:
1895 @cli_osm.command(name
='nst-update', short_help
='updates a Network Slice Template (NST)')
1896 @click.argument('name')
1897 @click.option('--content', default
=None,
1898 help='filename with the NST/NSTpkg replacing the current one')
1900 def nst_update1(ctx
, name
, content
):
1901 """updates a Network Slice Template (NST)
1903 NAME: name or ID of the NSD/NSpkg
1906 nst_update(ctx
, name
, content
)
1909 @cli_osm.command(name
='netslice-template-update', short_help
='updates a Network Slice Template (NST)')
1910 @click.argument('name')
1911 @click.option('--content', default
=None,
1912 help='filename with the NST/NSTpkg replacing the current one')
1914 def nst_update2(ctx
, name
, content
):
1915 """updates a Network Slice Template (NST)
1917 NAME: name or ID of the NSD/NSpkg
1920 nst_update(ctx
, name
, content
)
1923 ####################
1925 ####################
1927 def nsd_delete(ctx
, name
, force
):
1931 ctx
.obj
.nsd
.delete(name
)
1933 check_client_version(ctx
.obj
, '--force')
1934 ctx
.obj
.nsd
.delete(name
, force
)
1935 # except ClientException as e:
1940 @cli_osm.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
1941 @click.argument('name')
1942 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1944 def nsd_delete1(ctx
, name
, force
):
1945 """deletes a NSD/NSpkg
1947 NAME: name or ID of the NSD/NSpkg to be deleted
1950 nsd_delete(ctx
, name
, force
)
1953 @cli_osm.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
1954 @click.argument('name')
1955 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1957 def nsd_delete2(ctx
, name
, force
):
1958 """deletes a NSD/NSpkg
1960 NAME: name or ID of the NSD/NSpkg to be deleted
1963 nsd_delete(ctx
, name
, force
)
1966 def vnfd_delete(ctx
, name
, force
):
1970 ctx
.obj
.vnfd
.delete(name
)
1972 check_client_version(ctx
.obj
, '--force')
1973 ctx
.obj
.vnfd
.delete(name
, force
)
1974 # except ClientException as e:
1979 @cli_osm.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
1980 @click.argument('name')
1981 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1983 def vnfd_delete1(ctx
, name
, force
):
1984 """deletes a VNFD/VNFpkg
1986 NAME: name or ID of the VNFD/VNFpkg to be deleted
1989 vnfd_delete(ctx
, name
, force
)
1992 @cli_osm.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
1993 @click.argument('name')
1994 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1996 def vnfd_delete2(ctx
, name
, force
):
1997 """deletes a VNFD/VNFpkg
1999 NAME: name or ID of the VNFD/VNFpkg to be deleted
2002 vnfd_delete(ctx
, name
, force
)
2005 @cli_osm.command(name
='nfpkg-delete', short_help
='deletes a NFpkg')
2006 @click.argument('name')
2007 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2009 def nfpkg_delete(ctx
, name
, force
):
2012 NAME: name or ID of the NFpkg to be deleted
2015 vnfd_delete(ctx
, name
, force
)
2018 @cli_osm.command(name
='ns-delete', short_help
='deletes a NS instance')
2019 @click.argument('name')
2020 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2021 @click.option('--config', default
=None,
2022 help="specific yaml configuration for the termination, e.g. '{autoremove: False, timeout_ns_terminate: "
2023 "600, skip_terminate_primitives: True}'")
2024 @click.option('--wait',
2028 help='do not return the control immediately, but keep it '
2029 'until the operation is completed, or timeout')
2031 def ns_delete(ctx
, name
, force
, config
, wait
):
2032 """deletes a NS instance
2034 NAME: name or ID of the NS instance to be deleted
2039 ctx
.obj
.ns
.delete(name
, config
=config
, wait
=wait
)
2041 check_client_version(ctx
.obj
, '--force')
2042 ctx
.obj
.ns
.delete(name
, force
, config
=config
, wait
=wait
)
2043 # except ClientException as e:
2048 def nst_delete(ctx
, name
, force
):
2051 check_client_version(ctx
.obj
, ctx
.command
.name
)
2052 ctx
.obj
.nst
.delete(name
, force
)
2053 # except ClientException as e:
2058 @cli_osm.command(name
='nst-delete', short_help
='deletes a Network Slice Template (NST)')
2059 @click.argument('name')
2060 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2062 def nst_delete1(ctx
, name
, force
):
2063 """deletes a Network Slice Template (NST)
2065 NAME: name or ID of the NST/NSTpkg to be deleted
2068 nst_delete(ctx
, name
, force
)
2071 @cli_osm.command(name
='netslice-template-delete', short_help
='deletes a Network Slice Template (NST)')
2072 @click.argument('name')
2073 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2075 def nst_delete2(ctx
, name
, force
):
2076 """deletes a Network Slice Template (NST)
2078 NAME: name or ID of the NST/NSTpkg to be deleted
2081 nst_delete(ctx
, name
, force
)
2084 def nsi_delete(ctx
, name
, force
, wait
):
2087 check_client_version(ctx
.obj
, ctx
.command
.name
)
2088 ctx
.obj
.nsi
.delete(name
, force
, wait
=wait
)
2089 # except ClientException as e:
2094 @cli_osm.command(name
='nsi-delete', short_help
='deletes a Network Slice Instance (NSI)')
2095 @click.argument('name')
2096 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2097 @click.option('--wait',
2101 help='do not return the control immediately, but keep it '
2102 'until the operation is completed, or timeout')
2104 def nsi_delete1(ctx
, name
, force
, wait
):
2105 """deletes a Network Slice Instance (NSI)
2107 NAME: name or ID of the Network Slice instance to be deleted
2110 nsi_delete(ctx
, name
, force
, wait
=wait
)
2113 @cli_osm.command(name
='netslice-instance-delete', short_help
='deletes a Network Slice Instance (NSI)')
2114 @click.argument('name')
2115 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2117 def nsi_delete2(ctx
, name
, force
, wait
):
2118 """deletes a Network Slice Instance (NSI)
2120 NAME: name or ID of the Network Slice instance to be deleted
2123 nsi_delete(ctx
, name
, force
, wait
=wait
)
2126 @cli_osm.command(name
='pdu-delete', short_help
='deletes a Physical Deployment Unit (PDU)')
2127 @click.argument('name')
2128 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2130 def pdu_delete(ctx
, name
, force
):
2131 """deletes a Physical Deployment Unit (PDU)
2133 NAME: name or ID of the PDU to be deleted
2137 check_client_version(ctx
.obj
, ctx
.command
.name
)
2138 ctx
.obj
.pdu
.delete(name
, force
)
2139 # except ClientException as e:
2148 @cli_osm.command(name
='vim-create', short_help
='creates a new VIM account')
2149 @click.option('--name',
2151 help='Name to create datacenter')
2152 @click.option('--user',
2154 help='VIM username')
2155 @click.option('--password',
2158 confirmation_prompt
=True,
2159 help='VIM password')
2160 @click.option('--auth_url',
2163 @click.option('--tenant',
2165 help='VIM tenant name')
2166 @click.option('--config',
2168 help='VIM specific config parameters')
2169 @click.option('--account_type',
2170 default
='openstack',
2172 @click.option('--description',
2174 help='human readable description')
2175 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
2176 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
2177 @click.option('--wait',
2181 help='do not return the control immediately, but keep it '
2182 'until the operation is completed, or timeout')
2196 """creates a new VIM account"""
2200 check_client_version(ctx
.obj
, '--sdn_controller')
2201 if sdn_port_mapping
:
2202 check_client_version(ctx
.obj
, '--sdn_port_mapping')
2204 vim
['vim-username'] = user
2205 vim
['vim-password'] = password
2206 vim
['vim-url'] = auth_url
2207 vim
['vim-tenant-name'] = tenant
2208 vim
['vim-type'] = account_type
2209 vim
['description'] = description
2210 vim
['config'] = config
2211 if sdn_controller
or sdn_port_mapping
:
2212 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
2214 ctx
.obj
.vim
.create(name
, vim
, wait
=wait
)
2215 # except ClientException as e:
2220 @cli_osm.command(name
='vim-update', short_help
='updates a VIM account')
2221 @click.argument('name')
2222 @click.option('--newname', help='New name for the VIM account')
2223 @click.option('--user', help='VIM username')
2224 @click.option('--password', help='VIM password')
2225 @click.option('--auth_url', help='VIM url')
2226 @click.option('--tenant', help='VIM tenant name')
2227 @click.option('--config', help='VIM specific config parameters')
2228 @click.option('--account_type', help='VIM type')
2229 @click.option('--description', help='human readable description')
2230 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller to be associated with this VIM'
2231 'account. Use empty string to disassociate')
2232 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
2233 @click.option('--wait',
2237 help='do not return the control immediately, but keep it '
2238 'until the operation is completed, or timeout')
2253 """updates a VIM account
2255 NAME: name or ID of the VIM account
2259 check_client_version(ctx
.obj
, ctx
.command
.name
)
2261 if newname
: vim
['name'] = newname
2262 if user
: vim
['vim_user'] = user
2263 if password
: vim
['vim_password'] = password
2264 if auth_url
: vim
['vim_url'] = auth_url
2265 if tenant
: vim
['vim-tenant-name'] = tenant
2266 if account_type
: vim
['vim_type'] = account_type
2267 if description
: vim
['description'] = description
2268 if config
: vim
['config'] = config
2269 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
2270 # except ClientException as e:
2275 @cli_osm.command(name
='vim-delete', short_help
='deletes a VIM account')
2276 @click.argument('name')
2277 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2278 @click.option('--wait',
2282 help='do not return the control immediately, but keep it '
2283 'until the operation is completed, or timeout')
2285 def vim_delete(ctx
, name
, force
, wait
):
2286 """deletes a VIM account
2288 NAME: name or ID of the VIM account to be deleted
2293 ctx
.obj
.vim
.delete(name
, wait
=wait
)
2295 check_client_version(ctx
.obj
, '--force')
2296 ctx
.obj
.vim
.delete(name
, force
, wait
=wait
)
2297 # except ClientException as e:
2302 @cli_osm.command(name
='vim-list', short_help
='list all VIM accounts')
2303 #@click.option('--ro_update/--no_ro_update',
2305 # help='update list from RO')
2306 @click.option('--filter', default
=None,
2307 help='restricts the list to the VIM accounts matching the filter')
2308 @click.option('--long', is_flag
=True,
2309 help='get more details of the NS (project, vim, deployment status, configuration status.')
2311 def vim_list(ctx
, filter, long):
2312 """list all VIM accounts"""
2315 check_client_version(ctx
.obj
, '--filter')
2317 # check_client_version(ctx.obj, '--ro_update', 'v1')
2318 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
2319 if fullclassname
== 'osmclient.sol005.client.Client':
2320 resp
= ctx
.obj
.vim
.list(filter)
2322 # resp = ctx.obj.vim.list(ro_update)
2324 table
= PrettyTable(['vim name', 'uuid', 'project', 'operational state', 'error details'])
2326 table
= PrettyTable(['vim name', 'uuid'])
2329 vim_details
= ctx
.obj
.vim
.get(vim
['uuid'])
2330 if 'vim_password' in vim_details
:
2331 vim_details
['vim_password']='********'
2332 logger
.debug('VIM details: {}'.format(yaml
.safe_dump(vim_details
)))
2333 vim_state
= vim_details
['_admin'].get('operationalState', '-')
2334 error_details
= 'N/A'
2335 if vim_state
== 'ERROR':
2336 error_details
= vim_details
['_admin'].get('detailed-status', 'Not found')
2337 project_list
= ctx
.obj
.project
.list()
2338 vim_project_list
= vim_details
.get('_admin').get('projects_read')
2340 project_name
= 'None'
2341 if vim_project_list
:
2342 project_id
= vim_project_list
[0]
2343 for p
in project_list
:
2344 if p
['_id'] == project_id
:
2345 project_name
= p
['name']
2347 table
.add_row([vim
['name'], vim
['uuid'], '{} ({})'.format(project_name
, project_id
),
2348 vim_state
, wrap_text(text
=error_details
, width
=80)])
2350 table
.add_row([vim
['name'], vim
['uuid']])
2355 @cli_osm.command(name
='vim-show', short_help
='shows the details of a VIM account')
2356 @click.argument('name')
2358 def vim_show(ctx
, name
):
2359 """shows the details of a VIM account
2361 NAME: name or ID of the VIM account
2365 resp
= ctx
.obj
.vim
.get(name
)
2366 if 'vim_password' in resp
:
2367 resp
['vim_password']='********'
2368 # except ClientException as e:
2372 table
= PrettyTable(['key', 'attribute'])
2373 for k
, v
in list(resp
.items()):
2374 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2379 ####################
2381 ####################
2383 @cli_osm.command(name
='wim-create', short_help
='creates a new WIM account')
2384 @click.option('--name',
2386 help='Name for the WIM account')
2387 @click.option('--user',
2388 help='WIM username')
2389 @click.option('--password',
2390 help='WIM password')
2391 @click.option('--url',
2394 # @click.option('--tenant',
2395 # help='wIM tenant name')
2396 @click.option('--config',
2398 help='WIM specific config parameters')
2399 @click.option('--wim_type',
2401 @click.option('--description',
2403 help='human readable description')
2404 @click.option('--wim_port_mapping', default
=None,
2405 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2406 "(WAN service endpoint id and info)")
2407 @click.option('--wait',
2411 help='do not return the control immediately, but keep it '
2412 'until the operation is completed, or timeout')
2425 """creates a new WIM account"""
2428 check_client_version(ctx
.obj
, ctx
.command
.name
)
2429 # if sdn_controller:
2430 # check_client_version(ctx.obj, '--sdn_controller')
2431 # if sdn_port_mapping:
2432 # check_client_version(ctx.obj, '--sdn_port_mapping')
2434 if user
: wim
['user'] = user
2435 if password
: wim
['password'] = password
2436 if url
: wim
['wim_url'] = url
2437 # if tenant: wim['tenant'] = tenant
2438 wim
['wim_type'] = wim_type
2439 if description
: wim
['description'] = description
2440 if config
: wim
['config'] = config
2441 ctx
.obj
.wim
.create(name
, wim
, wim_port_mapping
, wait
=wait
)
2442 # except ClientException as e:
2447 @cli_osm.command(name
='wim-update', short_help
='updates a WIM account')
2448 @click.argument('name')
2449 @click.option('--newname', help='New name for the WIM account')
2450 @click.option('--user', help='WIM username')
2451 @click.option('--password', help='WIM password')
2452 @click.option('--url', help='WIM url')
2453 @click.option('--config', help='WIM specific config parameters')
2454 @click.option('--wim_type', help='WIM type')
2455 @click.option('--description', help='human readable description')
2456 @click.option('--wim_port_mapping', default
=None,
2457 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2458 "(WAN service endpoint id and info)")
2459 @click.option('--wait',
2463 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2476 """updates a WIM account
2478 NAME: name or ID of the WIM account
2482 check_client_version(ctx
.obj
, ctx
.command
.name
)
2484 if newname
: wim
['name'] = newname
2485 if user
: wim
['user'] = user
2486 if password
: wim
['password'] = password
2487 if url
: wim
['url'] = url
2488 # if tenant: wim['tenant'] = tenant
2489 if wim_type
: wim
['wim_type'] = wim_type
2490 if description
: wim
['description'] = description
2491 if config
: wim
['config'] = config
2492 ctx
.obj
.wim
.update(name
, wim
, wim_port_mapping
, wait
=wait
)
2493 # except ClientException as e:
2498 @cli_osm.command(name
='wim-delete', short_help
='deletes a WIM account')
2499 @click.argument('name')
2500 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2501 @click.option('--wait',
2505 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2507 def wim_delete(ctx
, name
, force
, wait
):
2508 """deletes a WIM account
2510 NAME: name or ID of the WIM account to be deleted
2514 check_client_version(ctx
.obj
, ctx
.command
.name
)
2515 ctx
.obj
.wim
.delete(name
, force
, wait
=wait
)
2516 # except ClientException as e:
2521 @cli_osm.command(name
='wim-list', short_help
='list all WIM accounts')
2522 @click.option('--filter', default
=None,
2523 help='restricts the list to the WIM accounts matching the filter')
2525 def wim_list(ctx
, filter):
2526 """list all WIM accounts"""
2529 check_client_version(ctx
.obj
, ctx
.command
.name
)
2530 resp
= ctx
.obj
.wim
.list(filter)
2531 table
= PrettyTable(['wim name', 'uuid'])
2533 table
.add_row([wim
['name'], wim
['uuid']])
2536 # except ClientException as e:
2541 @cli_osm.command(name
='wim-show', short_help
='shows the details of a WIM account')
2542 @click.argument('name')
2544 def wim_show(ctx
, name
):
2545 """shows the details of a WIM account
2547 NAME: name or ID of the WIM account
2551 check_client_version(ctx
.obj
, ctx
.command
.name
)
2552 resp
= ctx
.obj
.wim
.get(name
)
2553 if 'password' in resp
:
2554 resp
['wim_password']='********'
2555 # except ClientException as e:
2559 table
= PrettyTable(['key', 'attribute'])
2560 for k
, v
in list(resp
.items()):
2561 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2566 ####################
2567 # SDN controller operations
2568 ####################
2570 @cli_osm.command(name
='sdnc-create', short_help
='creates a new SDN controller')
2571 @click.option('--name',
2573 help='Name to create sdn controller')
2574 @click.option('--type',
2576 help='SDN controller type')
2577 @click.option('--sdn_controller_version', # hidden=True,
2578 help='Deprecated. Use --config {version: sdn_controller_version}')
2579 @click.option('--url',
2580 help='URL in format http[s]://HOST:IP/')
2581 @click.option('--ip_address', # hidden=True,
2582 help='Deprecated. Use --url')
2583 @click.option('--port', # hidden=True,
2584 help='Deprecated. Use --url')
2585 @click.option('--switch_dpid', # hidden=True,
2586 help='Deprecated. Use --config {switch_id: DPID}')
2587 @click.option('--config',
2588 help='Extra information for SDN in yaml format, as {switch_id: identity used for the plugin (e.g. DPID: '
2589 'Openflow Datapath ID), version: version}')
2590 @click.option('--user',
2591 help='SDN controller username')
2592 @click.option('--password',
2594 confirmation_prompt
=True,
2595 help='SDN controller password')
2596 @click.option('--description', default
=None, help='human readable description')
2597 @click.option('--wait',
2601 help="do not return the control immediately, but keep it until the operation is completed, or timeout")
2603 def sdnc_create(ctx
, **kwargs
):
2604 """creates a new SDN controller"""
2606 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2607 x
not in ("wait", "ip_address", "port", "switch_dpid")}
2608 if kwargs
.get("port"):
2609 print("option '--port' is deprecated, use '--url' instead")
2610 sdncontroller
["port"] = int(kwargs
["port"])
2611 if kwargs
.get("ip_address"):
2612 print("option '--ip_address' is deprecated, use '--url' instead")
2613 sdncontroller
["ip"] = kwargs
["ip_address"]
2614 if kwargs
.get("switch_dpid"):
2615 print("option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead")
2616 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2617 if kwargs
.get("sdn_controller_version"):
2618 print("option '--sdn_controller_version' is deprecated, use '--config={version: SDN_CONTROLLER_VERSION}'"
2621 check_client_version(ctx
.obj
, ctx
.command
.name
)
2622 ctx
.obj
.sdnc
.create(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2623 # except ClientException as e:
2627 @cli_osm.command(name
='sdnc-update', short_help
='updates an SDN controller')
2628 @click.argument('name')
2629 @click.option('--newname', help='New name for the SDN controller')
2630 @click.option('--description', default
=None, help='human readable description')
2631 @click.option('--type', help='SDN controller type')
2632 @click.option('--url', help='URL in format http[s]://HOST:IP/')
2633 @click.option('--config', help='Extra information for SDN in yaml format, as '
2634 '{switch_id: identity used for the plugin (e.g. DPID: '
2635 'Openflow Datapath ID), version: version}')
2636 @click.option('--user', help='SDN controller username')
2637 @click.option('--password', help='SDN controller password')
2638 @click.option('--ip_address', help='Deprecated. Use --url') # hidden=True
2639 @click.option('--port', help='Deprecated. Use --url') # hidden=True
2640 @click.option('--switch_dpid', help='Deprecated. Use --config {switch_dpid: DPID}') # hidden=True
2641 @click.option('--sdn_controller_version', help='Deprecated. Use --config {version: VERSION}') # hidden=True
2642 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2643 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2645 def sdnc_update(ctx
, **kwargs
):
2646 """updates an SDN controller
2648 NAME: name or ID of the SDN controller
2651 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2652 x
not in ("wait", "ip_address", "port", "switch_dpid", "new_name")}
2653 if kwargs
.get("newname"):
2654 sdncontroller
["name"] = kwargs
["newname"]
2655 if kwargs
.get("port"):
2656 print("option '--port' is deprecated, use '--url' instead")
2657 sdncontroller
["port"] = int(kwargs
["port"])
2658 if kwargs
.get("ip_address"):
2659 print("option '--ip_address' is deprecated, use '--url' instead")
2660 sdncontroller
["ip"] = kwargs
["ip_address"]
2661 if kwargs
.get("switch_dpid"):
2662 print("option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead")
2663 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2664 if kwargs
.get("sdn_controller_version"):
2665 print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'"
2669 check_client_version(ctx
.obj
, ctx
.command
.name
)
2670 ctx
.obj
.sdnc
.update(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2671 # except ClientException as e:
2676 @cli_osm.command(name
='sdnc-delete', short_help
='deletes an SDN controller')
2677 @click.argument('name')
2678 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2679 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2680 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2682 def sdnc_delete(ctx
, name
, force
, wait
):
2683 """deletes an SDN controller
2685 NAME: name or ID of the SDN controller to be deleted
2689 check_client_version(ctx
.obj
, ctx
.command
.name
)
2690 ctx
.obj
.sdnc
.delete(name
, force
, wait
=wait
)
2691 # except ClientException as e:
2696 @cli_osm.command(name
='sdnc-list', short_help
='list all SDN controllers')
2697 @click.option('--filter', default
=None,
2698 help="restricts the list to the SDN controllers matching the filter with format: 'k[.k..]=v[&k[.k]=v2]'")
2700 def sdnc_list(ctx
, filter):
2701 """list all SDN controllers"""
2704 check_client_version(ctx
.obj
, ctx
.command
.name
)
2705 resp
= ctx
.obj
.sdnc
.list(filter)
2706 # except ClientException as e:
2709 table
= PrettyTable(['sdnc name', 'id'])
2711 table
.add_row([sdnc
['name'], sdnc
['_id']])
2716 @cli_osm.command(name
='sdnc-show', short_help
='shows the details of an SDN controller')
2717 @click.argument('name')
2719 def sdnc_show(ctx
, name
):
2720 """shows the details of an SDN controller
2722 NAME: name or ID of the SDN controller
2726 check_client_version(ctx
.obj
, ctx
.command
.name
)
2727 resp
= ctx
.obj
.sdnc
.get(name
)
2728 # except ClientException as e:
2732 table
= PrettyTable(['key', 'attribute'])
2733 for k
, v
in list(resp
.items()):
2734 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2739 ###########################
2740 # K8s cluster operations
2741 ###########################
2743 @cli_osm.command(name
='k8scluster-add', short_help
='adds a K8s cluster to OSM')
2744 @click.argument('name')
2745 @click.option('--creds',
2747 help='credentials file, i.e. a valid `.kube/config` file')
2748 @click.option('--version',
2750 help='Kubernetes version')
2751 @click.option('--vim',
2753 help='VIM target, the VIM where the cluster resides')
2754 @click.option('--k8s-nets',
2756 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) ...]}"')
2757 @click.option('--description',
2759 help='human readable description')
2760 @click.option('--namespace',
2761 default
='kube-system',
2762 help='namespace to be used for its operation, defaults to `kube-system`')
2763 @click.option('--cni',
2765 help='list of CNI plugins, in JSON inline format, used in the cluster')
2766 #@click.option('--skip-init',
2768 # help='If set, K8s cluster is assumed to be ready for its use with OSM')
2769 #@click.option('--wait',
2771 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2773 def k8scluster_add(ctx
,
2782 """adds a K8s cluster to OSM
2784 NAME: name of the K8s cluster
2787 check_client_version(ctx
.obj
, ctx
.command
.name
)
2789 cluster
['name'] = name
2790 with
open(creds
, 'r') as cf
:
2791 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2792 cluster
['k8s_version'] = version
2793 cluster
['vim_account'] = vim
2794 cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2796 cluster
['description'] = description
2797 if namespace
: cluster
['namespace'] = namespace
2798 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2799 ctx
.obj
.k8scluster
.create(name
, cluster
)
2800 # except ClientException as e:
2805 @cli_osm.command(name
='k8scluster-update', short_help
='updates a K8s cluster')
2806 @click.argument('name')
2807 @click.option('--newname', help='New name for the K8s cluster')
2808 @click.option('--creds', help='credentials file, i.e. a valid `.kube/config` file')
2809 @click.option('--version', help='Kubernetes version')
2810 @click.option('--vim', help='VIM target, the VIM where the cluster resides')
2811 @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) ...]}"')
2812 @click.option('--description', help='human readable description')
2813 @click.option('--namespace', help='namespace to be used for its operation, defaults to `kube-system`')
2814 @click.option('--cni', help='list of CNI plugins, in JSON inline format, used in the cluster')
2816 def k8scluster_update(ctx
,
2826 """updates a K8s cluster
2828 NAME: name or ID of the K8s cluster
2831 check_client_version(ctx
.obj
, ctx
.command
.name
)
2833 if newname
: cluster
['name'] = newname
2835 with
open(creds
, 'r') as cf
:
2836 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2837 if version
: cluster
['k8s_version'] = version
2838 if vim
: cluster
['vim_account'] = vim
2839 if k8s_nets
: cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2840 if description
: cluster
['description'] = description
2841 if namespace
: cluster
['namespace'] = namespace
2842 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2843 ctx
.obj
.k8scluster
.update(name
, cluster
)
2844 # except ClientException as e:
2849 @cli_osm.command(name
='k8scluster-delete', short_help
='deletes a K8s cluster')
2850 @click.argument('name')
2851 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2852 #@click.option('--wait',
2854 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2856 def k8scluster_delete(ctx
, name
, force
):
2857 """deletes a K8s cluster
2859 NAME: name or ID of the K8s cluster to be deleted
2862 check_client_version(ctx
.obj
, ctx
.command
.name
)
2863 ctx
.obj
.k8scluster
.delete(name
, force
=force
)
2864 # except ClientException as e:
2869 @cli_osm.command(name
='k8scluster-list')
2870 @click.option('--filter', default
=None,
2871 help='restricts the list to the K8s clusters matching the filter')
2872 @click.option('--literal', is_flag
=True,
2873 help='print literally, no pretty table')
2875 def k8scluster_list(ctx
, filter, literal
):
2876 """list all K8s clusters"""
2878 check_client_version(ctx
.obj
, ctx
.command
.name
)
2879 resp
= ctx
.obj
.k8scluster
.list(filter)
2881 print(yaml
.safe_dump(resp
))
2883 table
= PrettyTable(['Name', 'Id', 'Version', 'VIM', 'K8s-nets', 'Operational State', 'Description'])
2884 for cluster
in resp
:
2885 table
.add_row([cluster
['name'], cluster
['_id'], cluster
['k8s_version'], cluster
['vim_account'],
2886 json
.dumps(cluster
['nets']), cluster
["_admin"]["operationalState"],
2887 trunc_text(cluster
.get('description',''),40)])
2890 # except ClientException as e:
2895 @cli_osm.command(name
='k8scluster-show', short_help
='shows the details of a K8s cluster')
2896 @click.argument('name')
2897 @click.option('--literal', is_flag
=True,
2898 help='print literally, no pretty table')
2900 def k8scluster_show(ctx
, name
, literal
):
2901 """shows the details of a K8s cluster
2903 NAME: name or ID of the K8s cluster
2906 resp
= ctx
.obj
.k8scluster
.get(name
)
2908 print(yaml
.safe_dump(resp
))
2910 table
= PrettyTable(['key', 'attribute'])
2911 for k
, v
in list(resp
.items()):
2912 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2915 # except ClientException as e:
2921 ###########################
2923 ###########################
2925 @cli_osm.command(name
='repo-add', short_help
='adds a repo to OSM')
2926 @click.argument('name')
2927 @click.argument('uri')
2928 @click.option('--type',
2929 type=click
.Choice(['helm-chart', 'juju-bundle']),
2931 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2932 @click.option('--description',
2934 help='human readable description')
2935 #@click.option('--wait',
2937 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2944 """adds a repo to OSM
2946 NAME: name of the repo
2947 URI: URI of the repo
2950 check_client_version(ctx
.obj
, ctx
.command
.name
)
2956 repo
['description'] = description
2957 ctx
.obj
.repo
.create(name
, repo
)
2958 # except ClientException as e:
2963 @cli_osm.command(name
='repo-update', short_help
='updates a repo in OSM')
2964 @click.argument('name')
2965 @click.option('--newname', help='New name for the repo')
2966 @click.option('--uri', help='URI of the repo')
2967 @click.option('--type', type=click
.Choice(['helm-chart', 'juju-bundle']),
2968 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2969 @click.option('--description', help='human readable description')
2970 #@click.option('--wait',
2972 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2974 def repo_update(ctx
,
2980 """updates a repo in OSM
2982 NAME: name of the repo
2985 check_client_version(ctx
.obj
, ctx
.command
.name
)
2987 if newname
: repo
['name'] = newname
2988 if uri
: repo
['uri'] = uri
2989 if type: repo
['type'] = type
2990 if description
: repo
['description'] = description
2991 ctx
.obj
.repo
.update(name
, repo
)
2992 # except ClientException as e:
2997 @cli_osm.command(name
='repo-delete', short_help
='deletes a repo')
2998 @click.argument('name')
2999 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
3000 #@click.option('--wait',
3002 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3004 def repo_delete(ctx
, name
, force
):
3007 NAME: name or ID of the repo to be deleted
3010 check_client_version(ctx
.obj
, ctx
.command
.name
)
3011 ctx
.obj
.repo
.delete(name
, force
=force
)
3012 # except ClientException as e:
3017 @cli_osm.command(name
='repo-list')
3018 @click.option('--filter', default
=None,
3019 help='restricts the list to the repos matching the filter')
3020 @click.option('--literal', is_flag
=True,
3021 help='print literally, no pretty table')
3023 def repo_list(ctx
, filter, literal
):
3024 """list all repos"""
3026 check_client_version(ctx
.obj
, ctx
.command
.name
)
3027 resp
= ctx
.obj
.repo
.list(filter)
3029 print(yaml
.safe_dump(resp
))
3031 table
= PrettyTable(['Name', 'Id', 'Type', 'URI', 'Description'])
3033 #cluster['k8s-nets'] = json.dumps(yaml.safe_load(cluster['k8s-nets']))
3034 table
.add_row([repo
['name'], repo
['_id'], repo
['type'], repo
['url'], trunc_text(repo
.get('description',''),40)])
3037 # except ClientException as e:
3042 @cli_osm.command(name
='repo-show', short_help
='shows the details of a repo')
3043 @click.argument('name')
3044 @click.option('--literal', is_flag
=True,
3045 help='print literally, no pretty table')
3047 def repo_show(ctx
, name
, literal
):
3048 """shows the details of a repo
3050 NAME: name or ID of the repo
3053 resp
= ctx
.obj
.repo
.get(name
)
3055 print(yaml
.safe_dump(resp
))
3057 table
= PrettyTable(['key', 'attribute'])
3058 for k
, v
in list(resp
.items()):
3059 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3062 # except ClientException as e:
3068 ####################
3069 # Project mgmt operations
3070 ####################
3072 @cli_osm.command(name
='project-create', short_help
='creates a new project')
3073 @click.argument('name')
3074 #@click.option('--description',
3075 # default='no description',
3076 # help='human readable description')
3077 @click.option('--domain-name', 'domain_name',
3079 help='assign to a domain')
3081 def project_create(ctx
, name
, domain_name
):
3082 """Creates a new project
3084 NAME: name of the project
3085 DOMAIN_NAME: optional domain name for the project when keystone authentication is used
3089 project
['name'] = name
3091 project
['domain_name'] = domain_name
3093 check_client_version(ctx
.obj
, ctx
.command
.name
)
3094 ctx
.obj
.project
.create(name
, project
)
3095 # except ClientException as e:
3100 @cli_osm.command(name
='project-delete', short_help
='deletes a project')
3101 @click.argument('name')
3102 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3104 def project_delete(ctx
, name
):
3105 """deletes a project
3107 NAME: name or ID of the project to be deleted
3111 check_client_version(ctx
.obj
, ctx
.command
.name
)
3112 ctx
.obj
.project
.delete(name
)
3113 # except ClientException as e:
3118 @cli_osm.command(name
='project-list', short_help
='list all projects')
3119 @click.option('--filter', default
=None,
3120 help='restricts the list to the projects matching the filter')
3122 def project_list(ctx
, filter):
3123 """list all projects"""
3126 check_client_version(ctx
.obj
, ctx
.command
.name
)
3127 resp
= ctx
.obj
.project
.list(filter)
3128 # except ClientException as e:
3131 table
= PrettyTable(['name', 'id'])
3133 table
.add_row([proj
['name'], proj
['_id']])
3138 @cli_osm.command(name
='project-show', short_help
='shows the details of a project')
3139 @click.argument('name')
3141 def project_show(ctx
, name
):
3142 """shows the details of a project
3144 NAME: name or ID of the project
3148 check_client_version(ctx
.obj
, ctx
.command
.name
)
3149 resp
= ctx
.obj
.project
.get(name
)
3150 # except ClientException as e:
3154 table
= PrettyTable(['key', 'attribute'])
3155 for k
, v
in resp
.items():
3156 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3161 @cli_osm.command(name
='project-update', short_help
='updates a project (only the name can be updated)')
3162 @click.argument('project')
3163 @click.option('--name',
3165 help='new name for the project')
3168 def project_update(ctx
, project
, name
):
3170 Update a project name
3173 :param project: id or name of the project to modify
3174 :param name: new name for the project
3178 project_changes
= {}
3179 project_changes
['name'] = name
3182 check_client_version(ctx
.obj
, ctx
.command
.name
)
3183 ctx
.obj
.project
.update(project
, project_changes
)
3184 # except ClientException as e:
3188 ####################
3189 # User mgmt operations
3190 ####################
3192 @cli_osm.command(name
='user-create', short_help
='creates a new user')
3193 @click.argument('username')
3194 @click.option('--password',
3197 confirmation_prompt
=True,
3198 help='user password')
3199 @click.option('--projects',
3200 # prompt="Comma separate list of projects",
3202 callback
=lambda ctx
, param
, value
: ''.join(value
).split(',') if all(len(x
)==1 for x
in value
) else value
,
3203 help='list of project ids that the user belongs to')
3204 @click.option('--project-role-mappings', 'project_role_mappings',
3205 default
=None, multiple
=True,
3206 help="assign role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3207 @click.option('--domain-name', 'domain_name',
3209 help='assign to a domain')
3211 def user_create(ctx
, username
, password
, projects
, project_role_mappings
, domain_name
):
3212 """Creates a new user
3215 USERNAME: name of the user
3216 PASSWORD: password of the user
3217 PROJECTS: projects assigned to user (internal only)
3218 PROJECT_ROLE_MAPPING: roles in projects assigned to user (keystone)
3219 DOMAIN_NAME: optional domain name for the user when keystone authentication is used
3223 user
['username'] = username
3224 user
['password'] = password
3225 user
['projects'] = projects
3226 user
['project_role_mappings'] = project_role_mappings
3228 user
['domain_name'] = domain_name
3231 check_client_version(ctx
.obj
, ctx
.command
.name
)
3232 ctx
.obj
.user
.create(username
, user
)
3233 # except ClientException as e:
3238 @cli_osm.command(name
='user-update', short_help
='updates user information')
3239 @click.argument('username')
3240 @click.option('--password',
3243 # confirmation_prompt=True,
3244 help='user password')
3245 @click.option('--set-username', 'set_username',
3247 help='change username')
3248 @click.option('--set-project', 'set_project',
3249 default
=None, multiple
=True,
3250 help="create/replace the roles for this project: 'project,role1[,role2,...]'")
3251 @click.option('--remove-project', 'remove_project',
3252 default
=None, multiple
=True,
3253 help="removes project from user: 'project'")
3254 @click.option('--add-project-role', 'add_project_role',
3255 default
=None, multiple
=True,
3256 help="assign role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3257 @click.option('--remove-project-role', 'remove_project_role',
3258 default
=None, multiple
=True,
3259 help="remove role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3261 def user_update(ctx
, username
, password
, set_username
, set_project
, remove_project
,
3262 add_project_role
, remove_project_role
):
3263 """Update a user information
3266 USERNAME: name of the user
3267 PASSWORD: new password
3268 SET_USERNAME: new username
3269 SET_PROJECT: creating mappings for project/role(s)
3270 REMOVE_PROJECT: deleting mappings for project/role(s)
3271 ADD_PROJECT_ROLE: adding mappings for project/role(s)
3272 REMOVE_PROJECT_ROLE: removing mappings for project/role(s)
3276 user
['password'] = password
3277 user
['username'] = set_username
3278 user
['set-project'] = set_project
3279 user
['remove-project'] = remove_project
3280 user
['add-project-role'] = add_project_role
3281 user
['remove-project-role'] = remove_project_role
3284 check_client_version(ctx
.obj
, ctx
.command
.name
)
3285 ctx
.obj
.user
.update(username
, user
)
3286 # except ClientException as e:
3291 @cli_osm.command(name
='user-delete', short_help
='deletes a user')
3292 @click.argument('name')
3293 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3295 def user_delete(ctx
, name
):
3299 NAME: name or ID of the user to be deleted
3303 check_client_version(ctx
.obj
, ctx
.command
.name
)
3304 ctx
.obj
.user
.delete(name
)
3305 # except ClientException as e:
3310 @cli_osm.command(name
='user-list', short_help
='list all users')
3311 @click.option('--filter', default
=None,
3312 help='restricts the list to the users matching the filter')
3314 def user_list(ctx
, filter):
3315 """list all users"""
3317 check_client_version(ctx
.obj
, ctx
.command
.name
)
3318 resp
= ctx
.obj
.user
.list(filter)
3319 # except ClientException as e:
3322 table
= PrettyTable(['name', 'id'])
3324 table
.add_row([user
['username'], user
['_id']])
3329 @cli_osm.command(name
='user-show', short_help
='shows the details of a user')
3330 @click.argument('name')
3332 def user_show(ctx
, name
):
3333 """shows the details of a user
3335 NAME: name or ID of the user
3339 check_client_version(ctx
.obj
, ctx
.command
.name
)
3340 resp
= ctx
.obj
.user
.get(name
)
3341 if 'password' in resp
:
3342 resp
['password']='********'
3343 # except ClientException as e:
3347 table
= PrettyTable(['key', 'attribute'])
3348 for k
, v
in resp
.items():
3349 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3354 ####################
3355 # Fault Management operations
3356 ####################
3358 @cli_osm.command(name
='ns-alarm-create')
3359 @click.argument('name')
3360 @click.option('--ns', prompt
=True, help='NS instance id or name')
3361 @click.option('--vnf', prompt
=True,
3362 help='VNF name (VNF member index as declared in the NSD)')
3363 @click.option('--vdu', prompt
=True,
3364 help='VDU name (VDU name as declared in the VNFD)')
3365 @click.option('--metric', prompt
=True,
3366 help='Name of the metric (e.g. cpu_utilization)')
3367 @click.option('--severity', default
='WARNING',
3368 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
3369 @click.option('--threshold_value', prompt
=True,
3370 help='threshold value that, when crossed, an alarm is triggered')
3371 @click.option('--threshold_operator', prompt
=True,
3372 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
3373 @click.option('--statistic', default
='AVERAGE',
3374 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
3376 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
3377 threshold_value
, threshold_operator
, statistic
):
3378 """creates a new alarm for a NS instance"""
3379 # TODO: Check how to validate threshold_value.
3380 # Should it be an integer (1-100), percentage, or decimal (0.01-1.00)?
3383 ns_instance
= ctx
.obj
.ns
.get(ns
)
3385 alarm
['alarm_name'] = name
3386 alarm
['ns_id'] = ns_instance
['_id']
3387 alarm
['correlation_id'] = ns_instance
['_id']
3388 alarm
['vnf_member_index'] = vnf
3389 alarm
['vdu_name'] = vdu
3390 alarm
['metric_name'] = metric
3391 alarm
['severity'] = severity
3392 alarm
['threshold_value'] = int(threshold_value
)
3393 alarm
['operation'] = threshold_operator
3394 alarm
['statistic'] = statistic
3395 check_client_version(ctx
.obj
, ctx
.command
.name
)
3396 ctx
.obj
.ns
.create_alarm(alarm
)
3397 # except ClientException as e:
3402 #@cli_osm.command(name='ns-alarm-delete')
3403 #@click.argument('name')
3404 #@click.pass_context
3405 #def ns_alarm_delete(ctx, name):
3406 # """deletes an alarm
3408 # NAME: name of the alarm to be deleted
3411 # check_client_version(ctx.obj, ctx.command.name)
3412 # ctx.obj.ns.delete_alarm(name)
3413 # except ClientException as e:
3418 ####################
3419 # Performance Management operations
3420 ####################
3422 @cli_osm.command(name
='ns-metric-export', short_help
='exports a metric to the internal OSM bus, which can be read by other apps')
3423 @click.option('--ns', prompt
=True, help='NS instance id or name')
3424 @click.option('--vnf', prompt
=True,
3425 help='VNF name (VNF member index as declared in the NSD)')
3426 @click.option('--vdu', prompt
=True,
3427 help='VDU name (VDU name as declared in the VNFD)')
3428 @click.option('--metric', prompt
=True,
3429 help='name of the metric (e.g. cpu_utilization)')
3430 #@click.option('--period', default='1w',
3431 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
3432 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
3434 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
3435 """exports a metric to the internal OSM bus, which can be read by other apps"""
3436 # TODO: Check how to validate interval.
3437 # Should it be an integer (seconds), or should a suffix (s,m,h,d,w) also be permitted?
3440 ns_instance
= ctx
.obj
.ns
.get(ns
)
3442 metric_data
['ns_id'] = ns_instance
['_id']
3443 metric_data
['correlation_id'] = ns_instance
['_id']
3444 metric_data
['vnf_member_index'] = vnf
3445 metric_data
['vdu_name'] = vdu
3446 metric_data
['metric_name'] = metric
3447 metric_data
['collection_unit'] = 'WEEK'
3448 metric_data
['collection_period'] = 1
3449 check_client_version(ctx
.obj
, ctx
.command
.name
)
3451 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
3455 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
3456 time
.sleep(int(interval
))
3458 # except ClientException as e:
3463 ####################
3465 ####################
3467 @cli_osm.command(name
='version', short_help
='shows client and server versions')
3469 def get_version(ctx
):
3470 """shows client and server versions"""
3472 check_client_version(ctx
.obj
, "version")
3473 print ("Server version: {}".format(ctx
.obj
.get_version()))
3474 print ("Client version: {}".format(pkg_resources
.get_distribution("osmclient").version
))
3475 # except ClientException as e:
3479 @cli_osm.command(name
='upload-package', short_help
='uploads a VNF package or NS package')
3480 @click.argument('filename')
3481 @click.option('--skip-charm-build', default
=False, is_flag
=True,
3482 help='the charm will not be compiled, it is assumed to already exist')
3484 def upload_package(ctx
, filename
, skip_charm_build
):
3485 """uploads a vnf package or ns package
3487 filename: vnf or ns package folder, or vnf or ns package file (tar.gz)
3491 ctx
.obj
.package
.upload(filename
, skip_charm_build
=skip_charm_build
)
3492 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
3493 if fullclassname
!= 'osmclient.sol005.client.Client':
3494 ctx
.obj
.package
.wait_for_upload(filename
)
3495 # except ClientException as e:
3500 #@cli_osm.command(name='ns-scaling-show')
3501 #@click.argument('ns_name')
3502 #@click.pass_context
3503 #def show_ns_scaling(ctx, ns_name):
3504 # """shows the status of a NS scaling operation
3506 # NS_NAME: name of the NS instance being scaled
3509 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3510 # resp = ctx.obj.ns.list()
3511 # except ClientException as e:
3515 # table = PrettyTable(
3518 # 'operational status',
3523 # if ns_name == ns['name']:
3524 # nsopdata = ctx.obj.ns.get_opdata(ns['id'])
3525 # scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
3526 # for record in scaling_records:
3527 # if 'instance' in record:
3528 # instances = record['instance']
3529 # for inst in instances:
3531 # [record['scaling-group-name-ref'],
3532 # inst['instance-id'],
3533 # inst['op-status'],
3534 # time.strftime('%Y-%m-%d %H:%M:%S',
3536 # inst['create-time'])),
3542 #@cli_osm.command(name='ns-scale')
3543 #@click.argument('ns_name')
3544 #@click.option('--ns_scale_group', prompt=True)
3545 #@click.option('--index', prompt=True)
3546 #@click.option('--wait',
3550 # help='do not return the control immediately, but keep it \
3551 # until the operation is completed, or timeout')
3552 #@click.pass_context
3553 #def ns_scale(ctx, ns_name, ns_scale_group, index, wait):
3556 # NS_NAME: name of the NS instance to be scaled
3559 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3560 # ctx.obj.ns.scale(ns_name, ns_scale_group, index, wait=wait)
3561 # except ClientException as e:
3566 #@cli_osm.command(name='config-agent-list')
3567 #@click.pass_context
3568 #def config_agent_list(ctx):
3569 # """list config agents"""
3571 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3572 # except ClientException as e:
3575 # table = PrettyTable(['name', 'account-type', 'details'])
3576 # for account in ctx.obj.vca.list():
3579 # account['account-type'],
3585 #@cli_osm.command(name='config-agent-delete')
3586 #@click.argument('name')
3587 #@click.pass_context
3588 #def config_agent_delete(ctx, name):
3589 # """deletes a config agent
3591 # NAME: name of the config agent to be deleted
3594 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3595 # ctx.obj.vca.delete(name)
3596 # except ClientException as e:
3601 #@cli_osm.command(name='config-agent-add')
3602 #@click.option('--name',
3604 #@click.option('--account_type',
3606 #@click.option('--server',
3608 #@click.option('--user',
3610 #@click.option('--secret',
3613 # confirmation_prompt=True)
3614 #@click.pass_context
3615 #def config_agent_add(ctx, name, account_type, server, user, secret):
3616 # """adds a config agent"""
3618 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3619 # ctx.obj.vca.create(name, account_type, server, user, secret)
3620 # except ClientException as e:
3625 #@cli_osm.command(name='ro-dump')
3626 #@click.pass_context
3628 # """shows RO agent information"""
3629 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3630 # resp = ctx.obj.vim.get_resource_orchestrator()
3631 # table = PrettyTable(['key', 'attribute'])
3632 # for k, v in list(resp.items()):
3633 # table.add_row([k, json.dumps(v, indent=2)])
3638 #@cli_osm.command(name='vcs-list')
3639 #@click.pass_context
3641 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3642 # resp = ctx.obj.utils.get_vcs_info()
3643 # table = PrettyTable(['component name', 'state'])
3644 # for component in resp:
3645 # table.add_row([component['component_name'], component['state']])
3650 @cli_osm.command(name
='ns-action', short_help
='executes an action/primitive over a NS instance')
3651 @click.argument('ns_name')
3652 @click.option('--vnf_name', default
=None, help='member-vnf-index if the target is a vnf instead of a ns)')
3653 @click.option('--kdu_name', default
=None, help='kdu-name if the target is a kdu)')
3654 @click.option('--vdu_id', default
=None, help='vdu-id if the target is a vdu')
3655 @click.option('--vdu_count', default
=None, help='number of vdu instance of this vdu_id')
3656 @click.option('--action_name', prompt
=True, help='action name')
3657 @click.option('--params', default
=None, help='action params in YAML/JSON inline string')
3658 @click.option('--params_file', default
=None, help='YAML/JSON file with action params')
3659 @click.option('--timeout', required
=False, default
=None, type=int, help='timeout in seconds')
3660 @click.option('--wait',
3664 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3677 """executes an action/primitive over a NS instance
3679 NS_NAME: name or ID of the NS instance
3683 check_client_version(ctx
.obj
, ctx
.command
.name
)
3686 op_data
['member_vnf_index'] = vnf_name
3688 op_data
['kdu_name'] = kdu_name
3690 op_data
['vdu_id'] = vdu_id
3692 op_data
['vdu_count_index'] = vdu_count
3694 op_data
['timeout_ns_action'] = timeout
3695 op_data
['primitive'] = action_name
3697 with
open(params_file
, 'r') as pf
:
3700 op_data
['primitive_params'] = yaml
.safe_load(params
)
3702 op_data
['primitive_params'] = {}
3703 print(ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
, wait
=wait
))
3705 # except ClientException as e:
3710 @cli_osm.command(name
='vnf-scale', short_help
='executes a VNF scale (adding/removing VDUs)')
3711 @click.argument('ns_name')
3712 @click.argument('vnf_name')
3713 @click.option('--scaling-group', prompt
=True, help="scaling-group-descriptor name to use")
3714 @click.option('--scale-in', default
=False, is_flag
=True, help="performs a scale in operation")
3715 @click.option('--scale-out', default
=False, is_flag
=True, help="performs a scale out operation (by default)")
3716 @click.option('--timeout', required
=False, default
=None, type=int, help='timeout in seconds')
3717 @click.option('--wait', required
=False, default
=False, is_flag
=True,
3718 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3729 Executes a VNF scale (adding/removing VDUs)
3732 NS_NAME: name or ID of the NS instance.
3733 VNF_NAME: member-vnf-index in the NS to be scaled.
3737 check_client_version(ctx
.obj
, ctx
.command
.name
)
3738 if not scale_in
and not scale_out
:
3740 ctx
.obj
.ns
.scale_vnf(ns_name
, vnf_name
, scaling_group
, scale_in
, scale_out
, wait
, timeout
)
3741 # except ClientException as e:
3746 ##############################
3747 # Role Management Operations #
3748 ##############################
3750 @cli_osm.command(name
='role-create', short_help
='creates a new role')
3751 @click.argument('name')
3752 @click.option('--permissions',
3754 help='role permissions using a dictionary')
3756 def role_create(ctx
, name
, permissions
):
3761 NAME: Name or ID of the role.
3762 DEFINITION: Definition of grant/denial of access to resources.
3766 check_client_version(ctx
.obj
, ctx
.command
.name
)
3767 ctx
.obj
.role
.create(name
, permissions
)
3768 # except ClientException as e:
3773 @cli_osm.command(name
='role-update', short_help
='updates a role')
3774 @click.argument('name')
3775 @click.option('--set-name',
3777 help='change name of rle')
3778 # @click.option('--permissions',
3780 # help='provide a yaml format dictionary with incremental changes. Values can be bool or None to delete')
3781 @click.option('--add',
3783 help='yaml format dictionary with permission: True/False to access grant/denial')
3784 @click.option('--remove',
3786 help='yaml format list to remove a permission')
3788 def role_update(ctx
, name
, set_name
, add
, remove
):
3793 NAME: Name or ID of the role.
3794 DEFINITION: Definition overwrites the old definition.
3795 ADD: Grant/denial of access to resource to add.
3796 REMOVE: Grant/denial of access to resource to remove.
3800 check_client_version(ctx
.obj
, ctx
.command
.name
)
3801 ctx
.obj
.role
.update(name
, set_name
, None, add
, remove
)
3802 # except ClientException as e:
3807 @cli_osm.command(name
='role-delete', short_help
='deletes a role')
3808 @click.argument('name')
3809 # @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3811 def role_delete(ctx
, name
):
3816 NAME: Name or ID of the role.
3820 check_client_version(ctx
.obj
, ctx
.command
.name
)
3821 ctx
.obj
.role
.delete(name
)
3822 # except ClientException as e:
3827 @cli_osm.command(name
='role-list', short_help
='list all roles')
3828 @click.option('--filter', default
=None,
3829 help='restricts the list to the projects matching the filter')
3831 def role_list(ctx
, filter):
3837 check_client_version(ctx
.obj
, ctx
.command
.name
)
3838 resp
= ctx
.obj
.role
.list(filter)
3839 # except ClientException as e:
3842 table
= PrettyTable(['name', 'id'])
3844 table
.add_row([role
['name'], role
['_id']])
3849 @cli_osm.command(name
='role-show', short_help
='show specific role')
3850 @click.argument('name')
3852 def role_show(ctx
, name
):
3854 Shows the details of a role.
3857 NAME: Name or ID of the role.
3861 check_client_version(ctx
.obj
, ctx
.command
.name
)
3862 resp
= ctx
.obj
.role
.get(name
)
3863 # except ClientException as e:
3867 table
= PrettyTable(['key', 'attribute'])
3868 for k
, v
in resp
.items():
3869 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3874 @cli_osm.command(name
='package-create',
3875 short_help
='Create a package descriptor')
3876 @click.argument('package-type')
3877 @click.argument('package-name')
3878 @click.option('--base-directory',
3880 help=('(NS/VNF/NST) Set the location for package creation. Default: "."'))
3881 @click.option('--image',
3882 default
="image-name",
3883 help='(VNF) Set the name of the vdu image. Default "image-name"')
3884 @click.option('--vdus',
3886 help='(VNF) Set the number of vdus in a VNF. Default 1')
3887 @click.option('--vcpu',
3889 help='(VNF) Set the number of virtual CPUs in a vdu. Default 1')
3890 @click.option('--memory',
3892 help='(VNF) Set the memory size (MB) of the vdu. Default 1024')
3893 @click.option('--storage',
3895 help='(VNF) Set the disk size (GB) of the vdu. Default 10')
3896 @click.option('--interfaces',
3898 help='(VNF) Set the number of additional interfaces apart from the management interface. Default 0')
3899 @click.option('--vendor',
3901 help='(NS/VNF) Set the descriptor vendor. Default "OSM"')
3902 @click.option('--override',
3905 help='(NS/VNF/NST) Flag for overriding the package if exists.')
3906 @click.option('--detailed',
3909 help='(NS/VNF/NST) Flag for generating descriptor .yaml with all possible commented options')
3910 @click.option('--netslice-subnets',
3912 help='(NST) Number of netslice subnets. Default 1')
3913 @click.option('--netslice-vlds',
3915 help='(NST) Number of netslice vlds. Default 1')
3917 def package_create(ctx
,
3933 Creates an OSM NS, VNF, NST package
3936 PACKAGE_TYPE: Package to be created: NS, VNF or NST.
3937 PACKAGE_NAME: Name of the package to create the folder with the content.
3941 check_client_version(ctx
.obj
, ctx
.command
.name
)
3942 print("Creating the {} structure: {}/{}".format(package_type
.upper(), base_directory
, package_name
))
3943 resp
= ctx
.obj
.package_tool
.create(package_type
,
3952 interfaces
=interfaces
,
3955 netslice_subnets
=netslice_subnets
,
3956 netslice_vlds
=netslice_vlds
)
3958 # except ClientException as inst:
3959 # print("ERROR: {}".format(inst))
3962 @cli_osm.command(name
='package-validate',
3963 short_help
='Validate a package descriptor')
3964 @click.argument('base-directory',
3967 @click.option('--recursive/--no-recursive',
3969 help='The activated recursive option will validate the yaml files'
3970 ' within the indicated directory and in its subdirectories')
3972 def package_validate(ctx
,
3976 Validate descriptors given a base directory.
3979 BASE_DIRECTORY: Stub folder for NS, VNF or NST package.
3982 check_client_version(ctx
.obj
, ctx
.command
.name
)
3983 results
= ctx
.obj
.package_tool
.validate(base_directory
, recursive
)
3984 table
= PrettyTable()
3985 table
.field_names
= ["TYPE", "PATH", "VALID", "ERROR"]
3986 # Print the dictionary generated by the validation function
3987 for result
in results
:
3988 table
.add_row([result
["type"], result
["path"], result
["valid"], result
["error"]])
3989 table
.sortby
= "VALID"
3990 table
.align
["PATH"] = "l"
3991 table
.align
["TYPE"] = "l"
3992 table
.align
["ERROR"] = "l"
3994 # except ClientException as inst:
3995 # print("ERROR: {}".format(inst))
3998 @cli_osm.command(name
='package-build',
3999 short_help
='Build the tar.gz of the package')
4000 @click.argument('package-folder')
4001 @click.option('--skip-validation',
4004 help='skip package validation')
4005 @click.option('--skip-charm-build', default
=False, is_flag
=True,
4006 help='the charm will not be compiled, it is assumed to already exist')
4008 def package_build(ctx
,
4013 Build the package NS, VNF given the package_folder.
4016 PACKAGE_FOLDER: Folder of the NS, VNF or NST to be packaged
4019 check_client_version(ctx
.obj
, ctx
.command
.name
)
4020 results
= ctx
.obj
.package_tool
.build(package_folder
,
4021 skip_validation
=skip_validation
,
4022 skip_charm_build
=skip_charm_build
)
4024 # except ClientException as inst:
4025 # print("ERROR: {}".format(inst))
4033 except pycurl
.error
as exc
:
4035 print('Maybe "--hostname" option or OSM_HOSTNAME environment variable needs to be specified')
4036 except ClientException
as exc
:
4037 print("ERROR: {}".format(exc
))
4038 except (FileNotFoundError
, PermissionError
) as exc
:
4039 print("Cannot open file: {}".format(exc
))
4040 except yaml
.YAMLError
as exc
:
4041 print("Invalid YAML format: {}".format(exc
))
4043 # TODO capture other controlled exceptions here
4044 # TODO remove the ClientException captures from all places, unless they do something different
4047 if __name__
== '__main__':