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
24 from datetime
import datetime
27 logger
= logging
.getLogger("osmclient")
30 def vnf_list(ctx
, ns
, filter, long, o
):
34 utils
.check_client_version(ctx
.obj
, "--ns")
36 filter = "&".join(filter)
37 utils
.check_client_version(ctx
.obj
, "--filter")
38 resp
= ctx
.obj
.vnf
.list(ns
, filter)
40 resp
= ctx
.obj
.vnf
.list()
41 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
42 if fullclassname
== "osmclient.sol005.client.Client":
64 table
= PrettyTable(field_names
)
66 name
= vnfr
["name"] if "name" in vnfr
else "-"
71 vnfr
["member-vnf-index-ref"],
73 vnfr
["vim-account-id"],
77 date
= datetime
.fromtimestamp(vnfr
["_admin"]["created"]).strftime(
80 last_update
= datetime
.fromtimestamp(
81 vnfr
["_admin"]["modified"]
82 ).strftime("%Y-%m-%dT%H:%M:%S")
83 new_row
.extend([date
, last_update
])
84 table
.add_row(new_row
)
86 table
= PrettyTable(["vnf name", "id", "operational status", "config status"])
88 if "mgmt-interface" not in vnfr
:
89 vnfr
["mgmt-interface"] = {}
90 vnfr
["mgmt-interface"]["ip-address"] = None
95 vnfr
["operational-status"],
96 vnfr
["config-status"],
101 print_output
.print_output(o
, table
.field_names
, table
._rows
)
104 @click.command(name
="vnf-list", short_help
="list all NF instances")
106 "--ns", default
=None, help="NS instance id or name to restrict the NF list"
112 help="restricts the list to the NF instances matching the filter.",
114 @click.option("--long", is_flag
=True, help="get more details")
119 callback
=print_output
.validate_command_output
,
120 help="adapt the output as table, yaml, csv, json, jsonpath",
123 def vnf_list1(ctx
, ns
, filter, long, o
):
124 """list all NF instances"""
126 vnf_list(ctx
, ns
, filter, long, o
)
129 @click.command(name
="nf-list", short_help
="list all NF instances")
131 "--ns", default
=None, help="NS instance id or name to restrict the NF list"
137 help="restricts the list to the NF instances matching the filter.",
139 @click.option("--long", is_flag
=True, help="get more details")
144 # callback=print_output.validate_command_output,
145 help="adapt the output as table, yaml, csv, json, jsonpath",
148 def nf_list(ctx
, ns
, filter, long, o
):
149 """list all NF instances
153 --ns TEXT NS instance id or name to restrict the VNF list
154 --filter filterExpr Restricts the list to the VNF instances matching the filter
157 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
158 concatenated using the "&" character:
161 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
162 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
163 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
165 value := scalar value
169 * zero or more occurrences
170 ? zero or one occurrence
171 [] grouping of expressions to be used with ? and *
172 "" quotation marks for marking string constants
176 "AttrName" is the name of one attribute in the data type that defines the representation
177 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
178 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
179 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
180 entries, it means that the operator "op" is applied to the attribute addressed by the last
181 <attrName> entry included in the concatenation. All simple filter expressions are combined
182 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
183 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
184 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
185 prefix". If an attribute referenced in an expression is an array, an object that contains a
186 corresponding array shall be considered to match the expression if any of the elements in the
187 array matches all expressions that have the same attribute prefix.
191 --filter vim-account-id=<VIM_ACCOUNT_ID>
192 --filter vnfd-ref=<VNFD_NAME>
193 --filter vdur.ip-address=<IP_ADDRESS>
194 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
197 vnf_list(ctx
, ns
, filter, long, o
)
200 @click.command(name
="vnf-show", short_help
="shows the info of a VNF instance")
201 @click.argument("name")
202 @click.option("--literal", is_flag
=True, help="print literally, no pretty table")
206 help="restricts the information to the fields in the filter",
208 @click.option("--kdu", default
=None, help="KDU name (whose status will be shown)")
213 callback
=print_output
.validate_command_output
,
214 help="adapt the output as table, yaml, csv, json, jsonpath",
217 def vnf_show(ctx
, name
, literal
, filter, kdu
, o
):
218 """shows the info of a VNF instance
220 NAME: name or ID of the VNF instance
223 def print_kdu_status(op_info_status
):
224 """print KDU status properly formatted"""
226 op_status
= yaml
.safe_load(op_info_status
)
228 "namespace" in op_status
229 and "info" in op_status
230 and "last_deployed" in op_status
["info"]
231 and "status" in op_status
["info"]
232 and "code" in op_status
["info"]["status"]
233 and "resources" in op_status
["info"]["status"]
234 and "seconds" in op_status
["info"]["last_deployed"]
236 last_deployed_time
= datetime
.fromtimestamp(
237 op_status
["info"]["last_deployed"]["seconds"]
238 ).strftime("%a %b %d %I:%M:%S %Y")
239 print("LAST DEPLOYED: {}".format(last_deployed_time
))
240 print("NAMESPACE: {}".format(op_status
["namespace"]))
241 status_code
= "UNKNOWN"
242 if op_status
["info"]["status"]["code"] == 1:
243 status_code
= "DEPLOYED"
244 print("STATUS: {}".format(status_code
))
247 print(op_status
["info"]["status"]["resources"])
248 if "notes" in op_status
["info"]["status"]:
250 print(op_status
["info"]["status"]["notes"])
252 print(op_info_status
)
254 print(op_info_status
)
259 raise ClientException(
260 '"--literal" option is incompatible with "--kdu" option'
263 raise ClientException(
264 '"--filter" option is incompatible with "--kdu" option'
267 utils
.check_client_version(ctx
.obj
, ctx
.command
.name
)
268 resp
= ctx
.obj
.vnf
.get(name
)
271 ns_id
= resp
["nsr-id-ref"]
273 op_data
["member_vnf_index"] = resp
["member-vnf-index-ref"]
274 op_data
["kdu_name"] = kdu
275 op_data
["primitive"] = "status"
276 op_data
["primitive_params"] = {}
277 op_id
= ctx
.obj
.ns
.exec_op(ns_id
, op_name
="action", op_data
=op_data
, wait
=False)
280 op_info
= ctx
.obj
.ns
.get_op(op_id
)
281 if op_info
["operationState"] == "COMPLETED":
282 print_kdu_status(op_info
["detailed-status"])
286 print("Could not determine KDU status")
290 print(yaml
.safe_dump(resp
, indent
=4, default_flow_style
=False))
293 table
= PrettyTable(["field", "value"])
294 for k
, v
in list(resp
.items()):
295 if not filter or k
in filter:
296 table
.add_row([k
, utils
.wrap_text(text
=json
.dumps(v
, indent
=2), width
=100)])
299 print_output
.print_output(o
, table
.field_names
, table
._rows
)