blob: 1f7c5581f0119cdf8dc1e506b2f3c3db2a6c8124 [file] [log] [blame]
# Copyright ETSI Contributors and Others.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import click
from osmclient.common.exceptions import ClientException
from osmclient.common import print_output
from osmclient.cli_commands import utils
from prettytable import PrettyTable
import yaml
import json
import time
from datetime import datetime
import logging
logger = logging.getLogger("osmclient")
def vnf_list(ctx, ns, filter, long, output):
logger.debug("")
if ns or filter:
if ns:
utils.check_client_version(ctx.obj, "--ns")
if filter:
filter = "&".join(filter)
utils.check_client_version(ctx.obj, "--filter")
resp = ctx.obj.vnf.list(ns, filter)
else:
resp = ctx.obj.vnf.list()
field_names = [
"vnf id",
"name",
"ns id",
"vnf member index",
"vnfd name",
"vim account id",
"mgmt ip address",
]
if long:
field_names = [
"vnf id",
"name",
"ns id",
"vnf member index",
"vnfd name",
"vim account id",
"mgmt ip address",
"date",
"last update",
"vdu ip addresses",
]
table = PrettyTable(field_names)
for vnfr in resp:
name = vnfr["name"] if "name" in vnfr else "-"
new_row = [
vnfr["_id"],
name,
vnfr["nsr-id-ref"],
vnfr["member-vnf-index-ref"],
vnfr["vnfd-ref"],
vnfr["vim-account-id"],
vnfr["ip-address"],
]
if long:
date = datetime.fromtimestamp(vnfr["_admin"]["created"]).strftime(
"%Y-%m-%dT%H:%M:%S"
)
last_update = datetime.fromtimestamp(vnfr["_admin"]["modified"]).strftime(
"%Y-%m-%dT%H:%M:%S"
)
vdu_ip_addresses = (
[
vnfr["vdur"][vdur]["interfaces"][interface].get("ip-address")
for vdur in range(len(vnfr["vdur"]))
for interface in range(len(vnfr["vdur"][vdur]["interfaces"]))
],
)
new_row.extend([date, last_update, vdu_ip_addresses])
table.add_row(new_row)
print_output.print_output(output, table.field_names, table._rows)
@click.command(name="vnf-list", short_help="list all NF instances")
@utils.require_hostname
@click.option(
"--ns", default=None, help="NS instance id or name to restrict the NF list"
)
@click.option(
"--filter",
default=None,
multiple=True,
help="restricts the list to the NF instances matching the filter.",
)
@click.option("--long", is_flag=True, help="get more details")
@print_output.output_option
@click.pass_context
def vnf_list1(ctx, ns, filter, long, output):
"""list all NF instances"""
logger.debug("")
vnf_list(ctx, ns, filter, long, output)
@click.command(name="nf-list", short_help="list all NF instances")
@utils.require_hostname
@click.option(
"--ns", default=None, help="NS instance id or name to restrict the NF list"
)
@click.option(
"--filter",
default=None,
multiple=True,
help="restricts the list to the NF instances matching the filter.",
)
@click.option("--long", is_flag=True, help="get more details")
@print_output.output_option
@click.pass_context
def nf_list(ctx, ns, filter, long, output):
"""list all NF instances
\b
Options:
--ns TEXT NS instance id or name to restrict the VNF list
--filter filterExpr Restricts the list to the VNF instances matching the filter
\b
filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
concatenated using the "&" character:
\b
filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
attrName := string
value := scalar value
\b
where:
* zero or more occurrences
? zero or one occurrence
[] grouping of expressions to be used with ? and *
"" quotation marks for marking string constants
<> name separator
\b
"AttrName" is the name of one attribute in the data type that defines the representation
of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
<attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
"Op" stands for the comparison operator. If the expression has concatenated <attrName>
entries, it means that the operator "op" is applied to the attribute addressed by the last
<attrName> entry included in the concatenation. All simple filter expressions are combined
by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
concatenation of all "attrName" entries except the leaf attribute is called the "attribute
prefix". If an attribute referenced in an expression is an array, an object that contains a
corresponding array shall be considered to match the expression if any of the elements in the
array matches all expressions that have the same attribute prefix.
\b
Filter examples:
--filter vim-account-id=<VIM_ACCOUNT_ID>
--filter vnfd-ref=<VNFD_NAME>
--filter vdur.ip-address=<IP_ADDRESS>
--filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
"""
logger.debug("")
vnf_list(ctx, ns, filter, long, output)
@click.command(name="vnf-show", short_help="shows the info of a VNF instance")
@utils.require_hostname
@click.argument("name")
@click.option("--literal", is_flag=True, help="print literally, no pretty table")
@click.option(
"--filter",
multiple=True,
help="restricts the information to the fields in the filter",
)
@click.option("--kdu", default=None, help="KDU name (whose status will be shown)")
@print_output.output_option
@click.pass_context
def vnf_show(ctx, name, literal, filter, kdu, output):
"""shows the info of a VNF instance
NAME: name or ID of the VNF instance
"""
def print_kdu_status(op_info_status):
"""print KDU status properly formatted"""
try:
op_status = yaml.safe_load(op_info_status)
if (
"namespace" in op_status
and "info" in op_status
and "last_deployed" in op_status["info"]
and "status" in op_status["info"]
and "code" in op_status["info"]["status"]
and "resources" in op_status["info"]["status"]
and "seconds" in op_status["info"]["last_deployed"]
):
last_deployed_time = datetime.fromtimestamp(
op_status["info"]["last_deployed"]["seconds"]
).strftime("%a %b %d %I:%M:%S %Y")
print("LAST DEPLOYED: {}".format(last_deployed_time))
print("NAMESPACE: {}".format(op_status["namespace"]))
status_code = "UNKNOWN"
if op_status["info"]["status"]["code"] == 1:
status_code = "DEPLOYED"
print("STATUS: {}".format(status_code))
print()
print("RESOURCES:")
print(op_status["info"]["status"]["resources"])
if "notes" in op_status["info"]["status"]:
print("NOTES:")
print(op_status["info"]["status"]["notes"])
else:
print(op_info_status)
except Exception:
print(op_info_status)
logger.debug("")
if kdu:
if literal:
raise ClientException(
'"--literal" option is incompatible with "--kdu" option'
)
if filter:
raise ClientException(
'"--filter" option is incompatible with "--kdu" option'
)
utils.check_client_version(ctx.obj, ctx.command.name)
resp = ctx.obj.vnf.get(name)
if kdu:
ns_id = resp["nsr-id-ref"]
op_data = {}
op_data["member_vnf_index"] = resp["member-vnf-index-ref"]
op_data["kdu_name"] = kdu
op_data["primitive"] = "status"
op_data["primitive_params"] = {}
op_id = ctx.obj.ns.exec_op(ns_id, op_name="action", op_data=op_data, wait=False)
t = 0
while t < 30:
op_info = ctx.obj.ns.get_op(op_id)
if op_info["operationState"] == "COMPLETED":
print_kdu_status(op_info["detailed-status"])
return
time.sleep(5)
t += 5
print("Could not determine KDU status")
return
if literal:
print(yaml.safe_dump(resp, indent=4, default_flow_style=False))
return
table = PrettyTable(["field", "value"])
for k, v in list(resp.items()):
if not filter or k in filter:
table.add_row([k, utils.wrap_text(text=json.dumps(v, indent=2), width=100)])
print_output.print_output(output, table.field_names, table._rows)