diff --git a/setup.cfg b/setup.cfg index 7c6a8387..273a58a5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -94,3 +94,4 @@ 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_op_rollback = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:RollbackVnfLcmOp diff --git a/tackerclient/osc/v1/vnflcm/vnflcm_op_occs.py b/tackerclient/osc/v1/vnflcm/vnflcm_op_occs.py new file mode 100644 index 00000000..a75e1c49 --- /dev/null +++ b/tackerclient/osc/v1/vnflcm/vnflcm_op_occs.py @@ -0,0 +1,45 @@ +# 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.i18n import _ + + +class RollbackVnfLcmOp(command.Command): + def get_parser(self, prog_name): + """Add arguments to parser. + + Args: + prog_name ([type]): program name + + Returns: + parser([ArgumentParser]): + """ + parser = super(RollbackVnfLcmOp, 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 rollback_vnf_instance and output comment. + + Args: + parsed_args ([Namespace]): arguments of CLI. + """ + client = self.app.client_manager.tackerclient + result = client.rollback_vnf_instance(parsed_args.vnf_lcm_op_occ_id) + if not result: + print((_('Rollback 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 new file mode 100644 index 00000000..bd20819c --- /dev/null +++ b/tackerclient/tests/unit/osc/v1/test_vnflcm_op_occs.py @@ -0,0 +1,94 @@ +# 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 io import StringIO +import os +import sys + +from oslo_utils.fixture import uuidsentinel +from unittest import mock + +from tackerclient.common import exceptions +from tackerclient.osc.v1.vnflcm import vnflcm_op_occs +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 + + +class TestRollbackVnfLcmOp(TestVnfLcm): + + def setUp(self): + super(TestRollbackVnfLcmOp, self).setUp() + self.rollback_vnf_lcm = vnflcm_op_occs.RollbackVnfLcmOp( + self.app, self.app_args, cmd_name='vnflcm op rollback') + + def test_take_action(self): + """take_action normal system test""" + + arglist = [uuidsentinel.vnf_lcm_op_occ_id] + verifylist = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)] + + parsed_args = self.check_parser( + self.rollback_vnf_lcm, arglist, verifylist) + url = os.path.join( + self.url, + 'vnflcm/v1/vnf_lcm_op_occs', + uuidsentinel.vnf_lcm_op_occ_id, + 'rollback') + + self.requests_mock.register_uri( + 'POST', url, headers=self.header, json={}) + + sys.stdout = buffer = StringIO() + self.rollback_vnf_lcm.take_action(parsed_args) + + actual_message = buffer.getvalue().strip() + + expected_message = ( + 'Rollback 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): + """take_action abnomaly system test""" + + arglist = [uuidsentinel.vnf_lcm_op_occ_id] + verifylist = [('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)] + + parsed_args = self.check_parser( + self.rollback_vnf_lcm, arglist, verifylist) + + url = os.path.join( + self.url, + 'vnflcm/v1/vnf_lcm_op_occs', + uuidsentinel.vnf_lcm_op_occ_id, + 'rollback') + self.requests_mock.register_uri( + 'POST', url, headers=self.header, status_code=404, json={}) + + self.assertRaises(exceptions.TackerClientException, + self.rollback_vnf_lcm.take_action, + parsed_args) diff --git a/tackerclient/v1_0/client.py b/tackerclient/v1_0/client.py index e1777cf0..28bc68ca 100644 --- a/tackerclient/v1_0/client.py +++ b/tackerclient/v1_0/client.py @@ -868,6 +868,7 @@ class VnfLCMClient(ClientBase): vnf_instances_path = '/vnflcm/v1/vnf_instances' vnf_instance_path = '/vnflcm/v1/vnf_instances/%s' + vnf_lcm_op_occs_path = '/vnflcm/v1/vnf_lcm_op_occs/%s' def build_action(self, action): return action @@ -914,6 +915,10 @@ class VnfLCMClient(ClientBase): return self.post((self.vnf_instance_path + "/scale") % vnf_id, body=body) + @APIParamsCall + def rollback_vnf_instance(self, occ_id): + return self.post((self.vnf_lcm_op_occs_path + "/rollback") % occ_id) + class Client(object): """Unified interface to interact with multiple applications of tacker service. @@ -1193,6 +1198,9 @@ class Client(object): def update_vnf_instance(self, vnf_id, body): return self.vnf_lcm_client.update_vnf_instance(vnf_id, body) + def rollback_vnf_instance(self, occ_id): + return self.vnf_lcm_client.rollback_vnf_instance(occ_id) + def update_vnf_package(self, vnf_package, body): return self.vnf_package_client.update_vnf_package(vnf_package, body)