OSC support for VNF package APIs
Added support vnf package create command and their unit test cases. Please see the results here: http://paste.openstack.org/show/775422/ Change-Id: Idf59847aaf33e360dae696eae819d217ae63570f Implements: bp tosca-csar-mgmt-driver
This commit is contained in:
parent
0edfda9171
commit
9940682bc8
@ -3,6 +3,7 @@ Babel==2.3.4
|
|||||||
cliff==2.8.0
|
cliff==2.8.0
|
||||||
cmd2==0.8.0
|
cmd2==0.8.0
|
||||||
coverage==4.0
|
coverage==4.0
|
||||||
|
ddt==1.0.1
|
||||||
debtcollector==1.2.0
|
debtcollector==1.2.0
|
||||||
decorator==3.4.0
|
decorator==3.4.0
|
||||||
deprecation==1.0
|
deprecation==1.0
|
||||||
@ -49,6 +50,7 @@ python-subunit==1.0.0
|
|||||||
pytz==2013.6
|
pytz==2013.6
|
||||||
PyYAML==3.12
|
PyYAML==3.12
|
||||||
requests==2.14.2
|
requests==2.14.2
|
||||||
|
requests-mock==1.2.0
|
||||||
requestsexceptions==1.2.0
|
requestsexceptions==1.2.0
|
||||||
rfc3986==0.3.1
|
rfc3986==0.3.1
|
||||||
simplejson==3.5.1
|
simplejson==3.5.1
|
||||||
|
@ -80,6 +80,7 @@ openstack.tackerclient.v1 =
|
|||||||
vnf_classifier_show = tackerclient.osc.v1.nfvo.vnffg:ShowFC
|
vnf_classifier_show = tackerclient.osc.v1.nfvo.vnffg:ShowFC
|
||||||
vnf_chain_list = tackerclient.osc.v1.nfvo.vnffg:ListSFC
|
vnf_chain_list = tackerclient.osc.v1.nfvo.vnffg:ListSFC
|
||||||
vnf_chain_show = tackerclient.osc.v1.nfvo.vnffg:ShowSFC
|
vnf_chain_show = tackerclient.osc.v1.nfvo.vnffg:ShowSFC
|
||||||
|
vnf_package_create = tackerclient.osc.v1.vnfpkgm.vnf_package:CreateVnfPackage
|
||||||
|
|
||||||
|
|
||||||
[build_releasenotes]
|
[build_releasenotes]
|
||||||
|
0
tackerclient/osc/v1/vnfpkgm/__init__.py
Normal file
0
tackerclient/osc/v1/vnfpkgm/__init__.py
Normal file
71
tackerclient/osc/v1/vnfpkgm/vnf_package.py
Normal file
71
tackerclient/osc/v1/vnfpkgm/vnf_package.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# Copyright (C) 2019 NTT DATA
|
||||||
|
# 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 logging
|
||||||
|
|
||||||
|
from osc_lib.cli import parseractions
|
||||||
|
from osc_lib.command import command
|
||||||
|
from osc_lib import utils
|
||||||
|
|
||||||
|
from tackerclient.i18n import _
|
||||||
|
from tackerclient.osc import sdk_utils
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
_mixed_case_fields = ('onboardingState', 'operationalState',
|
||||||
|
'usageState', 'userDefinedData')
|
||||||
|
|
||||||
|
|
||||||
|
def _get_columns(item):
|
||||||
|
column_map = {
|
||||||
|
'_links': 'Links',
|
||||||
|
'onboardingState': 'Onboarding State',
|
||||||
|
'operationalState': 'Operational State',
|
||||||
|
'usageState': 'Usage State',
|
||||||
|
'userDefinedData': 'User Defined Data',
|
||||||
|
'id': 'ID'
|
||||||
|
}
|
||||||
|
return sdk_utils.get_osc_show_columns_for_sdk_resource(item, column_map)
|
||||||
|
|
||||||
|
|
||||||
|
class CreateVnfPackage(command.ShowOne):
|
||||||
|
_description = _("Create a new VNF Package")
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
LOG.debug('get_parser(%s)', prog_name)
|
||||||
|
parser = super(CreateVnfPackage, self).get_parser(prog_name)
|
||||||
|
parser.add_argument(
|
||||||
|
'--user-data',
|
||||||
|
metavar='<key=value>',
|
||||||
|
action=parseractions.KeyValueAction,
|
||||||
|
help=_('User defined data for the VNF package '
|
||||||
|
'(repeat option to set multiple user defined data)'),
|
||||||
|
)
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def args2body(self, parsed_args):
|
||||||
|
body = {}
|
||||||
|
if parsed_args.user_data:
|
||||||
|
body["userDefinedData"] = parsed_args.user_data
|
||||||
|
return body
|
||||||
|
|
||||||
|
def take_action(self, parsed_args):
|
||||||
|
client = self.app.client_manager.tackerclient
|
||||||
|
vnf_package = client.create_vnf_package(self.args2body(parsed_args))
|
||||||
|
display_columns, columns = _get_columns(vnf_package)
|
||||||
|
data = utils.get_item_properties(
|
||||||
|
sdk_utils.DictModel(vnf_package),
|
||||||
|
columns, mixed_case_fields=_mixed_case_fields)
|
||||||
|
return (display_columns, data)
|
0
tackerclient/tests/unit/osc/__init__.py
Normal file
0
tackerclient/tests/unit/osc/__init__.py
Normal file
48
tackerclient/tests/unit/osc/base.py
Normal file
48
tackerclient/tests/unit/osc/base.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# Copyright (C) 2019 NTT DATA
|
||||||
|
# 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 mock
|
||||||
|
from requests_mock.contrib import fixture as requests_mock_fixture
|
||||||
|
import testtools
|
||||||
|
|
||||||
|
|
||||||
|
class FixturedTestCase(testtools.TestCase):
|
||||||
|
client_fixture_class = None
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(FixturedTestCase, self).setUp()
|
||||||
|
self.app = mock.MagicMock()
|
||||||
|
if self.client_fixture_class:
|
||||||
|
self.requests_mock = self.useFixture(requests_mock_fixture.
|
||||||
|
Fixture())
|
||||||
|
fix = self.client_fixture_class(self.requests_mock)
|
||||||
|
self.cs = self.useFixture(fix).client
|
||||||
|
|
||||||
|
def check_parser(self, cmd, args, verify_args):
|
||||||
|
cmd_parser = cmd.get_parser('check_parser')
|
||||||
|
try:
|
||||||
|
parsed_args = cmd_parser.parse_args(args)
|
||||||
|
except SystemExit:
|
||||||
|
raise ParserException
|
||||||
|
for av in verify_args:
|
||||||
|
attr, value = av
|
||||||
|
if attr:
|
||||||
|
self.assertIn(attr, parsed_args)
|
||||||
|
self.assertEqual(getattr(parsed_args, attr), value)
|
||||||
|
return parsed_args
|
||||||
|
|
||||||
|
|
||||||
|
class ParserException(Exception):
|
||||||
|
pass
|
0
tackerclient/tests/unit/osc/v1/__init__.py
Normal file
0
tackerclient/tests/unit/osc/v1/__init__.py
Normal file
60
tackerclient/tests/unit/osc/v1/fixture_data/client.py
Normal file
60
tackerclient/tests/unit/osc/v1/fixture_data/client.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# Copyright 2019 NTT DATA
|
||||||
|
#
|
||||||
|
# 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 fixtures
|
||||||
|
from keystoneauth1 import fixture
|
||||||
|
from keystoneauth1 import loading
|
||||||
|
from keystoneauth1 import session
|
||||||
|
|
||||||
|
from tackerclient.v1_0 import client as proxy_client
|
||||||
|
|
||||||
|
IDENTITY_URL = 'http://identityserver:5000/v3'
|
||||||
|
TACKER_URL = 'http://nfv-orchestration'
|
||||||
|
|
||||||
|
|
||||||
|
class ClientFixture(fixtures.Fixture):
|
||||||
|
|
||||||
|
def __init__(self, requests_mock, identity_url=IDENTITY_URL):
|
||||||
|
super(ClientFixture, self).__init__()
|
||||||
|
self.identity_url = identity_url
|
||||||
|
self.client = None
|
||||||
|
self.token = fixture.V2Token()
|
||||||
|
self.token.set_scope()
|
||||||
|
self.requests_mock = requests_mock
|
||||||
|
self.discovery = fixture.V2Discovery(href=self.identity_url)
|
||||||
|
s = self.token.add_service('nfv-orchestration')
|
||||||
|
s.add_endpoint(TACKER_URL)
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(ClientFixture, self).setUp()
|
||||||
|
auth_url = '%s/tokens' % self.identity_url
|
||||||
|
headers = {'X-Content-Type': 'application/json'}
|
||||||
|
self.requests_mock.post(auth_url, json=self.token, headers=headers)
|
||||||
|
self.requests_mock.get(self.identity_url, json=self.discovery,
|
||||||
|
headers=headers)
|
||||||
|
self.client = self.new_client()
|
||||||
|
|
||||||
|
def new_client(self):
|
||||||
|
self.session = session.Session()
|
||||||
|
loader = loading.get_plugin_loader('password')
|
||||||
|
self.session.auth = loader.load_from_options(
|
||||||
|
auth_url=self.identity_url, username='xx', password='xx')
|
||||||
|
|
||||||
|
return proxy_client.Client(service_type='nfv-orchestration',
|
||||||
|
interface='public',
|
||||||
|
endpoint_type='public',
|
||||||
|
region_name='RegionOne',
|
||||||
|
auth_url=self.identity_url,
|
||||||
|
token=self.token.token_id,
|
||||||
|
endpoint_url=TACKER_URL)
|
70
tackerclient/tests/unit/osc/v1/test_vnf_package.py
Normal file
70
tackerclient/tests/unit/osc/v1/test_vnf_package.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
# Copyright (C) 2019 NTT DATA
|
||||||
|
# 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 ddt
|
||||||
|
import mock
|
||||||
|
|
||||||
|
from tackerclient.osc.v1.vnfpkgm import vnf_package
|
||||||
|
from tackerclient.tests.unit.osc import base
|
||||||
|
from tackerclient.tests.unit.osc.v1.fixture_data import client
|
||||||
|
from tackerclient.tests.unit.osc.v1 import vnf_package_fakes
|
||||||
|
|
||||||
|
|
||||||
|
class TestVnfPackage(base.FixturedTestCase):
|
||||||
|
client_fixture_class = client.ClientFixture
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestVnfPackage, self).setUp()
|
||||||
|
self.url = client.TACKER_URL
|
||||||
|
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 TestCreateVnfPackage(TestVnfPackage):
|
||||||
|
|
||||||
|
columns = ('ID', 'Links', 'Onboarding State', 'Operational State',
|
||||||
|
'Usage State', 'User Defined Data')
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestCreateVnfPackage, self).setUp()
|
||||||
|
self.create_vnf_package = vnf_package.CreateVnfPackage(
|
||||||
|
self.app, self.app_args, cmd_name='vnf package create')
|
||||||
|
|
||||||
|
@ddt.data((["--user-data", 'Test_key=Test_value'],
|
||||||
|
[('user_data', {'Test_key': 'Test_value'})]),
|
||||||
|
([], []))
|
||||||
|
@ddt.unpack
|
||||||
|
def test_take_action(self, arglist, verifylist):
|
||||||
|
# command param
|
||||||
|
parsed_args = self.check_parser(self.create_vnf_package, arglist,
|
||||||
|
verifylist)
|
||||||
|
header = {'content-type': 'application/json'}
|
||||||
|
|
||||||
|
if arglist:
|
||||||
|
json = vnf_package_fakes.vnf_package_obj(
|
||||||
|
attrs={'userDefinedData': {'Test_key': 'Test_value'}})
|
||||||
|
else:
|
||||||
|
json = vnf_package_fakes.vnf_package_obj()
|
||||||
|
self.requests_mock.register_uri(
|
||||||
|
'POST', self.url + '/vnfpkgm/v1/vnf_packages',
|
||||||
|
json=json, headers=header)
|
||||||
|
|
||||||
|
columns, data = (self.create_vnf_package.take_action(parsed_args))
|
||||||
|
self.assertEqual(self.columns, columns)
|
||||||
|
self.assertItemsEqual(vnf_package_fakes.get_vnf_package_data(json),
|
||||||
|
data)
|
58
tackerclient/tests/unit/osc/v1/vnf_package_fakes.py
Normal file
58
tackerclient/tests/unit/osc/v1/vnf_package_fakes.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
# Copyright (C) 2019 NTT DATA
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
|
||||||
|
def vnf_package_obj(attrs=None):
|
||||||
|
"""Create a fake vnf package.
|
||||||
|
|
||||||
|
:param Dictionary attrs:
|
||||||
|
A dictionary with all attributes
|
||||||
|
:return:
|
||||||
|
A FakeVnfPackage dict
|
||||||
|
"""
|
||||||
|
attrs = attrs or {}
|
||||||
|
|
||||||
|
# Set default attributes.
|
||||||
|
fake_vnf_package = {"id": "60a6ac16-b50d-4e92-964b-b3cf98c7cf5c",
|
||||||
|
"_links": {"self": {"href": "string"},
|
||||||
|
"vnfd": {"href": "string"},
|
||||||
|
"packageContent": {"href": "string"}
|
||||||
|
},
|
||||||
|
"onboardingState": "CREATED",
|
||||||
|
"operationalState": "DISABLED",
|
||||||
|
"usageState": "NOT_IN_USE",
|
||||||
|
"userDefinedData": None}
|
||||||
|
|
||||||
|
# Overwrite default attributes.
|
||||||
|
fake_vnf_package.update(attrs)
|
||||||
|
return fake_vnf_package
|
||||||
|
|
||||||
|
|
||||||
|
def get_vnf_package_data(vnf_package=None):
|
||||||
|
"""Get the vnf package data from a FakeVnfPackage dict object.
|
||||||
|
|
||||||
|
:param vnf_package:
|
||||||
|
A FakeVnfPackage dict object
|
||||||
|
:return:
|
||||||
|
A tuple which may include the following values:
|
||||||
|
(u"packageContent='{'href': 'string'}', self='{'href': 'string'}',
|
||||||
|
vnfd='{'href': 'string'}'", '60a6ac16-b50d-4e92-964b-b3cf98c7cf5c',
|
||||||
|
'CREATED', 'DISABLED', 'NOT_IN_USE', u"Test_key='Test_value'")
|
||||||
|
"""
|
||||||
|
data_list = []
|
||||||
|
if vnf_package is not None:
|
||||||
|
for x in sorted(vnf_package.keys()):
|
||||||
|
data_list.append(vnf_package[x])
|
||||||
|
return tuple(data_list)
|
@ -192,9 +192,9 @@ class CLITestV10Base(testtools.TestCase):
|
|||||||
def setUp(self, plurals={}):
|
def setUp(self, plurals={}):
|
||||||
"""Prepare the test environment."""
|
"""Prepare the test environment."""
|
||||||
super(CLITestV10Base, self).setUp()
|
super(CLITestV10Base, self).setUp()
|
||||||
client.Client.EXTED_PLURALS.update(constants.PLURALS)
|
client.LegacyClient.EXTED_PLURALS.update(constants.PLURALS)
|
||||||
client.Client.EXTED_PLURALS.update(plurals)
|
client.LegacyClient.EXTED_PLURALS.update(plurals)
|
||||||
self.metadata = {'plurals': client.Client.EXTED_PLURALS,
|
self.metadata = {'plurals': client.LegacyClient.EXTED_PLURALS,
|
||||||
'xmlns': constants.XML_NS_V10,
|
'xmlns': constants.XML_NS_V10,
|
||||||
constants.EXT_NS: {'prefix':
|
constants.EXT_NS: {'prefix':
|
||||||
'http://xxxx.yy.com'}}
|
'http://xxxx.yy.com'}}
|
||||||
@ -207,7 +207,8 @@ class CLITestV10Base(testtools.TestCase):
|
|||||||
self.useFixture(fixtures.MonkeyPatch(
|
self.useFixture(fixtures.MonkeyPatch(
|
||||||
'tackerclient.tacker.v1_0.find_resourceid_by_id',
|
'tackerclient.tacker.v1_0.find_resourceid_by_id',
|
||||||
self._find_resourceid))
|
self._find_resourceid))
|
||||||
self.client = client.Client(token=TOKEN, endpoint_url=self.endurl)
|
self.client = client.LegacyClient(token=TOKEN,
|
||||||
|
endpoint_url=self.endurl)
|
||||||
|
|
||||||
@mock.patch.object(TackerCommand, 'get_client')
|
@mock.patch.object(TackerCommand, 'get_client')
|
||||||
def _test_create_resource(self, resource, cmd,
|
def _test_create_resource(self, resource, cmd,
|
||||||
@ -685,7 +686,7 @@ class ClientV1TestJson(CLITestV10Base):
|
|||||||
error = self.assertRaises(exceptions.TackerClientException,
|
error = self.assertRaises(exceptions.TackerClientException,
|
||||||
self.client.do_request, 'PUT', '/test',
|
self.client.do_request, 'PUT', '/test',
|
||||||
body='', params=params)
|
body='', params=params)
|
||||||
self.assertEqual("An error", str(error))
|
self.assertEqual("400-tackerFault", str(error))
|
||||||
|
|
||||||
|
|
||||||
class CLITestV10ExceptionHandler(CLITestV10Base):
|
class CLITestV10ExceptionHandler(CLITestV10Base):
|
||||||
@ -779,11 +780,11 @@ class CLITestV10ExceptionHandler(CLITestV10Base):
|
|||||||
error_content = {'message': 'This is an error message'}
|
error_content = {'message': 'This is an error message'}
|
||||||
self._test_exception_handler_v10(
|
self._test_exception_handler_v10(
|
||||||
exceptions.TackerClientException, 500,
|
exceptions.TackerClientException, 500,
|
||||||
expected_msg='This is an error message',
|
expected_msg='500-tackerFault',
|
||||||
error_content=error_content)
|
error_content=error_content)
|
||||||
|
|
||||||
def test_exception_handler_v10_error_dict_not_contain_message(self):
|
def test_exception_handler_v10_error_dict_not_contain_message(self):
|
||||||
error_content = {'error': 'This is an error message'}
|
error_content = 'tackerFault'
|
||||||
expected_msg = '%s-%s' % (500, error_content)
|
expected_msg = '%s-%s' % (500, error_content)
|
||||||
self._test_exception_handler_v10(
|
self._test_exception_handler_v10(
|
||||||
exceptions.TackerClientException, 500,
|
exceptions.TackerClientException, 500,
|
||||||
|
@ -31,6 +31,18 @@ from tackerclient.i18n import _
|
|||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
DEFAULT_DESC_LENGTH = 25
|
DEFAULT_DESC_LENGTH = 25
|
||||||
DEFAULT_ERROR_REASON_LENGTH = 100
|
DEFAULT_ERROR_REASON_LENGTH = 100
|
||||||
|
STATUS_CODE_MAP = {
|
||||||
|
400: "badRequest",
|
||||||
|
401: "unauthorized",
|
||||||
|
403: "forbidden",
|
||||||
|
404: "itemNotFound",
|
||||||
|
405: "badMethod",
|
||||||
|
409: "conflictingRequest",
|
||||||
|
413: "overLimit",
|
||||||
|
415: "badMediaType",
|
||||||
|
429: "overLimit",
|
||||||
|
501: "notImplemented",
|
||||||
|
503: "serviceUnavailable"}
|
||||||
|
|
||||||
|
|
||||||
def exception_handler_v10(status_code, error_content):
|
def exception_handler_v10(status_code, error_content):
|
||||||
@ -45,6 +57,9 @@ def exception_handler_v10(status_code, error_content):
|
|||||||
error_dict = None
|
error_dict = None
|
||||||
if isinstance(error_content, dict):
|
if isinstance(error_content, dict):
|
||||||
error_dict = error_content.get('TackerError')
|
error_dict = error_content.get('TackerError')
|
||||||
|
if not error_dict:
|
||||||
|
error_content = error_content.get(STATUS_CODE_MAP.get(status_code),
|
||||||
|
'tackerFault')
|
||||||
# Find real error type
|
# Find real error type
|
||||||
bad_tacker_error_flag = False
|
bad_tacker_error_flag = False
|
||||||
if error_dict:
|
if error_dict:
|
||||||
@ -141,17 +156,6 @@ class ClientBase(object):
|
|||||||
:param session: Keystone client auth session to use. (optional)
|
:param session: Keystone client auth session to use. (optional)
|
||||||
:param auth: Keystone auth plugin to use. (optional)
|
:param auth: Keystone auth plugin to use. (optional)
|
||||||
|
|
||||||
Example::
|
|
||||||
|
|
||||||
from tackerclient.v1_0 import client
|
|
||||||
tacker = client.Client(username=USER,
|
|
||||||
password=PASS,
|
|
||||||
tenant_name=TENANT_NAME,
|
|
||||||
auth_url=KEYSTONE_URL)
|
|
||||||
|
|
||||||
nets = tacker.list_networks()
|
|
||||||
...
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# API has no way to report plurals, so we have to hard code them
|
# API has no way to report plurals, so we have to hard code them
|
||||||
@ -182,15 +186,19 @@ class ClientBase(object):
|
|||||||
# Raise the appropriate exception
|
# Raise the appropriate exception
|
||||||
exception_handler_v10(status_code, des_error_body)
|
exception_handler_v10(status_code, des_error_body)
|
||||||
|
|
||||||
def do_request(self, method, action, body=None, headers=None, params=None):
|
def build_action(self, action):
|
||||||
# Add format and tenant_id
|
|
||||||
action += ".%s" % self.format
|
action += ".%s" % self.format
|
||||||
action = self.action_prefix + action
|
action = self.action_prefix + action
|
||||||
|
return action
|
||||||
|
|
||||||
|
def do_request(self, method, action, body=None, headers=None, params=None):
|
||||||
|
action = self.build_action(action)
|
||||||
|
# Add format and tenant_id
|
||||||
if type(params) is dict and params:
|
if type(params) is dict and params:
|
||||||
params = utils.safe_encode_dict(params)
|
params = utils.safe_encode_dict(params)
|
||||||
action += '?' + urlparse.urlencode(params, doseq=1)
|
action += '?' + urlparse.urlencode(params, doseq=1)
|
||||||
|
|
||||||
if body:
|
if body or body == {}:
|
||||||
body = self.serialize(body)
|
body = self.serialize(body)
|
||||||
|
|
||||||
resp, replybody = self.httpclient.do_request(
|
resp, replybody = self.httpclient.do_request(
|
||||||
@ -329,7 +337,7 @@ class ClientBase(object):
|
|||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
class Client(ClientBase):
|
class LegacyClient(ClientBase):
|
||||||
|
|
||||||
extensions_path = "/extensions"
|
extensions_path = "/extensions"
|
||||||
extension_path = "/extensions/%s"
|
extension_path = "/extensions/%s"
|
||||||
@ -708,3 +716,232 @@ class Client(ClientBase):
|
|||||||
@APIParamsCall
|
@APIParamsCall
|
||||||
def delete_clustermember(self, clustermember):
|
def delete_clustermember(self, clustermember):
|
||||||
return self.delete(self.cluster_member_path % clustermember)
|
return self.delete(self.cluster_member_path % clustermember)
|
||||||
|
|
||||||
|
|
||||||
|
class VnfPackageClient(ClientBase):
|
||||||
|
"""Client for vnfpackage APIs.
|
||||||
|
|
||||||
|
Purpose of this class is to create required request url for vnfpackage
|
||||||
|
APIs.
|
||||||
|
"""
|
||||||
|
|
||||||
|
vnfpackages_path = '/vnfpkgm/v1/vnf_packages'
|
||||||
|
|
||||||
|
def build_action(self, action):
|
||||||
|
return action
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def create_vnf_package(self, body):
|
||||||
|
return self.post(self.vnfpackages_path, body=body)
|
||||||
|
|
||||||
|
|
||||||
|
class Client(object):
|
||||||
|
"""Unified interface to interact with multiple applications of tacker service.
|
||||||
|
|
||||||
|
This class is a single entry point to interact with legacy tacker apis and
|
||||||
|
vnf packages apis.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
from tackerclient.v1_0 import client
|
||||||
|
tacker = client.Client(username=USER,
|
||||||
|
password=PASS,
|
||||||
|
tenant_name=TENANT_NAME,
|
||||||
|
auth_url=KEYSTONE_URL)
|
||||||
|
|
||||||
|
vnf_package = tacker.create_vnf_package(...)
|
||||||
|
nsd = tacker.create_nsd(...)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self.vnf_package_client = VnfPackageClient(**kwargs)
|
||||||
|
self.legacy_client = LegacyClient(**kwargs)
|
||||||
|
|
||||||
|
# LegacyClient methods
|
||||||
|
|
||||||
|
def list_extensions(self, **_params):
|
||||||
|
return self.legacy_client.list_extensions(**_params)
|
||||||
|
|
||||||
|
def show_extension(self, ext_alias, **_params):
|
||||||
|
"""Fetch a list of all exts on server side."""
|
||||||
|
return self.legacy_client.show_extension(ext_alias, **_params)
|
||||||
|
|
||||||
|
def list_vnfds(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_vnfds(retrieve_all=retrieve_all,
|
||||||
|
**_params)
|
||||||
|
|
||||||
|
def show_vnfd(self, vnfd, **_params):
|
||||||
|
return self.legacy_client.show_vnfd(vnfd, **_params)
|
||||||
|
|
||||||
|
def create_vnfd(self, body):
|
||||||
|
return self.legacy_client.create_vnfd(body)
|
||||||
|
|
||||||
|
def delete_vnfd(self, vnfd):
|
||||||
|
return self.legacy_client.delete_vnfd(vnfd)
|
||||||
|
|
||||||
|
def list_vnfs(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_vnfs(retrieve_all=retrieve_all,
|
||||||
|
**_params)
|
||||||
|
|
||||||
|
def show_vnf(self, vnf, **_params):
|
||||||
|
return self.legacy_client.show_vnf(vnf, **_params)
|
||||||
|
|
||||||
|
def create_vnf(self, body):
|
||||||
|
return self.legacy_client.create_vnf(body)
|
||||||
|
|
||||||
|
def delete_vnf(self, vnf, body=None):
|
||||||
|
return self.legacy_client.delete_vnf(vnf, body=body)
|
||||||
|
|
||||||
|
def update_vnf(self, vnf, body):
|
||||||
|
return self.legacy_client.update_vnf(vnf, body)
|
||||||
|
|
||||||
|
def list_vnf_resources(self, vnf, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_vnf_resources(
|
||||||
|
vnf, retrieve_all=retrieve_all, **_params)
|
||||||
|
|
||||||
|
def scale_vnf(self, vnf, body=None):
|
||||||
|
return self.legacy_client.scale_vnf(vnf, body=body)
|
||||||
|
|
||||||
|
def show_vim(self, vim, **_params):
|
||||||
|
return self.legacy_client.show_vim(vim, **_params)
|
||||||
|
|
||||||
|
def create_vim(self, body):
|
||||||
|
return self.legacy_client.create_vim(body)
|
||||||
|
|
||||||
|
def delete_vim(self, vim):
|
||||||
|
return self.legacy_client.delete_vim(vim)
|
||||||
|
|
||||||
|
def update_vim(self, vim, body):
|
||||||
|
return self.legacy_client.update_vim(vim, body)
|
||||||
|
|
||||||
|
def list_vims(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_vims(retrieve_all=retrieve_all,
|
||||||
|
**_params)
|
||||||
|
|
||||||
|
def list_events(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_events(retrieve_all=retrieve_all,
|
||||||
|
**_params)
|
||||||
|
|
||||||
|
def list_vnf_events(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_vnf_events(
|
||||||
|
retrieve_all=retrieve_all, **_params)
|
||||||
|
|
||||||
|
def list_vnfd_events(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_vnfd_events(
|
||||||
|
retrieve_all=retrieve_all, **_params)
|
||||||
|
|
||||||
|
def list_vim_events(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_vim_events(
|
||||||
|
retrieve_all=retrieve_all, **_params)
|
||||||
|
|
||||||
|
def show_event(self, event_id, **_params):
|
||||||
|
return self.legacy_client.show_event(event_id, **_params)
|
||||||
|
|
||||||
|
def create_vnffgd(self, body):
|
||||||
|
return self.legacy_client.create_vnffgd(body)
|
||||||
|
|
||||||
|
def list_vnffgds(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_vnffgds(retrieve_all=retrieve_all,
|
||||||
|
**_params)
|
||||||
|
|
||||||
|
def show_vnffgd(self, vnffgd, **_params):
|
||||||
|
return self.legacy_client.show_vnffgd(vnffgd, **_params)
|
||||||
|
|
||||||
|
def delete_vnffgd(self, vnffgd):
|
||||||
|
return self.legacy_client.delete_vnffgd(vnffgd)
|
||||||
|
|
||||||
|
def list_vnffgs(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_vnffgs(retrieve_all=retrieve_all,
|
||||||
|
**_params)
|
||||||
|
|
||||||
|
def show_vnffg(self, vnffg, **_params):
|
||||||
|
return self.legacy_client.show_vnffg(vnffg, **_params)
|
||||||
|
|
||||||
|
def create_vnffg(self, body):
|
||||||
|
return self.legacy_client.create_vnffg(body)
|
||||||
|
|
||||||
|
def delete_vnffg(self, vnffg):
|
||||||
|
return self.legacy_client.delete_vnffg(vnffg)
|
||||||
|
|
||||||
|
def update_vnffg(self, vnffg, body):
|
||||||
|
return self.legacy_client.update_vnffg(vnffg, body)
|
||||||
|
|
||||||
|
def list_sfcs(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_sfcs(retrieve_all=retrieve_all,
|
||||||
|
**_params)
|
||||||
|
|
||||||
|
def show_sfc(self, chain, **_params):
|
||||||
|
return self.legacy_client.show_sfc(chain, **_params)
|
||||||
|
|
||||||
|
def list_nfps(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_nfps(retrieve_all=retrieve_all,
|
||||||
|
**_params)
|
||||||
|
|
||||||
|
def show_nfp(self, nfp, **_params):
|
||||||
|
return self.legacy_client.show_nfp(nfp, **_params)
|
||||||
|
|
||||||
|
def list_classifiers(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_classifiers(
|
||||||
|
retrieve_all=retrieve_all, **_params)
|
||||||
|
|
||||||
|
def show_classifier(self, classifier, **_params):
|
||||||
|
return self.legacy_client.show_classifier(classifier, **_params)
|
||||||
|
|
||||||
|
def list_nsds(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_nsds(retrieve_all=retrieve_all,
|
||||||
|
**_params)
|
||||||
|
|
||||||
|
def show_nsd(self, nsd, **_params):
|
||||||
|
return self.legacy_client.show_nsd(nsd, **_params)
|
||||||
|
|
||||||
|
def create_nsd(self, body):
|
||||||
|
return self.legacy_client.create_nsd(body)
|
||||||
|
|
||||||
|
def delete_nsd(self, nsd):
|
||||||
|
return self.legacy_client.delete_nsd(nsd)
|
||||||
|
|
||||||
|
def list_nss(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_nss(retrieve_all=retrieve_all,
|
||||||
|
**_params)
|
||||||
|
|
||||||
|
def show_ns(self, ns, **_params):
|
||||||
|
return self.legacy_client.show_ns(ns, **_params)
|
||||||
|
|
||||||
|
def create_ns(self, body):
|
||||||
|
return self.legacy_client.create_ns(body)
|
||||||
|
|
||||||
|
def delete_ns(self, ns):
|
||||||
|
return self.legacy_client.delete_ns(ns)
|
||||||
|
|
||||||
|
def create_cluster(self, body=None):
|
||||||
|
return self.legacy_client.create_cluster(body=body)
|
||||||
|
|
||||||
|
def list_clusters(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_clusters(retrieve_all=retrieve_all,
|
||||||
|
**_params)
|
||||||
|
|
||||||
|
def show_cluster(self, cluster, **_params):
|
||||||
|
return self.legacy_client.show_cluster(cluster, **_params)
|
||||||
|
|
||||||
|
def delete_cluster(self, cluster):
|
||||||
|
return self.legacy_client.delete_cluster(cluster)
|
||||||
|
|
||||||
|
def create_clustermember(self, body=None):
|
||||||
|
return self.legacy_client.create_clustermember(body=body)
|
||||||
|
|
||||||
|
def list_clustermembers(self, retrieve_all=True, **_params):
|
||||||
|
return self.legacy_client.list_clustermembers(
|
||||||
|
retrieve_all=retrieve_all, **_params)
|
||||||
|
|
||||||
|
def show_clustermember(self, clustermember, **_params):
|
||||||
|
return self.legacy_client.show_clustermember(clustermember,
|
||||||
|
**_params)
|
||||||
|
|
||||||
|
def delete_clustermember(self, clustermember):
|
||||||
|
return self.legacy_client.delete_clustermember(clustermember)
|
||||||
|
|
||||||
|
# VnfPackageClient methods
|
||||||
|
|
||||||
|
def create_vnf_package(self, body):
|
||||||
|
return self.vnf_package_client.create_vnf_package(body)
|
||||||
|
@ -4,8 +4,10 @@
|
|||||||
|
|
||||||
hacking>=1.1.0,<1.2.0 # Apache-2.0
|
hacking>=1.1.0,<1.2.0 # Apache-2.0
|
||||||
coverage!=4.4,>=4.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
|
fixtures>=3.0.0 # Apache-2.0/BSD
|
||||||
python-subunit>=1.0.0 # Apache-2.0/BSD
|
python-subunit>=1.0.0 # Apache-2.0/BSD
|
||||||
|
requests-mock>=1.2.0 # Apache-2.0
|
||||||
stestr>=2.0.0 # Apache-2.0
|
stestr>=2.0.0 # Apache-2.0
|
||||||
testtools>=2.2.0 # MIT
|
testtools>=2.2.0 # MIT
|
||||||
mock>=2.0.0 # BSD
|
mock>=2.0.0 # BSD
|
||||||
|
Loading…
Reference in New Issue
Block a user