Support ChangeVNFPackage command in tackerclient
Add ``openstack vnflcm change_vnfpkg`` to python-tackerclient. This command can execute change current vnf package operation [1]. [1] https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/003/03.03.01_60/gs_NFV-SOL003v030301p.pdf Implements: blueprint upgrade-vnf-package Change-Id: I0d9c88147dee3a273cb27224db6be6c91cf7fe55
This commit is contained in:
parent
b7f27c3dc6
commit
ab901b6466
@ -110,6 +110,7 @@ openstack.tackerclient.v2 =
|
||||
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_op_list = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ListVnfLcmOp
|
||||
vnflcm_op_show = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ShowVnfLcmOp
|
||||
|
@ -207,6 +207,10 @@ 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):
|
||||
|
@ -566,3 +566,30 @@ class ChangeExtConnVnfLcm(command.Command):
|
||||
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))
|
||||
|
@ -0,0 +1,36 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
@ -850,6 +850,40 @@ class TestChangeExtConnVnfLcm(TestVnfLcm):
|
||||
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'
|
||||
|
@ -13,8 +13,18 @@
|
||||
# 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):
|
||||
@ -30,3 +40,112 @@ class TestVnfLcmV2(base.FixturedTestCase):
|
||||
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))
|
||||
|
@ -966,6 +966,15 @@ class VnfLCMClient(ClientBase):
|
||||
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,
|
||||
@ -1272,6 +1281,9 @@ class Client(object):
|
||||
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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user