diff --git a/setup.cfg b/setup.cfg index 5fe367ca..cbd5ef15 100644 --- a/setup.cfg +++ b/setup.cfg @@ -97,3 +97,4 @@ openstack.tackerclient.v1 = 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 + vnflcm_op_retry = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:RetryVnfLcmOp diff --git a/tackerclient/osc/v1/vnflcm/vnflcm_op_occs.py b/tackerclient/osc/v1/vnflcm/vnflcm_op_occs.py index 2266ec48..6e519c3c 100644 --- a/tackerclient/osc/v1/vnflcm/vnflcm_op_occs.py +++ b/tackerclient/osc/v1/vnflcm/vnflcm_op_occs.py @@ -108,3 +108,36 @@ class FailVnfLcmOp(command.ShowOne): columns, formatters=_FORMATTERS, mixed_case_fields=_MIXED_CASE_FIELDS) return (display_columns, data) + + +class RetryVnfLcmOp(command.Command): + _description = _("Retry VNF Instance") + + def get_parser(self, prog_name): + """Add arguments to parser. + + Args: + prog_name ([type]): program name + + Returns: + parser([ArgumentParser]): + """ + + parser = super(RetryVnfLcmOp, self).get_parser(prog_name) + parser.add_argument( + _VNF_LCM_OP_OCC_ID, + metavar="", + help=_('VNF lifecycle management operation occurrence ID.')) + return parser + + def take_action(self, parsed_args): + """Execute retry_vnf_instance and output comment. + + Args: + parsed_args ([Namespace]): arguments of CLI. + """ + client = self.app.client_manager.tackerclient + result = client.retry_vnf_instance(parsed_args.vnf_lcm_op_occ_id) + if not result: + print((_('Retry request for LCM operation %(id)s has been' + ' accepted') % {'id': parsed_args.vnf_lcm_op_occ_id})) diff --git a/tackerclient/tests/unit/osc/v1/test_vnflcm_op_occs.py b/tackerclient/tests/unit/osc/v1/test_vnflcm_op_occs.py index ce7a55b3..3906a4f8 100644 --- a/tackerclient/tests/unit/osc/v1/test_vnflcm_op_occs.py +++ b/tackerclient/tests/unit/osc/v1/test_vnflcm_op_occs.py @@ -210,3 +210,117 @@ class TestFailVnfLcmOp(TestVnfLcm): verify_list = [('vnf_lcm_op_occ_id', arg_list)] self.assertRaises(base.ParserException, self.check_parser, self.fail_vnf_lcm, arg_list, verify_list) + + +class TestRetryVnfLcmOp(TestVnfLcm): + + def setUp(self): + super(TestRetryVnfLcmOp, self).setUp() + self.retry_vnf_lcm = vnflcm_op_occs.RetryVnfLcmOp( + self.app, self.app_args, cmd_name='vnflcm op retry') + + def test_take_action(self): + """Test of take_action()""" + arg_list = [uuidsentinel.vnf_lcm_op_occ_id] + verify_list = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)] + + # command param + parsed_args = self.check_parser( + self.retry_vnf_lcm, arg_list, verify_list) + url = os.path.join( + self.url, + 'vnflcm/v1/vnf_lcm_op_occs', + uuidsentinel.vnf_lcm_op_occ_id, + 'retry') + + self.requests_mock.register_uri( + 'POST', url, headers=self.header, json={}) + + sys.stdout = buffer = StringIO() + self.retry_vnf_lcm.take_action(parsed_args) + + actual_message = buffer.getvalue().strip() + + expected_message = ( + 'Retry request for LCM operation ' + + uuidsentinel.vnf_lcm_op_occ_id + + ' has been accepted') + + self.assertEqual(expected_message, actual_message) + + def test_take_action_vnf_lcm_op_occ_id_not_found(self): + """Test if vnf-lcm-op-occ-id is not found.""" + arglist = [uuidsentinel.vnf_lcm_op_occ_id] + verifylist = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)] + + # command param + parsed_args = self.check_parser( + self.retry_vnf_lcm, arglist, verifylist) + + url = os.path.join( + self.url, + 'vnflcm/v1/vnf_lcm_op_occs', + uuidsentinel.vnf_lcm_op_occ_id, + 'retry') + + self.requests_mock.register_uri( + 'POST', url, headers=self.header, status_code=404, json={}) + + self.assertRaises(exceptions.TackerClientException, + self.retry_vnf_lcm.take_action, + parsed_args) + + def test_take_action_vnf_lcm_op_occ_state_is_conflict(self): + """Test if vnf-lcm-op-occ state is conflict""" + + arg_list = [uuidsentinel.vnf_lcm_op_occ_id] + verify_list = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)] + + # command param + parsed_args = self.check_parser( + self.retry_vnf_lcm, arg_list, verify_list) + + url = os.path.join( + self.url, + 'vnflcm/v1/vnf_lcm_op_occs', + uuidsentinel.vnf_lcm_op_occ_id, + 'retry') + + self.requests_mock.register_uri( + 'POST', url, headers=self.header, status_code=409, json={}) + + self.assertRaises(exceptions.TackerClientException, + self.retry_vnf_lcm.take_action, + parsed_args) + + def test_take_action_vnf_lcm_op_occ_internal_server_error(self): + """Test if request is internal server error""" + + arg_list = [uuidsentinel.vnf_lcm_op_occ_id] + verify_list = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)] + + # command param + parsed_args = self.check_parser( + self.retry_vnf_lcm, arg_list, verify_list) + + url = os.path.join( + self.url, + 'vnflcm/v1/vnf_lcm_op_occs', + uuidsentinel.vnf_lcm_op_occ_id, + 'retry') + + self.requests_mock.register_uri( + 'POST', url, headers=self.header, status_code=500, json={}) + + self.assertRaises(exceptions.TackerClientException, + self.retry_vnf_lcm.take_action, + parsed_args) + + def test_take_action_vnf_lcm_op_occ_missing_vnf_lcm_op_occ_id_argument( + self): + """Test if vnflcm_op_occ_id is not provided""" + + arg_list = [] + verify_list = [('vnf_lcm_op_occ_id', arg_list)] + self.assertRaises(base.ParserException, self.check_parser, + self.retry_vnf_lcm, arg_list, verify_list) diff --git a/tackerclient/v1_0/client.py b/tackerclient/v1_0/client.py index e93236cb..76745c81 100644 --- a/tackerclient/v1_0/client.py +++ b/tackerclient/v1_0/client.py @@ -936,6 +936,10 @@ class VnfLCMClient(ClientBase): return self.post((self.vnf_instance_path + "/change_ext_conn") % vnf_id, body=body) + @APIParamsCall + def retry_vnf_instance(self, occ_id): + return self.post((self.vnf_lcm_op_occs_path + "/retry") % occ_id) + class Client(object): """Unified interface to interact with multiple applications of tacker service. @@ -1224,6 +1228,9 @@ class Client(object): def fail_vnf_instance(self, occ_id): return self.vnf_lcm_client.fail_vnf_instance(occ_id) + def retry_vnf_instance(self, occ_id): + return self.vnf_lcm_client.retry_vnf_instance(occ_id) + def update_vnf_package(self, vnf_package, body): return self.vnf_package_client.update_vnf_package(vnf_package, body)