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
):
233 net_list
= status_dict
.get('nets',[])
236 if net
['status'] not in status_nets
:
237 status_nets
[net
['status']] = 1
239 status_nets
[net
['status']] +=1
241 for k
,v
in status_nets
.items():
242 message
+= "{}:{},".format(k
,v
)
243 message
+= "TOTAL:{}".format(n_nets
)
244 summary
+= "{}".format(message
)
249 vnf_list
= status_dict
['vnfs']
251 member_vnf_index
= vnf
['member_vnf_index']
252 if member_vnf_index
not in status_vnfs
:
253 status_vnfs
[member_vnf_index
] = {}
254 for vm
in vnf
['vms']:
256 if vm
['status'] not in status_vms
:
257 status_vms
[vm
['status']] = 1
259 status_vms
[vm
['status']] +=1
260 if vm
['status'] not in status_vnfs
[member_vnf_index
]:
261 status_vnfs
[member_vnf_index
][vm
['status']] = 1
263 status_vnfs
[member_vnf_index
][vm
['status']] += 1
265 for k
,v
in status_vms
.items():
266 message
+= "{}:{},".format(k
,v
)
267 message
+= "TOTAL:{}".format(n_vms
)
268 summary
+= "\n{}".format(message
)
270 for k
,v
in status_vnfs
.items():
272 message
= "\n {} VMs: ".format(k
)
273 for k2
,v2
in v
.items():
274 message
+= "{}:{},".format(k2
,v2
)
276 message
+= "TOTAL:{}".format(total
)
280 def summarize_config_status(ee_list
):
285 if ee
['elementType'] not in status_ee
:
286 status_ee
[ee
['elementType']] = {}
287 status_ee
[ee
['elementType']][ee
['status']] = 1
289 if ee
['status'] in status_ee
[ee
['elementType']]:
290 status_ee
[ee
['elementType']][ee
['status']] += 1
292 status_ee
[ee
['elementType']][ee
['status']] = 1
294 for elementType
in ["KDU", "VDU", "PDU", "VNF", "NS"]:
295 if elementType
in status_ee
:
298 for k
,v
in status_ee
[elementType
].items():
299 message
+= "{}:{},".format(k
,v
)
301 message
+= "TOTAL:{}\n".format(total
)
302 summary
+= "{}: {}".format(elementType
, message
)
303 summary
+= "TOTAL Exec. Env.: {}".format(n_ee
)
308 check_client_version(ctx
.obj
, '--filter')
309 resp
= ctx
.obj
.ns
.list(filter)
311 resp
= ctx
.obj
.ns
.list()
323 'configuration status'])
324 project_list
= ctx
.obj
.project
.list()
325 vim_list
= ctx
.obj
.vim
.list()
335 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
336 if fullclassname
== 'osmclient.sol005.client.Client':
338 logger
.debug('NS info: {}'.format(nsr
))
339 nsr_name
= nsr
['name']
341 date
= datetime
.fromtimestamp(nsr
['create-time']).strftime("%Y-%m-%dT%H:%M:%S")
342 ns_state
= nsr
.get('nsState', nsr
['_admin']['nsState'])
344 deployment_status
= summarize_deployment_status(nsr
['deploymentStatus'])
345 config_status
= summarize_config_status(nsr
['configurationStatus'])
346 project_id
= nsr
.get('_admin').get('projects_read')[0]
348 for p
in project_list
:
349 if p
['_id'] == project_id
:
350 project_name
= p
['name']
352 #project = '{} ({})'.format(project_name, project_id)
353 project
= project_name
354 vim_id
= nsr
.get('datacenter')
357 if v
['uuid'] == vim_id
:
360 #vim = '{} ({})'.format(vim_name, vim_id)
362 if 'currentOperation' in nsr
:
363 current_operation
= "{} ({})".format(nsr
['currentOperation'],nsr
['currentOperationID'])
365 current_operation
= "{} ({})".format(nsr
['_admin'].get('current-operation','-'), nsr
['_admin']['nslcmop'])
366 error_details
= "N/A"
367 if ns_state
== "BROKEN" or ns_state
== "DEGRADED" or nsr
.get('errorDescription'):
368 error_details
= "{}\nDetail: {}".format(nsr
['errorDescription'], nsr
['errorDetail'])
370 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
371 nsr
= nsopdata
['nsr:nsr']
372 nsr_name
= nsr
['name-ref']
373 nsr_id
= nsr
['ns-instance-config-ref']
376 deployment_status
= nsr
['operational-status'] if 'operational-status' in nsr
else 'Not found'
377 ns_state
= deployment_status
378 config_status
= nsr
.get('config-status', 'Not found')
379 current_operation
= "Unknown"
380 error_details
= nsr
.get('detailed-status', 'Not found')
381 if config_status
== "config_not_needed":
382 config_status
= "configured (no charms)"
391 wrap_text(text
=error_details
,width
=40),
403 wrap_text(text
=error_details
,width
=40)])
406 print('To get the history of all operations over a NS, run "osm ns-op-list NS_ID"')
407 print('For more details on the current operation, run "osm ns-op-show OPERATION_ID"')
409 def nsd_list(ctx
, filter, long):
412 check_client_version(ctx
.obj
, '--filter')
413 resp
= ctx
.obj
.nsd
.list(filter)
415 resp
= ctx
.obj
.nsd
.list()
416 # print(yaml.safe_dump(resp))
417 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
418 if fullclassname
== 'osmclient.sol005.client.Client':
420 table
= PrettyTable(['nsd name', 'id', 'onboarding state', 'operational state',
421 'usage state', 'date', 'last update'])
423 table
= PrettyTable(['nsd name', 'id'])
425 name
= nsd
.get('name','-')
427 onb_state
= nsd
['_admin'].get('onboardingState','-')
428 op_state
= nsd
['_admin'].get('operationalState','-')
429 usage_state
= nsd
['_admin'].get('usageState','-')
430 date
= datetime
.fromtimestamp(nsd
['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S")
431 last_update
= datetime
.fromtimestamp(nsd
['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S")
432 table
.add_row([name
, nsd
['_id'], onb_state
, op_state
, usage_state
, date
, last_update
])
434 table
.add_row([name
, nsd
['_id']])
436 table
= PrettyTable(['nsd name', 'id'])
438 table
.add_row([nsd
['name'], nsd
['id']])
443 @cli_osm.command(name
='nsd-list', short_help
='list all NS packages')
444 @click.option('--filter', default
=None,
445 help='restricts the list to the NSD/NSpkg matching the filter')
446 @click.option('--long', is_flag
=True, help='get more details')
448 def nsd_list1(ctx
, filter, long):
449 """list all NSD/NS pkg in the system"""
451 nsd_list(ctx
, filter, long)
454 @cli_osm.command(name
='nspkg-list', short_help
='list all NS packages')
455 @click.option('--filter', default
=None,
456 help='restricts the list to the NSD/NSpkg matching the filter')
457 @click.option('--long', is_flag
=True, help='get more details')
459 def nsd_list2(ctx
, filter, long):
460 """list all NS packages"""
462 nsd_list(ctx
, filter, long)
465 def vnfd_list(ctx
, nf_type
, filter, long):
468 check_client_version(ctx
.obj
, '--nf_type')
470 check_client_version(ctx
.obj
, '--filter')
473 nf_filter
= "_admin.type=vnfd"
474 elif nf_type
== "pnf":
475 nf_filter
= "_admin.type=pnfd"
476 elif nf_type
== "hnf":
477 nf_filter
= "_admin.type=hnfd"
479 raise ClientException('wrong value for "--nf_type" option, allowed values: vnf, pnf, hnf')
481 filter = '{}&{}'.format(nf_filter
, filter)
485 resp
= ctx
.obj
.vnfd
.list(filter)
487 resp
= ctx
.obj
.vnfd
.list()
488 # print(yaml.safe_dump(resp))
489 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
490 if fullclassname
== 'osmclient.sol005.client.Client':
492 table
= PrettyTable(['nfpkg name', 'id', 'onboarding state', 'operational state',
493 'usage state', 'date', 'last update'])
495 table
= PrettyTable(['nfpkg name', 'id'])
497 name
= vnfd
['name'] if 'name' in vnfd
else '-'
499 onb_state
= vnfd
['_admin'].get('onboardingState','-')
500 op_state
= vnfd
['_admin'].get('operationalState','-')
501 usage_state
= vnfd
['_admin'].get('usageState','-')
502 date
= datetime
.fromtimestamp(vnfd
['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S")
503 last_update
= datetime
.fromtimestamp(vnfd
['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S")
504 table
.add_row([name
, vnfd
['_id'], onb_state
, op_state
, usage_state
, date
, last_update
])
506 table
.add_row([name
, vnfd
['_id']])
508 table
= PrettyTable(['nfpkg name', 'id'])
510 table
.add_row([vnfd
['name'], vnfd
['id']])
515 @cli_osm.command(name
='vnfd-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
516 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
517 @click.option('--filter', default
=None,
518 help='restricts the list to the NF pkg matching the filter')
519 @click.option('--long', is_flag
=True, help='get more details')
521 def vnfd_list1(ctx
, nf_type
, filter, long):
522 """list all xNF packages (VNF, HNF, PNF)"""
524 vnfd_list(ctx
, nf_type
, filter, long)
527 @cli_osm.command(name
='vnfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
528 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
529 @click.option('--filter', default
=None,
530 help='restricts the list to the NFpkg matching the filter')
531 @click.option('--long', is_flag
=True, help='get more details')
533 def vnfd_list2(ctx
, nf_type
, filter, long):
534 """list all xNF packages (VNF, HNF, PNF)"""
536 vnfd_list(ctx
, nf_type
, filter, long)
539 @cli_osm.command(name
='nfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
540 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
541 @click.option('--filter', default
=None,
542 help='restricts the list to the NFpkg matching the filter')
543 @click.option('--long', is_flag
=True, help='get more details')
545 def nfpkg_list(ctx
, nf_type
, filter, long):
546 """list all xNF packages (VNF, HNF, PNF)"""
549 check_client_version(ctx
.obj
, ctx
.command
.name
)
550 vnfd_list(ctx
, nf_type
, filter, long)
551 # except ClientException as e:
556 def vnf_list(ctx
, ns
, filter, long):
560 check_client_version(ctx
.obj
, '--ns')
562 check_client_version(ctx
.obj
, '--filter')
563 resp
= ctx
.obj
.vnf
.list(ns
, filter)
565 resp
= ctx
.obj
.vnf
.list()
566 # except ClientException as e:
569 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
570 if fullclassname
== 'osmclient.sol005.client.Client':
571 field_names
= ['vnf id', 'name', 'ns id', 'vnf member index',
572 'vnfd name', 'vim account id', 'ip address']
574 field_names
= ['vnf id', 'name', 'ns id', 'vnf member index',
575 'vnfd name', 'vim account id', 'ip address',
576 'date', 'last update']
577 table
= PrettyTable(field_names
)
579 name
= vnfr
['name'] if 'name' in vnfr
else '-'
580 new_row
= [vnfr
['_id'], name
, vnfr
['nsr-id-ref'],
581 vnfr
['member-vnf-index-ref'], vnfr
['vnfd-ref'],
582 vnfr
['vim-account-id'], vnfr
['ip-address']]
584 date
= datetime
.fromtimestamp(vnfr
['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S")
585 last_update
= datetime
.fromtimestamp(vnfr
['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S")
586 new_row
.extend([date
, last_update
])
587 table
.add_row(new_row
)
592 'operational status',
595 if 'mgmt-interface' not in vnfr
:
596 vnfr
['mgmt-interface'] = {}
597 vnfr
['mgmt-interface']['ip-address'] = None
601 vnfr
['operational-status'],
602 vnfr
['config-status']])
607 @cli_osm.command(name
='vnf-list', short_help
='list all NF instances')
608 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
609 @click.option('--filter', default
=None,
610 help='restricts the list to the NF instances matching the filter.')
611 @click.option('--long', is_flag
=True, help='get more details')
613 def vnf_list1(ctx
, ns
, filter, long):
614 """list all NF instances"""
616 vnf_list(ctx
, ns
, filter, long)
619 @cli_osm.command(name
='nf-list', short_help
='list all NF instances')
620 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
621 @click.option('--filter', default
=None,
622 help='restricts the list to the NF instances matching the filter.')
623 @click.option('--long', is_flag
=True, help='get more details')
625 def nf_list(ctx
, ns
, filter, long):
626 """list all NF instances
630 --ns TEXT NS instance id or name to restrict the VNF list
631 --filter filterExpr Restricts the list to the VNF instances matching the filter
634 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
635 concatenated using the "&" character:
638 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
639 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
640 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
642 value := scalar value
646 * zero or more occurrences
647 ? zero or one occurrence
648 [] grouping of expressions to be used with ? and *
649 "" quotation marks for marking string constants
653 "AttrName" is the name of one attribute in the data type that defines the representation
654 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
655 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
656 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
657 entries, it means that the operator "op" is applied to the attribute addressed by the last
658 <attrName> entry included in the concatenation. All simple filter expressions are combined
659 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
660 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
661 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
662 prefix". If an attribute referenced in an expression is an array, an object that contains a
663 corresponding array shall be considered to match the expression if any of the elements in the
664 array matches all expressions that have the same attribute prefix.
668 --filter vim-account-id=<VIM_ACCOUNT_ID>
669 --filter vnfd-ref=<VNFD_NAME>
670 --filter vdur.ip-address=<IP_ADDRESS>
671 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
674 vnf_list(ctx
, ns
, filter)
677 @cli_osm.command(name
='ns-op-list', short_help
='shows the history of operations over a NS instance')
678 @click.argument('name')
679 @click.option('--long', is_flag
=True,
680 help='get more details of the NS operation (date, ).')
682 def ns_op_list(ctx
, name
, long):
683 """shows the history of operations over a NS instance
685 NAME: name or ID of the NS instance
687 def formatParams(params
):
688 if params
['lcmOperationType']=='instantiate':
689 params
.pop('nsDescription')
693 elif params
['lcmOperationType']=='action':
694 params
.pop('primitive')
695 params
.pop('lcmOperationType')
696 params
.pop('nsInstanceId')
701 check_client_version(ctx
.obj
, ctx
.command
.name
)
702 resp
= ctx
.obj
.ns
.list_op(name
)
703 # except ClientException as e:
708 table
= PrettyTable(['id', 'operation', 'action_name', 'operation_params', 'status', 'date', 'last update', 'detail'])
710 table
= PrettyTable(['id', 'operation', 'action_name', 'status', 'date', 'detail'])
712 #print(yaml.safe_dump(resp))
715 if op
['lcmOperationType']=='action':
716 action_name
= op
['operationParams']['primitive']
718 if op
['operationState']=='PROCESSING':
719 if op
['lcmOperationType'] in ('instantiate', 'terminate'):
723 detail
= "In queue. Current position: {}".format(op
['queuePosition'])
724 elif op
['operationState'] in ('FAILED', 'FAILED_TEMP'):
725 detail
= op
.get('errorMessage','-')
726 date
= datetime
.fromtimestamp(op
['startTime']).strftime("%Y-%m-%dT%H:%M:%S")
727 last_update
= datetime
.fromtimestamp(op
['statusEnteredTime']).strftime("%Y-%m-%dT%H:%M:%S")
729 table
.add_row([op
['id'],
730 op
['lcmOperationType'],
732 wrap_text(text
=json
.dumps(formatParams(op
['operationParams']),indent
=2),width
=50),
733 op
['operationState'],
736 wrap_text(text
=detail
,width
=50)])
738 table
.add_row([op
['id'], op
['lcmOperationType'], action_name
,
739 op
['operationState'], date
, wrap_text(text
=detail
or "",width
=50)])
744 def nsi_list(ctx
, filter):
745 """list all Network Slice Instances"""
748 check_client_version(ctx
.obj
, ctx
.command
.name
)
749 resp
= ctx
.obj
.nsi
.list(filter)
750 # except ClientException as e:
754 ['netslice instance name',
756 'operational status',
760 nsi_name
= nsi
['name']
762 opstatus
= nsi
['operational-status'] if 'operational-status' in nsi
else 'Not found'
763 configstatus
= nsi
['config-status'] if 'config-status' in nsi
else 'Not found'
764 detailed_status
= nsi
['detailed-status'] if 'detailed-status' in nsi
else 'Not found'
765 if configstatus
== "config_not_needed":
766 configstatus
= "configured (no charms)"
777 @cli_osm.command(name
='nsi-list', short_help
='list all Network Slice Instances (NSI)')
778 @click.option('--filter', default
=None,
779 help='restricts the list to the Network Slice Instances matching the filter')
781 def nsi_list1(ctx
, filter):
782 """list all Network Slice Instances (NSI)"""
784 nsi_list(ctx
, filter)
787 @cli_osm.command(name
='netslice-instance-list', short_help
='list all Network Slice Instances (NSI)')
788 @click.option('--filter', default
=None,
789 help='restricts the list to the Network Slice Instances matching the filter')
791 def nsi_list2(ctx
, filter):
792 """list all Network Slice Instances (NSI)"""
794 nsi_list(ctx
, filter)
797 def nst_list(ctx
, filter):
800 check_client_version(ctx
.obj
, ctx
.command
.name
)
801 resp
= ctx
.obj
.nst
.list(filter)
802 # except ClientException as e:
805 # print(yaml.safe_dump(resp))
806 table
= PrettyTable(['nst name', 'id'])
808 name
= nst
['name'] if 'name' in nst
else '-'
809 table
.add_row([name
, nst
['_id']])
814 @cli_osm.command(name
='nst-list', short_help
='list all Network Slice Templates (NST)')
815 @click.option('--filter', default
=None,
816 help='restricts the list to the NST matching the filter')
818 def nst_list1(ctx
, filter):
819 """list all Network Slice Templates (NST) in the system"""
821 nst_list(ctx
, filter)
824 @cli_osm.command(name
='netslice-template-list', short_help
='list all Network Slice Templates (NST)')
825 @click.option('--filter', default
=None,
826 help='restricts the list to the NST matching the filter')
828 def nst_list2(ctx
, filter):
829 """list all Network Slice Templates (NST) in the system"""
831 nst_list(ctx
, filter)
834 def nsi_op_list(ctx
, name
):
837 check_client_version(ctx
.obj
, ctx
.command
.name
)
838 resp
= ctx
.obj
.nsi
.list_op(name
)
839 # except ClientException as e:
842 table
= PrettyTable(['id', 'operation', 'status'])
844 table
.add_row([op
['id'], op
['lcmOperationType'],
845 op
['operationState']])
850 @cli_osm.command(name
='nsi-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
851 @click.argument('name')
853 def nsi_op_list1(ctx
, name
):
854 """shows the history of operations over a Network Slice Instance (NSI)
856 NAME: name or ID of the Network Slice Instance
859 nsi_op_list(ctx
, name
)
862 @cli_osm.command(name
='netslice-instance-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
863 @click.argument('name')
865 def nsi_op_list2(ctx
, name
):
866 """shows the history of operations over a Network Slice Instance (NSI)
868 NAME: name or ID of the Network Slice Instance
871 nsi_op_list(ctx
, name
)
874 @cli_osm.command(name
='pdu-list', short_help
='list all Physical Deployment Units (PDU)')
875 @click.option('--filter', default
=None,
876 help='restricts the list to the Physical Deployment Units matching the filter')
878 def pdu_list(ctx
, filter):
879 """list all Physical Deployment Units (PDU)"""
882 check_client_version(ctx
.obj
, ctx
.command
.name
)
883 resp
= ctx
.obj
.pdu
.list(filter)
884 # except ClientException as e:
893 pdu_name
= pdu
['name']
895 pdu_type
= pdu
['type']
896 pdu_ipaddress
= "None"
897 for iface
in pdu
['interfaces']:
899 pdu_ipaddress
= iface
['ip-address']
914 def nsd_show(ctx
, name
, literal
):
917 resp
= ctx
.obj
.nsd
.get(name
)
918 # resp = ctx.obj.nsd.get_individual(name)
919 # except ClientException as e:
924 print(yaml
.safe_dump(resp
))
927 table
= PrettyTable(['field', 'value'])
928 for k
, v
in list(resp
.items()):
929 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
934 @cli_osm.command(name
='nsd-show', short_help
='shows the content of a NSD')
935 @click.option('--literal', is_flag
=True,
936 help='print literally, no pretty table')
937 @click.argument('name')
939 def nsd_show1(ctx
, name
, literal
):
940 """shows the content of a NSD
942 NAME: name or ID of the NSD/NSpkg
945 nsd_show(ctx
, name
, literal
)
948 @cli_osm.command(name
='nspkg-show', short_help
='shows the content of a NSD')
949 @click.option('--literal', is_flag
=True,
950 help='print literally, no pretty table')
951 @click.argument('name')
953 def nsd_show2(ctx
, name
, literal
):
954 """shows the content of a NSD
956 NAME: name or ID of the NSD/NSpkg
959 nsd_show(ctx
, name
, literal
)
962 def vnfd_show(ctx
, name
, literal
):
965 resp
= ctx
.obj
.vnfd
.get(name
)
966 # resp = ctx.obj.vnfd.get_individual(name)
967 # except ClientException as e:
972 print(yaml
.safe_dump(resp
))
975 table
= PrettyTable(['field', 'value'])
976 for k
, v
in list(resp
.items()):
977 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
982 @cli_osm.command(name
='vnfd-show', short_help
='shows the content of a VNFD')
983 @click.option('--literal', is_flag
=True,
984 help='print literally, no pretty table')
985 @click.argument('name')
987 def vnfd_show1(ctx
, name
, literal
):
988 """shows the content of a VNFD
990 NAME: name or ID of the VNFD/VNFpkg
993 vnfd_show(ctx
, name
, literal
)
996 @cli_osm.command(name
='vnfpkg-show', short_help
='shows the content of a VNFD')
997 @click.option('--literal', is_flag
=True,
998 help='print literally, no pretty table')
999 @click.argument('name')
1001 def vnfd_show2(ctx
, name
, literal
):
1002 """shows the content of a VNFD
1004 NAME: name or ID of the VNFD/VNFpkg
1007 vnfd_show(ctx
, name
, literal
)
1010 @cli_osm.command(name
='nfpkg-show', short_help
='shows the content of a NF Descriptor')
1011 @click.option('--literal', is_flag
=True,
1012 help='print literally, no pretty table')
1013 @click.argument('name')
1015 def nfpkg_show(ctx
, name
, literal
):
1016 """shows the content of a NF Descriptor
1018 NAME: name or ID of the NFpkg
1021 vnfd_show(ctx
, name
, literal
)
1024 @cli_osm.command(name
='ns-show', short_help
='shows the info of a NS instance')
1025 @click.argument('name')
1026 @click.option('--literal', is_flag
=True,
1027 help='print literally, no pretty table')
1028 @click.option('--filter', default
=None)
1030 def ns_show(ctx
, name
, literal
, filter):
1031 """shows the info of a NS instance
1033 NAME: name or ID of the NS instance
1037 ns
= ctx
.obj
.ns
.get(name
)
1038 # except ClientException as e:
1043 print(yaml
.safe_dump(ns
))
1046 table
= PrettyTable(['field', 'value'])
1048 for k
, v
in list(ns
.items()):
1049 if filter is None or filter in k
:
1050 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
1052 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1053 if fullclassname
!= 'osmclient.sol005.client.Client':
1054 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
1055 nsr_optdata
= nsopdata
['nsr:nsr']
1056 for k
, v
in list(nsr_optdata
.items()):
1057 if filter is None or filter in k
:
1058 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2),width
=100)])
1063 @cli_osm.command(name
='vnf-show', short_help
='shows the info of a VNF instance')
1064 @click.argument('name')
1065 @click.option('--literal', is_flag
=True,
1066 help='print literally, no pretty table')
1067 @click.option('--filter', default
=None, help='restricts the information to the fields in the filter')
1068 @click.option('--kdu', default
=None, help='KDU name (whose status will be shown)')
1070 def vnf_show(ctx
, name
, literal
, filter, kdu
):
1071 """shows the info of a VNF instance
1073 NAME: name or ID of the VNF instance
1075 def print_kdu_status(op_info_status
):
1076 """print KDU status properly formatted
1079 op_status
= yaml
.safe_load(op_info_status
)
1080 if "namespace" in op_status
and "info" in op_status
and \
1081 "last_deployed" in op_status
["info"] and "status" in op_status
["info"] and \
1082 "code" in op_status
["info"]["status"] and "resources" in op_status
["info"]["status"] and \
1083 "seconds" in op_status
["info"]["last_deployed"]:
1084 last_deployed_time
= datetime
.fromtimestamp(op_status
["info"]["last_deployed"]["seconds"]).strftime("%a %b %d %I:%M:%S %Y")
1085 print("LAST DEPLOYED: {}".format(last_deployed_time
))
1086 print("NAMESPACE: {}".format(op_status
["namespace"]))
1087 status_code
= "UNKNOWN"
1088 if op_status
["info"]["status"]["code"]==1:
1089 status_code
= "DEPLOYED"
1090 print("STATUS: {}".format(status_code
))
1093 print(op_status
["info"]["status"]["resources"])
1094 if "notes" in op_status
["info"]["status"]:
1096 print(op_status
["info"]["status"]["notes"])
1098 print(op_info_status
)
1100 print(op_info_status
)
1105 raise ClientException('"--literal" option is incompatible with "--kdu" option')
1107 raise ClientException('"--filter" option is incompatible with "--kdu" option')
1110 check_client_version(ctx
.obj
, ctx
.command
.name
)
1111 resp
= ctx
.obj
.vnf
.get(name
)
1114 ns_id
= resp
['nsr-id-ref']
1116 op_data
['member_vnf_index'] = resp
['member-vnf-index-ref']
1117 op_data
['kdu_name'] = kdu
1118 op_data
['primitive'] = 'status'
1119 op_data
['primitive_params'] = {}
1120 op_id
= ctx
.obj
.ns
.exec_op(ns_id
, op_name
='action', op_data
=op_data
, wait
=False)
1123 op_info
= ctx
.obj
.ns
.get_op(op_id
)
1124 if op_info
['operationState'] == 'COMPLETED':
1125 print_kdu_status(op_info
['detailed-status'])
1129 print ("Could not determine KDU status")
1132 print(yaml
.safe_dump(resp
))
1135 table
= PrettyTable(['field', 'value'])
1137 for k
, v
in list(resp
.items()):
1138 if filter is None or filter in k
:
1139 table
.add_row([k
, wrap_text(text
=json
.dumps(v
,indent
=2),width
=100)])
1142 # except ClientException as e:
1147 #@cli_osm.command(name='vnf-monitoring-show')
1148 #@click.argument('vnf_name')
1149 #@click.pass_context
1150 #def vnf_monitoring_show(ctx, vnf_name):
1152 # check_client_version(ctx.obj, ctx.command.name, 'v1')
1153 # resp = ctx.obj.vnf.get_monitoring(vnf_name)
1154 # except ClientException as e:
1158 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
1159 # if resp is not None:
1160 # for monitor in resp:
1164 # monitor['value-integer'],
1165 # monitor['units']])
1170 #@cli_osm.command(name='ns-monitoring-show')
1171 #@click.argument('ns_name')
1172 #@click.pass_context
1173 #def ns_monitoring_show(ctx, ns_name):
1175 # check_client_version(ctx.obj, ctx.command.name, 'v1')
1176 # resp = ctx.obj.ns.get_monitoring(ns_name)
1177 # except ClientException as e:
1181 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
1182 # for key, val in list(resp.items()):
1183 # for monitor in val:
1187 # monitor['value-integer'],
1188 # monitor['units']])
1193 @cli_osm.command(name
='ns-op-show', short_help
='shows the info of a NS operation')
1194 @click.argument('id')
1195 @click.option('--filter', default
=None)
1196 @click.option('--literal', is_flag
=True,
1197 help='print literally, no pretty table')
1199 def ns_op_show(ctx
, id, filter, literal
):
1200 """shows the detailed info of a NS operation
1202 ID: operation identifier
1206 check_client_version(ctx
.obj
, ctx
.command
.name
)
1207 op_info
= ctx
.obj
.ns
.get_op(id)
1208 # except ClientException as e:
1213 print(yaml
.safe_dump(op_info
))
1216 table
= PrettyTable(['field', 'value'])
1217 for k
, v
in list(op_info
.items()):
1218 if filter is None or filter in k
:
1219 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
1224 def nst_show(ctx
, name
, literal
):
1227 check_client_version(ctx
.obj
, ctx
.command
.name
)
1228 resp
= ctx
.obj
.nst
.get(name
)
1229 #resp = ctx.obj.nst.get_individual(name)
1230 # except ClientException as e:
1235 print(yaml
.safe_dump(resp
))
1238 table
= PrettyTable(['field', 'value'])
1239 for k
, v
in list(resp
.items()):
1240 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
1245 @cli_osm.command(name
='nst-show', short_help
='shows the content of a Network Slice Template (NST)')
1246 @click.option('--literal', is_flag
=True,
1247 help='print literally, no pretty table')
1248 @click.argument('name')
1250 def nst_show1(ctx
, name
, literal
):
1251 """shows the content of a Network Slice Template (NST)
1253 NAME: name or ID of the NST
1256 nst_show(ctx
, name
, literal
)
1259 @cli_osm.command(name
='netslice-template-show', short_help
='shows the content of a Network Slice Template (NST)')
1260 @click.option('--literal', is_flag
=True,
1261 help='print literally, no pretty table')
1262 @click.argument('name')
1264 def nst_show2(ctx
, name
, literal
):
1265 """shows the content of a Network Slice Template (NST)
1267 NAME: name or ID of the NST
1270 nst_show(ctx
, name
, literal
)
1273 def nsi_show(ctx
, name
, literal
, filter):
1276 check_client_version(ctx
.obj
, ctx
.command
.name
)
1277 nsi
= ctx
.obj
.nsi
.get(name
)
1278 # except ClientException as e:
1283 print(yaml
.safe_dump(nsi
))
1286 table
= PrettyTable(['field', 'value'])
1288 for k
, v
in list(nsi
.items()):
1289 if filter is None or filter in k
:
1290 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1296 @cli_osm.command(name
='nsi-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1297 @click.argument('name')
1298 @click.option('--literal', is_flag
=True,
1299 help='print literally, no pretty table')
1300 @click.option('--filter', default
=None)
1302 def nsi_show1(ctx
, name
, literal
, filter):
1303 """shows the content of a Network Slice Instance (NSI)
1305 NAME: name or ID of the Network Slice Instance
1308 nsi_show(ctx
, name
, literal
, filter)
1311 @cli_osm.command(name
='netslice-instance-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1312 @click.argument('name')
1313 @click.option('--literal', is_flag
=True,
1314 help='print literally, no pretty table')
1315 @click.option('--filter', default
=None)
1317 def nsi_show2(ctx
, name
, literal
, filter):
1318 """shows the content of a Network Slice Instance (NSI)
1320 NAME: name or ID of the Network Slice Instance
1323 nsi_show(ctx
, name
, literal
, filter)
1326 def nsi_op_show(ctx
, id, filter):
1329 check_client_version(ctx
.obj
, ctx
.command
.name
)
1330 op_info
= ctx
.obj
.nsi
.get_op(id)
1331 # except ClientException as e:
1335 table
= PrettyTable(['field', 'value'])
1336 for k
, v
in list(op_info
.items()):
1337 if filter is None or filter in k
:
1338 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1343 @cli_osm.command(name
='nsi-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1344 @click.argument('id')
1345 @click.option('--filter', default
=None)
1347 def nsi_op_show1(ctx
, id, filter):
1348 """shows the info of an operation over a Network Slice Instance(NSI)
1350 ID: operation identifier
1353 nsi_op_show(ctx
, id, filter)
1356 @cli_osm.command(name
='netslice-instance-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1357 @click.argument('id')
1358 @click.option('--filter', default
=None)
1360 def nsi_op_show2(ctx
, id, filter):
1361 """shows the info of an operation over a Network Slice Instance(NSI)
1363 ID: operation identifier
1366 nsi_op_show(ctx
, id, filter)
1369 @cli_osm.command(name
='pdu-show', short_help
='shows the content of a Physical Deployment Unit (PDU)')
1370 @click.argument('name')
1371 @click.option('--literal', is_flag
=True,
1372 help='print literally, no pretty table')
1373 @click.option('--filter', default
=None)
1375 def pdu_show(ctx
, name
, literal
, filter):
1376 """shows the content of a Physical Deployment Unit (PDU)
1378 NAME: name or ID of the PDU
1382 check_client_version(ctx
.obj
, ctx
.command
.name
)
1383 pdu
= ctx
.obj
.pdu
.get(name
)
1384 # except ClientException as e:
1389 print(yaml
.safe_dump(pdu
))
1392 table
= PrettyTable(['field', 'value'])
1394 for k
, v
in list(pdu
.items()):
1395 if filter is None or filter in k
:
1396 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1402 ####################
1404 ####################
1406 def nsd_create(ctx
, filename
, overwrite
, skip_charm_build
):
1409 check_client_version(ctx
.obj
, ctx
.command
.name
)
1410 ctx
.obj
.nsd
.create(filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
)
1411 # except ClientException as e:
1416 @cli_osm.command(name
='nsd-create', short_help
='creates a new NSD/NSpkg')
1417 @click.argument('filename')
1418 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1419 help='Deprecated. Use override')
1420 @click.option('--override', 'overwrite', default
=None,
1421 help='overrides fields in descriptor, format: '
1422 '"key1.key2...=value[;key3...=value;...]"')
1423 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1424 help='The charm will not be compiled, it is assumed to already exist')
1426 def nsd_create1(ctx
, filename
, overwrite
, skip_charm_build
):
1427 """creates a new NSD/NSpkg
1429 FILENAME: NSD yaml file or NSpkg tar.gz file
1432 nsd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
)
1435 @cli_osm.command(name
='nspkg-create', short_help
='creates a new NSD/NSpkg')
1436 @click.argument('filename')
1437 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1438 help='Deprecated. Use override')
1439 @click.option('--override', 'overwrite', default
=None,
1440 help='overrides fields in descriptor, format: '
1441 '"key1.key2...=value[;key3...=value;...]"')
1442 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1443 help='The charm will not be compiled, it is assumed to already exist')
1445 def nsd_create2(ctx
, filename
, overwrite
, skip_charm_build
):
1446 """creates a new NSD/NSpkg
1448 FILENAME: NSD folder, NSD yaml file or NSpkg tar.gz file
1451 nsd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
)
1454 def vnfd_create(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1457 check_client_version(ctx
.obj
, ctx
.command
.name
)
1458 ctx
.obj
.vnfd
.create(filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1459 override_epa
=override_epa
, override_nonepa
=override_nonepa
,
1460 override_paravirt
=override_paravirt
)
1461 # except ClientException as e:
1466 @cli_osm.command(name
='vnfd-create', short_help
='creates a new VNFD/VNFpkg')
1467 @click.argument('filename')
1468 @click.option('--overwrite', 'overwrite', default
=None,
1469 help='overwrite deprecated, use override')
1470 @click.option('--override', 'overwrite', default
=None,
1471 help='overrides fields in descriptor, format: '
1472 '"key1.key2...=value[;key3...=value;...]"')
1473 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1474 help='The charm will not be compiled, it is assumed to already exist')
1475 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1476 help='adds guest-epa parameters to all VDU')
1477 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1478 help='removes all guest-epa parameters from all VDU')
1479 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1480 help='overrides all VDU interfaces to PARAVIRT')
1482 def vnfd_create1(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1483 """creates a new VNFD/VNFpkg
1485 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1488 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1489 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
)
1492 @cli_osm.command(name
='vnfpkg-create', short_help
='creates a new VNFD/VNFpkg')
1493 @click.argument('filename')
1494 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1495 help='Deprecated. Use override')
1496 @click.option('--override', 'overwrite', default
=None,
1497 help='overrides fields in descriptor, format: '
1498 '"key1.key2...=value[;key3...=value;...]"')
1499 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1500 help='The charm will not be compiled, it is assumed to already exist')
1501 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1502 help='adds guest-epa parameters to all VDU')
1503 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1504 help='removes all guest-epa parameters from all VDU')
1505 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1506 help='overrides all VDU interfaces to PARAVIRT')
1508 def vnfd_create2(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1509 """creates a new VNFD/VNFpkg
1511 FILENAME: NF Package Folder, NF Descriptor yaml file or NFpkg tar.gz file
1514 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1515 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
)
1518 @cli_osm.command(name
='nfpkg-create', short_help
='creates a new NFpkg')
1519 @click.argument('filename')
1520 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1521 help='Deprecated. Use override')
1522 @click.option('--override', 'overwrite', default
=None,
1523 help='overrides fields in descriptor, format: '
1524 '"key1.key2...=value[;key3...=value;...]"')
1525 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1526 help='The charm will not be compiled, it is assumed to already exist')
1527 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1528 help='adds guest-epa parameters to all VDU')
1529 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1530 help='removes all guest-epa parameters from all VDU')
1531 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1532 help='overrides all VDU interfaces to PARAVIRT')
1534 def nfpkg_create(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1535 """creates a new NFpkg
1537 FILENAME: NF Package Folder, NF Descriptor yaml file or NFpkg tar.gz filems to build
1540 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1541 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
)
1544 @cli_osm.command(name
='ns-create', short_help
='creates a new Network Service instance')
1545 @click.option('--ns_name',
1546 prompt
=True, help='name of the NS instance')
1547 @click.option('--nsd_name',
1548 prompt
=True, help='name of the NS descriptor')
1549 @click.option('--vim_account',
1550 prompt
=True, help='default VIM account id or name for the deployment')
1551 @click.option('--admin_status',
1553 help='administration status')
1554 @click.option('--ssh_keys',
1556 help='comma separated list of public key files to inject to vnfs')
1557 @click.option('--config',
1559 help='ns specific yaml configuration')
1560 @click.option('--config_file',
1562 help='ns specific yaml configuration file')
1563 @click.option('--wait',
1567 help='do not return the control immediately, but keep it '
1568 'until the operation is completed, or timeout')
1579 """creates a new NS instance"""
1583 check_client_version(ctx
.obj
, '--config_file')
1585 raise ClientException('"--config" option is incompatible with "--config_file" option')
1586 with
open(config_file
, 'r') as cf
:
1593 account
=vim_account
,
1595 # except ClientException as e:
1600 def nst_create(ctx
, filename
, overwrite
):
1603 check_client_version(ctx
.obj
, ctx
.command
.name
)
1604 ctx
.obj
.nst
.create(filename
, overwrite
)
1605 # except ClientException as e:
1610 @cli_osm.command(name
='nst-create', short_help
='creates a new Network Slice Template (NST)')
1611 @click.argument('filename')
1612 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1613 help='Deprecated. Use override')
1614 @click.option('--override', 'overwrite', default
=None,
1615 help='overrides fields in descriptor, format: '
1616 '"key1.key2...=value[;key3...=value;...]"')
1618 def nst_create1(ctx
, charm_folder
, overwrite
):
1619 """creates a new Network Slice Template (NST)
1621 FILENAME: NST package folder, NST yaml file or NSTpkg tar.gz file
1624 nst_create(ctx
, charm_folder
, overwrite
)
1627 @cli_osm.command(name
='netslice-template-create', short_help
='creates a new Network Slice Template (NST)')
1628 @click.argument('filename')
1629 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1630 help='Deprecated. Use override')
1631 @click.option('--override', 'overwrite', default
=None,
1632 help='overrides fields in descriptor, format: '
1633 '"key1.key2...=value[;key3...=value;...]"')
1635 def nst_create2(ctx
, filename
, overwrite
):
1636 """creates a new Network Slice Template (NST)
1638 FILENAME: NST yaml file or NSTpkg tar.gz file
1641 nst_create(ctx
, filename
, overwrite
)
1644 def nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1645 """creates a new Network Slice Instance (NSI)"""
1648 check_client_version(ctx
.obj
, ctx
.command
.name
)
1651 raise ClientException('"--config" option is incompatible with "--config_file" option')
1652 with
open(config_file
, 'r') as cf
:
1654 ctx
.obj
.nsi
.create(nst_name
, nsi_name
, config
=config
, ssh_keys
=ssh_keys
,
1655 account
=vim_account
, wait
=wait
)
1656 # except ClientException as e:
1661 @cli_osm.command(name
='nsi-create', short_help
='creates a new Network Slice Instance')
1662 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1663 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1664 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1665 @click.option('--ssh_keys', default
=None,
1666 help='comma separated list of keys to inject to vnfs')
1667 @click.option('--config', default
=None,
1668 help='Netslice specific yaml configuration:\n'
1669 'netslice_subnet: [\n'
1670 'id: TEXT, vim_account: TEXT,\n'
1671 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1672 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]\n'
1673 'additionalParamsForNsi: {param: value, ...}\n'
1674 'additionalParamsForsubnet: [{id: SUBNET_ID, additionalParamsForNs: {}, additionalParamsForVnf: {}}]\n'
1676 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1678 @click.option('--config_file',
1680 help='nsi specific yaml configuration file')
1681 @click.option('--wait',
1685 help='do not return the control immediately, but keep it '
1686 'until the operation is completed, or timeout')
1688 def nsi_create1(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1689 """creates a new Network Slice Instance (NSI)"""
1691 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1694 @cli_osm.command(name
='netslice-instance-create', short_help
='creates a new Network Slice Instance')
1695 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1696 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1697 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1698 @click.option('--ssh_keys', default
=None,
1699 help='comma separated list of keys to inject to vnfs')
1700 @click.option('--config', default
=None,
1701 help='Netslice specific yaml configuration:\n'
1702 'netslice_subnet: [\n'
1703 'id: TEXT, vim_account: TEXT,\n'
1704 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1705 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1707 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1709 @click.option('--config_file',
1711 help='nsi specific yaml configuration file')
1712 @click.option('--wait',
1716 help='do not return the control immediately, but keep it '
1717 'until the operation is completed, or timeout')
1719 def nsi_create2(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1720 """creates a new Network Slice Instance (NSI)"""
1722 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1725 @cli_osm.command(name
='pdu-create', short_help
='adds a new Physical Deployment Unit to the catalog')
1726 @click.option('--name', help='name of the Physical Deployment Unit')
1727 @click.option('--pdu_type', help='type of PDU (e.g. router, firewall, FW001)')
1728 @click.option('--interface',
1729 help='interface(s) of the PDU: name=<NAME>,mgmt=<true|false>,ip-address=<IP_ADDRESS>'+
1730 '[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]',
1732 @click.option('--description', help='human readable description')
1733 @click.option('--vim_account', help='list of VIM accounts (in the same VIM) that can reach this PDU', multiple
=True)
1734 @click.option('--descriptor_file', default
=None,
1735 help='PDU descriptor file (as an alternative to using the other arguments')
1737 def pdu_create(ctx
, name
, pdu_type
, interface
, description
, vim_account
, descriptor_file
):
1738 """creates a new Physical Deployment Unit (PDU)"""
1741 check_client_version(ctx
.obj
, ctx
.command
.name
)
1743 if not descriptor_file
:
1745 raise ClientException('in absence of descriptor file, option "--name" is mandatory')
1747 raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory')
1749 raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)')
1751 raise ClientException('in absence of descriptor file, option "--vim_account" is mandatory (at least once)')
1753 with
open(descriptor_file
, 'r') as df
:
1754 pdu
= yaml
.safe_load(df
.read())
1755 if name
: pdu
["name"] = name
1756 if pdu_type
: pdu
["type"] = pdu_type
1757 if description
: pdu
["description"] = description
1758 if vim_account
: pdu
["vim_accounts"] = vim_account
1761 for iface
in interface
:
1762 new_iface
={k
:v
for k
,v
in [i
.split('=') for i
in iface
.split(',')]}
1763 new_iface
["mgmt"] = (new_iface
.get("mgmt","false").lower() == "true")
1764 ifaces_list
.append(new_iface
)
1765 pdu
["interfaces"] = ifaces_list
1766 ctx
.obj
.pdu
.create(pdu
)
1767 # except ClientException as e:
1772 ####################
1774 ####################
1776 def nsd_update(ctx
, name
, content
):
1779 check_client_version(ctx
.obj
, ctx
.command
.name
)
1780 ctx
.obj
.nsd
.update(name
, content
)
1781 # except ClientException as e:
1786 @cli_osm.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
1787 @click.argument('name')
1788 @click.option('--content', default
=None,
1789 help='filename with the NSD/NSpkg replacing the current one')
1791 def nsd_update1(ctx
, name
, content
):
1792 """updates a NSD/NSpkg
1794 NAME: name or ID of the NSD/NSpkg
1797 nsd_update(ctx
, name
, content
)
1800 @cli_osm.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
1801 @click.argument('name')
1802 @click.option('--content', default
=None,
1803 help='filename with the NSD/NSpkg replacing the current one')
1805 def nsd_update2(ctx
, name
, content
):
1806 """updates a NSD/NSpkg
1808 NAME: name or ID of the NSD/NSpkg
1811 nsd_update(ctx
, name
, content
)
1814 def vnfd_update(ctx
, name
, content
):
1817 check_client_version(ctx
.obj
, ctx
.command
.name
)
1818 ctx
.obj
.vnfd
.update(name
, content
)
1819 # except ClientException as e:
1824 @cli_osm.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
1825 @click.argument('name')
1826 @click.option('--content', default
=None,
1827 help='filename with the VNFD/VNFpkg replacing the current one')
1829 def vnfd_update1(ctx
, name
, content
):
1830 """updates a VNFD/VNFpkg
1832 NAME: name or ID of the VNFD/VNFpkg
1835 vnfd_update(ctx
, name
, content
)
1838 @cli_osm.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
1839 @click.argument('name')
1840 @click.option('--content', default
=None,
1841 help='filename with the VNFD/VNFpkg replacing the current one')
1843 def vnfd_update2(ctx
, name
, content
):
1844 """updates a VNFD/VNFpkg
1846 NAME: VNFD yaml file or VNFpkg tar.gz file
1849 vnfd_update(ctx
, name
, content
)
1852 @cli_osm.command(name
='nfpkg-update', short_help
='updates a NFpkg')
1853 @click.argument('name')
1854 @click.option('--content', default
=None,
1855 help='filename with the NFpkg replacing the current one')
1857 def nfpkg_update(ctx
, name
, content
):
1860 NAME: NF Descriptor yaml file or NFpkg tar.gz file
1863 vnfd_update(ctx
, name
, content
)
1866 def nst_update(ctx
, name
, content
):
1869 check_client_version(ctx
.obj
, ctx
.command
.name
)
1870 ctx
.obj
.nst
.update(name
, content
)
1871 # except ClientException as e:
1876 @cli_osm.command(name
='nst-update', short_help
='updates a Network Slice Template (NST)')
1877 @click.argument('name')
1878 @click.option('--content', default
=None,
1879 help='filename with the NST/NSTpkg replacing the current one')
1881 def nst_update1(ctx
, name
, content
):
1882 """updates a Network Slice Template (NST)
1884 NAME: name or ID of the NSD/NSpkg
1887 nst_update(ctx
, name
, content
)
1890 @cli_osm.command(name
='netslice-template-update', short_help
='updates a Network Slice Template (NST)')
1891 @click.argument('name')
1892 @click.option('--content', default
=None,
1893 help='filename with the NST/NSTpkg replacing the current one')
1895 def nst_update2(ctx
, name
, content
):
1896 """updates a Network Slice Template (NST)
1898 NAME: name or ID of the NSD/NSpkg
1901 nst_update(ctx
, name
, content
)
1904 ####################
1906 ####################
1908 def nsd_delete(ctx
, name
, force
):
1912 ctx
.obj
.nsd
.delete(name
)
1914 check_client_version(ctx
.obj
, '--force')
1915 ctx
.obj
.nsd
.delete(name
, force
)
1916 # except ClientException as e:
1921 @cli_osm.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
1922 @click.argument('name')
1923 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1925 def nsd_delete1(ctx
, name
, force
):
1926 """deletes a NSD/NSpkg
1928 NAME: name or ID of the NSD/NSpkg to be deleted
1931 nsd_delete(ctx
, name
, force
)
1934 @cli_osm.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
1935 @click.argument('name')
1936 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1938 def nsd_delete2(ctx
, name
, force
):
1939 """deletes a NSD/NSpkg
1941 NAME: name or ID of the NSD/NSpkg to be deleted
1944 nsd_delete(ctx
, name
, force
)
1947 def vnfd_delete(ctx
, name
, force
):
1951 ctx
.obj
.vnfd
.delete(name
)
1953 check_client_version(ctx
.obj
, '--force')
1954 ctx
.obj
.vnfd
.delete(name
, force
)
1955 # except ClientException as e:
1960 @cli_osm.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
1961 @click.argument('name')
1962 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1964 def vnfd_delete1(ctx
, name
, force
):
1965 """deletes a VNFD/VNFpkg
1967 NAME: name or ID of the VNFD/VNFpkg to be deleted
1970 vnfd_delete(ctx
, name
, force
)
1973 @cli_osm.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
1974 @click.argument('name')
1975 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1977 def vnfd_delete2(ctx
, name
, force
):
1978 """deletes a VNFD/VNFpkg
1980 NAME: name or ID of the VNFD/VNFpkg to be deleted
1983 vnfd_delete(ctx
, name
, force
)
1986 @cli_osm.command(name
='nfpkg-delete', short_help
='deletes a NFpkg')
1987 @click.argument('name')
1988 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1990 def nfpkg_delete(ctx
, name
, force
):
1993 NAME: name or ID of the NFpkg to be deleted
1996 vnfd_delete(ctx
, name
, force
)
1999 @cli_osm.command(name
='ns-delete', short_help
='deletes a NS instance')
2000 @click.argument('name')
2001 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2002 @click.option('--config', default
=None,
2003 help="specific yaml configuration for the termination, e.g. '{autoremove: False, timeout_ns_terminate: "
2004 "600, skip_terminate_primitives: True}'")
2005 @click.option('--wait',
2009 help='do not return the control immediately, but keep it '
2010 'until the operation is completed, or timeout')
2012 def ns_delete(ctx
, name
, force
, config
, wait
):
2013 """deletes a NS instance
2015 NAME: name or ID of the NS instance to be deleted
2020 ctx
.obj
.ns
.delete(name
, config
=config
, wait
=wait
)
2022 check_client_version(ctx
.obj
, '--force')
2023 ctx
.obj
.ns
.delete(name
, force
, config
=config
, wait
=wait
)
2024 # except ClientException as e:
2029 def nst_delete(ctx
, name
, force
):
2032 check_client_version(ctx
.obj
, ctx
.command
.name
)
2033 ctx
.obj
.nst
.delete(name
, force
)
2034 # except ClientException as e:
2039 @cli_osm.command(name
='nst-delete', short_help
='deletes a Network Slice Template (NST)')
2040 @click.argument('name')
2041 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2043 def nst_delete1(ctx
, name
, force
):
2044 """deletes a Network Slice Template (NST)
2046 NAME: name or ID of the NST/NSTpkg to be deleted
2049 nst_delete(ctx
, name
, force
)
2052 @cli_osm.command(name
='netslice-template-delete', short_help
='deletes a Network Slice Template (NST)')
2053 @click.argument('name')
2054 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2056 def nst_delete2(ctx
, name
, force
):
2057 """deletes a Network Slice Template (NST)
2059 NAME: name or ID of the NST/NSTpkg to be deleted
2062 nst_delete(ctx
, name
, force
)
2065 def nsi_delete(ctx
, name
, force
, wait
):
2068 check_client_version(ctx
.obj
, ctx
.command
.name
)
2069 ctx
.obj
.nsi
.delete(name
, force
, wait
=wait
)
2070 # except ClientException as e:
2075 @cli_osm.command(name
='nsi-delete', short_help
='deletes a Network Slice Instance (NSI)')
2076 @click.argument('name')
2077 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2078 @click.option('--wait',
2082 help='do not return the control immediately, but keep it '
2083 'until the operation is completed, or timeout')
2085 def nsi_delete1(ctx
, name
, force
, wait
):
2086 """deletes a Network Slice Instance (NSI)
2088 NAME: name or ID of the Network Slice instance to be deleted
2091 nsi_delete(ctx
, name
, force
, wait
=wait
)
2094 @cli_osm.command(name
='netslice-instance-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')
2098 def nsi_delete2(ctx
, name
, force
, wait
):
2099 """deletes a Network Slice Instance (NSI)
2101 NAME: name or ID of the Network Slice instance to be deleted
2104 nsi_delete(ctx
, name
, force
, wait
=wait
)
2107 @cli_osm.command(name
='pdu-delete', short_help
='deletes a Physical Deployment Unit (PDU)')
2108 @click.argument('name')
2109 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2111 def pdu_delete(ctx
, name
, force
):
2112 """deletes a Physical Deployment Unit (PDU)
2114 NAME: name or ID of the PDU to be deleted
2118 check_client_version(ctx
.obj
, ctx
.command
.name
)
2119 ctx
.obj
.pdu
.delete(name
, force
)
2120 # except ClientException as e:
2129 @cli_osm.command(name
='vim-create', short_help
='creates a new VIM account')
2130 @click.option('--name',
2132 help='Name to create datacenter')
2133 @click.option('--user',
2135 help='VIM username')
2136 @click.option('--password',
2139 confirmation_prompt
=True,
2140 help='VIM password')
2141 @click.option('--auth_url',
2144 @click.option('--tenant',
2146 help='VIM tenant name')
2147 @click.option('--config',
2149 help='VIM specific config parameters')
2150 @click.option('--account_type',
2151 default
='openstack',
2153 @click.option('--description',
2155 help='human readable description')
2156 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
2157 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
2158 @click.option('--wait',
2162 help='do not return the control immediately, but keep it '
2163 'until the operation is completed, or timeout')
2177 """creates a new VIM account"""
2181 check_client_version(ctx
.obj
, '--sdn_controller')
2182 if sdn_port_mapping
:
2183 check_client_version(ctx
.obj
, '--sdn_port_mapping')
2185 vim
['vim-username'] = user
2186 vim
['vim-password'] = password
2187 vim
['vim-url'] = auth_url
2188 vim
['vim-tenant-name'] = tenant
2189 vim
['vim-type'] = account_type
2190 vim
['description'] = description
2191 vim
['config'] = config
2192 if sdn_controller
or sdn_port_mapping
:
2193 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
2195 ctx
.obj
.vim
.create(name
, vim
, wait
=wait
)
2196 # except ClientException as e:
2201 @cli_osm.command(name
='vim-update', short_help
='updates a VIM account')
2202 @click.argument('name')
2203 @click.option('--newname', help='New name for the VIM account')
2204 @click.option('--user', help='VIM username')
2205 @click.option('--password', help='VIM password')
2206 @click.option('--auth_url', help='VIM url')
2207 @click.option('--tenant', help='VIM tenant name')
2208 @click.option('--config', help='VIM specific config parameters')
2209 @click.option('--account_type', help='VIM type')
2210 @click.option('--description', help='human readable description')
2211 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller to be associated with this VIM'
2212 'account. Use empty string to disassociate')
2213 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
2214 @click.option('--wait',
2218 help='do not return the control immediately, but keep it '
2219 'until the operation is completed, or timeout')
2234 """updates a VIM account
2236 NAME: name or ID of the VIM account
2240 check_client_version(ctx
.obj
, ctx
.command
.name
)
2242 if newname
: vim
['name'] = newname
2243 if user
: vim
['vim_user'] = user
2244 if password
: vim
['vim_password'] = password
2245 if auth_url
: vim
['vim_url'] = auth_url
2246 if tenant
: vim
['vim-tenant-name'] = tenant
2247 if account_type
: vim
['vim_type'] = account_type
2248 if description
: vim
['description'] = description
2249 if config
: vim
['config'] = config
2250 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
2251 # except ClientException as e:
2256 @cli_osm.command(name
='vim-delete', short_help
='deletes a VIM account')
2257 @click.argument('name')
2258 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2259 @click.option('--wait',
2263 help='do not return the control immediately, but keep it '
2264 'until the operation is completed, or timeout')
2266 def vim_delete(ctx
, name
, force
, wait
):
2267 """deletes a VIM account
2269 NAME: name or ID of the VIM account to be deleted
2274 ctx
.obj
.vim
.delete(name
, wait
=wait
)
2276 check_client_version(ctx
.obj
, '--force')
2277 ctx
.obj
.vim
.delete(name
, force
, wait
=wait
)
2278 # except ClientException as e:
2283 @cli_osm.command(name
='vim-list', short_help
='list all VIM accounts')
2284 #@click.option('--ro_update/--no_ro_update',
2286 # help='update list from RO')
2287 @click.option('--filter', default
=None,
2288 help='restricts the list to the VIM accounts matching the filter')
2289 @click.option('--long', is_flag
=True,
2290 help='get more details of the NS (project, vim, deployment status, configuration status.')
2292 def vim_list(ctx
, filter, long):
2293 """list all VIM accounts"""
2296 check_client_version(ctx
.obj
, '--filter')
2298 # check_client_version(ctx.obj, '--ro_update', 'v1')
2299 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
2300 if fullclassname
== 'osmclient.sol005.client.Client':
2301 resp
= ctx
.obj
.vim
.list(filter)
2303 # resp = ctx.obj.vim.list(ro_update)
2305 table
= PrettyTable(['vim name', 'uuid', 'project', 'operational state', 'error details'])
2307 table
= PrettyTable(['vim name', 'uuid'])
2310 vim_details
= ctx
.obj
.vim
.get(vim
['uuid'])
2311 if 'vim_password' in vim_details
:
2312 vim_details
['vim_password']='********'
2313 logger
.debug('VIM details: {}'.format(yaml
.safe_dump(vim_details
)))
2314 vim_state
= vim_details
['_admin'].get('operationalState', '-')
2315 error_details
= 'N/A'
2316 if vim_state
== 'ERROR':
2317 error_details
= vim_details
['_admin'].get('detailed-status', 'Not found')
2318 project_list
= ctx
.obj
.project
.list()
2319 vim_project_list
= vim_details
.get('_admin').get('projects_read')
2321 project_name
= 'None'
2322 if vim_project_list
:
2323 project_id
= vim_project_list
[0]
2324 for p
in project_list
:
2325 if p
['_id'] == project_id
:
2326 project_name
= p
['name']
2328 table
.add_row([vim
['name'], vim
['uuid'], '{} ({})'.format(project_name
, project_id
),
2329 vim_state
, wrap_text(text
=error_details
, width
=80)])
2331 table
.add_row([vim
['name'], vim
['uuid']])
2336 @cli_osm.command(name
='vim-show', short_help
='shows the details of a VIM account')
2337 @click.argument('name')
2339 def vim_show(ctx
, name
):
2340 """shows the details of a VIM account
2342 NAME: name or ID of the VIM account
2346 resp
= ctx
.obj
.vim
.get(name
)
2347 if 'vim_password' in resp
:
2348 resp
['vim_password']='********'
2349 # except ClientException as e:
2353 table
= PrettyTable(['key', 'attribute'])
2354 for k
, v
in list(resp
.items()):
2355 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2360 ####################
2362 ####################
2364 @cli_osm.command(name
='wim-create', short_help
='creates a new WIM account')
2365 @click.option('--name',
2367 help='Name for the WIM account')
2368 @click.option('--user',
2369 help='WIM username')
2370 @click.option('--password',
2371 help='WIM password')
2372 @click.option('--url',
2375 # @click.option('--tenant',
2376 # help='wIM tenant name')
2377 @click.option('--config',
2379 help='WIM specific config parameters')
2380 @click.option('--wim_type',
2382 @click.option('--description',
2384 help='human readable description')
2385 @click.option('--wim_port_mapping', default
=None,
2386 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2387 "(WAN service endpoint id and info)")
2388 @click.option('--wait',
2392 help='do not return the control immediately, but keep it '
2393 'until the operation is completed, or timeout')
2406 """creates a new WIM account"""
2409 check_client_version(ctx
.obj
, ctx
.command
.name
)
2410 # if sdn_controller:
2411 # check_client_version(ctx.obj, '--sdn_controller')
2412 # if sdn_port_mapping:
2413 # check_client_version(ctx.obj, '--sdn_port_mapping')
2415 if user
: wim
['user'] = user
2416 if password
: wim
['password'] = password
2417 if url
: wim
['wim_url'] = url
2418 # if tenant: wim['tenant'] = tenant
2419 wim
['wim_type'] = wim_type
2420 if description
: wim
['description'] = description
2421 if config
: wim
['config'] = config
2422 ctx
.obj
.wim
.create(name
, wim
, wim_port_mapping
, wait
=wait
)
2423 # except ClientException as e:
2428 @cli_osm.command(name
='wim-update', short_help
='updates a WIM account')
2429 @click.argument('name')
2430 @click.option('--newname', help='New name for the WIM account')
2431 @click.option('--user', help='WIM username')
2432 @click.option('--password', help='WIM password')
2433 @click.option('--url', help='WIM url')
2434 @click.option('--config', help='WIM specific config parameters')
2435 @click.option('--wim_type', help='WIM type')
2436 @click.option('--description', help='human readable description')
2437 @click.option('--wim_port_mapping', default
=None,
2438 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2439 "(WAN service endpoint id and info)")
2440 @click.option('--wait',
2444 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2457 """updates a WIM account
2459 NAME: name or ID of the WIM account
2463 check_client_version(ctx
.obj
, ctx
.command
.name
)
2465 if newname
: wim
['name'] = newname
2466 if user
: wim
['user'] = user
2467 if password
: wim
['password'] = password
2468 if url
: wim
['url'] = url
2469 # if tenant: wim['tenant'] = tenant
2470 if wim_type
: wim
['wim_type'] = wim_type
2471 if description
: wim
['description'] = description
2472 if config
: wim
['config'] = config
2473 ctx
.obj
.wim
.update(name
, wim
, wim_port_mapping
, wait
=wait
)
2474 # except ClientException as e:
2479 @cli_osm.command(name
='wim-delete', short_help
='deletes a WIM account')
2480 @click.argument('name')
2481 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2482 @click.option('--wait',
2486 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2488 def wim_delete(ctx
, name
, force
, wait
):
2489 """deletes a WIM account
2491 NAME: name or ID of the WIM account to be deleted
2495 check_client_version(ctx
.obj
, ctx
.command
.name
)
2496 ctx
.obj
.wim
.delete(name
, force
, wait
=wait
)
2497 # except ClientException as e:
2502 @cli_osm.command(name
='wim-list', short_help
='list all WIM accounts')
2503 @click.option('--filter', default
=None,
2504 help='restricts the list to the WIM accounts matching the filter')
2506 def wim_list(ctx
, filter):
2507 """list all WIM accounts"""
2510 check_client_version(ctx
.obj
, ctx
.command
.name
)
2511 resp
= ctx
.obj
.wim
.list(filter)
2512 table
= PrettyTable(['wim name', 'uuid'])
2514 table
.add_row([wim
['name'], wim
['uuid']])
2517 # except ClientException as e:
2522 @cli_osm.command(name
='wim-show', short_help
='shows the details of a WIM account')
2523 @click.argument('name')
2525 def wim_show(ctx
, name
):
2526 """shows the details of a WIM account
2528 NAME: name or ID of the WIM account
2532 check_client_version(ctx
.obj
, ctx
.command
.name
)
2533 resp
= ctx
.obj
.wim
.get(name
)
2534 if 'password' in resp
:
2535 resp
['wim_password']='********'
2536 # except ClientException as e:
2540 table
= PrettyTable(['key', 'attribute'])
2541 for k
, v
in list(resp
.items()):
2542 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2547 ####################
2548 # SDN controller operations
2549 ####################
2551 @cli_osm.command(name
='sdnc-create', short_help
='creates a new SDN controller')
2552 @click.option('--name',
2554 help='Name to create sdn controller')
2555 @click.option('--type',
2557 help='SDN controller type')
2558 @click.option('--sdn_controller_version', # hidden=True,
2559 help='Deprecated. Use --config {version: sdn_controller_version}')
2560 @click.option('--url',
2561 help='URL in format http[s]://HOST:IP/')
2562 @click.option('--ip_address', # hidden=True,
2563 help='Deprecated. Use --url')
2564 @click.option('--port', # hidden=True,
2565 help='Deprecated. Use --url')
2566 @click.option('--switch_dpid', # hidden=True,
2567 help='Deprecated. Use --config {switch_id: DPID}')
2568 @click.option('--config',
2569 help='Extra information for SDN in yaml format, as {switch_id: identity used for the plugin (e.g. DPID: '
2570 'Openflow Datapath ID), version: version}')
2571 @click.option('--user',
2572 help='SDN controller username')
2573 @click.option('--password',
2575 confirmation_prompt
=True,
2576 help='SDN controller password')
2577 @click.option('--description', default
=None, help='human readable description')
2578 @click.option('--wait',
2582 help="do not return the control immediately, but keep it until the operation is completed, or timeout")
2584 def sdnc_create(ctx
, **kwargs
):
2585 """creates a new SDN controller"""
2587 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2588 x
not in ("wait", "ip_address", "port", "switch_dpid")}
2589 if kwargs
.get("port"):
2590 print("option '--port' is deprecated, use '--url' instead")
2591 sdncontroller
["port"] = int(kwargs
["port"])
2592 if kwargs
.get("ip_address"):
2593 print("option '--ip_address' is deprecated, use '--url' instead")
2594 sdncontroller
["ip"] = kwargs
["ip_address"]
2595 if kwargs
.get("switch_dpid"):
2596 print("option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead")
2597 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2598 if kwargs
.get("sdn_controller_version"):
2599 print("option '--sdn_controller_version' is deprecated, use '--config={version: SDN_CONTROLLER_VERSION}'"
2602 check_client_version(ctx
.obj
, ctx
.command
.name
)
2603 ctx
.obj
.sdnc
.create(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2604 # except ClientException as e:
2608 @cli_osm.command(name
='sdnc-update', short_help
='updates an SDN controller')
2609 @click.argument('name')
2610 @click.option('--newname', help='New name for the SDN controller')
2611 @click.option('--description', default
=None, help='human readable description')
2612 @click.option('--type', help='SDN controller type')
2613 @click.option('--url', help='URL in format http[s]://HOST:IP/')
2614 @click.option('--config', help='Extra information for SDN in yaml format, as '
2615 '{switch_id: identity used for the plugin (e.g. DPID: '
2616 'Openflow Datapath ID), version: version}')
2617 @click.option('--user', help='SDN controller username')
2618 @click.option('--password', help='SDN controller password')
2619 @click.option('--ip_address', help='Deprecated. Use --url') # hidden=True
2620 @click.option('--port', help='Deprecated. Use --url') # hidden=True
2621 @click.option('--switch_dpid', help='Deprecated. Use --config {switch_dpid: DPID}') # hidden=True
2622 @click.option('--sdn_controller_version', help='Deprecated. Use --config {version: VERSION}') # hidden=True
2623 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2624 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2626 def sdnc_update(ctx
, **kwargs
):
2627 """updates an SDN controller
2629 NAME: name or ID of the SDN controller
2632 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2633 x
not in ("wait", "ip_address", "port", "switch_dpid", "new_name")}
2634 if kwargs
.get("newname"):
2635 sdncontroller
["name"] = kwargs
["newname"]
2636 if kwargs
.get("port"):
2637 print("option '--port' is deprecated, use '--url' instead")
2638 sdncontroller
["port"] = int(kwargs
["port"])
2639 if kwargs
.get("ip_address"):
2640 print("option '--ip_address' is deprecated, use '--url' instead")
2641 sdncontroller
["ip"] = kwargs
["ip_address"]
2642 if kwargs
.get("switch_dpid"):
2643 print("option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead")
2644 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2645 if kwargs
.get("sdn_controller_version"):
2646 print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'"
2650 check_client_version(ctx
.obj
, ctx
.command
.name
)
2651 ctx
.obj
.sdnc
.update(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2652 # except ClientException as e:
2657 @cli_osm.command(name
='sdnc-delete', short_help
='deletes an SDN controller')
2658 @click.argument('name')
2659 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2660 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2661 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2663 def sdnc_delete(ctx
, name
, force
, wait
):
2664 """deletes an SDN controller
2666 NAME: name or ID of the SDN controller to be deleted
2670 check_client_version(ctx
.obj
, ctx
.command
.name
)
2671 ctx
.obj
.sdnc
.delete(name
, force
, wait
=wait
)
2672 # except ClientException as e:
2677 @cli_osm.command(name
='sdnc-list', short_help
='list all SDN controllers')
2678 @click.option('--filter', default
=None,
2679 help="restricts the list to the SDN controllers matching the filter with format: 'k[.k..]=v[&k[.k]=v2]'")
2681 def sdnc_list(ctx
, filter):
2682 """list all SDN controllers"""
2685 check_client_version(ctx
.obj
, ctx
.command
.name
)
2686 resp
= ctx
.obj
.sdnc
.list(filter)
2687 # except ClientException as e:
2690 table
= PrettyTable(['sdnc name', 'id'])
2692 table
.add_row([sdnc
['name'], sdnc
['_id']])
2697 @cli_osm.command(name
='sdnc-show', short_help
='shows the details of an SDN controller')
2698 @click.argument('name')
2700 def sdnc_show(ctx
, name
):
2701 """shows the details of an SDN controller
2703 NAME: name or ID of the SDN controller
2707 check_client_version(ctx
.obj
, ctx
.command
.name
)
2708 resp
= ctx
.obj
.sdnc
.get(name
)
2709 # except ClientException as e:
2713 table
= PrettyTable(['key', 'attribute'])
2714 for k
, v
in list(resp
.items()):
2715 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2720 ###########################
2721 # K8s cluster operations
2722 ###########################
2724 @cli_osm.command(name
='k8scluster-add', short_help
='adds a K8s cluster to OSM')
2725 @click.argument('name')
2726 @click.option('--creds',
2728 help='credentials file, i.e. a valid `.kube/config` file')
2729 @click.option('--version',
2731 help='Kubernetes version')
2732 @click.option('--vim',
2734 help='VIM target, the VIM where the cluster resides')
2735 @click.option('--k8s-nets',
2737 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) ...]}"')
2738 @click.option('--description',
2740 help='human readable description')
2741 @click.option('--namespace',
2742 default
='kube-system',
2743 help='namespace to be used for its operation, defaults to `kube-system`')
2744 @click.option('--cni',
2746 help='list of CNI plugins, in JSON inline format, used in the cluster')
2747 #@click.option('--skip-init',
2749 # help='If set, K8s cluster is assumed to be ready for its use with OSM')
2750 #@click.option('--wait',
2752 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2754 def k8scluster_add(ctx
,
2763 """adds a K8s cluster to OSM
2765 NAME: name of the K8s cluster
2768 check_client_version(ctx
.obj
, ctx
.command
.name
)
2770 cluster
['name'] = name
2771 with
open(creds
, 'r') as cf
:
2772 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2773 cluster
['k8s_version'] = version
2774 cluster
['vim_account'] = vim
2775 cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2777 cluster
['description'] = description
2778 if namespace
: cluster
['namespace'] = namespace
2779 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2780 ctx
.obj
.k8scluster
.create(name
, cluster
)
2781 # except ClientException as e:
2786 @cli_osm.command(name
='k8scluster-update', short_help
='updates a K8s cluster')
2787 @click.argument('name')
2788 @click.option('--newname', help='New name for the K8s cluster')
2789 @click.option('--creds', help='credentials file, i.e. a valid `.kube/config` file')
2790 @click.option('--version', help='Kubernetes version')
2791 @click.option('--vim', help='VIM target, the VIM where the cluster resides')
2792 @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) ...]}"')
2793 @click.option('--description', help='human readable description')
2794 @click.option('--namespace', help='namespace to be used for its operation, defaults to `kube-system`')
2795 @click.option('--cni', help='list of CNI plugins, in JSON inline format, used in the cluster')
2797 def k8scluster_update(ctx
,
2807 """updates a K8s cluster
2809 NAME: name or ID of the K8s cluster
2812 check_client_version(ctx
.obj
, ctx
.command
.name
)
2814 if newname
: cluster
['name'] = newname
2816 with
open(creds
, 'r') as cf
:
2817 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2818 if version
: cluster
['k8s_version'] = version
2819 if vim
: cluster
['vim_account'] = vim
2820 if k8s_nets
: cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2821 if description
: cluster
['description'] = description
2822 if namespace
: cluster
['namespace'] = namespace
2823 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2824 ctx
.obj
.k8scluster
.update(name
, cluster
)
2825 # except ClientException as e:
2830 @cli_osm.command(name
='k8scluster-delete', short_help
='deletes a K8s cluster')
2831 @click.argument('name')
2832 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2833 #@click.option('--wait',
2835 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2837 def k8scluster_delete(ctx
, name
, force
):
2838 """deletes a K8s cluster
2840 NAME: name or ID of the K8s cluster to be deleted
2843 check_client_version(ctx
.obj
, ctx
.command
.name
)
2844 ctx
.obj
.k8scluster
.delete(name
, force
=force
)
2845 # except ClientException as e:
2850 @cli_osm.command(name
='k8scluster-list')
2851 @click.option('--filter', default
=None,
2852 help='restricts the list to the K8s clusters matching the filter')
2853 @click.option('--literal', is_flag
=True,
2854 help='print literally, no pretty table')
2856 def k8scluster_list(ctx
, filter, literal
):
2857 """list all K8s clusters"""
2859 check_client_version(ctx
.obj
, ctx
.command
.name
)
2860 resp
= ctx
.obj
.k8scluster
.list(filter)
2862 print(yaml
.safe_dump(resp
))
2864 table
= PrettyTable(['Name', 'Id', 'Version', 'VIM', 'K8s-nets', 'Operational State', 'Description'])
2865 for cluster
in resp
:
2866 table
.add_row([cluster
['name'], cluster
['_id'], cluster
['k8s_version'], cluster
['vim_account'],
2867 json
.dumps(cluster
['nets']), cluster
["_admin"]["operationalState"],
2868 trunc_text(cluster
.get('description',''),40)])
2871 # except ClientException as e:
2876 @cli_osm.command(name
='k8scluster-show', short_help
='shows the details of a K8s cluster')
2877 @click.argument('name')
2878 @click.option('--literal', is_flag
=True,
2879 help='print literally, no pretty table')
2881 def k8scluster_show(ctx
, name
, literal
):
2882 """shows the details of a K8s cluster
2884 NAME: name or ID of the K8s cluster
2887 resp
= ctx
.obj
.k8scluster
.get(name
)
2889 print(yaml
.safe_dump(resp
))
2891 table
= PrettyTable(['key', 'attribute'])
2892 for k
, v
in list(resp
.items()):
2893 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2896 # except ClientException as e:
2902 ###########################
2904 ###########################
2906 @cli_osm.command(name
='repo-add', short_help
='adds a repo to OSM')
2907 @click.argument('name')
2908 @click.argument('uri')
2909 @click.option('--type',
2910 type=click
.Choice(['helm-chart', 'juju-bundle']),
2912 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2913 @click.option('--description',
2915 help='human readable description')
2916 #@click.option('--wait',
2918 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2925 """adds a repo to OSM
2927 NAME: name of the repo
2928 URI: URI of the repo
2931 check_client_version(ctx
.obj
, ctx
.command
.name
)
2937 repo
['description'] = description
2938 ctx
.obj
.repo
.create(name
, repo
)
2939 # except ClientException as e:
2944 @cli_osm.command(name
='repo-update', short_help
='updates a repo in OSM')
2945 @click.argument('name')
2946 @click.option('--newname', help='New name for the repo')
2947 @click.option('--uri', help='URI of the repo')
2948 @click.option('--type', type=click
.Choice(['helm-chart', 'juju-bundle']),
2949 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2950 @click.option('--description', help='human readable description')
2951 #@click.option('--wait',
2953 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2955 def repo_update(ctx
,
2961 """updates a repo in OSM
2963 NAME: name of the repo
2966 check_client_version(ctx
.obj
, ctx
.command
.name
)
2968 if newname
: repo
['name'] = newname
2969 if uri
: repo
['uri'] = uri
2970 if type: repo
['type'] = type
2971 if description
: repo
['description'] = description
2972 ctx
.obj
.repo
.update(name
, repo
)
2973 # except ClientException as e:
2978 @cli_osm.command(name
='repo-delete', short_help
='deletes a repo')
2979 @click.argument('name')
2980 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2981 #@click.option('--wait',
2983 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2985 def repo_delete(ctx
, name
, force
):
2988 NAME: name or ID of the repo to be deleted
2991 check_client_version(ctx
.obj
, ctx
.command
.name
)
2992 ctx
.obj
.repo
.delete(name
, force
=force
)
2993 # except ClientException as e:
2998 @cli_osm.command(name
='repo-list')
2999 @click.option('--filter', default
=None,
3000 help='restricts the list to the repos matching the filter')
3001 @click.option('--literal', is_flag
=True,
3002 help='print literally, no pretty table')
3004 def repo_list(ctx
, filter, literal
):
3005 """list all repos"""
3007 check_client_version(ctx
.obj
, ctx
.command
.name
)
3008 resp
= ctx
.obj
.repo
.list(filter)
3010 print(yaml
.safe_dump(resp
))
3012 table
= PrettyTable(['Name', 'Id', 'Type', 'URI', 'Description'])
3014 #cluster['k8s-nets'] = json.dumps(yaml.safe_load(cluster['k8s-nets']))
3015 table
.add_row([repo
['name'], repo
['_id'], repo
['type'], repo
['url'], trunc_text(repo
.get('description',''),40)])
3018 # except ClientException as e:
3023 @cli_osm.command(name
='repo-show', short_help
='shows the details of a repo')
3024 @click.argument('name')
3025 @click.option('--literal', is_flag
=True,
3026 help='print literally, no pretty table')
3028 def repo_show(ctx
, name
, literal
):
3029 """shows the details of a repo
3031 NAME: name or ID of the repo
3034 resp
= ctx
.obj
.repo
.get(name
)
3036 print(yaml
.safe_dump(resp
))
3038 table
= PrettyTable(['key', 'attribute'])
3039 for k
, v
in list(resp
.items()):
3040 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3043 # except ClientException as e:
3049 ####################
3050 # Project mgmt operations
3051 ####################
3053 @cli_osm.command(name
='project-create', short_help
='creates a new project')
3054 @click.argument('name')
3055 #@click.option('--description',
3056 # default='no description',
3057 # help='human readable description')
3058 @click.option('--domain-name', 'domain_name',
3060 help='assign to a domain')
3062 def project_create(ctx
, name
, domain_name
):
3063 """Creates a new project
3065 NAME: name of the project
3066 DOMAIN_NAME: optional domain name for the project when keystone authentication is used
3070 project
['name'] = name
3072 project
['domain_name'] = domain_name
3074 check_client_version(ctx
.obj
, ctx
.command
.name
)
3075 ctx
.obj
.project
.create(name
, project
)
3076 # except ClientException as e:
3081 @cli_osm.command(name
='project-delete', short_help
='deletes a project')
3082 @click.argument('name')
3083 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3085 def project_delete(ctx
, name
):
3086 """deletes a project
3088 NAME: name or ID of the project to be deleted
3092 check_client_version(ctx
.obj
, ctx
.command
.name
)
3093 ctx
.obj
.project
.delete(name
)
3094 # except ClientException as e:
3099 @cli_osm.command(name
='project-list', short_help
='list all projects')
3100 @click.option('--filter', default
=None,
3101 help='restricts the list to the projects matching the filter')
3103 def project_list(ctx
, filter):
3104 """list all projects"""
3107 check_client_version(ctx
.obj
, ctx
.command
.name
)
3108 resp
= ctx
.obj
.project
.list(filter)
3109 # except ClientException as e:
3112 table
= PrettyTable(['name', 'id'])
3114 table
.add_row([proj
['name'], proj
['_id']])
3119 @cli_osm.command(name
='project-show', short_help
='shows the details of a project')
3120 @click.argument('name')
3122 def project_show(ctx
, name
):
3123 """shows the details of a project
3125 NAME: name or ID of the project
3129 check_client_version(ctx
.obj
, ctx
.command
.name
)
3130 resp
= ctx
.obj
.project
.get(name
)
3131 # except ClientException as e:
3135 table
= PrettyTable(['key', 'attribute'])
3136 for k
, v
in resp
.items():
3137 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3142 @cli_osm.command(name
='project-update', short_help
='updates a project (only the name can be updated)')
3143 @click.argument('project')
3144 @click.option('--name',
3146 help='new name for the project')
3149 def project_update(ctx
, project
, name
):
3151 Update a project name
3154 :param project: id or name of the project to modify
3155 :param name: new name for the project
3159 project_changes
= {}
3160 project_changes
['name'] = name
3163 check_client_version(ctx
.obj
, ctx
.command
.name
)
3164 ctx
.obj
.project
.update(project
, project_changes
)
3165 # except ClientException as e:
3169 ####################
3170 # User mgmt operations
3171 ####################
3173 @cli_osm.command(name
='user-create', short_help
='creates a new user')
3174 @click.argument('username')
3175 @click.option('--password',
3178 confirmation_prompt
=True,
3179 help='user password')
3180 @click.option('--projects',
3181 # prompt="Comma separate list of projects",
3183 callback
=lambda ctx
, param
, value
: ''.join(value
).split(',') if all(len(x
)==1 for x
in value
) else value
,
3184 help='list of project ids that the user belongs to')
3185 @click.option('--project-role-mappings', 'project_role_mappings',
3186 default
=None, multiple
=True,
3187 help="assign role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3188 @click.option('--domain-name', 'domain_name',
3190 help='assign to a domain')
3192 def user_create(ctx
, username
, password
, projects
, project_role_mappings
, domain_name
):
3193 """Creates a new user
3196 USERNAME: name of the user
3197 PASSWORD: password of the user
3198 PROJECTS: projects assigned to user (internal only)
3199 PROJECT_ROLE_MAPPING: roles in projects assigned to user (keystone)
3200 DOMAIN_NAME: optional domain name for the user when keystone authentication is used
3204 user
['username'] = username
3205 user
['password'] = password
3206 user
['projects'] = projects
3207 user
['project_role_mappings'] = project_role_mappings
3209 user
['domain_name'] = domain_name
3212 check_client_version(ctx
.obj
, ctx
.command
.name
)
3213 ctx
.obj
.user
.create(username
, user
)
3214 # except ClientException as e:
3219 @cli_osm.command(name
='user-update', short_help
='updates user information')
3220 @click.argument('username')
3221 @click.option('--password',
3224 # confirmation_prompt=True,
3225 help='user password')
3226 @click.option('--set-username', 'set_username',
3228 help='change username')
3229 @click.option('--set-project', 'set_project',
3230 default
=None, multiple
=True,
3231 help="create/replace the roles for this project: 'project,role1[,role2,...]'")
3232 @click.option('--remove-project', 'remove_project',
3233 default
=None, multiple
=True,
3234 help="removes project from user: 'project'")
3235 @click.option('--add-project-role', 'add_project_role',
3236 default
=None, multiple
=True,
3237 help="assign role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3238 @click.option('--remove-project-role', 'remove_project_role',
3239 default
=None, multiple
=True,
3240 help="remove role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3242 def user_update(ctx
, username
, password
, set_username
, set_project
, remove_project
,
3243 add_project_role
, remove_project_role
):
3244 """Update a user information
3247 USERNAME: name of the user
3248 PASSWORD: new password
3249 SET_USERNAME: new username
3250 SET_PROJECT: creating mappings for project/role(s)
3251 REMOVE_PROJECT: deleting mappings for project/role(s)
3252 ADD_PROJECT_ROLE: adding mappings for project/role(s)
3253 REMOVE_PROJECT_ROLE: removing mappings for project/role(s)
3257 user
['password'] = password
3258 user
['username'] = set_username
3259 user
['set-project'] = set_project
3260 user
['remove-project'] = remove_project
3261 user
['add-project-role'] = add_project_role
3262 user
['remove-project-role'] = remove_project_role
3265 check_client_version(ctx
.obj
, ctx
.command
.name
)
3266 ctx
.obj
.user
.update(username
, user
)
3267 # except ClientException as e:
3272 @cli_osm.command(name
='user-delete', short_help
='deletes a user')
3273 @click.argument('name')
3274 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3276 def user_delete(ctx
, name
):
3280 NAME: name or ID of the user to be deleted
3284 check_client_version(ctx
.obj
, ctx
.command
.name
)
3285 ctx
.obj
.user
.delete(name
)
3286 # except ClientException as e:
3291 @cli_osm.command(name
='user-list', short_help
='list all users')
3292 @click.option('--filter', default
=None,
3293 help='restricts the list to the users matching the filter')
3295 def user_list(ctx
, filter):
3296 """list all users"""
3298 check_client_version(ctx
.obj
, ctx
.command
.name
)
3299 resp
= ctx
.obj
.user
.list(filter)
3300 # except ClientException as e:
3303 table
= PrettyTable(['name', 'id'])
3305 table
.add_row([user
['username'], user
['_id']])
3310 @cli_osm.command(name
='user-show', short_help
='shows the details of a user')
3311 @click.argument('name')
3313 def user_show(ctx
, name
):
3314 """shows the details of a user
3316 NAME: name or ID of the user
3320 check_client_version(ctx
.obj
, ctx
.command
.name
)
3321 resp
= ctx
.obj
.user
.get(name
)
3322 if 'password' in resp
:
3323 resp
['password']='********'
3324 # except ClientException as e:
3328 table
= PrettyTable(['key', 'attribute'])
3329 for k
, v
in resp
.items():
3330 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3335 ####################
3336 # Fault Management operations
3337 ####################
3339 @cli_osm.command(name
='ns-alarm-create')
3340 @click.argument('name')
3341 @click.option('--ns', prompt
=True, help='NS instance id or name')
3342 @click.option('--vnf', prompt
=True,
3343 help='VNF name (VNF member index as declared in the NSD)')
3344 @click.option('--vdu', prompt
=True,
3345 help='VDU name (VDU name as declared in the VNFD)')
3346 @click.option('--metric', prompt
=True,
3347 help='Name of the metric (e.g. cpu_utilization)')
3348 @click.option('--severity', default
='WARNING',
3349 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
3350 @click.option('--threshold_value', prompt
=True,
3351 help='threshold value that, when crossed, an alarm is triggered')
3352 @click.option('--threshold_operator', prompt
=True,
3353 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
3354 @click.option('--statistic', default
='AVERAGE',
3355 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
3357 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
3358 threshold_value
, threshold_operator
, statistic
):
3359 """creates a new alarm for a NS instance"""
3360 # TODO: Check how to validate threshold_value.
3361 # Should it be an integer (1-100), percentage, or decimal (0.01-1.00)?
3364 ns_instance
= ctx
.obj
.ns
.get(ns
)
3366 alarm
['alarm_name'] = name
3367 alarm
['ns_id'] = ns_instance
['_id']
3368 alarm
['correlation_id'] = ns_instance
['_id']
3369 alarm
['vnf_member_index'] = vnf
3370 alarm
['vdu_name'] = vdu
3371 alarm
['metric_name'] = metric
3372 alarm
['severity'] = severity
3373 alarm
['threshold_value'] = int(threshold_value
)
3374 alarm
['operation'] = threshold_operator
3375 alarm
['statistic'] = statistic
3376 check_client_version(ctx
.obj
, ctx
.command
.name
)
3377 ctx
.obj
.ns
.create_alarm(alarm
)
3378 # except ClientException as e:
3383 #@cli_osm.command(name='ns-alarm-delete')
3384 #@click.argument('name')
3385 #@click.pass_context
3386 #def ns_alarm_delete(ctx, name):
3387 # """deletes an alarm
3389 # NAME: name of the alarm to be deleted
3392 # check_client_version(ctx.obj, ctx.command.name)
3393 # ctx.obj.ns.delete_alarm(name)
3394 # except ClientException as e:
3399 ####################
3400 # Performance Management operations
3401 ####################
3403 @cli_osm.command(name
='ns-metric-export', short_help
='exports a metric to the internal OSM bus, which can be read by other apps')
3404 @click.option('--ns', prompt
=True, help='NS instance id or name')
3405 @click.option('--vnf', prompt
=True,
3406 help='VNF name (VNF member index as declared in the NSD)')
3407 @click.option('--vdu', prompt
=True,
3408 help='VDU name (VDU name as declared in the VNFD)')
3409 @click.option('--metric', prompt
=True,
3410 help='name of the metric (e.g. cpu_utilization)')
3411 #@click.option('--period', default='1w',
3412 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
3413 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
3415 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
3416 """exports a metric to the internal OSM bus, which can be read by other apps"""
3417 # TODO: Check how to validate interval.
3418 # Should it be an integer (seconds), or should a suffix (s,m,h,d,w) also be permitted?
3421 ns_instance
= ctx
.obj
.ns
.get(ns
)
3423 metric_data
['ns_id'] = ns_instance
['_id']
3424 metric_data
['correlation_id'] = ns_instance
['_id']
3425 metric_data
['vnf_member_index'] = vnf
3426 metric_data
['vdu_name'] = vdu
3427 metric_data
['metric_name'] = metric
3428 metric_data
['collection_unit'] = 'WEEK'
3429 metric_data
['collection_period'] = 1
3430 check_client_version(ctx
.obj
, ctx
.command
.name
)
3432 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
3436 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
3437 time
.sleep(int(interval
))
3439 # except ClientException as e:
3444 ####################
3446 ####################
3448 @cli_osm.command(name
='version', short_help
='shows client and server versions')
3450 def get_version(ctx
):
3451 """shows client and server versions"""
3453 check_client_version(ctx
.obj
, "version")
3454 print ("Server version: {}".format(ctx
.obj
.get_version()))
3455 print ("Client version: {}".format(pkg_resources
.get_distribution("osmclient").version
))
3456 # except ClientException as e:
3460 @cli_osm.command(name
='upload-package', short_help
='uploads a VNF package or NS package')
3461 @click.argument('filename')
3462 @click.option('--skip-charm-build', default
=False, is_flag
=True,
3463 help='the charm will not be compiled, it is assumed to already exist')
3465 def upload_package(ctx
, filename
, skip_charm_build
):
3466 """uploads a vnf package or ns package
3468 filename: vnf or ns package folder, or vnf or ns package file (tar.gz)
3472 ctx
.obj
.package
.upload(filename
, skip_charm_build
=skip_charm_build
)
3473 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
3474 if fullclassname
!= 'osmclient.sol005.client.Client':
3475 ctx
.obj
.package
.wait_for_upload(filename
)
3476 # except ClientException as e:
3481 #@cli_osm.command(name='ns-scaling-show')
3482 #@click.argument('ns_name')
3483 #@click.pass_context
3484 #def show_ns_scaling(ctx, ns_name):
3485 # """shows the status of a NS scaling operation
3487 # NS_NAME: name of the NS instance being scaled
3490 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3491 # resp = ctx.obj.ns.list()
3492 # except ClientException as e:
3496 # table = PrettyTable(
3499 # 'operational status',
3504 # if ns_name == ns['name']:
3505 # nsopdata = ctx.obj.ns.get_opdata(ns['id'])
3506 # scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
3507 # for record in scaling_records:
3508 # if 'instance' in record:
3509 # instances = record['instance']
3510 # for inst in instances:
3512 # [record['scaling-group-name-ref'],
3513 # inst['instance-id'],
3514 # inst['op-status'],
3515 # time.strftime('%Y-%m-%d %H:%M:%S',
3517 # inst['create-time'])),
3523 #@cli_osm.command(name='ns-scale')
3524 #@click.argument('ns_name')
3525 #@click.option('--ns_scale_group', prompt=True)
3526 #@click.option('--index', prompt=True)
3527 #@click.option('--wait',
3531 # help='do not return the control immediately, but keep it \
3532 # until the operation is completed, or timeout')
3533 #@click.pass_context
3534 #def ns_scale(ctx, ns_name, ns_scale_group, index, wait):
3537 # NS_NAME: name of the NS instance to be scaled
3540 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3541 # ctx.obj.ns.scale(ns_name, ns_scale_group, index, wait=wait)
3542 # except ClientException as e:
3547 #@cli_osm.command(name='config-agent-list')
3548 #@click.pass_context
3549 #def config_agent_list(ctx):
3550 # """list config agents"""
3552 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3553 # except ClientException as e:
3556 # table = PrettyTable(['name', 'account-type', 'details'])
3557 # for account in ctx.obj.vca.list():
3560 # account['account-type'],
3566 #@cli_osm.command(name='config-agent-delete')
3567 #@click.argument('name')
3568 #@click.pass_context
3569 #def config_agent_delete(ctx, name):
3570 # """deletes a config agent
3572 # NAME: name of the config agent to be deleted
3575 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3576 # ctx.obj.vca.delete(name)
3577 # except ClientException as e:
3582 #@cli_osm.command(name='config-agent-add')
3583 #@click.option('--name',
3585 #@click.option('--account_type',
3587 #@click.option('--server',
3589 #@click.option('--user',
3591 #@click.option('--secret',
3594 # confirmation_prompt=True)
3595 #@click.pass_context
3596 #def config_agent_add(ctx, name, account_type, server, user, secret):
3597 # """adds a config agent"""
3599 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3600 # ctx.obj.vca.create(name, account_type, server, user, secret)
3601 # except ClientException as e:
3606 #@cli_osm.command(name='ro-dump')
3607 #@click.pass_context
3609 # """shows RO agent information"""
3610 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3611 # resp = ctx.obj.vim.get_resource_orchestrator()
3612 # table = PrettyTable(['key', 'attribute'])
3613 # for k, v in list(resp.items()):
3614 # table.add_row([k, json.dumps(v, indent=2)])
3619 #@cli_osm.command(name='vcs-list')
3620 #@click.pass_context
3622 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3623 # resp = ctx.obj.utils.get_vcs_info()
3624 # table = PrettyTable(['component name', 'state'])
3625 # for component in resp:
3626 # table.add_row([component['component_name'], component['state']])
3631 @cli_osm.command(name
='ns-action', short_help
='executes an action/primitive over a NS instance')
3632 @click.argument('ns_name')
3633 @click.option('--vnf_name', default
=None, help='member-vnf-index if the target is a vnf instead of a ns)')
3634 @click.option('--kdu_name', default
=None, help='kdu-name if the target is a kdu)')
3635 @click.option('--vdu_id', default
=None, help='vdu-id if the target is a vdu')
3636 @click.option('--vdu_count', default
=None, help='number of vdu instance of this vdu_id')
3637 @click.option('--action_name', prompt
=True, help='action name')
3638 @click.option('--params', default
=None, help='action params in YAML/JSON inline string')
3639 @click.option('--params_file', default
=None, help='YAML/JSON file with action params')
3640 @click.option('--timeout', required
=False, default
=None, type=int, help='timeout in seconds')
3641 @click.option('--wait',
3645 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3658 """executes an action/primitive over a NS instance
3660 NS_NAME: name or ID of the NS instance
3664 check_client_version(ctx
.obj
, ctx
.command
.name
)
3667 op_data
['member_vnf_index'] = vnf_name
3669 op_data
['kdu_name'] = kdu_name
3671 op_data
['vdu_id'] = vdu_id
3673 op_data
['vdu_count_index'] = vdu_count
3675 op_data
['timeout_ns_action'] = timeout
3676 op_data
['primitive'] = action_name
3678 with
open(params_file
, 'r') as pf
:
3681 op_data
['primitive_params'] = yaml
.safe_load(params
)
3683 op_data
['primitive_params'] = {}
3684 print(ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
, wait
=wait
))
3686 # except ClientException as e:
3691 @cli_osm.command(name
='vnf-scale', short_help
='executes a VNF scale (adding/removing VDUs)')
3692 @click.argument('ns_name')
3693 @click.argument('vnf_name')
3694 @click.option('--scaling-group', prompt
=True, help="scaling-group-descriptor name to use")
3695 @click.option('--scale-in', default
=False, is_flag
=True, help="performs a scale in operation")
3696 @click.option('--scale-out', default
=False, is_flag
=True, help="performs a scale out operation (by default)")
3697 @click.option('--timeout', required
=False, default
=None, type=int, help='timeout in seconds')
3698 @click.option('--wait', required
=False, default
=False, is_flag
=True,
3699 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3710 Executes a VNF scale (adding/removing VDUs)
3713 NS_NAME: name or ID of the NS instance.
3714 VNF_NAME: member-vnf-index in the NS to be scaled.
3718 check_client_version(ctx
.obj
, ctx
.command
.name
)
3719 if not scale_in
and not scale_out
:
3721 ctx
.obj
.ns
.scale_vnf(ns_name
, vnf_name
, scaling_group
, scale_in
, scale_out
, wait
, timeout
)
3722 # except ClientException as e:
3727 ##############################
3728 # Role Management Operations #
3729 ##############################
3731 @cli_osm.command(name
='role-create', short_help
='creates a new role')
3732 @click.argument('name')
3733 @click.option('--permissions',
3735 help='role permissions using a dictionary')
3737 def role_create(ctx
, name
, permissions
):
3742 NAME: Name or ID of the role.
3743 DEFINITION: Definition of grant/denial of access to resources.
3747 check_client_version(ctx
.obj
, ctx
.command
.name
)
3748 ctx
.obj
.role
.create(name
, permissions
)
3749 # except ClientException as e:
3754 @cli_osm.command(name
='role-update', short_help
='updates a role')
3755 @click.argument('name')
3756 @click.option('--set-name',
3758 help='change name of rle')
3759 # @click.option('--permissions',
3761 # help='provide a yaml format dictionary with incremental changes. Values can be bool or None to delete')
3762 @click.option('--add',
3764 help='yaml format dictionary with permission: True/False to access grant/denial')
3765 @click.option('--remove',
3767 help='yaml format list to remove a permission')
3769 def role_update(ctx
, name
, set_name
, add
, remove
):
3774 NAME: Name or ID of the role.
3775 DEFINITION: Definition overwrites the old definition.
3776 ADD: Grant/denial of access to resource to add.
3777 REMOVE: Grant/denial of access to resource to remove.
3781 check_client_version(ctx
.obj
, ctx
.command
.name
)
3782 ctx
.obj
.role
.update(name
, set_name
, None, add
, remove
)
3783 # except ClientException as e:
3788 @cli_osm.command(name
='role-delete', short_help
='deletes a role')
3789 @click.argument('name')
3790 # @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3792 def role_delete(ctx
, name
):
3797 NAME: Name or ID of the role.
3801 check_client_version(ctx
.obj
, ctx
.command
.name
)
3802 ctx
.obj
.role
.delete(name
)
3803 # except ClientException as e:
3808 @cli_osm.command(name
='role-list', short_help
='list all roles')
3809 @click.option('--filter', default
=None,
3810 help='restricts the list to the projects matching the filter')
3812 def role_list(ctx
, filter):
3818 check_client_version(ctx
.obj
, ctx
.command
.name
)
3819 resp
= ctx
.obj
.role
.list(filter)
3820 # except ClientException as e:
3823 table
= PrettyTable(['name', 'id'])
3825 table
.add_row([role
['name'], role
['_id']])
3830 @cli_osm.command(name
='role-show', short_help
='show specific role')
3831 @click.argument('name')
3833 def role_show(ctx
, name
):
3835 Shows the details of a role.
3838 NAME: Name or ID of the role.
3842 check_client_version(ctx
.obj
, ctx
.command
.name
)
3843 resp
= ctx
.obj
.role
.get(name
)
3844 # except ClientException as e:
3848 table
= PrettyTable(['key', 'attribute'])
3849 for k
, v
in resp
.items():
3850 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3855 @cli_osm.command(name
='package-create',
3856 short_help
='Create a package descriptor')
3857 @click.argument('package-type')
3858 @click.argument('package-name')
3859 @click.option('--base-directory',
3861 help=('(NS/VNF/NST) Set the location for package creation. Default: "."'))
3862 @click.option('--image',
3863 default
="image-name",
3864 help='(VNF) Set the name of the vdu image. Default "image-name"')
3865 @click.option('--vdus',
3867 help='(VNF) Set the number of vdus in a VNF. Default 1')
3868 @click.option('--vcpu',
3870 help='(VNF) Set the number of virtual CPUs in a vdu. Default 1')
3871 @click.option('--memory',
3873 help='(VNF) Set the memory size (MB) of the vdu. Default 1024')
3874 @click.option('--storage',
3876 help='(VNF) Set the disk size (GB) of the vdu. Default 10')
3877 @click.option('--interfaces',
3879 help='(VNF) Set the number of additional interfaces apart from the management interface. Default 0')
3880 @click.option('--vendor',
3882 help='(NS/VNF) Set the descriptor vendor. Default "OSM"')
3883 @click.option('--override',
3886 help='(NS/VNF/NST) Flag for overriding the package if exists.')
3887 @click.option('--detailed',
3890 help='(NS/VNF/NST) Flag for generating descriptor .yaml with all possible commented options')
3891 @click.option('--netslice-subnets',
3893 help='(NST) Number of netslice subnets. Default 1')
3894 @click.option('--netslice-vlds',
3896 help='(NST) Number of netslice vlds. Default 1')
3898 def package_create(ctx
,
3914 Creates an OSM NS, VNF, NST package
3917 PACKAGE_TYPE: Package to be created: NS, VNF or NST.
3918 PACKAGE_NAME: Name of the package to create the folder with the content.
3922 check_client_version(ctx
.obj
, ctx
.command
.name
)
3923 print("Creating the {} structure: {}/{}".format(package_type
.upper(), base_directory
, package_name
))
3924 resp
= ctx
.obj
.package_tool
.create(package_type
,
3933 interfaces
=interfaces
,
3936 netslice_subnets
=netslice_subnets
,
3937 netslice_vlds
=netslice_vlds
)
3939 # except ClientException as inst:
3940 # print("ERROR: {}".format(inst))
3943 @cli_osm.command(name
='package-validate',
3944 short_help
='Validate a package descriptor')
3945 @click.argument('base-directory',
3948 @click.option('--recursive/--no-recursive',
3950 help='The activated recursive option will validate the yaml files'
3951 ' within the indicated directory and in its subdirectories')
3953 def package_validate(ctx
,
3957 Validate descriptors given a base directory.
3960 BASE_DIRECTORY: Stub folder for NS, VNF or NST package.
3963 check_client_version(ctx
.obj
, ctx
.command
.name
)
3964 results
= ctx
.obj
.package_tool
.validate(base_directory
, recursive
)
3965 table
= PrettyTable()
3966 table
.field_names
= ["TYPE", "PATH", "VALID", "ERROR"]
3967 # Print the dictionary generated by the validation function
3968 for result
in results
:
3969 table
.add_row([result
["type"], result
["path"], result
["valid"], result
["error"]])
3970 table
.sortby
= "VALID"
3971 table
.align
["PATH"] = "l"
3972 table
.align
["TYPE"] = "l"
3973 table
.align
["ERROR"] = "l"
3975 # except ClientException as inst:
3976 # print("ERROR: {}".format(inst))
3979 @cli_osm.command(name
='package-build',
3980 short_help
='Build the tar.gz of the package')
3981 @click.argument('package-folder')
3982 @click.option('--skip-validation',
3985 help='skip package validation')
3986 @click.option('--skip-charm-build', default
=False, is_flag
=True,
3987 help='the charm will not be compiled, it is assumed to already exist')
3989 def package_build(ctx
,
3994 Build the package NS, VNF given the package_folder.
3997 PACKAGE_FOLDER: Folder of the NS, VNF or NST to be packaged
4000 check_client_version(ctx
.obj
, ctx
.command
.name
)
4001 results
= ctx
.obj
.package_tool
.build(package_folder
,
4002 skip_validation
=skip_validation
,
4003 skip_charm_build
=skip_charm_build
)
4005 # except ClientException as inst:
4006 # print("ERROR: {}".format(inst))
4014 except pycurl
.error
as exc
:
4016 print('Maybe "--hostname" option or OSM_HOSTNAME environment variable needs to be specified')
4017 except ClientException
as exc
:
4018 print("ERROR: {}".format(exc
))
4019 except (FileNotFoundError
, PermissionError
) as exc
:
4020 print("Cannot open file: {}".format(exc
))
4021 except yaml
.YAMLError
as exc
:
4022 print("Invalid YAML format: {}".format(exc
))
4024 # TODO capture other controlled exceptions here
4025 # TODO remove the ClientException captures from all places, unless they do something different
4028 if __name__
== '__main__':