Support CLI of Change External VNF Connectivity
Add ``openstack vnflcm op chg-ext-conn`` to python-tackerclient. This command can execute Change external VNF Connectivity operation. This API can change VL setting. Implements: blueprint support-change-external-connectivity Spec: https://specs.openstack.org/openstack/tacker-specs/specs/wallaby/support-change-external-VNF-connectivity-operation.html Change-Id: I3a935296646361032665082a4060bc21ff51c1b1
This commit is contained in:

committed by
Aldinson Esto

parent
58167535c7
commit
cfe14110d1
@@ -94,5 +94,6 @@ 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_fail = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:FailVnfLcmOp
|
||||
|
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@@ -537,3 +537,30 @@ class ScaleVnfLcm(command.Command):
|
||||
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))
|
||||
|
@@ -739,3 +739,110 @@ 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))
|
||||
|
@@ -931,6 +931,11 @@ class VnfLCMClient(ClientBase):
|
||||
def fail_vnf_instance(self, occ_id):
|
||||
return self.post((self.vnf_lcm_op_occs_path + "/fail") % occ_id)
|
||||
|
||||
@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)
|
||||
|
||||
|
||||
class Client(object):
|
||||
"""Unified interface to interact with multiple applications of tacker service.
|
||||
@@ -1204,6 +1209,9 @@ 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 delete_vnf_instance(self, vnf_id):
|
||||
return self.vnf_lcm_client.delete_vnf_instance(vnf_id)
|
||||
|
||||
|
Reference in New Issue
Block a user