1 |
|
# Copyright 2017-2018 Sandvine |
2 |
|
# Copyright 2018 Telefonica |
3 |
|
# |
4 |
|
# All Rights Reserved. |
5 |
|
# |
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 |
9 |
|
# |
10 |
|
# http://www.apache.org/licenses/LICENSE-2.0 |
11 |
|
# |
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 |
16 |
|
# under the License. |
17 |
0 |
""" |
18 |
|
OSM shell/cli |
19 |
|
""" |
20 |
|
|
21 |
0 |
import click |
22 |
0 |
from osmclient import client |
23 |
0 |
from osmclient.common.exceptions import ClientException, NotFound |
24 |
0 |
from prettytable import PrettyTable |
25 |
0 |
import yaml |
26 |
0 |
import json |
27 |
0 |
import time |
28 |
0 |
import pycurl |
29 |
0 |
import os |
30 |
0 |
import textwrap |
31 |
0 |
import pkg_resources |
32 |
0 |
import logging |
33 |
0 |
from datetime import datetime |
34 |
|
|
35 |
|
|
36 |
|
# Global variables |
37 |
|
|
38 |
0 |
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'], max_content_width=160) |
39 |
|
|
40 |
0 |
def wrap_text(text, width): |
41 |
0 |
wrapper = textwrap.TextWrapper(width=width) |
42 |
0 |
lines = text.splitlines() |
43 |
0 |
return "\n".join(map(wrapper.fill, lines)) |
44 |
|
|
45 |
|
|
46 |
0 |
def trunc_text(text, length): |
47 |
0 |
if len(text) > length: |
48 |
0 |
return text[:(length - 3)] + '...' |
49 |
|
else: |
50 |
0 |
return text |
51 |
|
|
52 |
|
|
53 |
0 |
def check_client_version(obj, what, version='sol005'): |
54 |
|
""" |
55 |
|
Checks the version of the client object and raises error if it not the expected. |
56 |
|
|
57 |
|
:param obj: the client object |
58 |
|
:what: the function or command under evaluation (used when an error is raised) |
59 |
|
:return: - |
60 |
|
:raises ClientError: if the specified version does not match the client version |
61 |
|
""" |
62 |
0 |
logger.debug("") |
63 |
0 |
fullclassname = obj.__module__ + "." + obj.__class__.__name__ |
64 |
0 |
message = 'The following commands or options are only supported with the option "--sol005": {}'.format(what) |
65 |
0 |
if version == 'v1': |
66 |
0 |
message = 'The following commands or options are not supported when using option "--sol005": {}'.format(what) |
67 |
0 |
if fullclassname != 'osmclient.{}.client.Client'.format(version): |
68 |
0 |
raise ClientException(message) |
69 |
0 |
return |
70 |
|
|
71 |
|
|
72 |
0 |
def get_project(project_list, item): |
73 |
|
# project_list = ctx.obj.project.list() |
74 |
0 |
item_project_list = item.get('_admin', {}).get('projects_read') |
75 |
0 |
project_id = 'None' |
76 |
0 |
project_name = 'None' |
77 |
0 |
if item_project_list: |
78 |
0 |
for p1 in item_project_list: |
79 |
0 |
project_id = p1 |
80 |
0 |
for p2 in project_list: |
81 |
0 |
if p2['_id'] == project_id: |
82 |
0 |
project_name = p2['name'] |
83 |
0 |
return project_id, project_name |
84 |
0 |
return project_id, project_name |
85 |
|
|
86 |
|
|
87 |
0 |
def get_vim_name(vim_list, vim_id): |
88 |
0 |
vim_name = '-' |
89 |
0 |
for v in vim_list: |
90 |
0 |
if v['uuid'] == vim_id: |
91 |
0 |
vim_name = v['name'] |
92 |
0 |
break |
93 |
0 |
return vim_name |
94 |
|
|
95 |
|
|
96 |
0 |
@click.group(context_settings=dict(help_option_names=['-h', '--help'], max_content_width=160)) |
97 |
0 |
@click.option('--hostname', |
98 |
|
default="127.0.0.1", |
99 |
|
envvar='OSM_HOSTNAME', |
100 |
|
help='hostname of server. ' + |
101 |
|
'Also can set OSM_HOSTNAME in environment') |
102 |
|
#@click.option('--sol005/--no-sol005', |
103 |
|
# default=True, |
104 |
|
# envvar='OSM_SOL005', |
105 |
|
# help='Use ETSI NFV SOL005 API (default) or the previous SO API. ' + |
106 |
|
# 'Also can set OSM_SOL005 in environment') |
107 |
0 |
@click.option('--user', |
108 |
|
default=None, |
109 |
|
envvar='OSM_USER', |
110 |
|
help='user (defaults to admin). ' + |
111 |
|
'Also can set OSM_USER in environment') |
112 |
0 |
@click.option('--password', |
113 |
|
default=None, |
114 |
|
envvar='OSM_PASSWORD', |
115 |
|
help='password (defaults to admin). ' + |
116 |
|
'Also can set OSM_PASSWORD in environment') |
117 |
0 |
@click.option('--project', |
118 |
|
default=None, |
119 |
|
envvar='OSM_PROJECT', |
120 |
|
help='project (defaults to admin). ' + |
121 |
|
'Also can set OSM_PROJECT in environment') |
122 |
0 |
@click.option('-v', '--verbose', count=True, |
123 |
|
help='increase verbosity (-v INFO, -vv VERBOSE, -vvv DEBUG)') |
124 |
0 |
@click.option('--all-projects', |
125 |
|
default=None, |
126 |
|
is_flag=True, |
127 |
|
help='include all projects') |
128 |
0 |
@click.option('--public/--no-public', default=None, |
129 |
|
help='flag for public items (packages, instances, VIM accounts, etc.)') |
130 |
0 |
@click.option('--project-domain-name', 'project_domain_name', |
131 |
|
default=None, |
132 |
|
envvar='OSM_PROJECT_DOMAIN_NAME', |
133 |
|
help='project domain name for keystone authentication (default to None). ' + |
134 |
|
'Also can set OSM_PROJECT_DOMAIN_NAME in environment') |
135 |
0 |
@click.option('--user-domain-name', 'user_domain_name', |
136 |
|
default=None, |
137 |
|
envvar='OSM_USER_DOMAIN_NAME', |
138 |
|
help='user domain name for keystone authentication (default to None). ' + |
139 |
|
'Also can set OSM_USER_DOMAIN_NAME in environment') |
140 |
|
#@click.option('--so-port', |
141 |
|
# default=None, |
142 |
|
# envvar='OSM_SO_PORT', |
143 |
|
# help='hostname of server. ' + |
144 |
|
# 'Also can set OSM_SO_PORT in environment') |
145 |
|
#@click.option('--so-project', |
146 |
|
# default=None, |
147 |
|
# envvar='OSM_SO_PROJECT', |
148 |
|
# help='Project Name in SO. ' + |
149 |
|
# 'Also can set OSM_SO_PROJECT in environment') |
150 |
|
#@click.option('--ro-hostname', |
151 |
|
# default=None, |
152 |
|
# envvar='OSM_RO_HOSTNAME', |
153 |
|
# help='hostname of RO server. ' + |
154 |
|
# 'Also can set OSM_RO_HOSTNAME in environment') |
155 |
|
#@click.option('--ro-port', |
156 |
|
# default=None, |
157 |
|
# envvar='OSM_RO_PORT', |
158 |
|
# help='hostname of RO server. ' + |
159 |
|
# 'Also can set OSM_RO_PORT in environment') |
160 |
0 |
@click.pass_context |
161 |
|
def cli_osm(ctx, **kwargs): |
162 |
|
global logger |
163 |
0 |
hostname = kwargs.pop("hostname", None) |
164 |
0 |
if hostname is None: |
165 |
0 |
print(( |
166 |
|
"either hostname option or OSM_HOSTNAME " + |
167 |
|
"environment variable needs to be specified")) |
168 |
0 |
exit(1) |
169 |
|
# Remove None values |
170 |
0 |
kwargs = {k: v for k, v in kwargs.items() if v is not None} |
171 |
|
# if so_port is not None: |
172 |
|
# kwargs['so_port']=so_port |
173 |
|
# if so_project is not None: |
174 |
|
# kwargs['so_project']=so_project |
175 |
|
# if ro_hostname is not None: |
176 |
|
# kwargs['ro_host']=ro_hostname |
177 |
|
# if ro_port is not None: |
178 |
|
# kwargs['ro_port']=ro_port |
179 |
0 |
sol005 = os.getenv('OSM_SOL005', True) |
180 |
|
# if user is not None: |
181 |
|
# kwargs['user']=user |
182 |
|
# if password is not None: |
183 |
|
# kwargs['password']=password |
184 |
|
# if project is not None: |
185 |
|
# kwargs['project']=project |
186 |
|
# if all_projects: |
187 |
|
# kwargs['all_projects']=all_projects |
188 |
|
# if public is not None: |
189 |
|
# kwargs['public']=public |
190 |
0 |
ctx.obj = client.Client(host=hostname, sol005=sol005, **kwargs) |
191 |
0 |
logger = logging.getLogger('osmclient') |
192 |
|
|
193 |
|
|
194 |
|
#################### |
195 |
|
# LIST operations |
196 |
|
#################### |
197 |
|
|
198 |
0 |
@cli_osm.command(name='ns-list', short_help='list all NS instances') |
199 |
0 |
@click.option('--filter', default=None, multiple=True, |
200 |
|
help='restricts the list to the NS instances matching the filter.') |
201 |
0 |
@click.option('--long', is_flag=True, |
202 |
|
help='get more details of the NS (project, vim, deployment status, configuration status.') |
203 |
0 |
@click.pass_context |
204 |
|
def ns_list(ctx, filter, long): |
205 |
|
"""list all NS instances |
206 |
|
|
207 |
|
\b |
208 |
|
Options: |
209 |
|
--filter filterExpr Restricts the list to the NS instances matching the filter |
210 |
|
|
211 |
|
\b |
212 |
|
filterExpr consists of one or more strings formatted according to "simpleFilterExpr", |
213 |
|
concatenated using the "&" character: |
214 |
|
|
215 |
|
\b |
216 |
|
filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]* |
217 |
|
simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]* |
218 |
|
op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont" |
219 |
|
attrName := string |
220 |
|
value := scalar value |
221 |
|
|
222 |
|
\b |
223 |
|
where: |
224 |
|
* zero or more occurrences |
225 |
|
? zero or one occurrence |
226 |
|
[] grouping of expressions to be used with ? and * |
227 |
|
"" quotation marks for marking string constants |
228 |
|
<> name separator |
229 |
|
|
230 |
|
\b |
231 |
|
"AttrName" is the name of one attribute in the data type that defines the representation |
232 |
|
of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of |
233 |
|
<attrName> entries to filter by attributes deeper in the hierarchy of a structured document. |
234 |
|
"Op" stands for the comparison operator. If the expression has concatenated <attrName> |
235 |
|
entries, it means that the operator "op" is applied to the attribute addressed by the last |
236 |
|
<attrName> entry included in the concatenation. All simple filter expressions are combined |
237 |
|
by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>, |
238 |
|
the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The |
239 |
|
concatenation of all "attrName" entries except the leaf attribute is called the "attribute |
240 |
|
prefix". If an attribute referenced in an expression is an array, an object that contains a |
241 |
|
corresponding array shall be considered to match the expression if any of the elements in the |
242 |
|
array matches all expressions that have the same attribute prefix. |
243 |
|
|
244 |
|
\b |
245 |
|
Filter examples: |
246 |
|
--filter admin-status=ENABLED |
247 |
|
--filter nsd-ref=<NSD_NAME> |
248 |
|
--filter nsd.vendor=<VENDOR> |
249 |
|
--filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME> |
250 |
|
--filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME> |
251 |
|
""" |
252 |
0 |
def summarize_deployment_status(status_dict): |
253 |
|
#Nets |
254 |
0 |
summary = "" |
255 |
0 |
if not status_dict: |
256 |
0 |
return summary |
257 |
0 |
n_nets = 0 |
258 |
0 |
status_nets = {} |
259 |
0 |
net_list = status_dict.get('nets',[]) |
260 |
0 |
for net in net_list: |
261 |
0 |
n_nets += 1 |
262 |
0 |
if net['status'] not in status_nets: |
263 |
0 |
status_nets[net['status']] = 1 |
264 |
|
else: |
265 |
0 |
status_nets[net['status']] +=1 |
266 |
0 |
message = "Nets: " |
267 |
0 |
for k,v in status_nets.items(): |
268 |
0 |
message += "{}:{},".format(k,v) |
269 |
0 |
message += "TOTAL:{}".format(n_nets) |
270 |
0 |
summary += "{}".format(message) |
271 |
|
#VMs and VNFs |
272 |
0 |
n_vms = 0 |
273 |
0 |
status_vms = {} |
274 |
0 |
status_vnfs = {} |
275 |
0 |
vnf_list = status_dict['vnfs'] |
276 |
0 |
for vnf in vnf_list: |
277 |
0 |
member_vnf_index = vnf['member_vnf_index'] |
278 |
0 |
if member_vnf_index not in status_vnfs: |
279 |
0 |
status_vnfs[member_vnf_index] = {} |
280 |
0 |
for vm in vnf['vms']: |
281 |
0 |
n_vms += 1 |
282 |
0 |
if vm['status'] not in status_vms: |
283 |
0 |
status_vms[vm['status']] = 1 |
284 |
|
else: |
285 |
0 |
status_vms[vm['status']] +=1 |
286 |
0 |
if vm['status'] not in status_vnfs[member_vnf_index]: |
287 |
0 |
status_vnfs[member_vnf_index][vm['status']] = 1 |
288 |
|
else: |
289 |
0 |
status_vnfs[member_vnf_index][vm['status']] += 1 |
290 |
0 |
message = "VMs: " |
291 |
0 |
for k,v in status_vms.items(): |
292 |
0 |
message += "{}:{},".format(k,v) |
293 |
0 |
message += "TOTAL:{}".format(n_vms) |
294 |
0 |
summary += "\n{}".format(message) |
295 |
0 |
summary += "\nNFs:" |
296 |
0 |
for k,v in status_vnfs.items(): |
297 |
0 |
total = 0 |
298 |
0 |
message = "\n {} VMs: ".format(k) |
299 |
0 |
for k2,v2 in v.items(): |
300 |
0 |
message += "{}:{},".format(k2,v2) |
301 |
0 |
total += v2 |
302 |
0 |
message += "TOTAL:{}".format(total) |
303 |
0 |
summary += message |
304 |
0 |
return summary |
305 |
|
|
306 |
0 |
def summarize_config_status(ee_list): |
307 |
0 |
summary = "" |
308 |
0 |
if not ee_list: |
309 |
0 |
return summary |
310 |
0 |
n_ee = 0 |
311 |
0 |
status_ee = {} |
312 |
0 |
for ee in ee_list: |
313 |
0 |
n_ee += 1 |
314 |
0 |
if ee['elementType'] not in status_ee: |
315 |
0 |
status_ee[ee['elementType']] = {} |
316 |
0 |
status_ee[ee['elementType']][ee['status']] = 1 |
317 |
0 |
continue |
318 |
0 |
if ee['status'] in status_ee[ee['elementType']]: |
319 |
0 |
status_ee[ee['elementType']][ee['status']] += 1 |
320 |
|
else: |
321 |
0 |
status_ee[ee['elementType']][ee['status']] = 1 |
322 |
0 |
for elementType in ["KDU", "VDU", "PDU", "VNF", "NS"]: |
323 |
0 |
if elementType in status_ee: |
324 |
0 |
message = "" |
325 |
0 |
total = 0 |
326 |
0 |
for k,v in status_ee[elementType].items(): |
327 |
0 |
message += "{}:{},".format(k,v) |
328 |
0 |
total += v |
329 |
0 |
message += "TOTAL:{}\n".format(total) |
330 |
0 |
summary += "{}: {}".format(elementType, message) |
331 |
0 |
summary += "TOTAL Exec. Env.: {}".format(n_ee) |
332 |
0 |
return summary |
333 |
|
|
334 |
0 |
logger.debug("") |
335 |
0 |
if filter: |
336 |
0 |
check_client_version(ctx.obj, '--filter') |
337 |
0 |
filter='&'.join(filter) |
338 |
0 |
resp = ctx.obj.ns.list(filter) |
339 |
|
else: |
340 |
0 |
resp = ctx.obj.ns.list() |
341 |
0 |
if long: |
342 |
0 |
table = PrettyTable( |
343 |
|
['ns instance name', |
344 |
|
'id', |
345 |
|
'date', |
346 |
|
'ns state', |
347 |
|
'current operation', |
348 |
|
'error details', |
349 |
|
'project', |
350 |
|
'vim (inst param)', |
351 |
|
'deployment status', |
352 |
|
'configuration status']) |
353 |
0 |
project_list = ctx.obj.project.list() |
354 |
0 |
try: |
355 |
0 |
vim_list = ctx.obj.vim.list() |
356 |
0 |
except: |
357 |
0 |
vim_list = [] |
358 |
|
else: |
359 |
0 |
table = PrettyTable( |
360 |
|
['ns instance name', |
361 |
|
'id', |
362 |
|
'date', |
363 |
|
'ns state', |
364 |
|
'current operation', |
365 |
|
'error details']) |
366 |
0 |
for ns in resp: |
367 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
368 |
0 |
if fullclassname == 'osmclient.sol005.client.Client': |
369 |
0 |
nsr = ns |
370 |
0 |
logger.debug('NS info: {}'.format(nsr)) |
371 |
0 |
nsr_name = nsr['name'] |
372 |
0 |
nsr_id = nsr['_id'] |
373 |
0 |
date = datetime.fromtimestamp(nsr['create-time']).strftime("%Y-%m-%dT%H:%M:%S") |
374 |
0 |
ns_state = nsr.get('nsState', nsr['_admin']['nsState']) |
375 |
0 |
if long: |
376 |
0 |
deployment_status = summarize_deployment_status(nsr.get('deploymentStatus')) |
377 |
0 |
config_status = summarize_config_status(nsr.get('configurationStatus')) |
378 |
0 |
project_id, project_name = get_project(project_list, nsr) |
379 |
|
#project = '{} ({})'.format(project_name, project_id) |
380 |
0 |
project = project_name |
381 |
0 |
vim_id = nsr.get('datacenter') |
382 |
0 |
vim_name = get_vim_name(vim_list, vim_id) |
383 |
|
|
384 |
|
#vim = '{} ({})'.format(vim_name, vim_id) |
385 |
0 |
vim = vim_name |
386 |
0 |
if 'currentOperation' in nsr: |
387 |
0 |
current_operation = "{} ({})".format(nsr['currentOperation'],nsr['currentOperationID']) |
388 |
|
else: |
389 |
0 |
current_operation = "{} ({})".format(nsr['_admin'].get('current-operation','-'), nsr['_admin']['nslcmop']) |
390 |
0 |
error_details = "N/A" |
391 |
0 |
if ns_state == "BROKEN" or ns_state == "DEGRADED" or \ |
392 |
|
('currentOperation' not in nsr and nsr.get('errorDescription')): |
393 |
0 |
error_details = "{}\nDetail: {}".format(nsr['errorDescription'], nsr['errorDetail']) |
394 |
|
else: |
395 |
0 |
nsopdata = ctx.obj.ns.get_opdata(ns['id']) |
396 |
0 |
nsr = nsopdata['nsr:nsr'] |
397 |
0 |
nsr_name = nsr['name-ref'] |
398 |
0 |
nsr_id = nsr['ns-instance-config-ref'] |
399 |
0 |
date = '-' |
400 |
0 |
project = '-' |
401 |
0 |
deployment_status = nsr['operational-status'] if 'operational-status' in nsr else 'Not found' |
402 |
0 |
ns_state = deployment_status |
403 |
0 |
config_status = nsr.get('config-status', 'Not found') |
404 |
0 |
current_operation = "Unknown" |
405 |
0 |
error_details = nsr.get('detailed-status', 'Not found') |
406 |
0 |
if config_status == "config_not_needed": |
407 |
0 |
config_status = "configured (no charms)" |
408 |
|
|
409 |
0 |
if long: |
410 |
0 |
table.add_row( |
411 |
|
[nsr_name, |
412 |
|
nsr_id, |
413 |
|
date, |
414 |
|
ns_state, |
415 |
|
current_operation, |
416 |
|
wrap_text(text=error_details,width=40), |
417 |
|
project, |
418 |
|
vim, |
419 |
|
deployment_status, |
420 |
|
config_status]) |
421 |
|
else: |
422 |
0 |
table.add_row( |
423 |
|
[nsr_name, |
424 |
|
nsr_id, |
425 |
|
date, |
426 |
|
ns_state, |
427 |
|
current_operation, |
428 |
|
wrap_text(text=error_details,width=40)]) |
429 |
0 |
table.align = 'l' |
430 |
0 |
print(table) |
431 |
0 |
print('To get the history of all operations over a NS, run "osm ns-op-list NS_ID"') |
432 |
0 |
print('For more details on the current operation, run "osm ns-op-show OPERATION_ID"') |
433 |
|
|
434 |
0 |
def nsd_list(ctx, filter, long): |
435 |
0 |
logger.debug("") |
436 |
0 |
if filter: |
437 |
0 |
check_client_version(ctx.obj, '--filter') |
438 |
0 |
filter='&'.join(filter) |
439 |
0 |
resp = ctx.obj.nsd.list(filter) |
440 |
|
else: |
441 |
0 |
resp = ctx.obj.nsd.list() |
442 |
|
# print(yaml.safe_dump(resp)) |
443 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
444 |
0 |
if fullclassname == 'osmclient.sol005.client.Client': |
445 |
0 |
if long: |
446 |
0 |
table = PrettyTable(['nsd name', 'id', 'onboarding state', 'operational state', |
447 |
|
'usage state', 'date', 'last update']) |
448 |
|
else: |
449 |
0 |
table = PrettyTable(['nsd name', 'id']) |
450 |
0 |
for nsd in resp: |
451 |
0 |
name = nsd.get('id', '-') |
452 |
0 |
if long: |
453 |
0 |
onb_state = nsd['_admin'].get('onboardingState','-') |
454 |
0 |
op_state = nsd['_admin'].get('operationalState','-') |
455 |
0 |
usage_state = nsd['_admin'].get('usageState','-') |
456 |
0 |
date = datetime.fromtimestamp(nsd['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S") |
457 |
0 |
last_update = datetime.fromtimestamp(nsd['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S") |
458 |
0 |
table.add_row([name, nsd['_id'], onb_state, op_state, usage_state, date, last_update]) |
459 |
|
else: |
460 |
0 |
table.add_row([name, nsd['_id']]) |
461 |
|
else: |
462 |
0 |
table = PrettyTable(['nsd name', 'id']) |
463 |
0 |
for nsd in resp: |
464 |
0 |
table.add_row([nsd['name'], nsd['id']]) |
465 |
0 |
table.align = 'l' |
466 |
0 |
print(table) |
467 |
|
|
468 |
|
|
469 |
0 |
@cli_osm.command(name='nsd-list', short_help='list all NS packages') |
470 |
0 |
@click.option('--filter', default=None, multiple=True, |
471 |
|
help='restricts the list to the NSD/NSpkg matching the filter') |
472 |
0 |
@click.option('--long', is_flag=True, help='get more details') |
473 |
0 |
@click.pass_context |
474 |
|
def nsd_list1(ctx, filter, long): |
475 |
|
"""list all NSD/NS pkg in the system""" |
476 |
0 |
logger.debug("") |
477 |
0 |
nsd_list(ctx, filter, long) |
478 |
|
|
479 |
|
|
480 |
0 |
@cli_osm.command(name='nspkg-list', short_help='list all NS packages') |
481 |
0 |
@click.option('--filter', default=None, multiple=True, |
482 |
|
help='restricts the list to the NSD/NSpkg matching the filter') |
483 |
0 |
@click.option('--long', is_flag=True, help='get more details') |
484 |
0 |
@click.pass_context |
485 |
|
def nsd_list2(ctx, filter, long): |
486 |
|
"""list all NS packages""" |
487 |
0 |
logger.debug("") |
488 |
0 |
nsd_list(ctx, filter, long) |
489 |
|
|
490 |
|
|
491 |
0 |
def pkg_repo_list(ctx, pkgtype, filter, repo, long): |
492 |
0 |
resp = ctx.obj.osmrepo.pkg_list(pkgtype, filter, repo) |
493 |
0 |
if long: |
494 |
0 |
table = PrettyTable(['nfpkg name', 'vendor', 'version', 'latest', 'description', 'repository']) |
495 |
|
else: |
496 |
0 |
table = PrettyTable(['nfpkg name', 'repository']) |
497 |
0 |
for vnfd in resp: |
498 |
0 |
name = vnfd.get('id', vnfd.get('name','-')) |
499 |
0 |
repository = vnfd.get('repository') |
500 |
0 |
if long: |
501 |
0 |
vendor = vnfd.get('provider', vnfd.get('vendor')) |
502 |
0 |
version = vnfd.get('version') |
503 |
0 |
description = vnfd.get('description') |
504 |
0 |
latest = vnfd.get('latest') |
505 |
0 |
table.add_row([name, vendor, version, latest, description, repository]) |
506 |
|
else: |
507 |
0 |
table.add_row([name, repository]) |
508 |
0 |
table.align = 'l' |
509 |
0 |
print(table) |
510 |
|
|
511 |
0 |
def vnfd_list(ctx, nf_type, filter, long): |
512 |
0 |
logger.debug("") |
513 |
0 |
if nf_type: |
514 |
0 |
check_client_version(ctx.obj, '--nf_type') |
515 |
0 |
elif filter: |
516 |
0 |
check_client_version(ctx.obj, '--filter') |
517 |
0 |
if filter: |
518 |
0 |
filter='&'.join(filter) |
519 |
0 |
if nf_type: |
520 |
0 |
if nf_type == "vnf": |
521 |
0 |
nf_filter = "_admin.type=vnfd" |
522 |
0 |
elif nf_type == "pnf": |
523 |
0 |
nf_filter = "_admin.type=pnfd" |
524 |
0 |
elif nf_type == "hnf": |
525 |
0 |
nf_filter = "_admin.type=hnfd" |
526 |
|
else: |
527 |
0 |
raise ClientException('wrong value for "--nf_type" option, allowed values: vnf, pnf, hnf') |
528 |
0 |
if filter: |
529 |
0 |
filter = '{}&{}'.format(nf_filter, filter) |
530 |
|
else: |
531 |
0 |
filter = nf_filter |
532 |
0 |
if filter: |
533 |
0 |
resp = ctx.obj.vnfd.list(filter) |
534 |
|
else: |
535 |
0 |
resp = ctx.obj.vnfd.list() |
536 |
|
# print(yaml.safe_dump(resp)) |
537 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
538 |
0 |
if fullclassname == 'osmclient.sol005.client.Client': |
539 |
0 |
if long: |
540 |
0 |
table = PrettyTable(['nfpkg name', 'id', 'desc type', 'vendor', 'version', 'onboarding state', 'operational state', |
541 |
|
'usage state', 'date', 'last update']) |
542 |
|
else: |
543 |
0 |
table = PrettyTable(['nfpkg name', 'id', 'desc type']) |
544 |
0 |
for vnfd in resp: |
545 |
0 |
name = vnfd.get('id', vnfd.get('name','-')) |
546 |
0 |
descriptor_type = 'sol006' if 'product-name' in vnfd else 'rel8' |
547 |
0 |
if long: |
548 |
0 |
onb_state = vnfd['_admin'].get('onboardingState','-') |
549 |
0 |
op_state = vnfd['_admin'].get('operationalState','-') |
550 |
0 |
vendor = vnfd.get('provider', vnfd.get('vendor')) |
551 |
0 |
version = vnfd.get('version') |
552 |
0 |
usage_state = vnfd['_admin'].get('usageState','-') |
553 |
0 |
date = datetime.fromtimestamp(vnfd['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S") |
554 |
0 |
last_update = datetime.fromtimestamp(vnfd['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S") |
555 |
0 |
table.add_row([name, vnfd['_id'], descriptor_type, vendor, version, onb_state, op_state, usage_state, date, last_update]) |
556 |
|
else: |
557 |
0 |
table.add_row([name, vnfd['_id'], descriptor_type]) |
558 |
|
else: |
559 |
0 |
table = PrettyTable(['nfpkg name', 'id']) |
560 |
0 |
for vnfd in resp: |
561 |
0 |
table.add_row([vnfd['name'], vnfd['id']]) |
562 |
0 |
table.align = 'l' |
563 |
0 |
print(table) |
564 |
|
|
565 |
|
|
566 |
0 |
@cli_osm.command(name='vnfd-list', short_help='list all xNF packages (VNF, HNF, PNF)') |
567 |
0 |
@click.option('--nf_type', help='type of NF (vnf, pnf, hnf)') |
568 |
0 |
@click.option('--filter', default=None, multiple=True, |
569 |
|
help='restricts the list to the NF pkg matching the filter') |
570 |
0 |
@click.option('--long', is_flag=True, help='get more details') |
571 |
0 |
@click.pass_context |
572 |
|
def vnfd_list1(ctx, nf_type, filter, long): |
573 |
|
"""list all xNF packages (VNF, HNF, PNF)""" |
574 |
0 |
logger.debug("") |
575 |
0 |
vnfd_list(ctx, nf_type, filter, long) |
576 |
|
|
577 |
|
|
578 |
0 |
@cli_osm.command(name='vnfpkg-list', short_help='list all xNF packages (VNF, HNF, PNF)') |
579 |
0 |
@click.option('--nf_type', help='type of NF (vnf, pnf, hnf)') |
580 |
0 |
@click.option('--filter', default=None, multiple=True, |
581 |
|
help='restricts the list to the NFpkg matching the filter') |
582 |
0 |
@click.option('--long', is_flag=True, help='get more details') |
583 |
0 |
@click.pass_context |
584 |
|
def vnfd_list2(ctx, nf_type, filter, long): |
585 |
|
"""list all xNF packages (VNF, HNF, PNF)""" |
586 |
0 |
logger.debug("") |
587 |
0 |
vnfd_list(ctx, nf_type, filter, long) |
588 |
|
|
589 |
|
|
590 |
0 |
@cli_osm.command(name='nfpkg-list', short_help='list all xNF packages (VNF, HNF, PNF)') |
591 |
0 |
@click.option('--nf_type', help='type of NF (vnf, pnf, hnf)') |
592 |
0 |
@click.option('--filter', default=None, multiple=True, |
593 |
|
help='restricts the list to the NFpkg matching the filter') |
594 |
0 |
@click.option('--long', is_flag=True, help='get more details') |
595 |
0 |
@click.pass_context |
596 |
|
def nfpkg_list(ctx, nf_type, filter, long): |
597 |
|
"""list all xNF packages (VNF, HNF, PNF)""" |
598 |
0 |
logger.debug("") |
599 |
|
# try: |
600 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
601 |
0 |
vnfd_list(ctx, nf_type, filter, long) |
602 |
|
# except ClientException as e: |
603 |
|
# print(str(e)) |
604 |
|
# exit(1) |
605 |
|
|
606 |
|
|
607 |
0 |
@cli_osm.command(name='vnfpkg-repo-list', short_help='list all xNF from OSM repositories') |
608 |
0 |
@click.option('--filter', default=None, multiple=True, |
609 |
|
help='restricts the list to the NFpkg matching the filter') |
610 |
0 |
@click.option('--repo', default=None, |
611 |
|
help='restricts the list to a particular OSM repository') |
612 |
0 |
@click.option('--long', is_flag=True, help='get more details') |
613 |
0 |
@click.pass_context |
614 |
|
def nfpkg_repo_list1(ctx, filter, repo, long): |
615 |
|
"""list xNF packages from OSM repositories""" |
616 |
0 |
pkgtype = 'vnf' |
617 |
0 |
pkg_repo_list(ctx, pkgtype, filter, repo, long) |
618 |
|
|
619 |
0 |
@cli_osm.command(name='nfpkg-repo-list', short_help='list all xNF from OSM repositories') |
620 |
0 |
@click.option('--filter', default=None, multiple=True, |
621 |
|
help='restricts the list to the NFpkg matching the filter') |
622 |
0 |
@click.option('--repo', default=None, |
623 |
|
help='restricts the list to a particular OSM repository') |
624 |
0 |
@click.option('--long', is_flag=True, help='get more details') |
625 |
0 |
@click.pass_context |
626 |
|
def nfpkg_repo_list2(ctx, filter, repo, long): |
627 |
|
"""list xNF packages from OSM repositories""" |
628 |
0 |
pkgtype = 'vnf' |
629 |
0 |
pkg_repo_list(ctx, pkgtype, filter, repo, long) |
630 |
|
|
631 |
|
|
632 |
0 |
def vnf_list(ctx, ns, filter, long): |
633 |
|
# try: |
634 |
0 |
if ns or filter: |
635 |
0 |
if ns: |
636 |
0 |
check_client_version(ctx.obj, '--ns') |
637 |
0 |
if filter: |
638 |
0 |
filter='&'.join(filter) |
639 |
0 |
check_client_version(ctx.obj, '--filter') |
640 |
0 |
resp = ctx.obj.vnf.list(ns, filter) |
641 |
|
else: |
642 |
0 |
resp = ctx.obj.vnf.list() |
643 |
|
# except ClientException as e: |
644 |
|
# print(str(e)) |
645 |
|
# exit(1) |
646 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
647 |
0 |
if fullclassname == 'osmclient.sol005.client.Client': |
648 |
0 |
field_names = ['vnf id', 'name', 'ns id', 'vnf member index', |
649 |
|
'vnfd name', 'vim account id', 'ip address'] |
650 |
0 |
if long: |
651 |
0 |
field_names = ['vnf id', 'name', 'ns id', 'vnf member index', |
652 |
|
'vnfd name', 'vim account id', 'ip address', |
653 |
|
'date', 'last update'] |
654 |
0 |
table = PrettyTable(field_names) |
655 |
0 |
for vnfr in resp: |
656 |
0 |
name = vnfr['name'] if 'name' in vnfr else '-' |
657 |
0 |
new_row = [vnfr['_id'], name, vnfr['nsr-id-ref'], |
658 |
|
vnfr['member-vnf-index-ref'], vnfr['vnfd-ref'], |
659 |
|
vnfr['vim-account-id'], vnfr['ip-address']] |
660 |
0 |
if long: |
661 |
0 |
date = datetime.fromtimestamp(vnfr['_admin']['created']).strftime("%Y-%m-%dT%H:%M:%S") |
662 |
0 |
last_update = datetime.fromtimestamp(vnfr['_admin']['modified']).strftime("%Y-%m-%dT%H:%M:%S") |
663 |
0 |
new_row.extend([date, last_update]) |
664 |
0 |
table.add_row(new_row) |
665 |
|
else: |
666 |
0 |
table = PrettyTable( |
667 |
|
['vnf name', |
668 |
|
'id', |
669 |
|
'operational status', |
670 |
|
'config status']) |
671 |
0 |
for vnfr in resp: |
672 |
0 |
if 'mgmt-interface' not in vnfr: |
673 |
0 |
vnfr['mgmt-interface'] = {} |
674 |
0 |
vnfr['mgmt-interface']['ip-address'] = None |
675 |
0 |
table.add_row( |
676 |
|
[vnfr['name'], |
677 |
|
vnfr['id'], |
678 |
|
vnfr['operational-status'], |
679 |
|
vnfr['config-status']]) |
680 |
0 |
table.align = 'l' |
681 |
0 |
print(table) |
682 |
|
|
683 |
|
|
684 |
0 |
@cli_osm.command(name='vnf-list', short_help='list all NF instances') |
685 |
0 |
@click.option('--ns', default=None, help='NS instance id or name to restrict the NF list') |
686 |
0 |
@click.option('--filter', default=None, multiple=True, |
687 |
|
help='restricts the list to the NF instances matching the filter.') |
688 |
0 |
@click.option('--long', is_flag=True, help='get more details') |
689 |
0 |
@click.pass_context |
690 |
|
def vnf_list1(ctx, ns, filter, long): |
691 |
|
"""list all NF instances""" |
692 |
0 |
logger.debug("") |
693 |
0 |
vnf_list(ctx, ns, filter, long) |
694 |
|
|
695 |
0 |
@cli_osm.command(name='nsd-repo-list', short_help='list all NS from OSM repositories') |
696 |
0 |
@click.option('--filter', default=None, multiple=True, |
697 |
|
help='restricts the list to the NS matching the filter') |
698 |
0 |
@click.option('--repo', default=None, |
699 |
|
help='restricts the list to a particular OSM repository') |
700 |
0 |
@click.option('--long', is_flag=True, help='get more details') |
701 |
0 |
@click.pass_context |
702 |
|
def nspkg_repo_list(ctx, filter, repo, long): |
703 |
|
"""list xNF packages from OSM repositories""" |
704 |
0 |
pkgtype = 'ns' |
705 |
0 |
pkg_repo_list(ctx, pkgtype, filter, repo, long) |
706 |
|
|
707 |
0 |
@cli_osm.command(name='nspkg-repo-list', short_help='list all NS from OSM repositories') |
708 |
0 |
@click.option('--filter', default=None, multiple=True, |
709 |
|
help='restricts the list to the NS matching the filter') |
710 |
0 |
@click.option('--repo', default=None, |
711 |
|
help='restricts the list to a particular OSM repository') |
712 |
0 |
@click.option('--long', is_flag=True, help='get more details') |
713 |
0 |
@click.pass_context |
714 |
|
def nspkg_repo_list2(ctx, filter, repo, long): |
715 |
|
"""list xNF packages from OSM repositories""" |
716 |
0 |
pkgtype = 'ns' |
717 |
0 |
pkg_repo_list(ctx, pkgtype, filter, repo, long) |
718 |
|
|
719 |
0 |
@cli_osm.command(name='nf-list', short_help='list all NF instances') |
720 |
0 |
@click.option('--ns', default=None, help='NS instance id or name to restrict the NF list') |
721 |
0 |
@click.option('--filter', default=None, multiple=True, |
722 |
|
help='restricts the list to the NF instances matching the filter.') |
723 |
0 |
@click.option('--long', is_flag=True, help='get more details') |
724 |
0 |
@click.pass_context |
725 |
|
def nf_list(ctx, ns, filter, long): |
726 |
|
"""list all NF instances |
727 |
|
|
728 |
|
\b |
729 |
|
Options: |
730 |
|
--ns TEXT NS instance id or name to restrict the VNF list |
731 |
|
--filter filterExpr Restricts the list to the VNF instances matching the filter |
732 |
|
|
733 |
|
\b |
734 |
|
filterExpr consists of one or more strings formatted according to "simpleFilterExpr", |
735 |
|
concatenated using the "&" character: |
736 |
|
|
737 |
|
\b |
738 |
|
filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]* |
739 |
|
simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]* |
740 |
|
op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont" |
741 |
|
attrName := string |
742 |
|
value := scalar value |
743 |
|
|
744 |
|
\b |
745 |
|
where: |
746 |
|
* zero or more occurrences |
747 |
|
? zero or one occurrence |
748 |
|
[] grouping of expressions to be used with ? and * |
749 |
|
"" quotation marks for marking string constants |
750 |
|
<> name separator |
751 |
|
|
752 |
|
\b |
753 |
|
"AttrName" is the name of one attribute in the data type that defines the representation |
754 |
|
of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of |
755 |
|
<attrName> entries to filter by attributes deeper in the hierarchy of a structured document. |
756 |
|
"Op" stands for the comparison operator. If the expression has concatenated <attrName> |
757 |
|
entries, it means that the operator "op" is applied to the attribute addressed by the last |
758 |
|
<attrName> entry included in the concatenation. All simple filter expressions are combined |
759 |
|
by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>, |
760 |
|
the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The |
761 |
|
concatenation of all "attrName" entries except the leaf attribute is called the "attribute |
762 |
|
prefix". If an attribute referenced in an expression is an array, an object that contains a |
763 |
|
corresponding array shall be considered to match the expression if any of the elements in the |
764 |
|
array matches all expressions that have the same attribute prefix. |
765 |
|
|
766 |
|
\b |
767 |
|
Filter examples: |
768 |
|
--filter vim-account-id=<VIM_ACCOUNT_ID> |
769 |
|
--filter vnfd-ref=<VNFD_NAME> |
770 |
|
--filter vdur.ip-address=<IP_ADDRESS> |
771 |
|
--filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS> |
772 |
|
""" |
773 |
0 |
logger.debug("") |
774 |
0 |
vnf_list(ctx, ns, filter, long) |
775 |
|
|
776 |
|
|
777 |
0 |
@cli_osm.command(name='ns-op-list', short_help='shows the history of operations over a NS instance') |
778 |
0 |
@click.argument('name') |
779 |
0 |
@click.option('--long', is_flag=True, |
780 |
|
help='get more details of the NS operation (date, ).') |
781 |
0 |
@click.pass_context |
782 |
|
def ns_op_list(ctx, name, long): |
783 |
|
"""shows the history of operations over a NS instance |
784 |
|
|
785 |
|
NAME: name or ID of the NS instance |
786 |
|
""" |
787 |
0 |
def formatParams(params): |
788 |
0 |
if params['lcmOperationType']=='instantiate': |
789 |
0 |
params.pop('nsDescription') |
790 |
0 |
params.pop('nsName') |
791 |
0 |
params.pop('nsdId') |
792 |
0 |
params.pop('nsr_id') |
793 |
0 |
elif params['lcmOperationType']=='action': |
794 |
0 |
params.pop('primitive') |
795 |
0 |
params.pop('lcmOperationType') |
796 |
0 |
params.pop('nsInstanceId') |
797 |
0 |
return params |
798 |
|
|
799 |
0 |
logger.debug("") |
800 |
|
# try: |
801 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
802 |
0 |
resp = ctx.obj.ns.list_op(name) |
803 |
|
# except ClientException as e: |
804 |
|
# print(str(e)) |
805 |
|
# exit(1) |
806 |
|
|
807 |
0 |
if long: |
808 |
0 |
table = PrettyTable(['id', 'operation', 'action_name', 'operation_params', 'status', 'date', 'last update', 'detail']) |
809 |
|
else: |
810 |
0 |
table = PrettyTable(['id', 'operation', 'action_name', 'status', 'date', 'detail']) |
811 |
|
|
812 |
|
#print(yaml.safe_dump(resp)) |
813 |
0 |
for op in resp: |
814 |
0 |
action_name = "N/A" |
815 |
0 |
if op['lcmOperationType']=='action': |
816 |
0 |
action_name = op['operationParams']['primitive'] |
817 |
0 |
detail = "-" |
818 |
0 |
if op['operationState'] == 'PROCESSING': |
819 |
0 |
if op['queuePosition'] is not None and op['queuePosition'] > 0: |
820 |
0 |
detail = "In queue. Current position: {}".format(op['queuePosition']) |
821 |
0 |
elif op['lcmOperationType'] in ('instantiate', 'terminate'): |
822 |
0 |
if op['stage']: |
823 |
0 |
detail = op['stage'] |
824 |
0 |
elif op['operationState'] in ('FAILED', 'FAILED_TEMP'): |
825 |
0 |
detail = op.get('errorMessage','-') |
826 |
0 |
date = datetime.fromtimestamp(op['startTime']).strftime("%Y-%m-%dT%H:%M:%S") |
827 |
0 |
last_update = datetime.fromtimestamp(op['statusEnteredTime']).strftime("%Y-%m-%dT%H:%M:%S") |
828 |
0 |
if long: |
829 |
0 |
table.add_row([op['id'], |
830 |
|
op['lcmOperationType'], |
831 |
|
action_name, |
832 |
|
wrap_text(text=json.dumps(formatParams(op['operationParams']),indent=2),width=50), |
833 |
|
op['operationState'], |
834 |
|
date, |
835 |
|
last_update, |
836 |
|
wrap_text(text=detail,width=50)]) |
837 |
|
else: |
838 |
0 |
table.add_row([op['id'], op['lcmOperationType'], action_name, |
839 |
|
op['operationState'], date, wrap_text(text=detail or "",width=50)]) |
840 |
0 |
table.align = 'l' |
841 |
0 |
print(table) |
842 |
|
|
843 |
|
|
844 |
0 |
def nsi_list(ctx, filter): |
845 |
|
"""list all Network Slice Instances""" |
846 |
0 |
logger.debug("") |
847 |
|
# try: |
848 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
849 |
0 |
if filter: |
850 |
0 |
filter='&'.join(filter) |
851 |
0 |
resp = ctx.obj.nsi.list(filter) |
852 |
|
# except ClientException as e: |
853 |
|
# print(str(e)) |
854 |
|
# exit(1) |
855 |
0 |
table = PrettyTable( |
856 |
|
['netslice instance name', |
857 |
|
'id', |
858 |
|
'operational status', |
859 |
|
'config status', |
860 |
|
'detailed status']) |
861 |
0 |
for nsi in resp: |
862 |
0 |
nsi_name = nsi['name'] |
863 |
0 |
nsi_id = nsi['_id'] |
864 |
0 |
opstatus = nsi['operational-status'] if 'operational-status' in nsi else 'Not found' |
865 |
0 |
configstatus = nsi['config-status'] if 'config-status' in nsi else 'Not found' |
866 |
0 |
detailed_status = nsi['detailed-status'] if 'detailed-status' in nsi else 'Not found' |
867 |
0 |
if configstatus == "config_not_needed": |
868 |
0 |
configstatus = "configured (no charms)" |
869 |
0 |
table.add_row( |
870 |
|
[nsi_name, |
871 |
|
nsi_id, |
872 |
|
opstatus, |
873 |
|
configstatus, |
874 |
|
detailed_status]) |
875 |
0 |
table.align = 'l' |
876 |
0 |
print(table) |
877 |
|
|
878 |
|
|
879 |
0 |
@cli_osm.command(name='nsi-list', short_help='list all Network Slice Instances (NSI)') |
880 |
0 |
@click.option('--filter', default=None, multiple=True, |
881 |
|
help='restricts the list to the Network Slice Instances matching the filter') |
882 |
0 |
@click.pass_context |
883 |
|
def nsi_list1(ctx, filter): |
884 |
|
"""list all Network Slice Instances (NSI)""" |
885 |
0 |
logger.debug("") |
886 |
0 |
nsi_list(ctx, filter) |
887 |
|
|
888 |
|
|
889 |
0 |
@cli_osm.command(name='netslice-instance-list', short_help='list all Network Slice Instances (NSI)') |
890 |
0 |
@click.option('--filter', default=None, multiple=True, |
891 |
|
help='restricts the list to the Network Slice Instances matching the filter') |
892 |
0 |
@click.pass_context |
893 |
|
def nsi_list2(ctx, filter): |
894 |
|
"""list all Network Slice Instances (NSI)""" |
895 |
0 |
logger.debug("") |
896 |
0 |
nsi_list(ctx, filter) |
897 |
|
|
898 |
|
|
899 |
0 |
def nst_list(ctx, filter): |
900 |
0 |
logger.debug("") |
901 |
|
# try: |
902 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
903 |
0 |
if filter: |
904 |
0 |
filter='&'.join(filter) |
905 |
0 |
resp = ctx.obj.nst.list(filter) |
906 |
|
# except ClientException as e: |
907 |
|
# print(str(e)) |
908 |
|
# exit(1) |
909 |
|
# print(yaml.safe_dump(resp)) |
910 |
0 |
table = PrettyTable(['nst name', 'id']) |
911 |
0 |
for nst in resp: |
912 |
0 |
name = nst['name'] if 'name' in nst else '-' |
913 |
0 |
table.add_row([name, nst['_id']]) |
914 |
0 |
table.align = 'l' |
915 |
0 |
print(table) |
916 |
|
|
917 |
|
|
918 |
0 |
@cli_osm.command(name='nst-list', short_help='list all Network Slice Templates (NST)') |
919 |
0 |
@click.option('--filter', default=None, multiple=True, |
920 |
|
help='restricts the list to the NST matching the filter') |
921 |
0 |
@click.pass_context |
922 |
|
def nst_list1(ctx, filter): |
923 |
|
"""list all Network Slice Templates (NST) in the system""" |
924 |
0 |
logger.debug("") |
925 |
0 |
nst_list(ctx, filter) |
926 |
|
|
927 |
|
|
928 |
0 |
@cli_osm.command(name='netslice-template-list', short_help='list all Network Slice Templates (NST)') |
929 |
0 |
@click.option('--filter', default=None, multiple=True, |
930 |
|
help='restricts the list to the NST matching the filter') |
931 |
0 |
@click.pass_context |
932 |
|
def nst_list2(ctx, filter): |
933 |
|
"""list all Network Slice Templates (NST) in the system""" |
934 |
0 |
logger.debug("") |
935 |
0 |
nst_list(ctx, filter) |
936 |
|
|
937 |
|
|
938 |
0 |
def nsi_op_list(ctx, name): |
939 |
0 |
logger.debug("") |
940 |
|
# try: |
941 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
942 |
0 |
resp = ctx.obj.nsi.list_op(name) |
943 |
|
# except ClientException as e: |
944 |
|
# print(str(e)) |
945 |
|
# exit(1) |
946 |
0 |
table = PrettyTable(['id', 'operation', 'status']) |
947 |
0 |
for op in resp: |
948 |
0 |
table.add_row([op['id'], op['lcmOperationType'], |
949 |
|
op['operationState']]) |
950 |
0 |
table.align = 'l' |
951 |
0 |
print(table) |
952 |
|
|
953 |
|
|
954 |
0 |
@cli_osm.command(name='nsi-op-list', short_help='shows the history of operations over a Network Slice Instance (NSI)') |
955 |
0 |
@click.argument('name') |
956 |
0 |
@click.pass_context |
957 |
|
def nsi_op_list1(ctx, name): |
958 |
|
"""shows the history of operations over a Network Slice Instance (NSI) |
959 |
|
|
960 |
|
NAME: name or ID of the Network Slice Instance |
961 |
|
""" |
962 |
0 |
logger.debug("") |
963 |
0 |
nsi_op_list(ctx, name) |
964 |
|
|
965 |
|
|
966 |
0 |
@cli_osm.command(name='netslice-instance-op-list', short_help='shows the history of operations over a Network Slice Instance (NSI)') |
967 |
0 |
@click.argument('name') |
968 |
0 |
@click.pass_context |
969 |
|
def nsi_op_list2(ctx, name): |
970 |
|
"""shows the history of operations over a Network Slice Instance (NSI) |
971 |
|
|
972 |
|
NAME: name or ID of the Network Slice Instance |
973 |
|
""" |
974 |
0 |
logger.debug("") |
975 |
0 |
nsi_op_list(ctx, name) |
976 |
|
|
977 |
|
|
978 |
0 |
@cli_osm.command(name='pdu-list', short_help='list all Physical Deployment Units (PDU)') |
979 |
0 |
@click.option('--filter', default=None, multiple=True, |
980 |
|
help='restricts the list to the Physical Deployment Units matching the filter') |
981 |
0 |
@click.pass_context |
982 |
|
def pdu_list(ctx, filter): |
983 |
|
"""list all Physical Deployment Units (PDU)""" |
984 |
0 |
logger.debug("") |
985 |
|
# try: |
986 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
987 |
0 |
if filter: |
988 |
0 |
filter='&'.join(filter) |
989 |
0 |
resp = ctx.obj.pdu.list(filter) |
990 |
|
# except ClientException as e: |
991 |
|
# print(str(e)) |
992 |
|
# exit(1) |
993 |
0 |
table = PrettyTable( |
994 |
|
['pdu name', |
995 |
|
'id', |
996 |
|
'type', |
997 |
|
'mgmt ip address']) |
998 |
0 |
for pdu in resp: |
999 |
0 |
pdu_name = pdu['name'] |
1000 |
0 |
pdu_id = pdu['_id'] |
1001 |
0 |
pdu_type = pdu['type'] |
1002 |
0 |
pdu_ipaddress = "None" |
1003 |
0 |
for iface in pdu['interfaces']: |
1004 |
0 |
if iface['mgmt']: |
1005 |
0 |
pdu_ipaddress = iface['ip-address'] |
1006 |
0 |
break |
1007 |
0 |
table.add_row( |
1008 |
|
[pdu_name, |
1009 |
|
pdu_id, |
1010 |
|
pdu_type, |
1011 |
|
pdu_ipaddress]) |
1012 |
0 |
table.align = 'l' |
1013 |
0 |
print(table) |
1014 |
|
|
1015 |
|
|
1016 |
|
#################### |
1017 |
|
# SHOW operations |
1018 |
|
#################### |
1019 |
|
|
1020 |
0 |
def nsd_show(ctx, name, literal): |
1021 |
0 |
logger.debug("") |
1022 |
|
# try: |
1023 |
0 |
resp = ctx.obj.nsd.get(name) |
1024 |
|
# resp = ctx.obj.nsd.get_individual(name) |
1025 |
|
# except ClientException as e: |
1026 |
|
# print(str(e)) |
1027 |
|
# exit(1) |
1028 |
|
|
1029 |
0 |
if literal: |
1030 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
1031 |
0 |
return |
1032 |
|
|
1033 |
0 |
table = PrettyTable(['field', 'value']) |
1034 |
0 |
for k, v in list(resp.items()): |
1035 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2),width=100)]) |
1036 |
0 |
table.align = 'l' |
1037 |
0 |
print(table) |
1038 |
|
|
1039 |
|
|
1040 |
0 |
@cli_osm.command(name='nsd-show', short_help='shows the details of a NS package') |
1041 |
0 |
@click.option('--literal', is_flag=True, |
1042 |
|
help='print literally, no pretty table') |
1043 |
0 |
@click.argument('name') |
1044 |
0 |
@click.pass_context |
1045 |
|
def nsd_show1(ctx, name, literal): |
1046 |
|
"""shows the content of a NSD |
1047 |
|
|
1048 |
|
NAME: name or ID of the NSD/NSpkg |
1049 |
|
""" |
1050 |
0 |
logger.debug("") |
1051 |
0 |
nsd_show(ctx, name, literal) |
1052 |
|
|
1053 |
|
|
1054 |
0 |
@cli_osm.command(name='nspkg-show', short_help='shows the details of a NS package') |
1055 |
0 |
@click.option('--literal', is_flag=True, |
1056 |
|
help='print literally, no pretty table') |
1057 |
0 |
@click.argument('name') |
1058 |
0 |
@click.pass_context |
1059 |
|
def nsd_show2(ctx, name, literal): |
1060 |
|
"""shows the content of a NSD |
1061 |
|
|
1062 |
|
NAME: name or ID of the NSD/NSpkg |
1063 |
|
""" |
1064 |
0 |
logger.debug("") |
1065 |
0 |
nsd_show(ctx, name, literal) |
1066 |
|
|
1067 |
|
|
1068 |
0 |
def vnfd_show(ctx, name, literal): |
1069 |
0 |
logger.debug("") |
1070 |
|
# try: |
1071 |
0 |
resp = ctx.obj.vnfd.get(name) |
1072 |
|
# resp = ctx.obj.vnfd.get_individual(name) |
1073 |
|
# except ClientException as e: |
1074 |
|
# print(str(e)) |
1075 |
|
# exit(1) |
1076 |
|
|
1077 |
0 |
if literal: |
1078 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
1079 |
0 |
return |
1080 |
|
|
1081 |
0 |
table = PrettyTable(['field', 'value']) |
1082 |
0 |
for k, v in list(resp.items()): |
1083 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2),width=100)]) |
1084 |
0 |
table.align = 'l' |
1085 |
0 |
print(table) |
1086 |
|
|
1087 |
|
|
1088 |
0 |
def pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal): |
1089 |
0 |
logger.debug("") |
1090 |
0 |
if filter: |
1091 |
0 |
filter='&'.join(filter) |
1092 |
|
# try: |
1093 |
0 |
resp = ctx.obj.osmrepo.pkg_get(pkgtype, name, repo, version, filter) |
1094 |
|
|
1095 |
0 |
if literal: |
1096 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
1097 |
0 |
return |
1098 |
0 |
pkgtype += 'd' |
1099 |
0 |
catalog = pkgtype + '-catalog' |
1100 |
0 |
full_catalog = pkgtype + ':' + catalog |
1101 |
0 |
if resp.get(catalog): |
1102 |
0 |
resp = resp.pop(catalog)[pkgtype][0] |
1103 |
0 |
elif resp.get(full_catalog): |
1104 |
0 |
resp = resp.pop(full_catalog)[pkgtype][0] |
1105 |
|
|
1106 |
0 |
table = PrettyTable(['field', 'value']) |
1107 |
0 |
for k, v in list(resp.items()): |
1108 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2), width=100)]) |
1109 |
0 |
table.align = 'l' |
1110 |
0 |
print(table) |
1111 |
|
|
1112 |
|
|
1113 |
0 |
@cli_osm.command(name='vnfd-show', short_help='shows the details of a NF package') |
1114 |
0 |
@click.option('--literal', is_flag=True, |
1115 |
|
help='print literally, no pretty table') |
1116 |
0 |
@click.argument('name') |
1117 |
0 |
@click.pass_context |
1118 |
|
def vnfd_show1(ctx, name, literal): |
1119 |
|
"""shows the content of a VNFD |
1120 |
|
|
1121 |
|
NAME: name or ID of the VNFD/VNFpkg |
1122 |
|
""" |
1123 |
0 |
logger.debug("") |
1124 |
0 |
vnfd_show(ctx, name, literal) |
1125 |
|
|
1126 |
|
|
1127 |
0 |
@cli_osm.command(name='vnfpkg-show', short_help='shows the details of a NF package') |
1128 |
0 |
@click.option('--literal', is_flag=True, |
1129 |
|
help='print literally, no pretty table') |
1130 |
0 |
@click.argument('name') |
1131 |
0 |
@click.pass_context |
1132 |
|
def vnfd_show2(ctx, name, literal): |
1133 |
|
"""shows the content of a VNFD |
1134 |
|
|
1135 |
|
NAME: name or ID of the VNFD/VNFpkg |
1136 |
|
""" |
1137 |
0 |
logger.debug("") |
1138 |
0 |
vnfd_show(ctx, name, literal) |
1139 |
|
|
1140 |
0 |
@cli_osm.command(name='vnfpkg-repo-show', short_help='shows the details of a NF package in an OSM repository') |
1141 |
0 |
@click.option('--literal', is_flag=True, |
1142 |
|
help='print literally, no pretty table') |
1143 |
0 |
@click.option('--repo', |
1144 |
|
required=True, |
1145 |
|
help='Repository name') |
1146 |
0 |
@click.argument('name') |
1147 |
0 |
@click.option('--filter', default=None, multiple=True, |
1148 |
|
help='filter by fields') |
1149 |
0 |
@click.option('--version', |
1150 |
|
default='latest', |
1151 |
|
help='package version') |
1152 |
0 |
@click.pass_context |
1153 |
0 |
def vnfd_show3(ctx, name, repo, version, literal=None, filter=None): |
1154 |
|
"""shows the content of a VNFD in a repository |
1155 |
|
|
1156 |
|
NAME: name or ID of the VNFD/VNFpkg |
1157 |
|
""" |
1158 |
0 |
pkgtype = 'vnf' |
1159 |
0 |
pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal) |
1160 |
|
|
1161 |
|
|
1162 |
0 |
@cli_osm.command(name='nsd-repo-show', short_help='shows the details of a NS package in an OSM repository') |
1163 |
0 |
@click.option('--literal', is_flag=True, |
1164 |
|
help='print literally, no pretty table') |
1165 |
0 |
@click.option('--repo', |
1166 |
|
required=True, |
1167 |
|
help='Repository name') |
1168 |
0 |
@click.argument('name') |
1169 |
0 |
@click.option('--filter', default=None, multiple=True, |
1170 |
|
help='filter by fields') |
1171 |
0 |
@click.option('--version', |
1172 |
|
default='latest', |
1173 |
|
help='package version') |
1174 |
0 |
@click.pass_context |
1175 |
0 |
def nsd_repo_show(ctx, name, repo, version, literal=None, filter=None): |
1176 |
|
"""shows the content of a VNFD in a repository |
1177 |
|
|
1178 |
|
NAME: name or ID of the VNFD/VNFpkg |
1179 |
|
""" |
1180 |
0 |
pkgtype = 'ns' |
1181 |
0 |
pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal) |
1182 |
|
|
1183 |
0 |
@cli_osm.command(name='nspkg-repo-show', short_help='shows the details of a NS package in an OSM repository') |
1184 |
0 |
@click.option('--literal', is_flag=True, |
1185 |
|
help='print literally, no pretty table') |
1186 |
0 |
@click.option('--repo', |
1187 |
|
required=True, |
1188 |
|
help='Repository name') |
1189 |
0 |
@click.argument('name') |
1190 |
0 |
@click.option('--filter', default=None, multiple=True, |
1191 |
|
help='filter by fields') |
1192 |
0 |
@click.option('--version', |
1193 |
|
default='latest', |
1194 |
|
help='package version') |
1195 |
0 |
@click.pass_context |
1196 |
0 |
def nsd_repo_show2(ctx, name, repo, version, literal=None, filter=None): |
1197 |
|
"""shows the content of a VNFD in a repository |
1198 |
|
|
1199 |
|
NAME: name or ID of the VNFD/VNFpkg |
1200 |
|
""" |
1201 |
0 |
pkgtype = 'ns' |
1202 |
0 |
pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal) |
1203 |
|
|
1204 |
|
|
1205 |
0 |
@cli_osm.command(name='nfpkg-show', short_help='shows the details of a NF package') |
1206 |
0 |
@click.option('--literal', is_flag=True, |
1207 |
|
help='print literally, no pretty table') |
1208 |
0 |
@click.argument('name') |
1209 |
0 |
@click.pass_context |
1210 |
|
def nfpkg_show(ctx, name, literal): |
1211 |
|
"""shows the content of a NF Descriptor |
1212 |
|
|
1213 |
|
NAME: name or ID of the NFpkg |
1214 |
|
""" |
1215 |
0 |
logger.debug("") |
1216 |
0 |
vnfd_show(ctx, name, literal) |
1217 |
|
|
1218 |
|
|
1219 |
0 |
@cli_osm.command(name='nfpkg-repo-show', short_help='shows the details of a NF package in an OSM repository') |
1220 |
0 |
@click.option('--literal', is_flag=True, |
1221 |
|
help='print literally, no pretty table') |
1222 |
0 |
@click.option('--repo', |
1223 |
|
required=True, |
1224 |
|
help='Repository name') |
1225 |
0 |
@click.argument('name') |
1226 |
0 |
@click.option('--filter', default=None, multiple=True, |
1227 |
|
help='filter by fields') |
1228 |
0 |
@click.option('--version', |
1229 |
|
default='latest', |
1230 |
|
help='package version') |
1231 |
0 |
@click.pass_context |
1232 |
0 |
def vnfd_show4(ctx, name, repo, version, literal=None, filter=None): |
1233 |
|
"""shows the content of a VNFD in a repository |
1234 |
|
|
1235 |
|
NAME: name or ID of the VNFD/VNFpkg |
1236 |
|
""" |
1237 |
0 |
pkgtype = 'vnf' |
1238 |
0 |
pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal) |
1239 |
|
|
1240 |
|
|
1241 |
0 |
@cli_osm.command(name='ns-show', short_help='shows the info of a NS instance') |
1242 |
0 |
@click.argument('name') |
1243 |
0 |
@click.option('--literal', is_flag=True, |
1244 |
|
help='print literally, no pretty table') |
1245 |
0 |
@click.option('--filter', multiple=True, |
1246 |
|
help='restricts the information to the fields in the filter') |
1247 |
0 |
@click.pass_context |
1248 |
|
def ns_show(ctx, name, literal, filter): |
1249 |
|
"""shows the info of a NS instance |
1250 |
|
|
1251 |
|
NAME: name or ID of the NS instance |
1252 |
|
""" |
1253 |
0 |
logger.debug("") |
1254 |
|
# try: |
1255 |
0 |
ns = ctx.obj.ns.get(name) |
1256 |
|
# except ClientException as e: |
1257 |
|
# print(str(e)) |
1258 |
|
# exit(1) |
1259 |
|
|
1260 |
0 |
if literal: |
1261 |
0 |
print(yaml.safe_dump(ns, indent=4, default_flow_style=False)) |
1262 |
0 |
return |
1263 |
|
|
1264 |
0 |
table = PrettyTable(['field', 'value']) |
1265 |
|
|
1266 |
0 |
for k, v in list(ns.items()): |
1267 |
0 |
if not filter or k in filter: |
1268 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2),width=100)]) |
1269 |
|
|
1270 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
1271 |
0 |
if fullclassname != 'osmclient.sol005.client.Client': |
1272 |
0 |
nsopdata = ctx.obj.ns.get_opdata(ns['id']) |
1273 |
0 |
nsr_optdata = nsopdata['nsr:nsr'] |
1274 |
0 |
for k, v in list(nsr_optdata.items()): |
1275 |
0 |
if not filter or k in filter: |
1276 |
0 |
table.add_row([k, wrap_text(json.dumps(v, indent=2),width=100)]) |
1277 |
0 |
table.align = 'l' |
1278 |
0 |
print(table) |
1279 |
|
|
1280 |
|
|
1281 |
0 |
@cli_osm.command(name='vnf-show', short_help='shows the info of a VNF instance') |
1282 |
0 |
@click.argument('name') |
1283 |
0 |
@click.option('--literal', is_flag=True, |
1284 |
|
help='print literally, no pretty table') |
1285 |
0 |
@click.option('--filter', multiple=True, |
1286 |
|
help='restricts the information to the fields in the filter') |
1287 |
0 |
@click.option('--kdu', default=None, help='KDU name (whose status will be shown)') |
1288 |
0 |
@click.pass_context |
1289 |
|
def vnf_show(ctx, name, literal, filter, kdu): |
1290 |
|
"""shows the info of a VNF instance |
1291 |
|
|
1292 |
|
NAME: name or ID of the VNF instance |
1293 |
|
""" |
1294 |
0 |
def print_kdu_status(op_info_status): |
1295 |
|
"""print KDU status properly formatted |
1296 |
|
""" |
1297 |
0 |
try: |
1298 |
0 |
op_status = yaml.safe_load(op_info_status) |
1299 |
0 |
if "namespace" in op_status and "info" in op_status and \ |
1300 |
|
"last_deployed" in op_status["info"] and "status" in op_status["info"] and \ |
1301 |
|
"code" in op_status["info"]["status"] and "resources" in op_status["info"]["status"] and \ |
1302 |
|
"seconds" in op_status["info"]["last_deployed"]: |
1303 |
0 |
last_deployed_time = datetime.fromtimestamp(op_status["info"]["last_deployed"]["seconds"]).strftime("%a %b %d %I:%M:%S %Y") |
1304 |
0 |
print("LAST DEPLOYED: {}".format(last_deployed_time)) |
1305 |
0 |
print("NAMESPACE: {}".format(op_status["namespace"])) |
1306 |
0 |
status_code = "UNKNOWN" |
1307 |
0 |
if op_status["info"]["status"]["code"]==1: |
1308 |
0 |
status_code = "DEPLOYED" |
1309 |
0 |
print("STATUS: {}".format(status_code)) |
1310 |
0 |
print() |
1311 |
0 |
print("RESOURCES:") |
1312 |
0 |
print(op_status["info"]["status"]["resources"]) |
1313 |
0 |
if "notes" in op_status["info"]["status"]: |
1314 |
0 |
print("NOTES:") |
1315 |
0 |
print(op_status["info"]["status"]["notes"]) |
1316 |
|
else: |
1317 |
0 |
print(op_info_status) |
1318 |
0 |
except Exception: |
1319 |
0 |
print(op_info_status) |
1320 |
|
|
1321 |
0 |
logger.debug("") |
1322 |
0 |
if kdu: |
1323 |
0 |
if literal: |
1324 |
0 |
raise ClientException('"--literal" option is incompatible with "--kdu" option') |
1325 |
0 |
if filter: |
1326 |
0 |
raise ClientException('"--filter" option is incompatible with "--kdu" option') |
1327 |
|
|
1328 |
|
# try: |
1329 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1330 |
0 |
resp = ctx.obj.vnf.get(name) |
1331 |
|
|
1332 |
0 |
if kdu: |
1333 |
0 |
ns_id = resp['nsr-id-ref'] |
1334 |
0 |
op_data={} |
1335 |
0 |
op_data['member_vnf_index'] = resp['member-vnf-index-ref'] |
1336 |
0 |
op_data['kdu_name'] = kdu |
1337 |
0 |
op_data['primitive'] = 'status' |
1338 |
0 |
op_data['primitive_params'] = {} |
1339 |
0 |
op_id = ctx.obj.ns.exec_op(ns_id, op_name='action', op_data=op_data, wait=False) |
1340 |
0 |
t = 0 |
1341 |
0 |
while t<30: |
1342 |
0 |
op_info = ctx.obj.ns.get_op(op_id) |
1343 |
0 |
if op_info['operationState'] == 'COMPLETED': |
1344 |
0 |
print_kdu_status(op_info['detailed-status']) |
1345 |
0 |
return |
1346 |
0 |
time.sleep(5) |
1347 |
0 |
t += 5 |
1348 |
0 |
print ("Could not determine KDU status") |
1349 |
0 |
return |
1350 |
|
|
1351 |
0 |
if literal: |
1352 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
1353 |
0 |
return |
1354 |
|
|
1355 |
0 |
table = PrettyTable(['field', 'value']) |
1356 |
0 |
for k, v in list(resp.items()): |
1357 |
0 |
if not filter or k in filter: |
1358 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v,indent=2),width=100)]) |
1359 |
0 |
table.align = 'l' |
1360 |
0 |
print(table) |
1361 |
|
# except ClientException as e: |
1362 |
|
# print(str(e)) |
1363 |
|
# exit(1) |
1364 |
|
|
1365 |
|
|
1366 |
|
#@cli_osm.command(name='vnf-monitoring-show') |
1367 |
|
#@click.argument('vnf_name') |
1368 |
|
#@click.pass_context |
1369 |
|
#def vnf_monitoring_show(ctx, vnf_name): |
1370 |
|
# try: |
1371 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
1372 |
|
# resp = ctx.obj.vnf.get_monitoring(vnf_name) |
1373 |
|
# except ClientException as e: |
1374 |
|
# print(str(e)) |
1375 |
|
# exit(1) |
1376 |
|
# |
1377 |
|
# table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units']) |
1378 |
|
# if resp is not None: |
1379 |
|
# for monitor in resp: |
1380 |
|
# table.add_row( |
1381 |
|
# [vnf_name, |
1382 |
|
# monitor['name'], |
1383 |
|
# monitor['value-integer'], |
1384 |
|
# monitor['units']]) |
1385 |
|
# table.align = 'l' |
1386 |
|
# print(table) |
1387 |
|
|
1388 |
|
|
1389 |
|
#@cli_osm.command(name='ns-monitoring-show') |
1390 |
|
#@click.argument('ns_name') |
1391 |
|
#@click.pass_context |
1392 |
|
#def ns_monitoring_show(ctx, ns_name): |
1393 |
|
# try: |
1394 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
1395 |
|
# resp = ctx.obj.ns.get_monitoring(ns_name) |
1396 |
|
# except ClientException as e: |
1397 |
|
# print(str(e)) |
1398 |
|
# exit(1) |
1399 |
|
# |
1400 |
|
# table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units']) |
1401 |
|
# for key, val in list(resp.items()): |
1402 |
|
# for monitor in val: |
1403 |
|
# table.add_row( |
1404 |
|
# [key, |
1405 |
|
# monitor['name'], |
1406 |
|
# monitor['value-integer'], |
1407 |
|
# monitor['units']]) |
1408 |
|
# table.align = 'l' |
1409 |
|
# print(table) |
1410 |
|
|
1411 |
|
|
1412 |
0 |
@cli_osm.command(name='ns-op-show', short_help='shows the info of a NS operation') |
1413 |
0 |
@click.argument('id') |
1414 |
0 |
@click.option('--filter', multiple=True, |
1415 |
|
help='restricts the information to the fields in the filter') |
1416 |
0 |
@click.option('--literal', is_flag=True, |
1417 |
|
help='print literally, no pretty table') |
1418 |
0 |
@click.pass_context |
1419 |
|
def ns_op_show(ctx, id, filter, literal): |
1420 |
|
"""shows the detailed info of a NS operation |
1421 |
|
|
1422 |
|
ID: operation identifier |
1423 |
|
""" |
1424 |
0 |
logger.debug("") |
1425 |
|
# try: |
1426 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1427 |
0 |
op_info = ctx.obj.ns.get_op(id) |
1428 |
|
# except ClientException as e: |
1429 |
|
# print(str(e)) |
1430 |
|
# exit(1) |
1431 |
|
|
1432 |
0 |
if literal: |
1433 |
0 |
print(yaml.safe_dump(op_info, indent=4, default_flow_style=False)) |
1434 |
0 |
return |
1435 |
|
|
1436 |
0 |
table = PrettyTable(['field', 'value']) |
1437 |
0 |
for k, v in list(op_info.items()): |
1438 |
0 |
if not filter or k in filter: |
1439 |
0 |
table.add_row([k, wrap_text(json.dumps(v, indent=2), 100)]) |
1440 |
0 |
table.align = 'l' |
1441 |
0 |
print(table) |
1442 |
|
|
1443 |
|
|
1444 |
0 |
def nst_show(ctx, name, literal): |
1445 |
0 |
logger.debug("") |
1446 |
|
# try: |
1447 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1448 |
0 |
resp = ctx.obj.nst.get(name) |
1449 |
|
#resp = ctx.obj.nst.get_individual(name) |
1450 |
|
# except ClientException as e: |
1451 |
|
# print(str(e)) |
1452 |
|
# exit(1) |
1453 |
|
|
1454 |
0 |
if literal: |
1455 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
1456 |
0 |
return |
1457 |
|
|
1458 |
0 |
table = PrettyTable(['field', 'value']) |
1459 |
0 |
for k, v in list(resp.items()): |
1460 |
0 |
table.add_row([k, wrap_text(json.dumps(v, indent=2), 100)]) |
1461 |
0 |
table.align = 'l' |
1462 |
0 |
print(table) |
1463 |
|
|
1464 |
|
|
1465 |
0 |
@cli_osm.command(name='nst-show', short_help='shows the content of a Network Slice Template (NST)') |
1466 |
0 |
@click.option('--literal', is_flag=True, |
1467 |
|
help='print literally, no pretty table') |
1468 |
0 |
@click.argument('name') |
1469 |
0 |
@click.pass_context |
1470 |
|
def nst_show1(ctx, name, literal): |
1471 |
|
"""shows the content of a Network Slice Template (NST) |
1472 |
|
|
1473 |
|
NAME: name or ID of the NST |
1474 |
|
""" |
1475 |
0 |
logger.debug("") |
1476 |
0 |
nst_show(ctx, name, literal) |
1477 |
|
|
1478 |
|
|
1479 |
0 |
@cli_osm.command(name='netslice-template-show', short_help='shows the content of a Network Slice Template (NST)') |
1480 |
0 |
@click.option('--literal', is_flag=True, |
1481 |
|
help='print literally, no pretty table') |
1482 |
0 |
@click.argument('name') |
1483 |
0 |
@click.pass_context |
1484 |
|
def nst_show2(ctx, name, literal): |
1485 |
|
"""shows the content of a Network Slice Template (NST) |
1486 |
|
|
1487 |
|
NAME: name or ID of the NST |
1488 |
|
""" |
1489 |
0 |
logger.debug("") |
1490 |
0 |
nst_show(ctx, name, literal) |
1491 |
|
|
1492 |
|
|
1493 |
0 |
def nsi_show(ctx, name, literal, filter): |
1494 |
0 |
logger.debug("") |
1495 |
|
# try: |
1496 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1497 |
0 |
nsi = ctx.obj.nsi.get(name) |
1498 |
|
# except ClientException as e: |
1499 |
|
# print(str(e)) |
1500 |
|
# exit(1) |
1501 |
|
|
1502 |
0 |
if literal: |
1503 |
0 |
print(yaml.safe_dump(nsi, indent=4, default_flow_style=False)) |
1504 |
0 |
return |
1505 |
|
|
1506 |
0 |
table = PrettyTable(['field', 'value']) |
1507 |
|
|
1508 |
0 |
for k, v in list(nsi.items()): |
1509 |
0 |
if not filter or k in filter: |
1510 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
1511 |
|
|
1512 |
0 |
table.align = 'l' |
1513 |
0 |
print(table) |
1514 |
|
|
1515 |
|
|
1516 |
0 |
@cli_osm.command(name='nsi-show', short_help='shows the content of a Network Slice Instance (NSI)') |
1517 |
0 |
@click.argument('name') |
1518 |
0 |
@click.option('--literal', is_flag=True, |
1519 |
|
help='print literally, no pretty table') |
1520 |
0 |
@click.option('--filter', multiple=True, |
1521 |
|
help='restricts the information to the fields in the filter') |
1522 |
0 |
@click.pass_context |
1523 |
|
def nsi_show1(ctx, name, literal, filter): |
1524 |
|
"""shows the content of a Network Slice Instance (NSI) |
1525 |
|
|
1526 |
|
NAME: name or ID of the Network Slice Instance |
1527 |
|
""" |
1528 |
0 |
logger.debug("") |
1529 |
0 |
nsi_show(ctx, name, literal, filter) |
1530 |
|
|
1531 |
|
|
1532 |
0 |
@cli_osm.command(name='netslice-instance-show', short_help='shows the content of a Network Slice Instance (NSI)') |
1533 |
0 |
@click.argument('name') |
1534 |
0 |
@click.option('--literal', is_flag=True, |
1535 |
|
help='print literally, no pretty table') |
1536 |
0 |
@click.option('--filter', multiple=True, |
1537 |
|
help='restricts the information to the fields in the filter') |
1538 |
0 |
@click.pass_context |
1539 |
|
def nsi_show2(ctx, name, literal, filter): |
1540 |
|
"""shows the content of a Network Slice Instance (NSI) |
1541 |
|
|
1542 |
|
NAME: name or ID of the Network Slice Instance |
1543 |
|
""" |
1544 |
0 |
logger.debug("") |
1545 |
0 |
nsi_show(ctx, name, literal, filter) |
1546 |
|
|
1547 |
|
|
1548 |
0 |
def nsi_op_show(ctx, id, filter): |
1549 |
0 |
logger.debug("") |
1550 |
|
# try: |
1551 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1552 |
0 |
op_info = ctx.obj.nsi.get_op(id) |
1553 |
|
# except ClientException as e: |
1554 |
|
# print(str(e)) |
1555 |
|
# exit(1) |
1556 |
|
|
1557 |
0 |
table = PrettyTable(['field', 'value']) |
1558 |
0 |
for k, v in list(op_info.items()): |
1559 |
0 |
if not filter or k in filter: |
1560 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
1561 |
0 |
table.align = 'l' |
1562 |
0 |
print(table) |
1563 |
|
|
1564 |
|
|
1565 |
0 |
@cli_osm.command(name='nsi-op-show', short_help='shows the info of an operation over a Network Slice Instance(NSI)') |
1566 |
0 |
@click.argument('id') |
1567 |
0 |
@click.option('--filter', multiple=True, |
1568 |
|
help='restricts the information to the fields in the filter') |
1569 |
0 |
@click.pass_context |
1570 |
|
def nsi_op_show1(ctx, id, filter): |
1571 |
|
"""shows the info of an operation over a Network Slice Instance(NSI) |
1572 |
|
|
1573 |
|
ID: operation identifier |
1574 |
|
""" |
1575 |
0 |
logger.debug("") |
1576 |
0 |
nsi_op_show(ctx, id, filter) |
1577 |
|
|
1578 |
|
|
1579 |
0 |
@cli_osm.command(name='netslice-instance-op-show', short_help='shows the info of an operation over a Network Slice Instance(NSI)') |
1580 |
0 |
@click.argument('id') |
1581 |
0 |
@click.option('--filter', multiple=True, |
1582 |
|
help='restricts the information to the fields in the filter') |
1583 |
0 |
@click.pass_context |
1584 |
|
def nsi_op_show2(ctx, id, filter): |
1585 |
|
"""shows the info of an operation over a Network Slice Instance(NSI) |
1586 |
|
|
1587 |
|
ID: operation identifier |
1588 |
|
""" |
1589 |
0 |
logger.debug("") |
1590 |
0 |
nsi_op_show(ctx, id, filter) |
1591 |
|
|
1592 |
|
|
1593 |
0 |
@cli_osm.command(name='pdu-show', short_help='shows the content of a Physical Deployment Unit (PDU)') |
1594 |
0 |
@click.argument('name') |
1595 |
0 |
@click.option('--literal', is_flag=True, |
1596 |
|
help='print literally, no pretty table') |
1597 |
0 |
@click.option('--filter', multiple=True, |
1598 |
|
help='restricts the information to the fields in the filter') |
1599 |
0 |
@click.pass_context |
1600 |
|
def pdu_show(ctx, name, literal, filter): |
1601 |
|
"""shows the content of a Physical Deployment Unit (PDU) |
1602 |
|
|
1603 |
|
NAME: name or ID of the PDU |
1604 |
|
""" |
1605 |
0 |
logger.debug("") |
1606 |
|
# try: |
1607 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1608 |
0 |
pdu = ctx.obj.pdu.get(name) |
1609 |
|
# except ClientException as e: |
1610 |
|
# print(str(e)) |
1611 |
|
# exit(1) |
1612 |
|
|
1613 |
0 |
if literal: |
1614 |
0 |
print(yaml.safe_dump(pdu, indent=4, default_flow_style=False)) |
1615 |
0 |
return |
1616 |
|
|
1617 |
0 |
table = PrettyTable(['field', 'value']) |
1618 |
|
|
1619 |
0 |
for k, v in list(pdu.items()): |
1620 |
0 |
if not filter or k in filter: |
1621 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
1622 |
|
|
1623 |
0 |
table.align = 'l' |
1624 |
0 |
print(table) |
1625 |
|
|
1626 |
|
|
1627 |
|
#################### |
1628 |
|
# CREATE operations |
1629 |
|
#################### |
1630 |
|
|
1631 |
0 |
def nsd_create(ctx, filename, overwrite, skip_charm_build, repo, vendor, version): |
1632 |
0 |
logger.debug("") |
1633 |
|
# try: |
1634 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1635 |
0 |
if repo: |
1636 |
0 |
filename = ctx.obj.osmrepo.get_pkg('ns', filename, repo, vendor, version) |
1637 |
0 |
ctx.obj.nsd.create(filename, overwrite=overwrite, skip_charm_build=skip_charm_build) |
1638 |
|
# except ClientException as e: |
1639 |
|
# print(str(e)) |
1640 |
|
# exit(1) |
1641 |
|
|
1642 |
|
|
1643 |
0 |
@cli_osm.command(name='nsd-create', short_help='creates a new NSD/NSpkg') |
1644 |
0 |
@click.argument('filename') |
1645 |
0 |
@click.option('--overwrite', 'overwrite', default=None, # hidden=True, |
1646 |
|
help='Deprecated. Use override') |
1647 |
0 |
@click.option('--override', 'overwrite', default=None, |
1648 |
|
help='overrides fields in descriptor, format: ' |
1649 |
|
'"key1.key2...=value[;key3...=value;...]"') |
1650 |
0 |
@click.option('--skip-charm-build', default=False, is_flag=True, |
1651 |
|
help='The charm will not be compiled, it is assumed to already exist') |
1652 |
0 |
@click.option('--repo', default=None, |
1653 |
|
help='[repository]: Repository name') |
1654 |
0 |
@click.option('--vendor', default=None, |
1655 |
|
help='[repository]: filter by vendor]') |
1656 |
0 |
@click.option('--version', default='latest', |
1657 |
|
help='[repository]: filter by version. Default: latest') |
1658 |
0 |
@click.pass_context |
1659 |
|
def nsd_create1(ctx, filename, overwrite, skip_charm_build, repo, vendor, version): |
1660 |
|
"""onboards a new NSpkg (alias of nspkg-create) (TO BE DEPRECATED) |
1661 |
|
|
1662 |
|
\b |
1663 |
|
FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder |
1664 |
|
If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded. |
1665 |
|
If FILENAME is an NF Package folder, it is built and then onboarded. |
1666 |
|
""" |
1667 |
0 |
logger.debug("") |
1668 |
0 |
nsd_create(ctx, filename, overwrite=overwrite, skip_charm_build=skip_charm_build, repo=repo, vendor=vendor, |
1669 |
|
version=version) |
1670 |
|
|
1671 |
|
|
1672 |
0 |
@cli_osm.command(name='nspkg-create', short_help='creates a new NSD/NSpkg') |
1673 |
0 |
@click.argument('filename') |
1674 |
0 |
@click.option('--overwrite', 'overwrite', default=None, # hidden=True, |
1675 |
|
help='Deprecated. Use override') |
1676 |
0 |
@click.option('--override', 'overwrite', default=None, |
1677 |
|
help='overrides fields in descriptor, format: ' |
1678 |
|
'"key1.key2...=value[;key3...=value;...]"') |
1679 |
0 |
@click.option('--skip-charm-build', default=False, is_flag=True, |
1680 |
|
help='The charm will not be compiled, it is assumed to already exist') |
1681 |
0 |
@click.option('--repo', default=None, |
1682 |
|
help='[repository]: Repository name') |
1683 |
0 |
@click.option('--vendor', default=None, |
1684 |
|
help='[repository]: filter by vendor]') |
1685 |
0 |
@click.option('--version', default='latest', |
1686 |
|
help='[repository]: filter by version. Default: latest') |
1687 |
0 |
@click.pass_context |
1688 |
|
def nsd_pkg_create(ctx, filename, overwrite, skip_charm_build, repo, vendor, version): |
1689 |
|
"""onboards a new NSpkg |
1690 |
|
\b |
1691 |
|
FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder |
1692 |
|
If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded. |
1693 |
|
If FILENAME is an NF Package folder, it is built and then onboarded. |
1694 |
|
""" |
1695 |
0 |
logger.debug("") |
1696 |
0 |
nsd_create(ctx, filename, overwrite=overwrite, skip_charm_build=skip_charm_build, repo=repo, vendor=vendor, |
1697 |
|
version=version) |
1698 |
|
|
1699 |
|
|
1700 |
0 |
def vnfd_create(ctx, filename, overwrite, skip_charm_build, override_epa, override_nonepa, override_paravirt, |
1701 |
|
repo, vendor, version): |
1702 |
0 |
logger.debug("") |
1703 |
|
# try: |
1704 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1705 |
0 |
if repo: |
1706 |
0 |
filename = ctx.obj.osmrepo.get_pkg('vnf', filename, repo, vendor, version) |
1707 |
0 |
ctx.obj.vnfd.create(filename, overwrite=overwrite, skip_charm_build=skip_charm_build, |
1708 |
|
override_epa=override_epa, override_nonepa=override_nonepa, |
1709 |
|
override_paravirt=override_paravirt) |
1710 |
|
# except ClientException as e: |
1711 |
|
# print(str(e)) |
1712 |
|
# exit(1) |
1713 |
|
|
1714 |
|
|
1715 |
0 |
@cli_osm.command(name='vnfd-create', short_help='creates a new VNFD/VNFpkg') |
1716 |
0 |
@click.argument('filename') |
1717 |
0 |
@click.option('--overwrite', 'overwrite', default=None, |
1718 |
|
help='overwrite deprecated, use override') |
1719 |
0 |
@click.option('--override', 'overwrite', default=None, |
1720 |
|
help='overrides fields in descriptor, format: ' |
1721 |
|
'"key1.key2...=value[;key3...=value;...]"') |
1722 |
0 |
@click.option('--skip-charm-build', default=False, is_flag=True, |
1723 |
|
help='The charm will not be compiled, it is assumed to already exist') |
1724 |
0 |
@click.option('--override-epa', required=False, default=False, is_flag=True, |
1725 |
|
help='adds guest-epa parameters to all VDU') |
1726 |
0 |
@click.option('--override-nonepa', required=False, default=False, is_flag=True, |
1727 |
|
help='removes all guest-epa parameters from all VDU') |
1728 |
0 |
@click.option('--override-paravirt', required=False, default=False, is_flag=True, |
1729 |
|
help='overrides all VDU interfaces to PARAVIRT') |
1730 |
0 |
@click.option('--repo', default=None, |
1731 |
|
help='[repository]: Repository name') |
1732 |
0 |
@click.option('--vendor', default=None, |
1733 |
|
help='[repository]: filter by vendor]') |
1734 |
0 |
@click.option('--version', default='latest', |
1735 |
|
help='[repository]: filter by version. Default: latest') |
1736 |
0 |
@click.pass_context |
1737 |
|
def vnfd_create1(ctx, filename, overwrite, skip_charm_build, override_epa, override_nonepa, override_paravirt, |
1738 |
|
repo,vendor, version): |
1739 |
|
"""creates a new VNFD/VNFpkg |
1740 |
|
\b |
1741 |
|
FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder |
1742 |
|
If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded. |
1743 |
|
If FILENAME is an NF Package folder, it is built and then onboarded. |
1744 |
|
""" |
1745 |
0 |
logger.debug("") |
1746 |
0 |
vnfd_create(ctx, filename, overwrite=overwrite, skip_charm_build=skip_charm_build, |
1747 |
|
override_epa=override_epa, override_nonepa=override_nonepa, override_paravirt=override_paravirt, |
1748 |
|
repo=repo, vendor=vendor, version=version) |
1749 |
|
|
1750 |
|
|
1751 |
0 |
@cli_osm.command(name='vnfpkg-create', short_help='creates a new VNFD/VNFpkg') |
1752 |
0 |
@click.argument('filename') |
1753 |
0 |
@click.option('--overwrite', 'overwrite', default=None, # hidden=True, |
1754 |
|
help='Deprecated. Use override') |
1755 |
0 |
@click.option('--override', 'overwrite', default=None, |
1756 |
|
help='overrides fields in descriptor, format: ' |
1757 |
|
'"key1.key2...=value[;key3...=value;...]"') |
1758 |
0 |
@click.option('--skip-charm-build', default=False, is_flag=True, |
1759 |
|
help='The charm will not be compiled, it is assumed to already exist') |
1760 |
0 |
@click.option('--override-epa', required=False, default=False, is_flag=True, |
1761 |
|
help='adds guest-epa parameters to all VDU') |
1762 |
0 |
@click.option('--override-nonepa', required=False, default=False, is_flag=True, |
1763 |
|
help='removes all guest-epa parameters from all VDU') |
1764 |
0 |
@click.option('--override-paravirt', required=False, default=False, is_flag=True, |
1765 |
|
help='overrides all VDU interfaces to PARAVIRT') |
1766 |
0 |
@click.option('--repo', default=None, |
1767 |
|
help='[repository]: Repository name') |
1768 |
0 |
@click.option('--vendor', default=None, |
1769 |
|
help='[repository]: filter by vendor]') |
1770 |
0 |
@click.option('--version', default='latest', |
1771 |
|
help='[repository]: filter by version. Default: latest') |
1772 |
0 |
@click.pass_context |
1773 |
|
def vnfd_create2(ctx, filename, overwrite, skip_charm_build, override_epa, override_nonepa, override_paravirt, |
1774 |
|
repo, vendor, version): |
1775 |
|
"""creates a new VNFD/VNFpkg |
1776 |
|
\b |
1777 |
|
FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder |
1778 |
|
If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded. |
1779 |
|
If FILENAME is an NF Package folder, it is built and then onboarded. |
1780 |
|
""" |
1781 |
0 |
logger.debug("") |
1782 |
0 |
vnfd_create(ctx, filename, overwrite=overwrite, skip_charm_build=skip_charm_build, |
1783 |
|
override_epa=override_epa, override_nonepa=override_nonepa, override_paravirt=override_paravirt, |
1784 |
|
repo=repo, vendor=vendor, version=version) |
1785 |
|
|
1786 |
0 |
@cli_osm.command(name='nfpkg-create', short_help='creates a new NFpkg') |
1787 |
0 |
@click.argument('filename') |
1788 |
0 |
@click.option('--overwrite', 'overwrite', default=None, # hidden=True, |
1789 |
|
help='Deprecated. Use override') |
1790 |
0 |
@click.option('--override', 'overwrite', default=None, |
1791 |
|
help='overrides fields in descriptor, format: ' |
1792 |
|
'"key1.key2...=value[;key3...=value;...]"') |
1793 |
0 |
@click.option('--skip-charm-build', default=False, is_flag=True, |
1794 |
|
help='The charm will not be compiled, it is assumed to already exist') |
1795 |
0 |
@click.option('--override-epa', required=False, default=False, is_flag=True, |
1796 |
|
help='adds guest-epa parameters to all VDU') |
1797 |
0 |
@click.option('--override-nonepa', required=False, default=False, is_flag=True, |
1798 |
|
help='removes all guest-epa parameters from all VDU') |
1799 |
0 |
@click.option('--override-paravirt', required=False, default=False, is_flag=True, |
1800 |
|
help='overrides all VDU interfaces to PARAVIRT') |
1801 |
0 |
@click.option('--repo', default=None, |
1802 |
|
help='[repository]: Repository name') |
1803 |
0 |
@click.option('--vendor', default=None, |
1804 |
|
help='[repository]: filter by vendor]') |
1805 |
0 |
@click.option('--version', default='latest', |
1806 |
|
help='[repository]: filter by version. Default: latest') |
1807 |
0 |
@click.pass_context |
1808 |
|
def nfpkg_create(ctx, filename, overwrite, skip_charm_build, override_epa, override_nonepa, override_paravirt, |
1809 |
|
repo, vendor, version): |
1810 |
|
"""creates a new NFpkg |
1811 |
|
|
1812 |
|
\b |
1813 |
|
FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder |
1814 |
|
If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded. |
1815 |
|
If FILENAME is an NF Package folder, it is built and then onboarded. |
1816 |
|
""" |
1817 |
0 |
logger.debug("") |
1818 |
0 |
vnfd_create(ctx, filename, overwrite=overwrite, skip_charm_build=skip_charm_build, |
1819 |
|
override_epa=override_epa, override_nonepa=override_nonepa, override_paravirt=override_paravirt, |
1820 |
|
repo=repo, vendor=vendor, version=version) |
1821 |
|
|
1822 |
|
|
1823 |
0 |
@cli_osm.command(name='ns-create', short_help='creates a new Network Service instance') |
1824 |
0 |
@click.option('--ns_name', |
1825 |
|
prompt=True, help='name of the NS instance') |
1826 |
0 |
@click.option('--nsd_name', |
1827 |
|
prompt=True, help='name of the NS descriptor') |
1828 |
0 |
@click.option('--vim_account', |
1829 |
|
prompt=True, help='default VIM account id or name for the deployment') |
1830 |
0 |
@click.option('--admin_status', |
1831 |
|
default='ENABLED', |
1832 |
|
help='administration status') |
1833 |
0 |
@click.option('--ssh_keys', |
1834 |
|
default=None, |
1835 |
|
help='comma separated list of public key files to inject to vnfs') |
1836 |
0 |
@click.option('--config', |
1837 |
|
default=None, |
1838 |
|
help='ns specific yaml configuration') |
1839 |
0 |
@click.option('--config_file', |
1840 |
|
default=None, |
1841 |
|
help='ns specific yaml configuration file') |
1842 |
0 |
@click.option('--wait', |
1843 |
|
required=False, |
1844 |
|
default=False, |
1845 |
|
is_flag=True, |
1846 |
|
help='do not return the control immediately, but keep it ' |
1847 |
|
'until the operation is completed, or timeout') |
1848 |
0 |
@click.pass_context |
1849 |
|
def ns_create(ctx, |
1850 |
|
nsd_name, |
1851 |
|
ns_name, |
1852 |
|
vim_account, |
1853 |
|
admin_status, |
1854 |
|
ssh_keys, |
1855 |
|
config, |
1856 |
|
config_file, |
1857 |
|
wait): |
1858 |
|
"""creates a new NS instance""" |
1859 |
0 |
logger.debug("") |
1860 |
|
# try: |
1861 |
0 |
if config_file: |
1862 |
0 |
check_client_version(ctx.obj, '--config_file') |
1863 |
0 |
if config: |
1864 |
0 |
raise ClientException('"--config" option is incompatible with "--config_file" option') |
1865 |
0 |
with open(config_file, 'r') as cf: |
1866 |
0 |
config=cf.read() |
1867 |
0 |
ctx.obj.ns.create( |
1868 |
|
nsd_name, |
1869 |
|
ns_name, |
1870 |
|
config=config, |
1871 |
|
ssh_keys=ssh_keys, |
1872 |
|
account=vim_account, |
1873 |
|
wait=wait) |
1874 |
|
# except ClientException as e: |
1875 |
|
# print(str(e)) |
1876 |
|
# exit(1) |
1877 |
|
|
1878 |
|
|
1879 |
0 |
def nst_create(ctx, filename, overwrite): |
1880 |
0 |
logger.debug("") |
1881 |
|
# try: |
1882 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1883 |
0 |
ctx.obj.nst.create(filename, overwrite) |
1884 |
|
# except ClientException as e: |
1885 |
|
# print(str(e)) |
1886 |
|
# exit(1) |
1887 |
|
|
1888 |
|
|
1889 |
0 |
@cli_osm.command(name='nst-create', short_help='creates a new Network Slice Template (NST)') |
1890 |
0 |
@click.argument('filename') |
1891 |
0 |
@click.option('--overwrite', 'overwrite', default=None, # hidden=True, |
1892 |
|
help='Deprecated. Use override') |
1893 |
0 |
@click.option('--override', 'overwrite', default=None, |
1894 |
|
help='overrides fields in descriptor, format: ' |
1895 |
|
'"key1.key2...=value[;key3...=value;...]"') |
1896 |
0 |
@click.pass_context |
1897 |
|
def nst_create1(ctx, filename, overwrite): |
1898 |
|
"""creates a new Network Slice Template (NST) |
1899 |
|
|
1900 |
|
FILENAME: NST package folder, NST yaml file or NSTpkg tar.gz file |
1901 |
|
""" |
1902 |
0 |
logger.debug("") |
1903 |
0 |
nst_create(ctx, filename, overwrite) |
1904 |
|
|
1905 |
|
|
1906 |
0 |
@cli_osm.command(name='netslice-template-create', short_help='creates a new Network Slice Template (NST)') |
1907 |
0 |
@click.argument('filename') |
1908 |
0 |
@click.option('--overwrite', 'overwrite', default=None, # hidden=True, |
1909 |
|
help='Deprecated. Use override') |
1910 |
0 |
@click.option('--override', 'overwrite', default=None, |
1911 |
|
help='overrides fields in descriptor, format: ' |
1912 |
|
'"key1.key2...=value[;key3...=value;...]"') |
1913 |
0 |
@click.pass_context |
1914 |
|
def nst_create2(ctx, filename, overwrite): |
1915 |
|
"""creates a new Network Slice Template (NST) |
1916 |
|
|
1917 |
|
FILENAME: NST yaml file or NSTpkg tar.gz file |
1918 |
|
""" |
1919 |
0 |
logger.debug("") |
1920 |
0 |
nst_create(ctx, filename, overwrite) |
1921 |
|
|
1922 |
|
|
1923 |
0 |
def nsi_create(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file, wait): |
1924 |
|
"""creates a new Network Slice Instance (NSI)""" |
1925 |
0 |
logger.debug("") |
1926 |
|
# try: |
1927 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1928 |
0 |
if config_file: |
1929 |
0 |
if config: |
1930 |
0 |
raise ClientException('"--config" option is incompatible with "--config_file" option') |
1931 |
0 |
with open(config_file, 'r') as cf: |
1932 |
0 |
config=cf.read() |
1933 |
0 |
ctx.obj.nsi.create(nst_name, nsi_name, config=config, ssh_keys=ssh_keys, |
1934 |
|
account=vim_account, wait=wait) |
1935 |
|
# except ClientException as e: |
1936 |
|
# print(str(e)) |
1937 |
|
# exit(1) |
1938 |
|
|
1939 |
|
|
1940 |
0 |
@cli_osm.command(name='nsi-create', short_help='creates a new Network Slice Instance') |
1941 |
0 |
@click.option('--nsi_name', prompt=True, help='name of the Network Slice Instance') |
1942 |
0 |
@click.option('--nst_name', prompt=True, help='name of the Network Slice Template') |
1943 |
0 |
@click.option('--vim_account', prompt=True, help='default VIM account id or name for the deployment') |
1944 |
0 |
@click.option('--ssh_keys', default=None, |
1945 |
|
help='comma separated list of keys to inject to vnfs') |
1946 |
0 |
@click.option('--config', default=None, |
1947 |
|
help='Netslice specific yaml configuration:\n' |
1948 |
|
'netslice_subnet: [\n' |
1949 |
|
'id: TEXT, vim_account: TEXT,\n' |
1950 |
|
'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n' |
1951 |
|
'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]\n' |
1952 |
|
'additionalParamsForNsi: {param: value, ...}\n' |
1953 |
|
'additionalParamsForsubnet: [{id: SUBNET_ID, additionalParamsForNs: {}, additionalParamsForVnf: {}}]\n' |
1954 |
|
'],\n' |
1955 |
|
'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]' |
1956 |
|
) |
1957 |
0 |
@click.option('--config_file', |
1958 |
|
default=None, |
1959 |
|
help='nsi specific yaml configuration file') |
1960 |
0 |
@click.option('--wait', |
1961 |
|
required=False, |
1962 |
|
default=False, |
1963 |
|
is_flag=True, |
1964 |
|
help='do not return the control immediately, but keep it ' |
1965 |
|
'until the operation is completed, or timeout') |
1966 |
0 |
@click.pass_context |
1967 |
|
def nsi_create1(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file, wait): |
1968 |
|
"""creates a new Network Slice Instance (NSI)""" |
1969 |
0 |
logger.debug("") |
1970 |
0 |
nsi_create(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file, wait=wait) |
1971 |
|
|
1972 |
|
|
1973 |
0 |
@cli_osm.command(name='netslice-instance-create', short_help='creates a new Network Slice Instance') |
1974 |
0 |
@click.option('--nsi_name', prompt=True, help='name of the Network Slice Instance') |
1975 |
0 |
@click.option('--nst_name', prompt=True, help='name of the Network Slice Template') |
1976 |
0 |
@click.option('--vim_account', prompt=True, help='default VIM account id or name for the deployment') |
1977 |
0 |
@click.option('--ssh_keys', default=None, |
1978 |
|
help='comma separated list of keys to inject to vnfs') |
1979 |
0 |
@click.option('--config', default=None, |
1980 |
|
help='Netslice specific yaml configuration:\n' |
1981 |
|
'netslice_subnet: [\n' |
1982 |
|
'id: TEXT, vim_account: TEXT,\n' |
1983 |
|
'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n' |
1984 |
|
'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]' |
1985 |
|
'],\n' |
1986 |
|
'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]' |
1987 |
|
) |
1988 |
0 |
@click.option('--config_file', |
1989 |
|
default=None, |
1990 |
|
help='nsi specific yaml configuration file') |
1991 |
0 |
@click.option('--wait', |
1992 |
|
required=False, |
1993 |
|
default=False, |
1994 |
|
is_flag=True, |
1995 |
|
help='do not return the control immediately, but keep it ' |
1996 |
|
'until the operation is completed, or timeout') |
1997 |
0 |
@click.pass_context |
1998 |
|
def nsi_create2(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file, wait): |
1999 |
|
"""creates a new Network Slice Instance (NSI)""" |
2000 |
0 |
logger.debug("") |
2001 |
0 |
nsi_create(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file, wait=wait) |
2002 |
|
|
2003 |
|
|
2004 |
0 |
@cli_osm.command(name='pdu-create', short_help='adds a new Physical Deployment Unit to the catalog') |
2005 |
0 |
@click.option('--name', help='name of the Physical Deployment Unit') |
2006 |
0 |
@click.option('--pdu_type', help='type of PDU (e.g. router, firewall, FW001)') |
2007 |
0 |
@click.option('--interface', |
2008 |
|
help='interface(s) of the PDU: name=<NAME>,mgmt=<true|false>,ip-address=<IP_ADDRESS>'+ |
2009 |
|
'[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]', |
2010 |
|
multiple=True) |
2011 |
0 |
@click.option('--description', help='human readable description') |
2012 |
0 |
@click.option('--vim_account', help='list of VIM accounts (in the same VIM) that can reach this PDU', multiple=True) |
2013 |
0 |
@click.option('--descriptor_file', default=None, |
2014 |
|
help='PDU descriptor file (as an alternative to using the other arguments') |
2015 |
0 |
@click.pass_context |
2016 |
|
def pdu_create(ctx, name, pdu_type, interface, description, vim_account, descriptor_file): |
2017 |
|
"""creates a new Physical Deployment Unit (PDU)""" |
2018 |
0 |
logger.debug("") |
2019 |
|
# try: |
2020 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2021 |
0 |
pdu = {} |
2022 |
0 |
if not descriptor_file: |
2023 |
0 |
if not name: |
2024 |
0 |
raise ClientException('in absence of descriptor file, option "--name" is mandatory') |
2025 |
0 |
if not pdu_type: |
2026 |
0 |
raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory') |
2027 |
0 |
if not interface: |
2028 |
0 |
raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)') |
2029 |
0 |
if not vim_account: |
2030 |
0 |
raise ClientException('in absence of descriptor file, option "--vim_account" is mandatory (at least once)') |
2031 |
|
else: |
2032 |
0 |
with open(descriptor_file, 'r') as df: |
2033 |
0 |
pdu = yaml.safe_load(df.read()) |
2034 |
0 |
if name: pdu["name"] = name |
2035 |
0 |
if pdu_type: pdu["type"] = pdu_type |
2036 |
0 |
if description: pdu["description"] = description |
2037 |
0 |
if vim_account: pdu["vim_accounts"] = vim_account |
2038 |
0 |
if interface: |
2039 |
0 |
ifaces_list = [] |
2040 |
0 |
for iface in interface: |
2041 |
0 |
new_iface={k:v for k,v in [i.split('=') for i in iface.split(',')]} |
2042 |
0 |
new_iface["mgmt"] = (new_iface.get("mgmt","false").lower() == "true") |
2043 |
0 |
ifaces_list.append(new_iface) |
2044 |
0 |
pdu["interfaces"] = ifaces_list |
2045 |
0 |
ctx.obj.pdu.create(pdu) |
2046 |
|
# except ClientException as e: |
2047 |
|
# print(str(e)) |
2048 |
|
# exit(1) |
2049 |
|
|
2050 |
|
|
2051 |
|
#################### |
2052 |
|
# UPDATE operations |
2053 |
|
#################### |
2054 |
|
|
2055 |
0 |
def nsd_update(ctx, name, content): |
2056 |
0 |
logger.debug("") |
2057 |
|
# try: |
2058 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2059 |
0 |
ctx.obj.nsd.update(name, content) |
2060 |
|
# except ClientException as e: |
2061 |
|
# print(str(e)) |
2062 |
|
# exit(1) |
2063 |
|
|
2064 |
|
|
2065 |
0 |
@cli_osm.command(name='nsd-update', short_help='updates a NSD/NSpkg') |
2066 |
0 |
@click.argument('name') |
2067 |
0 |
@click.option('--content', default=None, |
2068 |
|
help='filename with the NSD/NSpkg replacing the current one') |
2069 |
0 |
@click.pass_context |
2070 |
|
def nsd_update1(ctx, name, content): |
2071 |
|
"""updates a NSD/NSpkg |
2072 |
|
|
2073 |
|
NAME: name or ID of the NSD/NSpkg |
2074 |
|
""" |
2075 |
0 |
logger.debug("") |
2076 |
0 |
nsd_update(ctx, name, content) |
2077 |
|
|
2078 |
|
|
2079 |
0 |
@cli_osm.command(name='nspkg-update', short_help='updates a NSD/NSpkg') |
2080 |
0 |
@click.argument('name') |
2081 |
0 |
@click.option('--content', default=None, |
2082 |
|
help='filename with the NSD/NSpkg replacing the current one') |
2083 |
0 |
@click.pass_context |
2084 |
|
def nsd_update2(ctx, name, content): |
2085 |
|
"""updates a NSD/NSpkg |
2086 |
|
|
2087 |
|
NAME: name or ID of the NSD/NSpkg |
2088 |
|
""" |
2089 |
0 |
logger.debug("") |
2090 |
0 |
nsd_update(ctx, name, content) |
2091 |
|
|
2092 |
|
|
2093 |
0 |
def vnfd_update(ctx, name, content): |
2094 |
0 |
logger.debug("") |
2095 |
|
# try: |
2096 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2097 |
0 |
ctx.obj.vnfd.update(name, content) |
2098 |
|
# except ClientException as e: |
2099 |
|
# print(str(e)) |
2100 |
|
# exit(1) |
2101 |
|
|
2102 |
|
|
2103 |
0 |
@cli_osm.command(name='vnfd-update', short_help='updates a new VNFD/VNFpkg') |
2104 |
0 |
@click.argument('name') |
2105 |
0 |
@click.option('--content', default=None, |
2106 |
|
help='filename with the VNFD/VNFpkg replacing the current one') |
2107 |
0 |
@click.pass_context |
2108 |
|
def vnfd_update1(ctx, name, content): |
2109 |
|
"""updates a VNFD/VNFpkg |
2110 |
|
|
2111 |
|
NAME: name or ID of the VNFD/VNFpkg |
2112 |
|
""" |
2113 |
0 |
logger.debug("") |
2114 |
0 |
vnfd_update(ctx, name, content) |
2115 |
|
|
2116 |
|
|
2117 |
0 |
@cli_osm.command(name='vnfpkg-update', short_help='updates a VNFD/VNFpkg') |
2118 |
0 |
@click.argument('name') |
2119 |
0 |
@click.option('--content', default=None, |
2120 |
|
help='filename with the VNFD/VNFpkg replacing the current one') |
2121 |
0 |
@click.pass_context |
2122 |
|
def vnfd_update2(ctx, name, content): |
2123 |
|
"""updates a VNFD/VNFpkg |
2124 |
|
|
2125 |
|
NAME: VNFD yaml file or VNFpkg tar.gz file |
2126 |
|
""" |
2127 |
0 |
logger.debug("") |
2128 |
0 |
vnfd_update(ctx, name, content) |
2129 |
|
|
2130 |
|
|
2131 |
0 |
@cli_osm.command(name='nfpkg-update', short_help='updates a NFpkg') |
2132 |
0 |
@click.argument('name') |
2133 |
0 |
@click.option('--content', default=None, |
2134 |
|
help='filename with the NFpkg replacing the current one') |
2135 |
0 |
@click.pass_context |
2136 |
|
def nfpkg_update(ctx, name, content): |
2137 |
|
"""updates a NFpkg |
2138 |
|
|
2139 |
|
NAME: NF Descriptor yaml file or NFpkg tar.gz file |
2140 |
|
""" |
2141 |
0 |
logger.debug("") |
2142 |
0 |
vnfd_update(ctx, name, content) |
2143 |
|
|
2144 |
|
|
2145 |
0 |
def nst_update(ctx, name, content): |
2146 |
0 |
logger.debug("") |
2147 |
|
# try: |
2148 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2149 |
0 |
ctx.obj.nst.update(name, content) |
2150 |
|
# except ClientException as e: |
2151 |
|
# print(str(e)) |
2152 |
|
# exit(1) |
2153 |
|
|
2154 |
|
|
2155 |
0 |
@cli_osm.command(name='nst-update', short_help='updates a Network Slice Template (NST)') |
2156 |
0 |
@click.argument('name') |
2157 |
0 |
@click.option('--content', default=None, |
2158 |
|
help='filename with the NST/NSTpkg replacing the current one') |
2159 |
0 |
@click.pass_context |
2160 |
|
def nst_update1(ctx, name, content): |
2161 |
|
"""updates a Network Slice Template (NST) |
2162 |
|
|
2163 |
|
NAME: name or ID of the NSD/NSpkg |
2164 |
|
""" |
2165 |
0 |
logger.debug("") |
2166 |
0 |
nst_update(ctx, name, content) |
2167 |
|
|
2168 |
|
|
2169 |
0 |
@cli_osm.command(name='netslice-template-update', short_help='updates a Network Slice Template (NST)') |
2170 |
0 |
@click.argument('name') |
2171 |
0 |
@click.option('--content', default=None, |
2172 |
|
help='filename with the NST/NSTpkg replacing the current one') |
2173 |
0 |
@click.pass_context |
2174 |
|
def nst_update2(ctx, name, content): |
2175 |
|
"""updates a Network Slice Template (NST) |
2176 |
|
|
2177 |
|
NAME: name or ID of the NSD/NSpkg |
2178 |
|
""" |
2179 |
0 |
logger.debug("") |
2180 |
0 |
nst_update(ctx, name, content) |
2181 |
|
|
2182 |
|
|
2183 |
|
#################### |
2184 |
|
# DELETE operations |
2185 |
|
#################### |
2186 |
|
|
2187 |
0 |
def nsd_delete(ctx, name, force): |
2188 |
0 |
logger.debug("") |
2189 |
|
# try: |
2190 |
0 |
if not force: |
2191 |
0 |
ctx.obj.nsd.delete(name) |
2192 |
|
else: |
2193 |
0 |
check_client_version(ctx.obj, '--force') |
2194 |
0 |
ctx.obj.nsd.delete(name, force) |
2195 |
|
# except ClientException as e: |
2196 |
|
# print(str(e)) |
2197 |
|
# exit(1) |
2198 |
|
|
2199 |
|
|
2200 |
0 |
@cli_osm.command(name='nsd-delete', short_help='deletes a NSD/NSpkg') |
2201 |
0 |
@click.argument('name') |
2202 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
2203 |
0 |
@click.pass_context |
2204 |
|
def nsd_delete1(ctx, name, force): |
2205 |
|
"""deletes a NSD/NSpkg |
2206 |
|
|
2207 |
|
NAME: name or ID of the NSD/NSpkg to be deleted |
2208 |
|
""" |
2209 |
0 |
logger.debug("") |
2210 |
0 |
nsd_delete(ctx, name, force) |
2211 |
|
|
2212 |
|
|
2213 |
0 |
@cli_osm.command(name='nspkg-delete', short_help='deletes a NSD/NSpkg') |
2214 |
0 |
@click.argument('name') |
2215 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
2216 |
0 |
@click.pass_context |
2217 |
|
def nsd_delete2(ctx, name, force): |
2218 |
|
"""deletes a NSD/NSpkg |
2219 |
|
|
2220 |
|
NAME: name or ID of the NSD/NSpkg to be deleted |
2221 |
|
""" |
2222 |
0 |
logger.debug("") |
2223 |
0 |
nsd_delete(ctx, name, force) |
2224 |
|
|
2225 |
|
|
2226 |
0 |
def vnfd_delete(ctx, name, force): |
2227 |
0 |
logger.debug("") |
2228 |
|
# try: |
2229 |
0 |
if not force: |
2230 |
0 |
ctx.obj.vnfd.delete(name) |
2231 |
|
else: |
2232 |
0 |
check_client_version(ctx.obj, '--force') |
2233 |
0 |
ctx.obj.vnfd.delete(name, force) |
2234 |
|
# except ClientException as e: |
2235 |
|
# print(str(e)) |
2236 |
|
# exit(1) |
2237 |
|
|
2238 |
|
|
2239 |
0 |
@cli_osm.command(name='vnfd-delete', short_help='deletes a VNFD/VNFpkg') |
2240 |
0 |
@click.argument('name') |
2241 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
2242 |
0 |
@click.pass_context |
2243 |
|
def vnfd_delete1(ctx, name, force): |
2244 |
|
"""deletes a VNFD/VNFpkg |
2245 |
|
|
2246 |
|
NAME: name or ID of the VNFD/VNFpkg to be deleted |
2247 |
|
""" |
2248 |
0 |
logger.debug("") |
2249 |
0 |
vnfd_delete(ctx, name, force) |
2250 |
|
|
2251 |
|
|
2252 |
0 |
@cli_osm.command(name='vnfpkg-delete', short_help='deletes a VNFD/VNFpkg') |
2253 |
0 |
@click.argument('name') |
2254 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
2255 |
0 |
@click.pass_context |
2256 |
|
def vnfd_delete2(ctx, name, force): |
2257 |
|
"""deletes a VNFD/VNFpkg |
2258 |
|
|
2259 |
|
NAME: name or ID of the VNFD/VNFpkg to be deleted |
2260 |
|
""" |
2261 |
0 |
logger.debug("") |
2262 |
0 |
vnfd_delete(ctx, name, force) |
2263 |
|
|
2264 |
|
|
2265 |
0 |
@cli_osm.command(name='nfpkg-delete', short_help='deletes a NFpkg') |
2266 |
0 |
@click.argument('name') |
2267 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
2268 |
0 |
@click.pass_context |
2269 |
|
def nfpkg_delete(ctx, name, force): |
2270 |
|
"""deletes a NFpkg |
2271 |
|
|
2272 |
|
NAME: name or ID of the NFpkg to be deleted |
2273 |
|
""" |
2274 |
0 |
logger.debug("") |
2275 |
0 |
vnfd_delete(ctx, name, force) |
2276 |
|
|
2277 |
|
|
2278 |
0 |
@cli_osm.command(name='ns-delete', short_help='deletes a NS instance') |
2279 |
0 |
@click.argument('name') |
2280 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
2281 |
0 |
@click.option('--config', default=None, |
2282 |
|
help="specific yaml configuration for the termination, e.g. '{autoremove: False, timeout_ns_terminate: " |
2283 |
|
"600, skip_terminate_primitives: True}'") |
2284 |
0 |
@click.option('--wait', |
2285 |
|
required=False, |
2286 |
|
default=False, |
2287 |
|
is_flag=True, |
2288 |
|
help='do not return the control immediately, but keep it ' |
2289 |
|
'until the operation is completed, or timeout') |
2290 |
0 |
@click.pass_context |
2291 |
|
def ns_delete(ctx, name, force, config, wait): |
2292 |
|
"""deletes a NS instance |
2293 |
|
|
2294 |
|
NAME: name or ID of the NS instance to be deleted |
2295 |
|
""" |
2296 |
0 |
logger.debug("") |
2297 |
|
# try: |
2298 |
0 |
if not force: |
2299 |
0 |
ctx.obj.ns.delete(name, config=config, wait=wait) |
2300 |
|
else: |
2301 |
0 |
check_client_version(ctx.obj, '--force') |
2302 |
0 |
ctx.obj.ns.delete(name, force, config=config, wait=wait) |
2303 |
|
# except ClientException as e: |
2304 |
|
# print(str(e)) |
2305 |
|
# exit(1) |
2306 |
|
|
2307 |
|
|
2308 |
0 |
def nst_delete(ctx, name, force): |
2309 |
0 |
logger.debug("") |
2310 |
|
# try: |
2311 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2312 |
0 |
ctx.obj.nst.delete(name, force) |
2313 |
|
# except ClientException as e: |
2314 |
|
# print(str(e)) |
2315 |
|
# exit(1) |
2316 |
|
|
2317 |
|
|
2318 |
0 |
@cli_osm.command(name='nst-delete', short_help='deletes a Network Slice Template (NST)') |
2319 |
0 |
@click.argument('name') |
2320 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
2321 |
0 |
@click.pass_context |
2322 |
|
def nst_delete1(ctx, name, force): |
2323 |
|
"""deletes a Network Slice Template (NST) |
2324 |
|
|
2325 |
|
NAME: name or ID of the NST/NSTpkg to be deleted |
2326 |
|
""" |
2327 |
0 |
logger.debug("") |
2328 |
0 |
nst_delete(ctx, name, force) |
2329 |
|
|
2330 |
|
|
2331 |
0 |
@cli_osm.command(name='netslice-template-delete', short_help='deletes a Network Slice Template (NST)') |
2332 |
0 |
@click.argument('name') |
2333 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
2334 |
0 |
@click.pass_context |
2335 |
|
def nst_delete2(ctx, name, force): |
2336 |
|
"""deletes a Network Slice Template (NST) |
2337 |
|
|
2338 |
|
NAME: name or ID of the NST/NSTpkg to be deleted |
2339 |
|
""" |
2340 |
0 |
logger.debug("") |
2341 |
0 |
nst_delete(ctx, name, force) |
2342 |
|
|
2343 |
|
|
2344 |
0 |
def nsi_delete(ctx, name, force, wait): |
2345 |
0 |
logger.debug("") |
2346 |
|
# try: |
2347 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2348 |
0 |
ctx.obj.nsi.delete(name, force, wait=wait) |
2349 |
|
# except ClientException as e: |
2350 |
|
# print(str(e)) |
2351 |
|
# exit(1) |
2352 |
|
|
2353 |
|
|
2354 |
0 |
@cli_osm.command(name='nsi-delete', short_help='deletes a Network Slice Instance (NSI)') |
2355 |
0 |
@click.argument('name') |
2356 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
2357 |
0 |
@click.option('--wait', |
2358 |
|
required=False, |
2359 |
|
default=False, |
2360 |
|
is_flag=True, |
2361 |
|
help='do not return the control immediately, but keep it ' |
2362 |
|
'until the operation is completed, or timeout') |
2363 |
0 |
@click.pass_context |
2364 |
|
def nsi_delete1(ctx, name, force, wait): |
2365 |
|
"""deletes a Network Slice Instance (NSI) |
2366 |
|
|
2367 |
|
NAME: name or ID of the Network Slice instance to be deleted |
2368 |
|
""" |
2369 |
0 |
logger.debug("") |
2370 |
0 |
nsi_delete(ctx, name, force, wait=wait) |
2371 |
|
|
2372 |
|
|
2373 |
0 |
@cli_osm.command(name='netslice-instance-delete', short_help='deletes a Network Slice Instance (NSI)') |
2374 |
0 |
@click.argument('name') |
2375 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
2376 |
0 |
@click.pass_context |
2377 |
|
def nsi_delete2(ctx, name, force, wait): |
2378 |
|
"""deletes a Network Slice Instance (NSI) |
2379 |
|
|
2380 |
|
NAME: name or ID of the Network Slice instance to be deleted |
2381 |
|
""" |
2382 |
0 |
logger.debug("") |
2383 |
0 |
nsi_delete(ctx, name, force, wait=wait) |
2384 |
|
|
2385 |
|
|
2386 |
0 |
@cli_osm.command(name='pdu-delete', short_help='deletes a Physical Deployment Unit (PDU)') |
2387 |
0 |
@click.argument('name') |
2388 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
2389 |
0 |
@click.pass_context |
2390 |
|
def pdu_delete(ctx, name, force): |
2391 |
|
"""deletes a Physical Deployment Unit (PDU) |
2392 |
|
|
2393 |
|
NAME: name or ID of the PDU to be deleted |
2394 |
|
""" |
2395 |
0 |
logger.debug("") |
2396 |
|
# try: |
2397 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2398 |
0 |
ctx.obj.pdu.delete(name, force) |
2399 |
|
# except ClientException as e: |
2400 |
|
# print(str(e)) |
2401 |
|
# exit(1) |
2402 |
|
|
2403 |
|
|
2404 |
|
################# |
2405 |
|
# VIM operations |
2406 |
|
################# |
2407 |
|
|
2408 |
0 |
@cli_osm.command(name='vim-create', short_help='creates a new VIM account') |
2409 |
0 |
@click.option('--name', |
2410 |
|
prompt=True, |
2411 |
|
help='Name to create datacenter') |
2412 |
0 |
@click.option('--user', |
2413 |
|
prompt=True, |
2414 |
|
help='VIM username') |
2415 |
0 |
@click.option('--password', |
2416 |
|
prompt=True, |
2417 |
|
hide_input=True, |
2418 |
|
confirmation_prompt=True, |
2419 |
|
help='VIM password') |
2420 |
0 |
@click.option('--auth_url', |
2421 |
|
prompt=True, |
2422 |
|
help='VIM url') |
2423 |
0 |
@click.option('--tenant', |
2424 |
|
prompt=True, |
2425 |
|
help='VIM tenant name') |
2426 |
0 |
@click.option('--config', |
2427 |
|
default=None, |
2428 |
|
help='VIM specific config parameters') |
2429 |
0 |
@click.option('--account_type', |
2430 |
|
default='openstack', |
2431 |
|
help='VIM type') |
2432 |
0 |
@click.option('--description', |
2433 |
|
default=None, |
2434 |
|
help='human readable description') |
2435 |
0 |
@click.option('--sdn_controller', default=None, help='Name or id of the SDN controller associated to this VIM account') |
2436 |
0 |
@click.option('--sdn_port_mapping', default=None, help="File describing the port mapping between compute nodes' ports and switch ports") |
2437 |
0 |
@click.option('--wait', |
2438 |
|
required=False, |
2439 |
|
default=False, |
2440 |
|
is_flag=True, |
2441 |
|
help='do not return the control immediately, but keep it ' |
2442 |
|
'until the operation is completed, or timeout') |
2443 |
0 |
@click.pass_context |
2444 |
|
def vim_create(ctx, |
2445 |
|
name, |
2446 |
|
user, |
2447 |
|
password, |
2448 |
|
auth_url, |
2449 |
|
tenant, |
2450 |
|
config, |
2451 |
|
account_type, |
2452 |
|
description, |
2453 |
|
sdn_controller, |
2454 |
|
sdn_port_mapping, |
2455 |
|
wait): |
2456 |
|
"""creates a new VIM account""" |
2457 |
0 |
logger.debug("") |
2458 |
|
# try: |
2459 |
0 |
if sdn_controller: |
2460 |
0 |
check_client_version(ctx.obj, '--sdn_controller') |
2461 |
0 |
if sdn_port_mapping: |
2462 |
0 |
check_client_version(ctx.obj, '--sdn_port_mapping') |
2463 |
0 |
vim = {} |
2464 |
0 |
vim['vim-username'] = user |
2465 |
0 |
vim['vim-password'] = password |
2466 |
0 |
vim['vim-url'] = auth_url |
2467 |
0 |
vim['vim-tenant-name'] = tenant |
2468 |
0 |
vim['vim-type'] = account_type |
2469 |
0 |
vim['description'] = description |
2470 |
0 |
vim['config'] = config |
2471 |
0 |
if sdn_controller or sdn_port_mapping: |
2472 |
0 |
ctx.obj.vim.create(name, vim, sdn_controller, sdn_port_mapping, wait=wait) |
2473 |
|
else: |
2474 |
0 |
ctx.obj.vim.create(name, vim, wait=wait) |
2475 |
|
# except ClientException as e: |
2476 |
|
# print(str(e)) |
2477 |
|
# exit(1) |
2478 |
|
|
2479 |
|
|
2480 |
0 |
@cli_osm.command(name='vim-update', short_help='updates a VIM account') |
2481 |
0 |
@click.argument('name') |
2482 |
0 |
@click.option('--newname', help='New name for the VIM account') |
2483 |
0 |
@click.option('--user', help='VIM username') |
2484 |
0 |
@click.option('--password', help='VIM password') |
2485 |
0 |
@click.option('--auth_url', help='VIM url') |
2486 |
0 |
@click.option('--tenant', help='VIM tenant name') |
2487 |
0 |
@click.option('--config', help='VIM specific config parameters') |
2488 |
0 |
@click.option('--account_type', help='VIM type') |
2489 |
0 |
@click.option('--description', help='human readable description') |
2490 |
0 |
@click.option('--sdn_controller', default=None, help='Name or id of the SDN controller to be associated with this VIM' |
2491 |
|
'account. Use empty string to disassociate') |
2492 |
0 |
@click.option('--sdn_port_mapping', default=None, help="File describing the port mapping between compute nodes' ports and switch ports") |
2493 |
0 |
@click.option('--wait', |
2494 |
|
required=False, |
2495 |
|
default=False, |
2496 |
|
is_flag=True, |
2497 |
|
help='do not return the control immediately, but keep it ' |
2498 |
|
'until the operation is completed, or timeout') |
2499 |
0 |
@click.pass_context |
2500 |
|
def vim_update(ctx, |
2501 |
|
name, |
2502 |
|
newname, |
2503 |
|
user, |
2504 |
|
password, |
2505 |
|
auth_url, |
2506 |
|
tenant, |
2507 |
|
config, |
2508 |
|
account_type, |
2509 |
|
description, |
2510 |
|
sdn_controller, |
2511 |
|
sdn_port_mapping, |
2512 |
|
wait): |
2513 |
|
"""updates a VIM account |
2514 |
|
|
2515 |
|
NAME: name or ID of the VIM account |
2516 |
|
""" |
2517 |
0 |
logger.debug("") |
2518 |
|
# try: |
2519 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2520 |
0 |
vim = {} |
2521 |
0 |
if newname: vim['name'] = newname |
2522 |
0 |
if user: vim['vim_user'] = user |
2523 |
0 |
if password: vim['vim_password'] = password |
2524 |
0 |
if auth_url: vim['vim_url'] = auth_url |
2525 |
0 |
if tenant: vim['vim-tenant-name'] = tenant |
2526 |
0 |
if account_type: vim['vim_type'] = account_type |
2527 |
0 |
if description: vim['description'] = description |
2528 |
0 |
if config: vim['config'] = config |
2529 |
0 |
ctx.obj.vim.update(name, vim, sdn_controller, sdn_port_mapping, wait=wait) |
2530 |
|
# except ClientException as e: |
2531 |
|
# print(str(e)) |
2532 |
|
# exit(1) |
2533 |
|
|
2534 |
|
|
2535 |
0 |
@cli_osm.command(name='vim-delete', short_help='deletes a VIM account') |
2536 |
0 |
@click.argument('name') |
2537 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
2538 |
0 |
@click.option('--wait', |
2539 |
|
required=False, |
2540 |
|
default=False, |
2541 |
|
is_flag=True, |
2542 |
|
help='do not return the control immediately, but keep it ' |
2543 |
|
'until the operation is completed, or timeout') |
2544 |
0 |
@click.pass_context |
2545 |
|
def vim_delete(ctx, name, force, wait): |
2546 |
|
"""deletes a VIM account |
2547 |
|
|
2548 |
|
NAME: name or ID of the VIM account to be deleted |
2549 |
|
""" |
2550 |
0 |
logger.debug("") |
2551 |
|
# try: |
2552 |
0 |
if not force: |
2553 |
0 |
ctx.obj.vim.delete(name, wait=wait) |
2554 |
|
else: |
2555 |
0 |
check_client_version(ctx.obj, '--force') |
2556 |
0 |
ctx.obj.vim.delete(name, force, wait=wait) |
2557 |
|
# except ClientException as e: |
2558 |
|
# print(str(e)) |
2559 |
|
# exit(1) |
2560 |
|
|
2561 |
|
|
2562 |
0 |
@cli_osm.command(name='vim-list', short_help='list all VIM accounts') |
2563 |
|
#@click.option('--ro_update/--no_ro_update', |
2564 |
|
# default=False, |
2565 |
|
# help='update list from RO') |
2566 |
0 |
@click.option('--filter', default=None, multiple=True, |
2567 |
|
help='restricts the list to the VIM accounts matching the filter') |
2568 |
0 |
@click.option('--long', is_flag=True, |
2569 |
|
help='get more details of the NS (project, vim, deployment status, configuration status.') |
2570 |
0 |
@click.pass_context |
2571 |
|
def vim_list(ctx, filter, long): |
2572 |
|
"""list all VIM accounts""" |
2573 |
0 |
logger.debug("") |
2574 |
0 |
if filter: |
2575 |
0 |
filter='&'.join(filter) |
2576 |
0 |
check_client_version(ctx.obj, '--filter') |
2577 |
|
# if ro_update: |
2578 |
|
# check_client_version(ctx.obj, '--ro_update', 'v1') |
2579 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
2580 |
0 |
if fullclassname == 'osmclient.sol005.client.Client': |
2581 |
0 |
resp = ctx.obj.vim.list(filter) |
2582 |
|
# else: |
2583 |
|
# resp = ctx.obj.vim.list(ro_update) |
2584 |
0 |
if long: |
2585 |
0 |
table = PrettyTable(['vim name', 'uuid', 'project', 'operational state', 'error details']) |
2586 |
0 |
project_list = ctx.obj.project.list() |
2587 |
|
else: |
2588 |
0 |
table = PrettyTable(['vim name', 'uuid', 'operational state']) |
2589 |
0 |
for vim in resp: |
2590 |
0 |
if long: |
2591 |
0 |
if 'vim_password' in vim: |
2592 |
0 |
vim['vim_password']='********' |
2593 |
0 |
logger.debug('VIM details: {}'.format(yaml.safe_dump(vim))) |
2594 |
0 |
vim_state = vim['_admin'].get('operationalState', '-') |
2595 |
0 |
error_details = 'N/A' |
2596 |
0 |
if vim_state == 'ERROR': |
2597 |
0 |
error_details = vim['_admin'].get('detailed-status', 'Not found') |
2598 |
0 |
project_id, project_name = get_project(project_list, vim) |
2599 |
|
#project_info = '{} ({})'.format(project_name, project_id) |
2600 |
0 |
project_info = project_name |
2601 |
0 |
table.add_row([vim['name'], vim['uuid'], project_info, |
2602 |
|
vim_state, wrap_text(text=error_details, width=80)]) |
2603 |
|
else: |
2604 |
0 |
table.add_row([vim['name'], vim['uuid'], vim['_admin'].get('operationalState', '-')]) |
2605 |
0 |
table.align = 'l' |
2606 |
0 |
print(table) |
2607 |
|
|
2608 |
|
|
2609 |
0 |
@cli_osm.command(name='vim-show', short_help='shows the details of a VIM account') |
2610 |
0 |
@click.argument('name') |
2611 |
0 |
@click.option('--filter', multiple=True, |
2612 |
|
help='restricts the information to the fields in the filter') |
2613 |
0 |
@click.pass_context |
2614 |
|
def vim_show(ctx, name, filter): |
2615 |
|
"""shows the details of a VIM account |
2616 |
|
|
2617 |
|
NAME: name or ID of the VIM account |
2618 |
|
""" |
2619 |
0 |
logger.debug("") |
2620 |
|
# try: |
2621 |
0 |
resp = ctx.obj.vim.get(name) |
2622 |
0 |
if 'vim_password' in resp: |
2623 |
0 |
resp['vim_password']='********' |
2624 |
|
# except ClientException as e: |
2625 |
|
# print(str(e)) |
2626 |
|
# exit(1) |
2627 |
|
|
2628 |
0 |
table = PrettyTable(['key', 'attribute']) |
2629 |
0 |
for k, v in list(resp.items()): |
2630 |
0 |
if not filter or k in filter: |
2631 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2),width=100)]) |
2632 |
0 |
table.align = 'l' |
2633 |
0 |
print(table) |
2634 |
|
|
2635 |
|
|
2636 |
|
#################### |
2637 |
|
# WIM operations |
2638 |
|
#################### |
2639 |
|
|
2640 |
0 |
@cli_osm.command(name='wim-create', short_help='creates a new WIM account') |
2641 |
0 |
@click.option('--name', |
2642 |
|
prompt=True, |
2643 |
|
help='Name for the WIM account') |
2644 |
0 |
@click.option('--user', |
2645 |
|
help='WIM username') |
2646 |
0 |
@click.option('--password', |
2647 |
|
help='WIM password') |
2648 |
0 |
@click.option('--url', |
2649 |
|
prompt=True, |
2650 |
|
help='WIM url') |
2651 |
|
# @click.option('--tenant', |
2652 |
|
# help='wIM tenant name') |
2653 |
0 |
@click.option('--config', |
2654 |
|
default=None, |
2655 |
|
help='WIM specific config parameters') |
2656 |
0 |
@click.option('--wim_type', |
2657 |
|
help='WIM type') |
2658 |
0 |
@click.option('--description', |
2659 |
|
default=None, |
2660 |
|
help='human readable description') |
2661 |
0 |
@click.option('--wim_port_mapping', default=None, |
2662 |
|
help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge " |
2663 |
|
"(WAN service endpoint id and info)") |
2664 |
0 |
@click.option('--wait', |
2665 |
|
required=False, |
2666 |
|
default=False, |
2667 |
|
is_flag=True, |
2668 |
|
help='do not return the control immediately, but keep it ' |
2669 |
|
'until the operation is completed, or timeout') |
2670 |
0 |
@click.pass_context |
2671 |
|
def wim_create(ctx, |
2672 |
|
name, |
2673 |
|
user, |
2674 |
|
password, |
2675 |
|
url, |
2676 |
|
# tenant, |
2677 |
|
config, |
2678 |
|
wim_type, |
2679 |
|
description, |
2680 |
|
wim_port_mapping, |
2681 |
|
wait): |
2682 |
|
"""creates a new WIM account""" |
2683 |
0 |
logger.debug("") |
2684 |
|
# try: |
2685 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2686 |
|
# if sdn_controller: |
2687 |
|
# check_client_version(ctx.obj, '--sdn_controller') |
2688 |
|
# if sdn_port_mapping: |
2689 |
|
# check_client_version(ctx.obj, '--sdn_port_mapping') |
2690 |
0 |
wim = {} |
2691 |
0 |
if user: wim['user'] = user |
2692 |
0 |
if password: wim['password'] = password |
2693 |
0 |
if url: wim['wim_url'] = url |
2694 |
|
# if tenant: wim['tenant'] = tenant |
2695 |
0 |
wim['wim_type'] = wim_type |
2696 |
0 |
if description: wim['description'] = description |
2697 |
0 |
if config: wim['config'] = config |
2698 |
0 |
ctx.obj.wim.create(name, wim, wim_port_mapping, wait=wait) |
2699 |
|
# except ClientException as e: |
2700 |
|
# print(str(e)) |
2701 |
|
# exit(1) |
2702 |
|
|
2703 |
|
|
2704 |
0 |
@cli_osm.command(name='wim-update', short_help='updates a WIM account') |
2705 |
0 |
@click.argument('name') |
2706 |
0 |
@click.option('--newname', help='New name for the WIM account') |
2707 |
0 |
@click.option('--user', help='WIM username') |
2708 |
0 |
@click.option('--password', help='WIM password') |
2709 |
0 |
@click.option('--url', help='WIM url') |
2710 |
0 |
@click.option('--config', help='WIM specific config parameters') |
2711 |
0 |
@click.option('--wim_type', help='WIM type') |
2712 |
0 |
@click.option('--description', help='human readable description') |
2713 |
0 |
@click.option('--wim_port_mapping', default=None, |
2714 |
|
help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge " |
2715 |
|
"(WAN service endpoint id and info)") |
2716 |
0 |
@click.option('--wait', |
2717 |
|
required=False, |
2718 |
|
default=False, |
2719 |
|
is_flag=True, |
2720 |
|
help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
2721 |
0 |
@click.pass_context |
2722 |
|
def wim_update(ctx, |
2723 |
|
name, |
2724 |
|
newname, |
2725 |
|
user, |
2726 |
|
password, |
2727 |
|
url, |
2728 |
|
config, |
2729 |
|
wim_type, |
2730 |
|
description, |
2731 |
|
wim_port_mapping, |
2732 |
|
wait): |
2733 |
|
"""updates a WIM account |
2734 |
|
|
2735 |
|
NAME: name or ID of the WIM account |
2736 |
|
""" |
2737 |
0 |
logger.debug("") |
2738 |
|
# try: |
2739 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2740 |
0 |
wim = {} |
2741 |
0 |
if newname: wim['name'] = newname |
2742 |
0 |
if user: wim['user'] = user |
2743 |
0 |
if password: wim['password'] = password |
2744 |
0 |
if url: wim['url'] = url |
2745 |
|
# if tenant: wim['tenant'] = tenant |
2746 |
0 |
if wim_type: wim['wim_type'] = wim_type |
2747 |
0 |
if description: wim['description'] = description |
2748 |
0 |
if config: wim['config'] = config |
2749 |
0 |
ctx.obj.wim.update(name, wim, wim_port_mapping, wait=wait) |
2750 |
|
# except ClientException as e: |
2751 |
|
# print(str(e)) |
2752 |
|
# exit(1) |
2753 |
|
|
2754 |
|
|
2755 |
0 |
@cli_osm.command(name='wim-delete', short_help='deletes a WIM account') |
2756 |
0 |
@click.argument('name') |
2757 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
2758 |
0 |
@click.option('--wait', |
2759 |
|
required=False, |
2760 |
|
default=False, |
2761 |
|
is_flag=True, |
2762 |
|
help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
2763 |
0 |
@click.pass_context |
2764 |
|
def wim_delete(ctx, name, force, wait): |
2765 |
|
"""deletes a WIM account |
2766 |
|
|
2767 |
|
NAME: name or ID of the WIM account to be deleted |
2768 |
|
""" |
2769 |
0 |
logger.debug("") |
2770 |
|
# try: |
2771 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2772 |
0 |
ctx.obj.wim.delete(name, force, wait=wait) |
2773 |
|
# except ClientException as e: |
2774 |
|
# print(str(e)) |
2775 |
|
# exit(1) |
2776 |
|
|
2777 |
|
|
2778 |
0 |
@cli_osm.command(name='wim-list', short_help='list all WIM accounts') |
2779 |
0 |
@click.option('--filter', default=None, multiple=True, |
2780 |
|
help='restricts the list to the WIM accounts matching the filter') |
2781 |
0 |
@click.pass_context |
2782 |
|
def wim_list(ctx, filter): |
2783 |
|
"""list all WIM accounts""" |
2784 |
0 |
logger.debug("") |
2785 |
|
# try: |
2786 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2787 |
0 |
if filter: |
2788 |
0 |
filter='&'.join(filter) |
2789 |
0 |
resp = ctx.obj.wim.list(filter) |
2790 |
0 |
table = PrettyTable(['wim name', 'uuid']) |
2791 |
0 |
for wim in resp: |
2792 |
0 |
table.add_row([wim['name'], wim['uuid']]) |
2793 |
0 |
table.align = 'l' |
2794 |
0 |
print(table) |
2795 |
|
# except ClientException as e: |
2796 |
|
# print(str(e)) |
2797 |
|
# exit(1) |
2798 |
|
|
2799 |
|
|
2800 |
0 |
@cli_osm.command(name='wim-show', short_help='shows the details of a WIM account') |
2801 |
0 |
@click.argument('name') |
2802 |
0 |
@click.pass_context |
2803 |
|
def wim_show(ctx, name): |
2804 |
|
"""shows the details of a WIM account |
2805 |
|
|
2806 |
|
NAME: name or ID of the WIM account |
2807 |
|
""" |
2808 |
0 |
logger.debug("") |
2809 |
|
# try: |
2810 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2811 |
0 |
resp = ctx.obj.wim.get(name) |
2812 |
0 |
if 'password' in resp: |
2813 |
0 |
resp['wim_password']='********' |
2814 |
|
# except ClientException as e: |
2815 |
|
# print(str(e)) |
2816 |
|
# exit(1) |
2817 |
|
|
2818 |
0 |
table = PrettyTable(['key', 'attribute']) |
2819 |
0 |
for k, v in list(resp.items()): |
2820 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
2821 |
0 |
table.align = 'l' |
2822 |
0 |
print(table) |
2823 |
|
|
2824 |
|
|
2825 |
|
#################### |
2826 |
|
# SDN controller operations |
2827 |
|
#################### |
2828 |
|
|
2829 |
0 |
@cli_osm.command(name='sdnc-create', short_help='creates a new SDN controller') |
2830 |
0 |
@click.option('--name', |
2831 |
|
prompt=True, |
2832 |
|
help='Name to create sdn controller') |
2833 |
0 |
@click.option('--type', |
2834 |
|
prompt=True, |
2835 |
|
help='SDN controller type') |
2836 |
0 |
@click.option('--sdn_controller_version', # hidden=True, |
2837 |
|
help='Deprecated. Use --config {version: sdn_controller_version}') |
2838 |
0 |
@click.option('--url', |
2839 |
|
help='URL in format http[s]://HOST:IP/') |
2840 |
0 |
@click.option('--ip_address', # hidden=True, |
2841 |
|
help='Deprecated. Use --url') |
2842 |
0 |
@click.option('--port', # hidden=True, |
2843 |
|
help='Deprecated. Use --url') |
2844 |
0 |
@click.option('--switch_dpid', # hidden=True, |
2845 |
|
help='Deprecated. Use --config {switch_id: DPID}') |
2846 |
0 |
@click.option('--config', |
2847 |
|
help='Extra information for SDN in yaml format, as {switch_id: identity used for the plugin (e.g. DPID: ' |
2848 |
|
'Openflow Datapath ID), version: version}') |
2849 |
0 |
@click.option('--user', |
2850 |
|
help='SDN controller username') |
2851 |
0 |
@click.option('--password', |
2852 |
|
hide_input=True, |
2853 |
|
confirmation_prompt=True, |
2854 |
|
help='SDN controller password') |
2855 |
0 |
@click.option('--description', default=None, help='human readable description') |
2856 |
0 |
@click.option('--wait', |
2857 |
|
required=False, |
2858 |
|
default=False, |
2859 |
|
is_flag=True, |
2860 |
|
help="do not return the control immediately, but keep it until the operation is completed, or timeout") |
2861 |
0 |
@click.pass_context |
2862 |
|
def sdnc_create(ctx, **kwargs): |
2863 |
|
"""creates a new SDN controller""" |
2864 |
0 |
logger.debug("") |
2865 |
0 |
sdncontroller = {x: kwargs[x] for x in kwargs if kwargs[x] and |
2866 |
|
x not in ("wait", "ip_address", "port", "switch_dpid")} |
2867 |
0 |
if kwargs.get("port"): |
2868 |
0 |
print("option '--port' is deprecated, use '--url' instead") |
2869 |
0 |
sdncontroller["port"] = int(kwargs["port"]) |
2870 |
0 |
if kwargs.get("ip_address"): |
2871 |
0 |
print("option '--ip_address' is deprecated, use '--url' instead") |
2872 |
0 |
sdncontroller["ip"] = kwargs["ip_address"] |
2873 |
0 |
if kwargs.get("switch_dpid"): |
2874 |
0 |
print("option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead") |
2875 |
0 |
sdncontroller["dpid"] = kwargs["switch_dpid"] |
2876 |
0 |
if kwargs.get("sdn_controller_version"): |
2877 |
0 |
print("option '--sdn_controller_version' is deprecated, use '--config={version: SDN_CONTROLLER_VERSION}'" |
2878 |
|
" instead") |
2879 |
|
# try: |
2880 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2881 |
0 |
ctx.obj.sdnc.create(kwargs["name"], sdncontroller, wait=kwargs["wait"]) |
2882 |
|
# except ClientException as e: |
2883 |
|
# print(str(e)) |
2884 |
|
# exit(1) |
2885 |
|
|
2886 |
0 |
@cli_osm.command(name='sdnc-update', short_help='updates an SDN controller') |
2887 |
0 |
@click.argument('name') |
2888 |
0 |
@click.option('--newname', help='New name for the SDN controller') |
2889 |
0 |
@click.option('--description', default=None, help='human readable description') |
2890 |
0 |
@click.option('--type', help='SDN controller type') |
2891 |
0 |
@click.option('--url', help='URL in format http[s]://HOST:IP/') |
2892 |
0 |
@click.option('--config', help='Extra information for SDN in yaml format, as ' |
2893 |
|
'{switch_id: identity used for the plugin (e.g. DPID: ' |
2894 |
|
'Openflow Datapath ID), version: version}') |
2895 |
0 |
@click.option('--user', help='SDN controller username') |
2896 |
0 |
@click.option('--password', help='SDN controller password') |
2897 |
0 |
@click.option('--ip_address', help='Deprecated. Use --url') # hidden=True |
2898 |
0 |
@click.option('--port', help='Deprecated. Use --url') # hidden=True |
2899 |
0 |
@click.option('--switch_dpid', help='Deprecated. Use --config {switch_dpid: DPID}') # hidden=True |
2900 |
0 |
@click.option('--sdn_controller_version', help='Deprecated. Use --config {version: VERSION}') # hidden=True |
2901 |
0 |
@click.option('--wait', required=False, default=False, is_flag=True, |
2902 |
|
help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
2903 |
0 |
@click.pass_context |
2904 |
|
def sdnc_update(ctx, **kwargs): |
2905 |
|
"""updates an SDN controller |
2906 |
|
|
2907 |
|
NAME: name or ID of the SDN controller |
2908 |
|
""" |
2909 |
0 |
logger.debug("") |
2910 |
0 |
sdncontroller = {x: kwargs[x] for x in kwargs if kwargs[x] and |
2911 |
|
x not in ("wait", "ip_address", "port", "switch_dpid", "new_name")} |
2912 |
0 |
if kwargs.get("newname"): |
2913 |
0 |
sdncontroller["name"] = kwargs["newname"] |
2914 |
0 |
if kwargs.get("port"): |
2915 |
0 |
print("option '--port' is deprecated, use '--url' instead") |
2916 |
0 |
sdncontroller["port"] = int(kwargs["port"]) |
2917 |
0 |
if kwargs.get("ip_address"): |
2918 |
0 |
print("option '--ip_address' is deprecated, use '--url' instead") |
2919 |
0 |
sdncontroller["ip"] = kwargs["ip_address"] |
2920 |
0 |
if kwargs.get("switch_dpid"): |
2921 |
0 |
print("option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead") |
2922 |
0 |
sdncontroller["dpid"] = kwargs["switch_dpid"] |
2923 |
0 |
if kwargs.get("sdn_controller_version"): |
2924 |
0 |
print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'" |
2925 |
|
" instead") |
2926 |
|
|
2927 |
|
# try: |
2928 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2929 |
0 |
ctx.obj.sdnc.update(kwargs["name"], sdncontroller, wait=kwargs["wait"]) |
2930 |
|
# except ClientException as e: |
2931 |
|
# print(str(e)) |
2932 |
|
# exit(1) |
2933 |
|
|
2934 |
|
|
2935 |
0 |
@cli_osm.command(name='sdnc-delete', short_help='deletes an SDN controller') |
2936 |
0 |
@click.argument('name') |
2937 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
2938 |
0 |
@click.option('--wait', required=False, default=False, is_flag=True, |
2939 |
|
help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
2940 |
0 |
@click.pass_context |
2941 |
|
def sdnc_delete(ctx, name, force, wait): |
2942 |
|
"""deletes an SDN controller |
2943 |
|
|
2944 |
|
NAME: name or ID of the SDN controller to be deleted |
2945 |
|
""" |
2946 |
0 |
logger.debug("") |
2947 |
|
# try: |
2948 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2949 |
0 |
ctx.obj.sdnc.delete(name, force, wait=wait) |
2950 |
|
# except ClientException as e: |
2951 |
|
# print(str(e)) |
2952 |
|
# exit(1) |
2953 |
|
|
2954 |
|
|
2955 |
0 |
@cli_osm.command(name='sdnc-list', short_help='list all SDN controllers') |
2956 |
0 |
@click.option('--filter', default=None, multiple=True, |
2957 |
|
help="restricts the list to the SDN controllers matching the filter with format: 'k[.k..]=v[&k[.k]=v2]'") |
2958 |
0 |
@click.pass_context |
2959 |
|
def sdnc_list(ctx, filter): |
2960 |
|
"""list all SDN controllers""" |
2961 |
0 |
logger.debug("") |
2962 |
|
# try: |
2963 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2964 |
0 |
if filter: |
2965 |
0 |
filter='&'.join(filter) |
2966 |
0 |
resp = ctx.obj.sdnc.list(filter) |
2967 |
|
# except ClientException as e: |
2968 |
|
# print(str(e)) |
2969 |
|
# exit(1) |
2970 |
0 |
table = PrettyTable(['sdnc name', 'id']) |
2971 |
0 |
for sdnc in resp: |
2972 |
0 |
table.add_row([sdnc['name'], sdnc['_id']]) |
2973 |
0 |
table.align = 'l' |
2974 |
0 |
print(table) |
2975 |
|
|
2976 |
|
|
2977 |
0 |
@cli_osm.command(name='sdnc-show', short_help='shows the details of an SDN controller') |
2978 |
0 |
@click.argument('name') |
2979 |
0 |
@click.pass_context |
2980 |
|
def sdnc_show(ctx, name): |
2981 |
|
"""shows the details of an SDN controller |
2982 |
|
|
2983 |
|
NAME: name or ID of the SDN controller |
2984 |
|
""" |
2985 |
0 |
logger.debug("") |
2986 |
|
# try: |
2987 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2988 |
0 |
resp = ctx.obj.sdnc.get(name) |
2989 |
|
# except ClientException as e: |
2990 |
|
# print(str(e)) |
2991 |
|
# exit(1) |
2992 |
|
|
2993 |
0 |
table = PrettyTable(['key', 'attribute']) |
2994 |
0 |
for k, v in list(resp.items()): |
2995 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
2996 |
0 |
table.align = 'l' |
2997 |
0 |
print(table) |
2998 |
|
|
2999 |
|
|
3000 |
|
########################### |
3001 |
|
# K8s cluster operations |
3002 |
|
########################### |
3003 |
|
|
3004 |
0 |
@cli_osm.command(name='k8scluster-add', short_help='adds a K8s cluster to OSM') |
3005 |
0 |
@click.argument('name') |
3006 |
0 |
@click.option('--creds', |
3007 |
|
prompt=True, |
3008 |
|
help='credentials file, i.e. a valid `.kube/config` file') |
3009 |
0 |
@click.option('--version', |
3010 |
|
prompt=True, |
3011 |
|
help='Kubernetes version') |
3012 |
0 |
@click.option('--vim', |
3013 |
|
prompt=True, |
3014 |
|
help='VIM target, the VIM where the cluster resides') |
3015 |
0 |
@click.option('--k8s-nets', |
3016 |
|
prompt=True, |
3017 |
|
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) ...]}"') |
3018 |
0 |
@click.option('--description', |
3019 |
|
default=None, |
3020 |
|
help='human readable description') |
3021 |
0 |
@click.option('--namespace', |
3022 |
|
default='kube-system', |
3023 |
|
help='namespace to be used for its operation, defaults to `kube-system`') |
3024 |
0 |
@click.option('--cni', |
3025 |
|
default=None, |
3026 |
|
help='list of CNI plugins, in JSON inline format, used in the cluster') |
3027 |
|
#@click.option('--skip-init', |
3028 |
|
# is_flag=True, |
3029 |
|
# help='If set, K8s cluster is assumed to be ready for its use with OSM') |
3030 |
|
#@click.option('--wait', |
3031 |
|
# is_flag=True, |
3032 |
|
# help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
3033 |
0 |
@click.pass_context |
3034 |
|
def k8scluster_add(ctx, |
3035 |
|
name, |
3036 |
|
creds, |
3037 |
|
version, |
3038 |
|
vim, |
3039 |
|
k8s_nets, |
3040 |
|
description, |
3041 |
|
namespace, |
3042 |
|
cni): |
3043 |
|
"""adds a K8s cluster to OSM |
3044 |
|
|
3045 |
|
NAME: name of the K8s cluster |
3046 |
|
""" |
3047 |
|
# try: |
3048 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3049 |
0 |
cluster = {} |
3050 |
0 |
cluster['name'] = name |
3051 |
0 |
with open(creds, 'r') as cf: |
3052 |
0 |
cluster['credentials'] = yaml.safe_load(cf.read()) |
3053 |
0 |
cluster['k8s_version'] = version |
3054 |
0 |
cluster['vim_account'] = vim |
3055 |
0 |
cluster['nets'] = yaml.safe_load(k8s_nets) |
3056 |
0 |
if description: |
3057 |
0 |
cluster['description'] = description |
3058 |
0 |
if namespace: cluster['namespace'] = namespace |
3059 |
0 |
if cni: cluster['cni'] = yaml.safe_load(cni) |
3060 |
0 |
ctx.obj.k8scluster.create(name, cluster) |
3061 |
|
# except ClientException as e: |
3062 |
|
# print(str(e)) |
3063 |
|
# exit(1) |
3064 |
|
|
3065 |
|
|
3066 |
0 |
@cli_osm.command(name='k8scluster-update', short_help='updates a K8s cluster') |
3067 |
0 |
@click.argument('name') |
3068 |
0 |
@click.option('--newname', help='New name for the K8s cluster') |
3069 |
0 |
@click.option('--creds', help='credentials file, i.e. a valid `.kube/config` file') |
3070 |
0 |
@click.option('--version', help='Kubernetes version') |
3071 |
0 |
@click.option('--vim', help='VIM target, the VIM where the cluster resides') |
3072 |
0 |
@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) ...]}"') |
3073 |
0 |
@click.option('--description', help='human readable description') |
3074 |
0 |
@click.option('--namespace', help='namespace to be used for its operation, defaults to `kube-system`') |
3075 |
0 |
@click.option('--cni', help='list of CNI plugins, in JSON inline format, used in the cluster') |
3076 |
0 |
@click.pass_context |
3077 |
|
def k8scluster_update(ctx, |
3078 |
|
name, |
3079 |
|
newname, |
3080 |
|
creds, |
3081 |
|
version, |
3082 |
|
vim, |
3083 |
|
k8s_nets, |
3084 |
|
description, |
3085 |
|
namespace, |
3086 |
|
cni): |
3087 |
|
"""updates a K8s cluster |
3088 |
|
|
3089 |
|
NAME: name or ID of the K8s cluster |
3090 |
|
""" |
3091 |
|
# try: |
3092 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3093 |
0 |
cluster = {} |
3094 |
0 |
if newname: cluster['name'] = newname |
3095 |
0 |
if creds: |
3096 |
0 |
with open(creds, 'r') as cf: |
3097 |
0 |
cluster['credentials'] = yaml.safe_load(cf.read()) |
3098 |
0 |
if version: cluster['k8s_version'] = version |
3099 |
0 |
if vim: cluster['vim_account'] = vim |
3100 |
0 |
if k8s_nets: cluster['nets'] = yaml.safe_load(k8s_nets) |
3101 |
0 |
if description: cluster['description'] = description |
3102 |
0 |
if namespace: cluster['namespace'] = namespace |
3103 |
0 |
if cni: cluster['cni'] = yaml.safe_load(cni) |
3104 |
0 |
ctx.obj.k8scluster.update(name, cluster) |
3105 |
|
# except ClientException as e: |
3106 |
|
# print(str(e)) |
3107 |
|
# exit(1) |
3108 |
|
|
3109 |
|
|
3110 |
0 |
@cli_osm.command(name='k8scluster-delete', short_help='deletes a K8s cluster') |
3111 |
0 |
@click.argument('name') |
3112 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion from the DB (not recommended)') |
3113 |
|
#@click.option('--wait', |
3114 |
|
# is_flag=True, |
3115 |
|
# help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
3116 |
0 |
@click.pass_context |
3117 |
|
def k8scluster_delete(ctx, name, force): |
3118 |
|
"""deletes a K8s cluster |
3119 |
|
|
3120 |
|
NAME: name or ID of the K8s cluster to be deleted |
3121 |
|
""" |
3122 |
|
# try: |
3123 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3124 |
0 |
ctx.obj.k8scluster.delete(name, force=force) |
3125 |
|
# except ClientException as e: |
3126 |
|
# print(str(e)) |
3127 |
|
# exit(1) |
3128 |
|
|
3129 |
|
|
3130 |
0 |
@cli_osm.command(name='k8scluster-list') |
3131 |
0 |
@click.option('--filter', default=None, multiple=True, |
3132 |
|
help='restricts the list to the K8s clusters matching the filter') |
3133 |
0 |
@click.option('--literal', is_flag=True, |
3134 |
|
help='print literally, no pretty table') |
3135 |
0 |
@click.option('--long', is_flag=True, help='get more details') |
3136 |
0 |
@click.pass_context |
3137 |
|
def k8scluster_list(ctx, filter, literal, long): |
3138 |
|
"""list all K8s clusters""" |
3139 |
|
# try: |
3140 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3141 |
0 |
if filter: |
3142 |
0 |
filter='&'.join(filter) |
3143 |
0 |
resp = ctx.obj.k8scluster.list(filter) |
3144 |
0 |
if literal: |
3145 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
3146 |
0 |
return |
3147 |
0 |
if long: |
3148 |
0 |
table = PrettyTable(['Name', 'Id', 'Project', 'Version', 'VIM', 'K8s-nets', |
3149 |
|
'Operational State', 'Op. state (details)', 'Description', 'Detailed status']) |
3150 |
0 |
project_list = ctx.obj.project.list() |
3151 |
|
else: |
3152 |
0 |
table = PrettyTable(['Name', 'Id', 'VIM', 'Operational State', 'Op. state details']) |
3153 |
0 |
try: |
3154 |
0 |
vim_list = ctx.obj.vim.list() |
3155 |
0 |
except: |
3156 |
0 |
vim_list = [] |
3157 |
0 |
for cluster in resp: |
3158 |
0 |
logger.debug('Cluster details: {}'.format(yaml.safe_dump(cluster))) |
3159 |
0 |
vim_name = get_vim_name(vim_list, cluster['vim_account']) |
3160 |
|
#vim_info = '{} ({})'.format(vim_name,cluster['vim_account']) |
3161 |
0 |
vim_info = vim_name |
3162 |
0 |
op_state_details = "Helm: {}\nJuju: {}".format( |
3163 |
|
cluster["_admin"].get("helm-chart", {}).get("operationalState", "-"), |
3164 |
|
cluster["_admin"].get("juju-bundle", {}).get("operationalState", "-")) |
3165 |
0 |
if long: |
3166 |
0 |
project_id, project_name = get_project(project_list, cluster) |
3167 |
|
#project_info = '{} ({})'.format(project_name, project_id) |
3168 |
0 |
project_info = project_name |
3169 |
0 |
detailed_status = cluster["_admin"].get("detailed-status","-") |
3170 |
0 |
table.add_row([cluster['name'], cluster['_id'], project_info, |
3171 |
|
cluster['k8s_version'], vim_info, |
3172 |
|
json.dumps(cluster['nets']), cluster["_admin"]["operationalState"], |
3173 |
|
op_state_details, trunc_text(cluster.get('description') or '', 40), |
3174 |
|
wrap_text(text=detailed_status, width=40)]) |
3175 |
|
else: |
3176 |
0 |
table.add_row([cluster['name'], cluster['_id'], vim_info, |
3177 |
|
cluster["_admin"]["operationalState"], op_state_details]) |
3178 |
0 |
table.align = 'l' |
3179 |
0 |
print(table) |
3180 |
|
# except ClientException as e: |
3181 |
|
# print(str(e)) |
3182 |
|
# exit(1) |
3183 |
|
|
3184 |
|
|
3185 |
0 |
@cli_osm.command(name='k8scluster-show', short_help='shows the details of a K8s cluster') |
3186 |
0 |
@click.argument('name') |
3187 |
0 |
@click.option('--literal', is_flag=True, |
3188 |
|
help='print literally, no pretty table') |
3189 |
0 |
@click.pass_context |
3190 |
|
def k8scluster_show(ctx, name, literal): |
3191 |
|
"""shows the details of a K8s cluster |
3192 |
|
|
3193 |
|
NAME: name or ID of the K8s cluster |
3194 |
|
""" |
3195 |
|
# try: |
3196 |
0 |
resp = ctx.obj.k8scluster.get(name) |
3197 |
0 |
if literal: |
3198 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
3199 |
0 |
return |
3200 |
0 |
table = PrettyTable(['key', 'attribute']) |
3201 |
0 |
for k, v in list(resp.items()): |
3202 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2),width=100)]) |
3203 |
0 |
table.align = 'l' |
3204 |
0 |
print(table) |
3205 |
|
# except ClientException as e: |
3206 |
|
# print(str(e)) |
3207 |
|
# exit(1) |
3208 |
|
|
3209 |
|
|
3210 |
|
|
3211 |
|
########################### |
3212 |
|
# Repo operations |
3213 |
|
########################### |
3214 |
|
|
3215 |
0 |
@cli_osm.command(name='repo-add', short_help='adds a repo to OSM') |
3216 |
0 |
@click.argument('name') |
3217 |
0 |
@click.argument('uri') |
3218 |
0 |
@click.option('--type', |
3219 |
|
type=click.Choice(['helm-chart', 'juju-bundle', 'osm']), |
3220 |
|
default='osm', |
3221 |
|
help='type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles, osm for OSM Repositories)') |
3222 |
0 |
@click.option('--description', |
3223 |
|
default=None, |
3224 |
|
help='human readable description') |
3225 |
0 |
@click.option('--user', |
3226 |
|
default=None, |
3227 |
|
help='OSM repository: The username of the OSM repository') |
3228 |
0 |
@click.option('--password', |
3229 |
|
default=None, |
3230 |
|
help='OSM repository: The password of the OSM repository') |
3231 |
|
#@click.option('--wait', |
3232 |
|
# is_flag=True, |
3233 |
|
# help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
3234 |
0 |
@click.pass_context |
3235 |
|
def repo_add(ctx, **kwargs): |
3236 |
|
"""adds a repo to OSM |
3237 |
|
|
3238 |
|
NAME: name of the repo |
3239 |
|
URI: URI of the repo |
3240 |
|
""" |
3241 |
|
# try: |
3242 |
0 |
kwargs = {k: v for k, v in kwargs.items() if v is not None} |
3243 |
0 |
repo = kwargs |
3244 |
0 |
repo["url"] = repo.pop("uri") |
3245 |
0 |
if repo["type"] in ['helm-chart', 'juju-bundle']: |
3246 |
0 |
ctx.obj.repo.create(repo['name'], repo) |
3247 |
|
else: |
3248 |
0 |
ctx.obj.osmrepo.create(repo['name'], repo) |
3249 |
|
# except ClientException as e: |
3250 |
|
# print(str(e)) |
3251 |
|
# exit(1) |
3252 |
|
|
3253 |
|
|
3254 |
0 |
@cli_osm.command(name='repo-update', short_help='updates a repo in OSM') |
3255 |
0 |
@click.argument('name') |
3256 |
0 |
@click.option('--newname', help='New name for the repo') |
3257 |
0 |
@click.option('--uri', help='URI of the repo') |
3258 |
0 |
@click.option('--description', help='human readable description') |
3259 |
|
#@click.option('--wait', |
3260 |
|
# is_flag=True, |
3261 |
|
# help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
3262 |
0 |
@click.pass_context |
3263 |
|
def repo_update(ctx, |
3264 |
|
name, |
3265 |
|
newname, |
3266 |
|
uri, |
3267 |
|
description): |
3268 |
|
"""updates a repo in OSM |
3269 |
|
|
3270 |
|
NAME: name of the repo |
3271 |
|
""" |
3272 |
|
# try: |
3273 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3274 |
0 |
repo = {} |
3275 |
0 |
if newname: |
3276 |
0 |
repo['name'] = newname |
3277 |
0 |
if uri: |
3278 |
0 |
repo['uri'] = uri |
3279 |
0 |
if description: repo['description'] = description |
3280 |
0 |
try: |
3281 |
0 |
ctx.obj.repo.update(name, repo) |
3282 |
0 |
except NotFound: |
3283 |
0 |
ctx.obj.osmrepo.update(name, repo) |
3284 |
|
|
3285 |
|
# except ClientException as e: |
3286 |
|
# print(str(e)) |
3287 |
|
# exit(1) |
3288 |
|
|
3289 |
|
|
3290 |
0 |
@cli_osm.command(name='repo-index', short_help='Index a repository from a folder with artifacts') |
3291 |
0 |
@click.option('--origin', default='.', help='origin path where the artifacts are located') |
3292 |
0 |
@click.option('--destination', default='.', help='destination path where the index is deployed') |
3293 |
0 |
@click.pass_context |
3294 |
|
def repo_index(ctx, origin, destination): |
3295 |
|
"""Index a repository |
3296 |
|
|
3297 |
|
NAME: name or ID of the repo to be deleted |
3298 |
|
""" |
3299 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3300 |
0 |
ctx.obj.osmrepo.repo_index(origin, destination) |
3301 |
|
|
3302 |
|
|
3303 |
0 |
@cli_osm.command(name='repo-delete', short_help='deletes a repo') |
3304 |
0 |
@click.argument('name') |
3305 |
0 |
@click.option('--force', is_flag=True, help='forces the deletion from the DB (not recommended)') |
3306 |
|
#@click.option('--wait', |
3307 |
|
# is_flag=True, |
3308 |
|
# help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
3309 |
0 |
@click.pass_context |
3310 |
|
def repo_delete(ctx, name, force): |
3311 |
|
"""deletes a repo |
3312 |
|
|
3313 |
|
NAME: name or ID of the repo to be deleted |
3314 |
|
""" |
3315 |
0 |
logger.debug("") |
3316 |
0 |
try: |
3317 |
0 |
ctx.obj.repo.delete(name, force=force) |
3318 |
0 |
except NotFound: |
3319 |
0 |
ctx.obj.osmrepo.delete(name, force=force) |
3320 |
|
# except ClientException as e: |
3321 |
|
# print(str(e)) |
3322 |
|
# exit(1) |
3323 |
|
|
3324 |
|
|
3325 |
0 |
@cli_osm.command(name='repo-list') |
3326 |
0 |
@click.option('--filter', default=None, multiple=True, |
3327 |
|
help='restricts the list to the repos matching the filter') |
3328 |
0 |
@click.option('--literal', is_flag=True, |
3329 |
|
help='print literally, no pretty table') |
3330 |
0 |
@click.pass_context |
3331 |
|
def repo_list(ctx, filter, literal): |
3332 |
|
"""list all repos""" |
3333 |
|
# try: |
3334 |
|
# K8s Repositories |
3335 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3336 |
0 |
if filter: |
3337 |
0 |
filter='&'.join(filter) |
3338 |
0 |
resp = ctx.obj.repo.list(filter) |
3339 |
0 |
resp += ctx.obj.osmrepo.list(filter) |
3340 |
0 |
if literal: |
3341 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
3342 |
0 |
return |
3343 |
0 |
table = PrettyTable(['Name', 'Id', 'Type', 'URI', 'Description']) |
3344 |
0 |
for repo in resp: |
3345 |
|
#cluster['k8s-nets'] = json.dumps(yaml.safe_load(cluster['k8s-nets'])) |
3346 |
0 |
table.add_row([repo['name'], repo['_id'], repo['type'], repo['url'], trunc_text(repo.get('description') or '',40)]) |
3347 |
0 |
table.align = 'l' |
3348 |
0 |
print(table) |
3349 |
|
|
3350 |
|
# except ClientException as e: |
3351 |
|
# print(str(e)) |
3352 |
|
# exit(1) |
3353 |
|
|
3354 |
|
|
3355 |
0 |
@cli_osm.command(name='repo-show', short_help='shows the details of a repo') |
3356 |
0 |
@click.argument('name') |
3357 |
0 |
@click.option('--literal', is_flag=True, |
3358 |
|
help='print literally, no pretty table') |
3359 |
0 |
@click.pass_context |
3360 |
|
def repo_show(ctx, name, literal): |
3361 |
|
"""shows the details of a repo |
3362 |
|
|
3363 |
|
NAME: name or ID of the repo |
3364 |
|
""" |
3365 |
0 |
try: |
3366 |
0 |
resp = ctx.obj.repo.get(name) |
3367 |
0 |
except NotFound: |
3368 |
0 |
resp = ctx.obj.osmrepo.get(name) |
3369 |
|
|
3370 |
0 |
if literal: |
3371 |
0 |
if resp: |
3372 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
3373 |
0 |
return |
3374 |
0 |
table = PrettyTable(['key', 'attribute']) |
3375 |
0 |
if resp: |
3376 |
0 |
for k, v in list(resp.items()): |
3377 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
3378 |
|
|
3379 |
0 |
table.align = 'l' |
3380 |
0 |
print(table) |
3381 |
|
# except ClientException as e: |
3382 |
|
# print(str(e)) |
3383 |
|
# exit(1) |
3384 |
|
|
3385 |
|
|
3386 |
|
|
3387 |
|
#################### |
3388 |
|
# Project mgmt operations |
3389 |
|
#################### |
3390 |
|
|
3391 |
0 |
@cli_osm.command(name='project-create', short_help='creates a new project') |
3392 |
0 |
@click.argument('name') |
3393 |
|
#@click.option('--description', |
3394 |
|
# default='no description', |
3395 |
|
# help='human readable description') |
3396 |
0 |
@click.option('--domain-name', 'domain_name', |
3397 |
|
default=None, |
3398 |
|
help='assign to a domain') |
3399 |
0 |
@click.option('--quotas', 'quotas', multiple=True, default=None, |
3400 |
|
help="provide quotas. Can be used several times: 'quota1=number[,quota2=number,...]'. Quotas can be one " |
3401 |
|
"of vnfds, nsds, nsts, pdus, nsrs, nsis, vim_accounts, wim_accounts, sdns, k8sclusters, k8srepos") |
3402 |
0 |
@click.pass_context |
3403 |
|
def project_create(ctx, name, domain_name, quotas): |
3404 |
|
"""Creates a new project |
3405 |
|
|
3406 |
|
NAME: name of the project |
3407 |
|
DOMAIN_NAME: optional domain name for the project when keystone authentication is used |
3408 |
|
QUOTAS: set quotas for the project |
3409 |
|
""" |
3410 |
0 |
logger.debug("") |
3411 |
0 |
project = {'name': name} |
3412 |
0 |
if domain_name: |
3413 |
0 |
project['domain_name'] = domain_name |
3414 |
0 |
quotas_dict = _process_project_quotas(quotas) |
3415 |
0 |
if quotas_dict: |
3416 |
0 |
project['quotas'] = quotas_dict |
3417 |
|
|
3418 |
|
# try: |
3419 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3420 |
0 |
ctx.obj.project.create(name, project) |
3421 |
|
# except ClientException as e: |
3422 |
|
# print(str(e)) |
3423 |
|
# exit(1) |
3424 |
|
|
3425 |
|
|
3426 |
0 |
def _process_project_quotas(quota_list): |
3427 |
0 |
quotas_dict = {} |
3428 |
0 |
if not quota_list: |
3429 |
0 |
return quotas_dict |
3430 |
0 |
try: |
3431 |
0 |
for quota in quota_list: |
3432 |
0 |
for single_quota in quota.split(","): |
3433 |
0 |
k, v = single_quota.split("=") |
3434 |
0 |
quotas_dict[k] = None if v in ('None', 'null', '') else int(v) |
3435 |
0 |
except (ValueError, TypeError): |
3436 |
0 |
raise ClientException("invalid format for 'quotas'. Use 'k1=v1,v1=v2'. v must be a integer or null") |
3437 |
0 |
return quotas_dict |
3438 |
|
|
3439 |
|
|
3440 |
0 |
@cli_osm.command(name='project-delete', short_help='deletes a project') |
3441 |
0 |
@click.argument('name') |
3442 |
|
#@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
3443 |
0 |
@click.pass_context |
3444 |
|
def project_delete(ctx, name): |
3445 |
|
"""deletes a project |
3446 |
|
|
3447 |
|
NAME: name or ID of the project to be deleted |
3448 |
|
""" |
3449 |
0 |
logger.debug("") |
3450 |
|
# try: |
3451 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3452 |
0 |
ctx.obj.project.delete(name) |
3453 |
|
# except ClientException as e: |
3454 |
|
# print(str(e)) |
3455 |
|
# exit(1) |
3456 |
|
|
3457 |
|
|
3458 |
0 |
@cli_osm.command(name='project-list', short_help='list all projects') |
3459 |
0 |
@click.option('--filter', default=None, multiple=True, |
3460 |
|
help='restricts the list to the projects matching the filter') |
3461 |
0 |
@click.pass_context |
3462 |
|
def project_list(ctx, filter): |
3463 |
|
"""list all projects""" |
3464 |
0 |
logger.debug("") |
3465 |
|
# try: |
3466 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3467 |
0 |
if filter: |
3468 |
0 |
filter='&'.join(filter) |
3469 |
0 |
resp = ctx.obj.project.list(filter) |
3470 |
|
# except ClientException as e: |
3471 |
|
# print(str(e)) |
3472 |
|
# exit(1) |
3473 |
0 |
table = PrettyTable(['name', 'id']) |
3474 |
0 |
for proj in resp: |
3475 |
0 |
table.add_row([proj['name'], proj['_id']]) |
3476 |
0 |
table.align = 'l' |
3477 |
0 |
print(table) |
3478 |
|
|
3479 |
|
|
3480 |
0 |
@cli_osm.command(name='project-show', short_help='shows the details of a project') |
3481 |
0 |
@click.argument('name') |
3482 |
0 |
@click.pass_context |
3483 |
|
def project_show(ctx, name): |
3484 |
|
"""shows the details of a project |
3485 |
|
|
3486 |
|
NAME: name or ID of the project |
3487 |
|
""" |
3488 |
0 |
logger.debug("") |
3489 |
|
# try: |
3490 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3491 |
0 |
resp = ctx.obj.project.get(name) |
3492 |
|
# except ClientException as e: |
3493 |
|
# print(str(e)) |
3494 |
|
# exit(1) |
3495 |
|
|
3496 |
0 |
table = PrettyTable(['key', 'attribute']) |
3497 |
0 |
for k, v in resp.items(): |
3498 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
3499 |
0 |
table.align = 'l' |
3500 |
0 |
print(table) |
3501 |
|
|
3502 |
|
|
3503 |
0 |
@cli_osm.command(name='project-update', short_help='updates a project (only the name can be updated)') |
3504 |
0 |
@click.argument('project') |
3505 |
0 |
@click.option('--name', default=None, |
3506 |
|
help='new name for the project') |
3507 |
0 |
@click.option('--quotas', 'quotas', multiple=True, default=None, |
3508 |
|
help="change quotas. Can be used several times: 'quota1=number|empty[,quota2=...]' " |
3509 |
|
"(use empty to reset quota to default") |
3510 |
0 |
@click.pass_context |
3511 |
|
def project_update(ctx, project, name, quotas): |
3512 |
|
""" |
3513 |
|
Update a project name |
3514 |
|
|
3515 |
|
:param ctx: |
3516 |
|
:param project: id or name of the project to modify |
3517 |
|
:param name: new name for the project |
3518 |
|
:param quotas: change quotas of the project |
3519 |
|
:return: |
3520 |
|
""" |
3521 |
0 |
logger.debug("") |
3522 |
0 |
project_changes = {} |
3523 |
0 |
if name: |
3524 |
0 |
project_changes['name'] = name |
3525 |
0 |
quotas_dict = _process_project_quotas(quotas) |
3526 |
0 |
if quotas_dict: |
3527 |
0 |
project_changes['quotas'] = quotas_dict |
3528 |
|
|
3529 |
|
# try: |
3530 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3531 |
0 |
ctx.obj.project.update(project, project_changes) |
3532 |
|
# except ClientException as e: |
3533 |
|
# print(str(e)) |
3534 |
|
|
3535 |
|
|
3536 |
|
#################### |
3537 |
|
# User mgmt operations |
3538 |
|
#################### |
3539 |
|
|
3540 |
0 |
@cli_osm.command(name='user-create', short_help='creates a new user') |
3541 |
0 |
@click.argument('username') |
3542 |
0 |
@click.option('--password', |
3543 |
|
prompt=True, |
3544 |
|
hide_input=True, |
3545 |
|
confirmation_prompt=True, |
3546 |
|
help='user password') |
3547 |
0 |
@click.option('--projects', |
3548 |
|
# prompt="Comma separate list of projects", |
3549 |
|
multiple=True, |
3550 |
|
callback=lambda ctx, param, value: ''.join(value).split(',') if all(len(x)==1 for x in value) else value, |
3551 |
|
help='list of project ids that the user belongs to') |
3552 |
0 |
@click.option('--project-role-mappings', 'project_role_mappings', |
3553 |
|
default=None, multiple=True, |
3554 |
|
help="assign role(s) in a project. Can be used several times: 'project,role1[,role2,...]'") |
3555 |
0 |
@click.option('--domain-name', 'domain_name', |
3556 |
|
default=None, |
3557 |
|
help='assign to a domain') |
3558 |
0 |
@click.pass_context |
3559 |
|
def user_create(ctx, username, password, projects, project_role_mappings, domain_name): |
3560 |
|
"""Creates a new user |
3561 |
|
|
3562 |
|
\b |
3563 |
|
USERNAME: name of the user |
3564 |
|
PASSWORD: password of the user |
3565 |
|
PROJECTS: projects assigned to user (internal only) |
3566 |
|
PROJECT_ROLE_MAPPING: roles in projects assigned to user (keystone) |
3567 |
|
DOMAIN_NAME: optional domain name for the user when keystone authentication is used |
3568 |
|
""" |
3569 |
0 |
logger.debug("") |
3570 |
0 |
user = {} |
3571 |
0 |
user['username'] = username |
3572 |
0 |
user['password'] = password |
3573 |
0 |
user['projects'] = projects |
3574 |
0 |
user['project_role_mappings'] = project_role_mappings |
3575 |
0 |
if domain_name: |
3576 |
0 |
user['domain_name'] = domain_name |
3577 |
|
|
3578 |
|
# try: |
3579 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3580 |
0 |
ctx.obj.user.create(username, user) |
3581 |
|
# except ClientException as e: |
3582 |
|
# print(str(e)) |
3583 |
|
# exit(1) |
3584 |
|
|
3585 |
|
|
3586 |
0 |
@cli_osm.command(name='user-update', short_help='updates user information') |
3587 |
0 |
@click.argument('username') |
3588 |
0 |
@click.option('--password', |
3589 |
|
# prompt=True, |
3590 |
|
# hide_input=True, |
3591 |
|
# confirmation_prompt=True, |
3592 |
|
help='user password') |
3593 |
0 |
@click.option('--set-username', 'set_username', |
3594 |
|
default=None, |
3595 |
|
help='change username') |
3596 |
0 |
@click.option('--set-project', 'set_project', |
3597 |
|
default=None, multiple=True, |
3598 |
|
help="create/replace the roles for this project: 'project,role1[,role2,...]'") |
3599 |
0 |
@click.option('--remove-project', 'remove_project', |
3600 |
|
default=None, multiple=True, |
3601 |
|
help="removes project from user: 'project'") |
3602 |
0 |
@click.option('--add-project-role', 'add_project_role', |
3603 |
|
default=None, multiple=True, |
3604 |
|
help="assign role(s) in a project. Can be used several times: 'project,role1[,role2,...]'") |
3605 |
0 |
@click.option('--remove-project-role', 'remove_project_role', |
3606 |
|
default=None, multiple=True, |
3607 |
|
help="remove role(s) in a project. Can be used several times: 'project,role1[,role2,...]'") |
3608 |
0 |
@click.pass_context |
3609 |
|
def user_update(ctx, username, password, set_username, set_project, remove_project, |
3610 |
|
add_project_role, remove_project_role): |
3611 |
|
"""Update a user information |
3612 |
|
|
3613 |
|
\b |
3614 |
|
USERNAME: name of the user |
3615 |
|
PASSWORD: new password |
3616 |
|
SET_USERNAME: new username |
3617 |
|
SET_PROJECT: creating mappings for project/role(s) |
3618 |
|
REMOVE_PROJECT: deleting mappings for project/role(s) |
3619 |
|
ADD_PROJECT_ROLE: adding mappings for project/role(s) |
3620 |
|
REMOVE_PROJECT_ROLE: removing mappings for project/role(s) |
3621 |
|
""" |
3622 |
0 |
logger.debug("") |
3623 |
0 |
user = {} |
3624 |
0 |
user['password'] = password |
3625 |
0 |
user['username'] = set_username |
3626 |
0 |
user['set-project'] = set_project |
3627 |
0 |
user['remove-project'] = remove_project |
3628 |
0 |
user['add-project-role'] = add_project_role |
3629 |
0 |
user['remove-project-role'] = remove_project_role |
3630 |
|
|
3631 |
|
# try: |
3632 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3633 |
0 |
ctx.obj.user.update(username, user) |
3634 |
|
# except ClientException as e: |
3635 |
|
# print(str(e)) |
3636 |
|
# exit(1) |
3637 |
|
|
3638 |
|
|
3639 |
0 |
@cli_osm.command(name='user-delete', short_help='deletes a user') |
3640 |
0 |
@click.argument('name') |
3641 |
|
#@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
3642 |
0 |
@click.pass_context |
3643 |
|
def user_delete(ctx, name): |
3644 |
|
"""deletes a user |
3645 |
|
|
3646 |
|
\b |
3647 |
|
NAME: name or ID of the user to be deleted |
3648 |
|
""" |
3649 |
0 |
logger.debug("") |
3650 |
|
# try: |
3651 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3652 |
0 |
ctx.obj.user.delete(name) |
3653 |
|
# except ClientException as e: |
3654 |
|
# print(str(e)) |
3655 |
|
# exit(1) |
3656 |
|
|
3657 |
|
|
3658 |
0 |
@cli_osm.command(name='user-list', short_help='list all users') |
3659 |
0 |
@click.option('--filter', default=None, multiple=True, |
3660 |
|
help='restricts the list to the users matching the filter') |
3661 |
0 |
@click.pass_context |
3662 |
|
def user_list(ctx, filter): |
3663 |
|
"""list all users""" |
3664 |
|
# try: |
3665 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3666 |
0 |
if filter: |
3667 |
0 |
filter='&'.join(filter) |
3668 |
0 |
resp = ctx.obj.user.list(filter) |
3669 |
|
# except ClientException as e: |
3670 |
|
# print(str(e)) |
3671 |
|
# exit(1) |
3672 |
0 |
table = PrettyTable(['name', 'id']) |
3673 |
0 |
for user in resp: |
3674 |
0 |
table.add_row([user['username'], user['_id']]) |
3675 |
0 |
table.align = 'l' |
3676 |
0 |
print(table) |
3677 |
|
|
3678 |
|
|
3679 |
0 |
@cli_osm.command(name='user-show', short_help='shows the details of a user') |
3680 |
0 |
@click.argument('name') |
3681 |
0 |
@click.pass_context |
3682 |
|
def user_show(ctx, name): |
3683 |
|
"""shows the details of a user |
3684 |
|
|
3685 |
|
NAME: name or ID of the user |
3686 |
|
""" |
3687 |
0 |
logger.debug("") |
3688 |
|
# try: |
3689 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3690 |
0 |
resp = ctx.obj.user.get(name) |
3691 |
0 |
if 'password' in resp: |
3692 |
0 |
resp['password']='********' |
3693 |
|
# except ClientException as e: |
3694 |
|
# print(str(e)) |
3695 |
|
# exit(1) |
3696 |
|
|
3697 |
0 |
table = PrettyTable(['key', 'attribute']) |
3698 |
0 |
for k, v in resp.items(): |
3699 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
3700 |
0 |
table.align = 'l' |
3701 |
0 |
print(table) |
3702 |
|
|
3703 |
|
|
3704 |
|
#################### |
3705 |
|
# Fault Management operations |
3706 |
|
#################### |
3707 |
|
|
3708 |
0 |
@cli_osm.command(name='ns-alarm-create') |
3709 |
0 |
@click.argument('name') |
3710 |
0 |
@click.option('--ns', prompt=True, help='NS instance id or name') |
3711 |
0 |
@click.option('--vnf', prompt=True, |
3712 |
|
help='VNF name (VNF member index as declared in the NSD)') |
3713 |
0 |
@click.option('--vdu', prompt=True, |
3714 |
|
help='VDU name (VDU name as declared in the VNFD)') |
3715 |
0 |
@click.option('--metric', prompt=True, |
3716 |
|
help='Name of the metric (e.g. cpu_utilization)') |
3717 |
0 |
@click.option('--severity', default='WARNING', |
3718 |
|
help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)') |
3719 |
0 |
@click.option('--threshold_value', prompt=True, |
3720 |
|
help='threshold value that, when crossed, an alarm is triggered') |
3721 |
0 |
@click.option('--threshold_operator', prompt=True, |
3722 |
|
help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)') |
3723 |
0 |
@click.option('--statistic', default='AVERAGE', |
3724 |
|
help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)') |
3725 |
0 |
@click.pass_context |
3726 |
|
def ns_alarm_create(ctx, name, ns, vnf, vdu, metric, severity, |
3727 |
|
threshold_value, threshold_operator, statistic): |
3728 |
|
"""creates a new alarm for a NS instance""" |
3729 |
|
# TODO: Check how to validate threshold_value. |
3730 |
|
# Should it be an integer (1-100), percentage, or decimal (0.01-1.00)? |
3731 |
0 |
logger.debug("") |
3732 |
|
# try: |
3733 |
0 |
ns_instance = ctx.obj.ns.get(ns) |
3734 |
0 |
alarm = {} |
3735 |
0 |
alarm['alarm_name'] = name |
3736 |
0 |
alarm['ns_id'] = ns_instance['_id'] |
3737 |
0 |
alarm['correlation_id'] = ns_instance['_id'] |
3738 |
0 |
alarm['vnf_member_index'] = vnf |
3739 |
0 |
alarm['vdu_name'] = vdu |
3740 |
0 |
alarm['metric_name'] = metric |
3741 |
0 |
alarm['severity'] = severity |
3742 |
0 |
alarm['threshold_value'] = int(threshold_value) |
3743 |
0 |
alarm['operation'] = threshold_operator |
3744 |
0 |
alarm['statistic'] = statistic |
3745 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3746 |
0 |
ctx.obj.ns.create_alarm(alarm) |
3747 |
|
# except ClientException as e: |
3748 |
|
# print(str(e)) |
3749 |
|
# exit(1) |
3750 |
|
|
3751 |
|
|
3752 |
|
#@cli_osm.command(name='ns-alarm-delete') |
3753 |
|
#@click.argument('name') |
3754 |
|
#@click.pass_context |
3755 |
|
#def ns_alarm_delete(ctx, name): |
3756 |
|
# """deletes an alarm |
3757 |
|
# |
3758 |
|
# NAME: name of the alarm to be deleted |
3759 |
|
# """ |
3760 |
|
# try: |
3761 |
|
# check_client_version(ctx.obj, ctx.command.name) |
3762 |
|
# ctx.obj.ns.delete_alarm(name) |
3763 |
|
# except ClientException as e: |
3764 |
|
# print(str(e)) |
3765 |
|
# exit(1) |
3766 |
|
|
3767 |
|
|
3768 |
|
#################### |
3769 |
|
# Performance Management operations |
3770 |
|
#################### |
3771 |
|
|
3772 |
0 |
@cli_osm.command(name='ns-metric-export', short_help='exports a metric to the internal OSM bus, which can be read by other apps') |
3773 |
0 |
@click.option('--ns', prompt=True, help='NS instance id or name') |
3774 |
0 |
@click.option('--vnf', prompt=True, |
3775 |
|
help='VNF name (VNF member index as declared in the NSD)') |
3776 |
0 |
@click.option('--vdu', prompt=True, |
3777 |
|
help='VDU name (VDU name as declared in the VNFD)') |
3778 |
0 |
@click.option('--metric', prompt=True, |
3779 |
|
help='name of the metric (e.g. cpu_utilization)') |
3780 |
|
#@click.option('--period', default='1w', |
3781 |
|
# help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)') |
3782 |
0 |
@click.option('--interval', help='periodic interval (seconds) to export metrics continuously') |
3783 |
0 |
@click.pass_context |
3784 |
|
def ns_metric_export(ctx, ns, vnf, vdu, metric, interval): |
3785 |
|
"""exports a metric to the internal OSM bus, which can be read by other apps""" |
3786 |
|
# TODO: Check how to validate interval. |
3787 |
|
# Should it be an integer (seconds), or should a suffix (s,m,h,d,w) also be permitted? |
3788 |
0 |
logger.debug("") |
3789 |
|
# try: |
3790 |
0 |
ns_instance = ctx.obj.ns.get(ns) |
3791 |
0 |
metric_data = {} |
3792 |
0 |
metric_data['ns_id'] = ns_instance['_id'] |
3793 |
0 |
metric_data['correlation_id'] = ns_instance['_id'] |
3794 |
0 |
metric_data['vnf_member_index'] = vnf |
3795 |
0 |
metric_data['vdu_name'] = vdu |
3796 |
0 |
metric_data['metric_name'] = metric |
3797 |
0 |
metric_data['collection_unit'] = 'WEEK' |
3798 |
0 |
metric_data['collection_period'] = 1 |
3799 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3800 |
0 |
if not interval: |
3801 |
0 |
print('{}'.format(ctx.obj.ns.export_metric(metric_data))) |
3802 |
|
else: |
3803 |
0 |
i = 1 |
3804 |
0 |
while True: |
3805 |
0 |
print('{} {}'.format(ctx.obj.ns.export_metric(metric_data),i)) |
3806 |
0 |
time.sleep(int(interval)) |
3807 |
0 |
i+=1 |
3808 |
|
# except ClientException as e: |
3809 |
|
# print(str(e)) |
3810 |
|
# exit(1) |
3811 |
|
|
3812 |
|
|
3813 |
|
#################### |
3814 |
|
# Other operations |
3815 |
|
#################### |
3816 |
|
|
3817 |
0 |
@cli_osm.command(name='version', short_help='shows client and server versions') |
3818 |
0 |
@click.pass_context |
3819 |
|
def get_version(ctx): |
3820 |
|
"""shows client and server versions""" |
3821 |
|
# try: |
3822 |
0 |
check_client_version(ctx.obj, "version") |
3823 |
0 |
print ("Server version: {}".format(ctx.obj.get_version())) |
3824 |
0 |
print ("Client version: {}".format(pkg_resources.get_distribution("osmclient").version)) |
3825 |
|
# except ClientException as e: |
3826 |
|
# print(str(e)) |
3827 |
|
# exit(1) |
3828 |
|
|
3829 |
0 |
@cli_osm.command(name='upload-package', short_help='uploads a VNF package or NS package') |
3830 |
0 |
@click.argument('filename') |
3831 |
0 |
@click.option('--skip-charm-build', default=False, is_flag=True, |
3832 |
|
help='the charm will not be compiled, it is assumed to already exist') |
3833 |
0 |
@click.pass_context |
3834 |
|
def upload_package(ctx, filename, skip_charm_build): |
3835 |
|
"""uploads a vnf package or ns package |
3836 |
|
|
3837 |
|
filename: vnf or ns package folder, or vnf or ns package file (tar.gz) |
3838 |
|
""" |
3839 |
0 |
logger.debug("") |
3840 |
|
# try: |
3841 |
0 |
ctx.obj.package.upload(filename, skip_charm_build=skip_charm_build) |
3842 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
3843 |
0 |
if fullclassname != 'osmclient.sol005.client.Client': |
3844 |
0 |
ctx.obj.package.wait_for_upload(filename) |
3845 |
|
# except ClientException as e: |
3846 |
|
# print(str(e)) |
3847 |
|
# exit(1) |
3848 |
|
|
3849 |
|
|
3850 |
|
#@cli_osm.command(name='ns-scaling-show') |
3851 |
|
#@click.argument('ns_name') |
3852 |
|
#@click.pass_context |
3853 |
|
#def show_ns_scaling(ctx, ns_name): |
3854 |
|
# """shows the status of a NS scaling operation |
3855 |
|
# |
3856 |
|
# NS_NAME: name of the NS instance being scaled |
3857 |
|
# """ |
3858 |
|
# try: |
3859 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
3860 |
|
# resp = ctx.obj.ns.list() |
3861 |
|
# except ClientException as e: |
3862 |
|
# print(str(e)) |
3863 |
|
# exit(1) |
3864 |
|
# |
3865 |
|
# table = PrettyTable( |
3866 |
|
# ['group-name', |
3867 |
|
# 'instance-id', |
3868 |
|
# 'operational status', |
3869 |
|
# 'create-time', |
3870 |
|
# 'vnfr ids']) |
3871 |
|
# |
3872 |
|
# for ns in resp: |
3873 |
|
# if ns_name == ns['name']: |
3874 |
|
# nsopdata = ctx.obj.ns.get_opdata(ns['id']) |
3875 |
|
# scaling_records = nsopdata['nsr:nsr']['scaling-group-record'] |
3876 |
|
# for record in scaling_records: |
3877 |
|
# if 'instance' in record: |
3878 |
|
# instances = record['instance'] |
3879 |
|
# for inst in instances: |
3880 |
|
# table.add_row( |
3881 |
|
# [record['scaling-group-name-ref'], |
3882 |
|
# inst['instance-id'], |
3883 |
|
# inst['op-status'], |
3884 |
|
# time.strftime('%Y-%m-%d %H:%M:%S', |
3885 |
|
# time.localtime( |
3886 |
|
# inst['create-time'])), |
3887 |
|
# inst['vnfrs']]) |
3888 |
|
# table.align = 'l' |
3889 |
|
# print(table) |
3890 |
|
|
3891 |
|
|
3892 |
|
#@cli_osm.command(name='ns-scale') |
3893 |
|
#@click.argument('ns_name') |
3894 |
|
#@click.option('--ns_scale_group', prompt=True) |
3895 |
|
#@click.option('--index', prompt=True) |
3896 |
|
#@click.option('--wait', |
3897 |
|
# required=False, |
3898 |
|
# default=False, |
3899 |
|
# is_flag=True, |
3900 |
|
# help='do not return the control immediately, but keep it \ |
3901 |
|
# until the operation is completed, or timeout') |
3902 |
|
#@click.pass_context |
3903 |
|
#def ns_scale(ctx, ns_name, ns_scale_group, index, wait): |
3904 |
|
# """scales NS |
3905 |
|
# |
3906 |
|
# NS_NAME: name of the NS instance to be scaled |
3907 |
|
# """ |
3908 |
|
# try: |
3909 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
3910 |
|
# ctx.obj.ns.scale(ns_name, ns_scale_group, index, wait=wait) |
3911 |
|
# except ClientException as e: |
3912 |
|
# print(str(e)) |
3913 |
|
# exit(1) |
3914 |
|
|
3915 |
|
|
3916 |
|
#@cli_osm.command(name='config-agent-list') |
3917 |
|
#@click.pass_context |
3918 |
|
#def config_agent_list(ctx): |
3919 |
|
# """list config agents""" |
3920 |
|
# try: |
3921 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
3922 |
|
# except ClientException as e: |
3923 |
|
# print(str(e)) |
3924 |
|
# exit(1) |
3925 |
|
# table = PrettyTable(['name', 'account-type', 'details']) |
3926 |
|
# for account in ctx.obj.vca.list(): |
3927 |
|
# table.add_row( |
3928 |
|
# [account['name'], |
3929 |
|
# account['account-type'], |
3930 |
|
# account['juju']]) |
3931 |
|
# table.align = 'l' |
3932 |
|
# print(table) |
3933 |
|
|
3934 |
|
|
3935 |
|
#@cli_osm.command(name='config-agent-delete') |
3936 |
|
#@click.argument('name') |
3937 |
|
#@click.pass_context |
3938 |
|
#def config_agent_delete(ctx, name): |
3939 |
|
# """deletes a config agent |
3940 |
|
# |
3941 |
|
# NAME: name of the config agent to be deleted |
3942 |
|
# """ |
3943 |
|
# try: |
3944 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
3945 |
|
# ctx.obj.vca.delete(name) |
3946 |
|
# except ClientException as e: |
3947 |
|
# print(str(e)) |
3948 |
|
# exit(1) |
3949 |
|
|
3950 |
|
|
3951 |
|
#@cli_osm.command(name='config-agent-add') |
3952 |
|
#@click.option('--name', |
3953 |
|
# prompt=True) |
3954 |
|
#@click.option('--account_type', |
3955 |
|
# prompt=True) |
3956 |
|
#@click.option('--server', |
3957 |
|
# prompt=True) |
3958 |
|
#@click.option('--user', |
3959 |
|
# prompt=True) |
3960 |
|
#@click.option('--secret', |
3961 |
|
# prompt=True, |
3962 |
|
# hide_input=True, |
3963 |
|
# confirmation_prompt=True) |
3964 |
|
#@click.pass_context |
3965 |
|
#def config_agent_add(ctx, name, account_type, server, user, secret): |
3966 |
|
# """adds a config agent""" |
3967 |
|
# try: |
3968 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
3969 |
|
# ctx.obj.vca.create(name, account_type, server, user, secret) |
3970 |
|
# except ClientException as e: |
3971 |
|
# print(str(e)) |
3972 |
|
# exit(1) |
3973 |
|
|
3974 |
|
|
3975 |
|
#@cli_osm.command(name='ro-dump') |
3976 |
|
#@click.pass_context |
3977 |
|
#def ro_dump(ctx): |
3978 |
|
# """shows RO agent information""" |
3979 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
3980 |
|
# resp = ctx.obj.vim.get_resource_orchestrator() |
3981 |
|
# table = PrettyTable(['key', 'attribute']) |
3982 |
|
# for k, v in list(resp.items()): |
3983 |
|
# table.add_row([k, json.dumps(v, indent=2)]) |
3984 |
|
# table.align = 'l' |
3985 |
|
# print(table) |
3986 |
|
|
3987 |
|
|
3988 |
|
#@cli_osm.command(name='vcs-list') |
3989 |
|
#@click.pass_context |
3990 |
|
#def vcs_list(ctx): |
3991 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
3992 |
|
# resp = ctx.obj.utils.get_vcs_info() |
3993 |
|
# table = PrettyTable(['component name', 'state']) |
3994 |
|
# for component in resp: |
3995 |
|
# table.add_row([component['component_name'], component['state']]) |
3996 |
|
# table.align = 'l' |
3997 |
|
# print(table) |
3998 |
|
|
3999 |
|
|
4000 |
0 |
@cli_osm.command(name='ns-action', short_help='executes an action/primitive over a NS instance') |
4001 |
0 |
@click.argument('ns_name') |
4002 |
0 |
@click.option('--vnf_name', default=None, help='member-vnf-index if the target is a vnf instead of a ns)') |
4003 |
0 |
@click.option('--kdu_name', default=None, help='kdu-name if the target is a kdu)') |
4004 |
0 |
@click.option('--vdu_id', default=None, help='vdu-id if the target is a vdu') |
4005 |
0 |
@click.option('--vdu_count', default=None, type=int, help='number of vdu instance of this vdu_id') |
4006 |
0 |
@click.option('--action_name', prompt=True, help='action name') |
4007 |
0 |
@click.option('--params', default=None, help='action params in YAML/JSON inline string') |
4008 |
0 |
@click.option('--params_file', default=None, help='YAML/JSON file with action params') |
4009 |
0 |
@click.option('--timeout', required=False, default=None, type=int, help='timeout in seconds') |
4010 |
0 |
@click.option('--wait', |
4011 |
|
required=False, |
4012 |
|
default=False, |
4013 |
|
is_flag=True, |
4014 |
|
help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
4015 |
0 |
@click.pass_context |
4016 |
|
def ns_action(ctx, |
4017 |
|
ns_name, |
4018 |
|
vnf_name, |
4019 |
|
kdu_name, |
4020 |
|
vdu_id, |
4021 |
|
vdu_count, |
4022 |
|
action_name, |
4023 |
|
params, |
4024 |
|
params_file, |
4025 |
|
timeout, |
4026 |
|
wait): |
4027 |
|
"""executes an action/primitive over a NS instance |
4028 |
|
|
4029 |
|
NS_NAME: name or ID of the NS instance |
4030 |
|
""" |
4031 |
0 |
logger.debug("") |
4032 |
|
# try: |
4033 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4034 |
0 |
op_data = {} |
4035 |
0 |
if vnf_name: |
4036 |
0 |
op_data['member_vnf_index'] = vnf_name |
4037 |
0 |
if kdu_name: |
4038 |
0 |
op_data['kdu_name'] = kdu_name |
4039 |
0 |
if vdu_id: |
4040 |
0 |
op_data['vdu_id'] = vdu_id |
4041 |
0 |
if vdu_count is not None: |
4042 |
0 |
op_data['vdu_count_index'] = vdu_count |
4043 |
0 |
if timeout: |
4044 |
0 |
op_data['timeout_ns_action'] = timeout |
4045 |
0 |
op_data['primitive'] = action_name |
4046 |
0 |
if params_file: |
4047 |
0 |
with open(params_file, 'r') as pf: |
4048 |
0 |
params = pf.read() |
4049 |
0 |
if params: |
4050 |
0 |
op_data['primitive_params'] = yaml.safe_load(params) |
4051 |
|
else: |
4052 |
0 |
op_data['primitive_params'] = {} |
4053 |
0 |
print(ctx.obj.ns.exec_op(ns_name, op_name='action', op_data=op_data, wait=wait)) |
4054 |
|
|
4055 |
|
# except ClientException as e: |
4056 |
|
# print(str(e)) |
4057 |
|
# exit(1) |
4058 |
|
|
4059 |
|
|
4060 |
0 |
@cli_osm.command(name='vnf-scale', short_help='executes a VNF scale (adding/removing VDUs)') |
4061 |
0 |
@click.argument('ns_name') |
4062 |
0 |
@click.argument('vnf_name') |
4063 |
0 |
@click.option('--scaling-group', prompt=True, help="scaling-group-descriptor name to use") |
4064 |
0 |
@click.option('--scale-in', default=False, is_flag=True, help="performs a scale in operation") |
4065 |
0 |
@click.option('--scale-out', default=False, is_flag=True, help="performs a scale out operation (by default)") |
4066 |
0 |
@click.option('--timeout', required=False, default=None, type=int, help='timeout in seconds') |
4067 |
0 |
@click.option('--wait', required=False, default=False, is_flag=True, |
4068 |
|
help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
4069 |
0 |
@click.pass_context |
4070 |
|
def vnf_scale(ctx, |
4071 |
|
ns_name, |
4072 |
|
vnf_name, |
4073 |
|
scaling_group, |
4074 |
|
scale_in, |
4075 |
|
scale_out, |
4076 |
|
timeout, |
4077 |
|
wait): |
4078 |
|
""" |
4079 |
|
Executes a VNF scale (adding/removing VDUs) |
4080 |
|
|
4081 |
|
\b |
4082 |
|
NS_NAME: name or ID of the NS instance. |
4083 |
|
VNF_NAME: member-vnf-index in the NS to be scaled. |
4084 |
|
""" |
4085 |
0 |
logger.debug("") |
4086 |
|
# try: |
4087 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4088 |
0 |
if not scale_in and not scale_out: |
4089 |
0 |
scale_out = True |
4090 |
0 |
ctx.obj.ns.scale_vnf(ns_name, vnf_name, scaling_group, scale_in, scale_out, wait, timeout) |
4091 |
|
# except ClientException as e: |
4092 |
|
# print(str(e)) |
4093 |
|
# exit(1) |
4094 |
|
|
4095 |
|
|
4096 |
|
############################## |
4097 |
|
# Role Management Operations # |
4098 |
|
############################## |
4099 |
|
|
4100 |
0 |
@cli_osm.command(name='role-create', short_help='creates a new role') |
4101 |
0 |
@click.argument('name') |
4102 |
0 |
@click.option('--permissions', |
4103 |
|
default=None, |
4104 |
|
help='role permissions using a dictionary') |
4105 |
0 |
@click.pass_context |
4106 |
|
def role_create(ctx, name, permissions): |
4107 |
|
""" |
4108 |
|
Creates a new role. |
4109 |
|
|
4110 |
|
\b |
4111 |
|
NAME: Name or ID of the role. |
4112 |
|
DEFINITION: Definition of grant/denial of access to resources. |
4113 |
|
""" |
4114 |
0 |
logger.debug("") |
4115 |
|
# try: |
4116 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4117 |
0 |
ctx.obj.role.create(name, permissions) |
4118 |
|
# except ClientException as e: |
4119 |
|
# print(str(e)) |
4120 |
|
# exit(1) |
4121 |
|
|
4122 |
|
|
4123 |
0 |
@cli_osm.command(name='role-update', short_help='updates a role') |
4124 |
0 |
@click.argument('name') |
4125 |
0 |
@click.option('--set-name', |
4126 |
|
default=None, |
4127 |
|
help='change name of rle') |
4128 |
|
# @click.option('--permissions', |
4129 |
|
# default=None, |
4130 |
|
# help='provide a yaml format dictionary with incremental changes. Values can be bool or None to delete') |
4131 |
0 |
@click.option('--add', |
4132 |
|
default=None, |
4133 |
|
help='yaml format dictionary with permission: True/False to access grant/denial') |
4134 |
0 |
@click.option('--remove', |
4135 |
|
default=None, |
4136 |
|
help='yaml format list to remove a permission') |
4137 |
0 |
@click.pass_context |
4138 |
|
def role_update(ctx, name, set_name, add, remove): |
4139 |
|
""" |
4140 |
|
Updates a role. |
4141 |
|
|
4142 |
|
\b |
4143 |
|
NAME: Name or ID of the role. |
4144 |
|
DEFINITION: Definition overwrites the old definition. |
4145 |
|
ADD: Grant/denial of access to resource to add. |
4146 |
|
REMOVE: Grant/denial of access to resource to remove. |
4147 |
|
""" |
4148 |
0 |
logger.debug("") |
4149 |
|
# try: |
4150 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4151 |
0 |
ctx.obj.role.update(name, set_name, None, add, remove) |
4152 |
|
# except ClientException as e: |
4153 |
|
# print(str(e)) |
4154 |
|
# exit(1) |
4155 |
|
|
4156 |
|
|
4157 |
0 |
@cli_osm.command(name='role-delete', short_help='deletes a role') |
4158 |
0 |
@click.argument('name') |
4159 |
|
# @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
4160 |
0 |
@click.pass_context |
4161 |
|
def role_delete(ctx, name): |
4162 |
|
""" |
4163 |
|
Deletes a role. |
4164 |
|
|
4165 |
|
\b |
4166 |
|
NAME: Name or ID of the role. |
4167 |
|
""" |
4168 |
0 |
logger.debug("") |
4169 |
|
# try: |
4170 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4171 |
0 |
ctx.obj.role.delete(name) |
4172 |
|
# except ClientException as e: |
4173 |
|
# print(str(e)) |
4174 |
|
# exit(1) |
4175 |
|
|
4176 |
|
|
4177 |
0 |
@cli_osm.command(name='role-list', short_help='list all roles') |
4178 |
0 |
@click.option('--filter', default=None, multiple=True, |
4179 |
|
help='restricts the list to the projects matching the filter') |
4180 |
0 |
@click.pass_context |
4181 |
|
def role_list(ctx, filter): |
4182 |
|
""" |
4183 |
|
List all roles. |
4184 |
|
""" |
4185 |
0 |
logger.debug("") |
4186 |
|
# try: |
4187 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4188 |
0 |
if filter: |
4189 |
0 |
filter='&'.join(filter) |
4190 |
0 |
resp = ctx.obj.role.list(filter) |
4191 |
|
# except ClientException as e: |
4192 |
|
# print(str(e)) |
4193 |
|
# exit(1) |
4194 |
0 |
table = PrettyTable(['name', 'id']) |
4195 |
0 |
for role in resp: |
4196 |
0 |
table.add_row([role['name'], role['_id']]) |
4197 |
0 |
table.align = 'l' |
4198 |
0 |
print(table) |
4199 |
|
|
4200 |
|
|
4201 |
0 |
@cli_osm.command(name='role-show', short_help='show specific role') |
4202 |
0 |
@click.argument('name') |
4203 |
0 |
@click.pass_context |
4204 |
|
def role_show(ctx, name): |
4205 |
|
""" |
4206 |
|
Shows the details of a role. |
4207 |
|
|
4208 |
|
\b |
4209 |
|
NAME: Name or ID of the role. |
4210 |
|
""" |
4211 |
0 |
logger.debug("") |
4212 |
|
# try: |
4213 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4214 |
0 |
resp = ctx.obj.role.get(name) |
4215 |
|
# except ClientException as e: |
4216 |
|
# print(str(e)) |
4217 |
|
# exit(1) |
4218 |
|
|
4219 |
0 |
table = PrettyTable(['key', 'attribute']) |
4220 |
0 |
for k, v in resp.items(): |
4221 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
4222 |
0 |
table.align = 'l' |
4223 |
0 |
print(table) |
4224 |
|
|
4225 |
|
|
4226 |
0 |
@cli_osm.command(name='package-create', |
4227 |
|
short_help='Create empty NS package structure') |
4228 |
0 |
@click.argument('package-type') |
4229 |
0 |
@click.argument('package-name') |
4230 |
0 |
@click.option('--base-directory', |
4231 |
|
default='.', |
4232 |
|
help=('(NS/VNF/NST) Set the location for package creation. Default: "."')) |
4233 |
0 |
@click.option('--image', |
4234 |
|
default="image-name", |
4235 |
|
help='(VNF) Set the name of the vdu image. Default "image-name"') |
4236 |
0 |
@click.option('--vdus', |
4237 |
|
default=1, |
4238 |
|
help='(VNF) Set the number of vdus in a VNF. Default 1') |
4239 |
0 |
@click.option('--vcpu', |
4240 |
|
default=1, |
4241 |
|
help='(VNF) Set the number of virtual CPUs in a vdu. Default 1') |
4242 |
0 |
@click.option('--memory', |
4243 |
|
default=1024, |
4244 |
|
help='(VNF) Set the memory size (MB) of the vdu. Default 1024') |
4245 |
0 |
@click.option('--storage', |
4246 |
|
default=10, |
4247 |
|
help='(VNF) Set the disk size (GB) of the vdu. Default 10') |
4248 |
0 |
@click.option('--interfaces', |
4249 |
|
default=0, |
4250 |
|
help='(VNF) Set the number of additional interfaces apart from the management interface. Default 0') |
4251 |
0 |
@click.option('--vendor', |
4252 |
|
default="OSM", |
4253 |
|
help='(NS/VNF) Set the descriptor vendor. Default "OSM"') |
4254 |
0 |
@click.option('--override', |
4255 |
|
default=False, |
4256 |
|
is_flag=True, |
4257 |
|
help='(NS/VNF/NST) Flag for overriding the package if exists.') |
4258 |
0 |
@click.option('--detailed', |
4259 |
|
is_flag=True, |
4260 |
|
default=False, |
4261 |
|
help='(NS/VNF/NST) Flag for generating descriptor .yaml with all possible commented options') |
4262 |
0 |
@click.option('--netslice-subnets', |
4263 |
|
default=1, |
4264 |
|
help='(NST) Number of netslice subnets. Default 1') |
4265 |
0 |
@click.option('--netslice-vlds', |
4266 |
|
default=1, |
4267 |
|
help='(NST) Number of netslice vlds. Default 1') |
4268 |
0 |
@click.option( |
4269 |
|
"--old", default=False, is_flag=True, help="Support flag for old versions of the OSM IM (OSM<9)" |
4270 |
|
) |
4271 |
0 |
@click.pass_context |
4272 |
|
def package_create(ctx, |
4273 |
|
package_type, |
4274 |
|
base_directory, |
4275 |
|
package_name, |
4276 |
|
override, |
4277 |
|
image, |
4278 |
|
vdus, |
4279 |
|
vcpu, |
4280 |
|
memory, |
4281 |
|
storage, |
4282 |
|
interfaces, |
4283 |
|
vendor, |
4284 |
|
detailed, |
4285 |
|
netslice_subnets, |
4286 |
|
netslice_vlds, |
4287 |
|
old,): |
4288 |
|
""" |
4289 |
|
Creates an OSM NS, VNF, NST package |
4290 |
|
|
4291 |
|
\b |
4292 |
|
PACKAGE_TYPE: Package to be created: NS, VNF or NST. |
4293 |
|
PACKAGE_NAME: Name of the package to create the folder with the content. |
4294 |
|
""" |
4295 |
|
|
4296 |
|
# try: |
4297 |
0 |
logger.debug("") |
4298 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4299 |
0 |
print("Creating the {} structure: {}/{}".format(package_type.upper(), base_directory, package_name)) |
4300 |
0 |
resp = ctx.obj.package_tool.create(package_type, |
4301 |
|
base_directory, |
4302 |
|
package_name, |
4303 |
|
override=override, |
4304 |
|
image=image, |
4305 |
|
vdus=vdus, |
4306 |
|
vcpu=vcpu, |
4307 |
|
memory=memory, |
4308 |
|
storage=storage, |
4309 |
|
interfaces=interfaces, |
4310 |
|
vendor=vendor, |
4311 |
|
detailed=detailed, |
4312 |
|
netslice_subnets=netslice_subnets, |
4313 |
|
netslice_vlds=netslice_vlds, |
4314 |
|
old=old,) |
4315 |
0 |
print(resp) |
4316 |
|
# except ClientException as inst: |
4317 |
|
# print("ERROR: {}".format(inst)) |
4318 |
|
# exit(1) |
4319 |
|
|
4320 |
0 |
@cli_osm.command(name='package-validate', |
4321 |
|
short_help='Validate descriptors given a base directory') |
4322 |
0 |
@click.argument('base-directory', |
4323 |
|
default=".", |
4324 |
|
required=False) |
4325 |
0 |
@click.option('--recursive/--no-recursive', |
4326 |
|
default=True, |
4327 |
|
help='The activated recursive option will validate the yaml files' |
4328 |
|
' within the indicated directory and in its subdirectories') |
4329 |
0 |
@click.option('--old', |
4330 |
|
is_flag=True, |
4331 |
|
default=False, |
4332 |
|
help='Validates also the descriptors using the previous OSM format (pre SOL006)') |
4333 |
0 |
@click.pass_context |
4334 |
|
def package_validate(ctx, |
4335 |
|
base_directory, |
4336 |
|
recursive, |
4337 |
|
old): |
4338 |
|
""" |
4339 |
|
Validate descriptors given a base directory. |
4340 |
|
|
4341 |
|
\b |
4342 |
|
BASE_DIRECTORY: Base folder for NS, VNF or NST package. |
4343 |
|
""" |
4344 |
|
# try: |
4345 |
0 |
logger.debug("") |
4346 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4347 |
0 |
results = ctx.obj.package_tool.validate(base_directory, recursive, old) |
4348 |
0 |
table = PrettyTable() |
4349 |
0 |
table.field_names = ["TYPE", "PATH", "VALID", "ERROR"] |
4350 |
|
# Print the dictionary generated by the validation function |
4351 |
0 |
for result in results: |
4352 |
0 |
table.add_row([result["type"], result["path"], result["valid"], result["error"]]) |
4353 |
0 |
table.sortby = "VALID" |
4354 |
0 |
table.align["PATH"] = "l" |
4355 |
0 |
table.align["TYPE"] = "l" |
4356 |
0 |
table.align["ERROR"] = "l" |
4357 |
0 |
print(table) |
4358 |
|
# except ClientException as inst: |
4359 |
|
# print("ERROR: {}".format(inst)) |
4360 |
|
# exit(1) |
4361 |
|
|
4362 |
0 |
@cli_osm.command(name='package-translate', |
4363 |
|
short_help='Translate descriptors given a base directory') |
4364 |
0 |
@click.argument('base-directory', |
4365 |
|
default=".", |
4366 |
|
required=False) |
4367 |
0 |
@click.option('--recursive/--no-recursive', |
4368 |
|
default=True, |
4369 |
|
help='The activated recursive option will translate the yaml files' |
4370 |
|
' within the indicated directory and in its subdirectories') |
4371 |
0 |
@click.option('--dryrun', |
4372 |
|
is_flag=True, |
4373 |
|
default=False, |
4374 |
|
help='Do not translate yet, only make a dry-run to test translation') |
4375 |
0 |
@click.pass_context |
4376 |
|
def package_translate(ctx, |
4377 |
|
base_directory, |
4378 |
|
recursive, |
4379 |
|
dryrun): |
4380 |
|
""" |
4381 |
|
Translate descriptors given a base directory. |
4382 |
|
|
4383 |
|
\b |
4384 |
|
BASE_DIRECTORY: Stub folder for NS, VNF or NST package. |
4385 |
|
""" |
4386 |
0 |
logger.debug("") |
4387 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4388 |
0 |
results = ctx.obj.package_tool.translate(base_directory, recursive, dryrun) |
4389 |
0 |
table = PrettyTable() |
4390 |
0 |
table.field_names = ["CURRENT TYPE", "NEW TYPE", "PATH", "VALID", "TRANSLATED", "ERROR"] |
4391 |
|
# Print the dictionary generated by the validation function |
4392 |
0 |
for result in results: |
4393 |
0 |
table.add_row([result["current type"], result["new type"], result["path"], result["valid"], result["translated"], result["error"]]) |
4394 |
0 |
table.sortby = "TRANSLATED" |
4395 |
0 |
table.align["PATH"] = "l" |
4396 |
0 |
table.align["TYPE"] = "l" |
4397 |
0 |
table.align["ERROR"] = "l" |
4398 |
0 |
print(table) |
4399 |
|
# except ClientException as inst: |
4400 |
|
# print("ERROR: {}".format(inst)) |
4401 |
|
# exit(1) |
4402 |
|
|
4403 |
0 |
@cli_osm.command(name='package-build', |
4404 |
|
short_help='Build the tar.gz of the package') |
4405 |
0 |
@click.argument('package-folder') |
4406 |
0 |
@click.option('--skip-validation', |
4407 |
|
default=False, |
4408 |
|
is_flag=True, |
4409 |
|
help='skip package validation') |
4410 |
0 |
@click.option('--skip-charm-build', default=False, is_flag=True, |
4411 |
|
help='the charm will not be compiled, it is assumed to already exist') |
4412 |
0 |
@click.pass_context |
4413 |
|
def package_build(ctx, |
4414 |
|
package_folder, |
4415 |
|
skip_validation, |
4416 |
|
skip_charm_build): |
4417 |
|
""" |
4418 |
|
Build the package NS, VNF given the package_folder. |
4419 |
|
|
4420 |
|
\b |
4421 |
|
PACKAGE_FOLDER: Folder of the NS, VNF or NST to be packaged |
4422 |
|
""" |
4423 |
|
# try: |
4424 |
0 |
logger.debug("") |
4425 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4426 |
0 |
results = ctx.obj.package_tool.build(package_folder, |
4427 |
|
skip_validation=skip_validation, |
4428 |
|
skip_charm_build=skip_charm_build) |
4429 |
0 |
print(results) |
4430 |
|
# except ClientException as inst: |
4431 |
|
# print("ERROR: {}".format(inst)) |
4432 |
|
# exit(1) |
4433 |
|
|
4434 |
0 |
@cli_osm.command(name='descriptor-translate', |
4435 |
|
short_help='Translate input descriptor file from Rel EIGHT OSM descriptors to SOL006 and prints in standard output') |
4436 |
0 |
@click.argument('descriptor-file', |
4437 |
|
required=True) |
4438 |
0 |
@click.pass_context |
4439 |
|
def descriptor_translate(ctx, |
4440 |
|
descriptor_file): |
4441 |
|
""" |
4442 |
|
Translate input descriptor. |
4443 |
|
|
4444 |
|
\b |
4445 |
|
DESCRIPTOR_FILE: Descriptor file for NS, VNF or Network Slice. |
4446 |
|
""" |
4447 |
0 |
logger.debug("") |
4448 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4449 |
0 |
result = ctx.obj.package_tool.descriptor_translate(descriptor_file) |
4450 |
0 |
print(result) |
4451 |
|
|
4452 |
|
|
4453 |
0 |
def cli(): |
4454 |
0 |
try: |
4455 |
0 |
cli_osm() |
4456 |
0 |
exit(0) |
4457 |
0 |
except pycurl.error as exc: |
4458 |
0 |
print(exc) |
4459 |
0 |
print('Maybe "--hostname" option or OSM_HOSTNAME environment variable needs to be specified') |
4460 |
0 |
except ClientException as exc: |
4461 |
0 |
print("ERROR: {}".format(exc)) |
4462 |
0 |
except (FileNotFoundError, PermissionError) as exc: |
4463 |
0 |
print("Cannot open file: {}".format(exc)) |
4464 |
0 |
except yaml.YAMLError as exc: |
4465 |
0 |
print("Invalid YAML format: {}".format(exc)) |
4466 |
0 |
exit(1) |
4467 |
|
# TODO capture other controlled exceptions here |
4468 |
|
# TODO remove the ClientException captures from all places, unless they do something different |
4469 |
|
|
4470 |
|
|
4471 |
0 |
if __name__ == '__main__': |
4472 |
0 |
cli() |
4473 |
|
|