441ae051b9fa042c468099b5878f0b1fccfcaae0
1 # Copyright ETSI Contributors and Others.
4 # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 # not use this file except in compliance with the License. You may obtain
6 # a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations
17 from osmclient
.common
.exceptions
import ClientException
18 from osmclient
.common
import print_output
19 from osmclient
.cli_commands
import utils
20 from prettytable
import PrettyTable
23 from datetime
import datetime
26 logger
= logging
.getLogger("osmclient")
29 @click.command(name
="ns-list", short_help
="list all NS instances")
34 help="restricts the list to the NS instances matching the filter.",
39 help="get more details of the NS (project, vim, deployment status, configuration status.",
45 callback
=print_output
.validate_command_output
,
46 help="adapt the output as table, yaml, csv, json, jsonpath",
49 def ns_list(ctx
, filter, long, o
):
50 """list all NS instances
54 --filter filterExpr Restricts the list to the NS instances matching the filter
57 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
58 concatenated using the "&" character:
61 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
62 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
63 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
69 * zero or more occurrences
70 ? zero or one occurrence
71 [] grouping of expressions to be used with ? and *
72 "" quotation marks for marking string constants
76 "AttrName" is the name of one attribute in the data type that defines the representation
77 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
78 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
79 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
80 entries, it means that the operator "op" is applied to the attribute addressed by the last
81 <attrName> entry included in the concatenation. All simple filter expressions are combined
82 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
83 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
84 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
85 prefix". If an attribute referenced in an expression is an array, an object that contains a
86 corresponding array shall be considered to match the expression if any of the elements in the
87 array matches all expressions that have the same attribute prefix.
91 --filter admin-status=ENABLED
92 --filter nsd-ref=<NSD_NAME>
93 --filter nsd.vendor=<VENDOR>
94 --filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME>
95 --filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME>
98 def summarize_deployment_status(status_dict
):
105 net_list
= status_dict
.get("nets", [])
108 if net
["status"] not in status_nets
:
109 status_nets
[net
["status"]] = 1
111 status_nets
[net
["status"]] += 1
113 for k
, v
in status_nets
.items():
114 message
+= "{}:{},".format(k
, v
)
115 message
+= "TOTAL:{}".format(n_nets
)
116 summary
+= "{}".format(message
)
121 vnf_list
= status_dict
["vnfs"]
123 member_vnf_index
= vnf
["member_vnf_index"]
124 if member_vnf_index
not in status_vnfs
:
125 status_vnfs
[member_vnf_index
] = {}
126 for vm
in vnf
["vms"]:
128 if vm
["status"] not in status_vms
:
129 status_vms
[vm
["status"]] = 1
131 status_vms
[vm
["status"]] += 1
132 if vm
["status"] not in status_vnfs
[member_vnf_index
]:
133 status_vnfs
[member_vnf_index
][vm
["status"]] = 1
135 status_vnfs
[member_vnf_index
][vm
["status"]] += 1
137 for k
, v
in status_vms
.items():
138 message
+= "{}:{},".format(k
, v
)
139 message
+= "TOTAL:{}".format(n_vms
)
140 summary
+= "\n{}".format(message
)
142 for k
, v
in status_vnfs
.items():
144 message
= "\n {} VMs: ".format(k
)
145 for k2
, v2
in v
.items():
146 message
+= "{}:{},".format(k2
, v2
)
148 message
+= "TOTAL:{}".format(total
)
152 def summarize_config_status(ee_list
):
160 if ee
["elementType"] not in status_ee
:
161 status_ee
[ee
["elementType"]] = {}
162 status_ee
[ee
["elementType"]][ee
["status"]] = 1
164 if ee
["status"] in status_ee
[ee
["elementType"]]:
165 status_ee
[ee
["elementType"]][ee
["status"]] += 1
167 status_ee
[ee
["elementType"]][ee
["status"]] = 1
168 for elementType
in ["KDU", "VDU", "PDU", "VNF", "NS"]:
169 if elementType
in status_ee
:
172 for k
, v
in status_ee
[elementType
].items():
173 message
+= "{}:{},".format(k
, v
)
175 message
+= "TOTAL:{}\n".format(total
)
176 summary
+= "{}: {}".format(elementType
, message
)
177 summary
+= "TOTAL Exec. Env.: {}".format(n_ee
)
182 utils
.check_client_version(ctx
.obj
, "--filter")
183 filter = "&".join(filter)
184 resp
= ctx
.obj
.ns
.list(filter)
186 resp
= ctx
.obj
.ns
.list()
199 "configuration status",
202 project_list
= ctx
.obj
.project
.list()
204 vim_list
= ctx
.obj
.vim
.list()
219 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
220 if fullclassname
== "osmclient.sol005.client.Client":
222 logger
.debug("NS info: {}".format(nsr
))
223 nsr_name
= nsr
["name"]
225 date
= datetime
.fromtimestamp(nsr
["create-time"]).strftime(
228 ns_state
= nsr
.get("nsState", nsr
["_admin"]["nsState"])
230 deployment_status
= summarize_deployment_status(
231 nsr
.get("deploymentStatus")
233 config_status
= summarize_config_status(nsr
.get("configurationStatus"))
234 project_id
, project_name
= utils
.get_project(project_list
, nsr
)
235 # project = '{} ({})'.format(project_name, project_id)
236 project
= project_name
237 vim_id
= nsr
.get("datacenter")
238 vim_name
= utils
.get_vim_name(vim_list
, vim_id
)
240 # vim = '{} ({})'.format(vim_name, vim_id)
242 if "currentOperation" in nsr
:
243 current_operation
= "{} ({})".format(
244 nsr
["currentOperation"], nsr
["currentOperationID"]
247 current_operation
= "{} ({})".format(
248 nsr
["_admin"].get("current-operation", "-"),
249 nsr
["_admin"]["nslcmop"],
251 error_details
= "N/A"
254 or ns_state
== "DEGRADED"
255 or ("currentOperation" not in nsr
and nsr
.get("errorDescription"))
257 error_details
= "{}\nDetail: {}".format(
258 nsr
["errorDescription"], nsr
["errorDetail"]
261 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
["id"])
262 nsr
= nsopdata
["nsr:nsr"]
263 nsr_name
= nsr
["name-ref"]
264 nsr_id
= nsr
["ns-instance-config-ref"]
267 deployment_status
= (
268 nsr
["operational-status"]
269 if "operational-status" in nsr
272 ns_state
= deployment_status
273 config_status
= nsr
.get("config-status", "Not found")
274 current_operation
= "Unknown"
275 error_details
= nsr
.get("detailed-status", "Not found")
276 if config_status
== "config_not_needed":
277 config_status
= "configured (no charms)"
287 utils
.wrap_text(text
=error_details
, width
=40),
302 utils
.wrap_text(text
=error_details
, width
=40),
307 print_output
.print_output(o
, table
.field_names
, table
._rows
)
308 print('To get the history of all operations over a NS, run "osm ns-op-list NS_ID"')
310 'For more details on the current operation, run "osm ns-op-show OPERATION_ID"'
314 @click.command(name
="ns-show", short_help
="shows the info of a NS instance")
315 @click.argument("name")
316 @click.option("--literal", is_flag
=True, help="print literally, no pretty table")
320 help="restricts the information to the fields in the filter",
326 callback
=print_output
.validate_command_output
,
327 help="adapt the output as table, yaml, csv, json, jsonpath",
330 def ns_show(ctx
, name
, literal
, filter, o
):
331 """shows the info of a NS instance
333 NAME: name or ID of the NS instance
336 ns
= ctx
.obj
.ns
.get(name
)
339 print(yaml
.safe_dump(ns
, indent
=4, default_flow_style
=False))
342 table
= PrettyTable(["field", "value"])
344 for k
, v
in list(ns
.items()):
345 if not filter or k
in filter:
346 table
.add_row([k
, utils
.wrap_text(text
=json
.dumps(v
, indent
=2), width
=100)])
348 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
349 if fullclassname
!= "osmclient.sol005.client.Client":
350 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
["id"])
351 nsr_optdata
= nsopdata
["nsr:nsr"]
352 for k
, v
in list(nsr_optdata
.items()):
353 if not filter or k
in filter:
354 table
.add_row([k
, utils
.wrap_text(json
.dumps(v
, indent
=2), width
=100)])
356 print_output
.print_output(o
, table
.field_names
, table
._rows
)
360 @click.command(name
="ns-create", short_help
="creates a new Network Service instance")
361 @click.option("--ns_name", prompt
=True, help="name of the NS instance")
362 @click.option("--nsd_name", prompt
=True, help="name of the NS descriptor")
366 help="default VIM account id or name for the deployment",
368 @click.option("--admin_status", default
="ENABLED", help="administration status")
372 help="comma separated list of public key files to inject to vnfs",
374 @click.option("--config", default
=None, help="ns specific yaml configuration")
375 @click.option("--config_file", default
=None, help="ns specific yaml configuration file")
381 help="do not return the control immediately, but keep it "
382 "until the operation is completed, or timeout",
384 @click.option("--timeout", default
=None, help="ns deployment timeout")
398 """creates a new NS instance"""
401 utils
.check_client_version(ctx
.obj
, "--config_file")
403 raise ClientException(
404 '"--config" option is incompatible with "--config_file" option'
406 with
open(config_file
, "r") as cf
:
419 @click.command(name
="ns-delete", short_help
="deletes a NS instance")
420 @click.argument("name")
422 "--force", is_flag
=True, help="forces the deletion bypassing pre-conditions"
427 help="specific yaml configuration for the termination, e.g. '{autoremove: False, timeout_ns_terminate: "
428 "600, skip_terminate_primitives: True}'",
435 help="do not return the control immediately, but keep it "
436 "until the operation is completed, or timeout",
439 def ns_delete(ctx
, name
, force
, config
, wait
):
440 """deletes a NS instance
442 NAME: name or ID of the NS instance to be deleted
446 ctx
.obj
.ns
.delete(name
, config
=config
, wait
=wait
)
448 utils
.check_client_version(ctx
.obj
, "--force")
449 ctx
.obj
.ns
.delete(name
, force
, config
=config
, wait
=wait
)