1 # Copyright 2017-2018 Sandvine
2 # Copyright 2018 Telefonica
6 # Licensed under the Apache License, Version 2.0 (the "License"); you may
7 # not use this file except in compliance with the License. You may obtain
8 # a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 # License for the specific language governing permissions and limitations
22 from osmclient
import client
23 from osmclient
.common
.exceptions
import ClientException
24 from prettytable
import PrettyTable
33 from datetime
import datetime
38 CONTEXT_SETTINGS
= dict(help_option_names
=['-h', '--help'], max_content_width
=160)
40 def wrap_text(text
, width
):
41 wrapper
= textwrap
.TextWrapper(width
=width
)
42 lines
= text
.splitlines()
43 return "\n".join(map(wrapper
.fill
, lines
))
46 def trunc_text(text
, length
):
47 if len(text
) > length
:
48 return text
[:(length
- 3)] + '...'
53 def check_client_version(obj
, what
, version
='sol005'):
55 Checks the version of the client object and raises error if it not the expected.
57 :param obj: the client object
58 :what: the function or command under evaluation (used when an error is raised)
60 :raises ClientError: if the specified version does not match the client version
63 fullclassname
= obj
.__module
__ + "." + obj
.__class
__.__name
__
64 message
= 'The following commands or options are only supported with the option "--sol005": {}'.format(what
)
66 message
= 'The following commands or options are not supported when using option "--sol005": {}'.format(what
)
67 if fullclassname
!= 'osmclient.{}.client.Client'.format(version
):
68 raise ClientException(message
)
72 @click.group(context_settings
=dict(help_option_names
=['-h', '--help'], max_content_width
=160))
73 @click.option('--hostname',
75 envvar
='OSM_HOSTNAME',
76 help='hostname of server. ' +
77 'Also can set OSM_HOSTNAME in environment')
78 #@click.option('--sol005/--no-sol005',
80 # envvar='OSM_SOL005',
81 # help='Use ETSI NFV SOL005 API (default) or the previous SO API. ' +
82 # 'Also can set OSM_SOL005 in environment')
83 @click.option('--user',
86 help='user (defaults to admin). ' +
87 'Also can set OSM_USER in environment')
88 @click.option('--password',
90 envvar
='OSM_PASSWORD',
91 help='password (defaults to admin). ' +
92 'Also can set OSM_PASSWORD in environment')
93 @click.option('--project',
96 help='project (defaults to admin). ' +
97 'Also can set OSM_PROJECT in environment')
98 @click.option('-v', '--verbose', count
=True,
99 help='increase verbosity (-v INFO, -vv VERBOSE, -vvv DEBUG)')
100 @click.option('--all-projects',
103 help='include all projects')
104 @click.option('--public/--no-public', default
=None,
105 help='flag for public items (packages, instances, VIM accounts, etc.)')
106 @click.option('--project-domain-name', 'project_domain_name',
108 envvar
='OSM_PROJECT_DOMAIN_NAME',
109 help='project domain name for keystone authentication (default to None). ' +
110 'Also can set OSM_PROJECT_DOMAIN_NAME in environment')
111 @click.option('--user-domain-name', 'user_domain_name',
113 envvar
='OSM_USER_DOMAIN_NAME',
114 help='user domain name for keystone authentication (default to None). ' +
115 'Also can set OSM_USER_DOMAIN_NAME in environment')
116 #@click.option('--so-port',
118 # envvar='OSM_SO_PORT',
119 # help='hostname of server. ' +
120 # 'Also can set OSM_SO_PORT in environment')
121 #@click.option('--so-project',
123 # envvar='OSM_SO_PROJECT',
124 # help='Project Name in SO. ' +
125 # 'Also can set OSM_SO_PROJECT in environment')
126 #@click.option('--ro-hostname',
128 # envvar='OSM_RO_HOSTNAME',
129 # help='hostname of RO server. ' +
130 # 'Also can set OSM_RO_HOSTNAME in environment')
131 #@click.option('--ro-port',
133 # envvar='OSM_RO_PORT',
134 # help='hostname of RO server. ' +
135 # 'Also can set OSM_RO_PORT in environment')
137 def cli_osm(ctx
, **kwargs
):
139 hostname
= kwargs
.pop("hostname", None)
142 "either hostname option or OSM_HOSTNAME " +
143 "environment variable needs to be specified"))
146 kwargs
= {k
: v
for k
, v
in kwargs
.items() if v
is not None}
147 # if so_port is not None:
148 # kwargs['so_port']=so_port
149 # if so_project is not None:
150 # kwargs['so_project']=so_project
151 # if ro_hostname is not None:
152 # kwargs['ro_host']=ro_hostname
153 # if ro_port is not None:
154 # kwargs['ro_port']=ro_port
155 sol005
= os
.getenv('OSM_SOL005', True)
156 # if user is not None:
157 # kwargs['user']=user
158 # if password is not None:
159 # kwargs['password']=password
160 # if project is not None:
161 # kwargs['project']=project
163 # kwargs['all_projects']=all_projects
164 # if public is not None:
165 # kwargs['public']=public
166 ctx
.obj
= client
.Client(host
=hostname
, sol005
=sol005
, **kwargs
)
167 logger
= logging
.getLogger('osmclient')
174 @cli_osm.command(name
='ns-list', short_help
='list all NS instances')
175 @click.option('--filter', default
=None,
176 help='restricts the list to the NS instances matching the filter.')
177 @click.option('--long', is_flag
=True,
178 help='get more details of the NS (project, vim, deployment status, configuration status.')
180 def ns_list(ctx
, filter, long):
181 """list all NS instances
185 --filter filterExpr Restricts the list to the NS instances matching the filter
188 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
189 concatenated using the "&" character:
192 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
193 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
194 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
196 value := scalar value
200 * zero or more occurrences
201 ? zero or one occurrence
202 [] grouping of expressions to be used with ? and *
203 "" quotation marks for marking string constants
207 "AttrName" is the name of one attribute in the data type that defines the representation
208 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
209 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
210 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
211 entries, it means that the operator "op" is applied to the attribute addressed by the last
212 <attrName> entry included in the concatenation. All simple filter expressions are combined
213 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
214 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
215 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
216 prefix". If an attribute referenced in an expression is an array, an object that contains a
217 corresponding array shall be considered to match the expression if any of the elements in the
218 array matches all expressions that have the same attribute prefix.
222 --filter admin-status=ENABLED
223 --filter nsd-ref=<NSD_NAME>
224 --filter nsd.vendor=<VENDOR>
225 --filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME>
226 --filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME>
228 def summarize_deployment_status(status_dict
):
233 net_list
= status_dict
.get('nets',[])
236 if net
['status'] not in status_nets
:
237 status_nets
[net
['status']] = 1
239 status_nets
[net
['status']] +=1
241 for k
,v
in status_nets
.items():
242 message
+= "{}:{},".format(k
,v
)
243 message
+= "TOTAL:{}".format(n_nets
)
244 summary
+= "{}".format(message
)
249 vnf_list
= status_dict
['vnfs']
251 member_vnf_index
= vnf
['member_vnf_index']
252 if member_vnf_index
not in status_vnfs
:
253 status_vnfs
[member_vnf_index
] = {}
254 for vm
in vnf
['vms']:
256 if vm
['status'] not in status_vms
:
257 status_vms
[vm
['status']] = 1
259 status_vms
[vm
['status']] +=1
260 if vm
['status'] not in status_vnfs
[member_vnf_index
]:
261 status_vnfs
[member_vnf_index
][vm
['status']] = 1
263 status_vnfs
[member_vnf_index
][vm
['status']] += 1
265 for k
,v
in status_vms
.items():
266 message
+= "{}:{},".format(k
,v
)
267 message
+= "TOTAL:{}".format(n_vms
)
268 summary
+= "\n{}".format(message
)
270 for k
,v
in status_vnfs
.items():
272 message
= "\n {} VMs: ".format(k
)
273 for k2
,v2
in v
.items():
274 message
+= "{}:{},".format(k2
,v2
)
276 message
+= "TOTAL:{}".format(total
)
280 def summarize_config_status(ee_list
):
285 if ee
['elementType'] not in status_ee
:
286 status_ee
[ee
['elementType']] = {}
287 status_ee
[ee
['elementType']][ee
['status']] = 1
289 if ee
['status'] in status_ee
[ee
['elementType']]:
290 status_ee
[ee
['elementType']][ee
['status']] += 1
292 status_ee
[ee
['elementType']][ee
['status']] = 1
294 for elementType
in ["KDU", "VDU", "PDU", "VNF", "NS"]:
295 if elementType
in status_ee
:
298 for k
,v
in status_ee
[elementType
].items():
299 message
+= "{}:{},".format(k
,v
)
301 message
+= "TOTAL:{}\n".format(total
)
302 summary
+= "{}: {}".format(elementType
, message
)
303 summary
+= "TOTAL Exec. Env.: {}".format(n_ee
)
307 check_client_version(ctx
.obj
, '--filter')
308 resp
= ctx
.obj
.ns
.list(filter)
310 resp
= ctx
.obj
.ns
.list()
322 'configuration status'])
323 project_list
= ctx
.obj
.project
.list()
324 vim_list
= ctx
.obj
.vim
.list()
334 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
335 if fullclassname
== 'osmclient.sol005.client.Client':
337 nsr_name
= nsr
['name']
339 date
= datetime
.fromtimestamp(nsr
['create-time']).strftime("%Y-%m-%dT%H:%M:%S")
340 ns_state
= nsr
['nsState']
342 deployment_status
= summarize_deployment_status(nsr
['deploymentStatus'])
343 config_status
= summarize_config_status(nsr
['configurationStatus'])
344 project_id
= nsr
.get('_admin').get('projects_read')[0]
346 for p
in project_list
:
347 if p
['_id'] == project_id
:
348 project_name
= p
['name']
350 #project = '{} ({})'.format(project_name, project_id)
351 project
= project_name
352 vim_id
= nsr
.get('datacenter')
355 if v
['uuid'] == vim_id
:
358 #vim = '{} ({})'.format(vim_name, vim_id)
360 current_operation
= "{} ({})".format(nsr
['currentOperation'],nsr
['currentOperationID'])
361 error_details
= "N/A"
362 if ns_state
== "BROKEN" or ns_state
== "DEGRADED" or nsr
['errorDescription']:
363 error_details
= "{}\nDetail: {}".format(nsr
['errorDescription'], nsr
['errorDetail'])
365 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
366 nsr
= nsopdata
['nsr:nsr']
367 nsr_name
= nsr
['name-ref']
368 nsr_id
= nsr
['ns-instance-config-ref']
371 deployment_status
= nsr
['operational-status'] if 'operational-status' in nsr
else 'Not found'
372 ns_state
= deployment_status
373 config_status
= nsr
.get('config-status', 'Not found')
374 current_operation
= "Unknown"
375 error_details
= nsr
.get('detailed-status', 'Not found')
376 if config_status
== "config_not_needed":
377 config_status
= "configured (no charms)"
386 wrap_text(text
=error_details
,width
=40),
398 wrap_text(text
=error_details
,width
=40)])
401 print('To get the history of all operations over a NS, run "osm ns-op-list NS_ID"')
402 print('For more details on the current operation, run "osm ns-op-show OPERATION_ID"')
404 def nsd_list(ctx
, filter, long):
407 check_client_version(ctx
.obj
, '--filter')
408 resp
= ctx
.obj
.nsd
.list(filter)
410 resp
= ctx
.obj
.nsd
.list()
411 # print(yaml.safe_dump(resp))
412 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
413 if fullclassname
== 'osmclient.sol005.client.Client':
415 table
= PrettyTable(['nsd name', 'id', 'onboarding state', 'operational state',
416 'usage state', 'date', 'last update'])
418 table
= PrettyTable(['nsd name', 'id'])
420 name
= nsd
.get('name','-')
422 onb_state
= nsd
['_admin'].get('onboardingState','-')
423 op_state
= nsd
['_admin'].get('operationalState','-')
424 usage_state
= nsd
['_admin'].get('usageState','-')
425 date
= datetime
.fromtimestamp(nsd
['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S")
426 last_update
= datetime
.fromtimestamp(nsd
['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S")
427 table
.add_row([name
, nsd
['_id'], onb_state
, op_state
, usage_state
, date
, last_update
])
429 table
.add_row([name
, nsd
['_id']])
431 table
= PrettyTable(['nsd name', 'id'])
433 table
.add_row([nsd
['name'], nsd
['id']])
438 @cli_osm.command(name
='nsd-list', short_help
='list all NS packages')
439 @click.option('--filter', default
=None,
440 help='restricts the list to the NSD/NSpkg matching the filter')
441 @click.option('--long', is_flag
=True, help='get more details')
443 def nsd_list1(ctx
, filter, long):
444 """list all NSD/NS pkg in the system"""
446 nsd_list(ctx
, filter, long)
449 @cli_osm.command(name
='nspkg-list', short_help
='list all NS packages')
450 @click.option('--filter', default
=None,
451 help='restricts the list to the NSD/NSpkg matching the filter')
452 @click.option('--long', is_flag
=True, help='get more details')
454 def nsd_list2(ctx
, filter, long):
455 """list all NS packages"""
457 nsd_list(ctx
, filter, long)
460 def vnfd_list(ctx
, nf_type
, filter, long):
463 check_client_version(ctx
.obj
, '--nf_type')
465 check_client_version(ctx
.obj
, '--filter')
468 nf_filter
= "_admin.type=vnfd"
469 elif nf_type
== "pnf":
470 nf_filter
= "_admin.type=pnfd"
471 elif nf_type
== "hnf":
472 nf_filter
= "_admin.type=hnfd"
474 raise ClientException('wrong value for "--nf_type" option, allowed values: vnf, pnf, hnf')
476 filter = '{}&{}'.format(nf_filter
, filter)
480 resp
= ctx
.obj
.vnfd
.list(filter)
482 resp
= ctx
.obj
.vnfd
.list()
483 # print(yaml.safe_dump(resp))
484 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
485 if fullclassname
== 'osmclient.sol005.client.Client':
487 table
= PrettyTable(['nfpkg name', 'id', 'onboarding state', 'operational state',
488 'usage state', 'date', 'last update'])
490 table
= PrettyTable(['nfpkg name', 'id'])
492 name
= vnfd
['name'] if 'name' in vnfd
else '-'
494 onb_state
= vnfd
['_admin'].get('onboardingState','-')
495 op_state
= vnfd
['_admin'].get('operationalState','-')
496 usage_state
= vnfd
['_admin'].get('usageState','-')
497 date
= datetime
.fromtimestamp(vnfd
['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S")
498 last_update
= datetime
.fromtimestamp(vnfd
['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S")
499 table
.add_row([name
, vnfd
['_id'], onb_state
, op_state
, usage_state
, date
, last_update
])
501 table
.add_row([name
, vnfd
['_id']])
503 table
= PrettyTable(['nfpkg name', 'id'])
505 table
.add_row([vnfd
['name'], vnfd
['id']])
510 @cli_osm.command(name
='vnfd-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
511 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
512 @click.option('--filter', default
=None,
513 help='restricts the list to the NF pkg matching the filter')
514 @click.option('--long', is_flag
=True, help='get more details')
516 def vnfd_list1(ctx
, nf_type
, filter, long):
517 """list all xNF packages (VNF, HNF, PNF)"""
519 vnfd_list(ctx
, nf_type
, filter, long)
522 @cli_osm.command(name
='vnfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
523 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
524 @click.option('--filter', default
=None,
525 help='restricts the list to the NFpkg matching the filter')
526 @click.option('--long', is_flag
=True, help='get more details')
528 def vnfd_list2(ctx
, nf_type
, filter, long):
529 """list all xNF packages (VNF, HNF, PNF)"""
531 vnfd_list(ctx
, nf_type
, filter, long)
534 @cli_osm.command(name
='nfpkg-list', short_help
='list all xNF packages (VNF, HNF, PNF)')
535 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
536 @click.option('--filter', default
=None,
537 help='restricts the list to the NFpkg matching the filter')
538 @click.option('--long', is_flag
=True, help='get more details')
540 def nfpkg_list(ctx
, nf_type
, filter, long):
541 """list all xNF packages (VNF, HNF, PNF)"""
544 check_client_version(ctx
.obj
, ctx
.command
.name
)
545 vnfd_list(ctx
, nf_type
, filter, long)
546 # except ClientException as e:
551 def vnf_list(ctx
, ns
, filter, long):
555 check_client_version(ctx
.obj
, '--ns')
557 check_client_version(ctx
.obj
, '--filter')
558 resp
= ctx
.obj
.vnf
.list(ns
, filter)
560 resp
= ctx
.obj
.vnf
.list()
561 # except ClientException as e:
564 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
565 if fullclassname
== 'osmclient.sol005.client.Client':
566 field_names
= ['vnf id', 'name', 'ns id', 'vnf member index',
567 'vnfd name', 'vim account id', 'ip address']
569 field_names
= ['vnf id', 'name', 'ns id', 'vnf member index',
570 'vnfd name', 'vim account id', 'ip address',
571 'date', 'last update']
572 table
= PrettyTable(field_names
)
574 name
= vnfr
['name'] if 'name' in vnfr
else '-'
575 new_row
= [vnfr
['_id'], name
, vnfr
['nsr-id-ref'],
576 vnfr
['member-vnf-index-ref'], vnfr
['vnfd-ref'],
577 vnfr
['vim-account-id'], vnfr
['ip-address']]
579 date
= datetime
.fromtimestamp(vnfr
['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S")
580 last_update
= datetime
.fromtimestamp(vnfr
['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S")
581 new_row
.extend([date
, last_update
])
582 table
.add_row(new_row
)
587 'operational status',
590 if 'mgmt-interface' not in vnfr
:
591 vnfr
['mgmt-interface'] = {}
592 vnfr
['mgmt-interface']['ip-address'] = None
596 vnfr
['operational-status'],
597 vnfr
['config-status']])
602 @cli_osm.command(name
='vnf-list', short_help
='list all NF instances')
603 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
604 @click.option('--filter', default
=None,
605 help='restricts the list to the NF instances matching the filter.')
606 @click.option('--long', is_flag
=True, help='get more details')
608 def vnf_list1(ctx
, ns
, filter, long):
609 """list all NF instances"""
611 vnf_list(ctx
, ns
, filter, long)
614 @cli_osm.command(name
='nf-list', short_help
='list all NF instances')
615 @click.option('--ns', default
=None, help='NS instance id or name to restrict the NF list')
616 @click.option('--filter', default
=None,
617 help='restricts the list to the NF instances matching the filter.')
618 @click.option('--long', is_flag
=True, help='get more details')
620 def nf_list(ctx
, ns
, filter, long):
621 """list all NF instances
625 --ns TEXT NS instance id or name to restrict the VNF list
626 --filter filterExpr Restricts the list to the VNF instances matching the filter
629 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
630 concatenated using the "&" character:
633 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
634 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
635 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
637 value := scalar value
641 * zero or more occurrences
642 ? zero or one occurrence
643 [] grouping of expressions to be used with ? and *
644 "" quotation marks for marking string constants
648 "AttrName" is the name of one attribute in the data type that defines the representation
649 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
650 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
651 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
652 entries, it means that the operator "op" is applied to the attribute addressed by the last
653 <attrName> entry included in the concatenation. All simple filter expressions are combined
654 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
655 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
656 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
657 prefix". If an attribute referenced in an expression is an array, an object that contains a
658 corresponding array shall be considered to match the expression if any of the elements in the
659 array matches all expressions that have the same attribute prefix.
663 --filter vim-account-id=<VIM_ACCOUNT_ID>
664 --filter vnfd-ref=<VNFD_NAME>
665 --filter vdur.ip-address=<IP_ADDRESS>
666 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
669 vnf_list(ctx
, ns
, filter)
672 @cli_osm.command(name
='ns-op-list', short_help
='shows the history of operations over a NS instance')
673 @click.argument('name')
674 @click.option('--long', is_flag
=True,
675 help='get more details of the NS operation (date, ).')
677 def ns_op_list(ctx
, name
, long):
678 """shows the history of operations over a NS instance
680 NAME: name or ID of the NS instance
682 def formatParams(params
):
683 if params
['lcmOperationType']=='instantiate':
684 params
.pop('nsDescription')
688 elif params
['lcmOperationType']=='action':
689 params
.pop('primitive')
690 params
.pop('lcmOperationType')
691 params
.pop('nsInstanceId')
696 check_client_version(ctx
.obj
, ctx
.command
.name
)
697 resp
= ctx
.obj
.ns
.list_op(name
)
698 # except ClientException as e:
703 table
= PrettyTable(['id', 'operation', 'action_name', 'operation_params', 'status', 'date', 'last update', 'detail'])
705 table
= PrettyTable(['id', 'operation', 'action_name', 'status', 'date', 'detail'])
707 #print(yaml.safe_dump(resp))
710 if op
['lcmOperationType']=='action':
711 action_name
= op
['operationParams']['primitive']
713 if op
['operationState']=='PROCESSING':
714 if op
['lcmOperationType'] in ('instantiate', 'terminate'):
718 detail
= "In queue. Current position: {}".format(op
['queuePosition'])
719 elif op
['operationState'] in ('FAILED', 'FAILED_TEMP'):
720 detail
= op
.get('errorMessage','-')
721 date
= datetime
.fromtimestamp(op
['startTime']).strftime("%Y-%m-%dT%H:%M:%S")
722 last_update
= datetime
.fromtimestamp(op
['statusEnteredTime']).strftime("%Y-%m-%dT%H:%M:%S")
724 table
.add_row([op
['id'],
725 op
['lcmOperationType'],
727 wrap_text(text
=json
.dumps(formatParams(op
['operationParams']),indent
=2),width
=50),
728 op
['operationState'],
731 wrap_text(text
=detail
,width
=50)])
733 table
.add_row([op
['id'], op
['lcmOperationType'], action_name
,
734 op
['operationState'], date
, wrap_text(text
=detail
or "",width
=50)])
739 def nsi_list(ctx
, filter):
740 """list all Network Slice Instances"""
743 check_client_version(ctx
.obj
, ctx
.command
.name
)
744 resp
= ctx
.obj
.nsi
.list(filter)
745 # except ClientException as e:
749 ['netslice instance name',
751 'operational status',
755 nsi_name
= nsi
['name']
757 opstatus
= nsi
['operational-status'] if 'operational-status' in nsi
else 'Not found'
758 configstatus
= nsi
['config-status'] if 'config-status' in nsi
else 'Not found'
759 detailed_status
= nsi
['detailed-status'] if 'detailed-status' in nsi
else 'Not found'
760 if configstatus
== "config_not_needed":
761 configstatus
= "configured (no charms)"
772 @cli_osm.command(name
='nsi-list', short_help
='list all Network Slice Instances (NSI)')
773 @click.option('--filter', default
=None,
774 help='restricts the list to the Network Slice Instances matching the filter')
776 def nsi_list1(ctx
, filter):
777 """list all Network Slice Instances (NSI)"""
779 nsi_list(ctx
, filter)
782 @cli_osm.command(name
='netslice-instance-list', short_help
='list all Network Slice Instances (NSI)')
783 @click.option('--filter', default
=None,
784 help='restricts the list to the Network Slice Instances matching the filter')
786 def nsi_list2(ctx
, filter):
787 """list all Network Slice Instances (NSI)"""
789 nsi_list(ctx
, filter)
792 def nst_list(ctx
, filter):
795 check_client_version(ctx
.obj
, ctx
.command
.name
)
796 resp
= ctx
.obj
.nst
.list(filter)
797 # except ClientException as e:
800 # print(yaml.safe_dump(resp))
801 table
= PrettyTable(['nst name', 'id'])
803 name
= nst
['name'] if 'name' in nst
else '-'
804 table
.add_row([name
, nst
['_id']])
809 @cli_osm.command(name
='nst-list', short_help
='list all Network Slice Templates (NST)')
810 @click.option('--filter', default
=None,
811 help='restricts the list to the NST matching the filter')
813 def nst_list1(ctx
, filter):
814 """list all Network Slice Templates (NST) in the system"""
816 nst_list(ctx
, filter)
819 @cli_osm.command(name
='netslice-template-list', short_help
='list all Network Slice Templates (NST)')
820 @click.option('--filter', default
=None,
821 help='restricts the list to the NST matching the filter')
823 def nst_list2(ctx
, filter):
824 """list all Network Slice Templates (NST) in the system"""
826 nst_list(ctx
, filter)
829 def nsi_op_list(ctx
, name
):
832 check_client_version(ctx
.obj
, ctx
.command
.name
)
833 resp
= ctx
.obj
.nsi
.list_op(name
)
834 # except ClientException as e:
837 table
= PrettyTable(['id', 'operation', 'status'])
839 table
.add_row([op
['id'], op
['lcmOperationType'],
840 op
['operationState']])
845 @cli_osm.command(name
='nsi-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
846 @click.argument('name')
848 def nsi_op_list1(ctx
, name
):
849 """shows the history of operations over a Network Slice Instance (NSI)
851 NAME: name or ID of the Network Slice Instance
854 nsi_op_list(ctx
, name
)
857 @cli_osm.command(name
='netslice-instance-op-list', short_help
='shows the history of operations over a Network Slice Instance (NSI)')
858 @click.argument('name')
860 def nsi_op_list2(ctx
, name
):
861 """shows the history of operations over a Network Slice Instance (NSI)
863 NAME: name or ID of the Network Slice Instance
866 nsi_op_list(ctx
, name
)
869 @cli_osm.command(name
='pdu-list', short_help
='list all Physical Deployment Units (PDU)')
870 @click.option('--filter', default
=None,
871 help='restricts the list to the Physical Deployment Units matching the filter')
873 def pdu_list(ctx
, filter):
874 """list all Physical Deployment Units (PDU)"""
877 check_client_version(ctx
.obj
, ctx
.command
.name
)
878 resp
= ctx
.obj
.pdu
.list(filter)
879 # except ClientException as e:
888 pdu_name
= pdu
['name']
890 pdu_type
= pdu
['type']
891 pdu_ipaddress
= "None"
892 for iface
in pdu
['interfaces']:
894 pdu_ipaddress
= iface
['ip-address']
909 def nsd_show(ctx
, name
, literal
):
912 resp
= ctx
.obj
.nsd
.get(name
)
913 # resp = ctx.obj.nsd.get_individual(name)
914 # except ClientException as e:
919 print(yaml
.safe_dump(resp
))
922 table
= PrettyTable(['field', 'value'])
923 for k
, v
in list(resp
.items()):
924 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
929 @cli_osm.command(name
='nsd-show', short_help
='shows the content of a NSD')
930 @click.option('--literal', is_flag
=True,
931 help='print literally, no pretty table')
932 @click.argument('name')
934 def nsd_show1(ctx
, name
, literal
):
935 """shows the content of a NSD
937 NAME: name or ID of the NSD/NSpkg
940 nsd_show(ctx
, name
, literal
)
943 @cli_osm.command(name
='nspkg-show', short_help
='shows the content of a NSD')
944 @click.option('--literal', is_flag
=True,
945 help='print literally, no pretty table')
946 @click.argument('name')
948 def nsd_show2(ctx
, name
, literal
):
949 """shows the content of a NSD
951 NAME: name or ID of the NSD/NSpkg
954 nsd_show(ctx
, name
, literal
)
957 def vnfd_show(ctx
, name
, literal
):
960 resp
= ctx
.obj
.vnfd
.get(name
)
961 # resp = ctx.obj.vnfd.get_individual(name)
962 # except ClientException as e:
967 print(yaml
.safe_dump(resp
))
970 table
= PrettyTable(['field', 'value'])
971 for k
, v
in list(resp
.items()):
972 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
977 @cli_osm.command(name
='vnfd-show', short_help
='shows the content of a VNFD')
978 @click.option('--literal', is_flag
=True,
979 help='print literally, no pretty table')
980 @click.argument('name')
982 def vnfd_show1(ctx
, name
, literal
):
983 """shows the content of a VNFD
985 NAME: name or ID of the VNFD/VNFpkg
988 vnfd_show(ctx
, name
, literal
)
991 @cli_osm.command(name
='vnfpkg-show', short_help
='shows the content of a VNFD')
992 @click.option('--literal', is_flag
=True,
993 help='print literally, no pretty table')
994 @click.argument('name')
996 def vnfd_show2(ctx
, name
, literal
):
997 """shows the content of a VNFD
999 NAME: name or ID of the VNFD/VNFpkg
1002 vnfd_show(ctx
, name
, literal
)
1005 @cli_osm.command(name
='nfpkg-show', short_help
='shows the content of a NF Descriptor')
1006 @click.option('--literal', is_flag
=True,
1007 help='print literally, no pretty table')
1008 @click.argument('name')
1010 def nfpkg_show(ctx
, name
, literal
):
1011 """shows the content of a NF Descriptor
1013 NAME: name or ID of the NFpkg
1016 vnfd_show(ctx
, name
, literal
)
1019 @cli_osm.command(name
='ns-show', short_help
='shows the info of a NS instance')
1020 @click.argument('name')
1021 @click.option('--literal', is_flag
=True,
1022 help='print literally, no pretty table')
1023 @click.option('--filter', default
=None)
1025 def ns_show(ctx
, name
, literal
, filter):
1026 """shows the info of a NS instance
1028 NAME: name or ID of the NS instance
1032 ns
= ctx
.obj
.ns
.get(name
)
1033 # except ClientException as e:
1038 print(yaml
.safe_dump(ns
))
1041 table
= PrettyTable(['field', 'value'])
1043 for k
, v
in list(ns
.items()):
1044 if filter is None or filter in k
:
1045 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
1047 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1048 if fullclassname
!= 'osmclient.sol005.client.Client':
1049 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
1050 nsr_optdata
= nsopdata
['nsr:nsr']
1051 for k
, v
in list(nsr_optdata
.items()):
1052 if filter is None or filter in k
:
1053 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2),width
=100)])
1058 @cli_osm.command(name
='vnf-show', short_help
='shows the info of a VNF instance')
1059 @click.argument('name')
1060 @click.option('--literal', is_flag
=True,
1061 help='print literally, no pretty table')
1062 @click.option('--filter', default
=None, help='restricts the information to the fields in the filter')
1063 @click.option('--kdu', default
=None, help='KDU name (whose status will be shown)')
1065 def vnf_show(ctx
, name
, literal
, filter, kdu
):
1066 """shows the info of a VNF instance
1068 NAME: name or ID of the VNF instance
1070 def print_kdu_status(op_info_status
):
1071 """print KDU status properly formatted
1074 op_status
= yaml
.safe_load(op_info_status
)
1075 if "namespace" in op_status
and "info" in op_status
and \
1076 "last_deployed" in op_status
["info"] and "status" in op_status
["info"] and \
1077 "code" in op_status
["info"]["status"] and "resources" in op_status
["info"]["status"] and \
1078 "seconds" in op_status
["info"]["last_deployed"]:
1079 last_deployed_time
= datetime
.fromtimestamp(op_status
["info"]["last_deployed"]["seconds"]).strftime("%a %b %d %I:%M:%S %Y")
1080 print("LAST DEPLOYED: {}".format(last_deployed_time
))
1081 print("NAMESPACE: {}".format(op_status
["namespace"]))
1082 status_code
= "UNKNOWN"
1083 if op_status
["info"]["status"]["code"]==1:
1084 status_code
= "DEPLOYED"
1085 print("STATUS: {}".format(status_code
))
1088 print(op_status
["info"]["status"]["resources"])
1089 if "notes" in op_status
["info"]["status"]:
1091 print(op_status
["info"]["status"]["notes"])
1093 print(op_info_status
)
1095 print(op_info_status
)
1100 raise ClientException('"--literal" option is incompatible with "--kdu" option')
1102 raise ClientException('"--filter" option is incompatible with "--kdu" option')
1105 check_client_version(ctx
.obj
, ctx
.command
.name
)
1106 resp
= ctx
.obj
.vnf
.get(name
)
1109 ns_id
= resp
['nsr-id-ref']
1111 op_data
['member_vnf_index'] = resp
['member-vnf-index-ref']
1112 op_data
['kdu_name'] = kdu
1113 op_data
['primitive'] = 'status'
1114 op_data
['primitive_params'] = {}
1115 op_id
= ctx
.obj
.ns
.exec_op(ns_id
, op_name
='action', op_data
=op_data
, wait
=False)
1118 op_info
= ctx
.obj
.ns
.get_op(op_id
)
1119 if op_info
['operationState'] == 'COMPLETED':
1120 print_kdu_status(op_info
['detailed-status'])
1124 print ("Could not determine KDU status")
1127 print(yaml
.safe_dump(resp
))
1130 table
= PrettyTable(['field', 'value'])
1132 for k
, v
in list(resp
.items()):
1133 if filter is None or filter in k
:
1134 table
.add_row([k
, wrap_text(text
=json
.dumps(v
,indent
=2),width
=100)])
1137 # except ClientException as e:
1142 #@cli_osm.command(name='vnf-monitoring-show')
1143 #@click.argument('vnf_name')
1144 #@click.pass_context
1145 #def vnf_monitoring_show(ctx, vnf_name):
1147 # check_client_version(ctx.obj, ctx.command.name, 'v1')
1148 # resp = ctx.obj.vnf.get_monitoring(vnf_name)
1149 # except ClientException as e:
1153 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
1154 # if resp is not None:
1155 # for monitor in resp:
1159 # monitor['value-integer'],
1160 # monitor['units']])
1165 #@cli_osm.command(name='ns-monitoring-show')
1166 #@click.argument('ns_name')
1167 #@click.pass_context
1168 #def ns_monitoring_show(ctx, ns_name):
1170 # check_client_version(ctx.obj, ctx.command.name, 'v1')
1171 # resp = ctx.obj.ns.get_monitoring(ns_name)
1172 # except ClientException as e:
1176 # table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
1177 # for key, val in list(resp.items()):
1178 # for monitor in val:
1182 # monitor['value-integer'],
1183 # monitor['units']])
1188 @cli_osm.command(name
='ns-op-show', short_help
='shows the info of a NS operation')
1189 @click.argument('id')
1190 @click.option('--filter', default
=None)
1191 @click.option('--literal', is_flag
=True,
1192 help='print literally, no pretty table')
1194 def ns_op_show(ctx
, id, filter, literal
):
1195 """shows the detailed info of a NS operation
1197 ID: operation identifier
1201 check_client_version(ctx
.obj
, ctx
.command
.name
)
1202 op_info
= ctx
.obj
.ns
.get_op(id)
1203 # except ClientException as e:
1208 print(yaml
.safe_dump(op_info
))
1211 table
= PrettyTable(['field', 'value'])
1212 for k
, v
in list(op_info
.items()):
1213 if filter is None or filter in k
:
1214 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
1219 def nst_show(ctx
, name
, literal
):
1222 check_client_version(ctx
.obj
, ctx
.command
.name
)
1223 resp
= ctx
.obj
.nst
.get(name
)
1224 #resp = ctx.obj.nst.get_individual(name)
1225 # except ClientException as e:
1230 print(yaml
.safe_dump(resp
))
1233 table
= PrettyTable(['field', 'value'])
1234 for k
, v
in list(resp
.items()):
1235 table
.add_row([k
, wrap_text(json
.dumps(v
, indent
=2), 100)])
1240 @cli_osm.command(name
='nst-show', short_help
='shows the content of a Network Slice Template (NST)')
1241 @click.option('--literal', is_flag
=True,
1242 help='print literally, no pretty table')
1243 @click.argument('name')
1245 def nst_show1(ctx
, name
, literal
):
1246 """shows the content of a Network Slice Template (NST)
1248 NAME: name or ID of the NST
1251 nst_show(ctx
, name
, literal
)
1254 @cli_osm.command(name
='netslice-template-show', short_help
='shows the content of a Network Slice Template (NST)')
1255 @click.option('--literal', is_flag
=True,
1256 help='print literally, no pretty table')
1257 @click.argument('name')
1259 def nst_show2(ctx
, name
, literal
):
1260 """shows the content of a Network Slice Template (NST)
1262 NAME: name or ID of the NST
1265 nst_show(ctx
, name
, literal
)
1268 def nsi_show(ctx
, name
, literal
, filter):
1271 check_client_version(ctx
.obj
, ctx
.command
.name
)
1272 nsi
= ctx
.obj
.nsi
.get(name
)
1273 # except ClientException as e:
1278 print(yaml
.safe_dump(nsi
))
1281 table
= PrettyTable(['field', 'value'])
1283 for k
, v
in list(nsi
.items()):
1284 if filter is None or filter in k
:
1285 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1291 @cli_osm.command(name
='nsi-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1292 @click.argument('name')
1293 @click.option('--literal', is_flag
=True,
1294 help='print literally, no pretty table')
1295 @click.option('--filter', default
=None)
1297 def nsi_show1(ctx
, name
, literal
, filter):
1298 """shows the content of a Network Slice Instance (NSI)
1300 NAME: name or ID of the Network Slice Instance
1303 nsi_show(ctx
, name
, literal
, filter)
1306 @cli_osm.command(name
='netslice-instance-show', short_help
='shows the content of a Network Slice Instance (NSI)')
1307 @click.argument('name')
1308 @click.option('--literal', is_flag
=True,
1309 help='print literally, no pretty table')
1310 @click.option('--filter', default
=None)
1312 def nsi_show2(ctx
, name
, literal
, filter):
1313 """shows the content of a Network Slice Instance (NSI)
1315 NAME: name or ID of the Network Slice Instance
1318 nsi_show(ctx
, name
, literal
, filter)
1321 def nsi_op_show(ctx
, id, filter):
1324 check_client_version(ctx
.obj
, ctx
.command
.name
)
1325 op_info
= ctx
.obj
.nsi
.get_op(id)
1326 # except ClientException as e:
1330 table
= PrettyTable(['field', 'value'])
1331 for k
, v
in list(op_info
.items()):
1332 if filter is None or filter in k
:
1333 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1338 @cli_osm.command(name
='nsi-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1339 @click.argument('id')
1340 @click.option('--filter', default
=None)
1342 def nsi_op_show1(ctx
, id, filter):
1343 """shows the info of an operation over a Network Slice Instance(NSI)
1345 ID: operation identifier
1348 nsi_op_show(ctx
, id, filter)
1351 @cli_osm.command(name
='netslice-instance-op-show', short_help
='shows the info of an operation over a Network Slice Instance(NSI)')
1352 @click.argument('id')
1353 @click.option('--filter', default
=None)
1355 def nsi_op_show2(ctx
, id, filter):
1356 """shows the info of an operation over a Network Slice Instance(NSI)
1358 ID: operation identifier
1361 nsi_op_show(ctx
, id, filter)
1364 @cli_osm.command(name
='pdu-show', short_help
='shows the content of a Physical Deployment Unit (PDU)')
1365 @click.argument('name')
1366 @click.option('--literal', is_flag
=True,
1367 help='print literally, no pretty table')
1368 @click.option('--filter', default
=None)
1370 def pdu_show(ctx
, name
, literal
, filter):
1371 """shows the content of a Physical Deployment Unit (PDU)
1373 NAME: name or ID of the PDU
1377 check_client_version(ctx
.obj
, ctx
.command
.name
)
1378 pdu
= ctx
.obj
.pdu
.get(name
)
1379 # except ClientException as e:
1384 print(yaml
.safe_dump(pdu
))
1387 table
= PrettyTable(['field', 'value'])
1389 for k
, v
in list(pdu
.items()):
1390 if filter is None or filter in k
:
1391 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1397 ####################
1399 ####################
1401 def nsd_create(ctx
, filename
, overwrite
, skip_charm_build
):
1404 check_client_version(ctx
.obj
, ctx
.command
.name
)
1405 ctx
.obj
.nsd
.create(filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
)
1406 # except ClientException as e:
1411 @cli_osm.command(name
='nsd-create', short_help
='creates a new NSD/NSpkg')
1412 @click.argument('filename')
1413 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1414 help='Deprecated. Use override')
1415 @click.option('--override', 'overwrite', default
=None,
1416 help='overrides fields in descriptor, format: '
1417 '"key1.key2...=value[;key3...=value;...]"')
1418 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1419 help='The charm will not be compiled, it is assumed to already exist')
1421 def nsd_create1(ctx
, filename
, overwrite
, skip_charm_build
):
1422 """creates a new NSD/NSpkg
1424 FILENAME: NSD yaml file or NSpkg tar.gz file
1427 nsd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
)
1430 @cli_osm.command(name
='nspkg-create', short_help
='creates a new NSD/NSpkg')
1431 @click.argument('filename')
1432 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1433 help='Deprecated. Use override')
1434 @click.option('--override', 'overwrite', default
=None,
1435 help='overrides fields in descriptor, format: '
1436 '"key1.key2...=value[;key3...=value;...]"')
1437 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1438 help='The charm will not be compiled, it is assumed to already exist')
1440 def nsd_create2(ctx
, filename
, overwrite
, skip_charm_build
):
1441 """creates a new NSD/NSpkg
1443 FILENAME: NSD folder, NSD yaml file or NSpkg tar.gz file
1446 nsd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
)
1449 def vnfd_create(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1452 check_client_version(ctx
.obj
, ctx
.command
.name
)
1453 ctx
.obj
.vnfd
.create(filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1454 override_epa
=override_epa
, override_nonepa
=override_nonepa
,
1455 override_paravirt
=override_paravirt
)
1456 # except ClientException as e:
1461 @cli_osm.command(name
='vnfd-create', short_help
='creates a new VNFD/VNFpkg')
1462 @click.argument('filename')
1463 @click.option('--overwrite', 'overwrite', default
=None,
1464 help='overwrite deprecated, use override')
1465 @click.option('--override', 'overwrite', default
=None,
1466 help='overrides fields in descriptor, format: '
1467 '"key1.key2...=value[;key3...=value;...]"')
1468 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1469 help='The charm will not be compiled, it is assumed to already exist')
1470 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1471 help='adds guest-epa parameters to all VDU')
1472 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1473 help='removes all guest-epa parameters from all VDU')
1474 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1475 help='overrides all VDU interfaces to PARAVIRT')
1477 def vnfd_create1(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1478 """creates a new VNFD/VNFpkg
1480 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1483 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1484 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
)
1487 @cli_osm.command(name
='vnfpkg-create', short_help
='creates a new VNFD/VNFpkg')
1488 @click.argument('filename')
1489 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1490 help='Deprecated. Use override')
1491 @click.option('--override', 'overwrite', default
=None,
1492 help='overrides fields in descriptor, format: '
1493 '"key1.key2...=value[;key3...=value;...]"')
1494 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1495 help='The charm will not be compiled, it is assumed to already exist')
1496 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1497 help='adds guest-epa parameters to all VDU')
1498 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1499 help='removes all guest-epa parameters from all VDU')
1500 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1501 help='overrides all VDU interfaces to PARAVIRT')
1503 def vnfd_create2(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1504 """creates a new VNFD/VNFpkg
1506 FILENAME: NF Package Folder, NF Descriptor yaml file or NFpkg tar.gz file
1509 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1510 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
)
1513 @cli_osm.command(name
='nfpkg-create', short_help
='creates a new NFpkg')
1514 @click.argument('filename')
1515 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1516 help='Deprecated. Use override')
1517 @click.option('--override', 'overwrite', default
=None,
1518 help='overrides fields in descriptor, format: '
1519 '"key1.key2...=value[;key3...=value;...]"')
1520 @click.option('--skip-charm-build', default
=False, is_flag
=True,
1521 help='The charm will not be compiled, it is assumed to already exist')
1522 @click.option('--override-epa', required
=False, default
=False, is_flag
=True,
1523 help='adds guest-epa parameters to all VDU')
1524 @click.option('--override-nonepa', required
=False, default
=False, is_flag
=True,
1525 help='removes all guest-epa parameters from all VDU')
1526 @click.option('--override-paravirt', required
=False, default
=False, is_flag
=True,
1527 help='overrides all VDU interfaces to PARAVIRT')
1529 def nfpkg_create(ctx
, filename
, overwrite
, skip_charm_build
, override_epa
, override_nonepa
, override_paravirt
):
1530 """creates a new NFpkg
1532 FILENAME: NF Package Folder, NF Descriptor yaml file or NFpkg tar.gz filems to build
1535 vnfd_create(ctx
, filename
, overwrite
=overwrite
, skip_charm_build
=skip_charm_build
,
1536 override_epa
=override_epa
, override_nonepa
=override_nonepa
, override_paravirt
=override_paravirt
)
1539 @cli_osm.command(name
='ns-create', short_help
='creates a new Network Service instance')
1540 @click.option('--ns_name',
1541 prompt
=True, help='name of the NS instance')
1542 @click.option('--nsd_name',
1543 prompt
=True, help='name of the NS descriptor')
1544 @click.option('--vim_account',
1545 prompt
=True, help='default VIM account id or name for the deployment')
1546 @click.option('--admin_status',
1548 help='administration status')
1549 @click.option('--ssh_keys',
1551 help='comma separated list of public key files to inject to vnfs')
1552 @click.option('--config',
1554 help='ns specific yaml configuration')
1555 @click.option('--config_file',
1557 help='ns specific yaml configuration file')
1558 @click.option('--wait',
1562 help='do not return the control immediately, but keep it '
1563 'until the operation is completed, or timeout')
1574 """creates a new NS instance"""
1578 check_client_version(ctx
.obj
, '--config_file')
1580 raise ClientException('"--config" option is incompatible with "--config_file" option')
1581 with
open(config_file
, 'r') as cf
:
1588 account
=vim_account
,
1590 # except ClientException as e:
1595 def nst_create(ctx
, filename
, overwrite
):
1598 check_client_version(ctx
.obj
, ctx
.command
.name
)
1599 ctx
.obj
.nst
.create(filename
, overwrite
)
1600 # except ClientException as e:
1605 @cli_osm.command(name
='nst-create', short_help
='creates a new Network Slice Template (NST)')
1606 @click.argument('filename')
1607 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1608 help='Deprecated. Use override')
1609 @click.option('--override', 'overwrite', default
=None,
1610 help='overrides fields in descriptor, format: '
1611 '"key1.key2...=value[;key3...=value;...]"')
1613 def nst_create1(ctx
, charm_folder
, overwrite
):
1614 """creates a new Network Slice Template (NST)
1616 FILENAME: NST package folder, NST yaml file or NSTpkg tar.gz file
1619 nst_create(ctx
, charm_folder
, overwrite
)
1622 @cli_osm.command(name
='netslice-template-create', short_help
='creates a new Network Slice Template (NST)')
1623 @click.argument('filename')
1624 @click.option('--overwrite', 'overwrite', default
=None, # hidden=True,
1625 help='Deprecated. Use override')
1626 @click.option('--override', 'overwrite', default
=None,
1627 help='overrides fields in descriptor, format: '
1628 '"key1.key2...=value[;key3...=value;...]"')
1630 def nst_create2(ctx
, filename
, overwrite
):
1631 """creates a new Network Slice Template (NST)
1633 FILENAME: NST yaml file or NSTpkg tar.gz file
1636 nst_create(ctx
, filename
, overwrite
)
1639 def nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1640 """creates a new Network Slice Instance (NSI)"""
1643 check_client_version(ctx
.obj
, ctx
.command
.name
)
1646 raise ClientException('"--config" option is incompatible with "--config_file" option')
1647 with
open(config_file
, 'r') as cf
:
1649 ctx
.obj
.nsi
.create(nst_name
, nsi_name
, config
=config
, ssh_keys
=ssh_keys
,
1650 account
=vim_account
, wait
=wait
)
1651 # except ClientException as e:
1656 @cli_osm.command(name
='nsi-create', short_help
='creates a new Network Slice Instance')
1657 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1658 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1659 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1660 @click.option('--ssh_keys', default
=None,
1661 help='comma separated list of keys to inject to vnfs')
1662 @click.option('--config', default
=None,
1663 help='Netslice specific yaml configuration:\n'
1664 'netslice_subnet: [\n'
1665 'id: TEXT, vim_account: TEXT,\n'
1666 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1667 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]\n'
1668 'additionalParamsForNsi: {param: value, ...}\n'
1669 'additionalParamsForsubnet: [{id: SUBNET_ID, additionalParamsForNs: {}, additionalParamsForVnf: {}}]\n'
1671 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1673 @click.option('--config_file',
1675 help='nsi specific yaml configuration file')
1676 @click.option('--wait',
1680 help='do not return the control immediately, but keep it '
1681 'until the operation is completed, or timeout')
1683 def nsi_create1(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1684 """creates a new Network Slice Instance (NSI)"""
1686 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1689 @cli_osm.command(name
='netslice-instance-create', short_help
='creates a new Network Slice Instance')
1690 @click.option('--nsi_name', prompt
=True, help='name of the Network Slice Instance')
1691 @click.option('--nst_name', prompt
=True, help='name of the Network Slice Template')
1692 @click.option('--vim_account', prompt
=True, help='default VIM account id or name for the deployment')
1693 @click.option('--ssh_keys', default
=None,
1694 help='comma separated list of keys to inject to vnfs')
1695 @click.option('--config', default
=None,
1696 help='Netslice specific yaml configuration:\n'
1697 'netslice_subnet: [\n'
1698 'id: TEXT, vim_account: TEXT,\n'
1699 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1700 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1702 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1704 @click.option('--config_file',
1706 help='nsi specific yaml configuration file')
1707 @click.option('--wait',
1711 help='do not return the control immediately, but keep it '
1712 'until the operation is completed, or timeout')
1714 def nsi_create2(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
):
1715 """creates a new Network Slice Instance (NSI)"""
1717 nsi_create(ctx
, nst_name
, nsi_name
, vim_account
, ssh_keys
, config
, config_file
, wait
=wait
)
1720 @cli_osm.command(name
='pdu-create', short_help
='adds a new Physical Deployment Unit to the catalog')
1721 @click.option('--name', help='name of the Physical Deployment Unit')
1722 @click.option('--pdu_type', help='type of PDU (e.g. router, firewall, FW001)')
1723 @click.option('--interface',
1724 help='interface(s) of the PDU: name=<NAME>,mgmt=<true|false>,ip-address=<IP_ADDRESS>'+
1725 '[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]',
1727 @click.option('--description', help='human readable description')
1728 @click.option('--vim_account', help='list of VIM accounts (in the same VIM) that can reach this PDU', multiple
=True)
1729 @click.option('--descriptor_file', default
=None,
1730 help='PDU descriptor file (as an alternative to using the other arguments')
1732 def pdu_create(ctx
, name
, pdu_type
, interface
, description
, vim_account
, descriptor_file
):
1733 """creates a new Physical Deployment Unit (PDU)"""
1736 check_client_version(ctx
.obj
, ctx
.command
.name
)
1738 if not descriptor_file
:
1740 raise ClientException('in absence of descriptor file, option "--name" is mandatory')
1742 raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory')
1744 raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)')
1746 raise ClientException('in absence of descriptor file, option "--vim_account" is mandatory (at least once)')
1748 with
open(descriptor_file
, 'r') as df
:
1749 pdu
= yaml
.safe_load(df
.read())
1750 if name
: pdu
["name"] = name
1751 if pdu_type
: pdu
["type"] = pdu_type
1752 if description
: pdu
["description"] = description
1753 if vim_account
: pdu
["vim_accounts"] = vim_account
1756 for iface
in interface
:
1757 new_iface
={k
:v
for k
,v
in [i
.split('=') for i
in iface
.split(',')]}
1758 new_iface
["mgmt"] = (new_iface
.get("mgmt","false").lower() == "true")
1759 ifaces_list
.append(new_iface
)
1760 pdu
["interfaces"] = ifaces_list
1761 ctx
.obj
.pdu
.create(pdu
)
1762 # except ClientException as e:
1767 ####################
1769 ####################
1771 def nsd_update(ctx
, name
, content
):
1774 check_client_version(ctx
.obj
, ctx
.command
.name
)
1775 ctx
.obj
.nsd
.update(name
, content
)
1776 # except ClientException as e:
1781 @cli_osm.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
1782 @click.argument('name')
1783 @click.option('--content', default
=None,
1784 help='filename with the NSD/NSpkg replacing the current one')
1786 def nsd_update1(ctx
, name
, content
):
1787 """updates a NSD/NSpkg
1789 NAME: name or ID of the NSD/NSpkg
1792 nsd_update(ctx
, name
, content
)
1795 @cli_osm.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
1796 @click.argument('name')
1797 @click.option('--content', default
=None,
1798 help='filename with the NSD/NSpkg replacing the current one')
1800 def nsd_update2(ctx
, name
, content
):
1801 """updates a NSD/NSpkg
1803 NAME: name or ID of the NSD/NSpkg
1806 nsd_update(ctx
, name
, content
)
1809 def vnfd_update(ctx
, name
, content
):
1812 check_client_version(ctx
.obj
, ctx
.command
.name
)
1813 ctx
.obj
.vnfd
.update(name
, content
)
1814 # except ClientException as e:
1819 @cli_osm.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
1820 @click.argument('name')
1821 @click.option('--content', default
=None,
1822 help='filename with the VNFD/VNFpkg replacing the current one')
1824 def vnfd_update1(ctx
, name
, content
):
1825 """updates a VNFD/VNFpkg
1827 NAME: name or ID of the VNFD/VNFpkg
1830 vnfd_update(ctx
, name
, content
)
1833 @cli_osm.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
1834 @click.argument('name')
1835 @click.option('--content', default
=None,
1836 help='filename with the VNFD/VNFpkg replacing the current one')
1838 def vnfd_update2(ctx
, name
, content
):
1839 """updates a VNFD/VNFpkg
1841 NAME: VNFD yaml file or VNFpkg tar.gz file
1844 vnfd_update(ctx
, name
, content
)
1847 @cli_osm.command(name
='nfpkg-update', short_help
='updates a NFpkg')
1848 @click.argument('name')
1849 @click.option('--content', default
=None,
1850 help='filename with the NFpkg replacing the current one')
1852 def nfpkg_update(ctx
, name
, content
):
1855 NAME: NF Descriptor yaml file or NFpkg tar.gz file
1858 vnfd_update(ctx
, name
, content
)
1861 def nst_update(ctx
, name
, content
):
1864 check_client_version(ctx
.obj
, ctx
.command
.name
)
1865 ctx
.obj
.nst
.update(name
, content
)
1866 # except ClientException as e:
1871 @cli_osm.command(name
='nst-update', short_help
='updates a Network Slice Template (NST)')
1872 @click.argument('name')
1873 @click.option('--content', default
=None,
1874 help='filename with the NST/NSTpkg replacing the current one')
1876 def nst_update1(ctx
, name
, content
):
1877 """updates a Network Slice Template (NST)
1879 NAME: name or ID of the NSD/NSpkg
1882 nst_update(ctx
, name
, content
)
1885 @cli_osm.command(name
='netslice-template-update', short_help
='updates a Network Slice Template (NST)')
1886 @click.argument('name')
1887 @click.option('--content', default
=None,
1888 help='filename with the NST/NSTpkg replacing the current one')
1890 def nst_update2(ctx
, name
, content
):
1891 """updates a Network Slice Template (NST)
1893 NAME: name or ID of the NSD/NSpkg
1896 nst_update(ctx
, name
, content
)
1899 ####################
1901 ####################
1903 def nsd_delete(ctx
, name
, force
):
1907 ctx
.obj
.nsd
.delete(name
)
1909 check_client_version(ctx
.obj
, '--force')
1910 ctx
.obj
.nsd
.delete(name
, force
)
1911 # except ClientException as e:
1916 @cli_osm.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
1917 @click.argument('name')
1918 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1920 def nsd_delete1(ctx
, name
, force
):
1921 """deletes a NSD/NSpkg
1923 NAME: name or ID of the NSD/NSpkg to be deleted
1926 nsd_delete(ctx
, name
, force
)
1929 @cli_osm.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
1930 @click.argument('name')
1931 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1933 def nsd_delete2(ctx
, name
, force
):
1934 """deletes a NSD/NSpkg
1936 NAME: name or ID of the NSD/NSpkg to be deleted
1939 nsd_delete(ctx
, name
, force
)
1942 def vnfd_delete(ctx
, name
, force
):
1946 ctx
.obj
.vnfd
.delete(name
)
1948 check_client_version(ctx
.obj
, '--force')
1949 ctx
.obj
.vnfd
.delete(name
, force
)
1950 # except ClientException as e:
1955 @cli_osm.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
1956 @click.argument('name')
1957 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1959 def vnfd_delete1(ctx
, name
, force
):
1960 """deletes a VNFD/VNFpkg
1962 NAME: name or ID of the VNFD/VNFpkg to be deleted
1965 vnfd_delete(ctx
, name
, force
)
1968 @cli_osm.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
1969 @click.argument('name')
1970 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1972 def vnfd_delete2(ctx
, name
, force
):
1973 """deletes a VNFD/VNFpkg
1975 NAME: name or ID of the VNFD/VNFpkg to be deleted
1978 vnfd_delete(ctx
, name
, force
)
1981 @cli_osm.command(name
='nfpkg-delete', short_help
='deletes a NFpkg')
1982 @click.argument('name')
1983 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1985 def nfpkg_delete(ctx
, name
, force
):
1988 NAME: name or ID of the NFpkg to be deleted
1991 vnfd_delete(ctx
, name
, force
)
1994 @cli_osm.command(name
='ns-delete', short_help
='deletes a NS instance')
1995 @click.argument('name')
1996 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1997 @click.option('--config', default
=None,
1998 help="specific yaml configuration for the termination, e.g. '{autoremove: False, timeout_ns_terminate: "
1999 "600, skip_terminate_primitives: True}'")
2000 @click.option('--wait',
2004 help='do not return the control immediately, but keep it '
2005 'until the operation is completed, or timeout')
2007 def ns_delete(ctx
, name
, force
, config
, wait
):
2008 """deletes a NS instance
2010 NAME: name or ID of the NS instance to be deleted
2015 ctx
.obj
.ns
.delete(name
, config
=config
, wait
=wait
)
2017 check_client_version(ctx
.obj
, '--force')
2018 ctx
.obj
.ns
.delete(name
, force
, config
=config
, wait
=wait
)
2019 # except ClientException as e:
2024 def nst_delete(ctx
, name
, force
):
2027 check_client_version(ctx
.obj
, ctx
.command
.name
)
2028 ctx
.obj
.nst
.delete(name
, force
)
2029 # except ClientException as e:
2034 @cli_osm.command(name
='nst-delete', short_help
='deletes a Network Slice Template (NST)')
2035 @click.argument('name')
2036 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2038 def nst_delete1(ctx
, name
, force
):
2039 """deletes a Network Slice Template (NST)
2041 NAME: name or ID of the NST/NSTpkg to be deleted
2044 nst_delete(ctx
, name
, force
)
2047 @cli_osm.command(name
='netslice-template-delete', short_help
='deletes a Network Slice Template (NST)')
2048 @click.argument('name')
2049 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2051 def nst_delete2(ctx
, name
, force
):
2052 """deletes a Network Slice Template (NST)
2054 NAME: name or ID of the NST/NSTpkg to be deleted
2057 nst_delete(ctx
, name
, force
)
2060 def nsi_delete(ctx
, name
, force
, wait
):
2063 check_client_version(ctx
.obj
, ctx
.command
.name
)
2064 ctx
.obj
.nsi
.delete(name
, force
, wait
=wait
)
2065 # except ClientException as e:
2070 @cli_osm.command(name
='nsi-delete', short_help
='deletes a Network Slice Instance (NSI)')
2071 @click.argument('name')
2072 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2073 @click.option('--wait',
2077 help='do not return the control immediately, but keep it '
2078 'until the operation is completed, or timeout')
2080 def nsi_delete1(ctx
, name
, force
, wait
):
2081 """deletes a Network Slice Instance (NSI)
2083 NAME: name or ID of the Network Slice instance to be deleted
2086 nsi_delete(ctx
, name
, force
, wait
=wait
)
2089 @cli_osm.command(name
='netslice-instance-delete', short_help
='deletes a Network Slice Instance (NSI)')
2090 @click.argument('name')
2091 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2093 def nsi_delete2(ctx
, name
, force
, wait
):
2094 """deletes a Network Slice Instance (NSI)
2096 NAME: name or ID of the Network Slice instance to be deleted
2099 nsi_delete(ctx
, name
, force
, wait
=wait
)
2102 @cli_osm.command(name
='pdu-delete', short_help
='deletes a Physical Deployment Unit (PDU)')
2103 @click.argument('name')
2104 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2106 def pdu_delete(ctx
, name
, force
):
2107 """deletes a Physical Deployment Unit (PDU)
2109 NAME: name or ID of the PDU to be deleted
2113 check_client_version(ctx
.obj
, ctx
.command
.name
)
2114 ctx
.obj
.pdu
.delete(name
, force
)
2115 # except ClientException as e:
2124 @cli_osm.command(name
='vim-create', short_help
='creates a new VIM account')
2125 @click.option('--name',
2127 help='Name to create datacenter')
2128 @click.option('--user',
2130 help='VIM username')
2131 @click.option('--password',
2134 confirmation_prompt
=True,
2135 help='VIM password')
2136 @click.option('--auth_url',
2139 @click.option('--tenant',
2141 help='VIM tenant name')
2142 @click.option('--config',
2144 help='VIM specific config parameters')
2145 @click.option('--account_type',
2146 default
='openstack',
2148 @click.option('--description',
2150 help='human readable description')
2151 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
2152 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
2153 @click.option('--wait',
2157 help='do not return the control immediately, but keep it '
2158 'until the operation is completed, or timeout')
2172 """creates a new VIM account"""
2176 check_client_version(ctx
.obj
, '--sdn_controller')
2177 if sdn_port_mapping
:
2178 check_client_version(ctx
.obj
, '--sdn_port_mapping')
2180 vim
['vim-username'] = user
2181 vim
['vim-password'] = password
2182 vim
['vim-url'] = auth_url
2183 vim
['vim-tenant-name'] = tenant
2184 vim
['vim-type'] = account_type
2185 vim
['description'] = description
2186 vim
['config'] = config
2187 if sdn_controller
or sdn_port_mapping
:
2188 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
2190 ctx
.obj
.vim
.create(name
, vim
, wait
=wait
)
2191 # except ClientException as e:
2196 @cli_osm.command(name
='vim-update', short_help
='updates a VIM account')
2197 @click.argument('name')
2198 @click.option('--newname', help='New name for the VIM account')
2199 @click.option('--user', help='VIM username')
2200 @click.option('--password', help='VIM password')
2201 @click.option('--auth_url', help='VIM url')
2202 @click.option('--tenant', help='VIM tenant name')
2203 @click.option('--config', help='VIM specific config parameters')
2204 @click.option('--account_type', help='VIM type')
2205 @click.option('--description', help='human readable description')
2206 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller to be associated with this VIM'
2207 'account. Use empty string to disassociate')
2208 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
2209 @click.option('--wait',
2213 help='do not return the control immediately, but keep it '
2214 'until the operation is completed, or timeout')
2229 """updates a VIM account
2231 NAME: name or ID of the VIM account
2235 check_client_version(ctx
.obj
, ctx
.command
.name
)
2237 if newname
: vim
['name'] = newname
2238 if user
: vim
['vim_user'] = user
2239 if password
: vim
['vim_password'] = password
2240 if auth_url
: vim
['vim_url'] = auth_url
2241 if tenant
: vim
['vim-tenant-name'] = tenant
2242 if account_type
: vim
['vim_type'] = account_type
2243 if description
: vim
['description'] = description
2244 if config
: vim
['config'] = config
2245 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
, wait
=wait
)
2246 # except ClientException as e:
2251 @cli_osm.command(name
='vim-delete', short_help
='deletes a VIM account')
2252 @click.argument('name')
2253 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2254 @click.option('--wait',
2258 help='do not return the control immediately, but keep it '
2259 'until the operation is completed, or timeout')
2261 def vim_delete(ctx
, name
, force
, wait
):
2262 """deletes a VIM account
2264 NAME: name or ID of the VIM account to be deleted
2269 ctx
.obj
.vim
.delete(name
, wait
=wait
)
2271 check_client_version(ctx
.obj
, '--force')
2272 ctx
.obj
.vim
.delete(name
, force
, wait
=wait
)
2273 # except ClientException as e:
2278 @cli_osm.command(name
='vim-list', short_help
='list all VIM accounts')
2279 #@click.option('--ro_update/--no_ro_update',
2281 # help='update list from RO')
2282 @click.option('--filter', default
=None,
2283 help='restricts the list to the VIM accounts matching the filter')
2284 @click.option('--long', is_flag
=True,
2285 help='get more details of the NS (project, vim, deployment status, configuration status.')
2287 def vim_list(ctx
, filter, long):
2288 """list all VIM accounts"""
2291 check_client_version(ctx
.obj
, '--filter')
2293 # check_client_version(ctx.obj, '--ro_update', 'v1')
2294 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
2295 if fullclassname
== 'osmclient.sol005.client.Client':
2296 resp
= ctx
.obj
.vim
.list(filter)
2298 # resp = ctx.obj.vim.list(ro_update)
2300 table
= PrettyTable(['vim name', 'uuid', 'project', 'operational state', 'error details'])
2302 table
= PrettyTable(['vim name', 'uuid'])
2305 vim_details
= ctx
.obj
.vim
.get(vim
['uuid'])
2306 if 'vim_password' in vim_details
:
2307 vim_details
['vim_password']='********'
2308 logger
.debug('VIM details: {}'.format(yaml
.safe_dump(vim_details
)))
2309 vim_state
= vim_details
['_admin'].get('operationalState', '-')
2310 error_details
= 'N/A'
2311 if vim_state
== 'ERROR':
2312 error_details
= vim_details
['_admin'].get('detailed-status', 'Not found')
2313 project_list
= ctx
.obj
.project
.list()
2314 vim_project_list
= vim_details
.get('_admin').get('projects_read')
2316 project_name
= 'None'
2317 if vim_project_list
:
2318 project_id
= vim_project_list
[0]
2319 for p
in project_list
:
2320 if p
['_id'] == project_id
:
2321 project_name
= p
['name']
2323 table
.add_row([vim
['name'], vim
['uuid'], '{} ({})'.format(project_name
, project_id
),
2324 vim_state
, wrap_text(text
=error_details
, width
=80)])
2326 table
.add_row([vim
['name'], vim
['uuid']])
2331 @cli_osm.command(name
='vim-show', short_help
='shows the details of a VIM account')
2332 @click.argument('name')
2334 def vim_show(ctx
, name
):
2335 """shows the details of a VIM account
2337 NAME: name or ID of the VIM account
2341 resp
= ctx
.obj
.vim
.get(name
)
2342 if 'vim_password' in resp
:
2343 resp
['vim_password']='********'
2344 # except ClientException as e:
2348 table
= PrettyTable(['key', 'attribute'])
2349 for k
, v
in list(resp
.items()):
2350 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2355 ####################
2357 ####################
2359 @cli_osm.command(name
='wim-create', short_help
='creates a new WIM account')
2360 @click.option('--name',
2362 help='Name for the WIM account')
2363 @click.option('--user',
2364 help='WIM username')
2365 @click.option('--password',
2366 help='WIM password')
2367 @click.option('--url',
2370 # @click.option('--tenant',
2371 # help='wIM tenant name')
2372 @click.option('--config',
2374 help='WIM specific config parameters')
2375 @click.option('--wim_type',
2377 @click.option('--description',
2379 help='human readable description')
2380 @click.option('--wim_port_mapping', default
=None,
2381 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2382 "(WAN service endpoint id and info)")
2383 @click.option('--wait',
2387 help='do not return the control immediately, but keep it '
2388 'until the operation is completed, or timeout')
2401 """creates a new WIM account"""
2404 check_client_version(ctx
.obj
, ctx
.command
.name
)
2405 # if sdn_controller:
2406 # check_client_version(ctx.obj, '--sdn_controller')
2407 # if sdn_port_mapping:
2408 # check_client_version(ctx.obj, '--sdn_port_mapping')
2410 if user
: wim
['user'] = user
2411 if password
: wim
['password'] = password
2412 if url
: wim
['wim_url'] = url
2413 # if tenant: wim['tenant'] = tenant
2414 wim
['wim_type'] = wim_type
2415 if description
: wim
['description'] = description
2416 if config
: wim
['config'] = config
2417 ctx
.obj
.wim
.create(name
, wim
, wim_port_mapping
, wait
=wait
)
2418 # except ClientException as e:
2423 @cli_osm.command(name
='wim-update', short_help
='updates a WIM account')
2424 @click.argument('name')
2425 @click.option('--newname', help='New name for the WIM account')
2426 @click.option('--user', help='WIM username')
2427 @click.option('--password', help='WIM password')
2428 @click.option('--url', help='WIM url')
2429 @click.option('--config', help='WIM specific config parameters')
2430 @click.option('--wim_type', help='WIM type')
2431 @click.option('--description', help='human readable description')
2432 @click.option('--wim_port_mapping', default
=None,
2433 help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge "
2434 "(WAN service endpoint id and info)")
2435 @click.option('--wait',
2439 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2452 """updates a WIM account
2454 NAME: name or ID of the WIM account
2458 check_client_version(ctx
.obj
, ctx
.command
.name
)
2460 if newname
: wim
['name'] = newname
2461 if user
: wim
['user'] = user
2462 if password
: wim
['password'] = password
2463 if url
: wim
['url'] = url
2464 # if tenant: wim['tenant'] = tenant
2465 if wim_type
: wim
['wim_type'] = wim_type
2466 if description
: wim
['description'] = description
2467 if config
: wim
['config'] = config
2468 ctx
.obj
.wim
.update(name
, wim
, wim_port_mapping
, wait
=wait
)
2469 # except ClientException as e:
2474 @cli_osm.command(name
='wim-delete', short_help
='deletes a WIM account')
2475 @click.argument('name')
2476 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2477 @click.option('--wait',
2481 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2483 def wim_delete(ctx
, name
, force
, wait
):
2484 """deletes a WIM account
2486 NAME: name or ID of the WIM account to be deleted
2490 check_client_version(ctx
.obj
, ctx
.command
.name
)
2491 ctx
.obj
.wim
.delete(name
, force
, wait
=wait
)
2492 # except ClientException as e:
2497 @cli_osm.command(name
='wim-list', short_help
='list all WIM accounts')
2498 @click.option('--filter', default
=None,
2499 help='restricts the list to the WIM accounts matching the filter')
2501 def wim_list(ctx
, filter):
2502 """list all WIM accounts"""
2505 check_client_version(ctx
.obj
, ctx
.command
.name
)
2506 resp
= ctx
.obj
.wim
.list(filter)
2507 table
= PrettyTable(['wim name', 'uuid'])
2509 table
.add_row([wim
['name'], wim
['uuid']])
2512 # except ClientException as e:
2517 @cli_osm.command(name
='wim-show', short_help
='shows the details of a WIM account')
2518 @click.argument('name')
2520 def wim_show(ctx
, name
):
2521 """shows the details of a WIM account
2523 NAME: name or ID of the WIM account
2527 check_client_version(ctx
.obj
, ctx
.command
.name
)
2528 resp
= ctx
.obj
.wim
.get(name
)
2529 if 'password' in resp
:
2530 resp
['wim_password']='********'
2531 # except ClientException as e:
2535 table
= PrettyTable(['key', 'attribute'])
2536 for k
, v
in list(resp
.items()):
2537 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2542 ####################
2543 # SDN controller operations
2544 ####################
2546 @cli_osm.command(name
='sdnc-create', short_help
='creates a new SDN controller')
2547 @click.option('--name',
2549 help='Name to create sdn controller')
2550 @click.option('--type',
2552 help='SDN controller type')
2553 @click.option('--sdn_controller_version', # hidden=True,
2554 help='Deprecated. Use --config {version: sdn_controller_version}')
2555 @click.option('--url',
2556 help='URL in format http[s]://HOST:IP/')
2557 @click.option('--ip_address', # hidden=True,
2558 help='Deprecated. Use --url')
2559 @click.option('--port', # hidden=True,
2560 help='Deprecated. Use --url')
2561 @click.option('--switch_dpid', # hidden=True,
2562 help='Deprecated. Use --config {switch_id: DPID}')
2563 @click.option('--config',
2564 help='Extra information for SDN in yaml format, as {switch_id: identity used for the plugin (e.g. DPID: '
2565 'Openflow Datapath ID), version: version}')
2566 @click.option('--user',
2567 help='SDN controller username')
2568 @click.option('--password',
2570 confirmation_prompt
=True,
2571 help='SDN controller password')
2572 @click.option('--description', default
=None, help='human readable description')
2573 @click.option('--wait',
2577 help="do not return the control immediately, but keep it until the operation is completed, or timeout")
2579 def sdnc_create(ctx
, **kwargs
):
2580 """creates a new SDN controller"""
2582 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2583 x
not in ("wait", "ip_address", "port", "switch_dpid")}
2584 if kwargs
.get("port"):
2585 print("option '--port' is deprecated, use '--url' instead")
2586 sdncontroller
["port"] = int(kwargs
["port"])
2587 if kwargs
.get("ip_address"):
2588 print("option '--ip_address' is deprecated, use '--url' instead")
2589 sdncontroller
["ip"] = kwargs
["ip_address"]
2590 if kwargs
.get("switch_dpid"):
2591 print("option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead")
2592 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2593 if kwargs
.get("sdn_controller_version"):
2594 print("option '--sdn_controller_version' is deprecated, use '--config={version: SDN_CONTROLLER_VERSION}'"
2597 check_client_version(ctx
.obj
, ctx
.command
.name
)
2598 ctx
.obj
.sdnc
.create(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2599 # except ClientException as e:
2603 @cli_osm.command(name
='sdnc-update', short_help
='updates an SDN controller')
2604 @click.argument('name')
2605 @click.option('--newname', help='New name for the SDN controller')
2606 @click.option('--description', default
=None, help='human readable description')
2607 @click.option('--type', help='SDN controller type')
2608 @click.option('--url', help='URL in format http[s]://HOST:IP/')
2609 @click.option('--config', help='Extra information for SDN in yaml format, as '
2610 '{switch_id: identity used for the plugin (e.g. DPID: '
2611 'Openflow Datapath ID), version: version}')
2612 @click.option('--user', help='SDN controller username')
2613 @click.option('--password', help='SDN controller password')
2614 @click.option('--ip_address', help='Deprecated. Use --url') # hidden=True
2615 @click.option('--port', help='Deprecated. Use --url') # hidden=True
2616 @click.option('--switch_dpid', help='Deprecated. Use --config {switch_dpid: DPID}') # hidden=True
2617 @click.option('--sdn_controller_version', help='Deprecated. Use --config {version: VERSION}') # hidden=True
2618 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2619 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2621 def sdnc_update(ctx
, **kwargs
):
2622 """updates an SDN controller
2624 NAME: name or ID of the SDN controller
2627 sdncontroller
= {x
: kwargs
[x
] for x
in kwargs
if kwargs
[x
] and
2628 x
not in ("wait", "ip_address", "port", "switch_dpid", "new_name")}
2629 if kwargs
.get("newname"):
2630 sdncontroller
["name"] = kwargs
["newname"]
2631 if kwargs
.get("port"):
2632 print("option '--port' is deprecated, use '--url' instead")
2633 sdncontroller
["port"] = int(kwargs
["port"])
2634 if kwargs
.get("ip_address"):
2635 print("option '--ip_address' is deprecated, use '--url' instead")
2636 sdncontroller
["ip"] = kwargs
["ip_address"]
2637 if kwargs
.get("switch_dpid"):
2638 print("option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead")
2639 sdncontroller
["dpid"] = kwargs
["switch_dpid"]
2640 if kwargs
.get("sdn_controller_version"):
2641 print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'"
2645 check_client_version(ctx
.obj
, ctx
.command
.name
)
2646 ctx
.obj
.sdnc
.update(kwargs
["name"], sdncontroller
, wait
=kwargs
["wait"])
2647 # except ClientException as e:
2652 @cli_osm.command(name
='sdnc-delete', short_help
='deletes an SDN controller')
2653 @click.argument('name')
2654 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
2655 @click.option('--wait', required
=False, default
=False, is_flag
=True,
2656 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2658 def sdnc_delete(ctx
, name
, force
, wait
):
2659 """deletes an SDN controller
2661 NAME: name or ID of the SDN controller to be deleted
2665 check_client_version(ctx
.obj
, ctx
.command
.name
)
2666 ctx
.obj
.sdnc
.delete(name
, force
, wait
=wait
)
2667 # except ClientException as e:
2672 @cli_osm.command(name
='sdnc-list', short_help
='list all SDN controllers')
2673 @click.option('--filter', default
=None,
2674 help="restricts the list to the SDN controllers matching the filter with format: 'k[.k..]=v[&k[.k]=v2]'")
2676 def sdnc_list(ctx
, filter):
2677 """list all SDN controllers"""
2680 check_client_version(ctx
.obj
, ctx
.command
.name
)
2681 resp
= ctx
.obj
.sdnc
.list(filter)
2682 # except ClientException as e:
2685 table
= PrettyTable(['sdnc name', 'id'])
2687 table
.add_row([sdnc
['name'], sdnc
['_id']])
2692 @cli_osm.command(name
='sdnc-show', short_help
='shows the details of an SDN controller')
2693 @click.argument('name')
2695 def sdnc_show(ctx
, name
):
2696 """shows the details of an SDN controller
2698 NAME: name or ID of the SDN controller
2702 check_client_version(ctx
.obj
, ctx
.command
.name
)
2703 resp
= ctx
.obj
.sdnc
.get(name
)
2704 # except ClientException as e:
2708 table
= PrettyTable(['key', 'attribute'])
2709 for k
, v
in list(resp
.items()):
2710 table
.add_row([k
, json
.dumps(v
, indent
=2)])
2715 ###########################
2716 # K8s cluster operations
2717 ###########################
2719 @cli_osm.command(name
='k8scluster-add', short_help
='adds a K8s cluster to OSM')
2720 @click.argument('name')
2721 @click.option('--creds',
2723 help='credentials file, i.e. a valid `.kube/config` file')
2724 @click.option('--version',
2726 help='Kubernetes version')
2727 @click.option('--vim',
2729 help='VIM target, the VIM where the cluster resides')
2730 @click.option('--k8s-nets',
2732 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) ...]}"')
2733 @click.option('--description',
2735 help='human readable description')
2736 @click.option('--namespace',
2737 default
='kube-system',
2738 help='namespace to be used for its operation, defaults to `kube-system`')
2739 @click.option('--cni',
2741 help='list of CNI plugins, in JSON inline format, used in the cluster')
2742 #@click.option('--skip-init',
2744 # help='If set, K8s cluster is assumed to be ready for its use with OSM')
2745 #@click.option('--wait',
2747 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2749 def k8scluster_add(ctx
,
2758 """adds a K8s cluster to OSM
2760 NAME: name of the K8s cluster
2763 check_client_version(ctx
.obj
, ctx
.command
.name
)
2765 cluster
['name'] = name
2766 with
open(creds
, 'r') as cf
:
2767 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2768 cluster
['k8s_version'] = version
2769 cluster
['vim_account'] = vim
2770 cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2772 cluster
['description'] = description
2773 if namespace
: cluster
['namespace'] = namespace
2774 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2775 ctx
.obj
.k8scluster
.create(name
, cluster
)
2776 # except ClientException as e:
2781 @cli_osm.command(name
='k8scluster-update', short_help
='updates a K8s cluster')
2782 @click.argument('name')
2783 @click.option('--newname', help='New name for the K8s cluster')
2784 @click.option('--creds', help='credentials file, i.e. a valid `.kube/config` file')
2785 @click.option('--version', help='Kubernetes version')
2786 @click.option('--vim', help='VIM target, the VIM where the cluster resides')
2787 @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) ...]}"')
2788 @click.option('--description', help='human readable description')
2789 @click.option('--namespace', help='namespace to be used for its operation, defaults to `kube-system`')
2790 @click.option('--cni', help='list of CNI plugins, in JSON inline format, used in the cluster')
2792 def k8scluster_update(ctx
,
2802 """updates a K8s cluster
2804 NAME: name or ID of the K8s cluster
2807 check_client_version(ctx
.obj
, ctx
.command
.name
)
2809 if newname
: cluster
['name'] = newname
2811 with
open(creds
, 'r') as cf
:
2812 cluster
['credentials'] = yaml
.safe_load(cf
.read())
2813 if version
: cluster
['k8s_version'] = version
2814 if vim
: cluster
['vim_account'] = vim
2815 if k8s_nets
: cluster
['nets'] = yaml
.safe_load(k8s_nets
)
2816 if description
: cluster
['description'] = description
2817 if namespace
: cluster
['namespace'] = namespace
2818 if cni
: cluster
['cni'] = yaml
.safe_load(cni
)
2819 ctx
.obj
.k8scluster
.update(name
, cluster
)
2820 # except ClientException as e:
2825 @cli_osm.command(name
='k8scluster-delete', short_help
='deletes a K8s cluster')
2826 @click.argument('name')
2827 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2828 #@click.option('--wait',
2830 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2832 def k8scluster_delete(ctx
, name
, force
):
2833 """deletes a K8s cluster
2835 NAME: name or ID of the K8s cluster to be deleted
2838 check_client_version(ctx
.obj
, ctx
.command
.name
)
2839 ctx
.obj
.k8scluster
.delete(name
, force
=force
)
2840 # except ClientException as e:
2845 @cli_osm.command(name
='k8scluster-list')
2846 @click.option('--filter', default
=None,
2847 help='restricts the list to the K8s clusters matching the filter')
2848 @click.option('--literal', is_flag
=True,
2849 help='print literally, no pretty table')
2851 def k8scluster_list(ctx
, filter, literal
):
2852 """list all K8s clusters"""
2854 check_client_version(ctx
.obj
, ctx
.command
.name
)
2855 resp
= ctx
.obj
.k8scluster
.list(filter)
2857 print(yaml
.safe_dump(resp
))
2859 table
= PrettyTable(['Name', 'Id', 'Version', 'VIM', 'K8s-nets', 'Operational State', 'Description'])
2860 for cluster
in resp
:
2861 table
.add_row([cluster
['name'], cluster
['_id'], cluster
['k8s_version'], cluster
['vim_account'],
2862 json
.dumps(cluster
['nets']), cluster
["_admin"]["operationalState"],
2863 trunc_text(cluster
.get('description',''),40)])
2866 # except ClientException as e:
2871 @cli_osm.command(name
='k8scluster-show', short_help
='shows the details of a K8s cluster')
2872 @click.argument('name')
2873 @click.option('--literal', is_flag
=True,
2874 help='print literally, no pretty table')
2876 def k8scluster_show(ctx
, name
, literal
):
2877 """shows the details of a K8s cluster
2879 NAME: name or ID of the K8s cluster
2882 resp
= ctx
.obj
.k8scluster
.get(name
)
2884 print(yaml
.safe_dump(resp
))
2886 table
= PrettyTable(['key', 'attribute'])
2887 for k
, v
in list(resp
.items()):
2888 table
.add_row([k
, wrap_text(text
=json
.dumps(v
, indent
=2),width
=100)])
2891 # except ClientException as e:
2897 ###########################
2899 ###########################
2901 @cli_osm.command(name
='repo-add', short_help
='adds a repo to OSM')
2902 @click.argument('name')
2903 @click.argument('uri')
2904 @click.option('--type',
2905 type=click
.Choice(['helm-chart', 'juju-bundle']),
2907 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2908 @click.option('--description',
2910 help='human readable description')
2911 #@click.option('--wait',
2913 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2920 """adds a repo to OSM
2922 NAME: name of the repo
2923 URI: URI of the repo
2926 check_client_version(ctx
.obj
, ctx
.command
.name
)
2932 repo
['description'] = description
2933 ctx
.obj
.repo
.create(name
, repo
)
2934 # except ClientException as e:
2939 @cli_osm.command(name
='repo-update', short_help
='updates a repo in OSM')
2940 @click.argument('name')
2941 @click.option('--newname', help='New name for the repo')
2942 @click.option('--uri', help='URI of the repo')
2943 @click.option('--type', type=click
.Choice(['helm-chart', 'juju-bundle']),
2944 help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles)')
2945 @click.option('--description', help='human readable description')
2946 #@click.option('--wait',
2948 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2950 def repo_update(ctx
,
2956 """updates a repo in OSM
2958 NAME: name of the repo
2961 check_client_version(ctx
.obj
, ctx
.command
.name
)
2963 if newname
: repo
['name'] = newname
2964 if uri
: repo
['uri'] = uri
2965 if type: repo
['type'] = type
2966 if description
: repo
['description'] = description
2967 ctx
.obj
.repo
.update(name
, repo
)
2968 # except ClientException as e:
2973 @cli_osm.command(name
='repo-delete', short_help
='deletes a repo')
2974 @click.argument('name')
2975 @click.option('--force', is_flag
=True, help='forces the deletion from the DB (not recommended)')
2976 #@click.option('--wait',
2978 # help='do not return the control immediately, but keep it until the operation is completed, or timeout')
2980 def repo_delete(ctx
, name
, force
):
2983 NAME: name or ID of the repo to be deleted
2986 check_client_version(ctx
.obj
, ctx
.command
.name
)
2987 ctx
.obj
.repo
.delete(name
, force
=force
)
2988 # except ClientException as e:
2993 @cli_osm.command(name
='repo-list')
2994 @click.option('--filter', default
=None,
2995 help='restricts the list to the repos matching the filter')
2996 @click.option('--literal', is_flag
=True,
2997 help='print literally, no pretty table')
2999 def repo_list(ctx
, filter, literal
):
3000 """list all repos"""
3002 check_client_version(ctx
.obj
, ctx
.command
.name
)
3003 resp
= ctx
.obj
.repo
.list(filter)
3005 print(yaml
.safe_dump(resp
))
3007 table
= PrettyTable(['Name', 'Id', 'Type', 'URI', 'Description'])
3009 #cluster['k8s-nets'] = json.dumps(yaml.safe_load(cluster['k8s-nets']))
3010 table
.add_row([repo
['name'], repo
['_id'], repo
['type'], repo
['url'], trunc_text(repo
.get('description',''),40)])
3013 # except ClientException as e:
3018 @cli_osm.command(name
='repo-show', short_help
='shows the details of a repo')
3019 @click.argument('name')
3020 @click.option('--literal', is_flag
=True,
3021 help='print literally, no pretty table')
3023 def repo_show(ctx
, name
, literal
):
3024 """shows the details of a repo
3026 NAME: name or ID of the repo
3029 resp
= ctx
.obj
.repo
.get(name
)
3031 print(yaml
.safe_dump(resp
))
3033 table
= PrettyTable(['key', 'attribute'])
3034 for k
, v
in list(resp
.items()):
3035 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3038 # except ClientException as e:
3044 ####################
3045 # Project mgmt operations
3046 ####################
3048 @cli_osm.command(name
='project-create', short_help
='creates a new project')
3049 @click.argument('name')
3050 #@click.option('--description',
3051 # default='no description',
3052 # help='human readable description')
3053 @click.option('--domain-name', 'domain_name',
3055 help='assign to a domain')
3057 def project_create(ctx
, name
, domain_name
):
3058 """Creates a new project
3060 NAME: name of the project
3061 DOMAIN_NAME: optional domain name for the project when keystone authentication is used
3065 project
['name'] = name
3067 project
['domain_name'] = domain_name
3069 check_client_version(ctx
.obj
, ctx
.command
.name
)
3070 ctx
.obj
.project
.create(name
, project
)
3071 # except ClientException as e:
3076 @cli_osm.command(name
='project-delete', short_help
='deletes a project')
3077 @click.argument('name')
3078 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3080 def project_delete(ctx
, name
):
3081 """deletes a project
3083 NAME: name or ID of the project to be deleted
3087 check_client_version(ctx
.obj
, ctx
.command
.name
)
3088 ctx
.obj
.project
.delete(name
)
3089 # except ClientException as e:
3094 @cli_osm.command(name
='project-list', short_help
='list all projects')
3095 @click.option('--filter', default
=None,
3096 help='restricts the list to the projects matching the filter')
3098 def project_list(ctx
, filter):
3099 """list all projects"""
3102 check_client_version(ctx
.obj
, ctx
.command
.name
)
3103 resp
= ctx
.obj
.project
.list(filter)
3104 # except ClientException as e:
3107 table
= PrettyTable(['name', 'id'])
3109 table
.add_row([proj
['name'], proj
['_id']])
3114 @cli_osm.command(name
='project-show', short_help
='shows the details of a project')
3115 @click.argument('name')
3117 def project_show(ctx
, name
):
3118 """shows the details of a project
3120 NAME: name or ID of the project
3124 check_client_version(ctx
.obj
, ctx
.command
.name
)
3125 resp
= ctx
.obj
.project
.get(name
)
3126 # except ClientException as e:
3130 table
= PrettyTable(['key', 'attribute'])
3131 for k
, v
in resp
.items():
3132 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3137 @cli_osm.command(name
='project-update', short_help
='updates a project (only the name can be updated)')
3138 @click.argument('project')
3139 @click.option('--name',
3141 help='new name for the project')
3144 def project_update(ctx
, project
, name
):
3146 Update a project name
3149 :param project: id or name of the project to modify
3150 :param name: new name for the project
3154 project_changes
= {}
3155 project_changes
['name'] = name
3158 check_client_version(ctx
.obj
, ctx
.command
.name
)
3159 ctx
.obj
.project
.update(project
, project_changes
)
3160 # except ClientException as e:
3164 ####################
3165 # User mgmt operations
3166 ####################
3168 @cli_osm.command(name
='user-create', short_help
='creates a new user')
3169 @click.argument('username')
3170 @click.option('--password',
3173 confirmation_prompt
=True,
3174 help='user password')
3175 @click.option('--projects',
3176 # prompt="Comma separate list of projects",
3178 callback
=lambda ctx
, param
, value
: ''.join(value
).split(',') if all(len(x
)==1 for x
in value
) else value
,
3179 help='list of project ids that the user belongs to')
3180 @click.option('--project-role-mappings', 'project_role_mappings',
3181 default
=None, multiple
=True,
3182 help="assign role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3183 @click.option('--domain-name', 'domain_name',
3185 help='assign to a domain')
3187 def user_create(ctx
, username
, password
, projects
, project_role_mappings
, domain_name
):
3188 """Creates a new user
3191 USERNAME: name of the user
3192 PASSWORD: password of the user
3193 PROJECTS: projects assigned to user (internal only)
3194 PROJECT_ROLE_MAPPING: roles in projects assigned to user (keystone)
3195 DOMAIN_NAME: optional domain name for the user when keystone authentication is used
3199 user
['username'] = username
3200 user
['password'] = password
3201 user
['projects'] = projects
3202 user
['project_role_mappings'] = project_role_mappings
3204 user
['domain_name'] = domain_name
3207 check_client_version(ctx
.obj
, ctx
.command
.name
)
3208 ctx
.obj
.user
.create(username
, user
)
3209 # except ClientException as e:
3214 @cli_osm.command(name
='user-update', short_help
='updates user information')
3215 @click.argument('username')
3216 @click.option('--password',
3219 # confirmation_prompt=True,
3220 help='user password')
3221 @click.option('--set-username', 'set_username',
3223 help='change username')
3224 @click.option('--set-project', 'set_project',
3225 default
=None, multiple
=True,
3226 help="create/replace the roles for this project: 'project,role1[,role2,...]'")
3227 @click.option('--remove-project', 'remove_project',
3228 default
=None, multiple
=True,
3229 help="removes project from user: 'project'")
3230 @click.option('--add-project-role', 'add_project_role',
3231 default
=None, multiple
=True,
3232 help="assign role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3233 @click.option('--remove-project-role', 'remove_project_role',
3234 default
=None, multiple
=True,
3235 help="remove role(s) in a project. Can be used several times: 'project,role1[,role2,...]'")
3237 def user_update(ctx
, username
, password
, set_username
, set_project
, remove_project
,
3238 add_project_role
, remove_project_role
):
3239 """Update a user information
3242 USERNAME: name of the user
3243 PASSWORD: new password
3244 SET_USERNAME: new username
3245 SET_PROJECT: creating mappings for project/role(s)
3246 REMOVE_PROJECT: deleting mappings for project/role(s)
3247 ADD_PROJECT_ROLE: adding mappings for project/role(s)
3248 REMOVE_PROJECT_ROLE: removing mappings for project/role(s)
3252 user
['password'] = password
3253 user
['username'] = set_username
3254 user
['set-project'] = set_project
3255 user
['remove-project'] = remove_project
3256 user
['add-project-role'] = add_project_role
3257 user
['remove-project-role'] = remove_project_role
3260 check_client_version(ctx
.obj
, ctx
.command
.name
)
3261 ctx
.obj
.user
.update(username
, user
)
3262 # except ClientException as e:
3267 @cli_osm.command(name
='user-delete', short_help
='deletes a user')
3268 @click.argument('name')
3269 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3271 def user_delete(ctx
, name
):
3275 NAME: name or ID of the user to be deleted
3279 check_client_version(ctx
.obj
, ctx
.command
.name
)
3280 ctx
.obj
.user
.delete(name
)
3281 # except ClientException as e:
3286 @cli_osm.command(name
='user-list', short_help
='list all users')
3287 @click.option('--filter', default
=None,
3288 help='restricts the list to the users matching the filter')
3290 def user_list(ctx
, filter):
3291 """list all users"""
3293 check_client_version(ctx
.obj
, ctx
.command
.name
)
3294 resp
= ctx
.obj
.user
.list(filter)
3295 # except ClientException as e:
3298 table
= PrettyTable(['name', 'id'])
3300 table
.add_row([user
['username'], user
['_id']])
3305 @cli_osm.command(name
='user-show', short_help
='shows the details of a user')
3306 @click.argument('name')
3308 def user_show(ctx
, name
):
3309 """shows the details of a user
3311 NAME: name or ID of the user
3315 check_client_version(ctx
.obj
, ctx
.command
.name
)
3316 resp
= ctx
.obj
.user
.get(name
)
3317 if 'password' in resp
:
3318 resp
['password']='********'
3319 # except ClientException as e:
3323 table
= PrettyTable(['key', 'attribute'])
3324 for k
, v
in resp
.items():
3325 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3330 ####################
3331 # Fault Management operations
3332 ####################
3334 @cli_osm.command(name
='ns-alarm-create')
3335 @click.argument('name')
3336 @click.option('--ns', prompt
=True, help='NS instance id or name')
3337 @click.option('--vnf', prompt
=True,
3338 help='VNF name (VNF member index as declared in the NSD)')
3339 @click.option('--vdu', prompt
=True,
3340 help='VDU name (VDU name as declared in the VNFD)')
3341 @click.option('--metric', prompt
=True,
3342 help='Name of the metric (e.g. cpu_utilization)')
3343 @click.option('--severity', default
='WARNING',
3344 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
3345 @click.option('--threshold_value', prompt
=True,
3346 help='threshold value that, when crossed, an alarm is triggered')
3347 @click.option('--threshold_operator', prompt
=True,
3348 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
3349 @click.option('--statistic', default
='AVERAGE',
3350 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
3352 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
3353 threshold_value
, threshold_operator
, statistic
):
3354 """creates a new alarm for a NS instance"""
3355 # TODO: Check how to validate threshold_value.
3356 # Should it be an integer (1-100), percentage, or decimal (0.01-1.00)?
3359 ns_instance
= ctx
.obj
.ns
.get(ns
)
3361 alarm
['alarm_name'] = name
3362 alarm
['ns_id'] = ns_instance
['_id']
3363 alarm
['correlation_id'] = ns_instance
['_id']
3364 alarm
['vnf_member_index'] = vnf
3365 alarm
['vdu_name'] = vdu
3366 alarm
['metric_name'] = metric
3367 alarm
['severity'] = severity
3368 alarm
['threshold_value'] = int(threshold_value
)
3369 alarm
['operation'] = threshold_operator
3370 alarm
['statistic'] = statistic
3371 check_client_version(ctx
.obj
, ctx
.command
.name
)
3372 ctx
.obj
.ns
.create_alarm(alarm
)
3373 # except ClientException as e:
3378 #@cli_osm.command(name='ns-alarm-delete')
3379 #@click.argument('name')
3380 #@click.pass_context
3381 #def ns_alarm_delete(ctx, name):
3382 # """deletes an alarm
3384 # NAME: name of the alarm to be deleted
3387 # check_client_version(ctx.obj, ctx.command.name)
3388 # ctx.obj.ns.delete_alarm(name)
3389 # except ClientException as e:
3394 ####################
3395 # Performance Management operations
3396 ####################
3398 @cli_osm.command(name
='ns-metric-export', short_help
='exports a metric to the internal OSM bus, which can be read by other apps')
3399 @click.option('--ns', prompt
=True, help='NS instance id or name')
3400 @click.option('--vnf', prompt
=True,
3401 help='VNF name (VNF member index as declared in the NSD)')
3402 @click.option('--vdu', prompt
=True,
3403 help='VDU name (VDU name as declared in the VNFD)')
3404 @click.option('--metric', prompt
=True,
3405 help='name of the metric (e.g. cpu_utilization)')
3406 #@click.option('--period', default='1w',
3407 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
3408 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
3410 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
3411 """exports a metric to the internal OSM bus, which can be read by other apps"""
3412 # TODO: Check how to validate interval.
3413 # Should it be an integer (seconds), or should a suffix (s,m,h,d,w) also be permitted?
3416 ns_instance
= ctx
.obj
.ns
.get(ns
)
3418 metric_data
['ns_id'] = ns_instance
['_id']
3419 metric_data
['correlation_id'] = ns_instance
['_id']
3420 metric_data
['vnf_member_index'] = vnf
3421 metric_data
['vdu_name'] = vdu
3422 metric_data
['metric_name'] = metric
3423 metric_data
['collection_unit'] = 'WEEK'
3424 metric_data
['collection_period'] = 1
3425 check_client_version(ctx
.obj
, ctx
.command
.name
)
3427 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
3431 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
3432 time
.sleep(int(interval
))
3434 # except ClientException as e:
3439 ####################
3441 ####################
3443 @cli_osm.command(name
='version', short_help
='shows client and server versions')
3445 def get_version(ctx
):
3446 """shows client and server versions"""
3448 check_client_version(ctx
.obj
, "version")
3449 print ("Server version: {}".format(ctx
.obj
.get_version()))
3450 print ("Client version: {}".format(pkg_resources
.get_distribution("osmclient").version
))
3451 # except ClientException as e:
3455 @cli_osm.command(name
='upload-package', short_help
='uploads a VNF package or NS package')
3456 @click.argument('filename')
3457 @click.option('--skip-charm-build', default
=False, is_flag
=True,
3458 help='the charm will not be compiled, it is assumed to already exist')
3460 def upload_package(ctx
, filename
, skip_charm_build
):
3461 """uploads a vnf package or ns package
3463 filename: vnf or ns package folder, or vnf or ns package file (tar.gz)
3467 ctx
.obj
.package
.upload(filename
, skip_charm_build
=skip_charm_build
)
3468 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
3469 if fullclassname
!= 'osmclient.sol005.client.Client':
3470 ctx
.obj
.package
.wait_for_upload(filename
)
3471 # except ClientException as e:
3476 #@cli_osm.command(name='ns-scaling-show')
3477 #@click.argument('ns_name')
3478 #@click.pass_context
3479 #def show_ns_scaling(ctx, ns_name):
3480 # """shows the status of a NS scaling operation
3482 # NS_NAME: name of the NS instance being scaled
3485 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3486 # resp = ctx.obj.ns.list()
3487 # except ClientException as e:
3491 # table = PrettyTable(
3494 # 'operational status',
3499 # if ns_name == ns['name']:
3500 # nsopdata = ctx.obj.ns.get_opdata(ns['id'])
3501 # scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
3502 # for record in scaling_records:
3503 # if 'instance' in record:
3504 # instances = record['instance']
3505 # for inst in instances:
3507 # [record['scaling-group-name-ref'],
3508 # inst['instance-id'],
3509 # inst['op-status'],
3510 # time.strftime('%Y-%m-%d %H:%M:%S',
3512 # inst['create-time'])),
3518 #@cli_osm.command(name='ns-scale')
3519 #@click.argument('ns_name')
3520 #@click.option('--ns_scale_group', prompt=True)
3521 #@click.option('--index', prompt=True)
3522 #@click.option('--wait',
3526 # help='do not return the control immediately, but keep it \
3527 # until the operation is completed, or timeout')
3528 #@click.pass_context
3529 #def ns_scale(ctx, ns_name, ns_scale_group, index, wait):
3532 # NS_NAME: name of the NS instance to be scaled
3535 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3536 # ctx.obj.ns.scale(ns_name, ns_scale_group, index, wait=wait)
3537 # except ClientException as e:
3542 #@cli_osm.command(name='config-agent-list')
3543 #@click.pass_context
3544 #def config_agent_list(ctx):
3545 # """list config agents"""
3547 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3548 # except ClientException as e:
3551 # table = PrettyTable(['name', 'account-type', 'details'])
3552 # for account in ctx.obj.vca.list():
3555 # account['account-type'],
3561 #@cli_osm.command(name='config-agent-delete')
3562 #@click.argument('name')
3563 #@click.pass_context
3564 #def config_agent_delete(ctx, name):
3565 # """deletes a config agent
3567 # NAME: name of the config agent to be deleted
3570 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3571 # ctx.obj.vca.delete(name)
3572 # except ClientException as e:
3577 #@cli_osm.command(name='config-agent-add')
3578 #@click.option('--name',
3580 #@click.option('--account_type',
3582 #@click.option('--server',
3584 #@click.option('--user',
3586 #@click.option('--secret',
3589 # confirmation_prompt=True)
3590 #@click.pass_context
3591 #def config_agent_add(ctx, name, account_type, server, user, secret):
3592 # """adds a config agent"""
3594 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3595 # ctx.obj.vca.create(name, account_type, server, user, secret)
3596 # except ClientException as e:
3601 #@cli_osm.command(name='ro-dump')
3602 #@click.pass_context
3604 # """shows RO agent information"""
3605 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3606 # resp = ctx.obj.vim.get_resource_orchestrator()
3607 # table = PrettyTable(['key', 'attribute'])
3608 # for k, v in list(resp.items()):
3609 # table.add_row([k, json.dumps(v, indent=2)])
3614 #@cli_osm.command(name='vcs-list')
3615 #@click.pass_context
3617 # check_client_version(ctx.obj, ctx.command.name, 'v1')
3618 # resp = ctx.obj.utils.get_vcs_info()
3619 # table = PrettyTable(['component name', 'state'])
3620 # for component in resp:
3621 # table.add_row([component['component_name'], component['state']])
3626 @cli_osm.command(name
='ns-action', short_help
='executes an action/primitive over a NS instance')
3627 @click.argument('ns_name')
3628 @click.option('--vnf_name', default
=None, help='member-vnf-index if the target is a vnf instead of a ns)')
3629 @click.option('--kdu_name', default
=None, help='kdu-name if the target is a kdu)')
3630 @click.option('--vdu_id', default
=None, help='vdu-id if the target is a vdu')
3631 @click.option('--vdu_count', default
=None, help='number of vdu instance of this vdu_id')
3632 @click.option('--action_name', prompt
=True, help='action name')
3633 @click.option('--params', default
=None, help='action params in YAML/JSON inline string')
3634 @click.option('--params_file', default
=None, help='YAML/JSON file with action params')
3635 @click.option('--timeout', required
=False, default
=None, type=int, help='timeout in seconds')
3636 @click.option('--wait',
3640 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3653 """executes an action/primitive over a NS instance
3655 NS_NAME: name or ID of the NS instance
3659 check_client_version(ctx
.obj
, ctx
.command
.name
)
3662 op_data
['member_vnf_index'] = vnf_name
3664 op_data
['kdu_name'] = kdu_name
3666 op_data
['vdu_id'] = vdu_id
3668 op_data
['vdu_count_index'] = vdu_count
3670 op_data
['timeout_ns_action'] = timeout
3671 op_data
['primitive'] = action_name
3673 with
open(params_file
, 'r') as pf
:
3676 op_data
['primitive_params'] = yaml
.safe_load(params
)
3678 op_data
['primitive_params'] = {}
3679 print(ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
, wait
=wait
))
3681 # except ClientException as e:
3686 @cli_osm.command(name
='vnf-scale', short_help
='executes a VNF scale (adding/removing VDUs)')
3687 @click.argument('ns_name')
3688 @click.argument('vnf_name')
3689 @click.option('--scaling-group', prompt
=True, help="scaling-group-descriptor name to use")
3690 @click.option('--scale-in', default
=False, is_flag
=True, help="performs a scale in operation")
3691 @click.option('--scale-out', default
=False, is_flag
=True, help="performs a scale out operation (by default)")
3692 @click.option('--timeout', required
=False, default
=None, type=int, help='timeout in seconds')
3693 @click.option('--wait', required
=False, default
=False, is_flag
=True,
3694 help='do not return the control immediately, but keep it until the operation is completed, or timeout')
3705 Executes a VNF scale (adding/removing VDUs)
3708 NS_NAME: name or ID of the NS instance.
3709 VNF_NAME: member-vnf-index in the NS to be scaled.
3713 check_client_version(ctx
.obj
, ctx
.command
.name
)
3714 if not scale_in
and not scale_out
:
3716 ctx
.obj
.ns
.scale_vnf(ns_name
, vnf_name
, scaling_group
, scale_in
, scale_out
, wait
, timeout
)
3717 # except ClientException as e:
3722 ##############################
3723 # Role Management Operations #
3724 ##############################
3726 @cli_osm.command(name
='role-create', short_help
='creates a new role')
3727 @click.argument('name')
3728 @click.option('--permissions',
3730 help='role permissions using a dictionary')
3732 def role_create(ctx
, name
, permissions
):
3737 NAME: Name or ID of the role.
3738 DEFINITION: Definition of grant/denial of access to resources.
3742 check_client_version(ctx
.obj
, ctx
.command
.name
)
3743 ctx
.obj
.role
.create(name
, permissions
)
3744 # except ClientException as e:
3749 @cli_osm.command(name
='role-update', short_help
='updates a role')
3750 @click.argument('name')
3751 @click.option('--set-name',
3753 help='change name of rle')
3754 # @click.option('--permissions',
3756 # help='provide a yaml format dictionary with incremental changes. Values can be bool or None to delete')
3757 @click.option('--add',
3759 help='yaml format dictionary with permission: True/False to access grant/denial')
3760 @click.option('--remove',
3762 help='yaml format list to remove a permission')
3764 def role_update(ctx
, name
, set_name
, add
, remove
):
3769 NAME: Name or ID of the role.
3770 DEFINITION: Definition overwrites the old definition.
3771 ADD: Grant/denial of access to resource to add.
3772 REMOVE: Grant/denial of access to resource to remove.
3776 check_client_version(ctx
.obj
, ctx
.command
.name
)
3777 ctx
.obj
.role
.update(name
, set_name
, None, add
, remove
)
3778 # except ClientException as e:
3783 @cli_osm.command(name
='role-delete', short_help
='deletes a role')
3784 @click.argument('name')
3785 # @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
3787 def role_delete(ctx
, name
):
3792 NAME: Name or ID of the role.
3796 check_client_version(ctx
.obj
, ctx
.command
.name
)
3797 ctx
.obj
.role
.delete(name
)
3798 # except ClientException as e:
3803 @cli_osm.command(name
='role-list', short_help
='list all roles')
3804 @click.option('--filter', default
=None,
3805 help='restricts the list to the projects matching the filter')
3807 def role_list(ctx
, filter):
3813 check_client_version(ctx
.obj
, ctx
.command
.name
)
3814 resp
= ctx
.obj
.role
.list(filter)
3815 # except ClientException as e:
3818 table
= PrettyTable(['name', 'id'])
3820 table
.add_row([role
['name'], role
['_id']])
3825 @cli_osm.command(name
='role-show', short_help
='show specific role')
3826 @click.argument('name')
3828 def role_show(ctx
, name
):
3830 Shows the details of a role.
3833 NAME: Name or ID of the role.
3837 check_client_version(ctx
.obj
, ctx
.command
.name
)
3838 resp
= ctx
.obj
.role
.get(name
)
3839 # except ClientException as e:
3843 table
= PrettyTable(['key', 'attribute'])
3844 for k
, v
in resp
.items():
3845 table
.add_row([k
, json
.dumps(v
, indent
=2)])
3850 @cli_osm.command(name
='package-create',
3851 short_help
='Create a package descriptor')
3852 @click.argument('package-type')
3853 @click.argument('package-name')
3854 @click.option('--base-directory',
3856 help=('(NS/VNF/NST) Set the location for package creation. Default: "."'))
3857 @click.option('--image',
3858 default
="image-name",
3859 help='(VNF) Set the name of the vdu image. Default "image-name"')
3860 @click.option('--vdus',
3862 help='(VNF) Set the number of vdus in a VNF. Default 1')
3863 @click.option('--vcpu',
3865 help='(VNF) Set the number of virtual CPUs in a vdu. Default 1')
3866 @click.option('--memory',
3868 help='(VNF) Set the memory size (MB) of the vdu. Default 1024')
3869 @click.option('--storage',
3871 help='(VNF) Set the disk size (GB) of the vdu. Default 10')
3872 @click.option('--interfaces',
3874 help='(VNF) Set the number of additional interfaces apart from the management interface. Default 0')
3875 @click.option('--vendor',
3877 help='(NS/VNF) Set the descriptor vendor. Default "OSM"')
3878 @click.option('--override',
3881 help='(NS/VNF/NST) Flag for overriding the package if exists.')
3882 @click.option('--detailed',
3885 help='(NS/VNF/NST) Flag for generating descriptor .yaml with all possible commented options')
3886 @click.option('--netslice-subnets',
3888 help='(NST) Number of netslice subnets. Default 1')
3889 @click.option('--netslice-vlds',
3891 help='(NST) Number of netslice vlds. Default 1')
3893 def package_create(ctx
,
3909 Creates an OSM NS, VNF, NST package
3912 PACKAGE_TYPE: Package to be created: NS, VNF or NST.
3913 PACKAGE_NAME: Name of the package to create the folder with the content.
3917 check_client_version(ctx
.obj
, ctx
.command
.name
)
3918 print("Creating the {} structure: {}/{}".format(package_type
.upper(), base_directory
, package_name
))
3919 resp
= ctx
.obj
.package_tool
.create(package_type
,
3928 interfaces
=interfaces
,
3931 netslice_subnets
=netslice_subnets
,
3932 netslice_vlds
=netslice_vlds
)
3934 # except ClientException as inst:
3935 # print("ERROR: {}".format(inst))
3938 @cli_osm.command(name
='package-validate',
3939 short_help
='Validate a package descriptor')
3940 @click.argument('base-directory',
3943 @click.option('--recursive/--no-recursive',
3945 help='The activated recursive option will validate the yaml files'
3946 ' within the indicated directory and in its subdirectories')
3948 def package_validate(ctx
,
3952 Validate descriptors given a base directory.
3955 BASE_DIRECTORY: Stub folder for NS, VNF or NST package.
3958 check_client_version(ctx
.obj
, ctx
.command
.name
)
3959 results
= ctx
.obj
.package_tool
.validate(base_directory
, recursive
)
3960 table
= PrettyTable()
3961 table
.field_names
= ["TYPE", "PATH", "VALID", "ERROR"]
3962 # Print the dictionary generated by the validation function
3963 for result
in results
:
3964 table
.add_row([result
["type"], result
["path"], result
["valid"], result
["error"]])
3965 table
.sortby
= "VALID"
3966 table
.align
["PATH"] = "l"
3967 table
.align
["TYPE"] = "l"
3968 table
.align
["ERROR"] = "l"
3970 # except ClientException as inst:
3971 # print("ERROR: {}".format(inst))
3974 @cli_osm.command(name
='package-build',
3975 short_help
='Build the tar.gz of the package')
3976 @click.argument('package-folder')
3977 @click.option('--skip-validation',
3980 help='skip package validation')
3981 @click.option('--skip-charm-build', default
=False, is_flag
=True,
3982 help='the charm will not be compiled, it is assumed to already exist')
3984 def package_build(ctx
,
3989 Build the package NS, VNF given the package_folder.
3992 PACKAGE_FOLDER: Folder of the NS, VNF or NST to be packaged
3995 check_client_version(ctx
.obj
, ctx
.command
.name
)
3996 results
= ctx
.obj
.package_tool
.build(package_folder
,
3997 skip_validation
=skip_validation
,
3998 skip_charm_build
=skip_charm_build
)
4000 # except ClientException as inst:
4001 # print("ERROR: {}".format(inst))
4009 except pycurl
.error
as exc
:
4011 print('Maybe "--hostname" option or OSM_HOSTNAME environment variable needs to be specified')
4012 except ClientException
as exc
:
4013 print("ERROR: {}".format(exc
))
4014 except (FileNotFoundError
, PermissionError
) as exc
:
4015 print("Cannot open file: {}".format(exc
))
4016 except yaml
.YAMLError
as exc
:
4017 print("Invalid YAML format: {}".format(exc
))
4019 # TODO capture other controlled exceptions here
4020 # TODO remove the ClientException captures from all places, unless they do something different
4023 if __name__
== '__main__':