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:
		 Wataru Juso
					Wataru Juso
				
			
				
					committed by
					
						 Aldinson Esto
						Aldinson Esto
					
				
			
			
				
	
			
			
			 Aldinson Esto
						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