Multi version API support
Add version '2' for support version of --os-tacker-api-version to 'openstack vnflcm' CLI. If '--os-tacker-api-version 2' is specified, REST API url '/vnflcm/v2' is used instead of '/vnflcm/v1'. New CLI 'openstack vnflcm versions' is added too. Implements: blueprint multi-version-api Change-Id: I256a4010043d0b84ffe43b055c6a6a67a2d5d661
This commit is contained in:
11
setup.cfg
11
setup.cfg
@@ -100,3 +100,14 @@ openstack.tackerclient.v1 =
|
||||
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_delete = tackerclient.osc.v1.vnflcm.vnflcm:DeleteVnfLcm
|
||||
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
|
||||
|
0
tackerclient/osc/common/__init__.py
Normal file
0
tackerclient/osc/common/__init__.py
Normal file
0
tackerclient/osc/common/vnflcm/__init__.py
Normal file
0
tackerclient/osc/common/vnflcm/__init__.py
Normal file
49
tackerclient/osc/common/vnflcm/vnflcm_versions.py
Normal file
49
tackerclient/osc/common/vnflcm/vnflcm_versions.py
Normal file
@@ -0,0 +1,49 @@
|
||||
# Copyright (C) 2021 Nippon Telegraph and Telephone Corporation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from osc_lib.command import command
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.i18n import _
|
||||
|
||||
|
||||
SUPPORTED_VERSIONS = [1, 2]
|
||||
|
||||
|
||||
class VnfLcmVersions(command.ShowOne):
|
||||
_description = _("Show VnfLcm Api versions")
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(VnfLcmVersions, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--major-version',
|
||||
metavar="<major-version>",
|
||||
type=int,
|
||||
help=_('Show only specify major version.'))
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
v = None
|
||||
if parsed_args.major_version:
|
||||
if parsed_args.major_version not in SUPPORTED_VERSIONS:
|
||||
msg = _("Major version %d is not supported")
|
||||
reason = msg % parsed_args.major_version
|
||||
raise exceptions.InvalidInput(reason=reason)
|
||||
v = "v{}".format(parsed_args.major_version)
|
||||
|
||||
client = self.app.client_manager.tackerclient
|
||||
data = client.show_vnf_lcm_versions(v)
|
||||
|
||||
return (tuple(data.keys()), tuple(data.values()))
|
@@ -26,15 +26,17 @@ 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,
|
||||
instance._api_version[API_NAME],
|
||||
api_version,
|
||||
API_VERSIONS)
|
||||
LOG.debug('Instantiating tacker client: %s', tacker_client)
|
||||
|
||||
@@ -42,7 +44,8 @@ def make_client(instance):
|
||||
'region_name': instance._region_name,
|
||||
'endpoint_type': instance._interface,
|
||||
'interface': instance._interface,
|
||||
'session': instance.session
|
||||
'session': instance.session,
|
||||
'api_version': api_version
|
||||
}
|
||||
|
||||
client = tacker_client(**kwargs)
|
||||
|
@@ -22,6 +22,7 @@ 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()
|
||||
@@ -29,7 +30,8 @@ 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)
|
||||
fix = self.client_fixture_class(self.requests_mock,
|
||||
api_version=self.api_version)
|
||||
self.cs = self.useFixture(fix).client
|
||||
|
||||
def check_parser(self, cmd, args, verify_args):
|
||||
|
0
tackerclient/tests/unit/osc/common/__init__.py
Normal file
0
tackerclient/tests/unit/osc/common/__init__.py
Normal file
101
tackerclient/tests/unit/osc/common/test_vnflcm_versions.py
Normal file
101
tackerclient/tests/unit/osc/common/test_vnflcm_versions.py
Normal file
@@ -0,0 +1,101 @@
|
||||
# Copyright (C) 2021 Nippon Telegraph and Telephone Corporation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
|
||||
import ddt
|
||||
from unittest import mock
|
||||
|
||||
from tackerclient.common import exceptions
|
||||
from tackerclient.osc.common.vnflcm import vnflcm_versions
|
||||
from tackerclient.tests.unit.osc import base
|
||||
from tackerclient.tests.unit.osc.v1.fixture_data import client
|
||||
|
||||
|
||||
class TestVnfLcm(base.FixturedTestCase):
|
||||
client_fixture_class = client.ClientFixture
|
||||
|
||||
def setUp(self):
|
||||
super(TestVnfLcm, self).setUp()
|
||||
self.url = client.TACKER_URL
|
||||
self.header = {'content-type': 'application/json'}
|
||||
self.app = mock.Mock()
|
||||
self.app_args = mock.Mock()
|
||||
self.client_manager = self.cs
|
||||
self.app.client_manager.tackerclient = self.client_manager
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestVnfLcmVersions(TestVnfLcm):
|
||||
|
||||
def setUp(self):
|
||||
super(TestVnfLcmVersions, self).setUp()
|
||||
self.vnflcm_versions = vnflcm_versions.VnfLcmVersions(
|
||||
self.app, self.app_args, cmd_name='vnflcm versions')
|
||||
|
||||
def _versions_response(self, major_version=None):
|
||||
if major_version is None:
|
||||
return {"uriPrefix": "/vnflcm",
|
||||
"apiVersions": [{"version": "1.3.0",
|
||||
"isDeprecated": False},
|
||||
{"version": "2.0.0",
|
||||
"isDeprecated": False}]}
|
||||
elif major_version == "1":
|
||||
return {"uriPrefix": "/vnflcm/v1",
|
||||
"apiVersions": [{"version": "1.3.0",
|
||||
"isDeprecated": False}]}
|
||||
elif major_version == "2":
|
||||
return {"uriPrefix": "/vnflcm/v2",
|
||||
"apiVersions": [{"version": "2.0.0",
|
||||
"isDeprecated": False}]}
|
||||
|
||||
def test_invalid_major_version(self):
|
||||
parser = self.vnflcm_versions.get_parser('vnflcm versions')
|
||||
parsed_args = parser.parse_args(["--major-version", "3"])
|
||||
self.assertRaises(exceptions.InvalidInput,
|
||||
self.vnflcm_versions.take_action,
|
||||
parsed_args)
|
||||
|
||||
def test_take_action_no_arg(self):
|
||||
parser = self.vnflcm_versions.get_parser('vnflcm versions')
|
||||
parsed_args = parser.parse_args([])
|
||||
|
||||
response = self._versions_response()
|
||||
self.requests_mock.register_uri(
|
||||
'GET', os.path.join(self.url, 'vnflcm/api_versions'),
|
||||
json=response, headers=self.header)
|
||||
|
||||
colmns, data = self.vnflcm_versions.take_action(parsed_args)
|
||||
|
||||
self.assertEqual(colmns, tuple(response.keys()))
|
||||
self.assertEqual(data, tuple(response.values()))
|
||||
|
||||
@ddt.data('1', '2')
|
||||
def test_take_action_with_major_version(self, major_version):
|
||||
parser = self.vnflcm_versions.get_parser('vnflcm versions')
|
||||
parsed_args = parser.parse_args(["--major-version",
|
||||
major_version])
|
||||
|
||||
response = self._versions_response(major_version)
|
||||
self.requests_mock.register_uri(
|
||||
'GET',
|
||||
os.path.join(self.url,
|
||||
'vnflcm/v{}/api_versions'.format(major_version)),
|
||||
json=response, headers=self.header)
|
||||
|
||||
colmns, data = self.vnflcm_versions.take_action(parsed_args)
|
||||
|
||||
self.assertEqual(colmns, tuple(response.keys()))
|
||||
self.assertEqual(data, tuple(response.values()))
|
@@ -25,7 +25,8 @@ TACKER_URL = 'http://nfv-orchestration'
|
||||
|
||||
class ClientFixture(fixtures.Fixture):
|
||||
|
||||
def __init__(self, requests_mock, identity_url=IDENTITY_URL):
|
||||
def __init__(self, requests_mock, identity_url=IDENTITY_URL,
|
||||
api_version='1'):
|
||||
super(ClientFixture, self).__init__()
|
||||
self.identity_url = identity_url
|
||||
self.client = None
|
||||
@@ -35,6 +36,7 @@ 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()
|
||||
@@ -57,4 +59,5 @@ class ClientFixture(fixtures.Fixture):
|
||||
region_name='RegionOne',
|
||||
auth_url=self.identity_url,
|
||||
token=self.token.token_id,
|
||||
endpoint_url=TACKER_URL)
|
||||
endpoint_url=TACKER_URL,
|
||||
api_version=self.api_version)
|
||||
|
@@ -848,3 +848,18 @@ class TestChangeExtConnVnfLcm(TestVnfLcm):
|
||||
|
||||
expected_msg = "Failed to load parameter file."
|
||||
self.assertIn(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.
|
||||
|
0
tackerclient/tests/unit/osc/v2/__init__.py
Normal file
0
tackerclient/tests/unit/osc/v2/__init__.py
Normal file
32
tackerclient/tests/unit/osc/v2/test_vnflcm.py
Normal file
32
tackerclient/tests/unit/osc/v2/test_vnflcm.py
Normal file
@@ -0,0 +1,32 @@
|
||||
# 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 tackerclient.tests.unit.osc import base
|
||||
from tackerclient.tests.unit.osc.v1.fixture_data import 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.
|
@@ -229,8 +229,12 @@ 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,
|
||||
action, method, body=body, headers=headers,
|
||||
content_type=self.content_type())
|
||||
|
||||
if 'application/zip' == resp.headers.get('Content-Type'):
|
||||
@@ -355,26 +359,27 @@ class ClientBase(object):
|
||||
return self.retry_request("PATCH", action, body=body,
|
||||
headers=headers, params=params)
|
||||
|
||||
def list(self, collection, path, retrieve_all=True, **params):
|
||||
def list(self, collection, path, retrieve_all=True, headers=None,
|
||||
**params):
|
||||
if retrieve_all:
|
||||
res = []
|
||||
for r in self._pagination(collection, path, **params):
|
||||
for r in self._pagination(collection, path, headers, **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, **params)
|
||||
return self._pagination(collection, path, headers, **params)
|
||||
|
||||
def _pagination(self, collection, path, **params):
|
||||
def _pagination(self, collection, path, headers, **params):
|
||||
if params.get('page_reverse', False):
|
||||
linkrel = 'previous'
|
||||
else:
|
||||
linkrel = 'next'
|
||||
next = True
|
||||
while next:
|
||||
res = self.get(path, params=params)
|
||||
res = self.get(path, headers=headers, params=params)
|
||||
yield res
|
||||
next = False
|
||||
try:
|
||||
@@ -874,82 +879,116 @@ class VnfLCMClient(ClientBase):
|
||||
APIs.
|
||||
"""
|
||||
|
||||
vnf_instances_path = '/vnflcm/v1/vnf_instances'
|
||||
vnf_instance_path = '/vnflcm/v1/vnf_instances/%s'
|
||||
vnf_lcm_op_occurrences_path = '/vnflcm/v1/vnf_lcm_op_occs'
|
||||
vnf_lcm_op_occs_path = '/vnflcm/v1/vnf_lcm_op_occs/%s'
|
||||
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))
|
||||
|
||||
def build_action(self, action):
|
||||
return action
|
||||
|
||||
@APIParamsCall
|
||||
def create_vnf_instance(self, body):
|
||||
return self.post(self.vnf_instances_path, body=body)
|
||||
return self.post(self.vnf_instances_path, body=body,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def show_vnf_instance(self, vnf_id, **_params):
|
||||
return self.get(self.vnf_instance_path % vnf_id, params=_params)
|
||||
return self.get(self.vnf_instance_path % vnf_id,
|
||||
headers=self.headers, params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def list_vnf_instances(self, retrieve_all=True, **_params):
|
||||
vnf_instances = self.list(None, self.vnf_instances_path,
|
||||
retrieve_all, **_params)
|
||||
retrieve_all, headers=self.headers,
|
||||
**_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)
|
||||
body=body, headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def heal_vnf_instance(self, vnf_id, body):
|
||||
return self.post((self.vnf_instance_path + "/heal") % vnf_id,
|
||||
body=body)
|
||||
body=body, headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def terminate_vnf_instance(self, vnf_id, body):
|
||||
return self.post((self.vnf_instance_path + "/terminate") % vnf_id,
|
||||
body=body)
|
||||
body=body, headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def delete_vnf_instance(self, vnf_id):
|
||||
return self.delete(self.vnf_instance_path % vnf_id)
|
||||
return self.delete(self.vnf_instance_path % vnf_id,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def update_vnf_instance(self, vnf_id, body):
|
||||
return self.patch(self.vnf_instance_path % vnf_id, body=body)
|
||||
return self.patch(self.vnf_instance_path % vnf_id, body=body,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def scale_vnf_instance(self, vnf_id, body):
|
||||
return self.post((self.vnf_instance_path + "/scale") % vnf_id,
|
||||
body=body)
|
||||
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)
|
||||
return self.post((self.vnf_lcm_op_occs_path + "/rollback") % occ_id,
|
||||
headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def fail_vnf_instance(self, occ_id):
|
||||
return self.post((self.vnf_lcm_op_occs_path + "/fail") % 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)
|
||||
vnf_id, body=body, headers=self.headers)
|
||||
|
||||
@APIParamsCall
|
||||
def retry_vnf_instance(self, occ_id):
|
||||
return self.post((self.vnf_lcm_op_occs_path + "/retry") % 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, **_params)
|
||||
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)
|
||||
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'})
|
||||
|
||||
|
||||
class Client(object):
|
||||
@@ -972,7 +1011,8 @@ class Client(object):
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.vnf_lcm_client = VnfLCMClient(**kwargs)
|
||||
api_version = kwargs.pop('api_version', '1')
|
||||
self.vnf_lcm_client = VnfLCMClient(api_version, **kwargs)
|
||||
self.vnf_package_client = VnfPackageClient(**kwargs)
|
||||
self.legacy_client = LegacyClient(**kwargs)
|
||||
|
||||
@@ -1263,3 +1303,6 @@ class Client(object):
|
||||
|
||||
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)
|
||||
|
Reference in New Issue
Block a user