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
.cli_commands
import utils
19 from prettytable
import PrettyTable
23 from datetime
import datetime
26 logger
= logging
.getLogger("osmclient")
29 def vnf_list(ctx
, ns
, filter, long):
33 utils
.check_client_version(ctx
.obj
, "--ns")
35 filter = "&".join(filter)
36 utils
.check_client_version(ctx
.obj
, "--filter")
37 resp
= ctx
.obj
.vnf
.list(ns
, filter)
39 resp
= ctx
.obj
.vnf
.list()
40 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
41 if fullclassname
== "osmclient.sol005.client.Client":
63 table
= PrettyTable(field_names
)
65 name
= vnfr
["name"] if "name" in vnfr
else "-"
70 vnfr
["member-vnf-index-ref"],
72 vnfr
["vim-account-id"],
76 date
= datetime
.fromtimestamp(vnfr
["_admin"]["created"]).strftime(
79 last_update
= datetime
.fromtimestamp(
80 vnfr
["_admin"]["modified"]
81 ).strftime("%Y-%m-%dT%H:%M:%S")
82 new_row
.extend([date
, last_update
])
83 table
.add_row(new_row
)
85 table
= PrettyTable(["vnf name", "id", "operational status", "config status"])
87 if "mgmt-interface" not in vnfr
:
88 vnfr
["mgmt-interface"] = {}
89 vnfr
["mgmt-interface"]["ip-address"] = None
94 vnfr
["operational-status"],
95 vnfr
["config-status"],
102 @click.command(name
="vnf-list", short_help
="list all NF instances")
104 "--ns", default
=None, help="NS instance id or name to restrict the NF list"
110 help="restricts the list to the NF instances matching the filter.",
112 @click.option("--long", is_flag
=True, help="get more details")
114 def vnf_list1(ctx
, ns
, filter, long):
115 """list all NF instances"""
117 vnf_list(ctx
, ns
, filter, long)
120 @click.command(name
="nf-list", short_help
="list all NF instances")
122 "--ns", default
=None, help="NS instance id or name to restrict the NF list"
128 help="restricts the list to the NF instances matching the filter.",
130 @click.option("--long", is_flag
=True, help="get more details")
132 def nf_list(ctx
, ns
, filter, long):
133 """list all NF instances
137 --ns TEXT NS instance id or name to restrict the VNF list
138 --filter filterExpr Restricts the list to the VNF instances matching the filter
141 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
142 concatenated using the "&" character:
145 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
146 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
147 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
149 value := scalar value
153 * zero or more occurrences
154 ? zero or one occurrence
155 [] grouping of expressions to be used with ? and *
156 "" quotation marks for marking string constants
160 "AttrName" is the name of one attribute in the data type that defines the representation
161 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
162 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
163 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
164 entries, it means that the operator "op" is applied to the attribute addressed by the last
165 <attrName> entry included in the concatenation. All simple filter expressions are combined
166 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
167 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
168 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
169 prefix". If an attribute referenced in an expression is an array, an object that contains a
170 corresponding array shall be considered to match the expression if any of the elements in the
171 array matches all expressions that have the same attribute prefix.
175 --filter vim-account-id=<VIM_ACCOUNT_ID>
176 --filter vnfd-ref=<VNFD_NAME>
177 --filter vdur.ip-address=<IP_ADDRESS>
178 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
181 vnf_list(ctx
, ns
, filter, long)
184 @click.command(name
="vnf-show", short_help
="shows the info of a VNF instance")
185 @click.argument("name")
186 @click.option("--literal", is_flag
=True, help="print literally, no pretty table")
190 help="restricts the information to the fields in the filter",
192 @click.option("--kdu", default
=None, help="KDU name (whose status will be shown)")
194 def vnf_show(ctx
, name
, literal
, filter, kdu
):
195 """shows the info of a VNF instance
197 NAME: name or ID of the VNF instance
200 def print_kdu_status(op_info_status
):
201 """print KDU status properly formatted"""
203 op_status
= yaml
.safe_load(op_info_status
)
205 "namespace" in op_status
206 and "info" in op_status
207 and "last_deployed" in op_status
["info"]
208 and "status" in op_status
["info"]
209 and "code" in op_status
["info"]["status"]
210 and "resources" in op_status
["info"]["status"]
211 and "seconds" in op_status
["info"]["last_deployed"]
213 last_deployed_time
= datetime
.fromtimestamp(
214 op_status
["info"]["last_deployed"]["seconds"]
215 ).strftime("%a %b %d %I:%M:%S %Y")
216 print("LAST DEPLOYED: {}".format(last_deployed_time
))
217 print("NAMESPACE: {}".format(op_status
["namespace"]))
218 status_code
= "UNKNOWN"
219 if op_status
["info"]["status"]["code"] == 1:
220 status_code
= "DEPLOYED"
221 print("STATUS: {}".format(status_code
))
224 print(op_status
["info"]["status"]["resources"])
225 if "notes" in op_status
["info"]["status"]:
227 print(op_status
["info"]["status"]["notes"])
229 print(op_info_status
)
231 print(op_info_status
)
236 raise ClientException(
237 '"--literal" option is incompatible with "--kdu" option'
240 raise ClientException(
241 '"--filter" option is incompatible with "--kdu" option'
244 utils
.check_client_version(ctx
.obj
, ctx
.command
.name
)
245 resp
= ctx
.obj
.vnf
.get(name
)
248 ns_id
= resp
["nsr-id-ref"]
250 op_data
["member_vnf_index"] = resp
["member-vnf-index-ref"]
251 op_data
["kdu_name"] = kdu
252 op_data
["primitive"] = "status"
253 op_data
["primitive_params"] = {}
254 op_id
= ctx
.obj
.ns
.exec_op(ns_id
, op_name
="action", op_data
=op_data
, wait
=False)
257 op_info
= ctx
.obj
.ns
.get_op(op_id
)
258 if op_info
["operationState"] == "COMPLETED":
259 print_kdu_status(op_info
["detailed-status"])
263 print("Could not determine KDU status")
267 print(yaml
.safe_dump(resp
, indent
=4, default_flow_style
=False))
270 table
= PrettyTable(["field", "value"])
271 for k
, v
in list(resp
.items()):
272 if not filter or k
in filter:
273 table
.add_row([k
, utils
.wrap_text(text
=json
.dumps(v
, indent
=2), width
=100)])