c6de974310b56973f3dfd475861b64d730298451
1 # Copyright 2017-2018 Sandvine
2 # Copyright 2018 Telefonica
6 # Licensed under the Apache License, Version 2.0 (the "License"); you may
7 # not use this file except in compliance with the License. You may obtain
8 # a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 # License for the specific language governing permissions and limitations
22 from osmclient
import client
23 from osmclient
.common
.exceptions
import ClientException
24 from prettytable
import PrettyTable
33 from datetime
import datetime
38 CONTEXT_SETTINGS
= dict(help_option_names
=['-h', '--help'], max_content_width
=160)
40 def wrap_text(text
, width
):
41 wrapper
= textwrap
.TextWrapper(width
=width
)
42 lines
= text
.splitlines()
43 return "\n".join(map(wrapper
.fill
, lines
))
46 def trunc_text(text
, length
):
47 if len(text
) > length
:
48 return text
[:(length
- 3)] + '...'
53 def check_client_version(obj
, what
, version
='sol005'):
55 Checks the version of the client object and raises error if it not the expected.
57 :param obj: the client object
58 :what: the function or command under evaluation (used when an error is raised)
60 :raises ClientError: if the specified version does not match the client version
63 fullclassname
= obj
.__module
__ + "." + obj
.__class
__.__name
__
64 message
= 'The following commands or options are only supported with the option "--sol005": {}'.format(what
)
66 message
= 'The following commands or options are not supported when using option "--sol005": {}'.format(what
)
67 if fullclassname
!= 'osmclient.{}.client.Client'.format(version
):
68 raise ClientException(message
)
72 @click.group(context_settings
=dict(help_option_names
=['-h', '--help'], max_content_width
=160))
73 @click.option('--hostname',
75 envvar
='OSM_HOSTNAME',
76 help='hostname of server. ' +
77 'Also can set OSM_HOSTNAME in environment')
78 #@click.option('--sol005/--no-sol005',
80 # envvar='OSM_SOL005',
81 # help='Use ETSI NFV SOL005 API (default) or the previous SO API. ' +
82 # 'Also can set OSM_SOL005 in environment')
83 @click.option('--user',
86 help='user (defaults to admin). ' +
87 'Also can set OSM_USER in environment')
88 @click.option('--password',
90 envvar
='OSM_PASSWORD',
91 help='password (defaults to admin). ' +
92 'Also can set OSM_PASSWORD in environment')
93 @click.option('--project',
96 help='project (defaults to admin). ' +
97 'Also can set OSM_PROJECT in environment')
98 @click.option('-v', '--verbose', count
=True,
99 help='increase verbosity (-v INFO, -vv VERBOSE, -vvv DEBUG)')
100 @click.option('--all-projects',
103 help='include all projects')
104 @click.option('--public/--no-public', default
=None,
105 help='flag for public items (packages, instances, VIM accounts, etc.)')
106 @click.option('--project-domain-name', 'project_domain_name',
108 envvar
='OSM_PROJECT_DOMAIN_NAME',
109 help='project domain name for keystone authentication (default to None). ' +
110 'Also can set OSM_PROJECT_DOMAIN_NAME in environment')
111 @click.option('--user-domain-name', 'user_domain_name',
113 envvar
='OSM_USER_DOMAIN_NAME',
114 help='user domain name for keystone authentication (default to None). ' +
115 'Also can set OSM_USER_DOMAIN_NAME in environment')
116 #@click.option('--so-port',
118 # envvar='OSM_SO_PORT',
119 # help='hostname of server. ' +
120 # 'Also can set OSM_SO_PORT in environment')
121 #@click.option('--so-project',
123 # envvar='OSM_SO_PROJECT',
124 # help='Project Name in SO. ' +
125 # 'Also can set OSM_SO_PROJECT in environment')
126 #@click.option('--ro-hostname',
128 # envvar='OSM_RO_HOSTNAME',
129 # help='hostname of RO server. ' +
130 # 'Also can set OSM_RO_HOSTNAME in environment')
131 #@click.option('--ro-port',
133 # envvar='OSM_RO_PORT',
134 # help='hostname of RO server. ' +
135 # 'Also can set OSM_RO_PORT in environment')
137 def cli_osm(ctx
, **kwargs
):
139 hostname
= kwargs
.pop("hostname", None)
142 "either hostname option or OSM_HOSTNAME " +
143 "environment variable needs to be specified"))
146 kwargs
= {k
: v
for k
, v
in kwargs
.items() if v
is not None}
147 # if so_port is not None:
148 # kwargs['so_port']=so_port
149 # if so_project is not None:
150 # kwargs['so_project']=so_project
151 # if ro_hostname is not None:
152 # kwargs['ro_host']=ro_hostname
153 # if ro_port is not None:
154 # kwargs['ro_port']=ro_port
155 sol005
= os
.getenv('OSM_SOL005', True)
156 # if user is not None:
157 # kwargs['user']=user
158 # if password is not None:
159 # kwargs['password']=password
160 # if project is not None:
161 # kwargs['project']=project
163 # kwargs['all_projects']=all_projects
164 # if public is not None:
165 # kwargs['public']=public
166 ctx
.obj
= client
.Client(host
=hostname
, sol005
=sol005
, **kwargs
)
167 logger
= logging
.getLogger('osmclient')
174 @cli_osm.command(name
='ns-list', short_help
='list all NS instances')
175 @click.option('--filter', default
=None,
176 help='restricts the list to the NS instances matching the filter.')
177 @click.option('--long', is_flag
=True,
178 help='get more details of the NS (project, vim, deployment status, configuration status.')
180 def ns_list(ctx
, filter, long):
181 """list all NS instances
185 --filter filterExpr Restricts the list to the NS instances matching the filter
188 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
189 concatenated using the "&" character:
192 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
193 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
194 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
196 value := scalar value
200 * zero or more occurrences
201 ? zero or one occurrence
202 [] grouping of expressions to be used with ? and *
203 "" quotation marks for marking string constants
207 "AttrName" is the name of one attribute in the data type that defines the representation
208 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
209 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
210 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
211 entries, it means that the operator "op" is applied to the attribute addressed by the last
212 <attrName> entry included in the concatenation. All simple filter expressions are combined
213 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
214 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
215 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
216 prefix". If an attribute referenced in an expression is an array, an object that contains a
217 corresponding array shall be considered to match the expression if any of the elements in the
218 array matches all expressions that have the same attribute prefix.
222 --filter admin-status=ENABLED
223 --filter nsd-ref=<NSD_NAME>
224 --filter nsd.vendor=<VENDOR>
225 --filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME>
226 --filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME>
228 def summarize_deployment_status(status_dict
):
235 net_list
= status_dict
.get('nets',[])
238 if net
['status'] not in status_nets
:
239 status_nets
[net
['status']] = 1
241 status_nets
[net
['status']] +=1
243 for k
,v
in status_nets
.items():
244 message
+= "{}:{},".format(k
,v
)
245 message
+= "TOTAL:{}".format(n_nets
)
246 summary
+= "{}".format(message
)
251 vnf_list
= status_dict
['vnfs']
253 member_vnf_index
= vnf
['member_vnf_index']
254 if member_vnf_index
not in status_vnfs
:
255 status_vnfs
[member_vnf_index
] = {}
256 for vm
in vnf
['vms']:
258 if vm
['status'] not in status_vms
:
259 status_vms
[vm
['status']] = 1
261 status_vms
[vm
['status']] +=1
262 if vm
['status'] not in status_vnfs
[member_vnf_index
]:
263 status_vnfs
[member_vnf_index
][vm
['status']] = 1
265 status_vnfs
[member_vnf_index
][vm
['status']] += 1
267 for k
,v
in status_vms
.items():
268 message
+= "{}:{},".format(k
,v
)
269 message
+= "TOTAL:{}".format(n_vms
)
270 summary
+= "\n{}".format(message
)
272 for k
,v
in status_vnfs
.items():
274 message
= "\n {} VMs: ".format(k
)
275 for k2
,v2
in v
.items():
276 message
+= "{}:{},".format(k2
,v2
)
278 message
+= "TOTAL:{}".format(total
)
282 def summarize_config_status(ee_list
):
290 if ee
['elementType'] not in status_ee
:
291 status_ee
[ee
['elementType']] = {}
292 status_ee
[ee
['elementType']][ee
['status']] = 1
294 if ee
['status'] in status_ee
[ee
['elementType']]:
295 status_ee
[ee
['elementType']][ee
['status']] += 1
297 status_ee
[ee
['elementType']][ee
['status']] = 1
298 for elementType
in ["KDU", "VDU", "PDU", "VNF", "NS"]:
299 if elementType
in status_ee
:
302 for k
,v
in status_ee
[elementType
].items():
303 message
+= "{}:{},".format(k
,v
)
305 message
+= "TOTAL:{}\n".format(total
)
306 summary
+= "{}: {}".format(elementType
, message
)
307 summary
+= "TOTAL Exec. Env.: {}".format(n_ee
)
312 check_client_version(ctx
.obj
, '--filter')
313 resp
= ctx
.obj
.ns
.list(filter)
315 resp
= ctx
.obj
.ns
.list()
327 'configuration status'])
328 project_list
= ctx
.obj
.project
.list()
329 vim_list
= ctx
.obj
.vim
.list()
339 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
340 if fullclassname
== 'osmclient.sol005.client.Client':
342 logger
.debug('NS info: {}'.format(nsr
))
343 nsr_name
= nsr
['name']
345 date
= datetime
.fromtimestamp(nsr
['create-time']).strftime("%Y-%m-%dT%H:%M:%S")
346 ns_state
= nsr
.get('nsState', nsr
['_admin']['nsState'])
348 deployment_status
= summarize_deployment_status(nsr
.get('deploymentStatus'))
349 config_status
= summarize_config_status(nsr
.get('configurationStatus'))
350 project_id
= nsr
.get('_admin').get('projects_read')[0]
352 for p
in project_list
:
353 if p
['_id'] == project_id
:
354 project_name
= p
['name']
356 #project = '{} ({})'.format(project_name, project_id)
357 project
= project_name
358 vim_id
= nsr
.get('datacenter')
361 if v
['uuid'] == vim_id
:
364 #vim = '{} ({})'.format(vim_name, vim_id)
366 if 'currentOperation' in nsr
:
367 current_operation
= "{} ({})".format(nsr
['currentOperation'],nsr
['currentOperationID'])
369 current_operation
= "{} ({})".format(nsr
['_admin'].get('current-operation','-'), nsr
['_admin']['nslcmop'])
370 error_details
= "N/A"
371 if ns_state
== "BROKEN" or ns_state
== "DEGRADED" or nsr
.get('errorDescription'):
372 error_details
= "{}\nDetail: {}".format(nsr
['errorDescription'], nsr
['errorDetail'])
374 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
375 nsr
= nsopdata
['nsr:nsr']
376 nsr_name
= nsr
['name-ref']
377 nsr_id
= nsr
['ns-instance-config-ref']
380 deployment_status
= nsr
['operational-status'] if 'operational-status' in nsr
else 'Not found'
381 ns_state
= deployment_status
382 config_status
= nsr
.get('config-status', 'Not found')
383 current_operation
= "Unknown"
384 error_details
= nsr
.get('detailed-status', 'Not found')
385 if config_status
== "config_not_needed":
386 config_status
= "configured (no charms)"
395 wrap_text(text
=error_details
,width
=40),
407 wrap_text(text
=error_details
,width
=40)])
410 print('To get the history of all operations over a NS, run "osm ns-op-list NS_ID"')
411 print('For more details on the current operation, run "osm ns-op-show OPERATION_ID"')
413 def nsd_list(ctx
, filter, long):
416 check_client_version(ctx
.obj
, '--filter')
417 resp
= ctx
.obj
.nsd
.list(filter)
419 resp
= ctx
.obj
.nsd
.list()
420 # print(yaml.safe_dump(resp))
421 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
422 if fullclassname
== 'osmclient.sol005.client.Client':
424 table
= PrettyTable(['nsd name', 'id', 'onboarding state', 'operational state',
425 'usage state', 'date', 'last update'])
427 table
= PrettyTable(['nsd name', 'id'])
429 name
= nsd
.get('name','-')
431 onb_state
= nsd
['_admin'].get('onboardingState','-')
432 op_state
= nsd
['_admin'].get('operationalState','-')
433 usage_state
= nsd
['_admin'].get('usageState','-')
434 date
= datetime
.fromtimestamp(nsd
['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S")
435 last_update
= datetime
.fromtimestamp(nsd
['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S")
436 table
.add_row([name
, nsd
['_id'], onb_state
, op_state
, usage_state
, date
, last_update
])
438 table
.add_row([name
, nsd
['_id']])
440 table
= PrettyTable(['nsd name', 'id'])
442 table
.add_row([nsd
['name'], nsd
['id']])
447 @cli_osm.command(name
='nsd-list', short_help
='list all NS packages')
448 @click.option('--filter', default
=None,
449 help='restricts the list to the NSD/NSpkg matching the filter')
450 @click.option('--long', is_flag
=True, help='get more details')
452 def nsd_list1(ctx
, filter, long):
453 """list all NSD/NS pkg in the system"""
455 nsd_list(ctx
, filter, long)
458 @cli_osm.command(name
='nspkg-list', short_help
='list all NS packages')
459 @click.option('--filter', default
=None,
460 help='restricts the list to the NSD/NSpkg matching the filter')
461 @click.option('--long', is_flag
=True, help='get more details')
463 def nsd_list2(ctx
, filter, long):
464 """list all NS packages"""
466 nsd_list(ctx
, filter, long)
469 def vnfd_list(ctx
, nf_type
, filter, long):
472 check_client_version(ctx
.obj
, '--nf_type')
474 check_client_version(ctx
.obj
, '--filter')
477 nf_filter
= "_admin.type=vnfd"
478 elif nf_type
== "pnf":
479 nf_filter
= "_admin.type=pnfd"
480 elif nf_type
== "hnf":
481 nf_filter
= "_admin.type=hnfd"
483 raise ClientException('wrong value for "--nf_type" option, allowed values: vnf, pnf, hnf')
485 filter = '{}&{}'.format(nf_filter
, filter)
489 resp
= ctx
.obj
.vnfd
.list(filter)
491 resp
= ctx
.obj
.vnfd
.list()
492 # print(yaml.safe_dump(resp))
493 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
494 if fullclassname
== 'osmclient.sol005.client.Client':
496 table
= PrettyTable(['nfpkg name', 'id', 'onboarding state', 'operational state',
497 'usage state', 'date', 'last update'])
499 table
= PrettyTable(['nfpkg name', 'id'])
501 name
= vnfd
['name'] if 'name' in vnfd
else '-'
503 onb_state
= vnfd
['_admin'].get('onboardingState','-')
504 op_state
= vnfd
['_admin'].get('operationalState','-')
505 usage_state
= vnfd
['_admin'].get('usageState','-')
506 date
= datetime
.fromtimestamp(vnfd
['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S")
507 last_update
= datetime
.fromtimestamp(vnfd
['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S")
508 table
.add_row([name
, vnfd
['_id'], onb_state
, op_state
, usage_state
, date
, last_update
])
510 table
.add_row([name
, vnfd
['_id']])
512 table
= PrettyTable(['nfpkg name', 'id'])
514 table
.add_row([vnfd
['name'], vnfd
['id']])
519 @cli_osm.command(name
='vnfd-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
520 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
521 @click.option('--filter', default
=None,
522 help='restricts the list to the NF pkg matching the filter')
523 @click.option('--long', is_flag
=True, help='get more details')
525 def vnfd_list1(ctx
, nf_type
, filter, long):
526 """list all xNF packages (VNF, HNF, PNF)"""
528 vnfd_list(ctx
, nf_type
, filter, long)
531 @cli_osm.command(name
='vnfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
532 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
533 @click.option('--filter', default
=None,
534 help='restricts the list to the NFpkg matching the filter')
535 @click.option('--long', is_flag
=True, help='get more details')
537 def vnfd_list2(ctx
, nf_type
, filter, long):
538 """list all xNF packages (VNF, HNF, PNF)"""
540 vnfd_list(ctx
, nf_type
, filter, long)
543 @cli_osm.command(name
='nfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
544 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
545 @click.option('--filter', default
=None,
546 help='restricts the list to the NFpkg matching the filter')
547 @click.option('--long', is_flag
=True, help='get more details')
549 def nfpkg_list(ctx
, nf_type
, filter, long):
550 """list all xNF packages (VNF, HNF, PNF)"""
553 check_client_version(ctx
.obj
, ctx
.command
.name
)
554 vnfd_list(ctx
, nf_type
, filter, long)
555 # except ClientException as e:
560 def vnf_list(ctx
, ns
, filter, long):
564 check_client_version(ctx
.obj
, '--ns')
566 check_client_version(ctx
.obj
, '--filter')
567 resp
= ctx
.obj
.vnf
.list(ns
, filter)
569 resp
= ctx
.obj
.vnf
.list()
570 # except ClientException as e:
573 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
574 if fullclassname
== 'osmclient.sol005.client.Client':
575 field_names
= ['vnf id', 'name', 'ns id', 'vnf member index',
576 'vnfd name', 'vim account id', 'ip address']
578 field_names
= ['vnf id', 'name', 'ns id', 'vnf member index',
579 'vnfd name', 'vim account id', 'ip address',
580 'date', 'last update']
581 table
= PrettyTable(field_names
)
583 name
= vnfr
['name'] if 'name' in vnfr
else '-'
584 new_row
= [vnfr
['_id'], name
, vnfr
['nsr-id-ref'],
585 vnfr
['member-vnf-index-ref'], vnfr
['vnfd-ref'],
586 vnfr
['vim-account-id'], vnfr
['ip-address']]
588 date
= datetime
.fromtimestamp(vnfr
['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S")
589 last_update
= datetime
.fromtimestamp(vnfr
['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S")
590 new_row
.extend([date
, last_update
])
591 table
.add_row(new_row
)
596 'operational status',
599 if 'mgmt-interface' not in vnfr
:
600 vnfr
['mgmt-interface'] = {}
601 vnfr
['mgmt-interface']['ip-address'] = None
605 vnfr
['operational-status'],
606 vnfr
['config-status']])
611 @cli_osm.command(name
='vnf-list', short_help
='list all NF instances')
612 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
613 @click.option('--filter', default
=None,
614 help='restricts the list to the NF instances matching the filter.')
615 @click.option('--long', is_flag
=True, help='get more details')
617 def vnf_list1(ctx
, ns
, filter, long):
618 """list all NF instances"""
620 vnf_list(ctx
, ns
, filter, long)
623 @cli_osm.command(name
='nf-list', short_help
='list all NF instances')
624 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
625 @click.option('--filter', default
=None,
626 help='restricts the list to the NF instances matching the filter.')
627 @click.option('--long', is_flag
=True, help='get more details')
629 def nf_list(ctx
, ns
, filter, long):
630 """list all NF instances
634 --ns TEXT NS instance id or name to restrict the VNF list
635 --filter filterExpr Restricts the list to the VNF instances matching the filter
638 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
639 concatenated using the "&" character:
642 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
643 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
644 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
646 value := scalar value
650 * zero or more occurrences
651 ? zero or one occurrence
652 [] grouping of expressions to be used with ? and *
653 "" quotation marks for marking string constants
657 "AttrName" is the name of one attribute in the data type that defines the representation
658 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
659 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
660 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
661 entries, it means that the operator "op" is applied to the attribute addressed by the last
662 <attrName> entry included in the concatenation. All simple filter expressions are combined
663 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
664 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
665 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
666 prefix". If an attribute referenced in an expression is an array, an object that contains a
667 corresponding array shall be considered to match the expression if any of the elements in the
668 array matches all expressions that have the same attribute prefix.
672 --filter vim-account-id=<VIM_ACCOUNT_ID>
673 --filter vnfd-ref=<VNFD_NAME>
674 --filter vdur.ip-address=<IP_ADDRESS>
675 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
678 vnf_list(ctx
, ns
, filter)
681 @cli_osm.command(name
='ns-op-list', short_help
='shows the history of operations over a NS instance')
682 @click.argument('name')
683 @click.option('--long', is_flag
=True,
684 help='get more details of the NS operation (date, ).')
686 def ns_op_list(ctx
, name
, long):
687 """shows the history of operations over a NS instance
689 NAME: name or ID of the NS instance
691 def formatParams(params
):
692 if params
['lcmOperationType']=='instantiate':
693 params
.pop('nsDescription')
697 elif params
['lcmOperationType']=='action':
698 params
.pop('primitive')
699 params
.pop('lcmOperationType')
700 params
.pop('nsInstanceId')
705 check_client_version(ctx
.obj
, ctx
.command
.name
)
706 resp
= ctx
.obj
.ns
.list_op(name
)
707 # except ClientException as e:
712 table
= PrettyTable(['id', 'operation', 'action_name', 'operation_params', 'status', 'date', 'last update', 'detail'])
714 table
= PrettyTable(['id', 'operation', 'action_name', 'status', 'date', 'detail'])
716 #print(yaml.safe_dump(resp))
719 if op
['lcmOperationType']=='action':
720 action_name
= op
['operationParams']['primitive']
722 if op
['operationState']=='PROCESSING':
723 if op
['lcmOperationType'] in ('instantiate', 'terminate'):
727 detail
= "In queue. Current position: {}".format(op
['queuePosition'])
728 elif op
['operationState'] in ('FAILED', 'FAILED_TEMP'):
729 detail
= op
.get('errorMessage','-')
730 date
= datetime
.fromtimestamp(op
['startTime']).strftime("%Y-%m-%dT%H:%M:%S")
731 last_update
= datetime
.fromtimestamp(op
['statusEnteredTime']).strftime("%Y-%m-%dT%H:%M:%S")
733 table
.add_row([op
['id'],
734 op
['lcmOperationType'],
736 wrap_text(text
=json
.dumps(formatParams(op
['operationParams']),indent
=2),width
=50),
737 op
['operationState'],
740 wrap_text(text
=detail
,width
=50)])
742 table
.add_row([op
['id'], op
['lcmOperationType'], action_name
,
743 op
['operationState'], date
, wrap_text(text
=detail
or "",width
=50)])
748 def nsi_list(ctx
, filter):
749 """list all Network Slice Instances"""
752 check_client_version(ctx
.obj
, ctx
.command
.name
)
753 resp
= ctx
.obj
.nsi
.list(filter)
754 # except ClientException as e:
758 ['netslice instance name',
760 'operational status',
764 nsi_name
= nsi
['name']
766 opstatus
= nsi
['operational-status'] if 'operational-status' in nsi
else 'Not found'
767 configstatus
= nsi
['config-status'] if 'config-status' in nsi
else 'Not found'
768 detailed_status
= nsi
['detailed-status'] if 'detailed-status' in nsi
else 'Not found'
769 if configstatus
== "config_not_needed":
770 configstatus
= "configured (no charms)"
781 @cli_osm.command(name
='nsi-list', short_help
='list all Network Slice Instances (NSI)')
782 @click.option('--filter', default
=None,
783 help='restricts the list to the Network Slice Instances matching the filter')
785 def nsi_list1(ctx
, filter):
786 """list all Network Slice Instances (NSI)"""
788 nsi_list(ctx
, filter)
791 @cli_osm.command(name
='netslice-instance-list', short_help
='list all Network Slice Instances (NSI)')
792 @click.option('--filter', default
=None,
793 help='restricts the list to the Network Slice Instances matching the filter')
795 def nsi_list2(ctx
, filter):
796 """list all Network Slice Instances (NSI)"""
798 nsi_list(ctx
, filter)
801 def nst_list(ctx
, filter):
804 check_client_version(ctx
.obj
, ctx
.command
.name
)
805 resp
= ctx
.obj
.nst
.list(filter)
806 # except ClientException as e:
809 # print(yaml.safe_dump(resp))
810 table
= PrettyTable(['nst name', 'id'])
812 name
= nst
['name'] if 'name' in nst
else '-'
813 table
.add_row([name
, nst
['_id']])
818 @cli_osm.command(name
='nst-list', short_help
='list all Network Slice Templates (NST)')
819 @click.option('--filter', default
=None,
820 help='restricts the list to the NST matching the filter')
822 def nst_list1(ctx
, filter):
823 """list all Network Slice Templates (NST) in the system"""
825 nst_list(ctx
, filter)
828 @cli_osm.command(name
='netslice-template-list', short_help
='list all Network Slice Templates (NST)')
829 @click.option('--filter', default
=None,
830 help='restricts the list to the NST matching the filter')
832 def nst_list2(ctx
, filter):
833 """list all Network Slice Templates (NST) in the system"""
835 nst_list(ctx
, filter)
838 def nsi_op_list(ctx
, name
):
841 check_client_version(ctx
.obj
, ctx
.command
.name
)
842 resp
= ctx
.obj
.nsi
.list_op(name
)
843 # except ClientException as e:
846 table
= PrettyTable(['id', 'operation', 'status'])
848 table
.add_row([op
['id'], op
['lcmOperationType'],
849 op
['operationState']])
854 @cli_osm.command(name
='nsi-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
855 @click.argument('name')
857 def nsi_op_list1(ctx
, name
):
858 """shows the history of operations over a Network Slice Instance (NSI)
860 NAME: name or ID of the Network Slice Instance
863 nsi_op_list(ctx
, name
)
866 @cli_osm.command(name
='netslice-instance-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
867 @click.argument('name')
869 def nsi_op_list2(ctx
, name
):
870 """shows the history of operations over a Network Slice Instance (NSI)
872 NAME: name or ID of the Network Slice Instance
875 nsi_op_list(ctx
, name
)
878 @cli_osm.command(name
='pdu-list', short_help
='list all Physical Deployment Units (PDU)')
879 @click.option('--filter', default
=None,
880 help='restricts the list to the Physical Deployment Units matching the filter')
882 def pdu_list(ctx
, filter):
883 """list all Physical Deployment Units (PDU)"""
886 check_client_version(ctx
.obj
, ctx
.command
.name
)
887 resp
= ctx
.obj
.pdu
.list(filter)
888 # except ClientException as e:
897 pdu_name
= pdu
['name']
899 pdu_type
= pdu
['type']
900 pdu_ipaddress
= "None"
901 for iface
in pdu
['interfaces']:
903 pdu_ipaddress
= iface
['ip-address']
918 def nsd_show(ctx
, name
, literal
):
921 resp
= ctx
.obj
.nsd
.get(name
)
922 # resp = ctx.obj.nsd.get_individual(name)
923 # except ClientException as e:
928 print(yaml
.safe_dump(resp
))
931 table
= PrettyTable(['field', 'value'])
932 for k
, v
in list(resp
.items()):
933 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
938 @cli_osm.command(name
='nsd-show', short_help
='shows the content of a NSD')
939 @click.option('--literal', is_flag
=True,
940 help='print literally, no pretty table')
941 @click.argument('name')
943 def nsd_show1(ctx
, name
, literal
):
944 """shows the content of a NSD
946 NAME: name or ID of the NSD/NSpkg
949 nsd_show(ctx
, name
, literal
)
952 @cli_osm.command(name
='nspkg-show', short_help
='shows the content of a NSD')
953 @click.option('--literal', is_flag
=True,
954 help='print literally, no pretty table')
955 @click.argument('name')
957 def nsd_show2(ctx
, name
, literal
):
958 """shows the content of a NSD
960 NAME: name or ID of the NSD/NSpkg
963 nsd_show(ctx
, name
, literal
)
966 def vnfd_show(ctx
, name
, literal
):
969 resp
= ctx
.obj
.vnfd
.get(name
)
970 # resp = ctx.obj.vnfd.get_individual(name)
971 # except ClientException as e:
976 print(yaml
.safe_dump(resp
))
979 table
= PrettyTable(['field', 'value'])
980 for k
, v
in list(resp
.items()):
981 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
986 @cli_osm.command(name
='vnfd-show', short_help
='shows the content of a VNFD')
987 @click.option('--literal', is_flag
=True,
988 help='print literally, no pretty table')
989 @click.argument('name')
991 def vnfd_show1(ctx
, name
, literal
):
992 """shows the content of a VNFD
994 NAME: name or ID of the VNFD/VNFpkg
997 vnfd_show(ctx
, name
, literal
)
1000 @cli_osm.command(name
='vnfpkg-show', short_help
='shows the content of a VNFD')
1001 @click.option('--literal', is_flag
=True,
1002 help='print literally, no pretty table')
1003 @click.argument('name')
1005 def vnfd_show2(ctx
, name
, literal
):
1006 """shows the content of a VNFD
1008 NAME: name or ID of the VNFD/VNFpkg
1011 vnfd_show(ctx
, name
, literal
)
1014 @cli_osm.command(name
='nfpkg-show', short_help
='shows the content of a NF Descriptor')
1015 @click.option('--literal', is_flag
=True,
1016 help='print literally, no pretty table')
1017 @click.argument('name')
1019 def nfpkg_show(ctx
, name
, literal
):
1020 """shows the content of a NF Descriptor
1022 NAME: name or ID of the NFpkg
1025 vnfd_show(ctx
, name
, literal
)
1028 @cli_osm.command(name
='ns-show', short_help
='shows the info of a NS instance')
1029 @click.argument('name')
1030 @click.option('--literal', is_flag
=True,
1031 help='print literally, no pretty table')
1032 @click.option('--filter', default
=None)
1034 def ns_show(ctx
, name
, literal
, filter):
1035 """shows the info of a NS instance
1037 NAME: name or ID of the NS instance
1041 ns
= ctx
.obj
.ns
.get(name
)
1042 # except ClientException as e:
1047 print(yaml
.safe_dump(ns
))
1050 table
= PrettyTable(['field', 'value'])
1052 for k
, v
in list(ns
.items()):
1053 if filter is None or filter in k
:
1054 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
1056 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1057 if fullclassname
!= 'osmclient.sol005.client.Client':
1058 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
1059 nsr_optdata
= nsopdata
['nsr:nsr']
1060 for k
, v
in list(nsr_optdata
.items()):
1061 if filter is None or filter in k
:
1062 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2),width
=100)])
1067 @cli_osm.command(name
='vnf-show', short_help
='shows the info of a VNF instance')
1068 @click.argument('name')
1069 @click.option('--literal', is_flag
=True,
1070 help='print literally, no pretty table')
1071 @click.option('--filter', default
=None, help='restricts the information to the fields in the filter')
1072 @click.option('--kdu', default
=None, help='KDU name (whose status will be shown)')
1074 def vnf_show(ctx
, name
, literal
, filter, kdu
):
1075 """shows the info of a VNF instance
1077 NAME: name or ID of the VNF instance
1079 def print_kdu_status(op_info_status
):
1080 """print KDU status properly formatted
1083 op_status
= yaml
.safe_load(op_info_status
)
1084 if "namespace" in op_status
and "info" in op_status
and \
1085 "last_deployed" in op_status
["info"] and "status" in op_status
["info"] and \
1086 "code" in op_status
["info"]["status"] and "resources" in op_status
["info"]["status"] and \
1087 "seconds" in op_status
["info"]["last_deployed"]:
1088 last_deployed_time
= datetime
.fromtimestamp(op_status
["info"]["last_deployed"]["seconds"]).strftime("%a %b %d %I:%M:%S %Y")
1089 print("LAST DEPLOYED: {}".format(last_deployed_time
))
1090 print("NAMESPACE: {}".format(op_status
["namespace"]))
1091 status_code
= "UNKNOWN"
1092 if op_status
["info"]["status"]["code"]==1:
1093 status_code
= "DEPLOYED"
1094 print("STATUS: {}".format(status_code
))
1097 print(op_status
["info"]["status"]["resources"])
1098 if "notes" in op_status
["info"]["status"]:
1100 print(op_status
["info"]["status"]["notes"])
1102 print(op_info_status
)
1104 print(op_info_status
)
1109 raise ClientException('"--literal" option is incompatible with "--kdu" option')
1111 raise ClientException('"--filter" option is incompatible with "--kdu" option')
1114 check_client_version(ctx
.obj
, ctx
.command
.name
)
1115 resp
= ctx
.obj
.vnf
.get(name
)
1118 ns_id
= resp
['nsr-id-ref']
1120 op_data
['member_vnf_index'] = resp
['member-vnf-index-ref']
1121 op_data
['kdu_name'] = kdu
1122 op_data
['primitive'] = 'status'
1123 op_data
['primitive_params'] = {}
1124 op_id
= ctx
.obj
.ns
.exec_op(ns_id
, op_name
='action', op_data
=op_data
, wait
=False)
1127 op_info
= ctx
.obj
.ns
.get_op(op_id
)
1128 if op_info
['operationState'] == 'COMPLETED':
1129 print_kdu_status(op_info
['detailed-status'])
1133 print ("Could not determine KDU status")
1136 print(yaml
.safe_dump(resp
))
1139 table
= PrettyTable(['field', 'value'])
1141 for k
, v
in list(resp
.items()):
1142 if filter is None or filter in k
:
1143 table
.add_row([k
, wrap_text(text
=json
.dumps(v
,indent
=2),width
=100)])
1146 # except ClientException as e:
1151 #@cli_osm.command(name='vnf-monitoring-show')
1152 #@click.argument('vnf_name')
1153 #@click.pass_context
1154 #def vnf_monitoring_show(ctx, vnf_name):
1156 # check_client_version(ctx.obj, ctx.command.name, 'v1')
1157 # resp = ctx.obj.vnf.get_monitoring(vnf_name)
1158 # except ClientException as e:
1162 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
1163 # if resp is not None:
1164 # for monitor in resp:
1168 # monitor['value-integer'],
1169 # monitor['units']])
1174 #@cli_osm.command(name='ns-monitoring-show')
1175 #@click.argument('ns_name')
1176 #@click.pass_context
1177 #def ns_monitoring_show(ctx, ns_name):
1179 # check_client_version(ctx.obj, ctx.command.name, 'v1')
1180 # resp = ctx.obj.ns.get_monitoring(ns_name)
1181 # except ClientException as e:
1185 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
1186 # for key, val in list(resp.items()):
1187 # for monitor in val:
1191 # monitor['value-integer'],
1192 # monitor['units']])
1197 @cli_osm.command(name
='ns-op-show', short_help
='shows the info of a NS operation')
1198 @click.argument('id')
1199 @click.option('--filter', default
=None)
1200 @click.option('--literal', is_flag
=True,
1201 help='print literally, no pretty table')
1203 def ns_op_show(ctx
, id, filter, literal
):
1204 """shows the detailed info of a NS operation
1206 ID: operation identifier
1210 check_client_version(ctx
.obj
, ctx
.command
.name
)
1211 op_info
= ctx
.obj
.ns
.get_op(id)
1212 # except ClientException as e:
1217 print(yaml
.safe_dump(op_info
))
1220 table
= PrettyTable(['field', 'value'])
1221 for k
, v
in list(op_info
.items()):
1222 if filter is None or filter in k
:
1223 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
1228 def nst_show(ctx
, name
, literal
):
1231 check_client_version(ctx
.obj
, ctx
.command
.name
)
1232 resp
= ctx
.obj
.nst
.get(name
)
1233 #resp = ctx.obj.nst.get_individual(name)
1234 # except ClientException as e:
1239 print(yaml
.safe_dump(resp
))
1242 table
= PrettyTable(['field', 'value'])
1243 for k
, v
in list(resp
.items()):
1244 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
1249 @cli_osm.command(name
='nst-show', short_help
='shows the content of a Network Slice Template (NST)')
1250 @click.option('--literal', is_flag
=True,
1251 help='print literally, no pretty table')
1252 @click.argument('name')
1254 def nst_show1(ctx
, name
, literal
):
1255 """shows the content of a Network Slice Template (NST)
1257 NAME: name or ID of the NST
1260 nst_show(ctx
, name
, literal
)
1263 @cli_osm.command(name
='netslice-template-show', short_help
='shows the content of a Network Slice Template (NST)')
1264 @click.option('--literal', is_flag
=True,
1265 help='print literally, no pretty table')
1266 @click.argument('name')
1268 def nst_show2(ctx
, name
, literal
):
1269 """shows the content of a Network Slice Template (NST)
1271 NAME: name or ID of the NST
1274 nst_show(ctx
, name
, literal
)
1277 def nsi_show(ctx
, name
, literal
, filter):
1280 check_client_version(ctx
.obj
, ctx
.command
.name
)
1281 nsi
= ctx
.obj
.nsi
.get(name
)
1282 # except ClientException as e:
1287 print(yaml
.safe_dump(nsi
))
1290 table
= PrettyTable(['field', 'value'])
1292 for k
, v
in list(nsi
.items()):
1293 if filter is None or filter in k
:
1294 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1300 @cli_osm.command(name
='nsi-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1301 @click.argument('name')
1302 @click.option('--literal', is_flag
=True,
1303 help='print literally, no pretty table')
1304 @click.option('--filter', default
=None)
1306 def nsi_show1(ctx
, name
, literal
, filter):
1307 """shows the content of a Network Slice Instance (NSI)
1309 NAME: name or ID of the Network Slice Instance
1312 nsi_show(ctx
, name
, literal
, filter)
1315 @cli_osm.command(name
='netslice-instance-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1316 @click.argument('name')
1317 @click.option('--literal', is_flag
=True,
1318 help='print literally, no pretty table')
1319 @click.option('--filter', default
=None)
1321 def nsi_show2(ctx
, name
, literal
, filter):
1322 """shows the content of a Network Slice Instance (NSI)
1324 NAME: name or ID of the Network Slice Instance
1327 nsi_show(ctx
, name
, literal
, filter)
1330 def nsi_op_show(ctx
, id, filter):
1333 check_client_version(ctx
.obj
, ctx
.command
.name
)
1334 op_info
= ctx
.obj
.nsi
.get_op(id)
1335 # except ClientException as e:
1339 table
= PrettyTable(['field', 'value'])
1340 for k
, v
in list(op_info
.items()):
1341 if filter is None or filter in k
:
1342 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1347 @cli_osm.command(name
='nsi-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1348 @click.argument('id')
1349 @click.option('--filter', default
=None)
1351 def nsi_op_show1(ctx
, id, filter):
1352 """shows the info of an operation over a Network Slice Instance(NSI)
1354 ID: operation identifier
1357 nsi_op_show(ctx
, id, filter)
1360 @cli_osm.command(name
='netslice-instance-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1361 @click.argument('id')
1362 @click.option('--filter', default
=None)
1364 def nsi_op_show2(ctx
, id, filter):
1365 """shows the info of an operation over a Network Slice Instance(NSI)
1367 ID: operation identifier
1370 nsi_op_show(ctx
, id, filter)
1373 @cli_osm.command(name
='pdu-show', short_help
='shows the content of a Physical Deployment Unit (PDU)')
1374 @click.argument('name')
1375 @click.option('--literal', is_flag
=True,
1376 help='print literally, no pretty table')
1377 @click.option('--filter', default
=None)
1379 def pdu_show(ctx
, name
, literal
, filter):
1380 """shows the content of a Physical Deployment Unit (PDU)
1382 NAME: name or ID of the PDU
1386 check_client_version(ctx
.obj
, ctx
.command
.name
)
1387 pdu
= ctx
.obj
.pdu
.get(name
)
1388 # except ClientException as e:
1393 print(yaml
.safe_dump(pdu
))
1396 table
= PrettyTable(['field', 'value'])
1398 for k
, v
in list(pdu
.items()):
1399 if filter is None or filter in k
:
1400 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1406 ####################
1408 ####################
1410 def nsd_create(ctx
, filename
, overwrite
, skip_charm_build
):
1413 check_client_version(ctx
.obj
, ctx
.command
.name
)
1414 ctx
.obj
.nsd
.create(filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
)
1415 # except ClientException as e:
1420 @cli_osm.command(name
='nsd-create', short_help
='creates a new NSD/NSpkg')
1421 @click.argument('filename')
1422 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1423 help='Deprecated. Use override')
1424 @click.option('--override', 'overwrite', default
=None,
1425 help='overrides fields in descriptor, format: '
1426 '"key1.key2...=value[;key3...=value;...]"')
1427 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1428 help='The charm will not be compiled, it is assumed to already exist')
1430 def nsd_create1(ctx
, filename
, overwrite
, skip_charm_build
):
1431 """creates a new NSD/NSpkg
1433 FILENAME: NSD yaml file or NSpkg tar.gz file
1436 nsd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
)
1439 @cli_osm.command(name
='nspkg-create', short_help
='creates a new NSD/NSpkg')
1440 @click.argument('filename')
1441 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1442 help='Deprecated. Use override')
1443 @click.option('--override', 'overwrite', default
=None,
1444 help='overrides fields in descriptor, format: '
1445 '"key1.key2...=value[;key3...=value;...]"')
1446 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1447 help='The charm will not be compiled, it is assumed to already exist')
1449 def nsd_create2(ctx
, filename
, overwrite
, skip_charm_build
):
1450 """creates a new NSD/NSpkg
1452 FILENAME: NSD folder, NSD yaml file or NSpkg tar.gz file
1455 nsd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
)
1458 def vnfd_create(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1461 check_client_version(ctx
.obj
, ctx
.command
.name
)
1462 ctx
.obj
.vnfd
.create(filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1463 override_epa
=override_epa
, override_nonepa
=override_nonepa
,
1464 override_paravirt
=override_paravirt
)
1465 # except ClientException as e:
1470 @cli_osm.command(name
='vnfd-create', short_help
='creates a new VNFD/VNFpkg')
1471 @click.argument('filename')
1472 @click.option('--overwrite', 'overwrite', default
=None,
1473 help='overwrite deprecated, use override')
1474 @click.option('--override', 'overwrite', default
=None,
1475 help='overrides fields in descriptor, format: '
1476 '"key1.key2...=value[;key3...=value;...]"')
1477 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1478 help='The charm will not be compiled, it is assumed to already exist')
1479 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1480 help='adds guest-epa parameters to all VDU')
1481 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1482 help='removes all guest-epa parameters from all VDU')
1483 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1484 help='overrides all VDU interfaces to PARAVIRT')
1486 def vnfd_create1(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1487 """creates a new VNFD/VNFpkg
1489 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1492 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1493 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
)
1496 @cli_osm.command(name
='vnfpkg-create', short_help
='creates a new VNFD/VNFpkg')
1497 @click.argument('filename')
1498 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1499 help='Deprecated. Use override')
1500 @click.option('--override', 'overwrite', default
=None,
1501 help='overrides fields in descriptor, format: '
1502 '"key1.key2...=value[;key3...=value;...]"')
1503 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1504 help='The charm will not be compiled, it is assumed to already exist')
1505 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1506 help='adds guest-epa parameters to all VDU')
1507 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1508 help='removes all guest-epa parameters from all VDU')
1509 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1510 help='overrides all VDU interfaces to PARAVIRT')
1512 def vnfd_create2(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1513 """creates a new VNFD/VNFpkg
1515 FILENAME: NF Package Folder, NF Descriptor yaml file or NFpkg tar.gz file
1518 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1519 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
)
1522 @cli_osm.command(name
='nfpkg-create', short_help
='creates a new NFpkg')
1523 @click.argument('filename')
1524 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1525 help='Deprecated. Use override')
1526 @click.option('--override', 'overwrite', default
=None,
1527 help='overrides fields in descriptor, format: '
1528 '"key1.key2...=value[;key3...=value;...]"')
1529 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1530 help='The charm will not be compiled, it is assumed to already exist')
1531 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1532 help='adds guest-epa parameters to all VDU')
1533 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1534 help='removes all guest-epa parameters from all VDU')
1535 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1536 help='overrides all VDU interfaces to PARAVIRT')
1538 def nfpkg_create(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1539 """creates a new NFpkg
1541 FILENAME: NF Package Folder, NF Descriptor yaml file or NFpkg tar.gz filems to build
1544 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1545 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
)
1548 @cli_osm.command(name
='ns-create', short_help
='creates a new Network Service instance')
1549 @click.option('--ns_name',
1550 prompt
=True, help='name of the NS instance')
1551 @click.option('--nsd_name',
1552 prompt
=True, help='name of the NS descriptor')
1553 @click.option('--vim_account',
1554 prompt
=True, help='default VIM account id or name for the deployment')
1555 @click.option('--admin_status',
1557 help='administration status')
1558 @click.option('--ssh_keys',
1560 help='comma separated list of public key files to inject to vnfs')
1561 @click.option('--config',
1563 help='ns specific yaml configuration')
1564 @click.option('--config_file',
1566 help='ns specific yaml configuration file')
1567 @click.option('--wait',
1571 help='do not return the control immediately, but keep it '
1572 'until the operation is completed, or timeout')
1583 """creates a new NS instance"""
1587 check_client_version(ctx
.obj
, '--config_file')
1589 raise ClientException('"--config" option is incompatible with "--config_file" option')
1590 with
open(config_file
, 'r') as cf
:
1597 account
=vim_account
,
1599 # except ClientException as e:
1604 def nst_create(ctx
, filename
, overwrite
):
1607 check_client_version(ctx
.obj
, ctx
.command
.name
)
1608 ctx
.obj
.nst
.create(filename
, overwrite
)
1609 # except ClientException as e:
1614 @cli_osm.command(name
='nst-create', short_help
='creates a new Network Slice Template (NST)')
1615 @click.argument('filename')
1616 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1617 help='Deprecated. Use override')
1618 @click.option('--override', 'overwrite', default
=None,
1619 help='overrides fields in descriptor, format: '
1620 '"key1.key2...=value[;key3...=value;...]"')
1622 def nst_create1(ctx
, charm_folder
, overwrite
):
1623 """creates a new Network Slice Template (NST)
1625 FILENAME: NST package folder, NST yaml file or NSTpkg tar.gz file
1628 nst_create(ctx
, charm_folder
, overwrite
)
1631 @cli_osm.command(name
='netslice-template-create', short_help
='creates a new Network Slice Template (NST)')
1632 @click.argument('filename')
1633 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1634 help='Deprecated. Use override')
1635 @click.option('--override', 'overwrite', default
=None,
1636 help='overrides fields in descriptor, format: '
1637 '"key1.key2...=value[;key3...=value;...]"')
1639 def nst_create2(ctx
, filename
, overwrite
):
1640 """creates a new Network Slice Template (NST)
1642 FILENAME: NST yaml file or NSTpkg tar.gz file
1645 nst_create(ctx
, filename
, overwrite
)
1648 def nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1649 """creates a new Network Slice Instance (NSI)"""
1652 check_client_version(ctx
.obj
, ctx
.command
.name
)
1655 raise ClientException('"--config" option is incompatible with "--config_file" option')
1656 with
open(config_file
, 'r') as cf
:
1658 ctx
.obj
.nsi
.create(nst_name
, nsi_name
, config
=config
, ssh_keys
=ssh_keys
,
1659 account
=vim_account
, wait
=wait
)
1660 # except ClientException as e:
1665 @cli_osm.command(name
='nsi-create', short_help
='creates a new Network Slice Instance')
1666 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1667 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1668 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1669 @click.option('--ssh_keys', default
=None,
1670 help='comma separated list of keys to inject to vnfs')
1671 @click.option('--config', default
=None,
1672 help='Netslice specific yaml configuration:\n'
1673 'netslice_subnet: [\n'
1674 'id: TEXT, vim_account: TEXT,\n'
1675 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1676 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]\n'
1677 'additionalParamsForNsi: {param: value, ...}\n'
1678 'additionalParamsForsubnet: [{id: SUBNET_ID, additionalParamsForNs: {}, additionalParamsForVnf: {}}]\n'
1680 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1682 @click.option('--config_file',
1684 help='nsi specific yaml configuration file')
1685 @click.option('--wait',
1689 help='do not return the control immediately, but keep it '
1690 'until the operation is completed, or timeout')
1692 def nsi_create1(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1693 """creates a new Network Slice Instance (NSI)"""
1695 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1698 @cli_osm.command(name
='netslice-instance-create', short_help
='creates a new Network Slice Instance')
1699 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1700 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1701 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1702 @click.option('--ssh_keys', default
=None,
1703 help='comma separated list of keys to inject to vnfs')
1704 @click.option('--config', default
=None,
1705 help='Netslice specific yaml configuration:\n'
1706 'netslice_subnet: [\n'
1707 'id: TEXT, vim_account: TEXT,\n'
1708 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1709 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1711 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1713 @click.option('--config_file',
1715 help='nsi specific yaml configuration file')
1716 @click.option('--wait',
1720 help='do not return the control immediately, but keep it '
1721 'until the operation is completed, or timeout')
1723 def nsi_create2(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1724 """creates a new Network Slice Instance (NSI)"""
1726 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1729 @cli_osm.command(name
='pdu-create', short_help
='adds a new Physical Deployment Unit to the catalog')
1730 @click.option('--name', help='name of the Physical Deployment Unit')
1731 @click.option('--pdu_type', help='type of PDU (e.g. router, firewall, FW001)')
1732 @click.option('--interface',
1733 help='interface(s) of the PDU: name=<NAME>,mgmt=<true|false>,ip-address=<IP_ADDRESS>'+
1734 '[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]',
1736 @click.option('--description', help='human readable description')
1737 @click.option('--vim_account', help='list of VIM accounts (in the same VIM) that can reach this PDU', multiple
=True)
1738 @click.option('--descriptor_file', default
=None,
1739 help='PDU descriptor file (as an alternative to using the other arguments')
1741 def pdu_create(ctx
, name
, pdu_type
, interface
, description
, vim_account
, descriptor_file
):
1742 """creates a new Physical Deployment Unit (PDU)"""
1745 check_client_version(ctx
.obj
, ctx
.command
.name
)
1747 if not descriptor_file
:
1749 raise ClientException('in absence of descriptor file, option "--name" is mandatory')
1751 raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory')
1753 raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)')
1755 raise ClientException('in absence of descriptor file, option "--vim_account" is mandatory (at least once)')
1757 with
open(descriptor_file
, 'r') as df
:
1758 pdu
= yaml
.safe_load(df
.read())
1759 if name
: pdu
["name"] = name
1760 if pdu_type
: pdu
["type"] = pdu_type
1761 if description
: pdu
["description"] = description
1762 if vim_account
: pdu
["vim_accounts"] = vim_account
1765 for iface
in interface
:
1766 new_iface
={k
:v
for k
,v
in [i
.split('=') for i
in iface
.split(',')]}
1767 new_iface
["mgmt"] = (new_iface
.get("mgmt","false").lower() == "true")
1768 ifaces_list
.append(new_iface
)
1769 pdu
["interfaces"] = ifaces_list
1770 ctx
.obj
.pdu
.create(pdu
)
1771 # except ClientException as e:
1776 ####################
1778 ####################
1780 def nsd_update(ctx
, name
, content
):
1783 check_client_version(ctx
.obj
, ctx
.command
.name
)
1784 ctx
.obj
.nsd
.update(name
, content
)
1785 # except ClientException as e:
1790 @cli_osm.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
1791 @click.argument('name')
1792 @click.option('--content', default
=None,
1793 help='filename with the NSD/NSpkg replacing the current one')
1795 def nsd_update1(ctx
, name
, content
):
1796 """updates a NSD/NSpkg
1798 NAME: name or ID of the NSD/NSpkg
1801 nsd_update(ctx
, name
, content
)
1804 @cli_osm.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
1805 @click.argument('name')
1806 @click.option('--content', default
=None,
1807 help='filename with the NSD/NSpkg replacing the current one')
1809 def nsd_update2(ctx
, name
, content
):
1810 """updates a NSD/NSpkg
1812 NAME: name or ID of the NSD/NSpkg
1815 nsd_update(ctx
, name
, content
)
1818 def vnfd_update(ctx
, name
, content
):
1821 check_client_version(ctx
.obj
, ctx
.command
.name
)
1822 ctx
.obj
.vnfd
.update(name
, content
)
1823 # except ClientException as e:
1828 @cli_osm.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
1829 @click.argument('name')
1830 @click.option('--content', default
=None,
1831 help='filename with the VNFD/VNFpkg replacing the current one')
1833 def vnfd_update1(ctx
, name
, content
):
1834 """updates a VNFD/VNFpkg
1836 NAME: name or ID of the VNFD/VNFpkg
1839 vnfd_update(ctx
, name
, content
)
1842 @cli_osm.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
1843 @click.argument('name')
1844 @click.option('--content', default
=None,
1845 help='filename with the VNFD/VNFpkg replacing the current one')
1847 def vnfd_update2(ctx
, name
, content
):
1848 """updates a VNFD/VNFpkg
1850 NAME: VNFD yaml file or VNFpkg tar.gz file
1853 vnfd_update(ctx
, name
, content
)
1856 @cli_osm.command(name
='nfpkg-update', short_help
='updates a NFpkg')
1857 @click.argument('name')
1858 @click.option('--content', default
=None,
1859 help='filename with the NFpkg replacing the current one')
1861 def nfpkg_update(ctx
, name
, content
):
1864 NAME: NF Descriptor yaml file or NFpkg tar.gz file
1867 vnfd_update(ctx
, name
, content
)
1870 def nst_update(ctx
, name
, content
):
1873 check_client_version(ctx
.obj
, ctx
.command
.name
)
1874 ctx
.obj
.nst
.update(name
, content
)
1875 # except ClientException as e:
1880 @cli_osm.command(name
='nst-update', short_help
='updates a Network Slice Template (NST)')
1881 @click.argument('name')
1882 @click.option('--content', default
=None,
1883 help='filename with the NST/NSTpkg replacing the current one')
1885 def nst_update1(ctx
, name
, content
):
1886 """updates a Network Slice Template (NST)
1888 NAME: name or ID of the NSD/NSpkg
1891 nst_update(ctx
, name
, content
)
1894 @cli_osm.command(name
='netslice-template-update', short_help
='updates a Network Slice Template (NST)')
1895 @click.argument('name')
1896 @click.option('--content', default
=None,
1897 help='filename with the NST/NSTpkg replacing the current one')
1899 def nst_update2(ctx
, name
, content
):
1900 """updates a Network Slice Template (NST)
1902 NAME: name or ID of the NSD/NSpkg
1905 nst_update(ctx
, name
, content
)
1908 ####################
1910 ####################
1912 def nsd_delete(ctx
, name
, force
):
1916 ctx
.obj
.nsd
.delete(name
)
1918 check_client_version(ctx
.obj
, '--force')
1919 ctx
.obj
.nsd
.delete(name
, force
)
1920 # except ClientException as e:
1925 @cli_osm.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
1926 @click.argument('name')
1927 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1929 def nsd_delete1(ctx
, name
, force
):
1930 """deletes a NSD/NSpkg
1932 NAME: name or ID of the NSD/NSpkg to be deleted
1935 nsd_delete(ctx
, name
, force
)
1938 @cli_osm.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
1939 @click.argument('name')
1940 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1942 def nsd_delete2(ctx
, name
, force
):
1943 """deletes a NSD/NSpkg
1945 NAME: name or ID of the NSD/NSpkg to be deleted
1948 nsd_delete(ctx
, name
, force
)
1951 def vnfd_delete(ctx
, name
, force
):
1955 ctx
.obj
.vnfd
.delete(name
)
1957 check_client_version(ctx
.obj
, '--force')
1958 ctx
.obj
.vnfd
.delete(name
, force
)
1959 # except ClientException as e:
1964 @cli_osm.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
1965 @click.argument('name')
1966 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1968 def vnfd_delete1(ctx
, name
, force
):
1969 """deletes a VNFD/VNFpkg
1971 NAME: name or ID of the VNFD/VNFpkg to be deleted
1974 vnfd_delete(ctx
, name
, force
)
1977 @cli_osm.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
1978 @click.argument('name')
1979 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1981 def vnfd_delete2(ctx
, name
, force
):
1982 """deletes a VNFD/VNFpkg
1984 NAME: name or ID of the VNFD/VNFpkg to be deleted
1987 vnfd_delete(ctx
, name
, force
)
1990 @cli_osm.command(name
='nfpkg-delete', short_help
='deletes a NFpkg')
1991 @click.argument('name')
1992 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1994 def nfpkg_delete(ctx
, name
, force
):
1997 NAME: name or ID of the NFpkg to be deleted
2000 vnfd_delete(ctx
, name
, force
)
2003 @cli_osm.command(name
='ns-delete', short_help
='deletes a NS instance')
2004 @click.argument('name')
2005 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2006 @click.option('--config', default
=None,
2007 help="specific yaml configuration for the termination, e.g. '{autoremove: False, timeout_ns_terminate: "
2008 "600, skip_terminate_primitives: True}'")
2009 @click.option('--wait',
2013 help='do not return the control immediately, but keep it '
2014 'until the operation is completed, or timeout')
2016 def ns_delete(ctx
, name
, force
, config
, wait
):
2017 """deletes a NS instance
2019 NAME: name or ID of the NS instance to be deleted
2024 ctx
.obj
.ns
.delete(name
, config
=config
, wait
=wait
)
2026 check_client_version(ctx
.obj
, '--force')
2027 ctx
.obj
.ns
.delete(name
, force
, config
=config
, wait
=wait
)
2028 # except ClientException as e:
2033 def nst_delete(ctx
, name
, force
):
2036 check_client_version(ctx
.obj
, ctx
.command
.name
)
2037 ctx
.obj
.nst
.delete(name
, force
)
2038 # except ClientException as e:
2043 @cli_osm.command(name
='nst-delete', short_help
='deletes a Network Slice Template (NST)')
2044 @click.argument('name')
2045 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2047 def nst_delete1(ctx
, name
, force
):
2048 """deletes a Network Slice Template (NST)
2050 NAME: name or ID of the NST/NSTpkg to be deleted
2053 nst_delete(ctx
, name
, force
)
2056 @cli_osm.command(name
='netslice-template-delete', short_help
='deletes a Network Slice Template (NST)')
2057 @click.argument('name')
2058 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2060 def nst_delete2(ctx
, name
, force
):
2061 """deletes a Network Slice Template (NST)
2063 NAME: name or ID of the NST/NSTpkg to be deleted
2066 nst_delete(ctx
, name
, force
)
2069 def nsi_delete(ctx
, name
, force
, wait
):
2072 check_client_version(ctx
.obj
, ctx
.command
.name
)
2073 ctx
.obj
.nsi
.delete(name
, force
, wait
=wait
)
2074 # except ClientException as e:
2079 @cli_osm.command(name
='nsi-delete', short_help
='deletes a Network Slice Instance (NSI)')
2080 @click.argument('name')
2081 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2082 @click.option('--wait',
2086 help='do not return the control immediately, but keep it '
2087 'until the operation is completed, or timeout')
2089 def nsi_delete1(ctx
, name
, force
, wait
):
2090 """deletes a Network Slice Instance (NSI)
2092 NAME: name or ID of the Network Slice instance to be deleted
2095 nsi_delete(ctx
, name
, force
, wait
=wait
)
2098 @cli_osm.command(name
='netslice-instance-delete', short_help
='deletes a Network Slice Instance (NSI)')
2099 @click.argument('name')
2100 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2102 def nsi_delete2(ctx
, name
, force
, wait
):
2103 """deletes a Network Slice Instance (NSI)
2105 NAME: name or ID of the Network Slice instance to be deleted
2108 nsi_delete(ctx
, name
, force
, wait
=wait
)
2111 @cli_osm.command(name
='pdu-delete', short_help
='deletes a Physical Deployment Unit (PDU)')
2112 @click.argument('name')
2113 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2115 def pdu_delete(ctx
, name
, force
):
2116 """deletes a Physical Deployment Unit (PDU)
2118 NAME: name or ID of the PDU to be deleted
2122 check_client_version(ctx
.obj
, ctx
.command
.name
)
2123 ctx
.obj
.pdu
.delete(name
, force
)
2124 # except ClientException as e:
2133 @cli_osm.command(name
='vim-create', short_help
='creates a new VIM account')
2134 @click.option('--name',
2136 help='Name to create datacenter')
2137 @click.option('--user',
2139 help='VIM username')
2140 @click.option('--password',
2143 confirmation_prompt
=True,
2144 help='VIM password')
2145 @click.option('--auth_url',
2148 @click.option('--tenant',
2150 help='VIM tenant name')
2151 @click.option('--config',
2153 help='VIM specific config parameters')
2154 @click.option('--account_type',
2155 default
='openstack',
2157 @click.option('--description',
2159 help='human readable description')
2160 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
2161 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
2162 @click.option('--wait',
2166 help='do not return the control immediately, but keep it '
2167 'until the operation is completed, or timeout')
2181 """creates a new VIM account"""
2185 check_client_version(ctx
.obj
, '--sdn_controller')
2186 if sdn_port_mapping
:
2187 check_client_version(ctx
.obj
, '--sdn_port_mapping')
2189 vim
['vim-username'] = user
2190 vim
['vim-password'] = password
2191 vim
['vim-url'] = auth_url
2192 vim
['vim-tenant-name'] = tenant
2193 vim
['vim-type'] = account_type
2194 vim
['description'] = description
2195 vim
['config'] = config
2196 if sdn_controller
or sdn_port_mapping
:
2197 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
2199 ctx
.obj
.vim
.create(name
, vim
, wait
=wait
)
2200 # except ClientException as e:
2205 @cli_osm.command(name
='vim-update', short_help
='updates a VIM account')
2206 @click.argument('name')
2207 @click.option('--newname', help='New name for the VIM account')
2208 @click.option('--user', help='VIM username')
2209 @click.option('--password', help='VIM password')
2210 @click.option('--auth_url', help='VIM url')
2211 @click.option('--tenant', help='VIM tenant name')
2212 @click.option('--config', help='VIM specific config parameters')
2213 @click.option('--account_type', help='VIM type')
2214 @click.option('--description', help='human readable description')
2215 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller to be associated with this VIM'
2216 'account. Use empty string to disassociate')
2217 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
2218 @click.option('--wait',
2222 help='do not return the control immediately, but keep it '
2223 'until the operation is completed, or timeout')
2238 """updates a VIM account
2240 NAME: name or ID of the VIM account
2244 check_client_version(ctx
.obj
, ctx
.command
.name
)
2246 if newname
: vim
['name'] = newname
2247 if user
: vim
['vim_user'] = user
2248 if password
: vim
['vim_password'] = password
2249 if auth_url
: vim
['vim_url'] = auth_url
2250 if tenant
: vim
['vim-tenant-name'] = tenant
2251 if account_type
: vim
['vim_type'] = account_type
2252 if description
: vim
['description'] = description
2253 if config
: vim
['config'] = config
2254 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
2255 # except ClientException as e:
2260 @cli_osm.command(name
='vim-delete', short_help
='deletes a VIM account')
2261 @click.argument('name')
2262 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2263 @click.option('--wait',
2267 help='do not return the control immediately, but keep it '
2268 'until the operation is completed, or timeout')
2270 def vim_delete(ctx
, name
, force
, wait
):
2271 """deletes a VIM account
2273 NAME: name or ID of the VIM account to be deleted
2278 ctx
.obj
.vim
.delete(name
, wait
=wait
)
2280 check_client_version(ctx
.obj
, '--force')
2281 ctx
.obj
.vim
.delete(name
, force
, wait
=wait
)
2282 # except ClientException as e:
2287 @cli_osm.command(name
='vim-list', short_help
='list all VIM accounts')
2288 #@click.option('--ro_update/--no_ro_update',
2290 # help='update list from RO')
2291 @click.option('--filter', default
=None,
2292 help='restricts the list to the VIM accounts matching the filter')
2293 @click.option('--long', is_flag
=True,
2294 help='get more details of the NS (project, vim, deployment status, configuration status.')
2296 def vim_list(ctx
, filter, long):
2297 """list all VIM accounts"""
2300 check_client_version(ctx
.obj
, '--filter')
2302 # check_client_version(ctx.obj, '--ro_update', 'v1')
2303 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
2304 if fullclassname
== 'osmclient.sol005.client.Client':
2305 resp
= ctx
.obj
.vim
.list(filter)
2307 # resp = ctx.obj.vim.list(ro_update)
2309 table
= PrettyTable(['vim name', 'uuid', 'project', 'operational state', 'error details'])
2311 table
= PrettyTable(['vim name', 'uuid'])
2314 vim_details
= ctx
.obj
.vim
.get(vim
['uuid'])
2315 if 'vim_password' in vim_details
:
2316 vim_details
['vim_password']='********'
2317 logger
.debug('VIM details: {}'.format(yaml
.safe_dump(vim_details
)))
2318 vim_state
= vim_details
['_admin'].get('operationalState', '-')
2319 error_details
= 'N/A'
2320 if vim_state
== 'ERROR':
2321 error_details
= vim_details
['_admin'].get('detailed-status', 'Not found')
2322 project_list
= ctx
.obj
.project
.list()
2323 vim_project_list
= vim_details
.get('_admin').get('projects_read')
2325 project_name
= 'None'
2326 if vim_project_list
:
2327 project_id
= vim_project_list
[0]
2328 for p
in project_list
:
2329 if p
['_id'] == project_id
:
2330 project_name
= p
['name']
2332 table
.add_row([vim
['name'], vim
['uuid'], '{} ({})'.format(project_name
, project_id
),
2333 vim_state
, wrap_text(text
=error_details
, width
=80)])
2335 table
.add_row([vim
['name'], vim
['uuid']])
2340 @cli_osm.command(name
='vim-show', short_help
='shows the details of a VIM account')
2341 @click.argument('name')
2343 def vim_show(ctx
, name
):
2344 """shows the details of a VIM account
2346 NAME: name or ID of the VIM account
2350 resp
= ctx
.obj
.vim
.get(name
)
2351 if 'vim_password' in resp
:
2352 resp
['vim_password']='********'
2353 # except ClientException as e:
2357 table
= PrettyTable(['key', 'attribute'])
2358 for k
, v
in list(resp
.items()):
2359 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2364 ####################
2366 ####################
2368 @cli_osm.command(name
='wim-create', short_help
='creates a new WIM account')
2369 @click.option('--name',
2371 help='Name for the WIM account')
2372 @click.option('--user',
2373 help='WIM username')
2374 @click.option('--password',
2375 help='WIM password')
2376 @click.option('--url',
2379 # @click.option('--tenant',
2380 # help='wIM tenant name')
2381 @click.option('--config',
2383 help='WIM specific config parameters')
2384 @click.option('--wim_type',
2386 @click.option('--description',
2388 help='human readable description')
2389 @click.option('--wim_port_mapping', default
=None,
2390 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2391 "(WAN service endpoint id and info)")
2392 @click.option('--wait',
2396 help='do not return the control immediately, but keep it '
2397 'until the operation is completed, or timeout')
2410 """creates a new WIM account"""
2413 check_client_version(ctx
.obj
, ctx
.command
.name
)
2414 # if sdn_controller:
2415 # check_client_version(ctx.obj, '--sdn_controller')
2416 # if sdn_port_mapping:
2417 # check_client_version(ctx.obj, '--sdn_port_mapping')
2419 if user
: wim
['user'] = user
2420 if password
: wim
['password'] = password
2421 if url
: wim
['wim_url'] = url
2422 # if tenant: wim['tenant'] = tenant
2423 wim
['wim_type'] = wim_type
2424 if description
: wim
['description'] = description
2425 if config
: wim
['config'] = config
2426 ctx
.obj
.wim
.create(name
, wim
, wim_port_mapping
, wait
=wait
)
2427 # except ClientException as e:
2432 @cli_osm.command(name
='wim-update', short_help
='updates a WIM account')
2433 @click.argument('name')
2434 @click.option('--newname', help='New name for the WIM account')
2435 @click.option('--user', help='WIM username')
2436 @click.option('--password', help='WIM password')
2437 @click.option('--url', help='WIM url')
2438 @click.option('--config', help='WIM specific config parameters')
2439 @click.option('--wim_type', help='WIM type')
2440 @click.option('--description', help='human readable description')
2441 @click.option('--wim_port_mapping', default
=None,
2442 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2443 "(WAN service endpoint id and info)")
2444 @click.option('--wait',
2448 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2461 """updates a WIM account
2463 NAME: name or ID of the WIM account
2467 check_client_version(ctx
.obj
, ctx
.command
.name
)
2469 if newname
: wim
['name'] = newname
2470 if user
: wim
['user'] = user
2471 if password
: wim
['password'] = password
2472 if url
: wim
['url'] = url
2473 # if tenant: wim['tenant'] = tenant
2474 if wim_type
: wim
['wim_type'] = wim_type
2475 if description
: wim
['description'] = description
2476 if config
: wim
['config'] = config
2477 ctx
.obj
.wim
.update(name
, wim
, wim_port_mapping
, wait
=wait
)
2478 # except ClientException as e:
2483 @cli_osm.command(name
='wim-delete', short_help
='deletes a WIM account')
2484 @click.argument('name')
2485 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2486 @click.option('--wait',
2490 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2492 def wim_delete(ctx
, name
, force
, wait
):
2493 """deletes a WIM account
2495 NAME: name or ID of the WIM account to be deleted
2499 check_client_version(ctx
.obj
, ctx
.command
.name
)
2500 ctx
.obj
.wim
.delete(name
, force
, wait
=wait
)
2501 # except ClientException as e:
2506 @cli_osm.command(name
='wim-list', short_help
='list all WIM accounts')
2507 @click.option('--filter', default
=None,
2508 help='restricts the list to the WIM accounts matching the filter')
2510 def wim_list(ctx
, filter):
2511 """list all WIM accounts"""
2514 check_client_version(ctx
.obj
, ctx
.command
.name
)
2515 resp
= ctx
.obj
.wim
.list(filter)
2516 table
= PrettyTable(['wim name', 'uuid'])
2518 table
.add_row([wim
['name'], wim
['uuid']])
2521 # except ClientException as e:
2526 @cli_osm.command(name
='wim-show', short_help
='shows the details of a WIM account')
2527 @click.argument('name')
2529 def wim_show(ctx
, name
):
2530 """shows the details of a WIM account
2532 NAME: name or ID of the WIM account
2536 check_client_version(ctx
.obj
, ctx
.command
.name
)
2537 resp
= ctx
.obj
.wim
.get(name
)
2538 if 'password' in resp
:
2539 resp
['wim_password']='********'
2540 # except ClientException as e:
2544 table
= PrettyTable(['key', 'attribute'])
2545 for k
, v
in list(resp
.items()):
2546 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2551 ####################
2552 # SDN controller operations
2553 ####################
2555 @cli_osm.command(name
='sdnc-create', short_help
='creates a new SDN controller')
2556 @click.option('--name',
2558 help='Name to create sdn controller')
2559 @click.option('--type',
2561 help='SDN controller type')
2562 @click.option('--sdn_controller_version', # hidden=True,
2563 help='Deprecated. Use --config {version: sdn_controller_version}')
2564 @click.option('--url',
2565 help='URL in format http[s]://HOST:IP/')
2566 @click.option('--ip_address', # hidden=True,
2567 help='Deprecated. Use --url')
2568 @click.option('--port', # hidden=True,
2569 help='Deprecated. Use --url')
2570 @click.option('--switch_dpid', # hidden=True,
2571 help='Deprecated. Use --config {switch_id: DPID}')
2572 @click.option('--config',
2573 help='Extra information for SDN in yaml format, as {switch_id: identity used for the plugin (e.g. DPID: '
2574 'Openflow Datapath ID), version: version}')
2575 @click.option('--user',
2576 help='SDN controller username')
2577 @click.option('--password',
2579 confirmation_prompt
=True,
2580 help='SDN controller password')
2581 @click.option('--description', default
=None, help='human readable description')
2582 @click.option('--wait',
2586 help="do not return the control immediately, but keep it until the operation is completed, or timeout")
2588 def sdnc_create(ctx
, **kwargs
):
2589 """creates a new SDN controller"""
2591 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2592 x
not in ("wait", "ip_address", "port", "switch_dpid")}
2593 if kwargs
.get("port"):
2594 print("option '--port' is deprecated, use '--url' instead")
2595 sdncontroller
["port"] = int(kwargs
["port"])
2596 if kwargs
.get("ip_address"):
2597 print("option '--ip_address' is deprecated, use '--url' instead")
2598 sdncontroller
["ip"] = kwargs
["ip_address"]
2599 if kwargs
.get("switch_dpid"):
2600 print("option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead")
2601 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2602 if kwargs
.get("sdn_controller_version"):
2603 print("option '--sdn_controller_version' is deprecated, use '--config={version: SDN_CONTROLLER_VERSION}'"
2606 check_client_version(ctx
.obj
, ctx
.command
.name
)
2607 ctx
.obj
.sdnc
.create(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2608 # except ClientException as e:
2612 @cli_osm.command(name
='sdnc-update', short_help
='updates an SDN controller')
2613 @click.argument('name')
2614 @click.option('--newname', help='New name for the SDN controller')
2615 @click.option('--description', default
=None, help='human readable description')
2616 @click.option('--type', help='SDN controller type')
2617 @click.option('--url', help='URL in format http[s]://HOST:IP/')
2618 @click.option('--config', help='Extra information for SDN in yaml format, as '
2619 '{switch_id: identity used for the plugin (e.g. DPID: '
2620 'Openflow Datapath ID), version: version}')
2621 @click.option('--user', help='SDN controller username')
2622 @click.option('--password', help='SDN controller password')
2623 @click.option('--ip_address', help='Deprecated. Use --url') # hidden=True
2624 @click.option('--port', help='Deprecated. Use --url') # hidden=True
2625 @click.option('--switch_dpid', help='Deprecated. Use --config {switch_dpid: DPID}') # hidden=True
2626 @click.option('--sdn_controller_version', help='Deprecated. Use --config {version: VERSION}') # hidden=True
2627 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2628 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2630 def sdnc_update(ctx
, **kwargs
):
2631 """updates an SDN controller
2633 NAME: name or ID of the SDN controller
2636 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2637 x
not in ("wait", "ip_address", "port", "switch_dpid", "new_name")}
2638 if kwargs
.get("newname"):
2639 sdncontroller
["name"] = kwargs
["newname"]
2640 if kwargs
.get("port"):
2641 print("option '--port' is deprecated, use '--url' instead")
2642 sdncontroller
["port"] = int(kwargs
["port"])
2643 if kwargs
.get("ip_address"):
2644 print("option '--ip_address' is deprecated, use '--url' instead")
2645 sdncontroller
["ip"] = kwargs
["ip_address"]
2646 if kwargs
.get("switch_dpid"):
2647 print("option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead")
2648 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2649 if kwargs
.get("sdn_controller_version"):
2650 print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'"
2654 check_client_version(ctx
.obj
, ctx
.command
.name
)
2655 ctx
.obj
.sdnc
.update(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2656 # except ClientException as e:
2661 @cli_osm.command(name
='sdnc-delete', short_help
='deletes an SDN controller')
2662 @click.argument('name')
2663 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2664 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2665 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2667 def sdnc_delete(ctx
, name
, force
, wait
):
2668 """deletes an SDN controller
2670 NAME: name or ID of the SDN controller to be deleted
2674 check_client_version(ctx
.obj
, ctx
.command
.name
)
2675 ctx
.obj
.sdnc
.delete(name
, force
, wait
=wait
)
2676 # except ClientException as e:
2681 @cli_osm.command(name
='sdnc-list', short_help
='list all SDN controllers')
2682 @click.option('--filter', default
=None,
2683 help="restricts the list to the SDN controllers matching the filter with format: 'k[.k..]=v[&k[.k]=v2]'")
2685 def sdnc_list(ctx
, filter):
2686 """list all SDN controllers"""
2689 check_client_version(ctx
.obj
, ctx
.command
.name
)
2690 resp
= ctx
.obj
.sdnc
.list(filter)
2691 # except ClientException as e:
2694 table
= PrettyTable(['sdnc name', 'id'])
2696 table
.add_row([sdnc
['name'], sdnc
['_id']])
2701 @cli_osm.command(name
='sdnc-show', short_help
='shows the details of an SDN controller')
2702 @click.argument('name')
2704 def sdnc_show(ctx
, name
):
2705 """shows the details of an SDN controller
2707 NAME: name or ID of the SDN controller
2711 check_client_version(ctx
.obj
, ctx
.command
.name
)
2712 resp
= ctx
.obj
.sdnc
.get(name
)
2713 # except ClientException as e:
2717 table
= PrettyTable(['key', 'attribute'])
2718 for k
, v
in list(resp
.items()):
2719 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2724 ###########################
2725 # K8s cluster operations
2726 ###########################
2728 @cli_osm.command(name
='k8scluster-add', short_help
='adds a K8s cluster to OSM')
2729 @click.argument('name')
2730 @click.option('--creds',
2732 help='credentials file, i.e. a valid `.kube/config` file')
2733 @click.option('--version',
2735 help='Kubernetes version')
2736 @click.option('--vim',
2738 help='VIM target, the VIM where the cluster resides')
2739 @click.option('--k8s-nets',
2741 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) ...]}"')
2742 @click.option('--description',
2744 help='human readable description')
2745 @click.option('--namespace',
2746 default
='kube-system',
2747 help='namespace to be used for its operation, defaults to `kube-system`')
2748 @click.option('--cni',
2750 help='list of CNI plugins, in JSON inline format, used in the cluster')
2751 #@click.option('--skip-init',
2753 # help='If set, K8s cluster is assumed to be ready for its use with OSM')
2754 #@click.option('--wait',
2756 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2758 def k8scluster_add(ctx
,
2767 """adds a K8s cluster to OSM
2769 NAME: name of the K8s cluster
2772 check_client_version(ctx
.obj
, ctx
.command
.name
)
2774 cluster
['name'] = name
2775 with
open(creds
, 'r') as cf
:
2776 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2777 cluster
['k8s_version'] = version
2778 cluster
['vim_account'] = vim
2779 cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2781 cluster
['description'] = description
2782 if namespace
: cluster
['namespace'] = namespace
2783 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2784 ctx
.obj
.k8scluster
.create(name
, cluster
)
2785 # except ClientException as e:
2790 @cli_osm.command(name
='k8scluster-update', short_help
='updates a K8s cluster')
2791 @click.argument('name')
2792 @click.option('--newname', help='New name for the K8s cluster')
2793 @click.option('--creds', help='credentials file, i.e. a valid `.kube/config` file')
2794 @click.option('--version', help='Kubernetes version')
2795 @click.option('--vim', help='VIM target, the VIM where the cluster resides')
2796 @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) ...]}"')
2797 @click.option('--description', help='human readable description')
2798 @click.option('--namespace', help='namespace to be used for its operation, defaults to `kube-system`')
2799 @click.option('--cni', help='list of CNI plugins, in JSON inline format, used in the cluster')
2801 def k8scluster_update(ctx
,
2811 """updates a K8s cluster
2813 NAME: name or ID of the K8s cluster
2816 check_client_version(ctx
.obj
, ctx
.command
.name
)
2818 if newname
: cluster
['name'] = newname
2820 with
open(creds
, 'r') as cf
:
2821 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2822 if version
: cluster
['k8s_version'] = version
2823 if vim
: cluster
['vim_account'] = vim
2824 if k8s_nets
: cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2825 if description
: cluster
['description'] = description
2826 if namespace
: cluster
['namespace'] = namespace
2827 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2828 ctx
.obj
.k8scluster
.update(name
, cluster
)
2829 # except ClientException as e:
2834 @cli_osm.command(name
='k8scluster-delete', short_help
='deletes a K8s cluster')
2835 @click.argument('name')
2836 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2837 #@click.option('--wait',
2839 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2841 def k8scluster_delete(ctx
, name
, force
):
2842 """deletes a K8s cluster
2844 NAME: name or ID of the K8s cluster to be deleted
2847 check_client_version(ctx
.obj
, ctx
.command
.name
)
2848 ctx
.obj
.k8scluster
.delete(name
, force
=force
)
2849 # except ClientException as e:
2854 @cli_osm.command(name
='k8scluster-list')
2855 @click.option('--filter', default
=None,
2856 help='restricts the list to the K8s clusters matching the filter')
2857 @click.option('--literal', is_flag
=True,
2858 help='print literally, no pretty table')
2860 def k8scluster_list(ctx
, filter, literal
):
2861 """list all K8s clusters"""
2863 check_client_version(ctx
.obj
, ctx
.command
.name
)
2864 resp
= ctx
.obj
.k8scluster
.list(filter)
2866 print(yaml
.safe_dump(resp
))
2868 table
= PrettyTable(['Name', 'Id', 'Version', 'VIM', 'K8s-nets', 'Operational State', 'Description'])
2869 for cluster
in resp
:
2870 table
.add_row([cluster
['name'], cluster
['_id'], cluster
['k8s_version'], cluster
['vim_account'],
2871 json
.dumps(cluster
['nets']), cluster
["_admin"]["operationalState"],
2872 trunc_text(cluster
.get('description',''),40)])
2875 # except ClientException as e:
2880 @cli_osm.command(name
='k8scluster-show', short_help
='shows the details of a K8s cluster')
2881 @click.argument('name')
2882 @click.option('--literal', is_flag
=True,
2883 help='print literally, no pretty table')
2885 def k8scluster_show(ctx
, name
, literal
):
2886 """shows the details of a K8s cluster
2888 NAME: name or ID of the K8s cluster
2891 resp
= ctx
.obj
.k8scluster
.get(name
)
2893 print(yaml
.safe_dump(resp
))
2895 table
= PrettyTable(['key', 'attribute'])
2896 for k
, v
in list(resp
.items()):
2897 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2900 # except ClientException as e:
2906 ###########################
2908 ###########################
2910 @cli_osm.command(name
='repo-add', short_help
='adds a repo to OSM')
2911 @click.argument('name')
2912 @click.argument('uri')
2913 @click.option('--type',
2914 type=click
.Choice(['helm-chart', 'juju-bundle']),
2916 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2917 @click.option('--description',
2919 help='human readable description')
2920 #@click.option('--wait',
2922 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2929 """adds a repo to OSM
2931 NAME: name of the repo
2932 URI: URI of the repo
2935 check_client_version(ctx
.obj
, ctx
.command
.name
)
2941 repo
['description'] = description
2942 ctx
.obj
.repo
.create(name
, repo
)
2943 # except ClientException as e:
2948 @cli_osm.command(name
='repo-update', short_help
='updates a repo in OSM')
2949 @click.argument('name')
2950 @click.option('--newname', help='New name for the repo')
2951 @click.option('--uri', help='URI of the repo')
2952 @click.option('--type', type=click
.Choice(['helm-chart', 'juju-bundle']),
2953 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2954 @click.option('--description', help='human readable description')
2955 #@click.option('--wait',
2957 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2959 def repo_update(ctx
,
2965 """updates a repo in OSM
2967 NAME: name of the repo
2970 check_client_version(ctx
.obj
, ctx
.command
.name
)
2972 if newname
: repo
['name'] = newname
2973 if uri
: repo
['uri'] = uri
2974 if type: repo
['type'] = type
2975 if description
: repo
['description'] = description
2976 ctx
.obj
.repo
.update(name
, repo
)
2977 # except ClientException as e:
2982 @cli_osm.command(name
='repo-delete', short_help
='deletes a repo')
2983 @click.argument('name')
2984 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2985 #@click.option('--wait',
2987 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2989 def repo_delete(ctx
, name
, force
):
2992 NAME: name or ID of the repo to be deleted
2995 check_client_version(ctx
.obj
, ctx
.command
.name
)
2996 ctx
.obj
.repo
.delete(name
, force
=force
)
2997 # except ClientException as e:
3002 @cli_osm.command(name
='repo-list')
3003 @click.option('--filter', default
=None,
3004 help='restricts the list to the repos matching the filter')
3005 @click.option('--literal', is_flag
=True,
3006 help='print literally, no pretty table')
3008 def repo_list(ctx
, filter, literal
):
3009 """list all repos"""
3011 check_client_version(ctx
.obj
, ctx
.command
.name
)
3012 resp
= ctx
.obj
.repo
.list(filter)
3014 print(yaml
.safe_dump(resp
))
3016 table
= PrettyTable(['Name', 'Id', 'Type', 'URI', 'Description'])
3018 #cluster['k8s-nets'] = json.dumps(yaml.safe_load(cluster['k8s-nets']))
3019 table
.add_row([repo
['name'], repo
['_id'], repo
['type'], repo
['url'], trunc_text(repo
.get('description',''),40)])
3022 # except ClientException as e:
3027 @cli_osm.command(name
='repo-show', short_help
='shows the details of a repo')
3028 @click.argument('name')
3029 @click.option('--literal', is_flag
=True,
3030 help='print literally, no pretty table')
3032 def repo_show(ctx
, name
, literal
):
3033 """shows the details of a repo
3035 NAME: name or ID of the repo
3038 resp
= ctx
.obj
.repo
.get(name
)
3040 print(yaml
.safe_dump(resp
))
3042 table
= PrettyTable(['key', 'attribute'])
3043 for k
, v
in list(resp
.items()):
3044 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3047 # except ClientException as e:
3053 ####################
3054 # Project mgmt operations
3055 ####################
3057 @cli_osm.command(name
='project-create', short_help
='creates a new project')
3058 @click.argument('name')
3059 #@click.option('--description',
3060 # default='no description',
3061 # help='human readable description')
3062 @click.option('--domain-name', 'domain_name',
3064 help='assign to a domain')
3066 def project_create(ctx
, name
, domain_name
):
3067 """Creates a new project
3069 NAME: name of the project
3070 DOMAIN_NAME: optional domain name for the project when keystone authentication is used
3074 project
['name'] = name
3076 project
['domain_name'] = domain_name
3078 check_client_version(ctx
.obj
, ctx
.command
.name
)
3079 ctx
.obj
.project
.create(name
, project
)
3080 # except ClientException as e:
3085 @cli_osm.command(name
='project-delete', short_help
='deletes a project')
3086 @click.argument('name')
3087 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3089 def project_delete(ctx
, name
):
3090 """deletes a project
3092 NAME: name or ID of the project to be deleted
3096 check_client_version(ctx
.obj
, ctx
.command
.name
)
3097 ctx
.obj
.project
.delete(name
)
3098 # except ClientException as e:
3103 @cli_osm.command(name
='project-list', short_help
='list all projects')
3104 @click.option('--filter', default
=None,
3105 help='restricts the list to the projects matching the filter')
3107 def project_list(ctx
, filter):
3108 """list all projects"""
3111 check_client_version(ctx
.obj
, ctx
.command
.name
)
3112 resp
= ctx
.obj
.project
.list(filter)
3113 # except ClientException as e:
3116 table
= PrettyTable(['name', 'id'])
3118 table
.add_row([proj
['name'], proj
['_id']])
3123 @cli_osm.command(name
='project-show', short_help
='shows the details of a project')
3124 @click.argument('name')
3126 def project_show(ctx
, name
):
3127 """shows the details of a project
3129 NAME: name or ID of the project
3133 check_client_version(ctx
.obj
, ctx
.command
.name
)
3134 resp
= ctx
.obj
.project
.get(name
)
3135 # except ClientException as e:
3139 table
= PrettyTable(['key', 'attribute'])
3140 for k
, v
in resp
.items():
3141 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3146 @cli_osm.command(name
='project-update', short_help
='updates a project (only the name can be updated)')
3147 @click.argument('project')
3148 @click.option('--name',
3150 help='new name for the project')
3153 def project_update(ctx
, project
, name
):
3155 Update a project name
3158 :param project: id or name of the project to modify
3159 :param name: new name for the project
3163 project_changes
= {}
3164 project_changes
['name'] = name
3167 check_client_version(ctx
.obj
, ctx
.command
.name
)
3168 ctx
.obj
.project
.update(project
, project_changes
)
3169 # except ClientException as e:
3173 ####################
3174 # User mgmt operations
3175 ####################
3177 @cli_osm.command(name
='user-create', short_help
='creates a new user')
3178 @click.argument('username')
3179 @click.option('--password',
3182 confirmation_prompt
=True,
3183 help='user password')
3184 @click.option('--projects',
3185 # prompt="Comma separate list of projects",
3187 callback
=lambda ctx
, param
, value
: ''.join(value
).split(',') if all(len(x
)==1 for x
in value
) else value
,
3188 help='list of project ids that the user belongs to')
3189 @click.option('--project-role-mappings', 'project_role_mappings',
3190 default
=None, multiple
=True,
3191 help="assign role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3192 @click.option('--domain-name', 'domain_name',
3194 help='assign to a domain')
3196 def user_create(ctx
, username
, password
, projects
, project_role_mappings
, domain_name
):
3197 """Creates a new user
3200 USERNAME: name of the user
3201 PASSWORD: password of the user
3202 PROJECTS: projects assigned to user (internal only)
3203 PROJECT_ROLE_MAPPING: roles in projects assigned to user (keystone)
3204 DOMAIN_NAME: optional domain name for the user when keystone authentication is used
3208 user
['username'] = username
3209 user
['password'] = password
3210 user
['projects'] = projects
3211 user
['project_role_mappings'] = project_role_mappings
3213 user
['domain_name'] = domain_name
3216 check_client_version(ctx
.obj
, ctx
.command
.name
)
3217 ctx
.obj
.user
.create(username
, user
)
3218 # except ClientException as e:
3223 @cli_osm.command(name
='user-update', short_help
='updates user information')
3224 @click.argument('username')
3225 @click.option('--password',
3228 # confirmation_prompt=True,
3229 help='user password')
3230 @click.option('--set-username', 'set_username',
3232 help='change username')
3233 @click.option('--set-project', 'set_project',
3234 default
=None, multiple
=True,
3235 help="create/replace the roles for this project: 'project,role1[,role2,...]'")
3236 @click.option('--remove-project', 'remove_project',
3237 default
=None, multiple
=True,
3238 help="removes project from user: 'project'")
3239 @click.option('--add-project-role', 'add_project_role',
3240 default
=None, multiple
=True,
3241 help="assign role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3242 @click.option('--remove-project-role', 'remove_project_role',
3243 default
=None, multiple
=True,
3244 help="remove role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3246 def user_update(ctx
, username
, password
, set_username
, set_project
, remove_project
,
3247 add_project_role
, remove_project_role
):
3248 """Update a user information
3251 USERNAME: name of the user
3252 PASSWORD: new password
3253 SET_USERNAME: new username
3254 SET_PROJECT: creating mappings for project/role(s)
3255 REMOVE_PROJECT: deleting mappings for project/role(s)
3256 ADD_PROJECT_ROLE: adding mappings for project/role(s)
3257 REMOVE_PROJECT_ROLE: removing mappings for project/role(s)
3261 user
['password'] = password
3262 user
['username'] = set_username
3263 user
['set-project'] = set_project
3264 user
['remove-project'] = remove_project
3265 user
['add-project-role'] = add_project_role
3266 user
['remove-project-role'] = remove_project_role
3269 check_client_version(ctx
.obj
, ctx
.command
.name
)
3270 ctx
.obj
.user
.update(username
, user
)
3271 # except ClientException as e:
3276 @cli_osm.command(name
='user-delete', short_help
='deletes a user')
3277 @click.argument('name')
3278 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3280 def user_delete(ctx
, name
):
3284 NAME: name or ID of the user to be deleted
3288 check_client_version(ctx
.obj
, ctx
.command
.name
)
3289 ctx
.obj
.user
.delete(name
)
3290 # except ClientException as e:
3295 @cli_osm.command(name
='user-list', short_help
='list all users')
3296 @click.option('--filter', default
=None,
3297 help='restricts the list to the users matching the filter')
3299 def user_list(ctx
, filter):
3300 """list all users"""
3302 check_client_version(ctx
.obj
, ctx
.command
.name
)
3303 resp
= ctx
.obj
.user
.list(filter)
3304 # except ClientException as e:
3307 table
= PrettyTable(['name', 'id'])
3309 table
.add_row([user
['username'], user
['_id']])
3314 @cli_osm.command(name
='user-show', short_help
='shows the details of a user')
3315 @click.argument('name')
3317 def user_show(ctx
, name
):
3318 """shows the details of a user
3320 NAME: name or ID of the user
3324 check_client_version(ctx
.obj
, ctx
.command
.name
)
3325 resp
= ctx
.obj
.user
.get(name
)
3326 if 'password' in resp
:
3327 resp
['password']='********'
3328 # except ClientException as e:
3332 table
= PrettyTable(['key', 'attribute'])
3333 for k
, v
in resp
.items():
3334 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3339 ####################
3340 # Fault Management operations
3341 ####################
3343 @cli_osm.command(name
='ns-alarm-create')
3344 @click.argument('name')
3345 @click.option('--ns', prompt
=True, help='NS instance id or name')
3346 @click.option('--vnf', prompt
=True,
3347 help='VNF name (VNF member index as declared in the NSD)')
3348 @click.option('--vdu', prompt
=True,
3349 help='VDU name (VDU name as declared in the VNFD)')
3350 @click.option('--metric', prompt
=True,
3351 help='Name of the metric (e.g. cpu_utilization)')
3352 @click.option('--severity', default
='WARNING',
3353 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
3354 @click.option('--threshold_value', prompt
=True,
3355 help='threshold value that, when crossed, an alarm is triggered')
3356 @click.option('--threshold_operator', prompt
=True,
3357 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
3358 @click.option('--statistic', default
='AVERAGE',
3359 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
3361 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
3362 threshold_value
, threshold_operator
, statistic
):
3363 """creates a new alarm for a NS instance"""
3364 # TODO: Check how to validate threshold_value.
3365 # Should it be an integer (1-100), percentage, or decimal (0.01-1.00)?
3368 ns_instance
= ctx
.obj
.ns
.get(ns
)
3370 alarm
['alarm_name'] = name
3371 alarm
['ns_id'] = ns_instance
['_id']
3372 alarm
['correlation_id'] = ns_instance
['_id']
3373 alarm
['vnf_member_index'] = vnf
3374 alarm
['vdu_name'] = vdu
3375 alarm
['metric_name'] = metric
3376 alarm
['severity'] = severity
3377 alarm
['threshold_value'] = int(threshold_value
)
3378 alarm
['operation'] = threshold_operator
3379 alarm
['statistic'] = statistic
3380 check_client_version(ctx
.obj
, ctx
.command
.name
)
3381 ctx
.obj
.ns
.create_alarm(alarm
)
3382 # except ClientException as e:
3387 #@cli_osm.command(name='ns-alarm-delete')
3388 #@click.argument('name')
3389 #@click.pass_context
3390 #def ns_alarm_delete(ctx, name):
3391 # """deletes an alarm
3393 # NAME: name of the alarm to be deleted
3396 # check_client_version(ctx.obj, ctx.command.name)
3397 # ctx.obj.ns.delete_alarm(name)
3398 # except ClientException as e:
3403 ####################
3404 # Performance Management operations
3405 ####################
3407 @cli_osm.command(name
='ns-metric-export', short_help
='exports a metric to the internal OSM bus, which can be read by other apps')
3408 @click.option('--ns', prompt
=True, help='NS instance id or name')
3409 @click.option('--vnf', prompt
=True,
3410 help='VNF name (VNF member index as declared in the NSD)')
3411 @click.option('--vdu', prompt
=True,
3412 help='VDU name (VDU name as declared in the VNFD)')
3413 @click.option('--metric', prompt
=True,
3414 help='name of the metric (e.g. cpu_utilization)')
3415 #@click.option('--period', default='1w',
3416 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
3417 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
3419 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
3420 """exports a metric to the internal OSM bus, which can be read by other apps"""
3421 # TODO: Check how to validate interval.
3422 # Should it be an integer (seconds), or should a suffix (s,m,h,d,w) also be permitted?
3425 ns_instance
= ctx
.obj
.ns
.get(ns
)
3427 metric_data
['ns_id'] = ns_instance
['_id']
3428 metric_data
['correlation_id'] = ns_instance
['_id']
3429 metric_data
['vnf_member_index'] = vnf
3430 metric_data
['vdu_name'] = vdu
3431 metric_data
['metric_name'] = metric
3432 metric_data
['collection_unit'] = 'WEEK'
3433 metric_data
['collection_period'] = 1
3434 check_client_version(ctx
.obj
, ctx
.command
.name
)
3436 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
3440 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
3441 time
.sleep(int(interval
))
3443 # except ClientException as e:
3448 ####################
3450 ####################
3452 @cli_osm.command(name
='version', short_help
='shows client and server versions')
3454 def get_version(ctx
):
3455 """shows client and server versions"""
3457 check_client_version(ctx
.obj
, "version")
3458 print ("Server version: {}".format(ctx
.obj
.get_version()))
3459 print ("Client version: {}".format(pkg_resources
.get_distribution("osmclient").version
))
3460 # except ClientException as e:
3464 @cli_osm.command(name
='upload-package', short_help
='uploads a VNF package or NS package')
3465 @click.argument('filename')
3466 @click.option('--skip-charm-build', default
=False, is_flag
=True,
3467 help='the charm will not be compiled, it is assumed to already exist')
3469 def upload_package(ctx
, filename
, skip_charm_build
):
3470 """uploads a vnf package or ns package
3472 filename: vnf or ns package folder, or vnf or ns package file (tar.gz)
3476 ctx
.obj
.package
.upload(filename
, skip_charm_build
=skip_charm_build
)
3477 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
3478 if fullclassname
!= 'osmclient.sol005.client.Client':
3479 ctx
.obj
.package
.wait_for_upload(filename
)
3480 # except ClientException as e:
3485 #@cli_osm.command(name='ns-scaling-show')
3486 #@click.argument('ns_name')
3487 #@click.pass_context
3488 #def show_ns_scaling(ctx, ns_name):
3489 # """shows the status of a NS scaling operation
3491 # NS_NAME: name of the NS instance being scaled
3494 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3495 # resp = ctx.obj.ns.list()
3496 # except ClientException as e:
3500 # table = PrettyTable(
3503 # 'operational status',
3508 # if ns_name == ns['name']:
3509 # nsopdata = ctx.obj.ns.get_opdata(ns['id'])
3510 # scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
3511 # for record in scaling_records:
3512 # if 'instance' in record:
3513 # instances = record['instance']
3514 # for inst in instances:
3516 # [record['scaling-group-name-ref'],
3517 # inst['instance-id'],
3518 # inst['op-status'],
3519 # time.strftime('%Y-%m-%d %H:%M:%S',
3521 # inst['create-time'])),
3527 #@cli_osm.command(name='ns-scale')
3528 #@click.argument('ns_name')
3529 #@click.option('--ns_scale_group', prompt=True)
3530 #@click.option('--index', prompt=True)
3531 #@click.option('--wait',
3535 # help='do not return the control immediately, but keep it \
3536 # until the operation is completed, or timeout')
3537 #@click.pass_context
3538 #def ns_scale(ctx, ns_name, ns_scale_group, index, wait):
3541 # NS_NAME: name of the NS instance to be scaled
3544 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3545 # ctx.obj.ns.scale(ns_name, ns_scale_group, index, wait=wait)
3546 # except ClientException as e:
3551 #@cli_osm.command(name='config-agent-list')
3552 #@click.pass_context
3553 #def config_agent_list(ctx):
3554 # """list config agents"""
3556 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3557 # except ClientException as e:
3560 # table = PrettyTable(['name', 'account-type', 'details'])
3561 # for account in ctx.obj.vca.list():
3564 # account['account-type'],
3570 #@cli_osm.command(name='config-agent-delete')
3571 #@click.argument('name')
3572 #@click.pass_context
3573 #def config_agent_delete(ctx, name):
3574 # """deletes a config agent
3576 # NAME: name of the config agent to be deleted
3579 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3580 # ctx.obj.vca.delete(name)
3581 # except ClientException as e:
3586 #@cli_osm.command(name='config-agent-add')
3587 #@click.option('--name',
3589 #@click.option('--account_type',
3591 #@click.option('--server',
3593 #@click.option('--user',
3595 #@click.option('--secret',
3598 # confirmation_prompt=True)
3599 #@click.pass_context
3600 #def config_agent_add(ctx, name, account_type, server, user, secret):
3601 # """adds a config agent"""
3603 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3604 # ctx.obj.vca.create(name, account_type, server, user, secret)
3605 # except ClientException as e:
3610 #@cli_osm.command(name='ro-dump')
3611 #@click.pass_context
3613 # """shows RO agent information"""
3614 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3615 # resp = ctx.obj.vim.get_resource_orchestrator()
3616 # table = PrettyTable(['key', 'attribute'])
3617 # for k, v in list(resp.items()):
3618 # table.add_row([k, json.dumps(v, indent=2)])
3623 #@cli_osm.command(name='vcs-list')
3624 #@click.pass_context
3626 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3627 # resp = ctx.obj.utils.get_vcs_info()
3628 # table = PrettyTable(['component name', 'state'])
3629 # for component in resp:
3630 # table.add_row([component['component_name'], component['state']])
3635 @cli_osm.command(name
='ns-action', short_help
='executes an action/primitive over a NS instance')
3636 @click.argument('ns_name')
3637 @click.option('--vnf_name', default
=None, help='member-vnf-index if the target is a vnf instead of a ns)')
3638 @click.option('--kdu_name', default
=None, help='kdu-name if the target is a kdu)')
3639 @click.option('--vdu_id', default
=None, help='vdu-id if the target is a vdu')
3640 @click.option('--vdu_count', default
=None, help='number of vdu instance of this vdu_id')
3641 @click.option('--action_name', prompt
=True, help='action name')
3642 @click.option('--params', default
=None, help='action params in YAML/JSON inline string')
3643 @click.option('--params_file', default
=None, help='YAML/JSON file with action params')
3644 @click.option('--timeout', required
=False, default
=None, type=int, help='timeout in seconds')
3645 @click.option('--wait',
3649 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3662 """executes an action/primitive over a NS instance
3664 NS_NAME: name or ID of the NS instance
3668 check_client_version(ctx
.obj
, ctx
.command
.name
)
3671 op_data
['member_vnf_index'] = vnf_name
3673 op_data
['kdu_name'] = kdu_name
3675 op_data
['vdu_id'] = vdu_id
3677 op_data
['vdu_count_index'] = vdu_count
3679 op_data
['timeout_ns_action'] = timeout
3680 op_data
['primitive'] = action_name
3682 with
open(params_file
, 'r') as pf
:
3685 op_data
['primitive_params'] = yaml
.safe_load(params
)
3687 op_data
['primitive_params'] = {}
3688 print(ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
, wait
=wait
))
3690 # except ClientException as e:
3695 @cli_osm.command(name
='vnf-scale', short_help
='executes a VNF scale (adding/removing VDUs)')
3696 @click.argument('ns_name')
3697 @click.argument('vnf_name')
3698 @click.option('--scaling-group', prompt
=True, help="scaling-group-descriptor name to use")
3699 @click.option('--scale-in', default
=False, is_flag
=True, help="performs a scale in operation")
3700 @click.option('--scale-out', default
=False, is_flag
=True, help="performs a scale out operation (by default)")
3701 @click.option('--timeout', required
=False, default
=None, type=int, help='timeout in seconds')
3702 @click.option('--wait', required
=False, default
=False, is_flag
=True,
3703 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3714 Executes a VNF scale (adding/removing VDUs)
3717 NS_NAME: name or ID of the NS instance.
3718 VNF_NAME: member-vnf-index in the NS to be scaled.
3722 check_client_version(ctx
.obj
, ctx
.command
.name
)
3723 if not scale_in
and not scale_out
:
3725 ctx
.obj
.ns
.scale_vnf(ns_name
, vnf_name
, scaling_group
, scale_in
, scale_out
, wait
, timeout
)
3726 # except ClientException as e:
3731 ##############################
3732 # Role Management Operations #
3733 ##############################
3735 @cli_osm.command(name
='role-create', short_help
='creates a new role')
3736 @click.argument('name')
3737 @click.option('--permissions',
3739 help='role permissions using a dictionary')
3741 def role_create(ctx
, name
, permissions
):
3746 NAME: Name or ID of the role.
3747 DEFINITION: Definition of grant/denial of access to resources.
3751 check_client_version(ctx
.obj
, ctx
.command
.name
)
3752 ctx
.obj
.role
.create(name
, permissions
)
3753 # except ClientException as e:
3758 @cli_osm.command(name
='role-update', short_help
='updates a role')
3759 @click.argument('name')
3760 @click.option('--set-name',
3762 help='change name of rle')
3763 # @click.option('--permissions',
3765 # help='provide a yaml format dictionary with incremental changes. Values can be bool or None to delete')
3766 @click.option('--add',
3768 help='yaml format dictionary with permission: True/False to access grant/denial')
3769 @click.option('--remove',
3771 help='yaml format list to remove a permission')
3773 def role_update(ctx
, name
, set_name
, add
, remove
):
3778 NAME: Name or ID of the role.
3779 DEFINITION: Definition overwrites the old definition.
3780 ADD: Grant/denial of access to resource to add.
3781 REMOVE: Grant/denial of access to resource to remove.
3785 check_client_version(ctx
.obj
, ctx
.command
.name
)
3786 ctx
.obj
.role
.update(name
, set_name
, None, add
, remove
)
3787 # except ClientException as e:
3792 @cli_osm.command(name
='role-delete', short_help
='deletes a role')
3793 @click.argument('name')
3794 # @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3796 def role_delete(ctx
, name
):
3801 NAME: Name or ID of the role.
3805 check_client_version(ctx
.obj
, ctx
.command
.name
)
3806 ctx
.obj
.role
.delete(name
)
3807 # except ClientException as e:
3812 @cli_osm.command(name
='role-list', short_help
='list all roles')
3813 @click.option('--filter', default
=None,
3814 help='restricts the list to the projects matching the filter')
3816 def role_list(ctx
, filter):
3822 check_client_version(ctx
.obj
, ctx
.command
.name
)
3823 resp
= ctx
.obj
.role
.list(filter)
3824 # except ClientException as e:
3827 table
= PrettyTable(['name', 'id'])
3829 table
.add_row([role
['name'], role
['_id']])
3834 @cli_osm.command(name
='role-show', short_help
='show specific role')
3835 @click.argument('name')
3837 def role_show(ctx
, name
):
3839 Shows the details of a role.
3842 NAME: Name or ID of the role.
3846 check_client_version(ctx
.obj
, ctx
.command
.name
)
3847 resp
= ctx
.obj
.role
.get(name
)
3848 # except ClientException as e:
3852 table
= PrettyTable(['key', 'attribute'])
3853 for k
, v
in resp
.items():
3854 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3859 @cli_osm.command(name
='package-create',
3860 short_help
='Create a package descriptor')
3861 @click.argument('package-type')
3862 @click.argument('package-name')
3863 @click.option('--base-directory',
3865 help=('(NS/VNF/NST) Set the location for package creation. Default: "."'))
3866 @click.option('--image',
3867 default
="image-name",
3868 help='(VNF) Set the name of the vdu image. Default "image-name"')
3869 @click.option('--vdus',
3871 help='(VNF) Set the number of vdus in a VNF. Default 1')
3872 @click.option('--vcpu',
3874 help='(VNF) Set the number of virtual CPUs in a vdu. Default 1')
3875 @click.option('--memory',
3877 help='(VNF) Set the memory size (MB) of the vdu. Default 1024')
3878 @click.option('--storage',
3880 help='(VNF) Set the disk size (GB) of the vdu. Default 10')
3881 @click.option('--interfaces',
3883 help='(VNF) Set the number of additional interfaces apart from the management interface. Default 0')
3884 @click.option('--vendor',
3886 help='(NS/VNF) Set the descriptor vendor. Default "OSM"')
3887 @click.option('--override',
3890 help='(NS/VNF/NST) Flag for overriding the package if exists.')
3891 @click.option('--detailed',
3894 help='(NS/VNF/NST) Flag for generating descriptor .yaml with all possible commented options')
3895 @click.option('--netslice-subnets',
3897 help='(NST) Number of netslice subnets. Default 1')
3898 @click.option('--netslice-vlds',
3900 help='(NST) Number of netslice vlds. Default 1')
3902 def package_create(ctx
,
3918 Creates an OSM NS, VNF, NST package
3921 PACKAGE_TYPE: Package to be created: NS, VNF or NST.
3922 PACKAGE_NAME: Name of the package to create the folder with the content.
3926 check_client_version(ctx
.obj
, ctx
.command
.name
)
3927 print("Creating the {} structure: {}/{}".format(package_type
.upper(), base_directory
, package_name
))
3928 resp
= ctx
.obj
.package_tool
.create(package_type
,
3937 interfaces
=interfaces
,
3940 netslice_subnets
=netslice_subnets
,
3941 netslice_vlds
=netslice_vlds
)
3943 # except ClientException as inst:
3944 # print("ERROR: {}".format(inst))
3947 @cli_osm.command(name
='package-validate',
3948 short_help
='Validate a package descriptor')
3949 @click.argument('base-directory',
3952 @click.option('--recursive/--no-recursive',
3954 help='The activated recursive option will validate the yaml files'
3955 ' within the indicated directory and in its subdirectories')
3957 def package_validate(ctx
,
3961 Validate descriptors given a base directory.
3964 BASE_DIRECTORY: Stub folder for NS, VNF or NST package.
3967 check_client_version(ctx
.obj
, ctx
.command
.name
)
3968 results
= ctx
.obj
.package_tool
.validate(base_directory
, recursive
)
3969 table
= PrettyTable()
3970 table
.field_names
= ["TYPE", "PATH", "VALID", "ERROR"]
3971 # Print the dictionary generated by the validation function
3972 for result
in results
:
3973 table
.add_row([result
["type"], result
["path"], result
["valid"], result
["error"]])
3974 table
.sortby
= "VALID"
3975 table
.align
["PATH"] = "l"
3976 table
.align
["TYPE"] = "l"
3977 table
.align
["ERROR"] = "l"
3979 # except ClientException as inst:
3980 # print("ERROR: {}".format(inst))
3983 @cli_osm.command(name
='package-build',
3984 short_help
='Build the tar.gz of the package')
3985 @click.argument('package-folder')
3986 @click.option('--skip-validation',
3989 help='skip package validation')
3990 @click.option('--skip-charm-build', default
=False, is_flag
=True,
3991 help='the charm will not be compiled, it is assumed to already exist')
3993 def package_build(ctx
,
3998 Build the package NS, VNF given the package_folder.
4001 PACKAGE_FOLDER: Folder of the NS, VNF or NST to be packaged
4004 check_client_version(ctx
.obj
, ctx
.command
.name
)
4005 results
= ctx
.obj
.package_tool
.build(package_folder
,
4006 skip_validation
=skip_validation
,
4007 skip_charm_build
=skip_charm_build
)
4009 # except ClientException as inst:
4010 # print("ERROR: {}".format(inst))
4018 except pycurl
.error
as exc
:
4020 print('Maybe "--hostname" option or OSM_HOSTNAME environment variable needs to be specified')
4021 except ClientException
as exc
:
4022 print("ERROR: {}".format(exc
))
4023 except (FileNotFoundError
, PermissionError
) as exc
:
4024 print("Cannot open file: {}".format(exc
))
4025 except yaml
.YAMLError
as exc
:
4026 print("Invalid YAML format: {}".format(exc
))
4028 # TODO capture other controlled exceptions here
4029 # TODO remove the ClientException captures from all places, unless they do something different
4032 if __name__
== '__main__':