Compare commits
3 Commits
yoga-eol
...
victoria-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
774923c5bb | ||
| 770e1fac13 | |||
| b5aca28e12 |
@@ -2,4 +2,4 @@
|
||||
host=review.opendev.org
|
||||
port=29418
|
||||
project=openstack/python-tackerclient.git
|
||||
defaultbranch=unmaintained/yoga
|
||||
defaultbranch=stable/victoria
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
- project:
|
||||
templates:
|
||||
- check-requirements
|
||||
- openstack-python3-yoga-jobs
|
||||
- openstack-python3-victoria-jobs
|
||||
- publish-openstack-docs-pti
|
||||
- release-notes-jobs-python3
|
||||
|
||||
@@ -71,8 +71,8 @@ htmlhelp_basename = 'tackerclientdoc'
|
||||
# -- Options for manual page output -------------------------------------------
|
||||
|
||||
man_pages = [
|
||||
('cli/index', 'tacker', 'Client for Tacker API',
|
||||
['OpenStack Contributors'], 1),
|
||||
('cli/index', 'tacker', u'Client for Tacker API',
|
||||
[u'OpenStack Contributors'], 1),
|
||||
]
|
||||
|
||||
# -- Options for openstackdocstheme -------------------------------------------
|
||||
|
||||
@@ -52,4 +52,5 @@ Indices and Tables
|
||||
------------------
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
||||
@@ -11,53 +11,59 @@
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Convention for heading levels in Neutron devref:
|
||||
======= Heading 0 (reserved for the title in a document)
|
||||
------- Heading 1
|
||||
~~~~~~~ Heading 2
|
||||
+++++++ Heading 3
|
||||
''''''' Heading 4
|
||||
(Avoid deeper levels because they do not render well.)
|
||||
|
||||
============
|
||||
Installation
|
||||
============
|
||||
|
||||
This document describes how to install python-tackerclient.
|
||||
**Note:** The paths we are using for configuration files in these steps
|
||||
are with reference to Ubuntu Operating System. The paths may vary for
|
||||
other Operating Systems.
|
||||
|
||||
.. note::
|
||||
|
||||
This installation guide contents are specific to Ubuntu distro.
|
||||
The branch_name which is used in commands, specify the branch_name
|
||||
as stable/<branch> for any stable branch installation. For eg:
|
||||
stable/queens, stable/pike. If unspecified the default will be
|
||||
master branch.
|
||||
|
||||
Using python install
|
||||
====================
|
||||
1. Clone python-tackerclient repository.
|
||||
|
||||
#. Clone python-tackerclient repository.
|
||||
::
|
||||
|
||||
You can use -b for specific release, optionally.
|
||||
$ cd ~/
|
||||
$ git clone https://github.com/openstack/python-tackerclient -b <branch_name>
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cd ~/
|
||||
$ git clone https://opendev.org/openstack/python-tackerclient -b <branch_name>
|
||||
2. Install python-tackerclient.
|
||||
|
||||
.. note::
|
||||
::
|
||||
|
||||
Make sure to replace the ``<branch_name>`` in command example with
|
||||
specific branch name, such as ``stable/victoria``.
|
||||
$ cd python-tackerclient
|
||||
$ sudo python setup.py install
|
||||
|
||||
#. Install python-tackerclient.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ cd python-tackerclient
|
||||
$ sudo python3 setup.py install
|
||||
|
||||
Using pip
|
||||
=========
|
||||
|
||||
You can also install the latest version by using ``pip`` command:
|
||||
|
||||
.. code-block:: console
|
||||
::
|
||||
|
||||
$ pip install python-tackerclient
|
||||
|
||||
$ pip3 install python-tackerclient
|
||||
|
||||
Or, if it is needed to install ``python-tackerclient`` from master branch,
|
||||
type
|
||||
|
||||
.. code-block:: console
|
||||
::
|
||||
|
||||
$ pip3 install git+https://opendev.org/openstack/python-tackerclient
|
||||
$ pip install git+https://github.com/openstack/python-tackerclient.git
|
||||
|
||||
|
||||
@@ -53,8 +53,8 @@ source_suffix = '.rst'
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'Tacker Client Release Notes'
|
||||
copyright = '2016, Tacker Developers'
|
||||
project = u'Tacker Client Release Notes'
|
||||
copyright = u'2016, Tacker Developers'
|
||||
|
||||
# Release notes are version independent.
|
||||
release = ''
|
||||
@@ -190,8 +190,8 @@ latex_elements = {
|
||||
# [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'TackerClientReleaseNotes.tex',
|
||||
'Tacker Client Release Notes Documentation',
|
||||
'Tacker Developers', 'manual'),
|
||||
u'Tacker Client Release Notes Documentation',
|
||||
u'Tacker Developers', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
@@ -221,8 +221,8 @@ latex_documents = [
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'tackerreleasenotes',
|
||||
'Tacker Client Release Notes Documentation',
|
||||
['Tacker Developers'], 1)
|
||||
u'Tacker Client Release Notes Documentation',
|
||||
[u'Tacker Developers'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
@@ -236,8 +236,8 @@ man_pages = [
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'TackerClientReleaseNotes',
|
||||
'Tacker Client Release Notes Documentation',
|
||||
'Tacker Developers', 'TackerClientReleaseNotes',
|
||||
u'Tacker Client Release Notes Documentation',
|
||||
u'Tacker Developers', 'TackerClientReleaseNotes',
|
||||
'Tacker Client Project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
@@ -7,9 +7,6 @@ Contents:
|
||||
:maxdepth: 2
|
||||
|
||||
unreleased
|
||||
xena
|
||||
wallaby
|
||||
victoria
|
||||
ussuri
|
||||
train
|
||||
stein
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
=============================
|
||||
Victoria Series Release Notes
|
||||
=============================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/victoria
|
||||
@@ -1,6 +0,0 @@
|
||||
============================
|
||||
Wallaby Series Release Notes
|
||||
============================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/wallaby
|
||||
@@ -1,6 +0,0 @@
|
||||
=========================
|
||||
Xena Series Release Notes
|
||||
=========================
|
||||
|
||||
.. release-notes::
|
||||
:branch: stable/xena
|
||||
@@ -8,6 +8,7 @@ netaddr>=0.7.18 # BSD
|
||||
requests>=2.14.2 # Apache-2.0
|
||||
python-keystoneclient>=3.8.0 # Apache-2.0
|
||||
simplejson>=3.5.1 # MIT
|
||||
six>=1.10.0 # MIT
|
||||
stevedore>=1.20.0 # Apache-2.0
|
||||
Babel!=2.4.0,>=2.3.4 # BSD
|
||||
oslo.i18n>=3.15.3 # Apache-2.0
|
||||
|
||||
35
setup.cfg
35
setup.cfg
@@ -1,12 +1,12 @@
|
||||
[metadata]
|
||||
name = python-tackerclient
|
||||
summary = CLI and Client Library for OpenStack Tacker
|
||||
description_file =
|
||||
description-file =
|
||||
README.rst
|
||||
author = OpenStack
|
||||
author_email = openstack-discuss@lists.openstack.org
|
||||
home_page = https://docs.openstack.org/python-tackerclient/
|
||||
python_requires = >=3.6
|
||||
author-email = openstack-discuss@lists.openstack.org
|
||||
home-page = https://docs.openstack.org/python-tackerclient/
|
||||
python-requires = >=3.6
|
||||
classifier =
|
||||
Environment :: OpenStack
|
||||
Intended Audience :: Developers
|
||||
@@ -20,8 +20,6 @@ classifier =
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3.6
|
||||
Programming Language :: Python :: 3.7
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
|
||||
[files]
|
||||
packages =
|
||||
@@ -96,29 +94,4 @@ openstack.tackerclient.v1 =
|
||||
vnflcm_heal = tackerclient.osc.v1.vnflcm.vnflcm:HealVnfLcm
|
||||
vnflcm_update = tackerclient.osc.v1.vnflcm.vnflcm:UpdateVnfLcm
|
||||
vnflcm_scale = tackerclient.osc.v1.vnflcm.vnflcm:ScaleVnfLcm
|
||||
vnflcm_change-ext-conn = tackerclient.osc.v1.vnflcm.vnflcm:ChangeExtConnVnfLcm
|
||||
vnflcm_op_rollback = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:RollbackVnfLcmOp
|
||||
vnflcm_op_cancel = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:CancelVnfLcmOp
|
||||
vnflcm_op_fail = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:FailVnfLcmOp
|
||||
vnflcm_op_retry = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:RetryVnfLcmOp
|
||||
vnflcm_op_list = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ListVnfLcmOp
|
||||
vnflcm_op_show = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ShowVnfLcmOp
|
||||
vnflcm_versions = tackerclient.osc.common.vnflcm.vnflcm_versions:VnfLcmVersions
|
||||
openstack.tackerclient.v2 =
|
||||
vnflcm_create = tackerclient.osc.v1.vnflcm.vnflcm:CreateVnfLcm
|
||||
vnflcm_show = tackerclient.osc.v1.vnflcm.vnflcm:ShowVnfLcm
|
||||
vnflcm_list = tackerclient.osc.v1.vnflcm.vnflcm:ListVnfLcm
|
||||
vnflcm_instantiate = tackerclient.osc.v1.vnflcm.vnflcm:InstantiateVnfLcm
|
||||
vnflcm_terminate = tackerclient.osc.v1.vnflcm.vnflcm:TerminateVnfLcm
|
||||
vnflcm_change-vnfpkg = tackerclient.osc.v1.vnflcm.vnflcm:ChangeVnfPkgVnfLcm
|
||||
vnflcm_delete = tackerclient.osc.v1.vnflcm.vnflcm:DeleteVnfLcm
|
||||
vnflcm_heal = tackerclient.osc.v1.vnflcm.vnflcm:HealVnfLcm
|
||||
vnflcm_update = tackerclient.osc.v1.vnflcm.vnflcm:UpdateVnfLcm
|
||||
vnflcm_scale = tackerclient.osc.v1.vnflcm.vnflcm:ScaleVnfLcm
|
||||
vnflcm_change-ext-conn = tackerclient.osc.v1.vnflcm.vnflcm:ChangeExtConnVnfLcm
|
||||
vnflcm_op_rollback = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:RollbackVnfLcmOp
|
||||
vnflcm_op_fail = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:FailVnfLcmOp
|
||||
vnflcm_op_retry = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:RetryVnfLcmOp
|
||||
vnflcm_op_list = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ListVnfLcmOp
|
||||
vnflcm_op_show = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ShowVnfLcmOp
|
||||
vnflcm_versions = tackerclient.osc.common.vnflcm.vnflcm_versions:VnfLcmVersions
|
||||
|
||||
@@ -28,6 +28,7 @@ ATOM_LINK_NOTATION = "{%s}link" % ATOM_NAMESPACE
|
||||
|
||||
TYPE_BOOL = "bool"
|
||||
TYPE_INT = "int"
|
||||
TYPE_LONG = "long"
|
||||
TYPE_FLOAT = "float"
|
||||
TYPE_LIST = "list"
|
||||
TYPE_DICT = "dict"
|
||||
|
||||
@@ -207,10 +207,6 @@ class InvalidInput(TackerClientException):
|
||||
message = _("Invalid input: %(reason)s")
|
||||
|
||||
|
||||
class UnsupportedCommandVersion(TackerClientException):
|
||||
message = _("This command is not supported in version %(version)s")
|
||||
|
||||
|
||||
# Command line exceptions
|
||||
|
||||
class TackerCLIError(TackerException):
|
||||
|
||||
@@ -18,6 +18,7 @@ from xml.etree import ElementTree as etree
|
||||
from xml.parsers import expat
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
import six
|
||||
|
||||
from tackerclient.common import constants
|
||||
from tackerclient.common import exceptions as exception
|
||||
@@ -25,6 +26,9 @@ from tackerclient.i18n import _
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
if six.PY3:
|
||||
long = int
|
||||
|
||||
|
||||
class ActionDispatcher(object):
|
||||
"""Maps method name to local methods through action name."""
|
||||
@@ -54,7 +58,7 @@ class JSONDictSerializer(DictSerializer):
|
||||
|
||||
def default(self, data):
|
||||
def sanitizer(obj):
|
||||
return str(obj)
|
||||
return six.text_type(obj)
|
||||
return jsonutils.dumps(data, default=sanitizer)
|
||||
|
||||
|
||||
@@ -89,7 +93,7 @@ class XMLDictSerializer(DictSerializer):
|
||||
root_key = constants.VIRTUAL_ROOT_KEY
|
||||
root_value = None
|
||||
else:
|
||||
link_keys = [k for k in data.keys() or []
|
||||
link_keys = [k for k in six.iterkeys(data) or []
|
||||
if k.endswith('_links')]
|
||||
if link_keys:
|
||||
links = data.pop(link_keys[0], None)
|
||||
@@ -179,6 +183,10 @@ class XMLDictSerializer(DictSerializer):
|
||||
result.set(
|
||||
constants.TYPE_ATTR,
|
||||
constants.TYPE_INT)
|
||||
elif isinstance(data, long):
|
||||
result.set(
|
||||
constants.TYPE_ATTR,
|
||||
constants.TYPE_LONG)
|
||||
elif isinstance(data, float):
|
||||
result.set(
|
||||
constants.TYPE_ATTR,
|
||||
@@ -186,7 +194,7 @@ class XMLDictSerializer(DictSerializer):
|
||||
LOG.debug("Data %(data)s type is %(type)s",
|
||||
{'data': data,
|
||||
'type': type(data)})
|
||||
result.text = str(data)
|
||||
result.text = six.text_type(data)
|
||||
return result
|
||||
|
||||
def _create_link_nodes(self, xml_doc, links):
|
||||
@@ -315,6 +323,8 @@ class XMLDeserializer(TextDeserializer):
|
||||
lambda x: x.lower() == 'true',
|
||||
constants.TYPE_INT:
|
||||
lambda x: int(x),
|
||||
constants.TYPE_LONG:
|
||||
lambda x: long(x),
|
||||
constants.TYPE_FLOAT:
|
||||
lambda x: float(x)}
|
||||
if attrType and attrType in converters:
|
||||
|
||||
@@ -24,6 +24,7 @@ import os
|
||||
from oslo_log import versionutils
|
||||
from oslo_utils import encodeutils
|
||||
from oslo_utils import importutils
|
||||
import six
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.i18n import _
|
||||
@@ -140,7 +141,7 @@ def http_log_resp(_logger, resp, body):
|
||||
|
||||
|
||||
def _safe_encode_without_obj(data):
|
||||
if isinstance(data, str):
|
||||
if isinstance(data, six.string_types):
|
||||
return encodeutils.safe_encode(data)
|
||||
return data
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
# Copyright (C) 2021 Nippon Telegraph and Telephone Corporation
|
||||
# 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.
|
||||
|
||||
from osc_lib.command import command
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.i18n import _
|
||||
|
||||
|
||||
SUPPORTED_VERSIONS = [1, 2]
|
||||
|
||||
|
||||
class VnfLcmVersions(command.ShowOne):
|
||||
_description = _("Show VnfLcm Api versions")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(VnfLcmVersions, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--major-version',
|
||||
metavar="<major-version>",
|
||||
type=int,
|
||||
help=_('Show only specify major version.'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
v = None
|
||||
if parsed_args.major_version:
|
||||
if parsed_args.major_version not in SUPPORTED_VERSIONS:
|
||||
msg = _("Major version %d is not supported")
|
||||
reason = msg % parsed_args.major_version
|
||||
raise exceptions.InvalidInput(reason=reason)
|
||||
v = "v{}".format(parsed_args.major_version)
|
||||
|
||||
client = self.app.client_manager.tackerclient
|
||||
data = client.show_vnf_lcm_versions(v)
|
||||
|
||||
return (tuple(data.keys()), tuple(data.values()))
|
||||
@@ -26,17 +26,15 @@ API_NAME = 'tackerclient'
|
||||
API_VERSION_OPTION = 'os_tacker_api_version'
|
||||
API_VERSIONS = {
|
||||
'1': 'tackerclient.v1_0.client.Client',
|
||||
'2': 'tackerclient.v1_0.client.Client',
|
||||
}
|
||||
|
||||
|
||||
def make_client(instance):
|
||||
"""Returns a client to the ClientManager."""
|
||||
|
||||
api_version = instance._api_version[API_NAME]
|
||||
tacker_client = utils.get_client_class(
|
||||
API_NAME,
|
||||
api_version,
|
||||
instance._api_version[API_NAME],
|
||||
API_VERSIONS)
|
||||
LOG.debug('Instantiating tacker client: %s', tacker_client)
|
||||
|
||||
@@ -44,8 +42,7 @@ def make_client(instance):
|
||||
'region_name': instance._region_name,
|
||||
'endpoint_type': instance._interface,
|
||||
'interface': instance._interface,
|
||||
'session': instance.session,
|
||||
'api_version': api_version
|
||||
'session': instance.session
|
||||
}
|
||||
|
||||
client = tacker_client(**kwargs)
|
||||
|
||||
@@ -217,7 +217,7 @@ class ShowTemplateNSD(command.ShowOne):
|
||||
obj[_NSD]['attributes']['nsd'])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj[_NSD]),
|
||||
('attributes',),
|
||||
(u'attributes',),
|
||||
formatters=_formatters)
|
||||
data = (data or _('Unable to display NSD template!'))
|
||||
return (('attributes',), data)
|
||||
return ((u'attributes',), data)
|
||||
|
||||
@@ -230,8 +230,7 @@ class UpdateVIM(command.ShowOne):
|
||||
with open(parsed_args.config_file) as f:
|
||||
config_yaml = f.read()
|
||||
try:
|
||||
config_param = yaml.load(config_yaml,
|
||||
Loader=yaml.SafeLoader)
|
||||
config_param = yaml.load(config_yaml)
|
||||
except yaml.YAMLError as e:
|
||||
raise exceptions.InvalidInput(reason=e)
|
||||
vim_obj = body[_VIM]
|
||||
|
||||
@@ -190,32 +190,18 @@ class DeleteVNFFG(command.Command):
|
||||
nargs="+",
|
||||
help=_("VNFFG(s) to delete (name or ID)")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--force',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help=_('Force delete VNFFG'))
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = dict()
|
||||
if parsed_args.force:
|
||||
body[_VNFFG] = dict()
|
||||
body[_VNFFG]['attributes'] = dict()
|
||||
body[_VNFFG]['attributes']['force'] = True
|
||||
return body
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
failure = False
|
||||
deleted_ids = []
|
||||
failed_items = {}
|
||||
body = self.args2body(parsed_args)
|
||||
for resource_id in parsed_args.vnffg:
|
||||
try:
|
||||
obj = tackerV10.find_resourceid_by_name_or_id(
|
||||
client, _VNFFG, resource_id)
|
||||
client.delete_vnffg(obj, body)
|
||||
client.delete_vnffg(obj)
|
||||
deleted_ids.append(resource_id)
|
||||
except Exception as e:
|
||||
failure = True
|
||||
|
||||
@@ -211,7 +211,7 @@ class ShowTemplateVNFFGD(command.ShowOne):
|
||||
obj = client.show_vnffgd(obj_id)
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj[_VNFFGD]),
|
||||
('template',),
|
||||
(u'template',),
|
||||
formatters=_formatters)
|
||||
data = (data or _('Unable to display VNFFGD template!'))
|
||||
return (('template',), data)
|
||||
return ((u'template',), data)
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
{
|
||||
"extVirtualLinks": [
|
||||
{
|
||||
"id": "ext-vl-uuid-VL1",
|
||||
"resourceId": "neutron-network-uuid_VL1",
|
||||
"extCps": [
|
||||
{
|
||||
"cpdId": "CP1",
|
||||
"cpConfig": [
|
||||
{
|
||||
"cpProtocolData": [
|
||||
{
|
||||
"layerProtocol": "IP_OVER_ETHERNET",
|
||||
"ipOverEthernet": {
|
||||
"ipAddresses": [
|
||||
{
|
||||
"type": "IPV4",
|
||||
"numDynamicAddresses": 1,
|
||||
"subnetId": "subnet-uuid"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cpdId": "CP2",
|
||||
"cpConfig": [
|
||||
{
|
||||
"cpProtocolData": [
|
||||
{
|
||||
"layerProtocol": "IP_OVER_ETHERNET",
|
||||
"ipOverEthernet": {
|
||||
"ipAddresses": [
|
||||
{
|
||||
"type": "IPV4",
|
||||
"fixedAddresses": [
|
||||
"10.0.0.1"
|
||||
],
|
||||
"subnetId": "subnet-uuid"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"vimConnectionInfo": [
|
||||
{
|
||||
"id": "vim-uuid",
|
||||
"vimType": "ETSINFV.OPENSTACK_KEYSTONE.v_2",
|
||||
"vimConnectionId": "dummy-vimid",
|
||||
"interfaceInfo": {
|
||||
"key1":"value1",
|
||||
"key2":"value2"
|
||||
},
|
||||
"accessInfo": {
|
||||
"key1":"value1",
|
||||
"key2":"value2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"additionalParams": {"all": true}
|
||||
}
|
||||
@@ -41,8 +41,7 @@ LOG = logging.getLogger(__name__)
|
||||
_mixed_case_fields = ('vnfInstanceName', 'vnfInstanceDescription', 'vnfdId',
|
||||
'vnfProvider', 'vnfProductName', 'vnfSoftwareVersion',
|
||||
'vnfdVersion', 'instantiationState',
|
||||
'vimConnectionInfo', 'instantiatedVnfInfo',
|
||||
'vnfConfigurableProperties')
|
||||
'vimConnectionInfo', 'instantiatedVnfInfo')
|
||||
|
||||
_VNF_INSTANCE = 'vnf_instance'
|
||||
|
||||
@@ -69,7 +68,6 @@ def _get_columns(vnflcm_obj, action="/?originalUrl=https%3A%2F%2Fgit.openstack.org%2FNone)%3A%253C%2Fcode">
|
||||
'vnfdVersion': 'VNFD Version',
|
||||
'instantiationState': 'Instantiation State',
|
||||
'_links': 'Links',
|
||||
'vnfConfigurableProperties': 'VNF Configurable Properties',
|
||||
}
|
||||
if action == 'show':
|
||||
if vnflcm_obj['instantiationState'] == 'INSTANTIATED':
|
||||
@@ -238,12 +236,6 @@ class HealVnfLcm(command.Command):
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(HealVnfLcm, self).get_parser(prog_name)
|
||||
usage_message = ('''%(prog)s [-h] [--cause CAUSE]
|
||||
[--vnfc-instance <vnfc-instance-id> '''
|
||||
'''[<vnfc-instance-id> ...]]
|
||||
[--additional-param-file <additional-param-file>]
|
||||
-- <vnf-instance>''')
|
||||
parser.usage = usage_message
|
||||
parser.add_argument(
|
||||
_VNF_INSTANCE,
|
||||
metavar="<vnf-instance>",
|
||||
@@ -257,11 +249,6 @@ class HealVnfLcm(command.Command):
|
||||
nargs="+",
|
||||
help=_("List of VNFC instances requiring a healing action.")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--additional-param-file',
|
||||
metavar="<additional-param-file>",
|
||||
help=_("Additional parameters passed by the NFVO as input "
|
||||
"to the healing process."))
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
@@ -270,8 +257,6 @@ class HealVnfLcm(command.Command):
|
||||
body['cause'] = parsed_args.cause
|
||||
if parsed_args.vnfc_instance:
|
||||
body['vnfcInstanceId'] = parsed_args.vnfc_instance
|
||||
if parsed_args.additional_param_file:
|
||||
body.update(jsonfile2body(parsed_args.additional_param_file))
|
||||
|
||||
return body
|
||||
|
||||
@@ -491,51 +476,46 @@ class ScaleVnfLcm(command.Command):
|
||||
_VNF_INSTANCE,
|
||||
metavar="<vnf-instance>",
|
||||
help=_('VNF instance ID to scale'))
|
||||
parser.add_argument(
|
||||
'--I',
|
||||
metavar="<param-file>",
|
||||
help=_("Specify scale request parameters in a json file."))
|
||||
parser.add_argument(
|
||||
'--type',
|
||||
metavar="<type>",
|
||||
choices=['SCALE_OUT', 'SCALE_IN'],
|
||||
help=_("Indicates the type of the scale operation requested"))
|
||||
parser.add_argument(
|
||||
'--aspect-id',
|
||||
metavar="<aspect-id>",
|
||||
help=_("Identifier of the scaling aspect."))
|
||||
parser.add_argument(
|
||||
'--number-of-steps',
|
||||
metavar="<number-of-steps>",
|
||||
type=int,
|
||||
help=_("Number of scaling steps to be executed as part of "
|
||||
help=_("Number of scaling steps to be executed as part of"
|
||||
"this Scale VNF operation."))
|
||||
parser.add_argument(
|
||||
'--additional-param-file',
|
||||
metavar="<additional-param-file>",
|
||||
help=_("Additional parameters passed by the NFVO as input "
|
||||
help=_("Additional parameters passed by the NFVO as input"
|
||||
"to the scaling process."))
|
||||
|
||||
scale_require_parameters = parser.add_argument_group(
|
||||
"require arguments"
|
||||
)
|
||||
scale_require_parameters.add_argument(
|
||||
'--type',
|
||||
metavar="<type>",
|
||||
required=True,
|
||||
choices=['SCALE_OUT', 'SCALE_IN'],
|
||||
help=_("SCALE_OUT or SCALE_IN for type of scale operation."))
|
||||
scale_require_parameters.add_argument(
|
||||
'--aspect-id',
|
||||
required=True,
|
||||
metavar="<aspect-id>",
|
||||
help=_("Identifier of the scaling aspect."))
|
||||
|
||||
return parser
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
def args2body(self, file_path=None):
|
||||
"""To store request body, call jsonfile2body.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
file_path ([string], optional): file path of param file(json).
|
||||
Defaults to None.
|
||||
|
||||
Returns:
|
||||
body ([dict]): Request body is stored
|
||||
body[dict]: [description]
|
||||
"""
|
||||
body = {'type': parsed_args.type, 'aspectId': parsed_args.aspect_id}
|
||||
body = {}
|
||||
|
||||
if parsed_args.number_of_steps:
|
||||
body['numberOfSteps'] = parsed_args.number_of_steps
|
||||
|
||||
if parsed_args.additional_param_file:
|
||||
body.update(jsonfile2body(parsed_args.additional_param_file))
|
||||
if file_path:
|
||||
return jsonfile2body(file_path)
|
||||
|
||||
return body
|
||||
|
||||
@@ -543,66 +523,13 @@ class ScaleVnfLcm(command.Command):
|
||||
"""Execute scale_vnf_instance and output result comment.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
parsed_args ([Namespace]): [description]
|
||||
"""
|
||||
client = self.app.client_manager.tackerclient
|
||||
result = client.scale_vnf_instance(
|
||||
parsed_args.vnf_instance,
|
||||
self.args2body(parsed_args))
|
||||
if not result:
|
||||
print((_('Scale request for VNF Instance %s has been accepted.')
|
||||
% parsed_args.vnf_instance))
|
||||
|
||||
|
||||
class ChangeExtConnVnfLcm(command.Command):
|
||||
_description = _("Change External VNF Connectivity")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ChangeExtConnVnfLcm, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_INSTANCE,
|
||||
metavar="<vnf-instance>",
|
||||
help=_("VNF instance ID to Change External VNF Connectivity"))
|
||||
parser.add_argument(
|
||||
'request_file',
|
||||
metavar="<param-file>",
|
||||
help=_("Specify change-ext-conn request parameters "
|
||||
"in a json file."))
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
result = client.change_ext_conn_vnf_instance(
|
||||
parsed_args.vnf_instance, jsonfile2body(
|
||||
parsed_args.request_file))
|
||||
if not result:
|
||||
print((_('Change External VNF Connectivity for VNF Instance %s '
|
||||
'has been accepted.') % parsed_args.vnf_instance))
|
||||
|
||||
|
||||
class ChangeVnfPkgVnfLcm(command.Command):
|
||||
_description = _("Change Current VNF Package")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ChangeVnfPkgVnfLcm, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_INSTANCE,
|
||||
metavar="<vnf-instance>",
|
||||
help=_("VNF instance ID to Change Current VNF Package"))
|
||||
parser.add_argument(
|
||||
'request_file',
|
||||
metavar="<param-file>",
|
||||
help=_("Specify change-vnfpkg request parameters "
|
||||
"in a json file."))
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
client = self.app.client_manager.tackerclient
|
||||
result = client.change_vnfpkg_vnf_instance(
|
||||
parsed_args.vnf_instance, jsonfile2body(
|
||||
parsed_args.request_file))
|
||||
if not result:
|
||||
print((_('Change Current VNF Package for VNF Instance %s '
|
||||
'has been accepted.') % parsed_args.vnf_instance))
|
||||
if parsed_args.additional_param_file:
|
||||
result = client.scale_vnf_instance(
|
||||
parsed_args.vnf_instance,
|
||||
self.args2body(file_path=parsed_args.additional_param_file))
|
||||
if not result:
|
||||
print((_('Scale request for VNF Instance %(id)s has been'
|
||||
' accepted.') % {'id': parsed_args.vnf_instance}))
|
||||
|
||||
@@ -11,63 +11,7 @@
|
||||
# under the License.
|
||||
|
||||
from osc_lib.command import command
|
||||
from osc_lib import utils
|
||||
from tackerclient.i18n import _
|
||||
from tackerclient.osc import sdk_utils
|
||||
from tackerclient.osc import utils as tacker_osc_utils
|
||||
|
||||
_VNF_LCM_OP_OCC_ID = 'vnf_lcm_op_occ_id'
|
||||
|
||||
_MIXED_CASE_FIELDS = ['operationState', 'stateEnteredTime', 'startTime',
|
||||
'vnfInstanceId', 'grantId', 'isAutomaticInvocation',
|
||||
'isCancelPending', 'cancelMode', 'operationParams',
|
||||
'resourceChanges', 'changedInfo',
|
||||
'changedExtConnectivity']
|
||||
|
||||
_FORMATTERS = {
|
||||
'operationParams': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'error': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'resourceChanges': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'changedInfo': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'changedExtConnectivity': tacker_osc_utils.FormatComplexDataColumn,
|
||||
'_links': tacker_osc_utils.FormatComplexDataColumn
|
||||
}
|
||||
|
||||
_ATTR_MAP = (
|
||||
('id', 'id', tacker_osc_utils.LIST_BOTH),
|
||||
('operationState', 'operationState', tacker_osc_utils.LIST_BOTH),
|
||||
('vnfInstanceId', 'vnfInstanceId', tacker_osc_utils.LIST_BOTH),
|
||||
('operation', 'operation', tacker_osc_utils.LIST_BOTH)
|
||||
)
|
||||
|
||||
|
||||
def _get_columns(vnflcm_op_occ_obj, action=None):
|
||||
|
||||
column_map = {
|
||||
'id': 'ID',
|
||||
'operationState': 'Operation State',
|
||||
'stateEnteredTime': 'State Entered Time',
|
||||
'startTime': 'Start Time',
|
||||
'vnfInstanceId': 'VNF Instance ID',
|
||||
'operation': 'Operation',
|
||||
'isAutomaticInvocation': 'Is Automatic Invocation',
|
||||
'isCancelPending': 'Is Cancel Pending',
|
||||
'error': 'Error',
|
||||
'_links': 'Links'
|
||||
}
|
||||
|
||||
if action == 'show':
|
||||
column_map.update(
|
||||
{'operationParams': 'Operation Parameters',
|
||||
'grantId': 'Grant ID',
|
||||
'resourceChanges': 'Resource Changes',
|
||||
'changedInfo': 'Changed Info',
|
||||
'cancelMode': 'Cancel Mode',
|
||||
'changedExtConnectivity': 'Changed External Connectivity'}
|
||||
)
|
||||
|
||||
return sdk_utils.get_osc_show_columns_for_sdk_resource(vnflcm_op_occ_obj,
|
||||
column_map)
|
||||
|
||||
|
||||
class RollbackVnfLcmOp(command.Command):
|
||||
@@ -82,7 +26,7 @@ class RollbackVnfLcmOp(command.Command):
|
||||
"""
|
||||
parser = super(RollbackVnfLcmOp, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_LCM_OP_OCC_ID,
|
||||
'vnf_lcm_op_occ_id',
|
||||
metavar="<vnf-lcm-op-occ-id>",
|
||||
help=_('VNF lifecycle management operation occurrence ID.'))
|
||||
|
||||
@@ -99,255 +43,3 @@ class RollbackVnfLcmOp(command.Command):
|
||||
if not result:
|
||||
print((_('Rollback request for LCM operation %(id)s has been'
|
||||
' accepted') % {'id': parsed_args.vnf_lcm_op_occ_id}))
|
||||
|
||||
|
||||
class CancelVnfLcmOp(command.ShowOne):
|
||||
_description = _("Cancel VNF Instance")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
"""Add arguments to parser.
|
||||
|
||||
Args:
|
||||
prog_name ([type]): program name
|
||||
|
||||
Returns:
|
||||
parser([ArgumentParser]):
|
||||
"""
|
||||
parser = super(CancelVnfLcmOp, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_LCM_OP_OCC_ID,
|
||||
metavar="<vnf-lcm-op-occ-id>",
|
||||
help=_('VNF lifecycle management operation occurrence ID.'))
|
||||
parser.add_argument(
|
||||
"--cancel-mode",
|
||||
default='GRACEFUL',
|
||||
metavar="<cancel-mode>",
|
||||
choices=['GRACEFUL', 'FORCEFUL'],
|
||||
help=_("Cancel mode can be 'GRACEFUL' or 'FORCEFUL'. "
|
||||
"Default is 'GRACEFUL'"))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
"""Execute cancel_vnf_instance and output comment.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
"""
|
||||
client = self.app.client_manager.tackerclient
|
||||
result = client.cancel_vnf_instance(
|
||||
parsed_args.vnf_lcm_op_occ_id,
|
||||
{'cancelMode': parsed_args.cancel_mode})
|
||||
if not result:
|
||||
print((_('Cancel request for LCM operation %(id)s has been'
|
||||
' accepted') % {'id': parsed_args.vnf_lcm_op_occ_id}))
|
||||
|
||||
|
||||
class FailVnfLcmOp(command.ShowOne):
|
||||
_description = _("Fail VNF Instance")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
"""Add arguments to parser.
|
||||
|
||||
Args:
|
||||
prog_name ([type]): program name
|
||||
|
||||
Returns:
|
||||
parser([ArgumentParser]):
|
||||
"""
|
||||
parser = super(FailVnfLcmOp, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_LCM_OP_OCC_ID,
|
||||
metavar="<vnf-lcm-op-occ-id>",
|
||||
help=_('VNF lifecycle management operation occurrence ID.'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
"""Execute fail_vnf_instance and output response.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
"""
|
||||
client = self.app.client_manager.tackerclient
|
||||
obj = client.fail_vnf_instance(parsed_args.vnf_lcm_op_occ_id)
|
||||
display_columns, columns = _get_columns(obj)
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj),
|
||||
columns, formatters=_FORMATTERS,
|
||||
mixed_case_fields=_MIXED_CASE_FIELDS)
|
||||
return (display_columns, data)
|
||||
|
||||
|
||||
class RetryVnfLcmOp(command.Command):
|
||||
_description = _("Retry VNF Instance")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
"""Add arguments to parser.
|
||||
|
||||
Args:
|
||||
prog_name ([type]): program name
|
||||
|
||||
Returns:
|
||||
parser([ArgumentParser]):
|
||||
"""
|
||||
|
||||
parser = super(RetryVnfLcmOp, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
_VNF_LCM_OP_OCC_ID,
|
||||
metavar="<vnf-lcm-op-occ-id>",
|
||||
help=_('VNF lifecycle management operation occurrence ID.'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
"""Execute retry_vnf_instance and output comment.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
"""
|
||||
client = self.app.client_manager.tackerclient
|
||||
result = client.retry_vnf_instance(parsed_args.vnf_lcm_op_occ_id)
|
||||
if not result:
|
||||
print((_('Retry request for LCM operation %(id)s has been'
|
||||
' accepted') % {'id': parsed_args.vnf_lcm_op_occ_id}))
|
||||
|
||||
|
||||
class ListVnfLcmOp(command.Lister):
|
||||
_description = _("List LCM Operation Occurrences")
|
||||
|
||||
def get_parser(self, program_name):
|
||||
"""Add arguments to parser.
|
||||
|
||||
Args:
|
||||
program_name ([type]): program name
|
||||
|
||||
Returns:
|
||||
parser([ArgumentParser]):
|
||||
"""
|
||||
parser = super(ListVnfLcmOp, self).get_parser(program_name)
|
||||
parser.add_argument(
|
||||
"--filter",
|
||||
metavar="<filter>",
|
||||
help=_("Attribute-based-filtering parameters"),
|
||||
)
|
||||
fields_exclusive_group = parser.add_mutually_exclusive_group(
|
||||
required=False)
|
||||
fields_exclusive_group.add_argument(
|
||||
"--fields",
|
||||
metavar="<fields>",
|
||||
help=_("Complex attributes to be included into the response"),
|
||||
)
|
||||
fields_exclusive_group.add_argument(
|
||||
"--exclude-fields",
|
||||
metavar="<exclude-fields>",
|
||||
help=_("Complex attributes to be excluded from the response"),
|
||||
)
|
||||
return parser
|
||||
|
||||
def get_attributes(self, exclude=None):
|
||||
"""Get attributes.
|
||||
|
||||
Args:
|
||||
exclude([exclude]): a list of fields which needs to exclude.
|
||||
|
||||
Returns:
|
||||
attributes([attributes]): a list of table entry definitions.
|
||||
Each entry should be a tuple consisting of
|
||||
(API attribute name, header name, listing mode).
|
||||
"""
|
||||
fields = [
|
||||
{
|
||||
"key": "id",
|
||||
"value": "ID"
|
||||
},
|
||||
{
|
||||
"key": "operationState",
|
||||
"value": "Operation State"
|
||||
},
|
||||
{
|
||||
"key": "vnfInstanceId",
|
||||
"value": "VNF Instance ID"
|
||||
},
|
||||
{
|
||||
"key": "operation",
|
||||
"value": "Operation"
|
||||
}
|
||||
]
|
||||
|
||||
attributes = []
|
||||
if exclude is None:
|
||||
exclude = []
|
||||
|
||||
for field in fields:
|
||||
if field['value'] not in exclude:
|
||||
attributes.extend([(field['key'], field['value'],
|
||||
tacker_osc_utils.LIST_BOTH)])
|
||||
return tuple(attributes)
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
"""Execute list_vnflcm_op_occs and output response.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
"""
|
||||
params = {}
|
||||
exclude_fields = []
|
||||
extra_fields = []
|
||||
|
||||
if parsed_args.filter:
|
||||
params['filter'] = parsed_args.filter
|
||||
if parsed_args.fields:
|
||||
params['fields'] = parsed_args.fields
|
||||
fields = parsed_args.fields.split(',')
|
||||
for field in fields:
|
||||
extra_fields.append(field.split('/')[0])
|
||||
if parsed_args.exclude_fields:
|
||||
params['exclude-fields'] = parsed_args.exclude_fields
|
||||
fields = parsed_args.exclude_fields.split(',')
|
||||
exclude_fields.extend(fields)
|
||||
|
||||
client = self.app.client_manager.tackerclient
|
||||
vnflcm_op_occs = client.list_vnf_lcm_op_occs(**params)
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
self.get_attributes(exclude=exclude_fields),
|
||||
long_listing=True)
|
||||
|
||||
dictionary_properties = (utils.get_dict_properties(
|
||||
s, columns, mixed_case_fields=_MIXED_CASE_FIELDS)
|
||||
for s in vnflcm_op_occs
|
||||
)
|
||||
|
||||
return (headers, dictionary_properties)
|
||||
|
||||
|
||||
class ShowVnfLcmOp(command.ShowOne):
|
||||
_description = _("Display Operation Occurrence details")
|
||||
|
||||
def get_parser(self, program_name):
|
||||
"""Add arguments to parser.
|
||||
|
||||
Args:
|
||||
program_name ([type]): program name
|
||||
|
||||
Returns:
|
||||
parser([ArgumentParser]):
|
||||
"""
|
||||
parser = super(ShowVnfLcmOp, self).get_parser(program_name)
|
||||
parser.add_argument(
|
||||
_VNF_LCM_OP_OCC_ID,
|
||||
metavar="<vnf-lcm-op-occ-id>",
|
||||
help=_('VNF lifecycle management operation occurrence ID.'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
"""Execute show_vnf_lcm_op_occs and output response.
|
||||
|
||||
Args:
|
||||
parsed_args ([Namespace]): arguments of CLI.
|
||||
"""
|
||||
client = self.app.client_manager.tackerclient
|
||||
obj = client.show_vnf_lcm_op_occs(parsed_args.vnf_lcm_op_occ_id)
|
||||
display_columns, columns = _get_columns(obj, action='show')
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj),
|
||||
columns, formatters=_FORMATTERS,
|
||||
mixed_case_fields=_MIXED_CASE_FIELDS)
|
||||
return (display_columns, data)
|
||||
|
||||
@@ -218,7 +218,7 @@ class ShowTemplateVNFD(command.ShowOne):
|
||||
obj[_VNFD]['attributes']['vnfd'])
|
||||
data = utils.get_item_properties(
|
||||
sdk_utils.DictModel(obj[_VNFD]),
|
||||
('attributes',),
|
||||
(u'attributes',),
|
||||
formatters=_formatters)
|
||||
data = (data or _('Unable to display VNFD template!'))
|
||||
return (('attributes',), data)
|
||||
return ((u'attributes',), data)
|
||||
|
||||
@@ -434,9 +434,9 @@ class DownloadVnfPackageArtifact(command.Command):
|
||||
parser.add_argument(
|
||||
"--file",
|
||||
metavar="<FILE>",
|
||||
help=_("Local file to save downloaded VNF Package artifact "
|
||||
"file data. If this is not specified and "
|
||||
"there is no redirection then data will not be saved.")
|
||||
help=_("Local file to save downloaded VNF Package or VNFD data. "
|
||||
"If this is not specified and there is no redirection "
|
||||
"then data will not be saved.")
|
||||
)
|
||||
return parser
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
{
|
||||
"vnfdId": "c6595341-a5bb-8246-53c4-7aeb843d60c5",
|
||||
"additionalParams": {
|
||||
"upgrade_type": "RollingUpdate",
|
||||
"lcm-operation-coordinate-old-vnf": "./Scripts/coordinate_old_vnf.py",
|
||||
"lcm-operation-coordinate-old-vnf-class": "CoordinateOldVnf",
|
||||
"lcm-operation-coordinate-new-vnf": "./Scripts/coordinate_new_vnf.py",
|
||||
"lcm-operation-coordinate-new-vnf-class": "CoordinateNewVnf",
|
||||
"vdu_params": [{
|
||||
"vduId": "VDU1",
|
||||
"old_vnfc_param": {
|
||||
"cp_name": "VDU1_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
},
|
||||
"new_vnfc_param": {
|
||||
"cp_name": "VDU1_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
}
|
||||
}, {
|
||||
"vduId": "VDU2",
|
||||
"old_vnfc_param": {
|
||||
"cp_name": "VDU2_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
},
|
||||
"new_vnfc_param": {
|
||||
"cp_name": "VDU2_CP1",
|
||||
"username": "ubuntu",
|
||||
"password": "ubuntu"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,6 @@ import itertools
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from urllib import parse as urlparse
|
||||
|
||||
from cliff import app
|
||||
from cliff import commandmanager
|
||||
|
||||
from keystoneclient.auth.identity import v2 as v2_auth
|
||||
from keystoneclient.auth.identity import v3 as v3_auth
|
||||
@@ -36,6 +32,10 @@ from keystoneclient import discover
|
||||
from keystoneclient import exceptions as ks_exc
|
||||
from keystoneclient import session
|
||||
from oslo_utils import encodeutils
|
||||
import six.moves.urllib.parse as urlparse
|
||||
|
||||
from cliff import app
|
||||
from cliff import commandmanager
|
||||
|
||||
from tackerclient.common import clientmanager
|
||||
from tackerclient.common import command as openstack_command
|
||||
|
||||
@@ -23,6 +23,7 @@ from cliff.formatters import table
|
||||
from cliff import lister
|
||||
from cliff import show
|
||||
from oslo_serialization import jsonutils
|
||||
import six
|
||||
|
||||
from tackerclient.common._i18n import _
|
||||
from tackerclient.common import command
|
||||
@@ -353,7 +354,8 @@ class TackerCommandMeta(abc.ABCMeta):
|
||||
name, bases, cls_dict)
|
||||
|
||||
|
||||
class TackerCommand(command.OpenStackCommand, metaclass=TackerCommandMeta):
|
||||
@six.add_metaclass(TackerCommandMeta)
|
||||
class TackerCommand(command.OpenStackCommand):
|
||||
|
||||
api = 'nfv-orchestration'
|
||||
values_specs = []
|
||||
|
||||
@@ -117,8 +117,7 @@ class UpdateVIM(tackerV10.UpdateCommand):
|
||||
with open(parsed_args.config_file) as f:
|
||||
config_yaml = f.read()
|
||||
try:
|
||||
config_param = yaml.load(config_yaml,
|
||||
Loader=yaml.SafeLoader)
|
||||
config_param = yaml.load(config_yaml)
|
||||
except yaml.YAMLError as e:
|
||||
raise exceptions.InvalidInput(reason=e)
|
||||
vim_obj = body[self.resource]
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from urllib import parse as urlparse
|
||||
import six.moves.urllib.parse as urlparse
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
|
||||
|
||||
@@ -232,18 +232,3 @@ class DeleteVNFFG(tackerV10.DeleteCommand):
|
||||
"""Delete a given VNFFG."""
|
||||
|
||||
resource = _VNFFG
|
||||
remove_output_fields = ["attributes"]
|
||||
|
||||
def add_known_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'--force',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help=_('Force delete VNFFG'))
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = dict()
|
||||
if parsed_args.force:
|
||||
body[self.resource] = dict()
|
||||
body[self.resource]['attributes'] = {'force': True}
|
||||
return body
|
||||
|
||||
@@ -22,7 +22,6 @@ from cliff import columns as cliff_columns
|
||||
|
||||
class FixturedTestCase(testtools.TestCase):
|
||||
client_fixture_class = None
|
||||
api_version = '1'
|
||||
|
||||
def setUp(self):
|
||||
super(FixturedTestCase, self).setUp()
|
||||
@@ -30,8 +29,7 @@ class FixturedTestCase(testtools.TestCase):
|
||||
if self.client_fixture_class:
|
||||
self.requests_mock = self.useFixture(requests_mock_fixture.
|
||||
Fixture())
|
||||
fix = self.client_fixture_class(self.requests_mock,
|
||||
api_version=self.api_version)
|
||||
fix = self.client_fixture_class(self.requests_mock)
|
||||
self.cs = self.useFixture(fix).client
|
||||
|
||||
def check_parser(self, cmd, args, verify_args):
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
# Copyright (C) 2021 Nippon Telegraph and Telephone Corporation
|
||||
# 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 os
|
||||
|
||||
import ddt
|
||||
from unittest import mock
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.osc.common.vnflcm import vnflcm_versions
|
||||
from tackerclient.tests.unit.osc import base
|
||||
from tackerclient.tests.unit.osc.v1.fixture_data import client
|
||||
|
||||
|
||||
class TestVnfLcm(base.FixturedTestCase):
|
||||
client_fixture_class = client.ClientFixture
|
||||
|
||||
def setUp(self):
|
||||
super(TestVnfLcm, self).setUp()
|
||||
self.url = client.TACKER_URL
|
||||
self.header = {'content-type': 'application/json'}
|
||||
self.app = mock.Mock()
|
||||
self.app_args = mock.Mock()
|
||||
self.client_manager = self.cs
|
||||
self.app.client_manager.tackerclient = self.client_manager
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestVnfLcmVersions(TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestVnfLcmVersions, self).setUp()
|
||||
self.vnflcm_versions = vnflcm_versions.VnfLcmVersions(
|
||||
self.app, self.app_args, cmd_name='vnflcm versions')
|
||||
|
||||
def _versions_response(self, major_version=None):
|
||||
if major_version is None:
|
||||
return {"uriPrefix": "/vnflcm",
|
||||
"apiVersions": [{"version": "1.3.0",
|
||||
"isDeprecated": False},
|
||||
{"version": "2.0.0",
|
||||
"isDeprecated": False}]}
|
||||
elif major_version == "1":
|
||||
return {"uriPrefix": "/vnflcm/v1",
|
||||
"apiVersions": [{"version": "1.3.0",
|
||||
"isDeprecated": False}]}
|
||||
elif major_version == "2":
|
||||
return {"uriPrefix": "/vnflcm/v2",
|
||||
"apiVersions": [{"version": "2.0.0",
|
||||
"isDeprecated": False}]}
|
||||
|
||||
def test_invalid_major_version(self):
|
||||
parser = self.vnflcm_versions.get_parser('vnflcm versions')
|
||||
parsed_args = parser.parse_args(["--major-version", "3"])
|
||||
self.assertRaises(exceptions.InvalidInput,
|
||||
self.vnflcm_versions.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_no_arg(self):
|
||||
parser = self.vnflcm_versions.get_parser('vnflcm versions')
|
||||
parsed_args = parser.parse_args([])
|
||||
|
||||
response = self._versions_response()
|
||||
self.requests_mock.register_uri(
|
||||
'GET', os.path.join(self.url, 'vnflcm/api_versions'),
|
||||
json=response, headers=self.header)
|
||||
|
||||
colmns, data = self.vnflcm_versions.take_action(parsed_args)
|
||||
|
||||
self.assertEqual(colmns, tuple(response.keys()))
|
||||
self.assertEqual(data, tuple(response.values()))
|
||||
|
||||
@ddt.data('1', '2')
|
||||
def test_take_action_with_major_version(self, major_version):
|
||||
parser = self.vnflcm_versions.get_parser('vnflcm versions')
|
||||
parsed_args = parser.parse_args(["--major-version",
|
||||
major_version])
|
||||
|
||||
response = self._versions_response(major_version)
|
||||
self.requests_mock.register_uri(
|
||||
'GET',
|
||||
os.path.join(self.url,
|
||||
'vnflcm/v{}/api_versions'.format(major_version)),
|
||||
json=response, headers=self.header)
|
||||
|
||||
colmns, data = self.vnflcm_versions.take_action(parsed_args)
|
||||
|
||||
self.assertEqual(colmns, tuple(response.keys()))
|
||||
self.assertEqual(data, tuple(response.values()))
|
||||
@@ -25,8 +25,7 @@ TACKER_URL = 'http://nfv-orchestration'
|
||||
|
||||
class ClientFixture(fixtures.Fixture):
|
||||
|
||||
def __init__(self, requests_mock, identity_url=IDENTITY_URL,
|
||||
api_version='1'):
|
||||
def __init__(self, requests_mock, identity_url=IDENTITY_URL):
|
||||
super(ClientFixture, self).__init__()
|
||||
self.identity_url = identity_url
|
||||
self.client = None
|
||||
@@ -36,7 +35,6 @@ class ClientFixture(fixtures.Fixture):
|
||||
self.discovery = fixture.V2Discovery(href=self.identity_url)
|
||||
s = self.token.add_service('nfv-orchestration')
|
||||
s.add_endpoint(TACKER_URL)
|
||||
self.api_version = api_version
|
||||
|
||||
def setUp(self):
|
||||
super(ClientFixture, self).setUp()
|
||||
@@ -59,5 +57,4 @@ class ClientFixture(fixtures.Fixture):
|
||||
region_name='RegionOne',
|
||||
auth_url=self.identity_url,
|
||||
token=self.token.token_id,
|
||||
endpoint_url=TACKER_URL,
|
||||
api_version=self.api_version)
|
||||
endpoint_url=TACKER_URL)
|
||||
|
||||
@@ -20,6 +20,7 @@ from unittest import mock
|
||||
|
||||
import ddt
|
||||
from oslo_utils.fixture import uuidsentinel
|
||||
import six
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.osc import utils as tacker_osc_utils
|
||||
@@ -46,14 +47,12 @@ class TestVnfLcm(base.FixturedTestCase):
|
||||
def _get_columns_vnflcm(action='create'):
|
||||
columns = ['ID', 'Instantiation State', 'VNF Instance Description',
|
||||
'VNF Instance Name', 'VNF Product Name', 'VNF Provider',
|
||||
'VNF Software Version', 'VNFD ID', 'VNFD Version', 'Links',
|
||||
'VNF Configurable Properties']
|
||||
'VNF Software Version', 'VNFD ID', 'VNFD Version', 'Links']
|
||||
if action == 'show':
|
||||
columns.extend(['Instantiated Vnf Info', 'VIM Connection Info'])
|
||||
if action == 'list':
|
||||
columns = [ele for ele in columns if ele not in
|
||||
['VNFD Version', 'VNF Instance Description',
|
||||
'VNF Configurable Properties']]
|
||||
['VNFD Version', 'VNF Instance Description']]
|
||||
columns.remove('Links')
|
||||
return columns
|
||||
|
||||
@@ -288,9 +287,6 @@ class TestHealVnfLcm(TestVnfLcm):
|
||||
self.heal_vnf_lcm = vnflcm.HealVnfLcm(
|
||||
self.app, self.app_args, cmd_name='vnflcm heal')
|
||||
|
||||
_heal_sample_param_file = ("./tackerclient/osc/v1/vnflcm/samples/"
|
||||
"heal_vnf_instance_param_sample.json")
|
||||
|
||||
@ddt.data((['--cause', 'test-cause', "--vnfc-instance",
|
||||
'vnfc-id-1', 'vnfc-id-2'],
|
||||
[('cause', 'test-cause'),
|
||||
@@ -299,8 +295,6 @@ class TestHealVnfLcm(TestVnfLcm):
|
||||
[('cause', 'test-cause')]),
|
||||
(["--vnfc-instance", 'vnfc-id-1', 'vnfc-id-2'],
|
||||
[('vnfc_instance', ['vnfc-id-1', 'vnfc-id-2'])]),
|
||||
(["--additional-param-file", _heal_sample_param_file],
|
||||
[('additional_param_file', _heal_sample_param_file)]),
|
||||
([], []))
|
||||
@ddt.unpack
|
||||
def test_take_action(self, arglist, verifylist):
|
||||
@@ -345,25 +339,6 @@ class TestHealVnfLcm(TestVnfLcm):
|
||||
self.heal_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_param_file_not_exists(self):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = "./not_exists.json"
|
||||
arglist = [vnf_instance['id'],
|
||||
'--additional-param-file', sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('additional_param_file', sample_param_file)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.heal_vnf_lcm, arglist,
|
||||
verifylist)
|
||||
|
||||
ex = self.assertRaises(exceptions.InvalidInput,
|
||||
self.heal_vnf_lcm.take_action, parsed_args)
|
||||
|
||||
expected_msg = ("Invalid input: File %s does not exist "
|
||||
"or user does not have read privileges to it")
|
||||
self.assertEqual(expected_msg % sample_param_file, str(ex))
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestTerminateVnfLcm(TestVnfLcm):
|
||||
@@ -473,7 +448,7 @@ class TestTerminateVnfLcm(TestVnfLcm):
|
||||
"delete vnf instance %(id)s"
|
||||
% {'timeout': 15, 'id': vnf_instance['id']})
|
||||
|
||||
self.assertIn(expected_message, str(result))
|
||||
self.assertIn(expected_message, six.text_type(result))
|
||||
self.assertNotCalled(mock_delete)
|
||||
|
||||
def test_terminate_no_options(self):
|
||||
@@ -677,38 +652,6 @@ class TestScaleVnfLcm(TestVnfLcm):
|
||||
|
||||
self.assertEqual(expected_message, actual_message)
|
||||
|
||||
@ddt.data('SCALE_IN', 'SCALE_OUT')
|
||||
def test_take_action_no_param_file(self, scale_type):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
|
||||
arglist = [vnf_instance['id'],
|
||||
'--aspect-id', uuidsentinel.aspect_id,
|
||||
'--number-of-steps', '1',
|
||||
'--type', scale_type]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('aspect_id', uuidsentinel.aspect_id),
|
||||
('number_of_steps', 1),
|
||||
('type', scale_type)]
|
||||
|
||||
parsed_args = self.check_parser(self.scale_vnf_lcm, arglist,
|
||||
verifylist)
|
||||
|
||||
url = os.path.join(self.url, 'vnflcm/v1/vnf_instances',
|
||||
vnf_instance['id'], 'scale')
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, json={})
|
||||
|
||||
sys.stdout = buffer = StringIO()
|
||||
self.scale_vnf_lcm.take_action(parsed_args)
|
||||
|
||||
actual_message = buffer.getvalue().strip()
|
||||
|
||||
expected_message = ("Scale request for VNF Instance %s has been "
|
||||
"accepted.") % vnf_instance['id']
|
||||
|
||||
self.assertEqual(expected_message, actual_message)
|
||||
|
||||
@ddt.data('SCALE_IN', 'SCALE_OUT')
|
||||
def test_take_action_param_file_not_exists(self, scale_type):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
@@ -765,159 +708,3 @@ class TestScaleVnfLcm(TestVnfLcm):
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.scale_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestChangeExtConnVnfLcm(TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestChangeExtConnVnfLcm, self).setUp()
|
||||
self.change_ext_conn_vnf_lcm = vnflcm.ChangeExtConnVnfLcm(
|
||||
self.app, self.app_args,
|
||||
cmd_name='vnflcm change-ext-conn')
|
||||
|
||||
def test_take_action(self):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = ("./tackerclient/osc/v1/vnflcm/samples/"
|
||||
"change_ext_conn_vnf_instance_param_sample.json")
|
||||
|
||||
arglist = [vnf_instance['id'], sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('request_file', sample_param_file)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.change_ext_conn_vnf_lcm,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
url = os.path.join(self.url, 'vnflcm/v1/vnf_instances',
|
||||
vnf_instance['id'], 'change_ext_conn')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, json={})
|
||||
|
||||
sys.stdout = buffer = StringIO()
|
||||
with mock.patch.object(proxy_client.ClientBase,
|
||||
'_handle_fault_response') as m:
|
||||
self.change_ext_conn_vnf_lcm.take_action(parsed_args)
|
||||
# check no fault response is received
|
||||
self.assertNotCalled(m)
|
||||
self.assertEqual(
|
||||
('Change External VNF Connectivity for VNF Instance {0} '
|
||||
'has been accepted.'.format(vnf_instance['id'])),
|
||||
buffer.getvalue().strip())
|
||||
|
||||
def test_take_action_vnf_instance_not_found(self):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = ("./tackerclient/osc/v1/vnflcm/samples/"
|
||||
"change_ext_conn_vnf_instance_param_sample.json")
|
||||
arglist = [vnf_instance['id'], sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('request_file', sample_param_file)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.change_ext_conn_vnf_lcm,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
url = os.path.join(self.url, 'vnflcm/v1/vnf_instances',
|
||||
vnf_instance['id'], 'change_ext_conn')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=404, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.change_ext_conn_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_param_file_not_exists(self):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = "./not_exists.json"
|
||||
arglist = [vnf_instance['id'], sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('request_file', sample_param_file)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.change_ext_conn_vnf_lcm,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
ex = self.assertRaises(
|
||||
exceptions.InvalidInput,
|
||||
self.change_ext_conn_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
expected_msg = ("Invalid input: File %s does not exist "
|
||||
"or user does not have read privileges to it")
|
||||
self.assertEqual(expected_msg % sample_param_file, str(ex))
|
||||
|
||||
@mock.patch("os.open")
|
||||
@mock.patch("os.access")
|
||||
def test_take_action_invalid_format_param_file(self, mock_open,
|
||||
mock_access):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = "./invalid_param_file.json"
|
||||
arglist = [vnf_instance['id'], sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('request_file', sample_param_file)]
|
||||
|
||||
mock_open.return_value = "invalid_json_data"
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.change_ext_conn_vnf_lcm,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
ex = self.assertRaises(
|
||||
exceptions.InvalidInput,
|
||||
self.change_ext_conn_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
expected_msg = "Failed to load parameter file."
|
||||
self.assertIn(expected_msg, str(ex))
|
||||
|
||||
|
||||
class TestChangeVnfPkgVnfLcm(TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestChangeVnfPkgVnfLcm, self).setUp()
|
||||
self.change_vnfpkg_vnf_lcm = vnflcm.ChangeVnfPkgVnfLcm(
|
||||
self.app, self.app_args,
|
||||
cmd_name='vnflcm change-vnfpkg')
|
||||
|
||||
def test_take_action_with_v1_version(self):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = ("./tackerclient/osc/v2/vnflcm/samples/"
|
||||
"change_vnfpkg_vnf_instance_param_sample.json")
|
||||
arglist = [vnf_instance['id'], sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('request_file', sample_param_file)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.change_vnfpkg_vnf_lcm,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
url = os.path.join(self.url, 'vnflcm/v1/vnf_instances',
|
||||
vnf_instance['id'], 'change_vnfpkg')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=400, json={})
|
||||
|
||||
ex = self.assertRaises(exceptions.UnsupportedCommandVersion,
|
||||
self.change_vnfpkg_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
expected_msg = "This command is not supported in version 1"
|
||||
self.assertEqual(expected_msg, str(ex))
|
||||
|
||||
|
||||
class TestVnfLcmV1(base.FixturedTestCase):
|
||||
client_fixture_class = client.ClientFixture
|
||||
api_version = '1'
|
||||
|
||||
def setUp(self):
|
||||
super(TestVnfLcmV1, self).setUp()
|
||||
|
||||
def test_client_v2(self):
|
||||
self.assertEqual(self.cs.vnf_lcm_client.headers,
|
||||
{'Version': '1.3.0'})
|
||||
self.assertEqual(self.cs.vnf_lcm_client.vnf_instances_path,
|
||||
'/vnflcm/v1/vnf_instances')
|
||||
# check of other paths is omitted.
|
||||
|
||||
@@ -14,38 +14,13 @@ from io import StringIO
|
||||
import os
|
||||
import sys
|
||||
|
||||
import ddt
|
||||
from oslo_utils.fixture import uuidsentinel
|
||||
from unittest import mock
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.osc import utils as tacker_osc_utils
|
||||
from tackerclient.osc.v1.vnflcm import vnflcm_op_occs
|
||||
from tackerclient.tests.unit.osc import base
|
||||
from tackerclient.tests.unit.osc.v1.fixture_data import client
|
||||
from tackerclient.tests.unit.osc.v1 import vnflcm_op_occs_fakes
|
||||
|
||||
|
||||
def _get_columns_vnflcm_op_occs(action='show', parameter=None):
|
||||
|
||||
if action == 'fail':
|
||||
return ['ID', 'Operation State', 'State Entered Time',
|
||||
'Start Time', 'VNF Instance ID', 'Operation',
|
||||
'Is Automatic Invocation', 'Is Cancel Pending',
|
||||
'Error', 'Links']
|
||||
elif action == 'list':
|
||||
if parameter is not None:
|
||||
return ['ID', 'Operation']
|
||||
else:
|
||||
return ['ID', 'Operation State', 'VNF Instance ID',
|
||||
'Operation']
|
||||
else:
|
||||
return ['ID', 'Operation State', 'State Entered Time',
|
||||
'Start Time', 'VNF Instance ID', 'Grant ID',
|
||||
'Operation', 'Is Automatic Invocation',
|
||||
'Operation Parameters', 'Is Cancel Pending',
|
||||
'Cancel Mode', 'Error', 'Resource Changes',
|
||||
'Changed Info', 'Changed External Connectivity', 'Links']
|
||||
|
||||
|
||||
class TestVnfLcm(base.FixturedTestCase):
|
||||
@@ -61,70 +36,6 @@ class TestVnfLcm(base.FixturedTestCase):
|
||||
self.app.client_manager.tackerclient = self.client_manager
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestCancelVnfLcmOp(TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestCancelVnfLcmOp, self).setUp()
|
||||
self.cancel_vnf_lcm = vnflcm_op_occs.CancelVnfLcmOp(
|
||||
self.app, self.app_args, cmd_name='vnflcm op cancel')
|
||||
|
||||
@ddt.data('GRACEFUL', 'FORCEFUL')
|
||||
def test_take_action(self, cancel_mode):
|
||||
"""take_action normal system test"""
|
||||
|
||||
arglist = ['--cancel-mode', cancel_mode,
|
||||
uuidsentinel.vnf_lcm_op_occ_id]
|
||||
verifylist = [('cancel_mode', cancel_mode),
|
||||
('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)]
|
||||
|
||||
parsed_args = self.check_parser(
|
||||
self.cancel_vnf_lcm, arglist, verifylist)
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
uuidsentinel.vnf_lcm_op_occ_id,
|
||||
'cancel')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, json={})
|
||||
|
||||
sys.stdout = buffer = StringIO()
|
||||
self.cancel_vnf_lcm.take_action(parsed_args)
|
||||
|
||||
actual_message = buffer.getvalue().strip()
|
||||
|
||||
expected_message = (
|
||||
'Cancel request for LCM operation ' +
|
||||
uuidsentinel.vnf_lcm_op_occ_id +
|
||||
' has been accepted')
|
||||
|
||||
self.assertEqual(expected_message, actual_message)
|
||||
|
||||
def test_terminate_no_options(self):
|
||||
self.assertRaises(base.ParserException, self.check_parser,
|
||||
self.cancel_vnf_lcm, [], [])
|
||||
|
||||
def test_take_action_vnf_lcm_op_occ_id_not_found(self):
|
||||
"""take_action abnomaly system test"""
|
||||
|
||||
arglist = [uuidsentinel.vnf_lcm_op_occ_id]
|
||||
verifylist = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)]
|
||||
|
||||
parsed_args = self.check_parser(
|
||||
self.cancel_vnf_lcm, arglist, verifylist)
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
uuidsentinel.vnf_lcm_op_occ_id,
|
||||
'cancel')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=404, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.cancel_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestRollbackVnfLcmOp(TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
@@ -181,421 +92,3 @@ class TestRollbackVnfLcmOp(TestVnfLcm):
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.rollback_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
|
||||
class TestFailVnfLcmOp(TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestFailVnfLcmOp, self).setUp()
|
||||
self.fail_vnf_lcm = vnflcm_op_occs.FailVnfLcmOp(
|
||||
self.app, self.app_args, cmd_name='vnflcm op fail')
|
||||
|
||||
def test_take_action(self):
|
||||
"""Test of take_action()"""
|
||||
|
||||
vnflcm_op_occ = vnflcm_op_occs_fakes.vnflcm_op_occ_response(
|
||||
action='fail')
|
||||
|
||||
arg_list = [vnflcm_op_occ['id']]
|
||||
verify_list = [('vnf_lcm_op_occ_id', vnflcm_op_occ['id'])]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.fail_vnf_lcm, arg_list, verify_list)
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
vnflcm_op_occ['id'],
|
||||
'fail')
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, json=vnflcm_op_occ)
|
||||
|
||||
columns, data = (self.fail_vnf_lcm.take_action(parsed_args))
|
||||
expected_columns = _get_columns_vnflcm_op_occs(action='fail')
|
||||
|
||||
self.assertCountEqual(expected_columns, columns)
|
||||
|
||||
def test_take_action_vnf_lcm_op_occ_id_not_found(self):
|
||||
"""Test if vnf-lcm-op-occ-id does not find"""
|
||||
|
||||
arg_list = [uuidsentinel.vnf_lcm_op_occ_id]
|
||||
verify_list = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.fail_vnf_lcm, arg_list, verify_list)
|
||||
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
uuidsentinel.vnf_lcm_op_occ_id,
|
||||
'fail')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=404, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.fail_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_vnf_lcm_op_occ_state_is_conflict(self):
|
||||
"""Test if vnf-lcm-op-occ state is conflict"""
|
||||
|
||||
arg_list = [uuidsentinel.vnf_lcm_op_occ_id]
|
||||
verify_list = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.fail_vnf_lcm, arg_list, verify_list)
|
||||
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
uuidsentinel.vnf_lcm_op_occ_id,
|
||||
'fail')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=409, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.fail_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_vnf_lcm_op_occ_internal_server_error(self):
|
||||
"""Test if request is internal server error"""
|
||||
|
||||
arg_list = [uuidsentinel.vnf_lcm_op_occ_id]
|
||||
verify_list = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.fail_vnf_lcm, arg_list, verify_list)
|
||||
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
uuidsentinel.vnf_lcm_op_occ_id,
|
||||
'fail')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=500, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.fail_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_vnf_lcm_op_occ_missing_vnf_lcm_op_occ_id_argument(
|
||||
self):
|
||||
"""Test if vnflcm_op_occ_id is not provided"""
|
||||
|
||||
arg_list = []
|
||||
verify_list = [('vnf_lcm_op_occ_id', arg_list)]
|
||||
self.assertRaises(base.ParserException, self.check_parser,
|
||||
self.fail_vnf_lcm, arg_list, verify_list)
|
||||
|
||||
|
||||
class TestRetryVnfLcmOp(TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRetryVnfLcmOp, self).setUp()
|
||||
self.retry_vnf_lcm = vnflcm_op_occs.RetryVnfLcmOp(
|
||||
self.app, self.app_args, cmd_name='vnflcm op retry')
|
||||
|
||||
def test_take_action(self):
|
||||
"""Test of take_action()"""
|
||||
arg_list = [uuidsentinel.vnf_lcm_op_occ_id]
|
||||
verify_list = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.retry_vnf_lcm, arg_list, verify_list)
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
uuidsentinel.vnf_lcm_op_occ_id,
|
||||
'retry')
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, json={})
|
||||
|
||||
sys.stdout = buffer = StringIO()
|
||||
self.retry_vnf_lcm.take_action(parsed_args)
|
||||
|
||||
actual_message = buffer.getvalue().strip()
|
||||
|
||||
expected_message = (
|
||||
'Retry request for LCM operation ' +
|
||||
uuidsentinel.vnf_lcm_op_occ_id +
|
||||
' has been accepted')
|
||||
|
||||
self.assertEqual(expected_message, actual_message)
|
||||
|
||||
def test_take_action_vnf_lcm_op_occ_id_not_found(self):
|
||||
"""Test if vnf-lcm-op-occ-id is not found."""
|
||||
arglist = [uuidsentinel.vnf_lcm_op_occ_id]
|
||||
verifylist = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.retry_vnf_lcm, arglist, verifylist)
|
||||
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
uuidsentinel.vnf_lcm_op_occ_id,
|
||||
'retry')
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=404, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.retry_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_vnf_lcm_op_occ_state_is_conflict(self):
|
||||
"""Test if vnf-lcm-op-occ state is conflict"""
|
||||
|
||||
arg_list = [uuidsentinel.vnf_lcm_op_occ_id]
|
||||
verify_list = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.retry_vnf_lcm, arg_list, verify_list)
|
||||
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
uuidsentinel.vnf_lcm_op_occ_id,
|
||||
'retry')
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=409, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.retry_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_vnf_lcm_op_occ_internal_server_error(self):
|
||||
"""Test if request is internal server error"""
|
||||
|
||||
arg_list = [uuidsentinel.vnf_lcm_op_occ_id]
|
||||
verify_list = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.retry_vnf_lcm, arg_list, verify_list)
|
||||
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
uuidsentinel.vnf_lcm_op_occ_id,
|
||||
'retry')
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=500, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.retry_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_vnf_lcm_op_occ_missing_vnf_lcm_op_occ_id_argument(
|
||||
self):
|
||||
"""Test if vnflcm_op_occ_id is not provided"""
|
||||
|
||||
arg_list = []
|
||||
verify_list = [('vnf_lcm_op_occ_id', arg_list)]
|
||||
self.assertRaises(base.ParserException, self.check_parser,
|
||||
self.retry_vnf_lcm, arg_list, verify_list)
|
||||
|
||||
|
||||
class TestListVnfLcmOp(TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestListVnfLcmOp, self).setUp()
|
||||
self.list_vnflcm_op_occ = vnflcm_op_occs.ListVnfLcmOp(
|
||||
self.app, self.app_args, cmd_name='vnflcm op list')
|
||||
|
||||
def test_take_action(self):
|
||||
vnflcm_op_occs_obj = vnflcm_op_occs_fakes.create_vnflcm_op_occs(
|
||||
count=3)
|
||||
parsed_args = self.check_parser(self.list_vnflcm_op_occ, [], [])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', os.path.join(self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs'),
|
||||
json=vnflcm_op_occs_obj, headers=self.header)
|
||||
|
||||
actual_columns, data = self.list_vnflcm_op_occ.take_action(parsed_args)
|
||||
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
self.list_vnflcm_op_occ.get_attributes(), long_listing=True)
|
||||
|
||||
expected_data = []
|
||||
for vnflcm_op_occ_obj_idx in vnflcm_op_occs_obj:
|
||||
expected_data.append(vnflcm_op_occs_fakes.get_vnflcm_op_occ_data(
|
||||
vnflcm_op_occ_obj_idx, columns=columns))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnflcm_op_occs(action='list'),
|
||||
actual_columns)
|
||||
self.assertCountEqual(expected_data, list(data))
|
||||
|
||||
def test_take_action_with_filter(self):
|
||||
vnflcm_op_occs_obj = vnflcm_op_occs_fakes.create_vnflcm_op_occs(
|
||||
count=3)
|
||||
parsed_args = self.check_parser(
|
||||
self.list_vnflcm_op_occ,
|
||||
["--filter", '(eq,operationState,STARTING)'],
|
||||
[('filter', '(eq,operationState,STARTING)')])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs?'
|
||||
'filter=(eq,operationState,STARTING)'),
|
||||
json=vnflcm_op_occs_obj, headers=self.header)
|
||||
|
||||
actual_columns, data = self.list_vnflcm_op_occ.take_action(parsed_args)
|
||||
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
self.list_vnflcm_op_occ.get_attributes(), long_listing=True)
|
||||
|
||||
expected_data = []
|
||||
for vnflcm_op_occ_obj_idx in vnflcm_op_occs_obj:
|
||||
expected_data.append(vnflcm_op_occs_fakes.get_vnflcm_op_occ_data(
|
||||
vnflcm_op_occ_obj_idx, columns=columns))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnflcm_op_occs(action='list'),
|
||||
actual_columns)
|
||||
self.assertListItemsEqual(expected_data, list(data))
|
||||
|
||||
def test_take_action_with_incorrect_filter(self):
|
||||
|
||||
parsed_args = self.check_parser(
|
||||
self.list_vnflcm_op_occ,
|
||||
["--filter", '(operationState)'],
|
||||
[('filter', '(operationState)')])
|
||||
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs?filter=(operationState)')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=400, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.list_vnflcm_op_occ.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_internal_server_error(self):
|
||||
|
||||
parsed_args = self.check_parser(
|
||||
self.list_vnflcm_op_occ,
|
||||
["--filter", '(eq,operationState,STARTING)'],
|
||||
[('filter', '(eq,operationState,STARTING)')])
|
||||
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs?'
|
||||
'filter=(eq,operationState,STARTING)')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=500, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.list_vnflcm_op_occ.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_with_exclude_fields(self):
|
||||
|
||||
vnflcm_op_occs_obj = vnflcm_op_occs_fakes.create_vnflcm_op_occs(
|
||||
count=3)
|
||||
parsed_args = self.check_parser(
|
||||
self.list_vnflcm_op_occ,
|
||||
["--exclude-fields", 'VNF Instance ID,Operation State'],
|
||||
[('exclude_fields', 'VNF Instance ID,Operation State')])
|
||||
self.requests_mock.register_uri(
|
||||
'GET', os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs?'
|
||||
'exclude-fields=VNF Instance ID,Operation State'),
|
||||
json=vnflcm_op_occs_obj, headers=self.header)
|
||||
actual_columns, data = self.list_vnflcm_op_occ.take_action(parsed_args)
|
||||
headers, columns = tacker_osc_utils.get_column_definitions(
|
||||
self.list_vnflcm_op_occ.get_attributes(
|
||||
exclude=['VNF Instance ID', 'Operation State']),
|
||||
long_listing=True)
|
||||
expected_data = []
|
||||
for vnflcm_op_occ_obj_idx in vnflcm_op_occs_obj:
|
||||
expected_data.append(
|
||||
vnflcm_op_occs_fakes.get_vnflcm_op_occ_data(
|
||||
vnflcm_op_occ_obj_idx, columns=columns))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnflcm_op_occs(
|
||||
action='list', parameter="exclude_fields"),
|
||||
actual_columns)
|
||||
self.assertListItemsEqual(expected_data, list(data))
|
||||
|
||||
|
||||
class TestShowVnfLcmOp(TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestShowVnfLcmOp, self).setUp()
|
||||
self.show_vnf_lcm_op_occs = vnflcm_op_occs.ShowVnfLcmOp(
|
||||
self.app, self.app_args, cmd_name='vnflcm op show')
|
||||
|
||||
def test_take_action(self):
|
||||
"""Test of take_action()"""
|
||||
vnflcm_op_occ = vnflcm_op_occs_fakes.vnflcm_op_occ_response()
|
||||
|
||||
arglist = [vnflcm_op_occ['id']]
|
||||
verifylist = [('vnf_lcm_op_occ_id', vnflcm_op_occ['id'])]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_lcm_op_occs, arglist, verifylist)
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
vnflcm_op_occ['id'])
|
||||
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, json=vnflcm_op_occ)
|
||||
|
||||
columns, data = (self.show_vnf_lcm_op_occs.take_action(parsed_args))
|
||||
|
||||
self.assertCountEqual(_get_columns_vnflcm_op_occs(),
|
||||
columns)
|
||||
|
||||
def test_take_action_vnf_lcm_op_occ_id_not_found(self):
|
||||
"""Test if vnf-lcm-op-occ-id does not find."""
|
||||
arglist = [uuidsentinel.vnf_lcm_op_occ_id]
|
||||
verifylist = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_lcm_op_occs, arglist, verifylist)
|
||||
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
uuidsentinel.vnf_lcm_op_occ_id)
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, status_code=404, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.show_vnf_lcm_op_occs.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_internal_server_error(self):
|
||||
"""Test for internal server error."""
|
||||
arglist = [uuidsentinel.vnf_lcm_op_occ_id]
|
||||
verifylist = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.show_vnf_lcm_op_occs, arglist, verifylist)
|
||||
|
||||
url = os.path.join(
|
||||
self.url,
|
||||
'vnflcm/v1/vnf_lcm_op_occs',
|
||||
uuidsentinel.vnf_lcm_op_occ_id)
|
||||
self.requests_mock.register_uri(
|
||||
'GET', url, headers=self.header, status_code=500, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.show_vnf_lcm_op_occs.take_action,
|
||||
parsed_args)
|
||||
|
||||
@@ -41,9 +41,7 @@ def vnf_instance_response(attrs=None, instantiation_state='NOT_INSTANTIATED'):
|
||||
"vnfdVersion": "1.0",
|
||||
"_links": "vnflcm/v1/vnf_instances/" + uuidsentinel.vnf_instance_id +
|
||||
"/instantiate",
|
||||
"instantiationState": instantiation_state,
|
||||
"vnfConfigurableProperties": {
|
||||
"test": "test_value"}}
|
||||
"instantiationState": instantiation_state}
|
||||
if instantiation_state == 'INSTANTIATED':
|
||||
dummy_vnf_instance.update({
|
||||
"vimConnectionInfo": [{
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
# 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.
|
||||
|
||||
from oslo_utils.fixture import uuidsentinel
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from tackerclient.osc import utils as tacker_osc_utils
|
||||
|
||||
|
||||
def vnflcm_op_occ_response(attrs=None, action=''):
|
||||
"""Create a fake vnflcm op occurrence.
|
||||
|
||||
:param Dictionary attrs:
|
||||
A dictionary with all attributes
|
||||
:return:
|
||||
A vnf lcm op occs dict
|
||||
"""
|
||||
attrs = attrs or {}
|
||||
|
||||
# Set default attributes.
|
||||
dummy_vnf_lcm_op_occ = {
|
||||
"id": uuidsentinel.vnflcm_op_occ_id,
|
||||
"operationState": "STARTING",
|
||||
"stateEnteredTime": "2018-12-22T16:59:45.187Z",
|
||||
"startTime": "2018-12-22T16:59:45.187Z",
|
||||
"vnfInstanceId": "376f37f3-d4e9-4d41-8e6a-9b0ec98695cc",
|
||||
"grantId": "",
|
||||
"operation": "INSTANTIATE",
|
||||
"isAutomaticInvocation": "true",
|
||||
"operationParams": {
|
||||
"flavourId": "default",
|
||||
"instantiationLevelId": "n-mme-min"
|
||||
},
|
||||
"isCancelPending": "true",
|
||||
"cancelMode": "",
|
||||
"error": {
|
||||
"status": "500",
|
||||
"detail": "internal server error"
|
||||
},
|
||||
"resourceChanges": [],
|
||||
"changedInfo": [],
|
||||
"changedExtConnectivity": [],
|
||||
"_links": {
|
||||
"self": ""
|
||||
}
|
||||
}
|
||||
|
||||
if action == 'fail':
|
||||
fail_not_needed_columns = [
|
||||
'grantId', 'operationParams',
|
||||
'cancelMode', 'resourceChanges', 'changedInfo',
|
||||
'changedExtConnectivity']
|
||||
|
||||
for key in fail_not_needed_columns:
|
||||
del dummy_vnf_lcm_op_occ[key]
|
||||
|
||||
# Overwrite default attributes.
|
||||
dummy_vnf_lcm_op_occ.update(attrs)
|
||||
|
||||
return dummy_vnf_lcm_op_occ
|
||||
|
||||
|
||||
def get_vnflcm_op_occ_data(vnf_lcm_op_occ, columns=None):
|
||||
"""Get the vnflcm op occurrence.
|
||||
|
||||
:return:
|
||||
A tuple object sorted based on the name of the columns.
|
||||
"""
|
||||
complex_attributes = [
|
||||
'operationParams', 'error', 'resourceChanges',
|
||||
'changedInfo', 'changedExtConnectivity', 'links']
|
||||
|
||||
for attribute in complex_attributes:
|
||||
if vnf_lcm_op_occ.get(attribute):
|
||||
vnf_lcm_op_occ.update(
|
||||
{attribute: tacker_osc_utils.FormatComplexDataColumn(
|
||||
vnf_lcm_op_occ[attribute])})
|
||||
|
||||
# return the list of data as per column order
|
||||
if columns:
|
||||
return tuple([vnf_lcm_op_occ[key] for key in columns])
|
||||
|
||||
return tuple([vnf_lcm_op_occ[key] for key in sorted(
|
||||
vnf_lcm_op_occ.keys())])
|
||||
|
||||
|
||||
def create_vnflcm_op_occs(count=2):
|
||||
"""Create multiple fake vnflcm op occs.
|
||||
|
||||
:param count: The number of vnflcm op occs to fake
|
||||
:return:
|
||||
A list of fake vnflcm op occs dictionary
|
||||
"""
|
||||
vnflcm_op_occs = []
|
||||
for i in range(0, count):
|
||||
unique_id = uuidutils.generate_uuid()
|
||||
vnflcm_op_occs.append(vnflcm_op_occ_response(attrs={'id': unique_id}))
|
||||
return vnflcm_op_occs
|
||||
@@ -1,151 +0,0 @@
|
||||
# Copyright (C) 2021 Nippon Telegraph and Telephone Corporation
|
||||
# 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.
|
||||
|
||||
from io import StringIO
|
||||
import os
|
||||
import sys
|
||||
from unittest import mock
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.osc.v1.vnflcm import vnflcm
|
||||
from tackerclient.tests.unit.osc import base
|
||||
from tackerclient.tests.unit.osc.v1.fixture_data import client
|
||||
from tackerclient.tests.unit.osc.v1 import test_vnflcm
|
||||
from tackerclient.tests.unit.osc.v1 import vnflcm_fakes
|
||||
from tackerclient.v1_0 import client as proxy_client
|
||||
|
||||
|
||||
class TestVnfLcmV2(base.FixturedTestCase):
|
||||
client_fixture_class = client.ClientFixture
|
||||
api_version = '2'
|
||||
|
||||
def setUp(self):
|
||||
super(TestVnfLcmV2, self).setUp()
|
||||
|
||||
def test_client_v2(self):
|
||||
self.assertEqual(self.cs.vnf_lcm_client.headers,
|
||||
{'Version': '2.0.0'})
|
||||
self.assertEqual(self.cs.vnf_lcm_client.vnf_instances_path,
|
||||
'/vnflcm/v2/vnf_instances')
|
||||
# check of other paths is omitted.
|
||||
|
||||
|
||||
class TestChangeVnfPkgVnfLcm(test_vnflcm.TestVnfLcm):
|
||||
api_version = '2'
|
||||
|
||||
def setUp(self):
|
||||
super(TestChangeVnfPkgVnfLcm, self).setUp()
|
||||
self.change_vnfpkg_vnf_lcm = vnflcm.ChangeVnfPkgVnfLcm(
|
||||
self.app, self.app_args,
|
||||
cmd_name='vnflcm change-vnfpkg')
|
||||
|
||||
def test_take_action(self):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = ("./tackerclient/osc/v2/vnflcm/samples/"
|
||||
"change_vnfpkg_vnf_instance_param_sample.json")
|
||||
|
||||
arglist = [vnf_instance['id'], sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('request_file', sample_param_file)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.change_vnfpkg_vnf_lcm,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
url = os.path.join(self.url, 'vnflcm/v2/vnf_instances',
|
||||
vnf_instance['id'], 'change_vnfpkg')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, json={})
|
||||
|
||||
sys.stdout = buffer = StringIO()
|
||||
with mock.patch.object(proxy_client.ClientBase,
|
||||
'_handle_fault_response') as m:
|
||||
self.change_vnfpkg_vnf_lcm.take_action(parsed_args)
|
||||
# check no fault response is received
|
||||
self.assertNotCalled(m)
|
||||
self.assertEqual(
|
||||
('Change Current VNF Package for VNF Instance {0} '
|
||||
'has been accepted.'.format(vnf_instance['id'])),
|
||||
buffer.getvalue().strip())
|
||||
|
||||
def test_take_action_vnf_instance_not_found(self):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = ("./tackerclient/osc/v1/vnflcm/samples/"
|
||||
"change_vnfpkg_vnf_instance_param_sample.json")
|
||||
arglist = [vnf_instance['id'], sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('request_file', sample_param_file)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.change_vnfpkg_vnf_lcm,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
url = os.path.join(self.url, 'vnflcm/v2/vnf_instances',
|
||||
vnf_instance['id'], 'change_vnfpkg')
|
||||
self.requests_mock.register_uri(
|
||||
'POST', url, headers=self.header, status_code=404, json={})
|
||||
|
||||
self.assertRaises(exceptions.TackerClientException,
|
||||
self.change_vnfpkg_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_param_file_not_exists(self):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = "./not_exists.json"
|
||||
arglist = [vnf_instance['id'], sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('request_file', sample_param_file)]
|
||||
|
||||
# command param
|
||||
parsed_args = self.check_parser(
|
||||
self.change_vnfpkg_vnf_lcm,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
ex = self.assertRaises(
|
||||
exceptions.InvalidInput,
|
||||
self.change_vnfpkg_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
expected_msg = ("Invalid input: File %s does not exist "
|
||||
"or user does not have read privileges to it")
|
||||
self.assertEqual(expected_msg % sample_param_file, str(ex))
|
||||
|
||||
@mock.patch("os.open")
|
||||
@mock.patch("os.access")
|
||||
def test_take_action_invalid_format_param_file(self, mock_access,
|
||||
mock_open):
|
||||
vnf_instance = vnflcm_fakes.vnf_instance_response()
|
||||
sample_param_file = "./invalid_param_file.json"
|
||||
arglist = [vnf_instance['id'], sample_param_file]
|
||||
verifylist = [('vnf_instance', vnf_instance['id']),
|
||||
('request_file', sample_param_file)]
|
||||
|
||||
mock_open.return_value = "invalid_json_data"
|
||||
mock_access.return_value = True
|
||||
# command param
|
||||
parsed_args = self.check_parser(self.change_vnfpkg_vnf_lcm,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
ex = self.assertRaises(
|
||||
exceptions.InvalidInput,
|
||||
self.change_vnfpkg_vnf_lcm.take_action,
|
||||
parsed_args)
|
||||
|
||||
expected_msg = "Failed to load parameter file."
|
||||
self.assertIn(expected_msg, str(ex))
|
||||
@@ -14,14 +14,15 @@
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import contextlib
|
||||
import fixtures
|
||||
import io
|
||||
import sys
|
||||
import testtools
|
||||
from unittest import mock
|
||||
import urllib
|
||||
from urllib import parse as urlparse
|
||||
|
||||
import contextlib
|
||||
import fixtures
|
||||
import six
|
||||
import six.moves.urllib.parse as urlparse
|
||||
import sys
|
||||
import testtools
|
||||
|
||||
from tackerclient.common import constants
|
||||
from tackerclient.common import exceptions
|
||||
@@ -39,7 +40,7 @@ ENDURL = 'localurl'
|
||||
|
||||
@contextlib.contextmanager
|
||||
def capture_std_streams():
|
||||
fake_stdout, fake_stderr = io.StringIO(), io.StringIO()
|
||||
fake_stdout, fake_stderr = six.StringIO(), six.StringIO()
|
||||
stdout, stderr = sys.stdout, sys.stderr
|
||||
try:
|
||||
sys.stdout, sys.stderr = fake_stdout, fake_stderr
|
||||
@@ -316,7 +317,7 @@ class CLITestV10Base(testtools.TestCase):
|
||||
args.append("--tag")
|
||||
for tag in tags:
|
||||
args.append(tag)
|
||||
if isinstance(tag, str):
|
||||
if isinstance(tag, six.string_types):
|
||||
tag = urllib.quote(tag.encode('utf-8'))
|
||||
if query:
|
||||
query += "&tag=" + tag
|
||||
@@ -413,7 +414,7 @@ class CLITestV10Base(testtools.TestCase):
|
||||
args.append("--tag")
|
||||
for tag in tags:
|
||||
args.append(tag)
|
||||
if isinstance(tag, str):
|
||||
if isinstance(tag, six.string_types):
|
||||
tag = urllib.quote(tag.encode('utf-8'))
|
||||
if query:
|
||||
query += "&tag=" + tag
|
||||
@@ -653,8 +654,8 @@ class CLITestV10Base(testtools.TestCase):
|
||||
class ClientV1TestJson(CLITestV10Base):
|
||||
def test_do_request_unicode(self):
|
||||
self.client.format = self.format
|
||||
unicode_text = '\u7f51\u7edc'
|
||||
action = '/test'
|
||||
unicode_text = u'\u7f51\u7edc'
|
||||
action = u'/test'
|
||||
params = {'test': unicode_text}
|
||||
body = params
|
||||
expect_body = self.client.serialize(body)
|
||||
@@ -663,7 +664,7 @@ class ClientV1TestJson(CLITestV10Base):
|
||||
mock_req.return_value = (MyResp(200), expect_body)
|
||||
res_body = self.client.do_request('PUT', action, body=body,
|
||||
params=params)
|
||||
expected_uri = 'localurl/v1.0/test.json?test=%E7%BD%91%E7%BB%9C'
|
||||
expected_uri = u'localurl/v1.0/test.json?test=%E7%BD%91%E7%BB%9C'
|
||||
mock_req.assert_called_with(
|
||||
expected_uri, 'PUT', body=expect_body,
|
||||
headers={'X-Auth-Token': unicode_text,
|
||||
@@ -798,27 +799,3 @@ class CLITestV10ExceptionHandler(CLITestV10Base):
|
||||
exceptions.TackerClientException, 500,
|
||||
expected_msg=expected_msg,
|
||||
error_content=error_content)
|
||||
|
||||
def test_exception_handler_v10_tacker_etsi_error(self):
|
||||
"""Test ETSI error response"""
|
||||
|
||||
known_error_map = [
|
||||
({
|
||||
"status": "status 1",
|
||||
"detail": "sample 1"
|
||||
}, 400),
|
||||
({
|
||||
"status": "status 2",
|
||||
"detail": "sample 2"
|
||||
}, 404),
|
||||
({
|
||||
"status": "status 3",
|
||||
"detail": "sample 3"
|
||||
}, 409)
|
||||
]
|
||||
|
||||
for error_content, status_code in known_error_map:
|
||||
self._test_exception_handler_v10(
|
||||
exceptions.TackerClientException, status_code,
|
||||
expected_msg=error_content['detail'],
|
||||
error_content=error_content)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import logging
|
||||
|
||||
import testtools
|
||||
from testtools import helpers
|
||||
|
||||
from tackerclient.tacker import v1_0 as tackerV10
|
||||
|
||||
@@ -26,7 +27,7 @@ class TestCommandMeta(testtools.TestCase):
|
||||
class FakeCommand(tackerV10.TackerCommand):
|
||||
pass
|
||||
|
||||
self.assertTrue(hasattr(FakeCommand, 'log'))
|
||||
self.assertTrue(helpers.safe_hasattr(FakeCommand, 'log'))
|
||||
self.assertIsInstance(FakeCommand.log, logging.getLoggerClass())
|
||||
self.assertEqual(FakeCommand.log.name, __name__ + ".FakeCommand")
|
||||
|
||||
@@ -34,5 +35,5 @@ class TestCommandMeta(testtools.TestCase):
|
||||
class FakeCommand(tackerV10.TackerCommand):
|
||||
log = None
|
||||
|
||||
self.assertTrue(hasattr(FakeCommand, 'log'))
|
||||
self.assertTrue(helpers.safe_hasattr(FakeCommand, 'log'))
|
||||
self.assertIsNone(FakeCommand.log)
|
||||
|
||||
@@ -14,17 +14,18 @@
|
||||
# under the License.
|
||||
|
||||
import argparse
|
||||
import fixtures
|
||||
import io
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import testtools
|
||||
from testtools import matchers
|
||||
from unittest import mock
|
||||
|
||||
import six
|
||||
import sys
|
||||
|
||||
import fixtures
|
||||
from keystoneclient import session
|
||||
import testtools
|
||||
from testtools import matchers
|
||||
|
||||
from tackerclient.common import clientmanager
|
||||
from tackerclient import shell as openstack_shell
|
||||
@@ -62,8 +63,8 @@ class ShellTest(testtools.TestCase):
|
||||
clean_env = {}
|
||||
_old_env, os.environ = os.environ, clean_env.copy()
|
||||
try:
|
||||
sys.stdout = io.StringIO()
|
||||
sys.stderr = io.StringIO()
|
||||
sys.stdout = six.StringIO()
|
||||
sys.stderr = six.StringIO()
|
||||
_shell = openstack_shell.TackerShell(DEFAULT_API_VERSION)
|
||||
_shell.run(argstr.split())
|
||||
except SystemExit:
|
||||
@@ -154,10 +155,10 @@ class ShellTest(testtools.TestCase):
|
||||
@mock.patch.object(openstack_shell.TackerShell, 'run')
|
||||
def test_main_with_unicode(self, mock_run):
|
||||
mock_run.return_value = 0
|
||||
unicode_text = '\u7f51\u7edc'
|
||||
unicode_text = u'\u7f51\u7edc'
|
||||
argv = ['net-list', unicode_text, unicode_text.encode('utf-8')]
|
||||
ret = openstack_shell.main(argv=argv)
|
||||
mock_run.assert_called_once_with(['net-list', unicode_text,
|
||||
mock_run.assert_called_once_with([u'net-list', unicode_text,
|
||||
unicode_text])
|
||||
self.assertEqual(0, ret)
|
||||
|
||||
|
||||
@@ -113,14 +113,8 @@ class CLITestV10VmVNFFGJSON(test_cli10.CLITestV10Base):
|
||||
args, extra_fields,
|
||||
get_client_called_count=2)
|
||||
|
||||
def test_delete_vnffg_without_force(self):
|
||||
def test_delete_vnffg(self):
|
||||
cmd = vnffg.DeleteVNFFG(test_cli10.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(self._RESOURCE, cmd, my_id, args)
|
||||
|
||||
def test_delete_vnffg_with_force(self):
|
||||
cmd = vnffg.DeleteVNFFG(test_cli10.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id, '--force']
|
||||
self._test_delete_resource(self._RESOURCE, cmd, my_id, args)
|
||||
|
||||
@@ -19,7 +19,7 @@ import logging
|
||||
import time
|
||||
|
||||
import requests
|
||||
from urllib import parse as urlparse
|
||||
import six.moves.urllib.parse as urlparse
|
||||
|
||||
from tackerclient import client
|
||||
from tackerclient.common import constants
|
||||
@@ -54,7 +54,6 @@ def exception_handler_v10(status_code, error_content):
|
||||
:param status_code: HTTP error status code
|
||||
:param error_content: deserialized body of error response
|
||||
"""
|
||||
etsi_error_content = error_content
|
||||
error_dict = None
|
||||
if isinstance(error_content, dict):
|
||||
error_dict = error_content.get('TackerError')
|
||||
@@ -95,13 +94,6 @@ def exception_handler_v10(status_code, error_content):
|
||||
if message:
|
||||
raise exceptions.TackerClientException(status_code=status_code,
|
||||
message=message)
|
||||
# ETSI error response
|
||||
if isinstance(etsi_error_content, dict):
|
||||
if etsi_error_content.get('status') and \
|
||||
etsi_error_content.get('detail'):
|
||||
message = etsi_error_content.get('detail')
|
||||
raise exceptions.TackerClientException(status_code=status_code,
|
||||
message=message)
|
||||
|
||||
# If we end up here the exception was not a tacker error
|
||||
msg = "%s-%s" % (status_code, error_content)
|
||||
@@ -229,12 +221,8 @@ class ClientBase(object):
|
||||
if body or body == {}:
|
||||
body = self.serialize(body)
|
||||
|
||||
if headers is None:
|
||||
# self.httpclient.do_request is not accept 'headers=None'.
|
||||
headers = {}
|
||||
|
||||
resp, replybody = self.httpclient.do_request(
|
||||
action, method, body=body, headers=headers,
|
||||
action, method, body=body,
|
||||
content_type=self.content_type())
|
||||
|
||||
if 'application/zip' == resp.headers.get('Content-Type'):
|
||||
@@ -359,27 +347,26 @@ class ClientBase(object):
|
||||
return self.retry_request("PATCH", action, body=body,
|
||||
headers=headers, params=params)
|
||||
|
||||
def list(self, collection, path, retrieve_all=True, headers=None,
|
||||
**params):
|
||||
def list(self, collection, path, retrieve_all=True, **params):
|
||||
if retrieve_all:
|
||||
res = []
|
||||
for r in self._pagination(collection, path, headers, **params):
|
||||
for r in self._pagination(collection, path, **params):
|
||||
if type(r) is list:
|
||||
res.extend(r)
|
||||
else:
|
||||
res.extend(r[collection])
|
||||
return {collection: res} if collection else res
|
||||
else:
|
||||
return self._pagination(collection, path, headers, **params)
|
||||
return self._pagination(collection, path, **params)
|
||||
|
||||
def _pagination(self, collection, path, headers, **params):
|
||||
def _pagination(self, collection, path, **params):
|
||||
if params.get('page_reverse', False):
|
||||
linkrel = 'previous'
|
||||
else:
|
||||
linkrel = 'next'
|
||||
next = True
|
||||
while next:
|
||||
res = self.get(path, headers=headers, params=params)
|
||||
res = self.get(path, params=params)
|
||||
yield res
|
||||
next = False
|
||||
try:
|
||||
@@ -631,8 +618,8 @@ class LegacyClient(ClientBase):
|
||||
return self.post(self.vnffgs_path, body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def delete_vnffg(self, vnffg, body=None):
|
||||
return self.delete(self.vnffg_path % vnffg, body=body)
|
||||
def delete_vnffg(self, vnffg):
|
||||
return self.delete(self.vnffg_path % vnffg)
|
||||
|
||||
@APIParamsCall
|
||||
def update_vnffg(self, vnffg, body):
|
||||
@@ -879,130 +866,58 @@ class VnfLCMClient(ClientBase):
|
||||
APIs.
|
||||
"""
|
||||
|
||||
def __init__(self, api_version, **kwargs):
|
||||
super(VnfLCMClient, self).__init__(**kwargs)
|
||||
self.headers = {'Version': '1.3.0'}
|
||||
sol_api_version = 'v1'
|
||||
if api_version == '2':
|
||||
self.headers = {'Version': '2.0.0'}
|
||||
sol_api_version = 'v2'
|
||||
|
||||
self.vnf_instances_path = (
|
||||
'/vnflcm/{}/vnf_instances'.format(sol_api_version))
|
||||
self.vnf_instance_path = (
|
||||
'/vnflcm/{}/vnf_instances/%s'.format(sol_api_version))
|
||||
self.vnf_lcm_op_occurrences_path = (
|
||||
'/vnflcm/{}/vnf_lcm_op_occs'.format(sol_api_version))
|
||||
self.vnf_lcm_op_occs_path = (
|
||||
'/vnflcm/{}/vnf_lcm_op_occs/%s'.format(sol_api_version))
|
||||
vnf_instances_path = '/vnflcm/v1/vnf_instances'
|
||||
vnf_instance_path = '/vnflcm/v1/vnf_instances/%s'
|
||||
vnf_lcm_op_occs_path = '/vnflcm/v1/vnf_lcm_op_occs/%s'
|
||||
|
||||
def build_action(self, action):
|
||||
return action
|
||||
|
||||
@APIParamsCall
|
||||
def create_vnf_instance(self, body):
|
||||
return self.post(self.vnf_instances_path, body=body,
|
||||
headers=self.headers)
|
||||
return self.post(self.vnf_instances_path, body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def show_vnf_instance(self, vnf_id, **_params):
|
||||
return self.get(self.vnf_instance_path % vnf_id,
|
||||
headers=self.headers, params=_params)
|
||||
return self.get(self.vnf_instance_path % vnf_id, params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def list_vnf_instances(self, retrieve_all=True, **_params):
|
||||
vnf_instances = self.list(None, self.vnf_instances_path,
|
||||
retrieve_all, headers=self.headers,
|
||||
**_params)
|
||||
retrieve_all, **_params)
|
||||
return vnf_instances
|
||||
|
||||
@APIParamsCall
|
||||
def instantiate_vnf_instance(self, vnf_id, body):
|
||||
return self.post((self.vnf_instance_path + "/instantiate") % vnf_id,
|
||||
body=body, headers=self.headers)
|
||||
body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def heal_vnf_instance(self, vnf_id, body):
|
||||
return self.post((self.vnf_instance_path + "/heal") % vnf_id,
|
||||
body=body, headers=self.headers)
|
||||
body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def terminate_vnf_instance(self, vnf_id, body):
|
||||
return self.post((self.vnf_instance_path + "/terminate") % vnf_id,
|
||||
body=body, headers=self.headers)
|
||||
body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def delete_vnf_instance(self, vnf_id):
|
||||
return self.delete(self.vnf_instance_path % vnf_id,
|
||||
headers=self.headers)
|
||||
return self.delete(self.vnf_instance_path % vnf_id)
|
||||
|
||||
@APIParamsCall
|
||||
def update_vnf_instance(self, vnf_id, body):
|
||||
return self.patch(self.vnf_instance_path % vnf_id, body=body,
|
||||
headers=self.headers)
|
||||
return self.patch(self.vnf_instance_path % vnf_id, body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def scale_vnf_instance(self, vnf_id, body):
|
||||
return self.post((self.vnf_instance_path + "/scale") % vnf_id,
|
||||
body=body, headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def rollback_vnf_instance(self, occ_id):
|
||||
return self.post((self.vnf_lcm_op_occs_path + "/rollback") % occ_id,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def cancel_vnf_instance(self, occ_id, body):
|
||||
return self.post((self.vnf_lcm_op_occs_path + "/cancel") % occ_id,
|
||||
body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def fail_vnf_instance(self, occ_id):
|
||||
return self.post((self.vnf_lcm_op_occs_path + "/fail") % occ_id,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def change_ext_conn_vnf_instance(self, vnf_id, body):
|
||||
return self.post((self.vnf_instance_path + "/change_ext_conn") %
|
||||
vnf_id, body=body, headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def change_vnfpkg_vnf_instance(self, vnf_id, body):
|
||||
# NOTE: it is only supported by V2-API.
|
||||
if self.vnf_instance_path.split('/')[2] == 'v2':
|
||||
return self.post((self.vnf_instance_path + "/change_vnfpkg") %
|
||||
vnf_id, body=body, headers=self.headers)
|
||||
else:
|
||||
raise exceptions.UnsupportedCommandVersion(version='1')
|
||||
|
||||
@APIParamsCall
|
||||
def retry_vnf_instance(self, occ_id):
|
||||
return self.post((self.vnf_lcm_op_occs_path + "/retry") % occ_id,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def list_vnf_lcm_op_occs(self, retrieve_all=True, **_params):
|
||||
vnf_lcm_op_occs = self.list(None, self.vnf_lcm_op_occurrences_path,
|
||||
retrieve_all, headers=self.headers,
|
||||
**_params)
|
||||
return vnf_lcm_op_occs
|
||||
|
||||
@APIParamsCall
|
||||
def show_vnf_lcm_op_occs(self, occ_id):
|
||||
return self.get(self.vnf_lcm_op_occs_path % occ_id,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def show_vnf_lcm_versions(self, major_version):
|
||||
if major_version is None:
|
||||
path = "/vnflcm/api_versions"
|
||||
else:
|
||||
path = "/vnflcm/{}/api_versions".format(major_version)
|
||||
# NOTE: This may be called with any combination of
|
||||
# --os-tacker-api-verson:[1, 2] and major_version:[None, 1, 2].
|
||||
# Specifying "headers={'Version': '2.0.0'}" is most simple to
|
||||
# make all cases OK.
|
||||
return self.get(path, headers={'Version': '2.0.0'})
|
||||
def rollback_vnf_instance(self, occ_id):
|
||||
return self.post((self.vnf_lcm_op_occs_path + "/rollback") % occ_id)
|
||||
|
||||
|
||||
class Client(object):
|
||||
@@ -1025,8 +940,7 @@ class Client(object):
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
api_version = kwargs.pop('api_version', '1')
|
||||
self.vnf_lcm_client = VnfLCMClient(api_version, **kwargs)
|
||||
self.vnf_lcm_client = VnfLCMClient(**kwargs)
|
||||
self.vnf_package_client = VnfPackageClient(**kwargs)
|
||||
self.legacy_client = LegacyClient(**kwargs)
|
||||
|
||||
@@ -1278,12 +1192,6 @@ class Client(object):
|
||||
def scale_vnf_instance(self, vnf_id, body):
|
||||
return self.vnf_lcm_client.scale_vnf_instance(vnf_id, body)
|
||||
|
||||
def change_ext_conn_vnf_instance(self, vnf_id, body):
|
||||
return self.vnf_lcm_client.change_ext_conn_vnf_instance(vnf_id, body)
|
||||
|
||||
def change_vnfpkg_vnf_instance(self, vnf_id, body):
|
||||
return self.vnf_lcm_client.change_vnfpkg_vnf_instance(vnf_id, body)
|
||||
|
||||
def delete_vnf_instance(self, vnf_id):
|
||||
return self.vnf_lcm_client.delete_vnf_instance(vnf_id)
|
||||
|
||||
@@ -1293,15 +1201,6 @@ class Client(object):
|
||||
def rollback_vnf_instance(self, occ_id):
|
||||
return self.vnf_lcm_client.rollback_vnf_instance(occ_id)
|
||||
|
||||
def cancel_vnf_instance(self, occ_id, body):
|
||||
return self.vnf_lcm_client.cancel_vnf_instance(occ_id, body)
|
||||
|
||||
def fail_vnf_instance(self, occ_id):
|
||||
return self.vnf_lcm_client.fail_vnf_instance(occ_id)
|
||||
|
||||
def retry_vnf_instance(self, occ_id):
|
||||
return self.vnf_lcm_client.retry_vnf_instance(occ_id)
|
||||
|
||||
def update_vnf_package(self, vnf_package, body):
|
||||
return self.vnf_package_client.update_vnf_package(vnf_package, body)
|
||||
|
||||
@@ -1316,13 +1215,3 @@ class Client(object):
|
||||
|
||||
def download_vnf_package(self, vnf_package):
|
||||
return self.vnf_package_client.download_vnf_package(vnf_package)
|
||||
|
||||
def list_vnf_lcm_op_occs(self, retrieve_all=True, **_params):
|
||||
return self.vnf_lcm_client.list_vnf_lcm_op_occs(
|
||||
retrieve_all=retrieve_all, **_params)
|
||||
|
||||
def show_vnf_lcm_op_occs(self, occ_id):
|
||||
return self.vnf_lcm_client.show_vnf_lcm_op_occs(occ_id)
|
||||
|
||||
def show_vnf_lcm_versions(self, major_version):
|
||||
return self.vnf_lcm_client.show_vnf_lcm_versions(major_version)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# process, which may cause wedges in the gate later.
|
||||
|
||||
hacking>=4.0.0,<4.1.0 # Apache-2.0
|
||||
hacking>=3.0.1,<3.1.0 # Apache-2.0
|
||||
coverage!=4.4,>=4.0 # Apache-2.0
|
||||
ddt>=1.0.1 # MIT
|
||||
fixtures>=3.0.0 # Apache-2.0/BSD
|
||||
|
||||
9
tox.ini
9
tox.ini
@@ -1,6 +1,6 @@
|
||||
[tox]
|
||||
envlist = py39,py38,py36,pep8,docs
|
||||
minversion = 3.18.0
|
||||
envlist = py37,py36,pep8,docs
|
||||
minversion = 3.1.1
|
||||
skipsdist = True
|
||||
ignore_basepython_conflict = True
|
||||
|
||||
@@ -11,8 +11,9 @@ setenv = VIRTUAL_ENV={envdir}
|
||||
LANGUAGE=en_US:en
|
||||
LC_ALL=C
|
||||
usedevelop = True
|
||||
install_command = pip install {opts} {packages}
|
||||
deps =
|
||||
-c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/yoga}
|
||||
-c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/victoria}
|
||||
-r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
commands = stestr run --slowest {posargs}
|
||||
@@ -30,7 +31,7 @@ commands = sphinx-build -W -b html doc/source doc/build/html
|
||||
|
||||
[testenv:releasenotes]
|
||||
deps =
|
||||
-c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/yoga}
|
||||
-c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/victoria}
|
||||
-r{toxinidir}/doc/requirements.txt
|
||||
commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
|
||||
|
||||
|
||||
Reference in New Issue
Block a user