help="do not return the control immediately, but keep it "
"until the operation is completed, or timeout",
)
+@click.option(
+ "--ns-config-template",
+ default=None,
+ help="specify the ns config template name or id",
+)
@click.option("--timeout", default=None, help="ns deployment timeout")
@click.pass_context
def ns_create(
ssh_keys,
config,
config_file,
+ ns_config_template,
wait,
timeout,
):
nsd_name,
ns_name,
config=config,
+ ns_config_template=ns_config_template,
ssh_keys=ssh_keys,
account=vim_account,
wait=wait,
import click
from osmclient.cli_commands import utils
+from osmclient.common.exceptions import NotFound
from prettytable import PrettyTable
import yaml
import json
"""
logger.debug("")
nsd_delete(ctx, name, force)
+
+
+@click.command(name="nsconfig-list", short_help="list all NS Config Templates")
+@click.option(
+ "--nsd",
+ default=None,
+ help="list all the NS Config Template based on the nsd",
+)
+@click.option("--long", is_flag=True, help="for more details")
+@click.pass_context
+def nsconfig_list(ctx, nsd, long):
+ """list all Ns config template in the system"""
+ logger.debug("")
+ if nsd:
+ utils.check_client_version(ctx.obj, "--nsd")
+ filter = nsd
+ resp = []
+ resp_id = ctx.obj.nct.list(filter)
+ resp_list = ctx.obj.nct.list()
+ for rep in resp_list:
+ if resp_id == rep.get("nsdId"):
+ resp.append(rep)
+ if not resp:
+ raise NotFound("ns config template not present for the nsd")
+ else:
+ resp = ctx.obj.nct.list()
+
+ if long:
+ table = PrettyTable(
+ [
+ "ns config template name",
+ "id",
+ "nsd id",
+ "onboarding state",
+ "operational state",
+ "usage state",
+ "date",
+ "last update",
+ ]
+ )
+ else:
+ table = PrettyTable(["ns config template name", "id", "nsd id"])
+ for nct in resp:
+ name = nct.get("name")
+ nsd_id = nct.get("nsdId")
+ if long:
+ onb_state = nct["_admin"].get("onboardingState", "-")
+ op_state = nct["_admin"].get("operationalState", "-")
+ usage_state = nct["_admin"].get("usageState", "-")
+ date = datetime.fromtimestamp(nct["_admin"]["created"]).strftime(
+ "%Y-%m-%dT%H:%M:%S"
+ )
+ last_update = datetime.fromtimestamp(nct["_admin"]["modified"]).strftime(
+ "%Y-%m-%dT%H:%M:%S"
+ )
+ table.add_row(
+ [
+ name,
+ nct["_id"],
+ nsd_id,
+ onb_state,
+ op_state,
+ usage_state,
+ date,
+ last_update,
+ ]
+ )
+ else:
+ table.add_row([name, nct["_id"], nsd_id])
+ table.align = "l"
+ print(table)
+
+
+@click.command(
+ name="nsconfig-show", short_help="shows the details of a Ns config template"
+)
+@click.option("--literal", is_flag=True, help="print literally, no pretty table")
+@click.argument("name")
+@click.pass_context
+def nsconfig_show(ctx, name, literal):
+ """shows the content of a Ns config template
+
+ NAME: name or ID of the Ns config template
+ """
+ logger.debug("")
+ resp = ctx.obj.nct.get(name)
+
+ 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()):
+ table.add_row([k, utils.wrap_text(text=json.dumps(v, indent=2), width=100)])
+ table.align = "l"
+ print(table)
+
+
+@click.command(name="nsconfig-delete", short_help="deletes a Ns config template")
+@click.argument("name")
+@click.option(
+ "--force", is_flag=True, help="forces the deletion bypassing pre-conditions"
+)
+@click.pass_context
+def nsconfig_delete(ctx, name, force):
+ """deletes a Ns config template
+
+ NAME: name or ID of the Ns config template to be deleted
+ """
+ logger.debug("")
+ if not force:
+ ctx.obj.nct.delete(name)
+ else:
+ utils.check_client_version(ctx.obj, "--force")
+ ctx.obj.nct.delete(name, force)
+
+
+@click.command(name="nsconfig-create", short_help="creates a Ns config template")
+@click.argument("name")
+@click.option(
+ "--config_file",
+ prompt=True,
+ help="ns config template specific yaml configuration file",
+)
+@click.option(
+ "--nsd",
+ prompt=True,
+ help=" specify the nsd for the template",
+)
+@click.pass_context
+def nsconfig_create(ctx, name, config_file, nsd):
+ """creates a new Ns Config Template"""
+ logger.debug("")
+ if config_file:
+ utils.check_client_version(ctx.obj, "--config_file")
+ with open(config_file, "r") as cf:
+ config = cf.read()
+ ctx.obj.nct.create(name, config, nsd)
+
+
+@click.command(
+ name="nsconfig-update", short_help="update content of Ns config template"
+)
+@click.argument("name")
+@click.option("--newname", help="New name for the Ns config template")
+@click.option(
+ "--config_file", help="Upload config file to edit the instantiation parameters"
+)
+@click.pass_context
+def nsconfig_update(ctx, name, newname, config_file):
+ """update the name and config parameters in the template"""
+ logger.debug("")
+ config = None
+ if config_file:
+ utils.check_client_version(ctx.obj, "--config_file")
+ with open(config_file, "r") as cf:
+ config = cf.read()
+
+ ctx.obj.nct.update(name, newname, config)
cli_osm.add_command(nspkg.nsd_update1)
cli_osm.add_command(nspkg.nsd_update2)
+ cli_osm.add_command(nspkg.nsconfig_list)
+ cli_osm.add_command(nspkg.nsconfig_show)
+ cli_osm.add_command(nspkg.nsconfig_delete)
+ cli_osm.add_command(nspkg.nsconfig_create)
+ cli_osm.add_command(nspkg.nsconfig_update)
+
cli_osm.add_command(other.get_version)
cli_osm.add_command(packages.descriptor_translate)
from osmclient.sol005 import nst
from osmclient.sol005 import nsi
from osmclient.sol005 import ns
+from osmclient.sol005 import nct
from osmclient.sol005 import vnf
from osmclient.sol005 import vim
from osmclient.sol005 import wim
self.nst = nst.Nst(self._http_client, client=self)
self.package = package.Package(self._http_client, client=self)
self.ns = ns.Ns(self._http_client, client=self)
+ self.nct = nct.Nct(self._http_client, client=self)
self.nsi = nsi.Nsi(self._http_client, client=self)
self.vim = vim.Vim(self._http_client, client=self)
self.wim = wim.Wim(self._http_client, client=self)
--- /dev/null
+# Copyright 2018 Telefonica
+#
+# 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.
+
+"""
+OSM nct API handling
+"""
+
+from osmclient.common.exceptions import NotFound
+from osmclient.common.exceptions import ClientException
+from osmclient.common import utils
+import yaml
+import json
+import logging
+
+
+class Nct(object):
+ def __init__(self, http=None, client=None):
+ self._http = http
+ self._client = client
+ self._logger = logging.getLogger("osmclient")
+ self._apiName = "/nsd"
+ self._apiVersion = "/v1"
+ self._apiResource = "/ns_config_template"
+ self._apiBase = "{}{}{}".format(
+ self._apiName, self._apiVersion, self._apiResource
+ )
+
+ def list(self, nsd=None):
+ self._logger.debug("")
+ self._client.get_token()
+ filter_string = ""
+ if nsd:
+ filter_string = "?{}".format(nsd)
+ _, resp = self._http.get2_cmd(
+ "{}{}/ns_descriptors{}".format(
+ self._apiName, self._apiVersion, filter_string
+ )
+ )
+ resp = json.loads(resp)
+ for rep in resp:
+ if nsd == rep.get("_id"):
+ resp_id = rep.get("_id")
+ return resp_id
+ if nsd == rep.get("name"):
+ resp_id = rep.get("_id")
+ return resp_id
+ raise NotFound("nsd {} not found".format(nsd))
+ _, resp = self._http.get2_cmd("{}".format(self._apiBase))
+ if resp:
+ return json.loads(resp)
+ return list()
+
+ def get(self, name):
+ self._logger.debug("")
+ self._client.get_token()
+ if utils.validate_uuid4(name):
+ for nct in self.list():
+ if name == nct["_id"]:
+ return nct
+ else:
+ for nct in self.list():
+ if "name" in nct and name == nct["name"]:
+ return nct
+ raise NotFound("ns config template {} not found".format(name))
+
+ def delete(self, name, force=False):
+ self._logger.debug("")
+ nct = self.get(name)
+ querystring = ""
+ if force:
+ querystring = "?FORCE=True"
+ http_code, resp = self._http.delete_cmd(
+ "{}/{}{}".format(self._apiBase, nct["_id"], querystring)
+ )
+
+ if http_code == 202:
+ print("Deletion in progress")
+ elif http_code == 204:
+ print("Deleted")
+ else:
+ msg = resp or ""
+ raise ClientException(
+ "failed to delete ns config template {} - {}".format(name, msg)
+ )
+
+ def create(self, name, config, nsd):
+ template = {}
+ vim_account_id = {}
+ config_param = yaml.safe_load(config)
+
+ def get_vim_account_id(vim_account):
+ self._logger.debug("")
+ if vim_account_id.get(vim_account):
+ return vim_account_id[vim_account]
+ vim = self._client.vim.get(vim_account)
+ if vim is None:
+ raise NotFound("cannot find vim account '{}'".format(vim_account))
+ vim_account_id[vim_account] = vim["_id"]
+ return vim["_id"]
+
+ if "vim-network-name" in config_param:
+ config_param["vld"] = config_param.pop("vim-network-name")
+ if "vld" in config_param:
+ if not isinstance(config_param["vld"], list):
+ raise ClientException(
+ "Error at --config 'vld' must be a list of dictionaries"
+ )
+ for vld in config_param["vld"]:
+ if not isinstance(vld, dict):
+ raise ClientException(
+ "Error at --config 'vld' must be a list of dictionaries"
+ )
+ if vld.get("vim-network-name"):
+ if isinstance(vld["vim-network-name"], dict):
+ vim_network_name_dict = {}
+ for vim_account, vim_net in vld["vim-network-name"].items():
+ vim_network_name_dict[get_vim_account_id(vim_account)] = (
+ vim_net
+ )
+ vld["vim-network-name"] = vim_network_name_dict
+ if "vnf" in config_param:
+ for vnf in config_param["vnf"]:
+ if vnf.get("vim_account"):
+ vnf["vimAccountId"] = get_vim_account_id(vnf.pop("vim_account"))
+
+ if "additionalParamsForNs" in config_param:
+ if not isinstance(config_param["additionalParamsForNs"], dict):
+ raise ClientException(
+ "Error at --config 'additionalParamsForNs' must be a dictionary"
+ )
+ if "additionalParamsForVnf" in config_param:
+ if not isinstance(config_param["additionalParamsForVnf"], list):
+ raise ClientException(
+ "Error at --config 'additionalParamsForVnf' must be a list"
+ )
+ for additional_param_vnf in config_param["additionalParamsForVnf"]:
+ if not isinstance(additional_param_vnf, dict):
+ raise ClientException(
+ "Error at --config 'additionalParamsForVnf' items must be dictionaries"
+ )
+ if not additional_param_vnf.get("member-vnf-index"):
+ raise ClientException(
+ "Error at --config 'additionalParamsForVnf' items must contain "
+ "'member-vnf-index'"
+ )
+ template["name"] = name
+ template["config"] = config_param
+ template["nsdId"] = self.list(nsd)
+
+ try:
+ headers = self._client._headers
+ headers["Content-Type"] = "application/json"
+ self._http.set_http_header(headers)
+ http_code, resp = self._http.post_cmd(
+ endpoint=self._apiBase, postfields_dict=template
+ )
+
+ if resp:
+ resp = json.loads(resp)
+ print(resp.get("id"))
+ if not resp or "id" not in resp:
+ raise ClientException(
+ "unexpected response from server - {} ".format(resp)
+ )
+ except ClientException as exc:
+ message = "failed to create ns config template: {}:\nerror:\n{}".format(
+ name, str(exc)
+ )
+ raise ClientException(message)
+
+ def update(self, name, newname=None, config=None):
+ self._logger.debug("")
+ template_edit = {}
+ config_name = self.get(name)
+ if newname:
+ template_edit["name"] = newname
+ if config:
+ config_content = yaml.safe_load(config)
+ template_edit["config"] = config_content
+ http_code, resp = self._http.put_cmd(
+ endpoint="{}/{}/template_content".format(self._apiBase, config_name["_id"]),
+ postfields_dict=template_edit,
+ )
+ if http_code == 204:
+ print("Updated")
nsr_name,
account,
config=None,
+ ns_config_template=None,
ssh_keys=None,
description="default description",
admin_status="ENABLED",
ns["ssh_keys"].append(f.read())
if timeout:
ns["timeout_ns_deploy"] = timeout
+ if ns_config_template:
+ _, resp = self._http.get2_cmd(
+ "/nsd{}/ns_config_template".format(self._apiVersion)
+ )
+ resp = json.loads(resp)
+ for rep in resp:
+ if ns_config_template == rep.get("name"):
+ ns["nsConfigTemplateId"] = rep.get("_id")
+ if ns_config_template == rep.get("_id"):
+ ns["nsConfigTemplateId"] = rep.get("_id")
if config:
ns_config = yaml.safe_load(config)
if "vim-network-name" in ns_config: