Compare commits

..

3 Commits

Author SHA1 Message Date
Yasufumi Ogawa
774923c5bb Drop test for lower constraints
As we agreed, drop lower constraints test from stable branches to avoid
difficulty of maintaining package depencencies for the recent pip
dependency resolver.

Signed-off-by: Yasufumi Ogawa <yasufum.o@gmail.com>
Change-Id: Ib2f5d298e7cae60361f21a0eb111b6eb8b7bddfa
2021-09-22 16:35:33 +09:00
770e1fac13 Update TOX_CONSTRAINTS_FILE for stable/victoria
Update the URL to the upper-constraints file to point to the redirect
rule on releases.openstack.org so that anyone working on this branch
will switch to the correct upper-constraints list automatically when
the requirements repository branches.

Until the requirements repository has as stable/victoria branch, tests will
continue to use the upper-constraints list on master.

Change-Id: I22fdd8156e50c38afb8da15445785ac86f196f89
2020-09-16 22:01:00 +00:00
b5aca28e12 Update .gitreview for stable/victoria
Change-Id: I1a55ac9127c386fbba6db3b0bd375f86548eeddd
2020-09-16 22:00:58 +00:00
53 changed files with 180 additions and 2006 deletions

View File

@@ -2,4 +2,4 @@
host=review.opendev.org
port=29418
project=openstack/python-tackerclient.git
defaultbranch=unmaintained/yoga
defaultbranch=stable/victoria

View File

@@ -1,6 +1,6 @@
- project:
templates:
- check-requirements
- openstack-python3-yoga-jobs
- openstack-python3-victoria-jobs
- publish-openstack-docs-pti
- release-notes-jobs-python3

View File

@@ -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 -------------------------------------------

View File

@@ -52,4 +52,5 @@ Indices and Tables
------------------
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@@ -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

View File

@@ -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'),
]

View File

@@ -7,9 +7,6 @@ Contents:
:maxdepth: 2
unreleased
xena
wallaby
victoria
ussuri
train
stein

View File

@@ -1,6 +0,0 @@
=============================
Victoria Series Release Notes
=============================
.. release-notes::
:branch: stable/victoria

View File

@@ -1,6 +0,0 @@
============================
Wallaby Series Release Notes
============================
.. release-notes::
:branch: stable/wallaby

View File

@@ -1,6 +0,0 @@
=========================
Xena Series Release Notes
=========================
.. release-notes::
:branch: stable/xena

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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):

View File

@@ -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:

View File

@@ -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

View File

@@ -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()))

View File

@@ -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)

View File

@@ -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)

View File

@@ -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]

View File

@@ -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

View File

@@ -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)

View File

@@ -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"
}
}
]
}

View File

@@ -1,3 +0,0 @@
{
"additionalParams": {"all": true}
}

View File

@@ -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}))

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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"
}
}]
}
}

View File

@@ -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

View File

@@ -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 = []

View File

@@ -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]

View File

@@ -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

View File

@@ -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

View File

@@ -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):

View File

@@ -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()))

View File

@@ -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)

View File

@@ -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.

View File

@@ -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)

View File

@@ -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": [{

View File

@@ -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

View File

@@ -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))

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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