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 |
1 |
""" |
18 |
|
OSM shell/cli |
19 |
|
""" |
20 |
|
|
21 |
1 |
import click |
22 |
1 |
from osmclient import client |
23 |
1 |
from osmclient.common.exceptions import ClientException, NotFound |
24 |
1 |
from prettytable import PrettyTable |
25 |
1 |
import yaml |
26 |
1 |
import json |
27 |
1 |
import time |
28 |
1 |
import pycurl |
29 |
1 |
import os |
30 |
1 |
import textwrap |
31 |
1 |
import pkg_resources |
32 |
1 |
import logging |
33 |
1 |
from datetime import datetime |
34 |
1 |
from typing import Any, Dict |
35 |
|
|
36 |
|
|
37 |
1 |
def wrap_text(text, width): |
38 |
1 |
wrapper = textwrap.TextWrapper(width=width) |
39 |
1 |
lines = text.splitlines() |
40 |
1 |
return "\n".join(map(wrapper.fill, lines)) |
41 |
|
|
42 |
|
|
43 |
1 |
def trunc_text(text, length): |
44 |
0 |
if len(text) > length: |
45 |
0 |
return text[: (length - 3)] + "..." |
46 |
|
else: |
47 |
0 |
return text |
48 |
|
|
49 |
|
|
50 |
1 |
def check_client_version(obj, what, version="sol005"): |
51 |
|
""" |
52 |
|
Checks the version of the client object and raises error if it not the expected. |
53 |
|
|
54 |
|
:param obj: the client object |
55 |
|
:what: the function or command under evaluation (used when an error is raised) |
56 |
|
:return: - |
57 |
|
:raises ClientError: if the specified version does not match the client version |
58 |
|
""" |
59 |
0 |
logger.debug("") |
60 |
0 |
fullclassname = obj.__module__ + "." + obj.__class__.__name__ |
61 |
0 |
message = 'The following commands or options are only supported with the option "--sol005": {}'.format( |
62 |
|
what |
63 |
|
) |
64 |
0 |
if version == "v1": |
65 |
0 |
message = 'The following commands or options are not supported when using option "--sol005": {}'.format( |
66 |
|
what |
67 |
|
) |
68 |
0 |
if fullclassname != "osmclient.{}.client.Client".format(version): |
69 |
0 |
raise ClientException(message) |
70 |
0 |
return |
71 |
|
|
72 |
|
|
73 |
1 |
def get_project(project_list, item): |
74 |
|
# project_list = ctx.obj.project.list() |
75 |
0 |
item_project_list = item.get("_admin", {}).get("projects_read") |
76 |
0 |
project_id = "None" |
77 |
0 |
project_name = "None" |
78 |
0 |
if item_project_list: |
79 |
0 |
for p1 in item_project_list: |
80 |
0 |
project_id = p1 |
81 |
0 |
for p2 in project_list: |
82 |
0 |
if p2["_id"] == project_id: |
83 |
0 |
project_name = p2["name"] |
84 |
0 |
return project_id, project_name |
85 |
0 |
return project_id, project_name |
86 |
|
|
87 |
|
|
88 |
1 |
def get_vim_name(vim_list, vim_id): |
89 |
0 |
vim_name = "-" |
90 |
0 |
for v in vim_list: |
91 |
0 |
if v["uuid"] == vim_id: |
92 |
0 |
vim_name = v["name"] |
93 |
0 |
break |
94 |
0 |
return vim_name |
95 |
|
|
96 |
|
|
97 |
1 |
def create_config(config_file, json_string): |
98 |
|
''' |
99 |
|
Combines a YAML or JSON file with a JSON string into a Python3 structure |
100 |
|
It loads the YAML or JSON file 'cfile' into a first dictionary. |
101 |
|
It loads the JSON string into a second dictionary. |
102 |
|
Then it updates the first dictionary with the info in the second dictionary. |
103 |
|
If the field is present in both cfile and cdict, the field in cdict prevails. |
104 |
|
If both cfile and cdict are None, it returns an empty dict (i.e. {}) |
105 |
|
''' |
106 |
0 |
config = {} |
107 |
0 |
if config_file: |
108 |
0 |
with open(config_file, "r") as cf: |
109 |
0 |
config = yaml.safe_load(cf.read()) |
110 |
0 |
if json_string: |
111 |
0 |
cdict = yaml.safe_load(json_string) |
112 |
0 |
for k, v in cdict.items(): |
113 |
0 |
config[k] = v |
114 |
0 |
return config |
115 |
|
|
116 |
|
|
117 |
1 |
@click.group( |
118 |
|
context_settings=dict(help_option_names=["-h", "--help"], max_content_width=160) |
119 |
|
) |
120 |
1 |
@click.option( |
121 |
|
"--hostname", |
122 |
|
default="127.0.0.1", |
123 |
|
envvar="OSM_HOSTNAME", |
124 |
|
help="hostname of server. " + "Also can set OSM_HOSTNAME in environment", |
125 |
|
) |
126 |
|
# @click.option('--sol005/--no-sol005', |
127 |
|
# default=True, |
128 |
|
# envvar='OSM_SOL005', |
129 |
|
# help='Use ETSI NFV SOL005 API (default) or the previous SO API. ' + |
130 |
|
# 'Also can set OSM_SOL005 in environment') |
131 |
1 |
@click.option( |
132 |
|
"--user", |
133 |
|
default=None, |
134 |
|
envvar="OSM_USER", |
135 |
|
help="user (defaults to admin). " + "Also can set OSM_USER in environment", |
136 |
|
) |
137 |
1 |
@click.option( |
138 |
|
"--password", |
139 |
|
default=None, |
140 |
|
envvar="OSM_PASSWORD", |
141 |
|
help="password (defaults to admin). " + "Also can set OSM_PASSWORD in environment", |
142 |
|
) |
143 |
1 |
@click.option( |
144 |
|
"--project", |
145 |
|
default=None, |
146 |
|
envvar="OSM_PROJECT", |
147 |
|
help="project (defaults to admin). " + "Also can set OSM_PROJECT in environment", |
148 |
|
) |
149 |
1 |
@click.option( |
150 |
|
"-v", |
151 |
|
"--verbose", |
152 |
|
count=True, |
153 |
|
help="increase verbosity (-v INFO, -vv VERBOSE, -vvv DEBUG)", |
154 |
|
) |
155 |
1 |
@click.option("--all-projects", default=None, is_flag=True, help="include all projects") |
156 |
1 |
@click.option( |
157 |
|
"--public/--no-public", |
158 |
|
default=None, |
159 |
|
help="flag for public items (packages, instances, VIM accounts, etc.)", |
160 |
|
) |
161 |
1 |
@click.option( |
162 |
|
"--project-domain-name", |
163 |
|
"project_domain_name", |
164 |
|
default=None, |
165 |
|
envvar="OSM_PROJECT_DOMAIN_NAME", |
166 |
|
help="project domain name for keystone authentication (default to None). " |
167 |
|
+ "Also can set OSM_PROJECT_DOMAIN_NAME in environment", |
168 |
|
) |
169 |
1 |
@click.option( |
170 |
|
"--user-domain-name", |
171 |
|
"user_domain_name", |
172 |
|
default=None, |
173 |
|
envvar="OSM_USER_DOMAIN_NAME", |
174 |
|
help="user domain name for keystone authentication (default to None). " |
175 |
|
+ "Also can set OSM_USER_DOMAIN_NAME in environment", |
176 |
|
) |
177 |
|
# @click.option('--so-port', |
178 |
|
# default=None, |
179 |
|
# envvar='OSM_SO_PORT', |
180 |
|
# help='hostname of server. ' + |
181 |
|
# 'Also can set OSM_SO_PORT in environment') |
182 |
|
# @click.option('--so-project', |
183 |
|
# default=None, |
184 |
|
# envvar='OSM_SO_PROJECT', |
185 |
|
# help='Project Name in SO. ' + |
186 |
|
# 'Also can set OSM_SO_PROJECT in environment') |
187 |
|
# @click.option('--ro-hostname', |
188 |
|
# default=None, |
189 |
|
# envvar='OSM_RO_HOSTNAME', |
190 |
|
# help='hostname of RO server. ' + |
191 |
|
# 'Also can set OSM_RO_HOSTNAME in environment') |
192 |
|
# @click.option('--ro-port', |
193 |
|
# default=None, |
194 |
|
# envvar='OSM_RO_PORT', |
195 |
|
# help='hostname of RO server. ' + |
196 |
|
# 'Also can set OSM_RO_PORT in environment') |
197 |
1 |
@click.pass_context |
198 |
1 |
def cli_osm(ctx, **kwargs): |
199 |
|
global logger |
200 |
1 |
hostname = kwargs.pop("hostname", None) |
201 |
1 |
if hostname is None: |
202 |
0 |
print( |
203 |
|
( |
204 |
|
"either hostname option or OSM_HOSTNAME " |
205 |
|
+ "environment variable needs to be specified" |
206 |
|
) |
207 |
|
) |
208 |
0 |
exit(1) |
209 |
|
# Remove None values |
210 |
1 |
kwargs = {k: v for k, v in kwargs.items() if v is not None} |
211 |
|
# if so_port is not None: |
212 |
|
# kwargs['so_port']=so_port |
213 |
|
# if so_project is not None: |
214 |
|
# kwargs['so_project']=so_project |
215 |
|
# if ro_hostname is not None: |
216 |
|
# kwargs['ro_host']=ro_hostname |
217 |
|
# if ro_port is not None: |
218 |
|
# kwargs['ro_port']=ro_port |
219 |
1 |
sol005 = os.getenv("OSM_SOL005", True) |
220 |
|
# if user is not None: |
221 |
|
# kwargs['user']=user |
222 |
|
# if password is not None: |
223 |
|
# kwargs['password']=password |
224 |
|
# if project is not None: |
225 |
|
# kwargs['project']=project |
226 |
|
# if all_projects: |
227 |
|
# kwargs['all_projects']=all_projects |
228 |
|
# if public is not None: |
229 |
|
# kwargs['public']=public |
230 |
1 |
ctx.obj = client.Client(host=hostname, sol005=sol005, **kwargs) |
231 |
1 |
logger = logging.getLogger("osmclient") |
232 |
|
|
233 |
|
|
234 |
|
#################### |
235 |
|
# LIST operations |
236 |
|
#################### |
237 |
|
|
238 |
|
|
239 |
1 |
@cli_osm.command(name="ns-list", short_help="list all NS instances") |
240 |
1 |
@click.option( |
241 |
|
"--filter", |
242 |
|
default=None, |
243 |
|
multiple=True, |
244 |
|
help="restricts the list to the NS instances matching the filter.", |
245 |
|
) |
246 |
1 |
@click.option( |
247 |
|
"--long", |
248 |
|
is_flag=True, |
249 |
|
help="get more details of the NS (project, vim, deployment status, configuration status.", |
250 |
|
) |
251 |
1 |
@click.pass_context |
252 |
1 |
def ns_list(ctx, filter, long): |
253 |
|
"""list all NS instances |
254 |
|
|
255 |
|
\b |
256 |
|
Options: |
257 |
|
--filter filterExpr Restricts the list to the NS instances matching the filter |
258 |
|
|
259 |
|
\b |
260 |
|
filterExpr consists of one or more strings formatted according to "simpleFilterExpr", |
261 |
|
concatenated using the "&" character: |
262 |
|
|
263 |
|
\b |
264 |
|
filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]* |
265 |
|
simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]* |
266 |
|
op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont" |
267 |
|
attrName := string |
268 |
|
value := scalar value |
269 |
|
|
270 |
|
\b |
271 |
|
where: |
272 |
|
* zero or more occurrences |
273 |
|
? zero or one occurrence |
274 |
|
[] grouping of expressions to be used with ? and * |
275 |
|
"" quotation marks for marking string constants |
276 |
|
<> name separator |
277 |
|
|
278 |
|
\b |
279 |
|
"AttrName" is the name of one attribute in the data type that defines the representation |
280 |
|
of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of |
281 |
|
<attrName> entries to filter by attributes deeper in the hierarchy of a structured document. |
282 |
|
"Op" stands for the comparison operator. If the expression has concatenated <attrName> |
283 |
|
entries, it means that the operator "op" is applied to the attribute addressed by the last |
284 |
|
<attrName> entry included in the concatenation. All simple filter expressions are combined |
285 |
|
by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>, |
286 |
|
the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The |
287 |
|
concatenation of all "attrName" entries except the leaf attribute is called the "attribute |
288 |
|
prefix". If an attribute referenced in an expression is an array, an object that contains a |
289 |
|
corresponding array shall be considered to match the expression if any of the elements in the |
290 |
|
array matches all expressions that have the same attribute prefix. |
291 |
|
|
292 |
|
\b |
293 |
|
Filter examples: |
294 |
|
--filter admin-status=ENABLED |
295 |
|
--filter nsd-ref=<NSD_NAME> |
296 |
|
--filter nsd.vendor=<VENDOR> |
297 |
|
--filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME> |
298 |
|
--filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME> |
299 |
|
""" |
300 |
|
|
301 |
0 |
def summarize_deployment_status(status_dict): |
302 |
|
# Nets |
303 |
0 |
summary = "" |
304 |
0 |
if not status_dict: |
305 |
0 |
return summary |
306 |
0 |
n_nets = 0 |
307 |
0 |
status_nets = {} |
308 |
0 |
net_list = status_dict.get("nets", []) |
309 |
0 |
for net in net_list: |
310 |
0 |
n_nets += 1 |
311 |
0 |
if net["status"] not in status_nets: |
312 |
0 |
status_nets[net["status"]] = 1 |
313 |
|
else: |
314 |
0 |
status_nets[net["status"]] += 1 |
315 |
0 |
message = "Nets: " |
316 |
0 |
for k, v in status_nets.items(): |
317 |
0 |
message += "{}:{},".format(k, v) |
318 |
0 |
message += "TOTAL:{}".format(n_nets) |
319 |
0 |
summary += "{}".format(message) |
320 |
|
# VMs and VNFs |
321 |
0 |
n_vms = 0 |
322 |
0 |
status_vms = {} |
323 |
0 |
status_vnfs = {} |
324 |
0 |
vnf_list = status_dict["vnfs"] |
325 |
0 |
for vnf in vnf_list: |
326 |
0 |
member_vnf_index = vnf["member_vnf_index"] |
327 |
0 |
if member_vnf_index not in status_vnfs: |
328 |
0 |
status_vnfs[member_vnf_index] = {} |
329 |
0 |
for vm in vnf["vms"]: |
330 |
0 |
n_vms += 1 |
331 |
0 |
if vm["status"] not in status_vms: |
332 |
0 |
status_vms[vm["status"]] = 1 |
333 |
|
else: |
334 |
0 |
status_vms[vm["status"]] += 1 |
335 |
0 |
if vm["status"] not in status_vnfs[member_vnf_index]: |
336 |
0 |
status_vnfs[member_vnf_index][vm["status"]] = 1 |
337 |
|
else: |
338 |
0 |
status_vnfs[member_vnf_index][vm["status"]] += 1 |
339 |
0 |
message = "VMs: " |
340 |
0 |
for k, v in status_vms.items(): |
341 |
0 |
message += "{}:{},".format(k, v) |
342 |
0 |
message += "TOTAL:{}".format(n_vms) |
343 |
0 |
summary += "\n{}".format(message) |
344 |
0 |
summary += "\nNFs:" |
345 |
0 |
for k, v in status_vnfs.items(): |
346 |
0 |
total = 0 |
347 |
0 |
message = "\n {} VMs: ".format(k) |
348 |
0 |
for k2, v2 in v.items(): |
349 |
0 |
message += "{}:{},".format(k2, v2) |
350 |
0 |
total += v2 |
351 |
0 |
message += "TOTAL:{}".format(total) |
352 |
0 |
summary += message |
353 |
0 |
return summary |
354 |
|
|
355 |
0 |
def summarize_config_status(ee_list): |
356 |
0 |
summary = "" |
357 |
0 |
if not ee_list: |
358 |
0 |
return summary |
359 |
0 |
n_ee = 0 |
360 |
0 |
status_ee = {} |
361 |
0 |
for ee in ee_list: |
362 |
0 |
n_ee += 1 |
363 |
0 |
if ee["elementType"] not in status_ee: |
364 |
0 |
status_ee[ee["elementType"]] = {} |
365 |
0 |
status_ee[ee["elementType"]][ee["status"]] = 1 |
366 |
0 |
continue |
367 |
0 |
if ee["status"] in status_ee[ee["elementType"]]: |
368 |
0 |
status_ee[ee["elementType"]][ee["status"]] += 1 |
369 |
|
else: |
370 |
0 |
status_ee[ee["elementType"]][ee["status"]] = 1 |
371 |
0 |
for elementType in ["KDU", "VDU", "PDU", "VNF", "NS"]: |
372 |
0 |
if elementType in status_ee: |
373 |
0 |
message = "" |
374 |
0 |
total = 0 |
375 |
0 |
for k, v in status_ee[elementType].items(): |
376 |
0 |
message += "{}:{},".format(k, v) |
377 |
0 |
total += v |
378 |
0 |
message += "TOTAL:{}\n".format(total) |
379 |
0 |
summary += "{}: {}".format(elementType, message) |
380 |
0 |
summary += "TOTAL Exec. Env.: {}".format(n_ee) |
381 |
0 |
return summary |
382 |
|
|
383 |
0 |
logger.debug("") |
384 |
0 |
if filter: |
385 |
0 |
check_client_version(ctx.obj, "--filter") |
386 |
0 |
filter = "&".join(filter) |
387 |
0 |
resp = ctx.obj.ns.list(filter) |
388 |
|
else: |
389 |
0 |
resp = ctx.obj.ns.list() |
390 |
0 |
if long: |
391 |
0 |
table = PrettyTable( |
392 |
|
[ |
393 |
|
"ns instance name", |
394 |
|
"id", |
395 |
|
"date", |
396 |
|
"ns state", |
397 |
|
"current operation", |
398 |
|
"error details", |
399 |
|
"project", |
400 |
|
"vim (inst param)", |
401 |
|
"deployment status", |
402 |
|
"configuration status", |
403 |
|
] |
404 |
|
) |
405 |
0 |
project_list = ctx.obj.project.list() |
406 |
0 |
try: |
407 |
0 |
vim_list = ctx.obj.vim.list() |
408 |
0 |
except Exception: |
409 |
0 |
vim_list = [] |
410 |
|
else: |
411 |
0 |
table = PrettyTable( |
412 |
|
[ |
413 |
|
"ns instance name", |
414 |
|
"id", |
415 |
|
"date", |
416 |
|
"ns state", |
417 |
|
"current operation", |
418 |
|
"error details", |
419 |
|
] |
420 |
|
) |
421 |
0 |
for ns in resp: |
422 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
423 |
0 |
if fullclassname == "osmclient.sol005.client.Client": |
424 |
0 |
nsr = ns |
425 |
0 |
logger.debug("NS info: {}".format(nsr)) |
426 |
0 |
nsr_name = nsr["name"] |
427 |
0 |
nsr_id = nsr["_id"] |
428 |
0 |
date = datetime.fromtimestamp(nsr["create-time"]).strftime( |
429 |
|
"%Y-%m-%dT%H:%M:%S" |
430 |
|
) |
431 |
0 |
ns_state = nsr.get("nsState", nsr["_admin"]["nsState"]) |
432 |
0 |
if long: |
433 |
0 |
deployment_status = summarize_deployment_status( |
434 |
|
nsr.get("deploymentStatus") |
435 |
|
) |
436 |
0 |
config_status = summarize_config_status(nsr.get("configurationStatus")) |
437 |
0 |
project_id, project_name = get_project(project_list, nsr) |
438 |
|
# project = '{} ({})'.format(project_name, project_id) |
439 |
0 |
project = project_name |
440 |
0 |
vim_id = nsr.get("datacenter") |
441 |
0 |
vim_name = get_vim_name(vim_list, vim_id) |
442 |
|
|
443 |
|
# vim = '{} ({})'.format(vim_name, vim_id) |
444 |
0 |
vim = vim_name |
445 |
0 |
if "currentOperation" in nsr: |
446 |
0 |
current_operation = "{} ({})".format( |
447 |
|
nsr["currentOperation"], nsr["currentOperationID"] |
448 |
|
) |
449 |
|
else: |
450 |
0 |
current_operation = "{} ({})".format( |
451 |
|
nsr["_admin"].get("current-operation", "-"), |
452 |
|
nsr["_admin"]["nslcmop"], |
453 |
|
) |
454 |
0 |
error_details = "N/A" |
455 |
0 |
if ( |
456 |
|
ns_state == "BROKEN" |
457 |
|
or ns_state == "DEGRADED" |
458 |
|
or ("currentOperation" not in nsr and nsr.get("errorDescription")) |
459 |
|
): |
460 |
0 |
error_details = "{}\nDetail: {}".format( |
461 |
|
nsr["errorDescription"], nsr["errorDetail"] |
462 |
|
) |
463 |
|
else: |
464 |
0 |
nsopdata = ctx.obj.ns.get_opdata(ns["id"]) |
465 |
0 |
nsr = nsopdata["nsr:nsr"] |
466 |
0 |
nsr_name = nsr["name-ref"] |
467 |
0 |
nsr_id = nsr["ns-instance-config-ref"] |
468 |
0 |
date = "-" |
469 |
0 |
project = "-" |
470 |
0 |
deployment_status = ( |
471 |
|
nsr["operational-status"] |
472 |
|
if "operational-status" in nsr |
473 |
|
else "Not found" |
474 |
|
) |
475 |
0 |
ns_state = deployment_status |
476 |
0 |
config_status = nsr.get("config-status", "Not found") |
477 |
0 |
current_operation = "Unknown" |
478 |
0 |
error_details = nsr.get("detailed-status", "Not found") |
479 |
0 |
if config_status == "config_not_needed": |
480 |
0 |
config_status = "configured (no charms)" |
481 |
|
|
482 |
0 |
if long: |
483 |
0 |
table.add_row( |
484 |
|
[ |
485 |
|
nsr_name, |
486 |
|
nsr_id, |
487 |
|
date, |
488 |
|
ns_state, |
489 |
|
current_operation, |
490 |
|
wrap_text(text=error_details, width=40), |
491 |
|
project, |
492 |
|
vim, |
493 |
|
deployment_status, |
494 |
|
config_status, |
495 |
|
] |
496 |
|
) |
497 |
|
else: |
498 |
0 |
table.add_row( |
499 |
|
[ |
500 |
|
nsr_name, |
501 |
|
nsr_id, |
502 |
|
date, |
503 |
|
ns_state, |
504 |
|
current_operation, |
505 |
|
wrap_text(text=error_details, width=40), |
506 |
|
] |
507 |
|
) |
508 |
0 |
table.align = "l" |
509 |
0 |
print(table) |
510 |
0 |
print('To get the history of all operations over a NS, run "osm ns-op-list NS_ID"') |
511 |
0 |
print( |
512 |
|
'For more details on the current operation, run "osm ns-op-show OPERATION_ID"' |
513 |
|
) |
514 |
|
|
515 |
|
|
516 |
1 |
def nsd_list(ctx, filter, long): |
517 |
0 |
logger.debug("") |
518 |
0 |
if filter: |
519 |
0 |
check_client_version(ctx.obj, "--filter") |
520 |
0 |
filter = "&".join(filter) |
521 |
0 |
resp = ctx.obj.nsd.list(filter) |
522 |
|
else: |
523 |
0 |
resp = ctx.obj.nsd.list() |
524 |
|
# print(yaml.safe_dump(resp)) |
525 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
526 |
0 |
if fullclassname == "osmclient.sol005.client.Client": |
527 |
0 |
if long: |
528 |
0 |
table = PrettyTable( |
529 |
|
[ |
530 |
|
"nsd name", |
531 |
|
"id", |
532 |
|
"onboarding state", |
533 |
|
"operational state", |
534 |
|
"usage state", |
535 |
|
"date", |
536 |
|
"last update", |
537 |
|
] |
538 |
|
) |
539 |
|
else: |
540 |
0 |
table = PrettyTable(["nsd name", "id"]) |
541 |
0 |
for nsd in resp: |
542 |
0 |
name = nsd.get("id", "-") |
543 |
0 |
if long: |
544 |
0 |
onb_state = nsd["_admin"].get("onboardingState", "-") |
545 |
0 |
op_state = nsd["_admin"].get("operationalState", "-") |
546 |
0 |
usage_state = nsd["_admin"].get("usageState", "-") |
547 |
0 |
date = datetime.fromtimestamp(nsd["_admin"]["created"]).strftime( |
548 |
|
"%Y-%m-%dT%H:%M:%S" |
549 |
|
) |
550 |
0 |
last_update = datetime.fromtimestamp( |
551 |
|
nsd["_admin"]["modified"] |
552 |
|
).strftime("%Y-%m-%dT%H:%M:%S") |
553 |
0 |
table.add_row( |
554 |
|
[ |
555 |
|
name, |
556 |
|
nsd["_id"], |
557 |
|
onb_state, |
558 |
|
op_state, |
559 |
|
usage_state, |
560 |
|
date, |
561 |
|
last_update, |
562 |
|
] |
563 |
|
) |
564 |
|
else: |
565 |
0 |
table.add_row([name, nsd["_id"]]) |
566 |
|
else: |
567 |
0 |
table = PrettyTable(["nsd name", "id"]) |
568 |
0 |
for nsd in resp: |
569 |
0 |
table.add_row([nsd["name"], nsd["id"]]) |
570 |
0 |
table.align = "l" |
571 |
0 |
print(table) |
572 |
|
|
573 |
|
|
574 |
1 |
@cli_osm.command(name="nsd-list", short_help="list all NS packages") |
575 |
1 |
@click.option( |
576 |
|
"--filter", |
577 |
|
default=None, |
578 |
|
multiple=True, |
579 |
|
help="restricts the list to the NSD/NSpkg matching the filter", |
580 |
|
) |
581 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
582 |
1 |
@click.pass_context |
583 |
1 |
def nsd_list1(ctx, filter, long): |
584 |
|
"""list all NSD/NS pkg in the system""" |
585 |
0 |
logger.debug("") |
586 |
0 |
nsd_list(ctx, filter, long) |
587 |
|
|
588 |
|
|
589 |
1 |
@cli_osm.command(name="nspkg-list", short_help="list all NS packages") |
590 |
1 |
@click.option( |
591 |
|
"--filter", |
592 |
|
default=None, |
593 |
|
multiple=True, |
594 |
|
help="restricts the list to the NSD/NSpkg matching the filter", |
595 |
|
) |
596 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
597 |
1 |
@click.pass_context |
598 |
1 |
def nsd_list2(ctx, filter, long): |
599 |
|
"""list all NS packages""" |
600 |
0 |
logger.debug("") |
601 |
0 |
nsd_list(ctx, filter, long) |
602 |
|
|
603 |
|
|
604 |
1 |
def pkg_repo_list(ctx, pkgtype, filter, repo, long): |
605 |
0 |
resp = ctx.obj.osmrepo.pkg_list(pkgtype, filter, repo) |
606 |
0 |
if long: |
607 |
0 |
table = PrettyTable( |
608 |
|
["nfpkg name", "vendor", "version", "latest", "description", "repository"] |
609 |
|
) |
610 |
|
else: |
611 |
0 |
table = PrettyTable(["nfpkg name", "repository"]) |
612 |
0 |
for vnfd in resp: |
613 |
0 |
name = vnfd.get("id", vnfd.get("name", "-")) |
614 |
0 |
repository = vnfd.get("repository") |
615 |
0 |
if long: |
616 |
0 |
vendor = vnfd.get("provider", vnfd.get("vendor")) |
617 |
0 |
version = vnfd.get("version") |
618 |
0 |
description = vnfd.get("description") |
619 |
0 |
latest = vnfd.get("latest") |
620 |
0 |
table.add_row([name, vendor, version, latest, description, repository]) |
621 |
|
else: |
622 |
0 |
table.add_row([name, repository]) |
623 |
0 |
table.align = "l" |
624 |
0 |
print(table) |
625 |
|
|
626 |
|
|
627 |
1 |
def vnfd_list(ctx, nf_type, filter, long): |
628 |
0 |
logger.debug("") |
629 |
0 |
if nf_type: |
630 |
0 |
check_client_version(ctx.obj, "--nf_type") |
631 |
0 |
elif filter: |
632 |
0 |
check_client_version(ctx.obj, "--filter") |
633 |
0 |
if filter: |
634 |
0 |
filter = "&".join(filter) |
635 |
0 |
if nf_type: |
636 |
0 |
if nf_type == "vnf": |
637 |
0 |
nf_filter = "_admin.type=vnfd" |
638 |
0 |
elif nf_type == "pnf": |
639 |
0 |
nf_filter = "_admin.type=pnfd" |
640 |
0 |
elif nf_type == "hnf": |
641 |
0 |
nf_filter = "_admin.type=hnfd" |
642 |
|
else: |
643 |
0 |
raise ClientException( |
644 |
|
'wrong value for "--nf_type" option, allowed values: vnf, pnf, hnf' |
645 |
|
) |
646 |
0 |
if filter: |
647 |
0 |
filter = "{}&{}".format(nf_filter, filter) |
648 |
|
else: |
649 |
0 |
filter = nf_filter |
650 |
0 |
if filter: |
651 |
0 |
resp = ctx.obj.vnfd.list(filter) |
652 |
|
else: |
653 |
0 |
resp = ctx.obj.vnfd.list() |
654 |
|
# print(yaml.safe_dump(resp)) |
655 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
656 |
0 |
if fullclassname == "osmclient.sol005.client.Client": |
657 |
0 |
if long: |
658 |
0 |
table = PrettyTable( |
659 |
|
[ |
660 |
|
"nfpkg name", |
661 |
|
"id", |
662 |
|
"desc type", |
663 |
|
"vendor", |
664 |
|
"version", |
665 |
|
"onboarding state", |
666 |
|
"operational state", |
667 |
|
"usage state", |
668 |
|
"date", |
669 |
|
"last update", |
670 |
|
] |
671 |
|
) |
672 |
|
else: |
673 |
0 |
table = PrettyTable(["nfpkg name", "id", "desc type"]) |
674 |
0 |
for vnfd in resp: |
675 |
0 |
name = vnfd.get("id", vnfd.get("name", "-")) |
676 |
0 |
descriptor_type = "sol006" if "product-name" in vnfd else "rel8" |
677 |
0 |
if long: |
678 |
0 |
onb_state = vnfd["_admin"].get("onboardingState", "-") |
679 |
0 |
op_state = vnfd["_admin"].get("operationalState", "-") |
680 |
0 |
vendor = vnfd.get("provider", vnfd.get("vendor")) |
681 |
0 |
version = vnfd.get("version") |
682 |
0 |
usage_state = vnfd["_admin"].get("usageState", "-") |
683 |
0 |
date = datetime.fromtimestamp(vnfd["_admin"]["created"]).strftime( |
684 |
|
"%Y-%m-%dT%H:%M:%S" |
685 |
|
) |
686 |
0 |
last_update = datetime.fromtimestamp( |
687 |
|
vnfd["_admin"]["modified"] |
688 |
|
).strftime("%Y-%m-%dT%H:%M:%S") |
689 |
0 |
table.add_row( |
690 |
|
[ |
691 |
|
name, |
692 |
|
vnfd["_id"], |
693 |
|
descriptor_type, |
694 |
|
vendor, |
695 |
|
version, |
696 |
|
onb_state, |
697 |
|
op_state, |
698 |
|
usage_state, |
699 |
|
date, |
700 |
|
last_update, |
701 |
|
] |
702 |
|
) |
703 |
|
else: |
704 |
0 |
table.add_row([name, vnfd["_id"], descriptor_type]) |
705 |
|
else: |
706 |
0 |
table = PrettyTable(["nfpkg name", "id"]) |
707 |
0 |
for vnfd in resp: |
708 |
0 |
table.add_row([vnfd["name"], vnfd["id"]]) |
709 |
0 |
table.align = "l" |
710 |
0 |
print(table) |
711 |
|
|
712 |
|
|
713 |
1 |
@cli_osm.command(name="vnfd-list", short_help="list all xNF packages (VNF, HNF, PNF)") |
714 |
1 |
@click.option("--nf_type", help="type of NF (vnf, pnf, hnf)") |
715 |
1 |
@click.option( |
716 |
|
"--filter", |
717 |
|
default=None, |
718 |
|
multiple=True, |
719 |
|
help="restricts the list to the NF pkg matching the filter", |
720 |
|
) |
721 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
722 |
1 |
@click.pass_context |
723 |
1 |
def vnfd_list1(ctx, nf_type, filter, long): |
724 |
|
"""list all xNF packages (VNF, HNF, PNF)""" |
725 |
0 |
logger.debug("") |
726 |
0 |
vnfd_list(ctx, nf_type, filter, long) |
727 |
|
|
728 |
|
|
729 |
1 |
@cli_osm.command(name="vnfpkg-list", short_help="list all xNF packages (VNF, HNF, PNF)") |
730 |
1 |
@click.option("--nf_type", help="type of NF (vnf, pnf, hnf)") |
731 |
1 |
@click.option( |
732 |
|
"--filter", |
733 |
|
default=None, |
734 |
|
multiple=True, |
735 |
|
help="restricts the list to the NFpkg matching the filter", |
736 |
|
) |
737 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
738 |
1 |
@click.pass_context |
739 |
1 |
def vnfd_list2(ctx, nf_type, filter, long): |
740 |
|
"""list all xNF packages (VNF, HNF, PNF)""" |
741 |
0 |
logger.debug("") |
742 |
0 |
vnfd_list(ctx, nf_type, filter, long) |
743 |
|
|
744 |
|
|
745 |
1 |
@cli_osm.command(name="nfpkg-list", short_help="list all xNF packages (VNF, HNF, PNF)") |
746 |
1 |
@click.option("--nf_type", help="type of NF (vnf, pnf, hnf)") |
747 |
1 |
@click.option( |
748 |
|
"--filter", |
749 |
|
default=None, |
750 |
|
multiple=True, |
751 |
|
help="restricts the list to the NFpkg matching the filter", |
752 |
|
) |
753 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
754 |
1 |
@click.pass_context |
755 |
1 |
def nfpkg_list(ctx, nf_type, filter, long): |
756 |
|
"""list all xNF packages (VNF, HNF, PNF)""" |
757 |
0 |
logger.debug("") |
758 |
|
# try: |
759 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
760 |
0 |
vnfd_list(ctx, nf_type, filter, long) |
761 |
|
# except ClientException as e: |
762 |
|
# print(str(e)) |
763 |
|
# exit(1) |
764 |
|
|
765 |
|
|
766 |
1 |
@cli_osm.command( |
767 |
|
name="vnfpkg-repo-list", short_help="list all xNF from OSM repositories" |
768 |
|
) |
769 |
1 |
@click.option( |
770 |
|
"--filter", |
771 |
|
default=None, |
772 |
|
multiple=True, |
773 |
|
help="restricts the list to the NFpkg matching the filter", |
774 |
|
) |
775 |
1 |
@click.option( |
776 |
|
"--repo", default=None, help="restricts the list to a particular OSM repository" |
777 |
|
) |
778 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
779 |
1 |
@click.pass_context |
780 |
1 |
def nfpkg_repo_list1(ctx, filter, repo, long): |
781 |
|
"""list xNF packages from OSM repositories""" |
782 |
0 |
pkgtype = "vnf" |
783 |
0 |
pkg_repo_list(ctx, pkgtype, filter, repo, long) |
784 |
|
|
785 |
|
|
786 |
1 |
@cli_osm.command( |
787 |
|
name="nfpkg-repo-list", short_help="list all xNF from OSM repositories" |
788 |
|
) |
789 |
1 |
@click.option( |
790 |
|
"--filter", |
791 |
|
default=None, |
792 |
|
multiple=True, |
793 |
|
help="restricts the list to the NFpkg matching the filter", |
794 |
|
) |
795 |
1 |
@click.option( |
796 |
|
"--repo", default=None, help="restricts the list to a particular OSM repository" |
797 |
|
) |
798 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
799 |
1 |
@click.pass_context |
800 |
1 |
def nfpkg_repo_list2(ctx, filter, repo, long): |
801 |
|
"""list xNF packages from OSM repositories""" |
802 |
0 |
pkgtype = "vnf" |
803 |
0 |
pkg_repo_list(ctx, pkgtype, filter, repo, long) |
804 |
|
|
805 |
|
|
806 |
1 |
def vnf_list(ctx, ns, filter, long): |
807 |
|
# try: |
808 |
0 |
if ns or filter: |
809 |
0 |
if ns: |
810 |
0 |
check_client_version(ctx.obj, "--ns") |
811 |
0 |
if filter: |
812 |
0 |
filter = "&".join(filter) |
813 |
0 |
check_client_version(ctx.obj, "--filter") |
814 |
0 |
resp = ctx.obj.vnf.list(ns, filter) |
815 |
|
else: |
816 |
0 |
resp = ctx.obj.vnf.list() |
817 |
|
# except ClientException as e: |
818 |
|
# print(str(e)) |
819 |
|
# exit(1) |
820 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
821 |
0 |
if fullclassname == "osmclient.sol005.client.Client": |
822 |
0 |
field_names = [ |
823 |
|
"vnf id", |
824 |
|
"name", |
825 |
|
"ns id", |
826 |
|
"vnf member index", |
827 |
|
"vnfd name", |
828 |
|
"vim account id", |
829 |
|
"ip address", |
830 |
|
] |
831 |
0 |
if long: |
832 |
0 |
field_names = [ |
833 |
|
"vnf id", |
834 |
|
"name", |
835 |
|
"ns id", |
836 |
|
"vnf member index", |
837 |
|
"vnfd name", |
838 |
|
"vim account id", |
839 |
|
"ip address", |
840 |
|
"date", |
841 |
|
"last update", |
842 |
|
] |
843 |
0 |
table = PrettyTable(field_names) |
844 |
0 |
for vnfr in resp: |
845 |
0 |
name = vnfr["name"] if "name" in vnfr else "-" |
846 |
0 |
new_row = [ |
847 |
|
vnfr["_id"], |
848 |
|
name, |
849 |
|
vnfr["nsr-id-ref"], |
850 |
|
vnfr["member-vnf-index-ref"], |
851 |
|
vnfr["vnfd-ref"], |
852 |
|
vnfr["vim-account-id"], |
853 |
|
vnfr["ip-address"], |
854 |
|
] |
855 |
0 |
if long: |
856 |
0 |
date = datetime.fromtimestamp(vnfr["_admin"]["created"]).strftime( |
857 |
|
"%Y-%m-%dT%H:%M:%S" |
858 |
|
) |
859 |
0 |
last_update = datetime.fromtimestamp( |
860 |
|
vnfr["_admin"]["modified"] |
861 |
|
).strftime("%Y-%m-%dT%H:%M:%S") |
862 |
0 |
new_row.extend([date, last_update]) |
863 |
0 |
table.add_row(new_row) |
864 |
|
else: |
865 |
0 |
table = PrettyTable(["vnf name", "id", "operational status", "config status"]) |
866 |
0 |
for vnfr in resp: |
867 |
0 |
if "mgmt-interface" not in vnfr: |
868 |
0 |
vnfr["mgmt-interface"] = {} |
869 |
0 |
vnfr["mgmt-interface"]["ip-address"] = None |
870 |
0 |
table.add_row( |
871 |
|
[ |
872 |
|
vnfr["name"], |
873 |
|
vnfr["id"], |
874 |
|
vnfr["operational-status"], |
875 |
|
vnfr["config-status"], |
876 |
|
] |
877 |
|
) |
878 |
0 |
table.align = "l" |
879 |
0 |
print(table) |
880 |
|
|
881 |
|
|
882 |
1 |
@cli_osm.command(name="vnf-list", short_help="list all NF instances") |
883 |
1 |
@click.option( |
884 |
|
"--ns", default=None, help="NS instance id or name to restrict the NF list" |
885 |
|
) |
886 |
1 |
@click.option( |
887 |
|
"--filter", |
888 |
|
default=None, |
889 |
|
multiple=True, |
890 |
|
help="restricts the list to the NF instances matching the filter.", |
891 |
|
) |
892 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
893 |
1 |
@click.pass_context |
894 |
1 |
def vnf_list1(ctx, ns, filter, long): |
895 |
|
"""list all NF instances""" |
896 |
0 |
logger.debug("") |
897 |
0 |
vnf_list(ctx, ns, filter, long) |
898 |
|
|
899 |
|
|
900 |
1 |
@cli_osm.command(name="nsd-repo-list", short_help="list all NS from OSM repositories") |
901 |
1 |
@click.option( |
902 |
|
"--filter", |
903 |
|
default=None, |
904 |
|
multiple=True, |
905 |
|
help="restricts the list to the NS matching the filter", |
906 |
|
) |
907 |
1 |
@click.option( |
908 |
|
"--repo", default=None, help="restricts the list to a particular OSM repository" |
909 |
|
) |
910 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
911 |
1 |
@click.pass_context |
912 |
1 |
def nspkg_repo_list(ctx, filter, repo, long): |
913 |
|
"""list xNF packages from OSM repositories""" |
914 |
0 |
pkgtype = "ns" |
915 |
0 |
pkg_repo_list(ctx, pkgtype, filter, repo, long) |
916 |
|
|
917 |
|
|
918 |
1 |
@cli_osm.command(name="nspkg-repo-list", short_help="list all NS from OSM repositories") |
919 |
1 |
@click.option( |
920 |
|
"--filter", |
921 |
|
default=None, |
922 |
|
multiple=True, |
923 |
|
help="restricts the list to the NS matching the filter", |
924 |
|
) |
925 |
1 |
@click.option( |
926 |
|
"--repo", default=None, help="restricts the list to a particular OSM repository" |
927 |
|
) |
928 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
929 |
1 |
@click.pass_context |
930 |
1 |
def nspkg_repo_list2(ctx, filter, repo, long): |
931 |
|
"""list xNF packages from OSM repositories""" |
932 |
0 |
pkgtype = "ns" |
933 |
0 |
pkg_repo_list(ctx, pkgtype, filter, repo, long) |
934 |
|
|
935 |
|
|
936 |
1 |
@cli_osm.command(name="nf-list", short_help="list all NF instances") |
937 |
1 |
@click.option( |
938 |
|
"--ns", default=None, help="NS instance id or name to restrict the NF list" |
939 |
|
) |
940 |
1 |
@click.option( |
941 |
|
"--filter", |
942 |
|
default=None, |
943 |
|
multiple=True, |
944 |
|
help="restricts the list to the NF instances matching the filter.", |
945 |
|
) |
946 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
947 |
1 |
@click.pass_context |
948 |
1 |
def nf_list(ctx, ns, filter, long): |
949 |
|
"""list all NF instances |
950 |
|
|
951 |
|
\b |
952 |
|
Options: |
953 |
|
--ns TEXT NS instance id or name to restrict the VNF list |
954 |
|
--filter filterExpr Restricts the list to the VNF instances matching the filter |
955 |
|
|
956 |
|
\b |
957 |
|
filterExpr consists of one or more strings formatted according to "simpleFilterExpr", |
958 |
|
concatenated using the "&" character: |
959 |
|
|
960 |
|
\b |
961 |
|
filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]* |
962 |
|
simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]* |
963 |
|
op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont" |
964 |
|
attrName := string |
965 |
|
value := scalar value |
966 |
|
|
967 |
|
\b |
968 |
|
where: |
969 |
|
* zero or more occurrences |
970 |
|
? zero or one occurrence |
971 |
|
[] grouping of expressions to be used with ? and * |
972 |
|
"" quotation marks for marking string constants |
973 |
|
<> name separator |
974 |
|
|
975 |
|
\b |
976 |
|
"AttrName" is the name of one attribute in the data type that defines the representation |
977 |
|
of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of |
978 |
|
<attrName> entries to filter by attributes deeper in the hierarchy of a structured document. |
979 |
|
"Op" stands for the comparison operator. If the expression has concatenated <attrName> |
980 |
|
entries, it means that the operator "op" is applied to the attribute addressed by the last |
981 |
|
<attrName> entry included in the concatenation. All simple filter expressions are combined |
982 |
|
by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>, |
983 |
|
the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The |
984 |
|
concatenation of all "attrName" entries except the leaf attribute is called the "attribute |
985 |
|
prefix". If an attribute referenced in an expression is an array, an object that contains a |
986 |
|
corresponding array shall be considered to match the expression if any of the elements in the |
987 |
|
array matches all expressions that have the same attribute prefix. |
988 |
|
|
989 |
|
\b |
990 |
|
Filter examples: |
991 |
|
--filter vim-account-id=<VIM_ACCOUNT_ID> |
992 |
|
--filter vnfd-ref=<VNFD_NAME> |
993 |
|
--filter vdur.ip-address=<IP_ADDRESS> |
994 |
|
--filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS> |
995 |
|
""" |
996 |
0 |
logger.debug("") |
997 |
0 |
vnf_list(ctx, ns, filter, long) |
998 |
|
|
999 |
|
|
1000 |
1 |
@cli_osm.command( |
1001 |
|
name="ns-op-list", short_help="shows the history of operations over a NS instance" |
1002 |
|
) |
1003 |
1 |
@click.argument("name") |
1004 |
1 |
@click.option( |
1005 |
|
"--long", is_flag=True, help="get more details of the NS operation (date, )." |
1006 |
|
) |
1007 |
1 |
@click.pass_context |
1008 |
1 |
def ns_op_list(ctx, name, long): |
1009 |
|
"""shows the history of operations over a NS instance |
1010 |
|
|
1011 |
|
NAME: name or ID of the NS instance |
1012 |
|
""" |
1013 |
|
|
1014 |
0 |
def formatParams(params): |
1015 |
0 |
if params["lcmOperationType"] == "instantiate": |
1016 |
0 |
params.pop("nsDescription") |
1017 |
0 |
params.pop("nsName") |
1018 |
0 |
params.pop("nsdId") |
1019 |
0 |
params.pop("nsr_id") |
1020 |
0 |
elif params["lcmOperationType"] == "action": |
1021 |
0 |
params.pop("primitive") |
1022 |
0 |
params.pop("lcmOperationType") |
1023 |
0 |
params.pop("nsInstanceId") |
1024 |
0 |
return params |
1025 |
|
|
1026 |
0 |
logger.debug("") |
1027 |
|
# try: |
1028 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1029 |
0 |
resp = ctx.obj.ns.list_op(name) |
1030 |
|
# except ClientException as e: |
1031 |
|
# print(str(e)) |
1032 |
|
# exit(1) |
1033 |
|
|
1034 |
0 |
if long: |
1035 |
0 |
table = PrettyTable( |
1036 |
|
[ |
1037 |
|
"id", |
1038 |
|
"operation", |
1039 |
|
"action_name", |
1040 |
|
"operation_params", |
1041 |
|
"status", |
1042 |
|
"date", |
1043 |
|
"last update", |
1044 |
|
"detail", |
1045 |
|
] |
1046 |
|
) |
1047 |
|
else: |
1048 |
0 |
table = PrettyTable( |
1049 |
|
["id", "operation", "action_name", "status", "date", "detail"] |
1050 |
|
) |
1051 |
|
|
1052 |
|
# print(yaml.safe_dump(resp)) |
1053 |
0 |
for op in resp: |
1054 |
0 |
action_name = "N/A" |
1055 |
0 |
if op["lcmOperationType"] == "action": |
1056 |
0 |
action_name = op["operationParams"]["primitive"] |
1057 |
0 |
detail = "-" |
1058 |
0 |
if op["operationState"] == "PROCESSING": |
1059 |
0 |
if op["queuePosition"] is not None and op["queuePosition"] > 0: |
1060 |
0 |
detail = "In queue. Current position: {}".format(op["queuePosition"]) |
1061 |
0 |
elif op["lcmOperationType"] in ("instantiate", "terminate"): |
1062 |
0 |
if op["stage"]: |
1063 |
0 |
detail = op["stage"] |
1064 |
0 |
elif op["operationState"] in ("FAILED", "FAILED_TEMP"): |
1065 |
0 |
detail = op.get("errorMessage", "-") |
1066 |
0 |
date = datetime.fromtimestamp(op["startTime"]).strftime("%Y-%m-%dT%H:%M:%S") |
1067 |
0 |
last_update = datetime.fromtimestamp(op["statusEnteredTime"]).strftime( |
1068 |
|
"%Y-%m-%dT%H:%M:%S" |
1069 |
|
) |
1070 |
0 |
if long: |
1071 |
0 |
table.add_row( |
1072 |
|
[ |
1073 |
|
op["id"], |
1074 |
|
op["lcmOperationType"], |
1075 |
|
action_name, |
1076 |
|
wrap_text( |
1077 |
|
text=json.dumps(formatParams(op["operationParams"]), indent=2), |
1078 |
|
width=50, |
1079 |
|
), |
1080 |
|
op["operationState"], |
1081 |
|
date, |
1082 |
|
last_update, |
1083 |
|
wrap_text(text=detail, width=50), |
1084 |
|
] |
1085 |
|
) |
1086 |
|
else: |
1087 |
0 |
table.add_row( |
1088 |
|
[ |
1089 |
|
op["id"], |
1090 |
|
op["lcmOperationType"], |
1091 |
|
action_name, |
1092 |
|
op["operationState"], |
1093 |
|
date, |
1094 |
|
wrap_text(text=detail or "", width=50), |
1095 |
|
] |
1096 |
|
) |
1097 |
0 |
table.align = "l" |
1098 |
0 |
print(table) |
1099 |
|
|
1100 |
|
|
1101 |
1 |
def nsi_list(ctx, filter): |
1102 |
|
"""list all Network Slice Instances""" |
1103 |
0 |
logger.debug("") |
1104 |
|
# try: |
1105 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1106 |
0 |
if filter: |
1107 |
0 |
filter = "&".join(filter) |
1108 |
0 |
resp = ctx.obj.nsi.list(filter) |
1109 |
|
# except ClientException as e: |
1110 |
|
# print(str(e)) |
1111 |
|
# exit(1) |
1112 |
0 |
table = PrettyTable( |
1113 |
|
[ |
1114 |
|
"netslice instance name", |
1115 |
|
"id", |
1116 |
|
"operational status", |
1117 |
|
"config status", |
1118 |
|
"detailed status", |
1119 |
|
] |
1120 |
|
) |
1121 |
0 |
for nsi in resp: |
1122 |
0 |
nsi_name = nsi["name"] |
1123 |
0 |
nsi_id = nsi["_id"] |
1124 |
0 |
opstatus = ( |
1125 |
|
nsi["operational-status"] if "operational-status" in nsi else "Not found" |
1126 |
|
) |
1127 |
0 |
configstatus = nsi["config-status"] if "config-status" in nsi else "Not found" |
1128 |
0 |
detailed_status = ( |
1129 |
|
nsi["detailed-status"] if "detailed-status" in nsi else "Not found" |
1130 |
|
) |
1131 |
0 |
if configstatus == "config_not_needed": |
1132 |
0 |
configstatus = "configured (no charms)" |
1133 |
0 |
table.add_row([nsi_name, nsi_id, opstatus, configstatus, detailed_status]) |
1134 |
0 |
table.align = "l" |
1135 |
0 |
print(table) |
1136 |
|
|
1137 |
|
|
1138 |
1 |
@cli_osm.command(name="nsi-list", short_help="list all Network Slice Instances (NSI)") |
1139 |
1 |
@click.option( |
1140 |
|
"--filter", |
1141 |
|
default=None, |
1142 |
|
multiple=True, |
1143 |
|
help="restricts the list to the Network Slice Instances matching the filter", |
1144 |
|
) |
1145 |
1 |
@click.pass_context |
1146 |
1 |
def nsi_list1(ctx, filter): |
1147 |
|
"""list all Network Slice Instances (NSI)""" |
1148 |
0 |
logger.debug("") |
1149 |
0 |
nsi_list(ctx, filter) |
1150 |
|
|
1151 |
|
|
1152 |
1 |
@cli_osm.command( |
1153 |
|
name="netslice-instance-list", short_help="list all Network Slice Instances (NSI)" |
1154 |
|
) |
1155 |
1 |
@click.option( |
1156 |
|
"--filter", |
1157 |
|
default=None, |
1158 |
|
multiple=True, |
1159 |
|
help="restricts the list to the Network Slice Instances matching the filter", |
1160 |
|
) |
1161 |
1 |
@click.pass_context |
1162 |
1 |
def nsi_list2(ctx, filter): |
1163 |
|
"""list all Network Slice Instances (NSI)""" |
1164 |
0 |
logger.debug("") |
1165 |
0 |
nsi_list(ctx, filter) |
1166 |
|
|
1167 |
|
|
1168 |
1 |
def nst_list(ctx, filter): |
1169 |
0 |
logger.debug("") |
1170 |
|
# try: |
1171 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1172 |
0 |
if filter: |
1173 |
0 |
filter = "&".join(filter) |
1174 |
0 |
resp = ctx.obj.nst.list(filter) |
1175 |
|
# except ClientException as e: |
1176 |
|
# print(str(e)) |
1177 |
|
# exit(1) |
1178 |
|
# print(yaml.safe_dump(resp)) |
1179 |
0 |
table = PrettyTable(["nst name", "id"]) |
1180 |
0 |
for nst in resp: |
1181 |
0 |
name = nst["name"] if "name" in nst else "-" |
1182 |
0 |
table.add_row([name, nst["_id"]]) |
1183 |
0 |
table.align = "l" |
1184 |
0 |
print(table) |
1185 |
|
|
1186 |
|
|
1187 |
1 |
@cli_osm.command(name="nst-list", short_help="list all Network Slice Templates (NST)") |
1188 |
1 |
@click.option( |
1189 |
|
"--filter", |
1190 |
|
default=None, |
1191 |
|
multiple=True, |
1192 |
|
help="restricts the list to the NST matching the filter", |
1193 |
|
) |
1194 |
1 |
@click.pass_context |
1195 |
1 |
def nst_list1(ctx, filter): |
1196 |
|
"""list all Network Slice Templates (NST) in the system""" |
1197 |
0 |
logger.debug("") |
1198 |
0 |
nst_list(ctx, filter) |
1199 |
|
|
1200 |
|
|
1201 |
1 |
@cli_osm.command( |
1202 |
|
name="netslice-template-list", short_help="list all Network Slice Templates (NST)" |
1203 |
|
) |
1204 |
1 |
@click.option( |
1205 |
|
"--filter", |
1206 |
|
default=None, |
1207 |
|
multiple=True, |
1208 |
|
help="restricts the list to the NST matching the filter", |
1209 |
|
) |
1210 |
1 |
@click.pass_context |
1211 |
1 |
def nst_list2(ctx, filter): |
1212 |
|
"""list all Network Slice Templates (NST) in the system""" |
1213 |
0 |
logger.debug("") |
1214 |
0 |
nst_list(ctx, filter) |
1215 |
|
|
1216 |
|
|
1217 |
1 |
def nsi_op_list(ctx, name): |
1218 |
0 |
logger.debug("") |
1219 |
|
# try: |
1220 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1221 |
0 |
resp = ctx.obj.nsi.list_op(name) |
1222 |
|
# except ClientException as e: |
1223 |
|
# print(str(e)) |
1224 |
|
# exit(1) |
1225 |
0 |
table = PrettyTable(["id", "operation", "status"]) |
1226 |
0 |
for op in resp: |
1227 |
0 |
table.add_row([op["id"], op["lcmOperationType"], op["operationState"]]) |
1228 |
0 |
table.align = "l" |
1229 |
0 |
print(table) |
1230 |
|
|
1231 |
|
|
1232 |
1 |
@cli_osm.command( |
1233 |
|
name="nsi-op-list", |
1234 |
|
short_help="shows the history of operations over a Network Slice Instance (NSI)", |
1235 |
|
) |
1236 |
1 |
@click.argument("name") |
1237 |
1 |
@click.pass_context |
1238 |
1 |
def nsi_op_list1(ctx, name): |
1239 |
|
"""shows the history of operations over a Network Slice Instance (NSI) |
1240 |
|
|
1241 |
|
NAME: name or ID of the Network Slice Instance |
1242 |
|
""" |
1243 |
0 |
logger.debug("") |
1244 |
0 |
nsi_op_list(ctx, name) |
1245 |
|
|
1246 |
|
|
1247 |
1 |
@cli_osm.command( |
1248 |
|
name="netslice-instance-op-list", |
1249 |
|
short_help="shows the history of operations over a Network Slice Instance (NSI)", |
1250 |
|
) |
1251 |
1 |
@click.argument("name") |
1252 |
1 |
@click.pass_context |
1253 |
1 |
def nsi_op_list2(ctx, name): |
1254 |
|
"""shows the history of operations over a Network Slice Instance (NSI) |
1255 |
|
|
1256 |
|
NAME: name or ID of the Network Slice Instance |
1257 |
|
""" |
1258 |
0 |
logger.debug("") |
1259 |
0 |
nsi_op_list(ctx, name) |
1260 |
|
|
1261 |
|
|
1262 |
1 |
@cli_osm.command(name="pdu-list", short_help="list all Physical Deployment Units (PDU)") |
1263 |
1 |
@click.option( |
1264 |
|
"--filter", |
1265 |
|
default=None, |
1266 |
|
multiple=True, |
1267 |
|
help="restricts the list to the Physical Deployment Units matching the filter", |
1268 |
|
) |
1269 |
1 |
@click.pass_context |
1270 |
1 |
def pdu_list(ctx, filter): |
1271 |
|
"""list all Physical Deployment Units (PDU)""" |
1272 |
0 |
logger.debug("") |
1273 |
|
# try: |
1274 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1275 |
0 |
if filter: |
1276 |
0 |
filter = "&".join(filter) |
1277 |
0 |
resp = ctx.obj.pdu.list(filter) |
1278 |
|
# except ClientException as e: |
1279 |
|
# print(str(e)) |
1280 |
|
# exit(1) |
1281 |
0 |
table = PrettyTable(["pdu name", "id", "type", "mgmt ip address"]) |
1282 |
0 |
for pdu in resp: |
1283 |
0 |
pdu_name = pdu["name"] |
1284 |
0 |
pdu_id = pdu["_id"] |
1285 |
0 |
pdu_type = pdu["type"] |
1286 |
0 |
pdu_ipaddress = "None" |
1287 |
0 |
for iface in pdu["interfaces"]: |
1288 |
0 |
if iface["mgmt"]: |
1289 |
0 |
pdu_ipaddress = iface["ip-address"] |
1290 |
0 |
break |
1291 |
0 |
table.add_row([pdu_name, pdu_id, pdu_type, pdu_ipaddress]) |
1292 |
0 |
table.align = "l" |
1293 |
0 |
print(table) |
1294 |
|
|
1295 |
|
|
1296 |
|
#################### |
1297 |
|
# SHOW operations |
1298 |
|
#################### |
1299 |
|
|
1300 |
|
|
1301 |
1 |
def nsd_show(ctx, name, literal): |
1302 |
0 |
logger.debug("") |
1303 |
|
# try: |
1304 |
0 |
resp = ctx.obj.nsd.get(name) |
1305 |
|
# resp = ctx.obj.nsd.get_individual(name) |
1306 |
|
# except ClientException as e: |
1307 |
|
# print(str(e)) |
1308 |
|
# exit(1) |
1309 |
|
|
1310 |
0 |
if literal: |
1311 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
1312 |
0 |
return |
1313 |
|
|
1314 |
0 |
table = PrettyTable(["field", "value"]) |
1315 |
0 |
for k, v in list(resp.items()): |
1316 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2), width=100)]) |
1317 |
0 |
table.align = "l" |
1318 |
0 |
print(table) |
1319 |
|
|
1320 |
|
|
1321 |
1 |
@cli_osm.command(name="nsd-show", short_help="shows the details of a NS package") |
1322 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1323 |
1 |
@click.argument("name") |
1324 |
1 |
@click.pass_context |
1325 |
1 |
def nsd_show1(ctx, name, literal): |
1326 |
|
"""shows the content of a NSD |
1327 |
|
|
1328 |
|
NAME: name or ID of the NSD/NSpkg |
1329 |
|
""" |
1330 |
0 |
logger.debug("") |
1331 |
0 |
nsd_show(ctx, name, literal) |
1332 |
|
|
1333 |
|
|
1334 |
1 |
@cli_osm.command(name="nspkg-show", short_help="shows the details of a NS package") |
1335 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1336 |
1 |
@click.argument("name") |
1337 |
1 |
@click.pass_context |
1338 |
1 |
def nsd_show2(ctx, name, literal): |
1339 |
|
"""shows the content of a NSD |
1340 |
|
|
1341 |
|
NAME: name or ID of the NSD/NSpkg |
1342 |
|
""" |
1343 |
0 |
logger.debug("") |
1344 |
0 |
nsd_show(ctx, name, literal) |
1345 |
|
|
1346 |
|
|
1347 |
1 |
def vnfd_show(ctx, name, literal): |
1348 |
0 |
logger.debug("") |
1349 |
|
# try: |
1350 |
0 |
resp = ctx.obj.vnfd.get(name) |
1351 |
|
# resp = ctx.obj.vnfd.get_individual(name) |
1352 |
|
# except ClientException as e: |
1353 |
|
# print(str(e)) |
1354 |
|
# exit(1) |
1355 |
|
|
1356 |
0 |
if literal: |
1357 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
1358 |
0 |
return |
1359 |
|
|
1360 |
0 |
table = PrettyTable(["field", "value"]) |
1361 |
0 |
for k, v in list(resp.items()): |
1362 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2), width=100)]) |
1363 |
0 |
table.align = "l" |
1364 |
0 |
print(table) |
1365 |
|
|
1366 |
|
|
1367 |
1 |
def pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal): |
1368 |
0 |
logger.debug("") |
1369 |
0 |
if filter: |
1370 |
0 |
filter = "&".join(filter) |
1371 |
|
# try: |
1372 |
0 |
resp = ctx.obj.osmrepo.pkg_get(pkgtype, name, repo, version, filter) |
1373 |
|
|
1374 |
0 |
if literal: |
1375 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
1376 |
0 |
return |
1377 |
0 |
pkgtype += "d" |
1378 |
0 |
catalog = pkgtype + "-catalog" |
1379 |
0 |
full_catalog = pkgtype + ":" + catalog |
1380 |
0 |
if resp.get(catalog): |
1381 |
0 |
resp = resp.pop(catalog)[pkgtype][0] |
1382 |
0 |
elif resp.get(full_catalog): |
1383 |
0 |
resp = resp.pop(full_catalog)[pkgtype][0] |
1384 |
|
|
1385 |
0 |
table = PrettyTable(["field", "value"]) |
1386 |
0 |
for k, v in list(resp.items()): |
1387 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2), width=100)]) |
1388 |
0 |
table.align = "l" |
1389 |
0 |
print(table) |
1390 |
|
|
1391 |
|
|
1392 |
1 |
@cli_osm.command(name="vnfd-show", short_help="shows the details of a NF package") |
1393 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1394 |
1 |
@click.argument("name") |
1395 |
1 |
@click.pass_context |
1396 |
1 |
def vnfd_show1(ctx, name, literal): |
1397 |
|
"""shows the content of a VNFD |
1398 |
|
|
1399 |
|
NAME: name or ID of the VNFD/VNFpkg |
1400 |
|
""" |
1401 |
0 |
logger.debug("") |
1402 |
0 |
vnfd_show(ctx, name, literal) |
1403 |
|
|
1404 |
|
|
1405 |
1 |
@cli_osm.command(name="vnfpkg-show", short_help="shows the details of a NF package") |
1406 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1407 |
1 |
@click.argument("name") |
1408 |
1 |
@click.pass_context |
1409 |
1 |
def vnfd_show2(ctx, name, literal): |
1410 |
|
"""shows the content of a VNFD |
1411 |
|
|
1412 |
|
NAME: name or ID of the VNFD/VNFpkg |
1413 |
|
""" |
1414 |
0 |
logger.debug("") |
1415 |
0 |
vnfd_show(ctx, name, literal) |
1416 |
|
|
1417 |
|
|
1418 |
1 |
@cli_osm.command( |
1419 |
|
name="vnfpkg-repo-show", |
1420 |
|
short_help="shows the details of a NF package in an OSM repository", |
1421 |
|
) |
1422 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1423 |
1 |
@click.option("--repo", required=True, help="Repository name") |
1424 |
1 |
@click.argument("name") |
1425 |
1 |
@click.option("--filter", default=None, multiple=True, help="filter by fields") |
1426 |
1 |
@click.option("--version", default="latest", help="package version") |
1427 |
1 |
@click.pass_context |
1428 |
1 |
def vnfd_show3(ctx, name, repo, version, literal=None, filter=None): |
1429 |
|
"""shows the content of a VNFD in a repository |
1430 |
|
|
1431 |
|
NAME: name or ID of the VNFD/VNFpkg |
1432 |
|
""" |
1433 |
0 |
pkgtype = "vnf" |
1434 |
0 |
pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal) |
1435 |
|
|
1436 |
|
|
1437 |
1 |
@cli_osm.command( |
1438 |
|
name="nsd-repo-show", |
1439 |
|
short_help="shows the details of a NS package in an OSM repository", |
1440 |
|
) |
1441 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1442 |
1 |
@click.option("--repo", required=True, help="Repository name") |
1443 |
1 |
@click.argument("name") |
1444 |
1 |
@click.option("--filter", default=None, multiple=True, help="filter by fields") |
1445 |
1 |
@click.option("--version", default="latest", help="package version") |
1446 |
1 |
@click.pass_context |
1447 |
1 |
def nsd_repo_show(ctx, name, repo, version, literal=None, filter=None): |
1448 |
|
"""shows the content of a VNFD in a repository |
1449 |
|
|
1450 |
|
NAME: name or ID of the VNFD/VNFpkg |
1451 |
|
""" |
1452 |
0 |
pkgtype = "ns" |
1453 |
0 |
pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal) |
1454 |
|
|
1455 |
|
|
1456 |
1 |
@cli_osm.command( |
1457 |
|
name="nspkg-repo-show", |
1458 |
|
short_help="shows the details of a NS package in an OSM repository", |
1459 |
|
) |
1460 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1461 |
1 |
@click.option("--repo", required=True, help="Repository name") |
1462 |
1 |
@click.argument("name") |
1463 |
1 |
@click.option("--filter", default=None, multiple=True, help="filter by fields") |
1464 |
1 |
@click.option("--version", default="latest", help="package version") |
1465 |
1 |
@click.pass_context |
1466 |
1 |
def nsd_repo_show2(ctx, name, repo, version, literal=None, filter=None): |
1467 |
|
"""shows the content of a VNFD in a repository |
1468 |
|
|
1469 |
|
NAME: name or ID of the VNFD/VNFpkg |
1470 |
|
""" |
1471 |
0 |
pkgtype = "ns" |
1472 |
0 |
pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal) |
1473 |
|
|
1474 |
|
|
1475 |
1 |
@cli_osm.command(name="nfpkg-show", short_help="shows the details of a NF package") |
1476 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1477 |
1 |
@click.argument("name") |
1478 |
1 |
@click.pass_context |
1479 |
1 |
def nfpkg_show(ctx, name, literal): |
1480 |
|
"""shows the content of a NF Descriptor |
1481 |
|
|
1482 |
|
NAME: name or ID of the NFpkg |
1483 |
|
""" |
1484 |
0 |
logger.debug("") |
1485 |
0 |
vnfd_show(ctx, name, literal) |
1486 |
|
|
1487 |
|
|
1488 |
1 |
@cli_osm.command( |
1489 |
|
name="nfpkg-repo-show", |
1490 |
|
short_help="shows the details of a NF package in an OSM repository", |
1491 |
|
) |
1492 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1493 |
1 |
@click.option("--repo", required=True, help="Repository name") |
1494 |
1 |
@click.argument("name") |
1495 |
1 |
@click.option("--filter", default=None, multiple=True, help="filter by fields") |
1496 |
1 |
@click.option("--version", default="latest", help="package version") |
1497 |
1 |
@click.pass_context |
1498 |
1 |
def vnfd_show4(ctx, name, repo, version, literal=None, filter=None): |
1499 |
|
"""shows the content of a VNFD in a repository |
1500 |
|
|
1501 |
|
NAME: name or ID of the VNFD/VNFpkg |
1502 |
|
""" |
1503 |
0 |
pkgtype = "vnf" |
1504 |
0 |
pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal) |
1505 |
|
|
1506 |
|
|
1507 |
1 |
@cli_osm.command(name="ns-show", short_help="shows the info of a NS instance") |
1508 |
1 |
@click.argument("name") |
1509 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1510 |
1 |
@click.option( |
1511 |
|
"--filter", |
1512 |
|
multiple=True, |
1513 |
|
help="restricts the information to the fields in the filter", |
1514 |
|
) |
1515 |
1 |
@click.pass_context |
1516 |
1 |
def ns_show(ctx, name, literal, filter): |
1517 |
|
"""shows the info of a NS instance |
1518 |
|
|
1519 |
|
NAME: name or ID of the NS instance |
1520 |
|
""" |
1521 |
0 |
logger.debug("") |
1522 |
|
# try: |
1523 |
0 |
ns = ctx.obj.ns.get(name) |
1524 |
|
# except ClientException as e: |
1525 |
|
# print(str(e)) |
1526 |
|
# exit(1) |
1527 |
|
|
1528 |
0 |
if literal: |
1529 |
0 |
print(yaml.safe_dump(ns, indent=4, default_flow_style=False)) |
1530 |
0 |
return |
1531 |
|
|
1532 |
0 |
table = PrettyTable(["field", "value"]) |
1533 |
|
|
1534 |
0 |
for k, v in list(ns.items()): |
1535 |
0 |
if not filter or k in filter: |
1536 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2), width=100)]) |
1537 |
|
|
1538 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
1539 |
0 |
if fullclassname != "osmclient.sol005.client.Client": |
1540 |
0 |
nsopdata = ctx.obj.ns.get_opdata(ns["id"]) |
1541 |
0 |
nsr_optdata = nsopdata["nsr:nsr"] |
1542 |
0 |
for k, v in list(nsr_optdata.items()): |
1543 |
0 |
if not filter or k in filter: |
1544 |
0 |
table.add_row([k, wrap_text(json.dumps(v, indent=2), width=100)]) |
1545 |
0 |
table.align = "l" |
1546 |
0 |
print(table) |
1547 |
|
|
1548 |
|
|
1549 |
1 |
@cli_osm.command(name="vnf-show", short_help="shows the info of a VNF instance") |
1550 |
1 |
@click.argument("name") |
1551 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1552 |
1 |
@click.option( |
1553 |
|
"--filter", |
1554 |
|
multiple=True, |
1555 |
|
help="restricts the information to the fields in the filter", |
1556 |
|
) |
1557 |
1 |
@click.option("--kdu", default=None, help="KDU name (whose status will be shown)") |
1558 |
1 |
@click.pass_context |
1559 |
1 |
def vnf_show(ctx, name, literal, filter, kdu): |
1560 |
|
"""shows the info of a VNF instance |
1561 |
|
|
1562 |
|
NAME: name or ID of the VNF instance |
1563 |
|
""" |
1564 |
|
|
1565 |
0 |
def print_kdu_status(op_info_status): |
1566 |
|
"""print KDU status properly formatted""" |
1567 |
0 |
try: |
1568 |
0 |
op_status = yaml.safe_load(op_info_status) |
1569 |
0 |
if ( |
1570 |
|
"namespace" in op_status |
1571 |
|
and "info" in op_status |
1572 |
|
and "last_deployed" in op_status["info"] |
1573 |
|
and "status" in op_status["info"] |
1574 |
|
and "code" in op_status["info"]["status"] |
1575 |
|
and "resources" in op_status["info"]["status"] |
1576 |
|
and "seconds" in op_status["info"]["last_deployed"] |
1577 |
|
): |
1578 |
0 |
last_deployed_time = datetime.fromtimestamp( |
1579 |
|
op_status["info"]["last_deployed"]["seconds"] |
1580 |
|
).strftime("%a %b %d %I:%M:%S %Y") |
1581 |
0 |
print("LAST DEPLOYED: {}".format(last_deployed_time)) |
1582 |
0 |
print("NAMESPACE: {}".format(op_status["namespace"])) |
1583 |
0 |
status_code = "UNKNOWN" |
1584 |
0 |
if op_status["info"]["status"]["code"] == 1: |
1585 |
0 |
status_code = "DEPLOYED" |
1586 |
0 |
print("STATUS: {}".format(status_code)) |
1587 |
0 |
print() |
1588 |
0 |
print("RESOURCES:") |
1589 |
0 |
print(op_status["info"]["status"]["resources"]) |
1590 |
0 |
if "notes" in op_status["info"]["status"]: |
1591 |
0 |
print("NOTES:") |
1592 |
0 |
print(op_status["info"]["status"]["notes"]) |
1593 |
|
else: |
1594 |
0 |
print(op_info_status) |
1595 |
0 |
except Exception: |
1596 |
0 |
print(op_info_status) |
1597 |
|
|
1598 |
0 |
logger.debug("") |
1599 |
0 |
if kdu: |
1600 |
0 |
if literal: |
1601 |
0 |
raise ClientException( |
1602 |
|
'"--literal" option is incompatible with "--kdu" option' |
1603 |
|
) |
1604 |
0 |
if filter: |
1605 |
0 |
raise ClientException( |
1606 |
|
'"--filter" option is incompatible with "--kdu" option' |
1607 |
|
) |
1608 |
|
|
1609 |
|
# try: |
1610 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1611 |
0 |
resp = ctx.obj.vnf.get(name) |
1612 |
|
|
1613 |
0 |
if kdu: |
1614 |
0 |
ns_id = resp["nsr-id-ref"] |
1615 |
0 |
op_data = {} |
1616 |
0 |
op_data["member_vnf_index"] = resp["member-vnf-index-ref"] |
1617 |
0 |
op_data["kdu_name"] = kdu |
1618 |
0 |
op_data["primitive"] = "status" |
1619 |
0 |
op_data["primitive_params"] = {} |
1620 |
0 |
op_id = ctx.obj.ns.exec_op(ns_id, op_name="action", op_data=op_data, wait=False) |
1621 |
0 |
t = 0 |
1622 |
0 |
while t < 30: |
1623 |
0 |
op_info = ctx.obj.ns.get_op(op_id) |
1624 |
0 |
if op_info["operationState"] == "COMPLETED": |
1625 |
0 |
print_kdu_status(op_info["detailed-status"]) |
1626 |
0 |
return |
1627 |
0 |
time.sleep(5) |
1628 |
0 |
t += 5 |
1629 |
0 |
print("Could not determine KDU status") |
1630 |
0 |
return |
1631 |
|
|
1632 |
0 |
if literal: |
1633 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
1634 |
0 |
return |
1635 |
|
|
1636 |
0 |
table = PrettyTable(["field", "value"]) |
1637 |
0 |
for k, v in list(resp.items()): |
1638 |
0 |
if not filter or k in filter: |
1639 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2), width=100)]) |
1640 |
0 |
table.align = "l" |
1641 |
0 |
print(table) |
1642 |
|
# except ClientException as e: |
1643 |
|
# print(str(e)) |
1644 |
|
# exit(1) |
1645 |
|
|
1646 |
|
|
1647 |
|
# @cli_osm.command(name='vnf-monitoring-show') |
1648 |
|
# @click.argument('vnf_name') |
1649 |
|
# @click.pass_context |
1650 |
|
# def vnf_monitoring_show(ctx, vnf_name): |
1651 |
|
# try: |
1652 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
1653 |
|
# resp = ctx.obj.vnf.get_monitoring(vnf_name) |
1654 |
|
# except ClientException as e: |
1655 |
|
# print(str(e)) |
1656 |
|
# exit(1) |
1657 |
|
# |
1658 |
|
# table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units']) |
1659 |
|
# if resp is not None: |
1660 |
|
# for monitor in resp: |
1661 |
|
# table.add_row( |
1662 |
|
# [vnf_name, |
1663 |
|
# monitor['name'], |
1664 |
|
# monitor['value-integer'], |
1665 |
|
# monitor['units']]) |
1666 |
|
# table.align = 'l' |
1667 |
|
# print(table) |
1668 |
|
|
1669 |
|
|
1670 |
|
# @cli_osm.command(name='ns-monitoring-show') |
1671 |
|
# @click.argument('ns_name') |
1672 |
|
# @click.pass_context |
1673 |
|
# def ns_monitoring_show(ctx, ns_name): |
1674 |
|
# try: |
1675 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
1676 |
|
# resp = ctx.obj.ns.get_monitoring(ns_name) |
1677 |
|
# except ClientException as e: |
1678 |
|
# print(str(e)) |
1679 |
|
# exit(1) |
1680 |
|
# |
1681 |
|
# table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units']) |
1682 |
|
# for key, val in list(resp.items()): |
1683 |
|
# for monitor in val: |
1684 |
|
# table.add_row( |
1685 |
|
# [key, |
1686 |
|
# monitor['name'], |
1687 |
|
# monitor['value-integer'], |
1688 |
|
# monitor['units']]) |
1689 |
|
# table.align = 'l' |
1690 |
|
# print(table) |
1691 |
|
|
1692 |
|
|
1693 |
1 |
@cli_osm.command(name="ns-op-show", short_help="shows the info of a NS operation") |
1694 |
1 |
@click.argument("id") |
1695 |
1 |
@click.option( |
1696 |
|
"--filter", |
1697 |
|
multiple=True, |
1698 |
|
help="restricts the information to the fields in the filter", |
1699 |
|
) |
1700 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1701 |
1 |
@click.pass_context |
1702 |
1 |
def ns_op_show(ctx, id, filter, literal): |
1703 |
|
"""shows the detailed info of a NS operation |
1704 |
|
|
1705 |
|
ID: operation identifier |
1706 |
|
""" |
1707 |
0 |
logger.debug("") |
1708 |
|
# try: |
1709 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1710 |
0 |
op_info = ctx.obj.ns.get_op(id) |
1711 |
|
# except ClientException as e: |
1712 |
|
# print(str(e)) |
1713 |
|
# exit(1) |
1714 |
|
|
1715 |
0 |
if literal: |
1716 |
0 |
print(yaml.safe_dump(op_info, indent=4, default_flow_style=False)) |
1717 |
0 |
return |
1718 |
|
|
1719 |
0 |
table = PrettyTable(["field", "value"]) |
1720 |
0 |
for k, v in list(op_info.items()): |
1721 |
0 |
if not filter or k in filter: |
1722 |
0 |
table.add_row([k, wrap_text(json.dumps(v, indent=2), 100)]) |
1723 |
0 |
table.align = "l" |
1724 |
0 |
print(table) |
1725 |
|
|
1726 |
|
|
1727 |
1 |
def nst_show(ctx, name, literal): |
1728 |
0 |
logger.debug("") |
1729 |
|
# try: |
1730 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1731 |
0 |
resp = ctx.obj.nst.get(name) |
1732 |
|
# resp = ctx.obj.nst.get_individual(name) |
1733 |
|
# except ClientException as e: |
1734 |
|
# print(str(e)) |
1735 |
|
# exit(1) |
1736 |
|
|
1737 |
0 |
if literal: |
1738 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
1739 |
0 |
return |
1740 |
|
|
1741 |
0 |
table = PrettyTable(["field", "value"]) |
1742 |
0 |
for k, v in list(resp.items()): |
1743 |
0 |
table.add_row([k, wrap_text(json.dumps(v, indent=2), 100)]) |
1744 |
0 |
table.align = "l" |
1745 |
0 |
print(table) |
1746 |
|
|
1747 |
|
|
1748 |
1 |
@cli_osm.command( |
1749 |
|
name="nst-show", short_help="shows the content of a Network Slice Template (NST)" |
1750 |
|
) |
1751 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1752 |
1 |
@click.argument("name") |
1753 |
1 |
@click.pass_context |
1754 |
1 |
def nst_show1(ctx, name, literal): |
1755 |
|
"""shows the content of a Network Slice Template (NST) |
1756 |
|
|
1757 |
|
NAME: name or ID of the NST |
1758 |
|
""" |
1759 |
0 |
logger.debug("") |
1760 |
0 |
nst_show(ctx, name, literal) |
1761 |
|
|
1762 |
|
|
1763 |
1 |
@cli_osm.command( |
1764 |
|
name="netslice-template-show", |
1765 |
|
short_help="shows the content of a Network Slice Template (NST)", |
1766 |
|
) |
1767 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1768 |
1 |
@click.argument("name") |
1769 |
1 |
@click.pass_context |
1770 |
1 |
def nst_show2(ctx, name, literal): |
1771 |
|
"""shows the content of a Network Slice Template (NST) |
1772 |
|
|
1773 |
|
NAME: name or ID of the NST |
1774 |
|
""" |
1775 |
0 |
logger.debug("") |
1776 |
0 |
nst_show(ctx, name, literal) |
1777 |
|
|
1778 |
|
|
1779 |
1 |
def nsi_show(ctx, name, literal, filter): |
1780 |
0 |
logger.debug("") |
1781 |
|
# try: |
1782 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1783 |
0 |
nsi = ctx.obj.nsi.get(name) |
1784 |
|
# except ClientException as e: |
1785 |
|
# print(str(e)) |
1786 |
|
# exit(1) |
1787 |
|
|
1788 |
0 |
if literal: |
1789 |
0 |
print(yaml.safe_dump(nsi, indent=4, default_flow_style=False)) |
1790 |
0 |
return |
1791 |
|
|
1792 |
0 |
table = PrettyTable(["field", "value"]) |
1793 |
|
|
1794 |
0 |
for k, v in list(nsi.items()): |
1795 |
0 |
if not filter or k in filter: |
1796 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
1797 |
|
|
1798 |
0 |
table.align = "l" |
1799 |
0 |
print(table) |
1800 |
|
|
1801 |
|
|
1802 |
1 |
@cli_osm.command( |
1803 |
|
name="nsi-show", short_help="shows the content of a Network Slice Instance (NSI)" |
1804 |
|
) |
1805 |
1 |
@click.argument("name") |
1806 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1807 |
1 |
@click.option( |
1808 |
|
"--filter", |
1809 |
|
multiple=True, |
1810 |
|
help="restricts the information to the fields in the filter", |
1811 |
|
) |
1812 |
1 |
@click.pass_context |
1813 |
1 |
def nsi_show1(ctx, name, literal, filter): |
1814 |
|
"""shows the content of a Network Slice Instance (NSI) |
1815 |
|
|
1816 |
|
NAME: name or ID of the Network Slice Instance |
1817 |
|
""" |
1818 |
0 |
logger.debug("") |
1819 |
0 |
nsi_show(ctx, name, literal, filter) |
1820 |
|
|
1821 |
|
|
1822 |
1 |
@cli_osm.command( |
1823 |
|
name="netslice-instance-show", |
1824 |
|
short_help="shows the content of a Network Slice Instance (NSI)", |
1825 |
|
) |
1826 |
1 |
@click.argument("name") |
1827 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1828 |
1 |
@click.option( |
1829 |
|
"--filter", |
1830 |
|
multiple=True, |
1831 |
|
help="restricts the information to the fields in the filter", |
1832 |
|
) |
1833 |
1 |
@click.pass_context |
1834 |
1 |
def nsi_show2(ctx, name, literal, filter): |
1835 |
|
"""shows the content of a Network Slice Instance (NSI) |
1836 |
|
|
1837 |
|
NAME: name or ID of the Network Slice Instance |
1838 |
|
""" |
1839 |
0 |
logger.debug("") |
1840 |
0 |
nsi_show(ctx, name, literal, filter) |
1841 |
|
|
1842 |
|
|
1843 |
1 |
def nsi_op_show(ctx, id, filter): |
1844 |
0 |
logger.debug("") |
1845 |
|
# try: |
1846 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1847 |
0 |
op_info = ctx.obj.nsi.get_op(id) |
1848 |
|
# except ClientException as e: |
1849 |
|
# print(str(e)) |
1850 |
|
# exit(1) |
1851 |
|
|
1852 |
0 |
table = PrettyTable(["field", "value"]) |
1853 |
0 |
for k, v in list(op_info.items()): |
1854 |
0 |
if not filter or k in filter: |
1855 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
1856 |
0 |
table.align = "l" |
1857 |
0 |
print(table) |
1858 |
|
|
1859 |
|
|
1860 |
1 |
@cli_osm.command( |
1861 |
|
name="nsi-op-show", |
1862 |
|
short_help="shows the info of an operation over a Network Slice Instance(NSI)", |
1863 |
|
) |
1864 |
1 |
@click.argument("id") |
1865 |
1 |
@click.option( |
1866 |
|
"--filter", |
1867 |
|
multiple=True, |
1868 |
|
help="restricts the information to the fields in the filter", |
1869 |
|
) |
1870 |
1 |
@click.pass_context |
1871 |
1 |
def nsi_op_show1(ctx, id, filter): |
1872 |
|
"""shows the info of an operation over a Network Slice Instance(NSI) |
1873 |
|
|
1874 |
|
ID: operation identifier |
1875 |
|
""" |
1876 |
0 |
logger.debug("") |
1877 |
0 |
nsi_op_show(ctx, id, filter) |
1878 |
|
|
1879 |
|
|
1880 |
1 |
@cli_osm.command( |
1881 |
|
name="netslice-instance-op-show", |
1882 |
|
short_help="shows the info of an operation over a Network Slice Instance(NSI)", |
1883 |
|
) |
1884 |
1 |
@click.argument("id") |
1885 |
1 |
@click.option( |
1886 |
|
"--filter", |
1887 |
|
multiple=True, |
1888 |
|
help="restricts the information to the fields in the filter", |
1889 |
|
) |
1890 |
1 |
@click.pass_context |
1891 |
1 |
def nsi_op_show2(ctx, id, filter): |
1892 |
|
"""shows the info of an operation over a Network Slice Instance(NSI) |
1893 |
|
|
1894 |
|
ID: operation identifier |
1895 |
|
""" |
1896 |
0 |
logger.debug("") |
1897 |
0 |
nsi_op_show(ctx, id, filter) |
1898 |
|
|
1899 |
|
|
1900 |
1 |
@cli_osm.command( |
1901 |
|
name="pdu-show", short_help="shows the content of a Physical Deployment Unit (PDU)" |
1902 |
|
) |
1903 |
1 |
@click.argument("name") |
1904 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
1905 |
1 |
@click.option( |
1906 |
|
"--filter", |
1907 |
|
multiple=True, |
1908 |
|
help="restricts the information to the fields in the filter", |
1909 |
|
) |
1910 |
1 |
@click.pass_context |
1911 |
1 |
def pdu_show(ctx, name, literal, filter): |
1912 |
|
"""shows the content of a Physical Deployment Unit (PDU) |
1913 |
|
|
1914 |
|
NAME: name or ID of the PDU |
1915 |
|
""" |
1916 |
0 |
logger.debug("") |
1917 |
|
# try: |
1918 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1919 |
0 |
pdu = ctx.obj.pdu.get(name) |
1920 |
|
# except ClientException as e: |
1921 |
|
# print(str(e)) |
1922 |
|
# exit(1) |
1923 |
|
|
1924 |
0 |
if literal: |
1925 |
0 |
print(yaml.safe_dump(pdu, indent=4, default_flow_style=False)) |
1926 |
0 |
return |
1927 |
|
|
1928 |
0 |
table = PrettyTable(["field", "value"]) |
1929 |
|
|
1930 |
0 |
for k, v in list(pdu.items()): |
1931 |
0 |
if not filter or k in filter: |
1932 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
1933 |
|
|
1934 |
0 |
table.align = "l" |
1935 |
0 |
print(table) |
1936 |
|
|
1937 |
|
|
1938 |
|
#################### |
1939 |
|
# CREATE operations |
1940 |
|
#################### |
1941 |
|
|
1942 |
|
|
1943 |
1 |
def nsd_create(ctx, filename, overwrite, skip_charm_build, repo, vendor, version): |
1944 |
0 |
logger.debug("") |
1945 |
|
# try: |
1946 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
1947 |
0 |
if repo: |
1948 |
0 |
filename = ctx.obj.osmrepo.get_pkg("ns", filename, repo, vendor, version) |
1949 |
0 |
ctx.obj.nsd.create(filename, overwrite=overwrite, skip_charm_build=skip_charm_build) |
1950 |
|
# except ClientException as e: |
1951 |
|
# print(str(e)) |
1952 |
|
# exit(1) |
1953 |
|
|
1954 |
|
|
1955 |
1 |
@cli_osm.command(name="nsd-create", short_help="creates a new NSD/NSpkg") |
1956 |
1 |
@click.argument("filename") |
1957 |
1 |
@click.option( |
1958 |
|
"--overwrite", |
1959 |
|
"overwrite", |
1960 |
|
default=None, # hidden=True, |
1961 |
|
help="Deprecated. Use override", |
1962 |
|
) |
1963 |
1 |
@click.option( |
1964 |
|
"--override", |
1965 |
|
"overwrite", |
1966 |
|
default=None, |
1967 |
|
help="overrides fields in descriptor, format: " |
1968 |
|
'"key1.key2...=value[;key3...=value;...]"', |
1969 |
|
) |
1970 |
1 |
@click.option( |
1971 |
|
"--skip-charm-build", |
1972 |
|
default=False, |
1973 |
|
is_flag=True, |
1974 |
|
help="The charm will not be compiled, it is assumed to already exist", |
1975 |
|
) |
1976 |
1 |
@click.option("--repo", default=None, help="[repository]: Repository name") |
1977 |
1 |
@click.option("--vendor", default=None, help="[repository]: filter by vendor]") |
1978 |
1 |
@click.option( |
1979 |
|
"--version", |
1980 |
|
default="latest", |
1981 |
|
help="[repository]: filter by version. Default: latest", |
1982 |
|
) |
1983 |
1 |
@click.pass_context |
1984 |
1 |
def nsd_create1(ctx, filename, overwrite, skip_charm_build, repo, vendor, version): |
1985 |
|
"""onboards a new NSpkg (alias of nspkg-create) (TO BE DEPRECATED) |
1986 |
|
|
1987 |
|
\b |
1988 |
|
FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder |
1989 |
|
If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded. |
1990 |
|
If FILENAME is an NF Package folder, it is built and then onboarded. |
1991 |
|
""" |
1992 |
0 |
logger.debug("") |
1993 |
0 |
nsd_create( |
1994 |
|
ctx, |
1995 |
|
filename, |
1996 |
|
overwrite=overwrite, |
1997 |
|
skip_charm_build=skip_charm_build, |
1998 |
|
repo=repo, |
1999 |
|
vendor=vendor, |
2000 |
|
version=version, |
2001 |
|
) |
2002 |
|
|
2003 |
|
|
2004 |
1 |
@cli_osm.command(name="nspkg-create", short_help="creates a new NSD/NSpkg") |
2005 |
1 |
@click.argument("filename") |
2006 |
1 |
@click.option( |
2007 |
|
"--overwrite", |
2008 |
|
"overwrite", |
2009 |
|
default=None, # hidden=True, |
2010 |
|
help="Deprecated. Use override", |
2011 |
|
) |
2012 |
1 |
@click.option( |
2013 |
|
"--override", |
2014 |
|
"overwrite", |
2015 |
|
default=None, |
2016 |
|
help="overrides fields in descriptor, format: " |
2017 |
|
'"key1.key2...=value[;key3...=value;...]"', |
2018 |
|
) |
2019 |
1 |
@click.option( |
2020 |
|
"--skip-charm-build", |
2021 |
|
default=False, |
2022 |
|
is_flag=True, |
2023 |
|
help="The charm will not be compiled, it is assumed to already exist", |
2024 |
|
) |
2025 |
1 |
@click.option("--repo", default=None, help="[repository]: Repository name") |
2026 |
1 |
@click.option("--vendor", default=None, help="[repository]: filter by vendor]") |
2027 |
1 |
@click.option( |
2028 |
|
"--version", |
2029 |
|
default="latest", |
2030 |
|
help="[repository]: filter by version. Default: latest", |
2031 |
|
) |
2032 |
1 |
@click.pass_context |
2033 |
1 |
def nsd_pkg_create(ctx, filename, overwrite, skip_charm_build, repo, vendor, version): |
2034 |
|
"""onboards a new NSpkg |
2035 |
|
\b |
2036 |
|
FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder |
2037 |
|
If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded. |
2038 |
|
If FILENAME is an NF Package folder, it is built and then onboarded. |
2039 |
|
""" |
2040 |
0 |
logger.debug("") |
2041 |
0 |
nsd_create( |
2042 |
|
ctx, |
2043 |
|
filename, |
2044 |
|
overwrite=overwrite, |
2045 |
|
skip_charm_build=skip_charm_build, |
2046 |
|
repo=repo, |
2047 |
|
vendor=vendor, |
2048 |
|
version=version, |
2049 |
|
) |
2050 |
|
|
2051 |
|
|
2052 |
1 |
def vnfd_create( |
2053 |
|
ctx, |
2054 |
|
filename, |
2055 |
|
overwrite, |
2056 |
|
skip_charm_build, |
2057 |
|
override_epa, |
2058 |
|
override_nonepa, |
2059 |
|
override_paravirt, |
2060 |
|
repo, |
2061 |
|
vendor, |
2062 |
|
version, |
2063 |
|
): |
2064 |
0 |
logger.debug("") |
2065 |
|
# try: |
2066 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2067 |
0 |
if repo: |
2068 |
0 |
filename = ctx.obj.osmrepo.get_pkg("vnf", filename, repo, vendor, version) |
2069 |
0 |
ctx.obj.vnfd.create( |
2070 |
|
filename, |
2071 |
|
overwrite=overwrite, |
2072 |
|
skip_charm_build=skip_charm_build, |
2073 |
|
override_epa=override_epa, |
2074 |
|
override_nonepa=override_nonepa, |
2075 |
|
override_paravirt=override_paravirt, |
2076 |
|
) |
2077 |
|
# except ClientException as e: |
2078 |
|
# print(str(e)) |
2079 |
|
# exit(1) |
2080 |
|
|
2081 |
|
|
2082 |
1 |
@cli_osm.command(name="vnfd-create", short_help="creates a new VNFD/VNFpkg") |
2083 |
1 |
@click.argument("filename") |
2084 |
1 |
@click.option( |
2085 |
|
"--overwrite", "overwrite", default=None, help="overwrite deprecated, use override" |
2086 |
|
) |
2087 |
1 |
@click.option( |
2088 |
|
"--override", |
2089 |
|
"overwrite", |
2090 |
|
default=None, |
2091 |
|
help="overrides fields in descriptor, format: " |
2092 |
|
'"key1.key2...=value[;key3...=value;...]"', |
2093 |
|
) |
2094 |
1 |
@click.option( |
2095 |
|
"--skip-charm-build", |
2096 |
|
default=False, |
2097 |
|
is_flag=True, |
2098 |
|
help="The charm will not be compiled, it is assumed to already exist", |
2099 |
|
) |
2100 |
1 |
@click.option( |
2101 |
|
"--override-epa", |
2102 |
|
required=False, |
2103 |
|
default=False, |
2104 |
|
is_flag=True, |
2105 |
|
help="adds guest-epa parameters to all VDU", |
2106 |
|
) |
2107 |
1 |
@click.option( |
2108 |
|
"--override-nonepa", |
2109 |
|
required=False, |
2110 |
|
default=False, |
2111 |
|
is_flag=True, |
2112 |
|
help="removes all guest-epa parameters from all VDU", |
2113 |
|
) |
2114 |
1 |
@click.option( |
2115 |
|
"--override-paravirt", |
2116 |
|
required=False, |
2117 |
|
default=False, |
2118 |
|
is_flag=True, |
2119 |
|
help="overrides all VDU interfaces to PARAVIRT", |
2120 |
|
) |
2121 |
1 |
@click.option("--repo", default=None, help="[repository]: Repository name") |
2122 |
1 |
@click.option("--vendor", default=None, help="[repository]: filter by vendor]") |
2123 |
1 |
@click.option( |
2124 |
|
"--version", |
2125 |
|
default="latest", |
2126 |
|
help="[repository]: filter by version. Default: latest", |
2127 |
|
) |
2128 |
1 |
@click.pass_context |
2129 |
1 |
def vnfd_create1( |
2130 |
|
ctx, |
2131 |
|
filename, |
2132 |
|
overwrite, |
2133 |
|
skip_charm_build, |
2134 |
|
override_epa, |
2135 |
|
override_nonepa, |
2136 |
|
override_paravirt, |
2137 |
|
repo, |
2138 |
|
vendor, |
2139 |
|
version, |
2140 |
|
): |
2141 |
|
"""creates a new VNFD/VNFpkg |
2142 |
|
\b |
2143 |
|
FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder |
2144 |
|
If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded. |
2145 |
|
If FILENAME is an NF Package folder, it is built and then onboarded. |
2146 |
|
""" |
2147 |
0 |
logger.debug("") |
2148 |
0 |
vnfd_create( |
2149 |
|
ctx, |
2150 |
|
filename, |
2151 |
|
overwrite=overwrite, |
2152 |
|
skip_charm_build=skip_charm_build, |
2153 |
|
override_epa=override_epa, |
2154 |
|
override_nonepa=override_nonepa, |
2155 |
|
override_paravirt=override_paravirt, |
2156 |
|
repo=repo, |
2157 |
|
vendor=vendor, |
2158 |
|
version=version, |
2159 |
|
) |
2160 |
|
|
2161 |
|
|
2162 |
1 |
@cli_osm.command(name="vnfpkg-create", short_help="creates a new VNFD/VNFpkg") |
2163 |
1 |
@click.argument("filename") |
2164 |
1 |
@click.option( |
2165 |
|
"--overwrite", |
2166 |
|
"overwrite", |
2167 |
|
default=None, # hidden=True, |
2168 |
|
help="Deprecated. Use override", |
2169 |
|
) |
2170 |
1 |
@click.option( |
2171 |
|
"--override", |
2172 |
|
"overwrite", |
2173 |
|
default=None, |
2174 |
|
help="overrides fields in descriptor, format: " |
2175 |
|
'"key1.key2...=value[;key3...=value;...]"', |
2176 |
|
) |
2177 |
1 |
@click.option( |
2178 |
|
"--skip-charm-build", |
2179 |
|
default=False, |
2180 |
|
is_flag=True, |
2181 |
|
help="The charm will not be compiled, it is assumed to already exist", |
2182 |
|
) |
2183 |
1 |
@click.option( |
2184 |
|
"--override-epa", |
2185 |
|
required=False, |
2186 |
|
default=False, |
2187 |
|
is_flag=True, |
2188 |
|
help="adds guest-epa parameters to all VDU", |
2189 |
|
) |
2190 |
1 |
@click.option( |
2191 |
|
"--override-nonepa", |
2192 |
|
required=False, |
2193 |
|
default=False, |
2194 |
|
is_flag=True, |
2195 |
|
help="removes all guest-epa parameters from all VDU", |
2196 |
|
) |
2197 |
1 |
@click.option( |
2198 |
|
"--override-paravirt", |
2199 |
|
required=False, |
2200 |
|
default=False, |
2201 |
|
is_flag=True, |
2202 |
|
help="overrides all VDU interfaces to PARAVIRT", |
2203 |
|
) |
2204 |
1 |
@click.option("--repo", default=None, help="[repository]: Repository name") |
2205 |
1 |
@click.option("--vendor", default=None, help="[repository]: filter by vendor]") |
2206 |
1 |
@click.option( |
2207 |
|
"--version", |
2208 |
|
default="latest", |
2209 |
|
help="[repository]: filter by version. Default: latest", |
2210 |
|
) |
2211 |
1 |
@click.pass_context |
2212 |
1 |
def vnfd_create2( |
2213 |
|
ctx, |
2214 |
|
filename, |
2215 |
|
overwrite, |
2216 |
|
skip_charm_build, |
2217 |
|
override_epa, |
2218 |
|
override_nonepa, |
2219 |
|
override_paravirt, |
2220 |
|
repo, |
2221 |
|
vendor, |
2222 |
|
version, |
2223 |
|
): |
2224 |
|
"""creates a new VNFD/VNFpkg |
2225 |
|
\b |
2226 |
|
FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder |
2227 |
|
If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded. |
2228 |
|
If FILENAME is an NF Package folder, it is built and then onboarded. |
2229 |
|
""" |
2230 |
0 |
logger.debug("") |
2231 |
0 |
vnfd_create( |
2232 |
|
ctx, |
2233 |
|
filename, |
2234 |
|
overwrite=overwrite, |
2235 |
|
skip_charm_build=skip_charm_build, |
2236 |
|
override_epa=override_epa, |
2237 |
|
override_nonepa=override_nonepa, |
2238 |
|
override_paravirt=override_paravirt, |
2239 |
|
repo=repo, |
2240 |
|
vendor=vendor, |
2241 |
|
version=version, |
2242 |
|
) |
2243 |
|
|
2244 |
|
|
2245 |
1 |
@cli_osm.command(name="nfpkg-create", short_help="creates a new NFpkg") |
2246 |
1 |
@click.argument("filename") |
2247 |
1 |
@click.option( |
2248 |
|
"--overwrite", |
2249 |
|
"overwrite", |
2250 |
|
default=None, # hidden=True, |
2251 |
|
help="Deprecated. Use override", |
2252 |
|
) |
2253 |
1 |
@click.option( |
2254 |
|
"--override", |
2255 |
|
"overwrite", |
2256 |
|
default=None, |
2257 |
|
help="overrides fields in descriptor, format: " |
2258 |
|
'"key1.key2...=value[;key3...=value;...]"', |
2259 |
|
) |
2260 |
1 |
@click.option( |
2261 |
|
"--skip-charm-build", |
2262 |
|
default=False, |
2263 |
|
is_flag=True, |
2264 |
|
help="The charm will not be compiled, it is assumed to already exist", |
2265 |
|
) |
2266 |
1 |
@click.option( |
2267 |
|
"--override-epa", |
2268 |
|
required=False, |
2269 |
|
default=False, |
2270 |
|
is_flag=True, |
2271 |
|
help="adds guest-epa parameters to all VDU", |
2272 |
|
) |
2273 |
1 |
@click.option( |
2274 |
|
"--override-nonepa", |
2275 |
|
required=False, |
2276 |
|
default=False, |
2277 |
|
is_flag=True, |
2278 |
|
help="removes all guest-epa parameters from all VDU", |
2279 |
|
) |
2280 |
1 |
@click.option( |
2281 |
|
"--override-paravirt", |
2282 |
|
required=False, |
2283 |
|
default=False, |
2284 |
|
is_flag=True, |
2285 |
|
help="overrides all VDU interfaces to PARAVIRT", |
2286 |
|
) |
2287 |
1 |
@click.option("--repo", default=None, help="[repository]: Repository name") |
2288 |
1 |
@click.option("--vendor", default=None, help="[repository]: filter by vendor]") |
2289 |
1 |
@click.option( |
2290 |
|
"--version", |
2291 |
|
default="latest", |
2292 |
|
help="[repository]: filter by version. Default: latest", |
2293 |
|
) |
2294 |
1 |
@click.pass_context |
2295 |
1 |
def nfpkg_create( |
2296 |
|
ctx, |
2297 |
|
filename, |
2298 |
|
overwrite, |
2299 |
|
skip_charm_build, |
2300 |
|
override_epa, |
2301 |
|
override_nonepa, |
2302 |
|
override_paravirt, |
2303 |
|
repo, |
2304 |
|
vendor, |
2305 |
|
version, |
2306 |
|
): |
2307 |
|
"""creates a new NFpkg |
2308 |
|
|
2309 |
|
\b |
2310 |
|
FILENAME: NF Package tar.gz file, NF Descriptor YAML file or NF Package folder |
2311 |
|
If FILENAME is a file (NF Package tar.gz or NF Descriptor YAML), it is onboarded. |
2312 |
|
If FILENAME is an NF Package folder, it is built and then onboarded. |
2313 |
|
""" |
2314 |
0 |
logger.debug("") |
2315 |
0 |
vnfd_create( |
2316 |
|
ctx, |
2317 |
|
filename, |
2318 |
|
overwrite=overwrite, |
2319 |
|
skip_charm_build=skip_charm_build, |
2320 |
|
override_epa=override_epa, |
2321 |
|
override_nonepa=override_nonepa, |
2322 |
|
override_paravirt=override_paravirt, |
2323 |
|
repo=repo, |
2324 |
|
vendor=vendor, |
2325 |
|
version=version, |
2326 |
|
) |
2327 |
|
|
2328 |
|
|
2329 |
1 |
@cli_osm.command(name="ns-create", short_help="creates a new Network Service instance") |
2330 |
1 |
@click.option("--ns_name", prompt=True, help="name of the NS instance") |
2331 |
1 |
@click.option("--nsd_name", prompt=True, help="name of the NS descriptor") |
2332 |
1 |
@click.option( |
2333 |
|
"--vim_account", |
2334 |
|
prompt=True, |
2335 |
|
help="default VIM account id or name for the deployment", |
2336 |
|
) |
2337 |
1 |
@click.option("--admin_status", default="ENABLED", help="administration status") |
2338 |
1 |
@click.option( |
2339 |
|
"--ssh_keys", |
2340 |
|
default=None, |
2341 |
|
help="comma separated list of public key files to inject to vnfs", |
2342 |
|
) |
2343 |
1 |
@click.option("--config", default=None, help="ns specific yaml configuration") |
2344 |
1 |
@click.option("--config_file", default=None, help="ns specific yaml configuration file") |
2345 |
1 |
@click.option( |
2346 |
|
"--wait", |
2347 |
|
required=False, |
2348 |
|
default=False, |
2349 |
|
is_flag=True, |
2350 |
|
help="do not return the control immediately, but keep it " |
2351 |
|
"until the operation is completed, or timeout", |
2352 |
|
) |
2353 |
1 |
@click.pass_context |
2354 |
1 |
def ns_create( |
2355 |
|
ctx, |
2356 |
|
nsd_name, |
2357 |
|
ns_name, |
2358 |
|
vim_account, |
2359 |
|
admin_status, |
2360 |
|
ssh_keys, |
2361 |
|
config, |
2362 |
|
config_file, |
2363 |
|
wait, |
2364 |
|
): |
2365 |
|
"""creates a new NS instance""" |
2366 |
0 |
logger.debug("") |
2367 |
|
# try: |
2368 |
0 |
if config_file: |
2369 |
0 |
check_client_version(ctx.obj, "--config_file") |
2370 |
0 |
if config: |
2371 |
0 |
raise ClientException( |
2372 |
|
'"--config" option is incompatible with "--config_file" option' |
2373 |
|
) |
2374 |
0 |
with open(config_file, "r") as cf: |
2375 |
0 |
config = cf.read() |
2376 |
0 |
ctx.obj.ns.create( |
2377 |
|
nsd_name, |
2378 |
|
ns_name, |
2379 |
|
config=config, |
2380 |
|
ssh_keys=ssh_keys, |
2381 |
|
account=vim_account, |
2382 |
|
wait=wait, |
2383 |
|
) |
2384 |
|
# except ClientException as e: |
2385 |
|
# print(str(e)) |
2386 |
|
# exit(1) |
2387 |
|
|
2388 |
|
|
2389 |
1 |
def nst_create(ctx, filename, overwrite): |
2390 |
0 |
logger.debug("") |
2391 |
|
# try: |
2392 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2393 |
0 |
ctx.obj.nst.create(filename, overwrite) |
2394 |
|
# except ClientException as e: |
2395 |
|
# print(str(e)) |
2396 |
|
# exit(1) |
2397 |
|
|
2398 |
|
|
2399 |
1 |
@cli_osm.command( |
2400 |
|
name="nst-create", short_help="creates a new Network Slice Template (NST)" |
2401 |
|
) |
2402 |
1 |
@click.argument("filename") |
2403 |
1 |
@click.option( |
2404 |
|
"--overwrite", |
2405 |
|
"overwrite", |
2406 |
|
default=None, # hidden=True, |
2407 |
|
help="Deprecated. Use override", |
2408 |
|
) |
2409 |
1 |
@click.option( |
2410 |
|
"--override", |
2411 |
|
"overwrite", |
2412 |
|
default=None, |
2413 |
|
help="overrides fields in descriptor, format: " |
2414 |
|
'"key1.key2...=value[;key3...=value;...]"', |
2415 |
|
) |
2416 |
1 |
@click.pass_context |
2417 |
1 |
def nst_create1(ctx, filename, overwrite): |
2418 |
|
"""creates a new Network Slice Template (NST) |
2419 |
|
|
2420 |
|
FILENAME: NST package folder, NST yaml file or NSTpkg tar.gz file |
2421 |
|
""" |
2422 |
0 |
logger.debug("") |
2423 |
0 |
nst_create(ctx, filename, overwrite) |
2424 |
|
|
2425 |
|
|
2426 |
1 |
@cli_osm.command( |
2427 |
|
name="netslice-template-create", |
2428 |
|
short_help="creates a new Network Slice Template (NST)", |
2429 |
|
) |
2430 |
1 |
@click.argument("filename") |
2431 |
1 |
@click.option( |
2432 |
|
"--overwrite", |
2433 |
|
"overwrite", |
2434 |
|
default=None, # hidden=True, |
2435 |
|
help="Deprecated. Use override", |
2436 |
|
) |
2437 |
1 |
@click.option( |
2438 |
|
"--override", |
2439 |
|
"overwrite", |
2440 |
|
default=None, |
2441 |
|
help="overrides fields in descriptor, format: " |
2442 |
|
'"key1.key2...=value[;key3...=value;...]"', |
2443 |
|
) |
2444 |
1 |
@click.pass_context |
2445 |
1 |
def nst_create2(ctx, filename, overwrite): |
2446 |
|
"""creates a new Network Slice Template (NST) |
2447 |
|
|
2448 |
|
FILENAME: NST yaml file or NSTpkg tar.gz file |
2449 |
|
""" |
2450 |
0 |
logger.debug("") |
2451 |
0 |
nst_create(ctx, filename, overwrite) |
2452 |
|
|
2453 |
|
|
2454 |
1 |
def nsi_create( |
2455 |
|
ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file, wait |
2456 |
|
): |
2457 |
|
"""creates a new Network Slice Instance (NSI)""" |
2458 |
0 |
logger.debug("") |
2459 |
|
# try: |
2460 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2461 |
0 |
if config_file: |
2462 |
0 |
if config: |
2463 |
0 |
raise ClientException( |
2464 |
|
'"--config" option is incompatible with "--config_file" option' |
2465 |
|
) |
2466 |
0 |
with open(config_file, "r") as cf: |
2467 |
0 |
config = cf.read() |
2468 |
0 |
ctx.obj.nsi.create( |
2469 |
|
nst_name, |
2470 |
|
nsi_name, |
2471 |
|
config=config, |
2472 |
|
ssh_keys=ssh_keys, |
2473 |
|
account=vim_account, |
2474 |
|
wait=wait, |
2475 |
|
) |
2476 |
|
# except ClientException as e: |
2477 |
|
# print(str(e)) |
2478 |
|
# exit(1) |
2479 |
|
|
2480 |
|
|
2481 |
1 |
@cli_osm.command(name="nsi-create", short_help="creates a new Network Slice Instance") |
2482 |
1 |
@click.option("--nsi_name", prompt=True, help="name of the Network Slice Instance") |
2483 |
1 |
@click.option("--nst_name", prompt=True, help="name of the Network Slice Template") |
2484 |
1 |
@click.option( |
2485 |
|
"--vim_account", |
2486 |
|
prompt=True, |
2487 |
|
help="default VIM account id or name for the deployment", |
2488 |
|
) |
2489 |
1 |
@click.option( |
2490 |
|
"--ssh_keys", default=None, help="comma separated list of keys to inject to vnfs" |
2491 |
|
) |
2492 |
1 |
@click.option( |
2493 |
|
"--config", |
2494 |
|
default=None, |
2495 |
|
help="Netslice specific yaml configuration:\n" |
2496 |
|
"netslice_subnet: [\n" |
2497 |
|
"id: TEXT, vim_account: TEXT,\n" |
2498 |
|
"vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n" |
2499 |
|
"vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]\n" |
2500 |
|
"additionalParamsForNsi: {param: value, ...}\n" |
2501 |
|
"additionalParamsForsubnet: [{id: SUBNET_ID, additionalParamsForNs: {}, additionalParamsForVnf: {}}]\n" |
2502 |
|
"],\n" |
2503 |
|
"netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]", |
2504 |
|
) |
2505 |
1 |
@click.option( |
2506 |
|
"--config_file", default=None, help="nsi specific yaml configuration file" |
2507 |
|
) |
2508 |
1 |
@click.option( |
2509 |
|
"--wait", |
2510 |
|
required=False, |
2511 |
|
default=False, |
2512 |
|
is_flag=True, |
2513 |
|
help="do not return the control immediately, but keep it " |
2514 |
|
"until the operation is completed, or timeout", |
2515 |
|
) |
2516 |
1 |
@click.pass_context |
2517 |
1 |
def nsi_create1( |
2518 |
|
ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file, wait |
2519 |
|
): |
2520 |
|
"""creates a new Network Slice Instance (NSI)""" |
2521 |
0 |
logger.debug("") |
2522 |
0 |
nsi_create( |
2523 |
|
ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file, wait=wait |
2524 |
|
) |
2525 |
|
|
2526 |
|
|
2527 |
1 |
@cli_osm.command( |
2528 |
|
name="netslice-instance-create", short_help="creates a new Network Slice Instance" |
2529 |
|
) |
2530 |
1 |
@click.option("--nsi_name", prompt=True, help="name of the Network Slice Instance") |
2531 |
1 |
@click.option("--nst_name", prompt=True, help="name of the Network Slice Template") |
2532 |
1 |
@click.option( |
2533 |
|
"--vim_account", |
2534 |
|
prompt=True, |
2535 |
|
help="default VIM account id or name for the deployment", |
2536 |
|
) |
2537 |
1 |
@click.option( |
2538 |
|
"--ssh_keys", default=None, help="comma separated list of keys to inject to vnfs" |
2539 |
|
) |
2540 |
1 |
@click.option( |
2541 |
|
"--config", |
2542 |
|
default=None, |
2543 |
|
help="Netslice specific yaml configuration:\n" |
2544 |
|
"netslice_subnet: [\n" |
2545 |
|
"id: TEXT, vim_account: TEXT,\n" |
2546 |
|
"vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n" |
2547 |
|
"vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]" |
2548 |
|
"],\n" |
2549 |
|
"netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]", |
2550 |
|
) |
2551 |
1 |
@click.option( |
2552 |
|
"--config_file", default=None, help="nsi specific yaml configuration file" |
2553 |
|
) |
2554 |
1 |
@click.option( |
2555 |
|
"--wait", |
2556 |
|
required=False, |
2557 |
|
default=False, |
2558 |
|
is_flag=True, |
2559 |
|
help="do not return the control immediately, but keep it " |
2560 |
|
"until the operation is completed, or timeout", |
2561 |
|
) |
2562 |
1 |
@click.pass_context |
2563 |
1 |
def nsi_create2( |
2564 |
|
ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file, wait |
2565 |
|
): |
2566 |
|
"""creates a new Network Slice Instance (NSI)""" |
2567 |
0 |
logger.debug("") |
2568 |
0 |
nsi_create( |
2569 |
|
ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file, wait=wait |
2570 |
|
) |
2571 |
|
|
2572 |
|
|
2573 |
1 |
@cli_osm.command( |
2574 |
|
name="pdu-create", short_help="adds a new Physical Deployment Unit to the catalog" |
2575 |
|
) |
2576 |
1 |
@click.option("--name", help="name of the Physical Deployment Unit") |
2577 |
1 |
@click.option("--pdu_type", help="type of PDU (e.g. router, firewall, FW001)") |
2578 |
1 |
@click.option( |
2579 |
|
"--interface", |
2580 |
|
help="interface(s) of the PDU: name=<NAME>,mgmt=<true|false>,ip-address=<IP_ADDRESS>" |
2581 |
|
+ "[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]", |
2582 |
|
multiple=True, |
2583 |
|
) |
2584 |
1 |
@click.option("--description", help="human readable description") |
2585 |
1 |
@click.option( |
2586 |
|
"--vim_account", |
2587 |
|
help="list of VIM accounts (in the same VIM) that can reach this PDU\n" |
2588 |
|
+ "The format for multiple VIMs is --vim_account <vim_account_id_1> " |
2589 |
|
+ "--vim_account <vim_account_id_2> ... --vim_account <vim_account_id_N>", |
2590 |
|
multiple=True, |
2591 |
|
) |
2592 |
1 |
@click.option( |
2593 |
|
"--descriptor_file", |
2594 |
|
default=None, |
2595 |
|
help="PDU descriptor file (as an alternative to using the other arguments)", |
2596 |
|
) |
2597 |
1 |
@click.pass_context |
2598 |
1 |
def pdu_create( |
2599 |
|
ctx, name, pdu_type, interface, description, vim_account, descriptor_file |
2600 |
|
): |
2601 |
|
"""creates a new Physical Deployment Unit (PDU)""" |
2602 |
0 |
logger.debug("") |
2603 |
|
|
2604 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2605 |
|
|
2606 |
0 |
pdu = create_pdu_dictionary( |
2607 |
|
name, pdu_type, interface, description, vim_account, descriptor_file |
2608 |
|
) |
2609 |
0 |
ctx.obj.pdu.create(pdu) |
2610 |
|
|
2611 |
|
|
2612 |
|
######################## |
2613 |
|
# UPDATE PDU operation # |
2614 |
|
######################## |
2615 |
|
|
2616 |
|
|
2617 |
1 |
@cli_osm.command( |
2618 |
|
name="pdu-update", short_help="updates a Physical Deployment Unit to the catalog" |
2619 |
|
) |
2620 |
1 |
@click.argument("name") |
2621 |
1 |
@click.option("--newname", help="New name for the Physical Deployment Unit") |
2622 |
1 |
@click.option("--pdu_type", help="type of PDU (e.g. router, firewall, FW001)") |
2623 |
1 |
@click.option( |
2624 |
|
"--interface", |
2625 |
|
help="interface(s) of the PDU: name=<NAME>,mgmt=<true|false>,ip-address=<IP_ADDRESS>" |
2626 |
|
+ "[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]", |
2627 |
|
multiple=True, |
2628 |
|
) |
2629 |
1 |
@click.option("--description", help="human readable description") |
2630 |
1 |
@click.option( |
2631 |
|
"--vim_account", |
2632 |
|
help="list of VIM accounts (in the same VIM) that can reach this PDU\n" |
2633 |
|
+ "The format for multiple VIMs is --vim_account <vim_account_id_1> " |
2634 |
|
+ "--vim_account <vim_account_id_2> ... --vim_account <vim_account_id_N>", |
2635 |
|
multiple=True, |
2636 |
|
) |
2637 |
1 |
@click.option( |
2638 |
|
"--descriptor_file", |
2639 |
|
default=None, |
2640 |
|
help="PDU descriptor file (as an alternative to using the other arguments)", |
2641 |
|
) |
2642 |
1 |
@click.pass_context |
2643 |
1 |
def pdu_update( |
2644 |
|
ctx, name, newname, pdu_type, interface, description, vim_account, descriptor_file |
2645 |
|
): |
2646 |
|
"""Updates a new Physical Deployment Unit (PDU)""" |
2647 |
0 |
logger.debug("") |
2648 |
|
|
2649 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2650 |
|
|
2651 |
0 |
update = True |
2652 |
|
|
2653 |
0 |
if not newname: |
2654 |
0 |
newname = name |
2655 |
|
|
2656 |
0 |
pdu = create_pdu_dictionary( |
2657 |
|
newname, pdu_type, interface, description, vim_account, descriptor_file, update |
2658 |
|
) |
2659 |
0 |
ctx.obj.pdu.update(name, pdu) |
2660 |
|
|
2661 |
|
|
2662 |
1 |
def create_pdu_dictionary( |
2663 |
|
name, pdu_type, interface, description, vim_account, descriptor_file, update=False |
2664 |
|
): |
2665 |
|
|
2666 |
0 |
logger.debug("") |
2667 |
0 |
pdu = {} |
2668 |
|
|
2669 |
0 |
if not descriptor_file: |
2670 |
0 |
if not update: |
2671 |
0 |
if not name: |
2672 |
0 |
raise ClientException( |
2673 |
|
'in absence of descriptor file, option "--name" is mandatory' |
2674 |
|
) |
2675 |
0 |
if not pdu_type: |
2676 |
0 |
raise ClientException( |
2677 |
|
'in absence of descriptor file, option "--pdu_type" is mandatory' |
2678 |
|
) |
2679 |
0 |
if not interface: |
2680 |
0 |
raise ClientException( |
2681 |
|
'in absence of descriptor file, option "--interface" is mandatory (at least once)' |
2682 |
|
) |
2683 |
0 |
if not vim_account: |
2684 |
0 |
raise ClientException( |
2685 |
|
'in absence of descriptor file, option "--vim_account" is mandatory (at least once)' |
2686 |
|
) |
2687 |
|
else: |
2688 |
0 |
with open(descriptor_file, "r") as df: |
2689 |
0 |
pdu = yaml.safe_load(df.read()) |
2690 |
0 |
if name: |
2691 |
0 |
pdu["name"] = name |
2692 |
0 |
if pdu_type: |
2693 |
0 |
pdu["type"] = pdu_type |
2694 |
0 |
if description: |
2695 |
0 |
pdu["description"] = description |
2696 |
0 |
if vim_account: |
2697 |
0 |
pdu["vim_accounts"] = vim_account |
2698 |
0 |
if interface: |
2699 |
0 |
ifaces_list = [] |
2700 |
0 |
for iface in interface: |
2701 |
0 |
new_iface = {k: v for k, v in [i.split("=") for i in iface.split(",")]} |
2702 |
0 |
new_iface["mgmt"] = new_iface.get("mgmt", "false").lower() == "true" |
2703 |
0 |
ifaces_list.append(new_iface) |
2704 |
0 |
pdu["interfaces"] = ifaces_list |
2705 |
0 |
return pdu |
2706 |
|
|
2707 |
|
|
2708 |
|
#################### |
2709 |
|
# UPDATE operations |
2710 |
|
#################### |
2711 |
|
|
2712 |
|
|
2713 |
1 |
def nsd_update(ctx, name, content): |
2714 |
0 |
logger.debug("") |
2715 |
|
# try: |
2716 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2717 |
0 |
ctx.obj.nsd.update(name, content) |
2718 |
|
# except ClientException as e: |
2719 |
|
# print(str(e)) |
2720 |
|
# exit(1) |
2721 |
|
|
2722 |
|
|
2723 |
1 |
@cli_osm.command(name="nsd-update", short_help="updates a NSD/NSpkg") |
2724 |
1 |
@click.argument("name") |
2725 |
1 |
@click.option( |
2726 |
|
"--content", |
2727 |
|
default=None, |
2728 |
|
help="filename with the NSD/NSpkg replacing the current one", |
2729 |
|
) |
2730 |
1 |
@click.pass_context |
2731 |
1 |
def nsd_update1(ctx, name, content): |
2732 |
|
"""updates a NSD/NSpkg |
2733 |
|
|
2734 |
|
NAME: name or ID of the NSD/NSpkg |
2735 |
|
""" |
2736 |
0 |
logger.debug("") |
2737 |
0 |
nsd_update(ctx, name, content) |
2738 |
|
|
2739 |
|
|
2740 |
1 |
@cli_osm.command(name="nspkg-update", short_help="updates a NSD/NSpkg") |
2741 |
1 |
@click.argument("name") |
2742 |
1 |
@click.option( |
2743 |
|
"--content", |
2744 |
|
default=None, |
2745 |
|
help="filename with the NSD/NSpkg replacing the current one", |
2746 |
|
) |
2747 |
1 |
@click.pass_context |
2748 |
1 |
def nsd_update2(ctx, name, content): |
2749 |
|
"""updates a NSD/NSpkg |
2750 |
|
|
2751 |
|
NAME: name or ID of the NSD/NSpkg |
2752 |
|
""" |
2753 |
0 |
logger.debug("") |
2754 |
0 |
nsd_update(ctx, name, content) |
2755 |
|
|
2756 |
|
|
2757 |
1 |
def vnfd_update(ctx, name, content): |
2758 |
0 |
logger.debug("") |
2759 |
|
# try: |
2760 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2761 |
0 |
ctx.obj.vnfd.update(name, content) |
2762 |
|
# except ClientException as e: |
2763 |
|
# print(str(e)) |
2764 |
|
# exit(1) |
2765 |
|
|
2766 |
|
|
2767 |
1 |
@cli_osm.command(name="vnfd-update", short_help="updates a new VNFD/VNFpkg") |
2768 |
1 |
@click.argument("name") |
2769 |
1 |
@click.option( |
2770 |
|
"--content", |
2771 |
|
default=None, |
2772 |
|
help="filename with the VNFD/VNFpkg replacing the current one", |
2773 |
|
) |
2774 |
1 |
@click.pass_context |
2775 |
1 |
def vnfd_update1(ctx, name, content): |
2776 |
|
"""updates a VNFD/VNFpkg |
2777 |
|
|
2778 |
|
NAME: name or ID of the VNFD/VNFpkg |
2779 |
|
""" |
2780 |
0 |
logger.debug("") |
2781 |
0 |
vnfd_update(ctx, name, content) |
2782 |
|
|
2783 |
|
|
2784 |
1 |
@cli_osm.command(name="vnfpkg-update", short_help="updates a VNFD/VNFpkg") |
2785 |
1 |
@click.argument("name") |
2786 |
1 |
@click.option( |
2787 |
|
"--content", |
2788 |
|
default=None, |
2789 |
|
help="filename with the VNFD/VNFpkg replacing the current one", |
2790 |
|
) |
2791 |
1 |
@click.pass_context |
2792 |
1 |
def vnfd_update2(ctx, name, content): |
2793 |
|
"""updates a VNFD/VNFpkg |
2794 |
|
|
2795 |
|
NAME: VNFD yaml file or VNFpkg tar.gz file |
2796 |
|
""" |
2797 |
0 |
logger.debug("") |
2798 |
0 |
vnfd_update(ctx, name, content) |
2799 |
|
|
2800 |
|
|
2801 |
1 |
@cli_osm.command(name="nfpkg-update", short_help="updates a NFpkg") |
2802 |
1 |
@click.argument("name") |
2803 |
1 |
@click.option( |
2804 |
|
"--content", default=None, help="filename with the NFpkg replacing the current one" |
2805 |
|
) |
2806 |
1 |
@click.pass_context |
2807 |
1 |
def nfpkg_update(ctx, name, content): |
2808 |
|
"""updates a NFpkg |
2809 |
|
|
2810 |
|
NAME: NF Descriptor yaml file or NFpkg tar.gz file |
2811 |
|
""" |
2812 |
0 |
logger.debug("") |
2813 |
0 |
vnfd_update(ctx, name, content) |
2814 |
|
|
2815 |
|
|
2816 |
1 |
def nst_update(ctx, name, content): |
2817 |
0 |
logger.debug("") |
2818 |
|
# try: |
2819 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
2820 |
0 |
ctx.obj.nst.update(name, content) |
2821 |
|
# except ClientException as e: |
2822 |
|
# print(str(e)) |
2823 |
|
# exit(1) |
2824 |
|
|
2825 |
|
|
2826 |
1 |
@cli_osm.command(name="nst-update", short_help="updates a Network Slice Template (NST)") |
2827 |
1 |
@click.argument("name") |
2828 |
1 |
@click.option( |
2829 |
|
"--content", |
2830 |
|
default=None, |
2831 |
|
help="filename with the NST/NSTpkg replacing the current one", |
2832 |
|
) |
2833 |
1 |
@click.pass_context |
2834 |
1 |
def nst_update1(ctx, name, content): |
2835 |
|
"""updates a Network Slice Template (NST) |
2836 |
|
|
2837 |
|
NAME: name or ID of the NSD/NSpkg |
2838 |
|
""" |
2839 |
0 |
logger.debug("") |
2840 |
0 |
nst_update(ctx, name, content) |
2841 |
|
|
2842 |
|
|
2843 |
1 |
@cli_osm.command( |
2844 |
|
name="netslice-template-update", short_help="updates a Network Slice Template (NST)" |
2845 |
|
) |
2846 |
1 |
@click.argument("name") |
2847 |
1 |
@click.option( |
2848 |
|
"--content", |
2849 |
|
default=None, |
2850 |
|
help="filename with the NST/NSTpkg replacing the current one", |
2851 |
|
) |
2852 |
1 |
@click.pass_context |
2853 |
1 |
def nst_update2(ctx, name, content): |
2854 |
|
"""updates a Network Slice Template (NST) |
2855 |
|
|
2856 |
|
NAME: name or ID of the NSD/NSpkg |
2857 |
|
""" |
2858 |
0 |
logger.debug("") |
2859 |
0 |
nst_update(ctx, name, content) |
2860 |
|
|
2861 |
|
|
2862 |
|
#################### |
2863 |
|
# DELETE operations |
2864 |
|
#################### |
2865 |
|
|
2866 |
|
|
2867 |
1 |
def nsd_delete(ctx, name, force): |
2868 |
0 |
logger.debug("") |
2869 |
|
# try: |
2870 |
0 |
if not force: |
2871 |
0 |
ctx.obj.nsd.delete(name) |
2872 |
|
else: |
2873 |
0 |
check_client_version(ctx.obj, "--force") |
2874 |
0 |
ctx.obj.nsd.delete(name, force) |
2875 |
|
# except ClientException as e: |
2876 |
|
# print(str(e)) |
2877 |
|
# exit(1) |
2878 |
|
|
2879 |
|
|
2880 |
1 |
@cli_osm.command(name="nsd-delete", short_help="deletes a NSD/NSpkg") |
2881 |
1 |
@click.argument("name") |
2882 |
1 |
@click.option( |
2883 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
2884 |
|
) |
2885 |
1 |
@click.pass_context |
2886 |
1 |
def nsd_delete1(ctx, name, force): |
2887 |
|
"""deletes a NSD/NSpkg |
2888 |
|
|
2889 |
|
NAME: name or ID of the NSD/NSpkg to be deleted |
2890 |
|
""" |
2891 |
0 |
logger.debug("") |
2892 |
0 |
nsd_delete(ctx, name, force) |
2893 |
|
|
2894 |
|
|
2895 |
1 |
@cli_osm.command(name="nspkg-delete", short_help="deletes a NSD/NSpkg") |
2896 |
1 |
@click.argument("name") |
2897 |
1 |
@click.option( |
2898 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
2899 |
|
) |
2900 |
1 |
@click.pass_context |
2901 |
1 |
def nsd_delete2(ctx, name, force): |
2902 |
|
"""deletes a NSD/NSpkg |
2903 |
|
|
2904 |
|
NAME: name or ID of the NSD/NSpkg to be deleted |
2905 |
|
""" |
2906 |
0 |
logger.debug("") |
2907 |
0 |
nsd_delete(ctx, name, force) |
2908 |
|
|
2909 |
|
|
2910 |
1 |
def vnfd_delete(ctx, name, force): |
2911 |
0 |
logger.debug("") |
2912 |
|
# try: |
2913 |
0 |
if not force: |
2914 |
0 |
ctx.obj.vnfd.delete(name) |
2915 |
|
else: |
2916 |
0 |
check_client_version(ctx.obj, "--force") |
2917 |
0 |
ctx.obj.vnfd.delete(name, force) |
2918 |
|
# except ClientException as e: |
2919 |
|
# print(str(e)) |
2920 |
|
# exit(1) |
2921 |
|
|
2922 |
|
|
2923 |
1 |
@cli_osm.command(name="vnfd-delete", short_help="deletes a VNFD/VNFpkg") |
2924 |
1 |
@click.argument("name") |
2925 |
1 |
@click.option( |
2926 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
2927 |
|
) |
2928 |
1 |
@click.pass_context |
2929 |
1 |
def vnfd_delete1(ctx, name, force): |
2930 |
|
"""deletes a VNFD/VNFpkg |
2931 |
|
|
2932 |
|
NAME: name or ID of the VNFD/VNFpkg to be deleted |
2933 |
|
""" |
2934 |
0 |
logger.debug("") |
2935 |
0 |
vnfd_delete(ctx, name, force) |
2936 |
|
|
2937 |
|
|
2938 |
1 |
@cli_osm.command(name="vnfpkg-delete", short_help="deletes a VNFD/VNFpkg") |
2939 |
1 |
@click.argument("name") |
2940 |
1 |
@click.option( |
2941 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
2942 |
|
) |
2943 |
1 |
@click.pass_context |
2944 |
1 |
def vnfd_delete2(ctx, name, force): |
2945 |
|
"""deletes a VNFD/VNFpkg |
2946 |
|
|
2947 |
|
NAME: name or ID of the VNFD/VNFpkg to be deleted |
2948 |
|
""" |
2949 |
0 |
logger.debug("") |
2950 |
0 |
vnfd_delete(ctx, name, force) |
2951 |
|
|
2952 |
|
|
2953 |
1 |
@cli_osm.command(name="nfpkg-delete", short_help="deletes a NFpkg") |
2954 |
1 |
@click.argument("name") |
2955 |
1 |
@click.option( |
2956 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
2957 |
|
) |
2958 |
1 |
@click.pass_context |
2959 |
1 |
def nfpkg_delete(ctx, name, force): |
2960 |
|
"""deletes a NFpkg |
2961 |
|
|
2962 |
|
NAME: name or ID of the NFpkg to be deleted |
2963 |
|
""" |
2964 |
0 |
logger.debug("") |
2965 |
0 |
vnfd_delete(ctx, name, force) |
2966 |
|
|
2967 |
|
|
2968 |
1 |
@cli_osm.command(name="ns-delete", short_help="deletes a NS instance") |
2969 |
1 |
@click.argument("name") |
2970 |
1 |
@click.option( |
2971 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
2972 |
|
) |
2973 |
1 |
@click.option( |
2974 |
|
"--config", |
2975 |
|
default=None, |
2976 |
|
help="specific yaml configuration for the termination, e.g. '{autoremove: False, timeout_ns_terminate: " |
2977 |
|
"600, skip_terminate_primitives: True}'", |
2978 |
|
) |
2979 |
1 |
@click.option( |
2980 |
|
"--wait", |
2981 |
|
required=False, |
2982 |
|
default=False, |
2983 |
|
is_flag=True, |
2984 |
|
help="do not return the control immediately, but keep it " |
2985 |
|
"until the operation is completed, or timeout", |
2986 |
|
) |
2987 |
1 |
@click.pass_context |
2988 |
1 |
def ns_delete(ctx, name, force, config, wait): |
2989 |
|
"""deletes a NS instance |
2990 |
|
|
2991 |
|
NAME: name or ID of the NS instance to be deleted |
2992 |
|
""" |
2993 |
0 |
logger.debug("") |
2994 |
|
# try: |
2995 |
0 |
if not force: |
2996 |
0 |
ctx.obj.ns.delete(name, config=config, wait=wait) |
2997 |
|
else: |
2998 |
0 |
check_client_version(ctx.obj, "--force") |
2999 |
0 |
ctx.obj.ns.delete(name, force, config=config, wait=wait) |
3000 |
|
# except ClientException as e: |
3001 |
|
# print(str(e)) |
3002 |
|
# exit(1) |
3003 |
|
|
3004 |
|
|
3005 |
1 |
def nst_delete(ctx, name, force): |
3006 |
0 |
logger.debug("") |
3007 |
|
# try: |
3008 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3009 |
0 |
ctx.obj.nst.delete(name, force) |
3010 |
|
# except ClientException as e: |
3011 |
|
# print(str(e)) |
3012 |
|
# exit(1) |
3013 |
|
|
3014 |
|
|
3015 |
1 |
@cli_osm.command(name="nst-delete", short_help="deletes a Network Slice Template (NST)") |
3016 |
1 |
@click.argument("name") |
3017 |
1 |
@click.option( |
3018 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
3019 |
|
) |
3020 |
1 |
@click.pass_context |
3021 |
1 |
def nst_delete1(ctx, name, force): |
3022 |
|
"""deletes a Network Slice Template (NST) |
3023 |
|
|
3024 |
|
NAME: name or ID of the NST/NSTpkg to be deleted |
3025 |
|
""" |
3026 |
0 |
logger.debug("") |
3027 |
0 |
nst_delete(ctx, name, force) |
3028 |
|
|
3029 |
|
|
3030 |
1 |
@cli_osm.command( |
3031 |
|
name="netslice-template-delete", short_help="deletes a Network Slice Template (NST)" |
3032 |
|
) |
3033 |
1 |
@click.argument("name") |
3034 |
1 |
@click.option( |
3035 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
3036 |
|
) |
3037 |
1 |
@click.pass_context |
3038 |
1 |
def nst_delete2(ctx, name, force): |
3039 |
|
"""deletes a Network Slice Template (NST) |
3040 |
|
|
3041 |
|
NAME: name or ID of the NST/NSTpkg to be deleted |
3042 |
|
""" |
3043 |
0 |
logger.debug("") |
3044 |
0 |
nst_delete(ctx, name, force) |
3045 |
|
|
3046 |
|
|
3047 |
1 |
def nsi_delete(ctx, name, force, wait): |
3048 |
0 |
logger.debug("") |
3049 |
|
# try: |
3050 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3051 |
0 |
ctx.obj.nsi.delete(name, force, wait=wait) |
3052 |
|
# except ClientException as e: |
3053 |
|
# print(str(e)) |
3054 |
|
# exit(1) |
3055 |
|
|
3056 |
|
|
3057 |
1 |
@cli_osm.command(name="nsi-delete", short_help="deletes a Network Slice Instance (NSI)") |
3058 |
1 |
@click.argument("name") |
3059 |
1 |
@click.option( |
3060 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
3061 |
|
) |
3062 |
1 |
@click.option( |
3063 |
|
"--wait", |
3064 |
|
required=False, |
3065 |
|
default=False, |
3066 |
|
is_flag=True, |
3067 |
|
help="do not return the control immediately, but keep it " |
3068 |
|
"until the operation is completed, or timeout", |
3069 |
|
) |
3070 |
1 |
@click.pass_context |
3071 |
1 |
def nsi_delete1(ctx, name, force, wait): |
3072 |
|
"""deletes a Network Slice Instance (NSI) |
3073 |
|
|
3074 |
|
NAME: name or ID of the Network Slice instance to be deleted |
3075 |
|
""" |
3076 |
0 |
logger.debug("") |
3077 |
0 |
nsi_delete(ctx, name, force, wait=wait) |
3078 |
|
|
3079 |
|
|
3080 |
1 |
@cli_osm.command( |
3081 |
|
name="netslice-instance-delete", short_help="deletes a Network Slice Instance (NSI)" |
3082 |
|
) |
3083 |
1 |
@click.argument("name") |
3084 |
1 |
@click.option( |
3085 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
3086 |
|
) |
3087 |
1 |
@click.pass_context |
3088 |
1 |
def nsi_delete2(ctx, name, force, wait): |
3089 |
|
"""deletes a Network Slice Instance (NSI) |
3090 |
|
|
3091 |
|
NAME: name or ID of the Network Slice instance to be deleted |
3092 |
|
""" |
3093 |
0 |
logger.debug("") |
3094 |
0 |
nsi_delete(ctx, name, force, wait=wait) |
3095 |
|
|
3096 |
|
|
3097 |
1 |
@cli_osm.command( |
3098 |
|
name="pdu-delete", short_help="deletes a Physical Deployment Unit (PDU)" |
3099 |
|
) |
3100 |
1 |
@click.argument("name") |
3101 |
1 |
@click.option( |
3102 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
3103 |
|
) |
3104 |
1 |
@click.pass_context |
3105 |
1 |
def pdu_delete(ctx, name, force): |
3106 |
|
"""deletes a Physical Deployment Unit (PDU) |
3107 |
|
|
3108 |
|
NAME: name or ID of the PDU to be deleted |
3109 |
|
""" |
3110 |
0 |
logger.debug("") |
3111 |
|
# try: |
3112 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3113 |
0 |
ctx.obj.pdu.delete(name, force) |
3114 |
|
# except ClientException as e: |
3115 |
|
# print(str(e)) |
3116 |
|
# exit(1) |
3117 |
|
|
3118 |
|
|
3119 |
|
################# |
3120 |
|
# VIM operations |
3121 |
|
################# |
3122 |
|
|
3123 |
|
|
3124 |
1 |
@cli_osm.command(name="vim-create", short_help="creates a new VIM account") |
3125 |
1 |
@click.option("--name", required=True, help="Name to create datacenter") |
3126 |
1 |
@click.option("--user", default=None, help="VIM username") |
3127 |
1 |
@click.option("--password", default=None, help="VIM password") |
3128 |
1 |
@click.option("--auth_url", default=None, help="VIM url") |
3129 |
1 |
@click.option("--tenant", "--project", "tenant", default=None, help="VIM tenant/project name") |
3130 |
1 |
@click.option("--config", default=None, help="VIM specific config parameters") |
3131 |
1 |
@click.option("--config_file", default=None, help="VIM specific config parameters in YAML or JSON file") |
3132 |
1 |
@click.option("--account_type", default="openstack", help="VIM type") |
3133 |
1 |
@click.option("--description", default=None, help="human readable description") |
3134 |
1 |
@click.option( |
3135 |
|
"--sdn_controller", |
3136 |
|
default=None, |
3137 |
|
help="Name or id of the SDN controller associated to this VIM account", |
3138 |
|
) |
3139 |
1 |
@click.option( |
3140 |
|
"--sdn_port_mapping", |
3141 |
|
default=None, |
3142 |
|
help="File describing the port mapping between compute nodes' ports and switch ports", |
3143 |
|
) |
3144 |
1 |
@click.option( |
3145 |
|
"--wait", |
3146 |
|
required=False, |
3147 |
|
default=False, |
3148 |
|
is_flag=True, |
3149 |
|
help="do not return the control immediately, but keep it " |
3150 |
|
"until the operation is completed, or timeout", |
3151 |
|
) |
3152 |
1 |
@click.option("--vca", default=None, help="VCA to be used in this VIM account") |
3153 |
1 |
@click.option("--creds", default=None, help="credentials file (only applycable for GCP VIM type)") |
3154 |
1 |
@click.pass_context |
3155 |
1 |
def vim_create( |
3156 |
|
ctx, |
3157 |
|
name, |
3158 |
|
user, |
3159 |
|
password, |
3160 |
|
auth_url, |
3161 |
|
tenant, |
3162 |
|
config, |
3163 |
|
config_file, |
3164 |
|
account_type, |
3165 |
|
description, |
3166 |
|
sdn_controller, |
3167 |
|
sdn_port_mapping, |
3168 |
|
wait, |
3169 |
|
vca, |
3170 |
|
creds, |
3171 |
|
): |
3172 |
|
"""creates a new VIM account""" |
3173 |
0 |
logger.debug("") |
3174 |
|
# try: |
3175 |
0 |
if sdn_controller: |
3176 |
0 |
check_client_version(ctx.obj, "--sdn_controller") |
3177 |
0 |
if sdn_port_mapping: |
3178 |
0 |
check_client_version(ctx.obj, "--sdn_port_mapping") |
3179 |
0 |
vim = {} |
3180 |
0 |
vim["vim-username"] = user |
3181 |
0 |
vim["vim-password"] = password |
3182 |
0 |
vim["vim-url"] = auth_url |
3183 |
0 |
vim["vim-tenant-name"] = tenant |
3184 |
0 |
vim["vim-type"] = account_type |
3185 |
0 |
vim["description"] = description |
3186 |
0 |
if vca: |
3187 |
0 |
vim["vca"] = vca |
3188 |
0 |
vim_config = create_config(config_file, config) |
3189 |
0 |
if creds: |
3190 |
0 |
with open(creds, "r") as cf: |
3191 |
0 |
vim_config["credentials"] = yaml.safe_load(cf.read()) |
3192 |
0 |
ctx.obj.vim.create(name, vim, vim_config, sdn_controller, sdn_port_mapping, wait=wait) |
3193 |
|
# except ClientException as e: |
3194 |
|
# print(str(e)) |
3195 |
|
# exit(1) |
3196 |
|
|
3197 |
|
|
3198 |
1 |
@cli_osm.command(name="vim-update", short_help="updates a VIM account") |
3199 |
1 |
@click.argument("name") |
3200 |
1 |
@click.option("--newname", help="New name for the VIM account") |
3201 |
1 |
@click.option("--user", help="VIM username") |
3202 |
1 |
@click.option("--password", help="VIM password") |
3203 |
1 |
@click.option("--auth_url", help="VIM url") |
3204 |
1 |
@click.option("--tenant", help="VIM tenant name") |
3205 |
1 |
@click.option("--config", help="VIM specific config parameters") |
3206 |
1 |
@click.option("--config_file", default=None, help="VIM specific config parameters in YAML or JSON file") |
3207 |
1 |
@click.option("--account_type", help="VIM type") |
3208 |
1 |
@click.option("--description", help="human readable description") |
3209 |
1 |
@click.option( |
3210 |
|
"--sdn_controller", |
3211 |
|
default=None, |
3212 |
|
help="Name or id of the SDN controller to be associated with this VIM" |
3213 |
|
"account. Use empty string to disassociate", |
3214 |
|
) |
3215 |
1 |
@click.option( |
3216 |
|
"--sdn_port_mapping", |
3217 |
|
default=None, |
3218 |
|
help="File describing the port mapping between compute nodes' ports and switch ports", |
3219 |
|
) |
3220 |
1 |
@click.option( |
3221 |
|
"--wait", |
3222 |
|
required=False, |
3223 |
|
default=False, |
3224 |
|
is_flag=True, |
3225 |
|
help="do not return the control immediately, but keep it " |
3226 |
|
"until the operation is completed, or timeout", |
3227 |
|
) |
3228 |
1 |
@click.option("--creds", default=None, help="credentials file (only applycable for GCP VIM type)") |
3229 |
1 |
@click.pass_context |
3230 |
1 |
def vim_update( |
3231 |
|
ctx, |
3232 |
|
name, |
3233 |
|
newname, |
3234 |
|
user, |
3235 |
|
password, |
3236 |
|
auth_url, |
3237 |
|
tenant, |
3238 |
|
config, |
3239 |
|
config_file, |
3240 |
|
account_type, |
3241 |
|
description, |
3242 |
|
sdn_controller, |
3243 |
|
sdn_port_mapping, |
3244 |
|
wait, |
3245 |
|
creds, |
3246 |
|
): |
3247 |
|
"""updates a VIM account |
3248 |
|
|
3249 |
|
NAME: name or ID of the VIM account |
3250 |
|
""" |
3251 |
0 |
logger.debug("") |
3252 |
|
# try: |
3253 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3254 |
0 |
vim = {} |
3255 |
0 |
if newname: |
3256 |
0 |
vim["name"] = newname |
3257 |
0 |
if user: |
3258 |
0 |
vim["vim_user"] = user |
3259 |
0 |
if password: |
3260 |
0 |
vim["vim_password"] = password |
3261 |
0 |
if auth_url: |
3262 |
0 |
vim["vim_url"] = auth_url |
3263 |
0 |
if tenant: |
3264 |
0 |
vim["vim-tenant-name"] = tenant |
3265 |
0 |
if account_type: |
3266 |
0 |
vim["vim_type"] = account_type |
3267 |
0 |
if description: |
3268 |
0 |
vim["description"] = description |
3269 |
0 |
vim_config = None |
3270 |
0 |
if config or config_file: |
3271 |
0 |
vim_config = create_config(config_file, config) |
3272 |
0 |
if creds: |
3273 |
0 |
with open(creds, "r") as cf: |
3274 |
0 |
vim_config["credentials"] = yaml.safe_load(cf.read()) |
3275 |
0 |
logger.info(f"VIM: {vim}, VIM config: {vim_config}") |
3276 |
0 |
ctx.obj.vim.update(name, vim, vim_config, sdn_controller, sdn_port_mapping, wait=wait) |
3277 |
|
# except ClientException as e: |
3278 |
|
# print(str(e)) |
3279 |
|
# exit(1) |
3280 |
|
|
3281 |
|
|
3282 |
1 |
@cli_osm.command(name="vim-delete", short_help="deletes a VIM account") |
3283 |
1 |
@click.argument("name") |
3284 |
1 |
@click.option( |
3285 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
3286 |
|
) |
3287 |
1 |
@click.option( |
3288 |
|
"--wait", |
3289 |
|
required=False, |
3290 |
|
default=False, |
3291 |
|
is_flag=True, |
3292 |
|
help="do not return the control immediately, but keep it " |
3293 |
|
"until the operation is completed, or timeout", |
3294 |
|
) |
3295 |
1 |
@click.pass_context |
3296 |
1 |
def vim_delete(ctx, name, force, wait): |
3297 |
|
"""deletes a VIM account |
3298 |
|
|
3299 |
|
NAME: name or ID of the VIM account to be deleted |
3300 |
|
""" |
3301 |
0 |
logger.debug("") |
3302 |
|
# try: |
3303 |
0 |
if not force: |
3304 |
0 |
ctx.obj.vim.delete(name, wait=wait) |
3305 |
|
else: |
3306 |
0 |
check_client_version(ctx.obj, "--force") |
3307 |
0 |
ctx.obj.vim.delete(name, force, wait=wait) |
3308 |
|
# except ClientException as e: |
3309 |
|
# print(str(e)) |
3310 |
|
# exit(1) |
3311 |
|
|
3312 |
|
|
3313 |
1 |
@cli_osm.command(name="vim-list", short_help="list all VIM accounts") |
3314 |
|
# @click.option('--ro_update/--no_ro_update', |
3315 |
|
# default=False, |
3316 |
|
# help='update list from RO') |
3317 |
1 |
@click.option( |
3318 |
|
"--filter", |
3319 |
|
default=None, |
3320 |
|
multiple=True, |
3321 |
|
help="restricts the list to the VIM accounts matching the filter", |
3322 |
|
) |
3323 |
1 |
@click.option( |
3324 |
|
"--long", |
3325 |
|
is_flag=True, |
3326 |
|
help="get more details of the NS (project, vim, deployment status, configuration status.", |
3327 |
|
) |
3328 |
1 |
@click.pass_context |
3329 |
1 |
def vim_list(ctx, filter, long): |
3330 |
|
"""list all VIM accounts""" |
3331 |
0 |
logger.debug("") |
3332 |
0 |
if filter: |
3333 |
0 |
filter = "&".join(filter) |
3334 |
0 |
check_client_version(ctx.obj, "--filter") |
3335 |
|
# if ro_update: |
3336 |
|
# check_client_version(ctx.obj, '--ro_update', 'v1') |
3337 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
3338 |
0 |
if fullclassname == "osmclient.sol005.client.Client": |
3339 |
0 |
resp = ctx.obj.vim.list(filter) |
3340 |
|
# else: |
3341 |
|
# resp = ctx.obj.vim.list(ro_update) |
3342 |
0 |
if long: |
3343 |
0 |
table = PrettyTable( |
3344 |
|
["vim name", "uuid", "project", "operational state", "error details"] |
3345 |
|
) |
3346 |
0 |
project_list = ctx.obj.project.list() |
3347 |
|
else: |
3348 |
0 |
table = PrettyTable(["vim name", "uuid", "operational state"]) |
3349 |
0 |
for vim in resp: |
3350 |
0 |
if long: |
3351 |
0 |
if "vim_password" in vim: |
3352 |
0 |
vim["vim_password"] = "********" |
3353 |
0 |
if "config" in vim and "credentials" in vim["config"]: |
3354 |
0 |
vim["config"]["credentials"] = "********" |
3355 |
0 |
logger.debug("VIM details: {}".format(yaml.safe_dump(vim))) |
3356 |
0 |
vim_state = vim["_admin"].get("operationalState", "-") |
3357 |
0 |
error_details = "N/A" |
3358 |
0 |
if vim_state == "ERROR": |
3359 |
0 |
error_details = vim["_admin"].get("detailed-status", "Not found") |
3360 |
0 |
project_id, project_name = get_project(project_list, vim) |
3361 |
|
# project_info = '{} ({})'.format(project_name, project_id) |
3362 |
0 |
project_info = project_name |
3363 |
0 |
table.add_row( |
3364 |
|
[ |
3365 |
|
vim["name"], |
3366 |
|
vim["uuid"], |
3367 |
|
project_info, |
3368 |
|
vim_state, |
3369 |
|
wrap_text(text=error_details, width=80), |
3370 |
|
] |
3371 |
|
) |
3372 |
|
else: |
3373 |
0 |
table.add_row( |
3374 |
|
[vim["name"], vim["uuid"], vim["_admin"].get("operationalState", "-")] |
3375 |
|
) |
3376 |
0 |
table.align = "l" |
3377 |
0 |
print(table) |
3378 |
|
|
3379 |
|
|
3380 |
1 |
@cli_osm.command(name="vim-show", short_help="shows the details of a VIM account") |
3381 |
1 |
@click.argument("name") |
3382 |
1 |
@click.option( |
3383 |
|
"--filter", |
3384 |
|
multiple=True, |
3385 |
|
help="restricts the information to the fields in the filter", |
3386 |
|
) |
3387 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
3388 |
1 |
@click.pass_context |
3389 |
1 |
def vim_show(ctx, name, filter, literal): |
3390 |
|
"""shows the details of a VIM account |
3391 |
|
|
3392 |
|
NAME: name or ID of the VIM account |
3393 |
|
""" |
3394 |
0 |
logger.debug("") |
3395 |
|
# try: |
3396 |
0 |
resp = ctx.obj.vim.get(name) |
3397 |
0 |
if "vim_password" in resp: |
3398 |
0 |
resp["vim_password"] = "********" |
3399 |
0 |
if "config" in resp and "credentials" in resp["config"]: |
3400 |
0 |
resp["config"]["credentials"] = "********" |
3401 |
|
# except ClientException as e: |
3402 |
|
# print(str(e)) |
3403 |
|
# exit(1) |
3404 |
|
|
3405 |
0 |
if literal: |
3406 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
3407 |
0 |
return |
3408 |
0 |
table = PrettyTable(["key", "attribute"]) |
3409 |
0 |
for k, v in list(resp.items()): |
3410 |
0 |
if not filter or k in filter: |
3411 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2), width=100)]) |
3412 |
0 |
table.align = "l" |
3413 |
0 |
print(table) |
3414 |
|
|
3415 |
|
|
3416 |
|
#################### |
3417 |
|
# WIM operations |
3418 |
|
#################### |
3419 |
|
|
3420 |
|
|
3421 |
1 |
@cli_osm.command(name="wim-create", short_help="creates a new WIM account") |
3422 |
1 |
@click.option("--name", prompt=True, help="Name for the WIM account") |
3423 |
1 |
@click.option("--user", help="WIM username") |
3424 |
1 |
@click.option("--password", help="WIM password") |
3425 |
1 |
@click.option("--url", prompt=True, help="WIM url") |
3426 |
|
# @click.option('--tenant', |
3427 |
|
# help='wIM tenant name') |
3428 |
1 |
@click.option("--config", default=None, help="WIM specific config parameters") |
3429 |
1 |
@click.option("--wim_type", help="WIM type") |
3430 |
1 |
@click.option("--description", default=None, help="human readable description") |
3431 |
1 |
@click.option( |
3432 |
|
"--wim_port_mapping", |
3433 |
|
default=None, |
3434 |
|
help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge " |
3435 |
|
"(WAN service endpoint id and info)", |
3436 |
|
) |
3437 |
1 |
@click.option( |
3438 |
|
"--wait", |
3439 |
|
required=False, |
3440 |
|
default=False, |
3441 |
|
is_flag=True, |
3442 |
|
help="do not return the control immediately, but keep it " |
3443 |
|
"until the operation is completed, or timeout", |
3444 |
|
) |
3445 |
1 |
@click.pass_context |
3446 |
1 |
def wim_create( |
3447 |
|
ctx, |
3448 |
|
name, |
3449 |
|
user, |
3450 |
|
password, |
3451 |
|
url, |
3452 |
|
# tenant, |
3453 |
|
config, |
3454 |
|
wim_type, |
3455 |
|
description, |
3456 |
|
wim_port_mapping, |
3457 |
|
wait, |
3458 |
|
): |
3459 |
|
"""creates a new WIM account""" |
3460 |
0 |
logger.debug("") |
3461 |
|
# try: |
3462 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3463 |
|
# if sdn_controller: |
3464 |
|
# check_client_version(ctx.obj, '--sdn_controller') |
3465 |
|
# if sdn_port_mapping: |
3466 |
|
# check_client_version(ctx.obj, '--sdn_port_mapping') |
3467 |
0 |
wim = {} |
3468 |
0 |
if user: |
3469 |
0 |
wim["user"] = user |
3470 |
0 |
if password: |
3471 |
0 |
wim["password"] = password |
3472 |
0 |
if url: |
3473 |
0 |
wim["wim_url"] = url |
3474 |
|
# if tenant: wim['tenant'] = tenant |
3475 |
0 |
wim["wim_type"] = wim_type |
3476 |
0 |
if description: |
3477 |
0 |
wim["description"] = description |
3478 |
0 |
if config: |
3479 |
0 |
wim["config"] = config |
3480 |
0 |
ctx.obj.wim.create(name, wim, wim_port_mapping, wait=wait) |
3481 |
|
# except ClientException as e: |
3482 |
|
# print(str(e)) |
3483 |
|
# exit(1) |
3484 |
|
|
3485 |
|
|
3486 |
1 |
@cli_osm.command(name="wim-update", short_help="updates a WIM account") |
3487 |
1 |
@click.argument("name") |
3488 |
1 |
@click.option("--newname", help="New name for the WIM account") |
3489 |
1 |
@click.option("--user", help="WIM username") |
3490 |
1 |
@click.option("--password", help="WIM password") |
3491 |
1 |
@click.option("--url", help="WIM url") |
3492 |
1 |
@click.option("--config", help="WIM specific config parameters") |
3493 |
1 |
@click.option("--wim_type", help="WIM type") |
3494 |
1 |
@click.option("--description", help="human readable description") |
3495 |
1 |
@click.option( |
3496 |
|
"--wim_port_mapping", |
3497 |
|
default=None, |
3498 |
|
help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge " |
3499 |
|
"(WAN service endpoint id and info)", |
3500 |
|
) |
3501 |
1 |
@click.option( |
3502 |
|
"--wait", |
3503 |
|
required=False, |
3504 |
|
default=False, |
3505 |
|
is_flag=True, |
3506 |
|
help="do not return the control immediately, but keep it until the operation is completed, or timeout", |
3507 |
|
) |
3508 |
1 |
@click.pass_context |
3509 |
1 |
def wim_update( |
3510 |
|
ctx, |
3511 |
|
name, |
3512 |
|
newname, |
3513 |
|
user, |
3514 |
|
password, |
3515 |
|
url, |
3516 |
|
config, |
3517 |
|
wim_type, |
3518 |
|
description, |
3519 |
|
wim_port_mapping, |
3520 |
|
wait, |
3521 |
|
): |
3522 |
|
"""updates a WIM account |
3523 |
|
|
3524 |
|
NAME: name or ID of the WIM account |
3525 |
|
""" |
3526 |
0 |
logger.debug("") |
3527 |
|
# try: |
3528 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3529 |
0 |
wim = {} |
3530 |
0 |
if newname: |
3531 |
0 |
wim["name"] = newname |
3532 |
0 |
if user: |
3533 |
0 |
wim["user"] = user |
3534 |
0 |
if password: |
3535 |
0 |
wim["password"] = password |
3536 |
0 |
if url: |
3537 |
0 |
wim["url"] = url |
3538 |
|
# if tenant: wim['tenant'] = tenant |
3539 |
0 |
if wim_type: |
3540 |
0 |
wim["wim_type"] = wim_type |
3541 |
0 |
if description: |
3542 |
0 |
wim["description"] = description |
3543 |
0 |
if config: |
3544 |
0 |
wim["config"] = config |
3545 |
0 |
ctx.obj.wim.update(name, wim, wim_port_mapping, wait=wait) |
3546 |
|
# except ClientException as e: |
3547 |
|
# print(str(e)) |
3548 |
|
# exit(1) |
3549 |
|
|
3550 |
|
|
3551 |
1 |
@cli_osm.command(name="wim-delete", short_help="deletes a WIM account") |
3552 |
1 |
@click.argument("name") |
3553 |
1 |
@click.option( |
3554 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
3555 |
|
) |
3556 |
1 |
@click.option( |
3557 |
|
"--wait", |
3558 |
|
required=False, |
3559 |
|
default=False, |
3560 |
|
is_flag=True, |
3561 |
|
help="do not return the control immediately, but keep it until the operation is completed, or timeout", |
3562 |
|
) |
3563 |
1 |
@click.pass_context |
3564 |
1 |
def wim_delete(ctx, name, force, wait): |
3565 |
|
"""deletes a WIM account |
3566 |
|
|
3567 |
|
NAME: name or ID of the WIM account to be deleted |
3568 |
|
""" |
3569 |
0 |
logger.debug("") |
3570 |
|
# try: |
3571 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3572 |
0 |
ctx.obj.wim.delete(name, force, wait=wait) |
3573 |
|
# except ClientException as e: |
3574 |
|
# print(str(e)) |
3575 |
|
# exit(1) |
3576 |
|
|
3577 |
|
|
3578 |
1 |
@cli_osm.command(name="wim-list", short_help="list all WIM accounts") |
3579 |
1 |
@click.option( |
3580 |
|
"--filter", |
3581 |
|
default=None, |
3582 |
|
multiple=True, |
3583 |
|
help="restricts the list to the WIM accounts matching the filter", |
3584 |
|
) |
3585 |
1 |
@click.pass_context |
3586 |
1 |
def wim_list(ctx, filter): |
3587 |
|
"""list all WIM accounts""" |
3588 |
0 |
logger.debug("") |
3589 |
|
# try: |
3590 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3591 |
0 |
if filter: |
3592 |
0 |
filter = "&".join(filter) |
3593 |
0 |
resp = ctx.obj.wim.list(filter) |
3594 |
0 |
table = PrettyTable(["wim name", "uuid"]) |
3595 |
0 |
for wim in resp: |
3596 |
0 |
table.add_row([wim["name"], wim["uuid"]]) |
3597 |
0 |
table.align = "l" |
3598 |
0 |
print(table) |
3599 |
|
# except ClientException as e: |
3600 |
|
# print(str(e)) |
3601 |
|
# exit(1) |
3602 |
|
|
3603 |
|
|
3604 |
1 |
@cli_osm.command(name="wim-show", short_help="shows the details of a WIM account") |
3605 |
1 |
@click.argument("name") |
3606 |
1 |
@click.pass_context |
3607 |
1 |
def wim_show(ctx, name): |
3608 |
|
"""shows the details of a WIM account |
3609 |
|
|
3610 |
|
NAME: name or ID of the WIM account |
3611 |
|
""" |
3612 |
0 |
logger.debug("") |
3613 |
|
# try: |
3614 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3615 |
0 |
resp = ctx.obj.wim.get(name) |
3616 |
0 |
if "password" in resp: |
3617 |
0 |
resp["wim_password"] = "********" |
3618 |
|
# except ClientException as e: |
3619 |
|
# print(str(e)) |
3620 |
|
# exit(1) |
3621 |
|
|
3622 |
0 |
table = PrettyTable(["key", "attribute"]) |
3623 |
0 |
for k, v in list(resp.items()): |
3624 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
3625 |
0 |
table.align = "l" |
3626 |
0 |
print(table) |
3627 |
|
|
3628 |
|
|
3629 |
|
#################### |
3630 |
|
# SDN controller operations |
3631 |
|
#################### |
3632 |
|
|
3633 |
|
|
3634 |
1 |
@cli_osm.command(name="sdnc-create", short_help="creates a new SDN controller") |
3635 |
1 |
@click.option("--name", prompt=True, help="Name to create sdn controller") |
3636 |
1 |
@click.option("--type", prompt=True, help="SDN controller type") |
3637 |
1 |
@click.option( |
3638 |
|
"--sdn_controller_version", # hidden=True, |
3639 |
|
help="Deprecated. Use --config {version: sdn_controller_version}", |
3640 |
|
) |
3641 |
1 |
@click.option("--url", help="URL in format http[s]://HOST:IP/") |
3642 |
1 |
@click.option("--ip_address", help="Deprecated. Use --url") # hidden=True, |
3643 |
1 |
@click.option("--port", help="Deprecated. Use --url") # hidden=True, |
3644 |
1 |
@click.option( |
3645 |
|
"--switch_dpid", help="Deprecated. Use --config {switch_id: DPID}" # hidden=True, |
3646 |
|
) |
3647 |
1 |
@click.option( |
3648 |
|
"--config", |
3649 |
|
help="Extra information for SDN in yaml format, as {switch_id: identity used for the plugin (e.g. DPID: " |
3650 |
|
"Openflow Datapath ID), version: version}", |
3651 |
|
) |
3652 |
1 |
@click.option("--user", help="SDN controller username") |
3653 |
1 |
@click.option( |
3654 |
|
"--password", |
3655 |
|
hide_input=True, |
3656 |
|
confirmation_prompt=True, |
3657 |
|
help="SDN controller password", |
3658 |
|
) |
3659 |
1 |
@click.option("--description", default=None, help="human readable description") |
3660 |
1 |
@click.option( |
3661 |
|
"--wait", |
3662 |
|
required=False, |
3663 |
|
default=False, |
3664 |
|
is_flag=True, |
3665 |
|
help="do not return the control immediately, but keep it until the operation is completed, or timeout", |
3666 |
|
) |
3667 |
1 |
@click.pass_context |
3668 |
1 |
def sdnc_create(ctx, **kwargs): |
3669 |
|
"""creates a new SDN controller""" |
3670 |
0 |
logger.debug("") |
3671 |
0 |
sdncontroller = { |
3672 |
|
x: kwargs[x] |
3673 |
|
for x in kwargs |
3674 |
|
if kwargs[x] and x not in ("wait", "ip_address", "port", "switch_dpid") |
3675 |
|
} |
3676 |
0 |
if kwargs.get("port"): |
3677 |
0 |
print("option '--port' is deprecated, use '--url' instead") |
3678 |
0 |
sdncontroller["port"] = int(kwargs["port"]) |
3679 |
0 |
if kwargs.get("ip_address"): |
3680 |
0 |
print("option '--ip_address' is deprecated, use '--url' instead") |
3681 |
0 |
sdncontroller["ip"] = kwargs["ip_address"] |
3682 |
0 |
if kwargs.get("switch_dpid"): |
3683 |
0 |
print( |
3684 |
|
"option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead" |
3685 |
|
) |
3686 |
0 |
sdncontroller["dpid"] = kwargs["switch_dpid"] |
3687 |
0 |
if kwargs.get("sdn_controller_version"): |
3688 |
0 |
print( |
3689 |
|
"option '--sdn_controller_version' is deprecated, use '--config={version: SDN_CONTROLLER_VERSION}'" |
3690 |
|
" instead" |
3691 |
|
) |
3692 |
|
# try: |
3693 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3694 |
0 |
ctx.obj.sdnc.create(kwargs["name"], sdncontroller, wait=kwargs["wait"]) |
3695 |
|
# except ClientException as e: |
3696 |
|
# print(str(e)) |
3697 |
|
# exit(1) |
3698 |
|
|
3699 |
|
|
3700 |
1 |
@cli_osm.command(name="sdnc-update", short_help="updates an SDN controller") |
3701 |
1 |
@click.argument("name") |
3702 |
1 |
@click.option("--newname", help="New name for the SDN controller") |
3703 |
1 |
@click.option("--description", default=None, help="human readable description") |
3704 |
1 |
@click.option("--type", help="SDN controller type") |
3705 |
1 |
@click.option("--url", help="URL in format http[s]://HOST:IP/") |
3706 |
1 |
@click.option( |
3707 |
|
"--config", |
3708 |
|
help="Extra information for SDN in yaml format, as " |
3709 |
|
"{switch_id: identity used for the plugin (e.g. DPID: " |
3710 |
|
"Openflow Datapath ID), version: version}", |
3711 |
|
) |
3712 |
1 |
@click.option("--user", help="SDN controller username") |
3713 |
1 |
@click.option("--password", help="SDN controller password") |
3714 |
1 |
@click.option("--ip_address", help="Deprecated. Use --url") # hidden=True |
3715 |
1 |
@click.option("--port", help="Deprecated. Use --url") # hidden=True |
3716 |
1 |
@click.option( |
3717 |
|
"--switch_dpid", help="Deprecated. Use --config {switch_dpid: DPID}" |
3718 |
|
) # hidden=True |
3719 |
1 |
@click.option( |
3720 |
|
"--sdn_controller_version", help="Deprecated. Use --config {version: VERSION}" |
3721 |
|
) # hidden=True |
3722 |
1 |
@click.option( |
3723 |
|
"--wait", |
3724 |
|
required=False, |
3725 |
|
default=False, |
3726 |
|
is_flag=True, |
3727 |
|
help="do not return the control immediately, but keep it until the operation is completed, or timeout", |
3728 |
|
) |
3729 |
1 |
@click.pass_context |
3730 |
1 |
def sdnc_update(ctx, **kwargs): |
3731 |
|
"""updates an SDN controller |
3732 |
|
|
3733 |
|
NAME: name or ID of the SDN controller |
3734 |
|
""" |
3735 |
0 |
logger.debug("") |
3736 |
0 |
sdncontroller = { |
3737 |
|
x: kwargs[x] |
3738 |
|
for x in kwargs |
3739 |
|
if kwargs[x] |
3740 |
|
and x not in ("wait", "ip_address", "port", "switch_dpid", "new_name") |
3741 |
|
} |
3742 |
0 |
if kwargs.get("newname"): |
3743 |
0 |
sdncontroller["name"] = kwargs["newname"] |
3744 |
0 |
if kwargs.get("port"): |
3745 |
0 |
print("option '--port' is deprecated, use '--url' instead") |
3746 |
0 |
sdncontroller["port"] = int(kwargs["port"]) |
3747 |
0 |
if kwargs.get("ip_address"): |
3748 |
0 |
print("option '--ip_address' is deprecated, use '--url' instead") |
3749 |
0 |
sdncontroller["ip"] = kwargs["ip_address"] |
3750 |
0 |
if kwargs.get("switch_dpid"): |
3751 |
0 |
print( |
3752 |
|
"option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead" |
3753 |
|
) |
3754 |
0 |
sdncontroller["dpid"] = kwargs["switch_dpid"] |
3755 |
0 |
if kwargs.get("sdn_controller_version"): |
3756 |
0 |
print( |
3757 |
|
"option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'" |
3758 |
|
" instead" |
3759 |
|
) |
3760 |
|
|
3761 |
|
# try: |
3762 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3763 |
0 |
ctx.obj.sdnc.update(kwargs["name"], sdncontroller, wait=kwargs["wait"]) |
3764 |
|
# except ClientException as e: |
3765 |
|
# print(str(e)) |
3766 |
|
# exit(1) |
3767 |
|
|
3768 |
|
|
3769 |
1 |
@cli_osm.command(name="sdnc-delete", short_help="deletes an SDN controller") |
3770 |
1 |
@click.argument("name") |
3771 |
1 |
@click.option( |
3772 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
3773 |
|
) |
3774 |
1 |
@click.option( |
3775 |
|
"--wait", |
3776 |
|
required=False, |
3777 |
|
default=False, |
3778 |
|
is_flag=True, |
3779 |
|
help="do not return the control immediately, but keep it until the operation is completed, or timeout", |
3780 |
|
) |
3781 |
1 |
@click.pass_context |
3782 |
1 |
def sdnc_delete(ctx, name, force, wait): |
3783 |
|
"""deletes an SDN controller |
3784 |
|
|
3785 |
|
NAME: name or ID of the SDN controller to be deleted |
3786 |
|
""" |
3787 |
0 |
logger.debug("") |
3788 |
|
# try: |
3789 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3790 |
0 |
ctx.obj.sdnc.delete(name, force, wait=wait) |
3791 |
|
# except ClientException as e: |
3792 |
|
# print(str(e)) |
3793 |
|
# exit(1) |
3794 |
|
|
3795 |
|
|
3796 |
1 |
@cli_osm.command(name="sdnc-list", short_help="list all SDN controllers") |
3797 |
1 |
@click.option( |
3798 |
|
"--filter", |
3799 |
|
default=None, |
3800 |
|
multiple=True, |
3801 |
|
help="restricts the list to the SDN controllers matching the filter with format: 'k[.k..]=v[&k[.k]=v2]'", |
3802 |
|
) |
3803 |
1 |
@click.pass_context |
3804 |
1 |
def sdnc_list(ctx, filter): |
3805 |
|
"""list all SDN controllers""" |
3806 |
0 |
logger.debug("") |
3807 |
|
# try: |
3808 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3809 |
0 |
if filter: |
3810 |
0 |
filter = "&".join(filter) |
3811 |
0 |
resp = ctx.obj.sdnc.list(filter) |
3812 |
|
# except ClientException as e: |
3813 |
|
# print(str(e)) |
3814 |
|
# exit(1) |
3815 |
0 |
table = PrettyTable(["sdnc name", "id"]) |
3816 |
0 |
for sdnc in resp: |
3817 |
0 |
table.add_row([sdnc["name"], sdnc["_id"]]) |
3818 |
0 |
table.align = "l" |
3819 |
0 |
print(table) |
3820 |
|
|
3821 |
|
|
3822 |
1 |
@cli_osm.command(name="sdnc-show", short_help="shows the details of an SDN controller") |
3823 |
1 |
@click.argument("name") |
3824 |
1 |
@click.pass_context |
3825 |
1 |
def sdnc_show(ctx, name): |
3826 |
|
"""shows the details of an SDN controller |
3827 |
|
|
3828 |
|
NAME: name or ID of the SDN controller |
3829 |
|
""" |
3830 |
0 |
logger.debug("") |
3831 |
|
# try: |
3832 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3833 |
0 |
resp = ctx.obj.sdnc.get(name) |
3834 |
|
# except ClientException as e: |
3835 |
|
# print(str(e)) |
3836 |
|
# exit(1) |
3837 |
|
|
3838 |
0 |
table = PrettyTable(["key", "attribute"]) |
3839 |
0 |
for k, v in list(resp.items()): |
3840 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
3841 |
0 |
table.align = "l" |
3842 |
0 |
print(table) |
3843 |
|
|
3844 |
|
|
3845 |
|
########################### |
3846 |
|
# K8s cluster operations |
3847 |
|
########################### |
3848 |
|
|
3849 |
|
|
3850 |
1 |
@cli_osm.command(name="k8scluster-add", short_help="adds a K8s cluster to OSM") |
3851 |
1 |
@click.argument("name") |
3852 |
1 |
@click.option( |
3853 |
|
"--creds", prompt=True, help="credentials file, i.e. a valid `.kube/config` file" |
3854 |
|
) |
3855 |
1 |
@click.option("--version", prompt=True, help="Kubernetes version") |
3856 |
1 |
@click.option( |
3857 |
|
"--vim", prompt=True, help="VIM target, the VIM where the cluster resides" |
3858 |
|
) |
3859 |
1 |
@click.option( |
3860 |
|
"--k8s-nets", |
3861 |
|
prompt=True, |
3862 |
|
help='''list of VIM networks, in JSON inline format, where the cluster is |
3863 |
|
accessible via L3 routing, e.g. "{(k8s_net1:vim_network1) [,(k8s_net2:vim_network2) ...]}"''', |
3864 |
|
) |
3865 |
1 |
@click.option("--description", default=None, help="human readable description") |
3866 |
1 |
@click.option( |
3867 |
|
"--namespace", |
3868 |
|
default="kube-system", |
3869 |
|
help="namespace to be used for its operation, defaults to `kube-system`", |
3870 |
|
) |
3871 |
1 |
@click.option( |
3872 |
|
"--wait", |
3873 |
|
required=False, |
3874 |
|
default=False, |
3875 |
|
is_flag=True, |
3876 |
|
help="do not return the control immediately, but keep it " |
3877 |
|
"until the operation is completed, or timeout", |
3878 |
|
) |
3879 |
1 |
@click.option( |
3880 |
|
"--cni", |
3881 |
|
default=None, |
3882 |
|
help="list of CNI plugins, in JSON inline format, used in the cluster", |
3883 |
|
) |
3884 |
|
# @click.option('--skip-init', |
3885 |
|
# is_flag=True, |
3886 |
|
# help='If set, K8s cluster is assumed to be ready for its use with OSM') |
3887 |
|
# @click.option('--wait', |
3888 |
|
# is_flag=True, |
3889 |
|
# help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
3890 |
1 |
@click.pass_context |
3891 |
1 |
def k8scluster_add( |
3892 |
|
ctx, name, creds, version, vim, k8s_nets, description, namespace, wait, cni |
3893 |
|
): |
3894 |
|
"""adds a K8s cluster to OSM |
3895 |
|
|
3896 |
|
NAME: name of the K8s cluster |
3897 |
|
""" |
3898 |
|
# try: |
3899 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3900 |
0 |
cluster = {} |
3901 |
0 |
cluster["name"] = name |
3902 |
0 |
with open(creds, "r") as cf: |
3903 |
0 |
cluster["credentials"] = yaml.safe_load(cf.read()) |
3904 |
0 |
cluster["k8s_version"] = version |
3905 |
0 |
cluster["vim_account"] = vim |
3906 |
0 |
cluster["nets"] = yaml.safe_load(k8s_nets) |
3907 |
0 |
if description: |
3908 |
0 |
cluster["description"] = description |
3909 |
0 |
if namespace: |
3910 |
0 |
cluster["namespace"] = namespace |
3911 |
0 |
if cni: |
3912 |
0 |
cluster["cni"] = yaml.safe_load(cni) |
3913 |
0 |
ctx.obj.k8scluster.create(name, cluster, wait) |
3914 |
|
# except ClientException as e: |
3915 |
|
# print(str(e)) |
3916 |
|
# exit(1) |
3917 |
|
|
3918 |
|
|
3919 |
1 |
@cli_osm.command(name="k8scluster-update", short_help="updates a K8s cluster") |
3920 |
1 |
@click.argument("name") |
3921 |
1 |
@click.option("--newname", help="New name for the K8s cluster") |
3922 |
1 |
@click.option("--creds", help="credentials file, i.e. a valid `.kube/config` file") |
3923 |
1 |
@click.option("--version", help="Kubernetes version") |
3924 |
1 |
@click.option("--vim", help="VIM target, the VIM where the cluster resides") |
3925 |
1 |
@click.option( |
3926 |
|
"--k8s-nets", |
3927 |
|
help='''list of VIM networks, in JSON inline format, where the cluster is accessible |
3928 |
|
via L3 routing, e.g. "{(k8s_net1:vim_network1) [,(k8s_net2:vim_network2) ...]}"''', |
3929 |
|
) |
3930 |
1 |
@click.option("--description", help="human readable description") |
3931 |
1 |
@click.option( |
3932 |
|
"--namespace", |
3933 |
|
help="namespace to be used for its operation, defaults to `kube-system`", |
3934 |
|
) |
3935 |
1 |
@click.option( |
3936 |
|
"--wait", |
3937 |
|
required=False, |
3938 |
|
default=False, |
3939 |
|
is_flag=True, |
3940 |
|
help="do not return the control immediately, but keep it " |
3941 |
|
"until the operation is completed, or timeout", |
3942 |
|
) |
3943 |
1 |
@click.option( |
3944 |
|
"--cni", help="list of CNI plugins, in JSON inline format, used in the cluster" |
3945 |
|
) |
3946 |
1 |
@click.pass_context |
3947 |
1 |
def k8scluster_update( |
3948 |
|
ctx, name, newname, creds, version, vim, k8s_nets, description, namespace, wait, cni |
3949 |
|
): |
3950 |
|
"""updates a K8s cluster |
3951 |
|
|
3952 |
|
NAME: name or ID of the K8s cluster |
3953 |
|
""" |
3954 |
|
# try: |
3955 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
3956 |
0 |
cluster = {} |
3957 |
0 |
if newname: |
3958 |
0 |
cluster["name"] = newname |
3959 |
0 |
if creds: |
3960 |
0 |
with open(creds, "r") as cf: |
3961 |
0 |
cluster["credentials"] = yaml.safe_load(cf.read()) |
3962 |
0 |
if version: |
3963 |
0 |
cluster["k8s_version"] = version |
3964 |
0 |
if vim: |
3965 |
0 |
cluster["vim_account"] = vim |
3966 |
0 |
if k8s_nets: |
3967 |
0 |
cluster["nets"] = yaml.safe_load(k8s_nets) |
3968 |
0 |
if description: |
3969 |
0 |
cluster["description"] = description |
3970 |
0 |
if namespace: |
3971 |
0 |
cluster["namespace"] = namespace |
3972 |
0 |
if cni: |
3973 |
0 |
cluster["cni"] = yaml.safe_load(cni) |
3974 |
0 |
ctx.obj.k8scluster.update(name, cluster, wait) |
3975 |
|
# except ClientException as e: |
3976 |
|
# print(str(e)) |
3977 |
|
# exit(1) |
3978 |
|
|
3979 |
|
|
3980 |
1 |
@cli_osm.command(name="k8scluster-delete", short_help="deletes a K8s cluster") |
3981 |
1 |
@click.argument("name") |
3982 |
1 |
@click.option( |
3983 |
|
"--force", is_flag=True, help="forces the deletion from the DB (not recommended)" |
3984 |
|
) |
3985 |
1 |
@click.option( |
3986 |
|
"--wait", |
3987 |
|
required=False, |
3988 |
|
default=False, |
3989 |
|
is_flag=True, |
3990 |
|
help="do not return the control immediately, but keep it " |
3991 |
|
"until the operation is completed, or timeout", |
3992 |
|
) |
3993 |
1 |
@click.pass_context |
3994 |
1 |
def k8scluster_delete(ctx, name, force, wait): |
3995 |
|
"""deletes a K8s cluster |
3996 |
|
|
3997 |
|
NAME: name or ID of the K8s cluster to be deleted |
3998 |
|
""" |
3999 |
|
# try: |
4000 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4001 |
0 |
ctx.obj.k8scluster.delete(name, force, wait) |
4002 |
|
# except ClientException as e: |
4003 |
|
# print(str(e)) |
4004 |
|
# exit(1) |
4005 |
|
|
4006 |
|
|
4007 |
1 |
@cli_osm.command(name="k8scluster-list") |
4008 |
1 |
@click.option( |
4009 |
|
"--filter", |
4010 |
|
default=None, |
4011 |
|
multiple=True, |
4012 |
|
help="restricts the list to the K8s clusters matching the filter", |
4013 |
|
) |
4014 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
4015 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
4016 |
1 |
@click.pass_context |
4017 |
1 |
def k8scluster_list(ctx, filter, literal, long): |
4018 |
|
"""list all K8s clusters""" |
4019 |
|
# try: |
4020 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4021 |
0 |
if filter: |
4022 |
0 |
filter = "&".join(filter) |
4023 |
0 |
resp = ctx.obj.k8scluster.list(filter) |
4024 |
0 |
if literal: |
4025 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
4026 |
0 |
return |
4027 |
0 |
if long: |
4028 |
0 |
table = PrettyTable( |
4029 |
|
[ |
4030 |
|
"Name", |
4031 |
|
"Id", |
4032 |
|
"Project", |
4033 |
|
"Version", |
4034 |
|
"VIM", |
4035 |
|
"K8s-nets", |
4036 |
|
"Operational State", |
4037 |
|
"Op. state (details)", |
4038 |
|
"Description", |
4039 |
|
"Detailed status", |
4040 |
|
] |
4041 |
|
) |
4042 |
0 |
project_list = ctx.obj.project.list() |
4043 |
|
else: |
4044 |
0 |
table = PrettyTable( |
4045 |
|
["Name", "Id", "VIM", "Operational State", "Op. state details"] |
4046 |
|
) |
4047 |
0 |
try: |
4048 |
0 |
vim_list = ctx.obj.vim.list() |
4049 |
0 |
except Exception: |
4050 |
0 |
vim_list = [] |
4051 |
0 |
for cluster in resp: |
4052 |
0 |
logger.debug("Cluster details: {}".format(yaml.safe_dump(cluster))) |
4053 |
0 |
vim_name = get_vim_name(vim_list, cluster["vim_account"]) |
4054 |
|
# vim_info = '{} ({})'.format(vim_name,cluster['vim_account']) |
4055 |
0 |
vim_info = vim_name |
4056 |
0 |
op_state_details = "Helm: {}\nJuju: {}".format( |
4057 |
|
cluster["_admin"].get("helm-chart", {}).get("operationalState", "-"), |
4058 |
|
cluster["_admin"].get("juju-bundle", {}).get("operationalState", "-"), |
4059 |
|
) |
4060 |
0 |
if long: |
4061 |
0 |
project_id, project_name = get_project(project_list, cluster) |
4062 |
|
# project_info = '{} ({})'.format(project_name, project_id) |
4063 |
0 |
project_info = project_name |
4064 |
0 |
detailed_status = cluster["_admin"].get("detailed-status", "-") |
4065 |
0 |
table.add_row( |
4066 |
|
[ |
4067 |
|
cluster["name"], |
4068 |
|
cluster["_id"], |
4069 |
|
project_info, |
4070 |
|
cluster["k8s_version"], |
4071 |
|
vim_info, |
4072 |
|
json.dumps(cluster["nets"]), |
4073 |
|
cluster["_admin"]["operationalState"], |
4074 |
|
op_state_details, |
4075 |
|
trunc_text(cluster.get("description") or "", 40), |
4076 |
|
wrap_text(text=detailed_status, width=40), |
4077 |
|
] |
4078 |
|
) |
4079 |
|
else: |
4080 |
0 |
table.add_row( |
4081 |
|
[ |
4082 |
|
cluster["name"], |
4083 |
|
cluster["_id"], |
4084 |
|
vim_info, |
4085 |
|
cluster["_admin"]["operationalState"], |
4086 |
|
op_state_details, |
4087 |
|
] |
4088 |
|
) |
4089 |
0 |
table.align = "l" |
4090 |
0 |
print(table) |
4091 |
|
# except ClientException as e: |
4092 |
|
# print(str(e)) |
4093 |
|
# exit(1) |
4094 |
|
|
4095 |
|
|
4096 |
1 |
@cli_osm.command( |
4097 |
|
name="k8scluster-show", short_help="shows the details of a K8s cluster" |
4098 |
|
) |
4099 |
1 |
@click.argument("name") |
4100 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
4101 |
1 |
@click.pass_context |
4102 |
1 |
def k8scluster_show(ctx, name, literal): |
4103 |
|
"""shows the details of a K8s cluster |
4104 |
|
|
4105 |
|
NAME: name or ID of the K8s cluster |
4106 |
|
""" |
4107 |
|
# try: |
4108 |
0 |
resp = ctx.obj.k8scluster.get(name) |
4109 |
0 |
if literal: |
4110 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
4111 |
0 |
return |
4112 |
0 |
table = PrettyTable(["key", "attribute"]) |
4113 |
0 |
for k, v in list(resp.items()): |
4114 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2), width=100)]) |
4115 |
0 |
table.align = "l" |
4116 |
0 |
print(table) |
4117 |
|
# except ClientException as e: |
4118 |
|
# print(str(e)) |
4119 |
|
# exit(1) |
4120 |
|
|
4121 |
|
|
4122 |
|
########################### |
4123 |
|
# VCA operations |
4124 |
|
########################### |
4125 |
|
|
4126 |
|
|
4127 |
1 |
@cli_osm.command(name="vca-add", short_help="adds a VCA (Juju controller) to OSM") |
4128 |
1 |
@click.argument("name") |
4129 |
1 |
@click.option( |
4130 |
|
"--endpoints", |
4131 |
|
prompt=True, |
4132 |
|
help="Comma-separated list of IP or hostnames of the Juju controller", |
4133 |
|
) |
4134 |
1 |
@click.option("--user", prompt=True, help="Username with admin priviledges") |
4135 |
1 |
@click.option("--secret", prompt=True, help="Password of the specified username") |
4136 |
1 |
@click.option("--cacert", prompt=True, help="CA certificate") |
4137 |
1 |
@click.option( |
4138 |
|
"--lxd-cloud", |
4139 |
|
prompt=True, |
4140 |
|
help="Name of the cloud that will be used for LXD containers (LXD proxy charms)", |
4141 |
|
) |
4142 |
1 |
@click.option( |
4143 |
|
"--lxd-credentials", |
4144 |
|
prompt=True, |
4145 |
|
help="Name of the cloud credentialsto be used for the LXD cloud", |
4146 |
|
) |
4147 |
1 |
@click.option( |
4148 |
|
"--k8s-cloud", |
4149 |
|
prompt=True, |
4150 |
|
help="Name of the cloud that will be used for K8s containers (K8s proxy charms)", |
4151 |
|
) |
4152 |
1 |
@click.option( |
4153 |
|
"--k8s-credentials", |
4154 |
|
prompt=True, |
4155 |
|
help="Name of the cloud credentialsto be used for the K8s cloud", |
4156 |
|
) |
4157 |
1 |
@click.option( |
4158 |
|
"--model-config", |
4159 |
|
default={}, |
4160 |
|
help="Configuration options for the models", |
4161 |
|
) |
4162 |
1 |
@click.option("--description", default=None, help="human readable description") |
4163 |
1 |
@click.pass_context |
4164 |
1 |
def vca_add( |
4165 |
|
ctx, |
4166 |
|
name, |
4167 |
|
endpoints, |
4168 |
|
user, |
4169 |
|
secret, |
4170 |
|
cacert, |
4171 |
|
lxd_cloud, |
4172 |
|
lxd_credentials, |
4173 |
|
k8s_cloud, |
4174 |
|
k8s_credentials, |
4175 |
|
model_config, |
4176 |
|
description, |
4177 |
|
): |
4178 |
|
"""adds a VCA to OSM |
4179 |
|
|
4180 |
|
NAME: name of the VCA |
4181 |
|
""" |
4182 |
1 |
check_client_version(ctx.obj, ctx.command.name) |
4183 |
1 |
vca = {} |
4184 |
1 |
vca["name"] = name |
4185 |
1 |
vca["endpoints"] = endpoints.split(",") |
4186 |
1 |
vca["user"] = user |
4187 |
1 |
vca["secret"] = secret |
4188 |
1 |
vca["cacert"] = cacert |
4189 |
1 |
vca["lxd-cloud"] = lxd_cloud |
4190 |
1 |
vca["lxd-credentials"] = lxd_credentials |
4191 |
1 |
vca["k8s-cloud"] = k8s_cloud |
4192 |
1 |
vca["k8s-credentials"] = k8s_credentials |
4193 |
1 |
if description: |
4194 |
1 |
vca["description"] = description |
4195 |
1 |
if model_config: |
4196 |
1 |
model_config = load(model_config) |
4197 |
1 |
vca["model-config"] = model_config |
4198 |
1 |
ctx.obj.vca.create(name, vca) |
4199 |
|
|
4200 |
|
|
4201 |
1 |
def load(data: Any): |
4202 |
1 |
if os.path.isfile(data): |
4203 |
0 |
return load_file(data) |
4204 |
|
else: |
4205 |
1 |
try: |
4206 |
1 |
return json.loads(data) |
4207 |
0 |
except ValueError as e: |
4208 |
0 |
raise ClientException(e) |
4209 |
|
|
4210 |
|
|
4211 |
1 |
def load_file(file_path: str) -> Dict: |
4212 |
0 |
content = None |
4213 |
0 |
with open(file_path, "r") as f: |
4214 |
0 |
content = f.read() |
4215 |
0 |
try: |
4216 |
0 |
return yaml.safe_load(content) |
4217 |
0 |
except yaml.scanner.ScannerError: |
4218 |
0 |
pass |
4219 |
0 |
try: |
4220 |
0 |
return json.loads(content) |
4221 |
0 |
except ValueError: |
4222 |
0 |
pass |
4223 |
0 |
raise ClientException(f"{file_path} must be a valid yaml or json file") |
4224 |
|
|
4225 |
|
|
4226 |
1 |
@cli_osm.command(name="vca-update", short_help="updates a K8s cluster") |
4227 |
1 |
@click.argument("name") |
4228 |
1 |
@click.option( |
4229 |
|
"--endpoints", help="Comma-separated list of IP or hostnames of the Juju controller" |
4230 |
|
) |
4231 |
1 |
@click.option("--user", help="Username with admin priviledges") |
4232 |
1 |
@click.option("--secret", help="Password of the specified username") |
4233 |
1 |
@click.option("--cacert", help="CA certificate") |
4234 |
1 |
@click.option( |
4235 |
|
"--lxd-cloud", |
4236 |
|
help="Name of the cloud that will be used for LXD containers (LXD proxy charms)", |
4237 |
|
) |
4238 |
1 |
@click.option( |
4239 |
|
"--lxd-credentials", |
4240 |
|
help="Name of the cloud credentialsto be used for the LXD cloud", |
4241 |
|
) |
4242 |
1 |
@click.option( |
4243 |
|
"--k8s-cloud", |
4244 |
|
help="Name of the cloud that will be used for K8s containers (K8s proxy charms)", |
4245 |
|
) |
4246 |
1 |
@click.option( |
4247 |
|
"--k8s-credentials", |
4248 |
|
help="Name of the cloud credentialsto be used for the K8s cloud", |
4249 |
|
) |
4250 |
1 |
@click.option( |
4251 |
|
"--model-config", |
4252 |
|
help="Configuration options for the models", |
4253 |
|
) |
4254 |
1 |
@click.option("--description", default=None, help="human readable description") |
4255 |
1 |
@click.pass_context |
4256 |
1 |
def vca_update( |
4257 |
|
ctx, |
4258 |
|
name, |
4259 |
|
endpoints, |
4260 |
|
user, |
4261 |
|
secret, |
4262 |
|
cacert, |
4263 |
|
lxd_cloud, |
4264 |
|
lxd_credentials, |
4265 |
|
k8s_cloud, |
4266 |
|
k8s_credentials, |
4267 |
|
model_config, |
4268 |
|
description, |
4269 |
|
): |
4270 |
|
"""updates a K8s cluster |
4271 |
|
|
4272 |
|
NAME: name or ID of the K8s cluster |
4273 |
|
""" |
4274 |
1 |
check_client_version(ctx.obj, ctx.command.name) |
4275 |
1 |
vca = {} |
4276 |
1 |
vca["name"] = name |
4277 |
1 |
if endpoints: |
4278 |
1 |
vca["endpoints"] = endpoints.split(",") |
4279 |
1 |
if user: |
4280 |
1 |
vca["user"] = user |
4281 |
1 |
if secret: |
4282 |
1 |
vca["secret"] = secret |
4283 |
1 |
if cacert: |
4284 |
1 |
vca["cacert"] = cacert |
4285 |
1 |
if lxd_cloud: |
4286 |
1 |
vca["lxd-cloud"] = lxd_cloud |
4287 |
1 |
if lxd_credentials: |
4288 |
1 |
vca["lxd-credentials"] = lxd_credentials |
4289 |
1 |
if k8s_cloud: |
4290 |
1 |
vca["k8s-cloud"] = k8s_cloud |
4291 |
1 |
if k8s_credentials: |
4292 |
1 |
vca["k8s-credentials"] = k8s_credentials |
4293 |
1 |
if description: |
4294 |
1 |
vca["description"] = description |
4295 |
1 |
if model_config: |
4296 |
1 |
model_config = load(model_config) |
4297 |
1 |
vca["model-config"] = model_config |
4298 |
1 |
ctx.obj.vca.update(name, vca) |
4299 |
|
|
4300 |
|
|
4301 |
1 |
@cli_osm.command(name="vca-delete", short_help="deletes a K8s cluster") |
4302 |
1 |
@click.argument("name") |
4303 |
1 |
@click.option( |
4304 |
|
"--force", is_flag=True, help="forces the deletion from the DB (not recommended)" |
4305 |
|
) |
4306 |
1 |
@click.pass_context |
4307 |
1 |
def vca_delete(ctx, name, force): |
4308 |
|
"""deletes a K8s cluster |
4309 |
|
|
4310 |
|
NAME: name or ID of the K8s cluster to be deleted |
4311 |
|
""" |
4312 |
1 |
check_client_version(ctx.obj, ctx.command.name) |
4313 |
1 |
ctx.obj.vca.delete(name, force=force) |
4314 |
|
|
4315 |
|
|
4316 |
1 |
@cli_osm.command(name="vca-list") |
4317 |
1 |
@click.option( |
4318 |
|
"--filter", |
4319 |
|
default=None, |
4320 |
|
multiple=True, |
4321 |
|
help="restricts the list to the VCAs matching the filter", |
4322 |
|
) |
4323 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
4324 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
4325 |
1 |
@click.pass_context |
4326 |
1 |
def vca_list(ctx, filter, literal, long): |
4327 |
|
"""list VCAs""" |
4328 |
1 |
check_client_version(ctx.obj, ctx.command.name) |
4329 |
1 |
if filter: |
4330 |
1 |
filter = "&".join(filter) |
4331 |
1 |
resp = ctx.obj.vca.list(filter) |
4332 |
1 |
if literal: |
4333 |
1 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
4334 |
1 |
return |
4335 |
1 |
if long: |
4336 |
1 |
table = PrettyTable( |
4337 |
|
["Name", "Id", "Project", "Operational State", "Detailed Status"] |
4338 |
|
) |
4339 |
1 |
project_list = ctx.obj.project.list() |
4340 |
|
else: |
4341 |
1 |
table = PrettyTable(["Name", "Id", "Operational State"]) |
4342 |
1 |
for vca in resp: |
4343 |
1 |
logger.debug("VCA details: {}".format(yaml.safe_dump(vca))) |
4344 |
1 |
if long: |
4345 |
1 |
project_id, project_name = get_project(project_list, vca) |
4346 |
1 |
detailed_status = vca.get("_admin", {}).get("detailed-status", "-") |
4347 |
1 |
table.add_row( |
4348 |
|
[ |
4349 |
|
vca["name"], |
4350 |
|
vca["_id"], |
4351 |
|
project_name, |
4352 |
|
vca.get("_admin", {}).get("operationalState", "-"), |
4353 |
|
wrap_text(text=detailed_status, width=40), |
4354 |
|
] |
4355 |
|
) |
4356 |
|
else: |
4357 |
1 |
table.add_row( |
4358 |
|
[ |
4359 |
|
vca["name"], |
4360 |
|
vca["_id"], |
4361 |
|
vca.get("_admin", {}).get("operationalState", "-"), |
4362 |
|
] |
4363 |
|
) |
4364 |
1 |
table.align = "l" |
4365 |
1 |
print(table) |
4366 |
|
|
4367 |
|
|
4368 |
1 |
@cli_osm.command(name="vca-show", short_help="shows the details of a K8s cluster") |
4369 |
1 |
@click.argument("name") |
4370 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
4371 |
1 |
@click.pass_context |
4372 |
1 |
def vca_show(ctx, name, literal): |
4373 |
|
"""shows the details of a K8s cluster |
4374 |
|
|
4375 |
|
NAME: name or ID of the K8s cluster |
4376 |
|
""" |
4377 |
|
# try: |
4378 |
1 |
resp = ctx.obj.vca.get(name) |
4379 |
1 |
if literal: |
4380 |
1 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
4381 |
1 |
return |
4382 |
1 |
table = PrettyTable(["key", "attribute"]) |
4383 |
1 |
for k, v in list(resp.items()): |
4384 |
1 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2), width=100)]) |
4385 |
1 |
table.align = "l" |
4386 |
1 |
print(table) |
4387 |
|
|
4388 |
|
|
4389 |
|
########################### |
4390 |
|
# Repo operations |
4391 |
|
########################### |
4392 |
|
|
4393 |
|
|
4394 |
1 |
@cli_osm.command(name="repo-add", short_help="adds a repo to OSM") |
4395 |
1 |
@click.argument("name") |
4396 |
1 |
@click.argument("uri") |
4397 |
1 |
@click.option( |
4398 |
|
"--type", |
4399 |
|
type=click.Choice(["helm-chart", "juju-bundle", "osm"]), |
4400 |
|
default="osm", |
4401 |
|
help="type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles, osm for OSM Repositories)", |
4402 |
|
) |
4403 |
1 |
@click.option("--description", default=None, help="human readable description") |
4404 |
1 |
@click.option( |
4405 |
|
"--user", default=None, help="OSM repository: The username of the OSM repository" |
4406 |
|
) |
4407 |
1 |
@click.option( |
4408 |
|
"--password", |
4409 |
|
default=None, |
4410 |
|
help="OSM repository: The password of the OSM repository", |
4411 |
|
) |
4412 |
|
# @click.option('--wait', |
4413 |
|
# is_flag=True, |
4414 |
|
# help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
4415 |
1 |
@click.pass_context |
4416 |
1 |
def repo_add(ctx, **kwargs): |
4417 |
|
"""adds a repo to OSM |
4418 |
|
|
4419 |
|
NAME: name of the repo |
4420 |
|
URI: URI of the repo |
4421 |
|
""" |
4422 |
|
# try: |
4423 |
0 |
kwargs = {k: v for k, v in kwargs.items() if v is not None} |
4424 |
0 |
repo = kwargs |
4425 |
0 |
repo["url"] = repo.pop("uri") |
4426 |
0 |
if repo["type"] in ["helm-chart", "juju-bundle"]: |
4427 |
0 |
ctx.obj.repo.create(repo["name"], repo) |
4428 |
|
else: |
4429 |
0 |
ctx.obj.osmrepo.create(repo["name"], repo) |
4430 |
|
# except ClientException as e: |
4431 |
|
# print(str(e)) |
4432 |
|
# exit(1) |
4433 |
|
|
4434 |
|
|
4435 |
1 |
@cli_osm.command(name="repo-update", short_help="updates a repo in OSM") |
4436 |
1 |
@click.argument("name") |
4437 |
1 |
@click.option("--newname", help="New name for the repo") |
4438 |
1 |
@click.option("--uri", help="URI of the repo") |
4439 |
1 |
@click.option("--description", help="human readable description") |
4440 |
|
# @click.option('--wait', |
4441 |
|
# is_flag=True, |
4442 |
|
# help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
4443 |
1 |
@click.pass_context |
4444 |
1 |
def repo_update(ctx, name, newname, uri, description): |
4445 |
|
"""updates a repo in OSM |
4446 |
|
|
4447 |
|
NAME: name of the repo |
4448 |
|
""" |
4449 |
|
# try: |
4450 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4451 |
0 |
repo = {} |
4452 |
0 |
if newname: |
4453 |
0 |
repo["name"] = newname |
4454 |
0 |
if uri: |
4455 |
0 |
repo["uri"] = uri |
4456 |
0 |
if description: |
4457 |
0 |
repo["description"] = description |
4458 |
0 |
try: |
4459 |
0 |
ctx.obj.repo.update(name, repo) |
4460 |
0 |
except NotFound: |
4461 |
0 |
ctx.obj.osmrepo.update(name, repo) |
4462 |
|
|
4463 |
|
# except ClientException as e: |
4464 |
|
# print(str(e)) |
4465 |
|
# exit(1) |
4466 |
|
|
4467 |
|
|
4468 |
1 |
@cli_osm.command( |
4469 |
|
name="repo-index", short_help="Index a repository from a folder with artifacts" |
4470 |
|
) |
4471 |
1 |
@click.option( |
4472 |
|
"--origin", default=".", help="origin path where the artifacts are located" |
4473 |
|
) |
4474 |
1 |
@click.option( |
4475 |
|
"--destination", default=".", help="destination path where the index is deployed" |
4476 |
|
) |
4477 |
1 |
@click.pass_context |
4478 |
1 |
def repo_index(ctx, origin, destination): |
4479 |
|
"""Index a repository |
4480 |
|
|
4481 |
|
NAME: name or ID of the repo to be deleted |
4482 |
|
""" |
4483 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4484 |
0 |
ctx.obj.osmrepo.repo_index(origin, destination) |
4485 |
|
|
4486 |
|
|
4487 |
1 |
@cli_osm.command(name="repo-delete", short_help="deletes a repo") |
4488 |
1 |
@click.argument("name") |
4489 |
1 |
@click.option( |
4490 |
|
"--force", is_flag=True, help="forces the deletion from the DB (not recommended)" |
4491 |
|
) |
4492 |
|
# @click.option('--wait', |
4493 |
|
# is_flag=True, |
4494 |
|
# help='do not return the control immediately, but keep it until the operation is completed, or timeout') |
4495 |
1 |
@click.pass_context |
4496 |
1 |
def repo_delete(ctx, name, force): |
4497 |
|
"""deletes a repo |
4498 |
|
|
4499 |
|
NAME: name or ID of the repo to be deleted |
4500 |
|
""" |
4501 |
0 |
logger.debug("") |
4502 |
0 |
try: |
4503 |
0 |
ctx.obj.repo.delete(name, force=force) |
4504 |
0 |
except NotFound: |
4505 |
0 |
ctx.obj.osmrepo.delete(name, force=force) |
4506 |
|
# except ClientException as e: |
4507 |
|
# print(str(e)) |
4508 |
|
# exit(1) |
4509 |
|
|
4510 |
|
|
4511 |
1 |
@cli_osm.command(name="repo-list") |
4512 |
1 |
@click.option( |
4513 |
|
"--filter", |
4514 |
|
default=None, |
4515 |
|
multiple=True, |
4516 |
|
help="restricts the list to the repos matching the filter", |
4517 |
|
) |
4518 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
4519 |
1 |
@click.pass_context |
4520 |
1 |
def repo_list(ctx, filter, literal): |
4521 |
|
"""list all repos""" |
4522 |
|
# try: |
4523 |
|
# K8s Repositories |
4524 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4525 |
0 |
if filter: |
4526 |
0 |
filter = "&".join(filter) |
4527 |
0 |
resp = ctx.obj.repo.list(filter) |
4528 |
0 |
resp += ctx.obj.osmrepo.list(filter) |
4529 |
0 |
if literal: |
4530 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
4531 |
0 |
return |
4532 |
0 |
table = PrettyTable(["Name", "Id", "Type", "URI", "Description"]) |
4533 |
0 |
for repo in resp: |
4534 |
|
# cluster['k8s-nets'] = json.dumps(yaml.safe_load(cluster['k8s-nets'])) |
4535 |
0 |
table.add_row( |
4536 |
|
[ |
4537 |
|
repo["name"], |
4538 |
|
repo["_id"], |
4539 |
|
repo["type"], |
4540 |
|
repo["url"], |
4541 |
|
trunc_text(repo.get("description") or "", 40), |
4542 |
|
] |
4543 |
|
) |
4544 |
0 |
table.align = "l" |
4545 |
0 |
print(table) |
4546 |
|
|
4547 |
|
# except ClientException as e: |
4548 |
|
# print(str(e)) |
4549 |
|
# exit(1) |
4550 |
|
|
4551 |
|
|
4552 |
1 |
@cli_osm.command(name="repo-show", short_help="shows the details of a repo") |
4553 |
1 |
@click.argument("name") |
4554 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
4555 |
1 |
@click.pass_context |
4556 |
1 |
def repo_show(ctx, name, literal): |
4557 |
|
"""shows the details of a repo |
4558 |
|
|
4559 |
|
NAME: name or ID of the repo |
4560 |
|
""" |
4561 |
0 |
try: |
4562 |
0 |
resp = ctx.obj.repo.get(name) |
4563 |
0 |
except NotFound: |
4564 |
0 |
resp = ctx.obj.osmrepo.get(name) |
4565 |
|
|
4566 |
0 |
if literal: |
4567 |
0 |
if resp: |
4568 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
4569 |
0 |
return |
4570 |
0 |
table = PrettyTable(["key", "attribute"]) |
4571 |
0 |
if resp: |
4572 |
0 |
for k, v in list(resp.items()): |
4573 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
4574 |
|
|
4575 |
0 |
table.align = "l" |
4576 |
0 |
print(table) |
4577 |
|
# except ClientException as e: |
4578 |
|
# print(str(e)) |
4579 |
|
# exit(1) |
4580 |
|
|
4581 |
|
|
4582 |
|
#################### |
4583 |
|
# Project mgmt operations |
4584 |
|
#################### |
4585 |
|
|
4586 |
|
|
4587 |
1 |
@cli_osm.command(name="project-create", short_help="creates a new project") |
4588 |
1 |
@click.argument("name") |
4589 |
|
# @click.option('--description', |
4590 |
|
# default='no description', |
4591 |
|
# help='human readable description') |
4592 |
1 |
@click.option("--domain-name", "domain_name", default=None, help="assign to a domain") |
4593 |
1 |
@click.option( |
4594 |
|
"--quotas", |
4595 |
|
"quotas", |
4596 |
|
multiple=True, |
4597 |
|
default=None, |
4598 |
|
help="provide quotas. Can be used several times: 'quota1=number[,quota2=number,...]'. Quotas can be one " |
4599 |
|
"of vnfds, nsds, nsts, pdus, nsrs, nsis, vim_accounts, wim_accounts, sdns, k8sclusters, k8srepos", |
4600 |
|
) |
4601 |
1 |
@click.pass_context |
4602 |
1 |
def project_create(ctx, name, domain_name, quotas): |
4603 |
|
"""Creates a new project |
4604 |
|
|
4605 |
|
NAME: name of the project |
4606 |
|
DOMAIN_NAME: optional domain name for the project when keystone authentication is used |
4607 |
|
QUOTAS: set quotas for the project |
4608 |
|
""" |
4609 |
0 |
logger.debug("") |
4610 |
0 |
project = {"name": name} |
4611 |
0 |
if domain_name: |
4612 |
0 |
project["domain_name"] = domain_name |
4613 |
0 |
quotas_dict = _process_project_quotas(quotas) |
4614 |
0 |
if quotas_dict: |
4615 |
0 |
project["quotas"] = quotas_dict |
4616 |
|
|
4617 |
|
# try: |
4618 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4619 |
0 |
ctx.obj.project.create(name, project) |
4620 |
|
# except ClientException as e: |
4621 |
|
# print(str(e)) |
4622 |
|
# exit(1) |
4623 |
|
|
4624 |
|
|
4625 |
1 |
def _process_project_quotas(quota_list): |
4626 |
0 |
quotas_dict = {} |
4627 |
0 |
if not quota_list: |
4628 |
0 |
return quotas_dict |
4629 |
0 |
try: |
4630 |
0 |
for quota in quota_list: |
4631 |
0 |
for single_quota in quota.split(","): |
4632 |
0 |
k, v = single_quota.split("=") |
4633 |
0 |
quotas_dict[k] = None if v in ("None", "null", "") else int(v) |
4634 |
0 |
except (ValueError, TypeError): |
4635 |
0 |
raise ClientException( |
4636 |
|
"invalid format for 'quotas'. Use 'k1=v1,v1=v2'. v must be a integer or null" |
4637 |
|
) |
4638 |
0 |
return quotas_dict |
4639 |
|
|
4640 |
|
|
4641 |
1 |
@cli_osm.command(name="project-delete", short_help="deletes a project") |
4642 |
1 |
@click.argument("name") |
4643 |
|
# @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
4644 |
1 |
@click.pass_context |
4645 |
1 |
def project_delete(ctx, name): |
4646 |
|
"""deletes a project |
4647 |
|
|
4648 |
|
NAME: name or ID of the project to be deleted |
4649 |
|
""" |
4650 |
0 |
logger.debug("") |
4651 |
|
# try: |
4652 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4653 |
0 |
ctx.obj.project.delete(name) |
4654 |
|
# except ClientException as e: |
4655 |
|
# print(str(e)) |
4656 |
|
# exit(1) |
4657 |
|
|
4658 |
|
|
4659 |
1 |
@cli_osm.command(name="project-list", short_help="list all projects") |
4660 |
1 |
@click.option( |
4661 |
|
"--filter", |
4662 |
|
default=None, |
4663 |
|
multiple=True, |
4664 |
|
help="restricts the list to the projects matching the filter", |
4665 |
|
) |
4666 |
1 |
@click.pass_context |
4667 |
1 |
def project_list(ctx, filter): |
4668 |
|
"""list all projects""" |
4669 |
0 |
logger.debug("") |
4670 |
|
# try: |
4671 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4672 |
0 |
if filter: |
4673 |
0 |
filter = "&".join(filter) |
4674 |
0 |
resp = ctx.obj.project.list(filter) |
4675 |
|
# except ClientException as e: |
4676 |
|
# print(str(e)) |
4677 |
|
# exit(1) |
4678 |
0 |
table = PrettyTable(["name", "id"]) |
4679 |
0 |
for proj in resp: |
4680 |
0 |
table.add_row([proj["name"], proj["_id"]]) |
4681 |
0 |
table.align = "l" |
4682 |
0 |
print(table) |
4683 |
|
|
4684 |
|
|
4685 |
1 |
@cli_osm.command(name="project-show", short_help="shows the details of a project") |
4686 |
1 |
@click.argument("name") |
4687 |
1 |
@click.pass_context |
4688 |
1 |
def project_show(ctx, name): |
4689 |
|
"""shows the details of a project |
4690 |
|
|
4691 |
|
NAME: name or ID of the project |
4692 |
|
""" |
4693 |
0 |
logger.debug("") |
4694 |
|
# try: |
4695 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4696 |
0 |
resp = ctx.obj.project.get(name) |
4697 |
|
# except ClientException as e: |
4698 |
|
# print(str(e)) |
4699 |
|
# exit(1) |
4700 |
|
|
4701 |
0 |
table = PrettyTable(["key", "attribute"]) |
4702 |
0 |
for k, v in resp.items(): |
4703 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
4704 |
0 |
table.align = "l" |
4705 |
0 |
print(table) |
4706 |
|
|
4707 |
|
|
4708 |
1 |
@cli_osm.command( |
4709 |
|
name="project-update", short_help="updates a project (only the name can be updated)" |
4710 |
|
) |
4711 |
1 |
@click.argument("project") |
4712 |
1 |
@click.option("--name", default=None, help="new name for the project") |
4713 |
1 |
@click.option( |
4714 |
|
"--quotas", |
4715 |
|
"quotas", |
4716 |
|
multiple=True, |
4717 |
|
default=None, |
4718 |
|
help="change quotas. Can be used several times: 'quota1=number|empty[,quota2=...]' " |
4719 |
|
"(use empty to reset quota to default", |
4720 |
|
) |
4721 |
1 |
@click.pass_context |
4722 |
1 |
def project_update(ctx, project, name, quotas): |
4723 |
|
""" |
4724 |
|
Update a project name |
4725 |
|
|
4726 |
|
:param ctx: |
4727 |
|
:param project: id or name of the project to modify |
4728 |
|
:param name: new name for the project |
4729 |
|
:param quotas: change quotas of the project |
4730 |
|
:return: |
4731 |
|
""" |
4732 |
0 |
logger.debug("") |
4733 |
0 |
project_changes = {} |
4734 |
0 |
if name: |
4735 |
0 |
project_changes["name"] = name |
4736 |
0 |
quotas_dict = _process_project_quotas(quotas) |
4737 |
0 |
if quotas_dict: |
4738 |
0 |
project_changes["quotas"] = quotas_dict |
4739 |
|
|
4740 |
|
# try: |
4741 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4742 |
0 |
ctx.obj.project.update(project, project_changes) |
4743 |
|
# except ClientException as e: |
4744 |
|
# print(str(e)) |
4745 |
|
|
4746 |
|
|
4747 |
|
#################### |
4748 |
|
# User mgmt operations |
4749 |
|
#################### |
4750 |
|
|
4751 |
|
|
4752 |
1 |
@cli_osm.command(name="user-create", short_help="creates a new user") |
4753 |
1 |
@click.argument("username") |
4754 |
1 |
@click.option( |
4755 |
|
"--password", |
4756 |
|
prompt=True, |
4757 |
|
hide_input=True, |
4758 |
|
confirmation_prompt=True, |
4759 |
|
help="user password", |
4760 |
|
) |
4761 |
1 |
@click.option( |
4762 |
|
"--projects", |
4763 |
|
# prompt="Comma separate list of projects", |
4764 |
|
multiple=True, |
4765 |
|
callback=lambda ctx, param, value: "".join(value).split(",") |
4766 |
|
if all(len(x) == 1 for x in value) |
4767 |
|
else value, |
4768 |
|
help="list of project ids that the user belongs to", |
4769 |
|
) |
4770 |
1 |
@click.option( |
4771 |
|
"--project-role-mappings", |
4772 |
|
"project_role_mappings", |
4773 |
|
default=None, |
4774 |
|
multiple=True, |
4775 |
|
help="assign role(s) in a project. Can be used several times: 'project,role1[,role2,...]'", |
4776 |
|
) |
4777 |
1 |
@click.option("--domain-name", "domain_name", default=None, help="assign to a domain") |
4778 |
1 |
@click.pass_context |
4779 |
1 |
def user_create(ctx, username, password, projects, project_role_mappings, domain_name): |
4780 |
|
"""Creates a new user |
4781 |
|
|
4782 |
|
\b |
4783 |
|
USERNAME: name of the user |
4784 |
|
PASSWORD: password of the user |
4785 |
|
PROJECTS: projects assigned to user (internal only) |
4786 |
|
PROJECT_ROLE_MAPPING: roles in projects assigned to user (keystone) |
4787 |
|
DOMAIN_NAME: optional domain name for the user when keystone authentication is used |
4788 |
|
""" |
4789 |
0 |
logger.debug("") |
4790 |
0 |
user = {} |
4791 |
0 |
user["username"] = username |
4792 |
0 |
user["password"] = password |
4793 |
0 |
user["projects"] = projects |
4794 |
0 |
user["project_role_mappings"] = project_role_mappings |
4795 |
0 |
if domain_name: |
4796 |
0 |
user["domain_name"] = domain_name |
4797 |
|
|
4798 |
|
# try: |
4799 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4800 |
0 |
ctx.obj.user.create(username, user) |
4801 |
|
# except ClientException as e: |
4802 |
|
# print(str(e)) |
4803 |
|
# exit(1) |
4804 |
|
|
4805 |
|
|
4806 |
1 |
@cli_osm.command(name="user-update", short_help="updates user information") |
4807 |
1 |
@click.argument("username") |
4808 |
1 |
@click.option( |
4809 |
|
"--password", |
4810 |
|
# prompt=True, |
4811 |
|
# hide_input=True, |
4812 |
|
# confirmation_prompt=True, |
4813 |
|
help="user password", |
4814 |
|
) |
4815 |
1 |
@click.option("--set-username", "set_username", default=None, help="change username") |
4816 |
1 |
@click.option( |
4817 |
|
"--set-project", |
4818 |
|
"set_project", |
4819 |
|
default=None, |
4820 |
|
multiple=True, |
4821 |
|
help="create/replace the roles for this project: 'project,role1[,role2,...]'", |
4822 |
|
) |
4823 |
1 |
@click.option( |
4824 |
|
"--remove-project", |
4825 |
|
"remove_project", |
4826 |
|
default=None, |
4827 |
|
multiple=True, |
4828 |
|
help="removes project from user: 'project'", |
4829 |
|
) |
4830 |
1 |
@click.option( |
4831 |
|
"--add-project-role", |
4832 |
|
"add_project_role", |
4833 |
|
default=None, |
4834 |
|
multiple=True, |
4835 |
|
help="assign role(s) in a project. Can be used several times: 'project,role1[,role2,...]'", |
4836 |
|
) |
4837 |
1 |
@click.option( |
4838 |
|
"--remove-project-role", |
4839 |
|
"remove_project_role", |
4840 |
|
default=None, |
4841 |
|
multiple=True, |
4842 |
|
help="remove role(s) in a project. Can be used several times: 'project,role1[,role2,...]'", |
4843 |
|
) |
4844 |
1 |
@click.pass_context |
4845 |
1 |
def user_update( |
4846 |
|
ctx, |
4847 |
|
username, |
4848 |
|
password, |
4849 |
|
set_username, |
4850 |
|
set_project, |
4851 |
|
remove_project, |
4852 |
|
add_project_role, |
4853 |
|
remove_project_role, |
4854 |
|
): |
4855 |
|
"""Update a user information |
4856 |
|
|
4857 |
|
\b |
4858 |
|
USERNAME: name of the user |
4859 |
|
PASSWORD: new password |
4860 |
|
SET_USERNAME: new username |
4861 |
|
SET_PROJECT: creating mappings for project/role(s) |
4862 |
|
REMOVE_PROJECT: deleting mappings for project/role(s) |
4863 |
|
ADD_PROJECT_ROLE: adding mappings for project/role(s) |
4864 |
|
REMOVE_PROJECT_ROLE: removing mappings for project/role(s) |
4865 |
|
""" |
4866 |
0 |
logger.debug("") |
4867 |
0 |
user = {} |
4868 |
0 |
user["password"] = password |
4869 |
0 |
user["username"] = set_username |
4870 |
0 |
user["set-project"] = set_project |
4871 |
0 |
user["remove-project"] = remove_project |
4872 |
0 |
user["add-project-role"] = add_project_role |
4873 |
0 |
user["remove-project-role"] = remove_project_role |
4874 |
|
|
4875 |
|
# try: |
4876 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4877 |
0 |
ctx.obj.user.update(username, user) |
4878 |
|
# except ClientException as e: |
4879 |
|
# print(str(e)) |
4880 |
|
# exit(1) |
4881 |
|
|
4882 |
|
|
4883 |
1 |
@cli_osm.command(name="user-delete", short_help="deletes a user") |
4884 |
1 |
@click.argument("name") |
4885 |
|
# @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
4886 |
1 |
@click.pass_context |
4887 |
1 |
def user_delete(ctx, name): |
4888 |
|
"""deletes a user |
4889 |
|
|
4890 |
|
\b |
4891 |
|
NAME: name or ID of the user to be deleted |
4892 |
|
""" |
4893 |
0 |
logger.debug("") |
4894 |
|
# try: |
4895 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4896 |
0 |
ctx.obj.user.delete(name) |
4897 |
|
# except ClientException as e: |
4898 |
|
# print(str(e)) |
4899 |
|
# exit(1) |
4900 |
|
|
4901 |
|
|
4902 |
1 |
@cli_osm.command(name="user-list", short_help="list all users") |
4903 |
1 |
@click.option( |
4904 |
|
"--filter", |
4905 |
|
default=None, |
4906 |
|
multiple=True, |
4907 |
|
help="restricts the list to the users matching the filter", |
4908 |
|
) |
4909 |
1 |
@click.pass_context |
4910 |
1 |
def user_list(ctx, filter): |
4911 |
|
"""list all users""" |
4912 |
|
# try: |
4913 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4914 |
0 |
if filter: |
4915 |
0 |
filter = "&".join(filter) |
4916 |
0 |
resp = ctx.obj.user.list(filter) |
4917 |
|
# except ClientException as e: |
4918 |
|
# print(str(e)) |
4919 |
|
# exit(1) |
4920 |
0 |
table = PrettyTable(["name", "id"]) |
4921 |
0 |
for user in resp: |
4922 |
0 |
table.add_row([user["username"], user["_id"]]) |
4923 |
0 |
table.align = "l" |
4924 |
0 |
print(table) |
4925 |
|
|
4926 |
|
|
4927 |
1 |
@cli_osm.command(name="user-show", short_help="shows the details of a user") |
4928 |
1 |
@click.argument("name") |
4929 |
1 |
@click.pass_context |
4930 |
1 |
def user_show(ctx, name): |
4931 |
|
"""shows the details of a user |
4932 |
|
|
4933 |
|
NAME: name or ID of the user |
4934 |
|
""" |
4935 |
0 |
logger.debug("") |
4936 |
|
# try: |
4937 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
4938 |
0 |
resp = ctx.obj.user.get(name) |
4939 |
0 |
if "password" in resp: |
4940 |
0 |
resp["password"] = "********" |
4941 |
|
# except ClientException as e: |
4942 |
|
# print(str(e)) |
4943 |
|
# exit(1) |
4944 |
|
|
4945 |
0 |
table = PrettyTable(["key", "attribute"]) |
4946 |
0 |
for k, v in resp.items(): |
4947 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
4948 |
0 |
table.align = "l" |
4949 |
0 |
print(table) |
4950 |
|
|
4951 |
|
|
4952 |
|
#################### |
4953 |
|
# Fault Management operations |
4954 |
|
#################### |
4955 |
|
|
4956 |
|
|
4957 |
1 |
@cli_osm.command(name="ns-alarm-create") |
4958 |
1 |
@click.argument("name") |
4959 |
1 |
@click.option("--ns", prompt=True, help="NS instance id or name") |
4960 |
1 |
@click.option( |
4961 |
|
"--vnf", prompt=True, help="VNF name (VNF member index as declared in the NSD)" |
4962 |
|
) |
4963 |
1 |
@click.option("--vdu", prompt=True, help="VDU name (VDU name as declared in the VNFD)") |
4964 |
1 |
@click.option("--metric", prompt=True, help="Name of the metric (e.g. cpu_utilization)") |
4965 |
1 |
@click.option( |
4966 |
|
"--severity", |
4967 |
|
default="WARNING", |
4968 |
|
help="severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)", |
4969 |
|
) |
4970 |
1 |
@click.option( |
4971 |
|
"--threshold_value", |
4972 |
|
prompt=True, |
4973 |
|
help="threshold value that, when crossed, an alarm is triggered", |
4974 |
|
) |
4975 |
1 |
@click.option( |
4976 |
|
"--threshold_operator", |
4977 |
|
prompt=True, |
4978 |
|
help="threshold operator describing the comparison (GE, LE, GT, LT, EQ)", |
4979 |
|
) |
4980 |
1 |
@click.option( |
4981 |
|
"--statistic", |
4982 |
|
default="AVERAGE", |
4983 |
|
help="statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)", |
4984 |
|
) |
4985 |
1 |
@click.pass_context |
4986 |
1 |
def ns_alarm_create( |
4987 |
|
ctx, |
4988 |
|
name, |
4989 |
|
ns, |
4990 |
|
vnf, |
4991 |
|
vdu, |
4992 |
|
metric, |
4993 |
|
severity, |
4994 |
|
threshold_value, |
4995 |
|
threshold_operator, |
4996 |
|
statistic, |
4997 |
|
): |
4998 |
|
"""creates a new alarm for a NS instance""" |
4999 |
|
# TODO: Check how to validate threshold_value. |
5000 |
|
# Should it be an integer (1-100), percentage, or decimal (0.01-1.00)? |
5001 |
0 |
logger.debug("") |
5002 |
|
# try: |
5003 |
0 |
ns_instance = ctx.obj.ns.get(ns) |
5004 |
0 |
alarm = {} |
5005 |
0 |
alarm["alarm_name"] = name |
5006 |
0 |
alarm["ns_id"] = ns_instance["_id"] |
5007 |
0 |
alarm["correlation_id"] = ns_instance["_id"] |
5008 |
0 |
alarm["vnf_member_index"] = vnf |
5009 |
0 |
alarm["vdu_name"] = vdu |
5010 |
0 |
alarm["metric_name"] = metric |
5011 |
0 |
alarm["severity"] = severity |
5012 |
0 |
alarm["threshold_value"] = int(threshold_value) |
5013 |
0 |
alarm["operation"] = threshold_operator |
5014 |
0 |
alarm["statistic"] = statistic |
5015 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5016 |
0 |
ctx.obj.ns.create_alarm(alarm) |
5017 |
|
# except ClientException as e: |
5018 |
|
# print(str(e)) |
5019 |
|
# exit(1) |
5020 |
|
|
5021 |
|
|
5022 |
|
# @cli_osm.command(name='ns-alarm-delete') |
5023 |
|
# @click.argument('name') |
5024 |
|
# @click.pass_context |
5025 |
|
# def ns_alarm_delete(ctx, name): |
5026 |
|
# """deletes an alarm |
5027 |
|
# |
5028 |
|
# NAME: name of the alarm to be deleted |
5029 |
|
# """ |
5030 |
|
# try: |
5031 |
|
# check_client_version(ctx.obj, ctx.command.name) |
5032 |
|
# ctx.obj.ns.delete_alarm(name) |
5033 |
|
# except ClientException as e: |
5034 |
|
# print(str(e)) |
5035 |
|
# exit(1) |
5036 |
|
|
5037 |
|
|
5038 |
|
#################### |
5039 |
|
# Performance Management operations |
5040 |
|
#################### |
5041 |
|
|
5042 |
|
|
5043 |
1 |
@cli_osm.command( |
5044 |
|
name="ns-metric-export", |
5045 |
|
short_help="exports a metric to the internal OSM bus, which can be read by other apps", |
5046 |
|
) |
5047 |
1 |
@click.option("--ns", prompt=True, help="NS instance id or name") |
5048 |
1 |
@click.option( |
5049 |
|
"--vnf", prompt=True, help="VNF name (VNF member index as declared in the NSD)" |
5050 |
|
) |
5051 |
1 |
@click.option("--vdu", prompt=True, help="VDU name (VDU name as declared in the VNFD)") |
5052 |
1 |
@click.option("--metric", prompt=True, help="name of the metric (e.g. cpu_utilization)") |
5053 |
|
# @click.option('--period', default='1w', |
5054 |
|
# help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)') |
5055 |
1 |
@click.option( |
5056 |
|
"--interval", help="periodic interval (seconds) to export metrics continuously" |
5057 |
|
) |
5058 |
1 |
@click.pass_context |
5059 |
1 |
def ns_metric_export(ctx, ns, vnf, vdu, metric, interval): |
5060 |
|
"""exports a metric to the internal OSM bus, which can be read by other apps""" |
5061 |
|
# TODO: Check how to validate interval. |
5062 |
|
# Should it be an integer (seconds), or should a suffix (s,m,h,d,w) also be permitted? |
5063 |
0 |
logger.debug("") |
5064 |
|
# try: |
5065 |
0 |
ns_instance = ctx.obj.ns.get(ns) |
5066 |
0 |
metric_data = {} |
5067 |
0 |
metric_data["ns_id"] = ns_instance["_id"] |
5068 |
0 |
metric_data["correlation_id"] = ns_instance["_id"] |
5069 |
0 |
metric_data["vnf_member_index"] = vnf |
5070 |
0 |
metric_data["vdu_name"] = vdu |
5071 |
0 |
metric_data["metric_name"] = metric |
5072 |
0 |
metric_data["collection_unit"] = "WEEK" |
5073 |
0 |
metric_data["collection_period"] = 1 |
5074 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5075 |
0 |
if not interval: |
5076 |
0 |
print("{}".format(ctx.obj.ns.export_metric(metric_data))) |
5077 |
|
else: |
5078 |
0 |
i = 1 |
5079 |
|
while True: |
5080 |
0 |
print("{} {}".format(ctx.obj.ns.export_metric(metric_data), i)) |
5081 |
0 |
time.sleep(int(interval)) |
5082 |
0 |
i += 1 |
5083 |
|
# except ClientException as e: |
5084 |
|
# print(str(e)) |
5085 |
|
# exit(1) |
5086 |
|
|
5087 |
|
|
5088 |
|
################# |
5089 |
|
# Subscription operations |
5090 |
|
################# |
5091 |
|
|
5092 |
|
|
5093 |
1 |
@cli_osm.command( |
5094 |
|
name="subscription-create", |
5095 |
|
short_help="creates a new subscription to a specific event", |
5096 |
|
) |
5097 |
1 |
@click.option( |
5098 |
|
"--event_type", |
5099 |
|
# type=click.Choice(['ns', 'nspkg', 'vnfpkg'], case_sensitive=False)) |
5100 |
|
type=click.Choice(["ns"], case_sensitive=False), |
5101 |
|
help="event type to be subscribed (for the moment, only ns is supported)", |
5102 |
|
) |
5103 |
1 |
@click.option("--event", default=None, help="specific yaml configuration for the event") |
5104 |
1 |
@click.option( |
5105 |
|
"--event_file", default=None, help="specific yaml configuration file for the event" |
5106 |
|
) |
5107 |
1 |
@click.pass_context |
5108 |
1 |
def subscription_create(ctx, event_type, event, event_file): |
5109 |
|
"""creates a new subscription to a specific event""" |
5110 |
0 |
logger.debug("") |
5111 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5112 |
0 |
if event_file: |
5113 |
0 |
if event: |
5114 |
0 |
raise ClientException( |
5115 |
|
'"--event" option is incompatible with "--event_file" option' |
5116 |
|
) |
5117 |
0 |
with open(event_file, "r") as cf: |
5118 |
0 |
event = cf.read() |
5119 |
0 |
ctx.obj.subscription.create(event_type, event) |
5120 |
|
|
5121 |
|
|
5122 |
1 |
@cli_osm.command(name="subscription-delete", short_help="deletes a subscription") |
5123 |
1 |
@click.option( |
5124 |
|
"--event_type", |
5125 |
|
# type=click.Choice(['ns', 'nspkg', 'vnfpkg'], case_sensitive=False)) |
5126 |
|
type=click.Choice(["ns"], case_sensitive=False), |
5127 |
|
help="event type to be subscribed (for the moment, only ns is supported)", |
5128 |
|
) |
5129 |
1 |
@click.argument("subscription_id") |
5130 |
1 |
@click.option( |
5131 |
|
"--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
5132 |
|
) |
5133 |
1 |
@click.pass_context |
5134 |
1 |
def subscription_delete(ctx, event_type, subscription_id, force): |
5135 |
|
"""deletes a subscription |
5136 |
|
|
5137 |
|
SUBSCRIPTION_ID: ID of the subscription to be deleted |
5138 |
|
""" |
5139 |
0 |
logger.debug("") |
5140 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5141 |
0 |
ctx.obj.subscription.delete(event_type, subscription_id, force) |
5142 |
|
|
5143 |
|
|
5144 |
1 |
@cli_osm.command(name="subscription-list", short_help="list all subscriptions") |
5145 |
1 |
@click.option( |
5146 |
|
"--event_type", |
5147 |
|
# type=click.Choice(['ns', 'nspkg', 'vnfpkg'], case_sensitive=False)) |
5148 |
|
type=click.Choice(["ns"], case_sensitive=False), |
5149 |
|
help="event type to be subscribed (for the moment, only ns is supported)", |
5150 |
|
) |
5151 |
1 |
@click.option( |
5152 |
|
"--filter", |
5153 |
|
default=None, |
5154 |
|
multiple=True, |
5155 |
|
help="restricts the list to the subscriptions matching the filter", |
5156 |
|
) |
5157 |
1 |
@click.pass_context |
5158 |
1 |
def subscription_list(ctx, event_type, filter): |
5159 |
|
"""list all subscriptions""" |
5160 |
0 |
logger.debug("") |
5161 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5162 |
0 |
if filter: |
5163 |
0 |
filter = "&".join(filter) |
5164 |
0 |
resp = ctx.obj.subscription.list(event_type, filter) |
5165 |
0 |
table = PrettyTable(["id", "filter", "CallbackUri"]) |
5166 |
0 |
for sub in resp: |
5167 |
0 |
table.add_row( |
5168 |
|
[ |
5169 |
|
sub["_id"], |
5170 |
|
wrap_text(text=json.dumps(sub["filter"], indent=2), width=70), |
5171 |
|
sub["CallbackUri"], |
5172 |
|
] |
5173 |
|
) |
5174 |
0 |
table.align = "l" |
5175 |
0 |
print(table) |
5176 |
|
|
5177 |
|
|
5178 |
1 |
@cli_osm.command( |
5179 |
|
name="subscription-show", short_help="shows the details of a subscription" |
5180 |
|
) |
5181 |
1 |
@click.argument("subscription_id") |
5182 |
1 |
@click.option( |
5183 |
|
"--event_type", |
5184 |
|
# type=click.Choice(['ns', 'nspkg', 'vnfpkg'], case_sensitive=False)) |
5185 |
|
type=click.Choice(["ns"], case_sensitive=False), |
5186 |
|
help="event type to be subscribed (for the moment, only ns is supported)", |
5187 |
|
) |
5188 |
1 |
@click.option( |
5189 |
|
"--filter", |
5190 |
|
multiple=True, |
5191 |
|
help="restricts the information to the fields in the filter", |
5192 |
|
) |
5193 |
1 |
@click.pass_context |
5194 |
1 |
def subscription_show(ctx, event_type, subscription_id, filter): |
5195 |
|
"""shows the details of a subscription |
5196 |
|
|
5197 |
|
SUBSCRIPTION_ID: ID of the subscription |
5198 |
|
""" |
5199 |
0 |
logger.debug("") |
5200 |
|
# try: |
5201 |
0 |
resp = ctx.obj.subscription.get(subscription_id) |
5202 |
0 |
table = PrettyTable(["key", "attribute"]) |
5203 |
0 |
for k, v in list(resp.items()): |
5204 |
0 |
if not filter or k in filter: |
5205 |
0 |
table.add_row([k, wrap_text(text=json.dumps(v, indent=2), width=100)]) |
5206 |
0 |
table.align = "l" |
5207 |
0 |
print(table) |
5208 |
|
|
5209 |
|
|
5210 |
|
#################### |
5211 |
|
# Other operations |
5212 |
|
#################### |
5213 |
|
|
5214 |
|
|
5215 |
1 |
@cli_osm.command(name="version", short_help="shows client and server versions") |
5216 |
1 |
@click.pass_context |
5217 |
1 |
def get_version(ctx): |
5218 |
|
"""shows client and server versions""" |
5219 |
|
# try: |
5220 |
0 |
check_client_version(ctx.obj, "version") |
5221 |
0 |
print("Server version: {}".format(ctx.obj.get_version())) |
5222 |
0 |
print( |
5223 |
|
"Client version: {}".format(pkg_resources.get_distribution("osmclient").version) |
5224 |
|
) |
5225 |
|
# except ClientException as e: |
5226 |
|
# print(str(e)) |
5227 |
|
# exit(1) |
5228 |
|
|
5229 |
|
|
5230 |
1 |
@cli_osm.command( |
5231 |
|
name="upload-package", short_help="uploads a VNF package or NS package" |
5232 |
|
) |
5233 |
1 |
@click.argument("filename") |
5234 |
1 |
@click.option( |
5235 |
|
"--skip-charm-build", |
5236 |
|
default=False, |
5237 |
|
is_flag=True, |
5238 |
|
help="the charm will not be compiled, it is assumed to already exist", |
5239 |
|
) |
5240 |
1 |
@click.pass_context |
5241 |
1 |
def upload_package(ctx, filename, skip_charm_build): |
5242 |
|
"""uploads a vnf package or ns package |
5243 |
|
|
5244 |
|
filename: vnf or ns package folder, or vnf or ns package file (tar.gz) |
5245 |
|
""" |
5246 |
0 |
logger.debug("") |
5247 |
|
# try: |
5248 |
0 |
ctx.obj.package.upload(filename, skip_charm_build=skip_charm_build) |
5249 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
5250 |
0 |
if fullclassname != "osmclient.sol005.client.Client": |
5251 |
0 |
ctx.obj.package.wait_for_upload(filename) |
5252 |
|
# except ClientException as e: |
5253 |
|
# print(str(e)) |
5254 |
|
# exit(1) |
5255 |
|
|
5256 |
|
|
5257 |
|
# @cli_osm.command(name='ns-scaling-show') |
5258 |
|
# @click.argument('ns_name') |
5259 |
|
# @click.pass_context |
5260 |
|
# def show_ns_scaling(ctx, ns_name): |
5261 |
|
# """shows the status of a NS scaling operation |
5262 |
|
# |
5263 |
|
# NS_NAME: name of the NS instance being scaled |
5264 |
|
# """ |
5265 |
|
# try: |
5266 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
5267 |
|
# resp = ctx.obj.ns.list() |
5268 |
|
# except ClientException as e: |
5269 |
|
# print(str(e)) |
5270 |
|
# exit(1) |
5271 |
|
# |
5272 |
|
# table = PrettyTable( |
5273 |
|
# ['group-name', |
5274 |
|
# 'instance-id', |
5275 |
|
# 'operational status', |
5276 |
|
# 'create-time', |
5277 |
|
# 'vnfr ids']) |
5278 |
|
# |
5279 |
|
# for ns in resp: |
5280 |
|
# if ns_name == ns['name']: |
5281 |
|
# nsopdata = ctx.obj.ns.get_opdata(ns['id']) |
5282 |
|
# scaling_records = nsopdata['nsr:nsr']['scaling-group-record'] |
5283 |
|
# for record in scaling_records: |
5284 |
|
# if 'instance' in record: |
5285 |
|
# instances = record['instance'] |
5286 |
|
# for inst in instances: |
5287 |
|
# table.add_row( |
5288 |
|
# [record['scaling-group-name-ref'], |
5289 |
|
# inst['instance-id'], |
5290 |
|
# inst['op-status'], |
5291 |
|
# time.strftime('%Y-%m-%d %H:%M:%S', |
5292 |
|
# time.localtime( |
5293 |
|
# inst['create-time'])), |
5294 |
|
# inst['vnfrs']]) |
5295 |
|
# table.align = 'l' |
5296 |
|
# print(table) |
5297 |
|
|
5298 |
|
|
5299 |
|
# @cli_osm.command(name='ns-scale') |
5300 |
|
# @click.argument('ns_name') |
5301 |
|
# @click.option('--ns_scale_group', prompt=True) |
5302 |
|
# @click.option('--index', prompt=True) |
5303 |
|
# @click.option('--wait', |
5304 |
|
# required=False, |
5305 |
|
# default=False, |
5306 |
|
# is_flag=True, |
5307 |
|
# help='do not return the control immediately, but keep it \ |
5308 |
|
# until the operation is completed, or timeout') |
5309 |
|
# @click.pass_context |
5310 |
|
# def ns_scale(ctx, ns_name, ns_scale_group, index, wait): |
5311 |
|
# """scales NS |
5312 |
|
# |
5313 |
|
# NS_NAME: name of the NS instance to be scaled |
5314 |
|
# """ |
5315 |
|
# try: |
5316 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
5317 |
|
# ctx.obj.ns.scale(ns_name, ns_scale_group, index, wait=wait) |
5318 |
|
# except ClientException as e: |
5319 |
|
# print(str(e)) |
5320 |
|
# exit(1) |
5321 |
|
|
5322 |
|
|
5323 |
|
# @cli_osm.command(name='config-agent-list') |
5324 |
|
# @click.pass_context |
5325 |
|
# def config_agent_list(ctx): |
5326 |
|
# """list config agents""" |
5327 |
|
# try: |
5328 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
5329 |
|
# except ClientException as e: |
5330 |
|
# print(str(e)) |
5331 |
|
# exit(1) |
5332 |
|
# table = PrettyTable(['name', 'account-type', 'details']) |
5333 |
|
# for account in ctx.obj.vca.list(): |
5334 |
|
# table.add_row( |
5335 |
|
# [account['name'], |
5336 |
|
# account['account-type'], |
5337 |
|
# account['juju']]) |
5338 |
|
# table.align = 'l' |
5339 |
|
# print(table) |
5340 |
|
|
5341 |
|
|
5342 |
|
# @cli_osm.command(name='config-agent-delete') |
5343 |
|
# @click.argument('name') |
5344 |
|
# @click.pass_context |
5345 |
|
# def config_agent_delete(ctx, name): |
5346 |
|
# """deletes a config agent |
5347 |
|
# |
5348 |
|
# NAME: name of the config agent to be deleted |
5349 |
|
# """ |
5350 |
|
# try: |
5351 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
5352 |
|
# ctx.obj.vca.delete(name) |
5353 |
|
# except ClientException as e: |
5354 |
|
# print(str(e)) |
5355 |
|
# exit(1) |
5356 |
|
|
5357 |
|
|
5358 |
|
# @cli_osm.command(name='config-agent-add') |
5359 |
|
# @click.option('--name', |
5360 |
|
# prompt=True) |
5361 |
|
# @click.option('--account_type', |
5362 |
|
# prompt=True) |
5363 |
|
# @click.option('--server', |
5364 |
|
# prompt=True) |
5365 |
|
# @click.option('--user', |
5366 |
|
# prompt=True) |
5367 |
|
# @click.option('--secret', |
5368 |
|
# prompt=True, |
5369 |
|
# hide_input=True, |
5370 |
|
# confirmation_prompt=True) |
5371 |
|
# @click.pass_context |
5372 |
|
# def config_agent_add(ctx, name, account_type, server, user, secret): |
5373 |
|
# """adds a config agent""" |
5374 |
|
# try: |
5375 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
5376 |
|
# ctx.obj.vca.create(name, account_type, server, user, secret) |
5377 |
|
# except ClientException as e: |
5378 |
|
# print(str(e)) |
5379 |
|
# exit(1) |
5380 |
|
|
5381 |
|
|
5382 |
|
# @cli_osm.command(name='ro-dump') |
5383 |
|
# @click.pass_context |
5384 |
|
# def ro_dump(ctx): |
5385 |
|
# """shows RO agent information""" |
5386 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
5387 |
|
# resp = ctx.obj.vim.get_resource_orchestrator() |
5388 |
|
# table = PrettyTable(['key', 'attribute']) |
5389 |
|
# for k, v in list(resp.items()): |
5390 |
|
# table.add_row([k, json.dumps(v, indent=2)]) |
5391 |
|
# table.align = 'l' |
5392 |
|
# print(table) |
5393 |
|
|
5394 |
|
|
5395 |
|
# @cli_osm.command(name='vcs-list') |
5396 |
|
# @click.pass_context |
5397 |
|
# def vcs_list(ctx): |
5398 |
|
# check_client_version(ctx.obj, ctx.command.name, 'v1') |
5399 |
|
# resp = ctx.obj.utils.get_vcs_info() |
5400 |
|
# table = PrettyTable(['component name', 'state']) |
5401 |
|
# for component in resp: |
5402 |
|
# table.add_row([component['component_name'], component['state']]) |
5403 |
|
# table.align = 'l' |
5404 |
|
# print(table) |
5405 |
|
|
5406 |
|
|
5407 |
1 |
@cli_osm.command( |
5408 |
|
name="ns-action", short_help="executes an action/primitive over a NS instance" |
5409 |
|
) |
5410 |
1 |
@click.argument("ns_name") |
5411 |
1 |
@click.option( |
5412 |
|
"--vnf_name", |
5413 |
|
default=None, |
5414 |
|
help="member-vnf-index if the target is a vnf instead of a ns)", |
5415 |
|
) |
5416 |
1 |
@click.option("--kdu_name", default=None, help="kdu-name if the target is a kdu)") |
5417 |
1 |
@click.option("--vdu_id", default=None, help="vdu-id if the target is a vdu") |
5418 |
1 |
@click.option( |
5419 |
|
"--vdu_count", default=None, type=int, help="number of vdu instance of this vdu_id" |
5420 |
|
) |
5421 |
1 |
@click.option("--action_name", prompt=True, help="action name") |
5422 |
1 |
@click.option("--params", default=None, help="action params in YAML/JSON inline string") |
5423 |
1 |
@click.option("--params_file", default=None, help="YAML/JSON file with action params") |
5424 |
1 |
@click.option( |
5425 |
|
"--timeout", required=False, default=None, type=int, help="timeout in seconds" |
5426 |
|
) |
5427 |
1 |
@click.option( |
5428 |
|
"--wait", |
5429 |
|
required=False, |
5430 |
|
default=False, |
5431 |
|
is_flag=True, |
5432 |
|
help="do not return the control immediately, but keep it until the operation is completed, or timeout", |
5433 |
|
) |
5434 |
1 |
@click.pass_context |
5435 |
1 |
def ns_action( |
5436 |
|
ctx, |
5437 |
|
ns_name, |
5438 |
|
vnf_name, |
5439 |
|
kdu_name, |
5440 |
|
vdu_id, |
5441 |
|
vdu_count, |
5442 |
|
action_name, |
5443 |
|
params, |
5444 |
|
params_file, |
5445 |
|
timeout, |
5446 |
|
wait, |
5447 |
|
): |
5448 |
|
"""executes an action/primitive over a NS instance |
5449 |
|
|
5450 |
|
NS_NAME: name or ID of the NS instance |
5451 |
|
""" |
5452 |
0 |
logger.debug("") |
5453 |
|
# try: |
5454 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5455 |
0 |
op_data = {} |
5456 |
0 |
if vnf_name: |
5457 |
0 |
op_data["member_vnf_index"] = vnf_name |
5458 |
0 |
if kdu_name: |
5459 |
0 |
op_data["kdu_name"] = kdu_name |
5460 |
0 |
if vdu_id: |
5461 |
0 |
op_data["vdu_id"] = vdu_id |
5462 |
0 |
if vdu_count is not None: |
5463 |
0 |
op_data["vdu_count_index"] = vdu_count |
5464 |
0 |
if timeout: |
5465 |
0 |
op_data["timeout_ns_action"] = timeout |
5466 |
0 |
op_data["primitive"] = action_name |
5467 |
0 |
if params_file: |
5468 |
0 |
with open(params_file, "r") as pf: |
5469 |
0 |
params = pf.read() |
5470 |
0 |
if params: |
5471 |
0 |
op_data["primitive_params"] = yaml.safe_load(params) |
5472 |
|
else: |
5473 |
0 |
op_data["primitive_params"] = {} |
5474 |
0 |
print(ctx.obj.ns.exec_op(ns_name, op_name="action", op_data=op_data, wait=wait)) |
5475 |
|
|
5476 |
|
# except ClientException as e: |
5477 |
|
# print(str(e)) |
5478 |
|
# exit(1) |
5479 |
|
|
5480 |
|
|
5481 |
1 |
@cli_osm.command( |
5482 |
|
name="vnf-scale", short_help="executes a VNF scale (adding/removing VDUs)" |
5483 |
|
) |
5484 |
1 |
@click.argument("ns_name") |
5485 |
1 |
@click.argument("vnf_name") |
5486 |
1 |
@click.option( |
5487 |
|
"--scaling-group", prompt=True, help="scaling-group-descriptor name to use" |
5488 |
|
) |
5489 |
1 |
@click.option( |
5490 |
|
"--scale-in", default=False, is_flag=True, help="performs a scale in operation" |
5491 |
|
) |
5492 |
1 |
@click.option( |
5493 |
|
"--scale-out", |
5494 |
|
default=False, |
5495 |
|
is_flag=True, |
5496 |
|
help="performs a scale out operation (by default)", |
5497 |
|
) |
5498 |
1 |
@click.option( |
5499 |
|
"--timeout", required=False, default=None, type=int, help="timeout in seconds" |
5500 |
|
) |
5501 |
1 |
@click.option( |
5502 |
|
"--wait", |
5503 |
|
required=False, |
5504 |
|
default=False, |
5505 |
|
is_flag=True, |
5506 |
|
help="do not return the control immediately, but keep it until the operation is completed, or timeout", |
5507 |
|
) |
5508 |
1 |
@click.pass_context |
5509 |
1 |
def vnf_scale( |
5510 |
|
ctx, ns_name, vnf_name, scaling_group, scale_in, scale_out, timeout, wait |
5511 |
|
): |
5512 |
|
""" |
5513 |
|
Executes a VNF scale (adding/removing VDUs) |
5514 |
|
|
5515 |
|
\b |
5516 |
|
NS_NAME: name or ID of the NS instance. |
5517 |
|
VNF_NAME: member-vnf-index in the NS to be scaled. |
5518 |
|
""" |
5519 |
0 |
logger.debug("") |
5520 |
|
# try: |
5521 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5522 |
0 |
if not scale_in and not scale_out: |
5523 |
0 |
scale_out = True |
5524 |
0 |
ctx.obj.ns.scale_vnf( |
5525 |
|
ns_name, vnf_name, scaling_group, scale_in, scale_out, wait, timeout |
5526 |
|
) |
5527 |
|
# except ClientException as e: |
5528 |
|
# print(str(e)) |
5529 |
|
# exit(1) |
5530 |
|
|
5531 |
|
|
5532 |
1 |
@cli_osm.command(name="alarm-show", short_help="show alarm details") |
5533 |
1 |
@click.argument("uuid") |
5534 |
1 |
@click.pass_context |
5535 |
1 |
def alarm_show(ctx, uuid): |
5536 |
|
"""Show alarm's detail information""" |
5537 |
|
|
5538 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5539 |
0 |
resp = ctx.obj.ns.get_alarm(uuid=uuid) |
5540 |
0 |
alarm_filter = [ |
5541 |
|
"uuid", |
5542 |
|
"name", |
5543 |
|
"metric", |
5544 |
|
"statistic", |
5545 |
|
"threshold", |
5546 |
|
"operation", |
5547 |
|
"ns-id", |
5548 |
|
"vnf-id", |
5549 |
|
"vdu_name", |
5550 |
|
"action", |
5551 |
|
"status", |
5552 |
|
] |
5553 |
0 |
table = PrettyTable(["key", "attribute"]) |
5554 |
0 |
try: |
5555 |
|
# Arrange and return the response data |
5556 |
0 |
resp = resp.replace("ObjectId", "") |
5557 |
0 |
alarm = eval(resp) |
5558 |
0 |
for key in alarm_filter: |
5559 |
0 |
if key == "uuid": |
5560 |
0 |
value = alarm.get(key) |
5561 |
0 |
key = "alarm-id" |
5562 |
0 |
elif key == "name": |
5563 |
0 |
value = alarm.get(key) |
5564 |
0 |
key = "alarm-name" |
5565 |
0 |
elif key == "ns-id": |
5566 |
0 |
value = alarm["tags"].get("ns_id") |
5567 |
0 |
elif key == "vdu_name": |
5568 |
0 |
value = alarm["tags"].get("vdu_name") |
5569 |
0 |
elif key == "status": |
5570 |
0 |
value = alarm["alarm_status"] |
5571 |
|
else: |
5572 |
0 |
value = alarm[key] |
5573 |
0 |
table.add_row([key, wrap_text(text=json.dumps(value, indent=2), width=100)]) |
5574 |
0 |
table.align = "l" |
5575 |
0 |
print(table) |
5576 |
0 |
except Exception: |
5577 |
0 |
print(resp) |
5578 |
|
|
5579 |
|
|
5580 |
|
# List alarm |
5581 |
1 |
@cli_osm.command(name="alarm-list", short_help="list all alarms") |
5582 |
1 |
@click.option( |
5583 |
|
"--ns_id", default=None, required=False, help="List out alarm for given ns id" |
5584 |
|
) |
5585 |
1 |
@click.pass_context |
5586 |
1 |
def alarm_list(ctx, ns_id): |
5587 |
|
"""list all alarm""" |
5588 |
|
|
5589 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5590 |
0 |
project_name = os.getenv("OSM_PROJECT", "admin") |
5591 |
0 |
resp = ctx.obj.ns.get_alarm(project_name=project_name, ns_id=ns_id) |
5592 |
|
|
5593 |
0 |
table = PrettyTable( |
5594 |
|
["alarm-id", "metric", "threshold", "operation", "action", "status"] |
5595 |
|
) |
5596 |
0 |
if resp: |
5597 |
|
# return the response data in a table |
5598 |
0 |
resp = resp.replace("ObjectId", "") |
5599 |
0 |
resp = eval(resp) |
5600 |
0 |
for alarm in resp: |
5601 |
0 |
table.add_row( |
5602 |
|
[ |
5603 |
|
wrap_text(text=str(alarm["uuid"]), width=38), |
5604 |
|
alarm["metric"], |
5605 |
|
alarm["threshold"], |
5606 |
|
alarm["operation"], |
5607 |
|
wrap_text(text=alarm["action"], width=25), |
5608 |
|
alarm["alarm_status"], |
5609 |
|
] |
5610 |
|
) |
5611 |
0 |
table.align = "l" |
5612 |
0 |
print(table) |
5613 |
|
|
5614 |
|
|
5615 |
|
# Update alarm |
5616 |
1 |
@cli_osm.command(name="alarm-update", short_help="Update a alarm") |
5617 |
1 |
@click.argument("uuid") |
5618 |
1 |
@click.option("--threshold", default=None, help="Alarm threshold") |
5619 |
1 |
@click.option("--is_enable", default=None, type=bool, help="enable or disable alarm") |
5620 |
1 |
@click.pass_context |
5621 |
1 |
def alarm_update(ctx, uuid, threshold, is_enable): |
5622 |
|
""" |
5623 |
|
Update alarm |
5624 |
|
|
5625 |
|
""" |
5626 |
0 |
if not threshold and is_enable is None: |
5627 |
0 |
raise ClientException( |
5628 |
|
"Please provide option to update i.e threshold or is_enable" |
5629 |
|
) |
5630 |
0 |
ctx.obj.ns.update_alarm(uuid, threshold, is_enable) |
5631 |
|
|
5632 |
|
|
5633 |
|
############################## |
5634 |
|
# Role Management Operations # |
5635 |
|
############################## |
5636 |
|
|
5637 |
|
|
5638 |
1 |
@cli_osm.command(name="role-create", short_help="creates a new role") |
5639 |
1 |
@click.argument("name") |
5640 |
1 |
@click.option("--permissions", default=None, help="role permissions using a dictionary") |
5641 |
1 |
@click.pass_context |
5642 |
1 |
def role_create(ctx, name, permissions): |
5643 |
|
""" |
5644 |
|
Creates a new role. |
5645 |
|
|
5646 |
|
\b |
5647 |
|
NAME: Name or ID of the role. |
5648 |
|
DEFINITION: Definition of grant/denial of access to resources. |
5649 |
|
""" |
5650 |
0 |
logger.debug("") |
5651 |
|
# try: |
5652 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5653 |
0 |
ctx.obj.role.create(name, permissions) |
5654 |
|
# except ClientException as e: |
5655 |
|
# print(str(e)) |
5656 |
|
# exit(1) |
5657 |
|
|
5658 |
|
|
5659 |
1 |
@cli_osm.command(name="role-update", short_help="updates a role") |
5660 |
1 |
@click.argument("name") |
5661 |
1 |
@click.option("--set-name", default=None, help="change name of rle") |
5662 |
|
# @click.option('--permissions', |
5663 |
|
# default=None, |
5664 |
|
# help='provide a yaml format dictionary with incremental changes. Values can be bool or None to delete') |
5665 |
1 |
@click.option( |
5666 |
|
"--add", |
5667 |
|
default=None, |
5668 |
|
help="yaml format dictionary with permission: True/False to access grant/denial", |
5669 |
|
) |
5670 |
1 |
@click.option("--remove", default=None, help="yaml format list to remove a permission") |
5671 |
1 |
@click.pass_context |
5672 |
1 |
def role_update(ctx, name, set_name, add, remove): |
5673 |
|
""" |
5674 |
|
Updates a role. |
5675 |
|
|
5676 |
|
\b |
5677 |
|
NAME: Name or ID of the role. |
5678 |
|
DEFINITION: Definition overwrites the old definition. |
5679 |
|
ADD: Grant/denial of access to resource to add. |
5680 |
|
REMOVE: Grant/denial of access to resource to remove. |
5681 |
|
""" |
5682 |
0 |
logger.debug("") |
5683 |
|
# try: |
5684 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5685 |
0 |
ctx.obj.role.update(name, set_name, None, add, remove) |
5686 |
|
# except ClientException as e: |
5687 |
|
# print(str(e)) |
5688 |
|
# exit(1) |
5689 |
|
|
5690 |
|
|
5691 |
1 |
@cli_osm.command(name="role-delete", short_help="deletes a role") |
5692 |
1 |
@click.argument("name") |
5693 |
|
# @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions') |
5694 |
1 |
@click.pass_context |
5695 |
1 |
def role_delete(ctx, name): |
5696 |
|
""" |
5697 |
|
Deletes a role. |
5698 |
|
|
5699 |
|
\b |
5700 |
|
NAME: Name or ID of the role. |
5701 |
|
""" |
5702 |
0 |
logger.debug("") |
5703 |
|
# try: |
5704 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5705 |
0 |
ctx.obj.role.delete(name) |
5706 |
|
# except ClientException as e: |
5707 |
|
# print(str(e)) |
5708 |
|
# exit(1) |
5709 |
|
|
5710 |
|
|
5711 |
1 |
@cli_osm.command(name="role-list", short_help="list all roles") |
5712 |
1 |
@click.option( |
5713 |
|
"--filter", |
5714 |
|
default=None, |
5715 |
|
multiple=True, |
5716 |
|
help="restricts the list to the projects matching the filter", |
5717 |
|
) |
5718 |
1 |
@click.pass_context |
5719 |
1 |
def role_list(ctx, filter): |
5720 |
|
""" |
5721 |
|
List all roles. |
5722 |
|
""" |
5723 |
0 |
logger.debug("") |
5724 |
|
# try: |
5725 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5726 |
0 |
if filter: |
5727 |
0 |
filter = "&".join(filter) |
5728 |
0 |
resp = ctx.obj.role.list(filter) |
5729 |
|
# except ClientException as e: |
5730 |
|
# print(str(e)) |
5731 |
|
# exit(1) |
5732 |
0 |
table = PrettyTable(["name", "id"]) |
5733 |
0 |
for role in resp: |
5734 |
0 |
table.add_row([role["name"], role["_id"]]) |
5735 |
0 |
table.align = "l" |
5736 |
0 |
print(table) |
5737 |
|
|
5738 |
|
|
5739 |
1 |
@cli_osm.command(name="role-show", short_help="show specific role") |
5740 |
1 |
@click.argument("name") |
5741 |
1 |
@click.pass_context |
5742 |
1 |
def role_show(ctx, name): |
5743 |
|
""" |
5744 |
|
Shows the details of a role. |
5745 |
|
|
5746 |
|
\b |
5747 |
|
NAME: Name or ID of the role. |
5748 |
|
""" |
5749 |
0 |
logger.debug("") |
5750 |
|
# try: |
5751 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5752 |
0 |
resp = ctx.obj.role.get(name) |
5753 |
|
# except ClientException as e: |
5754 |
|
# print(str(e)) |
5755 |
|
# exit(1) |
5756 |
|
|
5757 |
0 |
table = PrettyTable(["key", "attribute"]) |
5758 |
0 |
for k, v in resp.items(): |
5759 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
5760 |
0 |
table.align = "l" |
5761 |
0 |
print(table) |
5762 |
|
|
5763 |
|
|
5764 |
1 |
@cli_osm.command(name="package-create", short_help="Create empty NS package structure") |
5765 |
1 |
@click.argument("package-type") |
5766 |
1 |
@click.argument("package-name") |
5767 |
1 |
@click.option( |
5768 |
|
"--base-directory", |
5769 |
|
default=".", |
5770 |
|
help=('(NS/VNF/NST) Set the location for package creation. Default: "."'), |
5771 |
|
) |
5772 |
1 |
@click.option( |
5773 |
|
"--image", |
5774 |
|
default="image-name", |
5775 |
|
help='(VNF) Set the name of the vdu image. Default "image-name"', |
5776 |
|
) |
5777 |
1 |
@click.option( |
5778 |
|
"--vdus", default=1, help="(VNF) Set the number of vdus in a VNF. Default 1" |
5779 |
|
) |
5780 |
1 |
@click.option( |
5781 |
|
"--vcpu", default=1, help="(VNF) Set the number of virtual CPUs in a vdu. Default 1" |
5782 |
|
) |
5783 |
1 |
@click.option( |
5784 |
|
"--memory", |
5785 |
|
default=1024, |
5786 |
|
help="(VNF) Set the memory size (MB) of the vdu. Default 1024", |
5787 |
|
) |
5788 |
1 |
@click.option( |
5789 |
|
"--storage", default=10, help="(VNF) Set the disk size (GB) of the vdu. Default 10" |
5790 |
|
) |
5791 |
1 |
@click.option( |
5792 |
|
"--interfaces", |
5793 |
|
default=0, |
5794 |
|
help="(VNF) Set the number of additional interfaces apart from the management interface. Default 0", |
5795 |
|
) |
5796 |
1 |
@click.option( |
5797 |
|
"--vendor", default="OSM", help='(NS/VNF) Set the descriptor vendor. Default "OSM"' |
5798 |
|
) |
5799 |
1 |
@click.option( |
5800 |
|
"--override", |
5801 |
|
default=False, |
5802 |
|
is_flag=True, |
5803 |
|
help="(NS/VNF/NST) Flag for overriding the package if exists.", |
5804 |
|
) |
5805 |
1 |
@click.option( |
5806 |
|
"--detailed", |
5807 |
|
is_flag=True, |
5808 |
|
default=False, |
5809 |
|
help="(NS/VNF/NST) Flag for generating descriptor .yaml with all possible commented options", |
5810 |
|
) |
5811 |
1 |
@click.option( |
5812 |
|
"--netslice-subnets", default=1, help="(NST) Number of netslice subnets. Default 1" |
5813 |
|
) |
5814 |
1 |
@click.option( |
5815 |
|
"--netslice-vlds", default=1, help="(NST) Number of netslice vlds. Default 1" |
5816 |
|
) |
5817 |
1 |
@click.option( |
5818 |
|
"--old", |
5819 |
|
default=False, |
5820 |
|
is_flag=True, |
5821 |
|
help="Flag to create a descriptor using the previous OSM format (pre SOL006, OSM<9)", |
5822 |
|
) |
5823 |
1 |
@click.pass_context |
5824 |
1 |
def package_create( |
5825 |
|
ctx, |
5826 |
|
package_type, |
5827 |
|
base_directory, |
5828 |
|
package_name, |
5829 |
|
override, |
5830 |
|
image, |
5831 |
|
vdus, |
5832 |
|
vcpu, |
5833 |
|
memory, |
5834 |
|
storage, |
5835 |
|
interfaces, |
5836 |
|
vendor, |
5837 |
|
detailed, |
5838 |
|
netslice_subnets, |
5839 |
|
netslice_vlds, |
5840 |
|
old, |
5841 |
|
): |
5842 |
|
""" |
5843 |
|
Creates an OSM NS, VNF, NST package |
5844 |
|
|
5845 |
|
\b |
5846 |
|
PACKAGE_TYPE: Package to be created: NS, VNF or NST. |
5847 |
|
PACKAGE_NAME: Name of the package to create the folder with the content. |
5848 |
|
""" |
5849 |
|
|
5850 |
|
# try: |
5851 |
0 |
logger.debug("") |
5852 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5853 |
0 |
print( |
5854 |
|
"Creating the {} structure: {}/{}".format( |
5855 |
|
package_type.upper(), base_directory, package_name |
5856 |
|
) |
5857 |
|
) |
5858 |
0 |
resp = ctx.obj.package_tool.create( |
5859 |
|
package_type, |
5860 |
|
base_directory, |
5861 |
|
package_name, |
5862 |
|
override=override, |
5863 |
|
image=image, |
5864 |
|
vdus=vdus, |
5865 |
|
vcpu=vcpu, |
5866 |
|
memory=memory, |
5867 |
|
storage=storage, |
5868 |
|
interfaces=interfaces, |
5869 |
|
vendor=vendor, |
5870 |
|
detailed=detailed, |
5871 |
|
netslice_subnets=netslice_subnets, |
5872 |
|
netslice_vlds=netslice_vlds, |
5873 |
|
old=old, |
5874 |
|
) |
5875 |
0 |
print(resp) |
5876 |
|
# except ClientException as inst: |
5877 |
|
# print("ERROR: {}".format(inst)) |
5878 |
|
# exit(1) |
5879 |
|
|
5880 |
|
|
5881 |
1 |
@cli_osm.command( |
5882 |
|
name="package-validate", short_help="Validate descriptors given a base directory" |
5883 |
|
) |
5884 |
1 |
@click.argument("base-directory", default=".", required=False) |
5885 |
1 |
@click.option( |
5886 |
|
"--recursive/--no-recursive", |
5887 |
|
default=True, |
5888 |
|
help="The activated recursive option will validate the yaml files" |
5889 |
|
" within the indicated directory and in its subdirectories", |
5890 |
|
) |
5891 |
1 |
@click.option( |
5892 |
|
"--old", |
5893 |
|
is_flag=True, |
5894 |
|
default=False, |
5895 |
|
help="Validates also the descriptors using the previous OSM format (pre SOL006)", |
5896 |
|
) |
5897 |
1 |
@click.pass_context |
5898 |
1 |
def package_validate(ctx, base_directory, recursive, old): |
5899 |
|
""" |
5900 |
|
Validate descriptors given a base directory. |
5901 |
|
|
5902 |
|
\b |
5903 |
|
BASE_DIRECTORY: Base folder for NS, VNF or NST package. |
5904 |
|
""" |
5905 |
|
# try: |
5906 |
0 |
logger.debug("") |
5907 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5908 |
0 |
results = ctx.obj.package_tool.validate(base_directory, recursive, old) |
5909 |
0 |
table = PrettyTable() |
5910 |
0 |
table.field_names = ["TYPE", "PATH", "VALID", "ERROR"] |
5911 |
|
# Print the dictionary generated by the validation function |
5912 |
0 |
for result in results: |
5913 |
0 |
table.add_row( |
5914 |
|
[result["type"], result["path"], result["valid"], result["error"]] |
5915 |
|
) |
5916 |
0 |
table.sortby = "VALID" |
5917 |
0 |
table.align["PATH"] = "l" |
5918 |
0 |
table.align["TYPE"] = "l" |
5919 |
0 |
table.align["ERROR"] = "l" |
5920 |
0 |
print(table) |
5921 |
|
# except ClientException as inst: |
5922 |
|
# print("ERROR: {}".format(inst)) |
5923 |
|
# exit(1) |
5924 |
|
|
5925 |
|
|
5926 |
1 |
@cli_osm.command( |
5927 |
|
name="package-translate", short_help="Translate descriptors given a base directory" |
5928 |
|
) |
5929 |
1 |
@click.argument("base-directory", default=".", required=False) |
5930 |
1 |
@click.option( |
5931 |
|
"--recursive/--no-recursive", |
5932 |
|
default=True, |
5933 |
|
help="The activated recursive option will translate the yaml files" |
5934 |
|
" within the indicated directory and in its subdirectories", |
5935 |
|
) |
5936 |
1 |
@click.option( |
5937 |
|
"--dryrun", |
5938 |
|
is_flag=True, |
5939 |
|
default=False, |
5940 |
|
help="Do not translate yet, only make a dry-run to test translation", |
5941 |
|
) |
5942 |
1 |
@click.pass_context |
5943 |
1 |
def package_translate(ctx, base_directory, recursive, dryrun): |
5944 |
|
""" |
5945 |
|
Translate descriptors given a base directory. |
5946 |
|
|
5947 |
|
\b |
5948 |
|
BASE_DIRECTORY: Stub folder for NS, VNF or NST package. |
5949 |
|
""" |
5950 |
0 |
logger.debug("") |
5951 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
5952 |
0 |
results = ctx.obj.package_tool.translate(base_directory, recursive, dryrun) |
5953 |
0 |
table = PrettyTable() |
5954 |
0 |
table.field_names = [ |
5955 |
|
"CURRENT TYPE", |
5956 |
|
"NEW TYPE", |
5957 |
|
"PATH", |
5958 |
|
"VALID", |
5959 |
|
"TRANSLATED", |
5960 |
|
"ERROR", |
5961 |
|
] |
5962 |
|
# Print the dictionary generated by the validation function |
5963 |
0 |
for result in results: |
5964 |
0 |
table.add_row( |
5965 |
|
[ |
5966 |
|
result["current type"], |
5967 |
|
result["new type"], |
5968 |
|
result["path"], |
5969 |
|
result["valid"], |
5970 |
|
result["translated"], |
5971 |
|
result["error"], |
5972 |
|
] |
5973 |
|
) |
5974 |
0 |
table.sortby = "TRANSLATED" |
5975 |
0 |
table.align["PATH"] = "l" |
5976 |
0 |
table.align["TYPE"] = "l" |
5977 |
0 |
table.align["ERROR"] = "l" |
5978 |
0 |
print(table) |
5979 |
|
# except ClientException as inst: |
5980 |
|
# print("ERROR: {}".format(inst)) |
5981 |
|
# exit(1) |
5982 |
|
|
5983 |
|
|
5984 |
1 |
@cli_osm.command(name="package-build", short_help="Build the tar.gz of the package") |
5985 |
1 |
@click.argument("package-folder") |
5986 |
1 |
@click.option( |
5987 |
|
"--skip-validation", default=False, is_flag=True, help="skip package validation" |
5988 |
|
) |
5989 |
1 |
@click.option( |
5990 |
|
"--skip-charm-build", |
5991 |
|
default=False, |
5992 |
|
is_flag=True, |
5993 |
|
help="the charm will not be compiled, it is assumed to already exist", |
5994 |
|
) |
5995 |
1 |
@click.pass_context |
5996 |
1 |
def package_build(ctx, package_folder, skip_validation, skip_charm_build): |
5997 |
|
""" |
5998 |
|
Build the package NS, VNF given the package_folder. |
5999 |
|
|
6000 |
|
\b |
6001 |
|
PACKAGE_FOLDER: Folder of the NS, VNF or NST to be packaged |
6002 |
|
""" |
6003 |
|
# try: |
6004 |
0 |
logger.debug("") |
6005 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
6006 |
0 |
results = ctx.obj.package_tool.build( |
6007 |
|
package_folder, |
6008 |
|
skip_validation=skip_validation, |
6009 |
|
skip_charm_build=skip_charm_build, |
6010 |
|
) |
6011 |
0 |
print(results) |
6012 |
|
# except ClientException as inst: |
6013 |
|
# print("ERROR: {}".format(inst)) |
6014 |
|
# exit(1) |
6015 |
|
|
6016 |
|
|
6017 |
1 |
@cli_osm.command( |
6018 |
|
name="descriptor-translate", |
6019 |
|
short_help="Translate input descriptor file from Rel EIGHT OSM descriptors to SOL006 and prints in standard output", |
6020 |
|
) |
6021 |
1 |
@click.argument("descriptor-file", required=True) |
6022 |
1 |
@click.pass_context |
6023 |
1 |
def descriptor_translate(ctx, descriptor_file): |
6024 |
|
""" |
6025 |
|
Translate input descriptor. |
6026 |
|
|
6027 |
|
\b |
6028 |
|
DESCRIPTOR_FILE: Descriptor file for NS, VNF or Network Slice. |
6029 |
|
""" |
6030 |
0 |
logger.debug("") |
6031 |
0 |
check_client_version(ctx.obj, ctx.command.name) |
6032 |
0 |
result = ctx.obj.package_tool.descriptor_translate(descriptor_file) |
6033 |
0 |
print(result) |
6034 |
|
|
6035 |
|
|
6036 |
1 |
def cli(): |
6037 |
0 |
try: |
6038 |
0 |
cli_osm() |
6039 |
0 |
exit(0) |
6040 |
0 |
except pycurl.error as exc: |
6041 |
0 |
print(exc) |
6042 |
0 |
print( |
6043 |
|
'Maybe "--hostname" option or OSM_HOSTNAME environment variable needs to be specified' |
6044 |
|
) |
6045 |
0 |
except ClientException as exc: |
6046 |
0 |
print("ERROR: {}".format(exc)) |
6047 |
0 |
except (FileNotFoundError, PermissionError) as exc: |
6048 |
0 |
print("Cannot open file: {}".format(exc)) |
6049 |
0 |
except yaml.YAMLError as exc: |
6050 |
0 |
print("Invalid YAML format: {}".format(exc)) |
6051 |
0 |
exit(1) |
6052 |
|
# TODO capture other controlled exceptions here |
6053 |
|
# TODO remove the ClientException captures from all places, unless they do something different |
6054 |
|
|
6055 |
|
|
6056 |
1 |
if __name__ == "__main__": |
6057 |
0 |
cli() |