Support of Cancel VNF command in openstackclient

Add ``openstack vnflcm op cancel`` to python-tackerclient. This
command can execute Cancel operation [1]. This API makes a transition a
LCM that is stopped in the PROCESSING state to the FAILED_TEMP state.

[1]
https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/003/03.03.01_60/gs_NFV-SOL003v030301p.pdf

Implements: blueprint support-cancel
Change-Id: Id957f6a7992f9fd5b04806aff3d76680d8d63a8d
Signed-off-by: Hiromu Asahina <hiromu.asahina.az@hco.ntt.co.jp>
This commit is contained in:
Hiromu Asahina 2021-11-05 00:13:55 +09:00
parent b5603cc45c
commit 6834454309
4 changed files with 115 additions and 0 deletions

View File

@ -96,6 +96,7 @@ openstack.tackerclient.v1 =
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_cancel = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:CancelVnfLcmOp
vnflcm_op_fail = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:FailVnfLcmOp
vnflcm_op_retry = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:RetryVnfLcmOp
vnflcm_op_list = tackerclient.osc.v1.vnflcm.vnflcm_op_occs:ListVnfLcmOp

View File

@ -101,6 +101,47 @@ class RollbackVnfLcmOp(command.Command):
' accepted') % {'id': parsed_args.vnf_lcm_op_occ_id}))
class CancelVnfLcmOp(command.ShowOne):
_description = _("Cancel VNF Instance")
def get_parser(self, prog_name):
"""Add arguments to parser.
Args:
prog_name ([type]): program name
Returns:
parser([ArgumentParser]):
"""
parser = super(CancelVnfLcmOp, self).get_parser(prog_name)
parser.add_argument(
_VNF_LCM_OP_OCC_ID,
metavar="<vnf-lcm-op-occ-id>",
help=_('VNF lifecycle management operation occurrence ID.'))
parser.add_argument(
"--cancel-mode",
default='GRACEFUL',
metavar="<cancel-mode>",
choices=['GRACEFUL', 'FORCEFUL'],
help=_("Cancel mode can be 'GRACEFUL' or 'FORCEFUL'. "
"Default is 'GRACEFUL'"))
return parser
def take_action(self, parsed_args):
"""Execute cancel_vnf_instance and output comment.
Args:
parsed_args ([Namespace]): arguments of CLI.
"""
client = self.app.client_manager.tackerclient
result = client.cancel_vnf_instance(
parsed_args.vnf_lcm_op_occ_id,
{'cancelMode': parsed_args.cancel_mode})
if not result:
print((_('Cancel request for LCM operation %(id)s has been'
' accepted') % {'id': parsed_args.vnf_lcm_op_occ_id}))
class FailVnfLcmOp(command.ShowOne):
_description = _("Fail VNF Instance")

View File

@ -14,6 +14,7 @@ from io import StringIO
import os
import sys
import ddt
from oslo_utils.fixture import uuidsentinel
from unittest import mock
@ -57,6 +58,70 @@ class TestVnfLcm(base.FixturedTestCase):
self.app.client_manager.tackerclient = self.client_manager
@ddt.ddt
class TestCancelVnfLcmOp(TestVnfLcm):
def setUp(self):
super(TestCancelVnfLcmOp, self).setUp()
self.cancel_vnf_lcm = vnflcm_op_occs.CancelVnfLcmOp(
self.app, self.app_args, cmd_name='vnflcm op cancel')
@ddt.data('GRACEFUL', 'FORCEFUL')
def test_take_action(self, cancel_mode):
"""take_action normal system test"""
arglist = ['--cancel-mode', cancel_mode,
uuidsentinel.vnf_lcm_op_occ_id]
verifylist = [('cancel_mode', cancel_mode),
('vnf_lcm_op_occ_id', uuidsentinel.vnf_lcm_op_occ_id)]
parsed_args = self.check_parser(
self.cancel_vnf_lcm, arglist, verifylist)
url = os.path.join(
self.url,
'vnflcm/v1/vnf_lcm_op_occs',
uuidsentinel.vnf_lcm_op_occ_id,
'cancel')
self.requests_mock.register_uri(
'POST', url, headers=self.header, json={})
sys.stdout = buffer = StringIO()
self.cancel_vnf_lcm.take_action(parsed_args)
actual_message = buffer.getvalue().strip()
expected_message = (
'Cancel request for LCM operation ' +
uuidsentinel.vnf_lcm_op_occ_id +
' has been accepted')
self.assertEqual(expected_message, actual_message)
def test_terminate_no_options(self):
self.assertRaises(base.ParserException, self.check_parser,
self.cancel_vnf_lcm, [], [])
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.cancel_vnf_lcm, arglist, verifylist)
url = os.path.join(
self.url,
'vnflcm/v1/vnf_lcm_op_occs',
uuidsentinel.vnf_lcm_op_occ_id,
'cancel')
self.requests_mock.register_uri(
'POST', url, headers=self.header, status_code=404, json={})
self.assertRaises(exceptions.TackerClientException,
self.cancel_vnf_lcm.take_action,
parsed_args)
class TestRollbackVnfLcmOp(TestVnfLcm):
def setUp(self):

View File

@ -928,6 +928,11 @@ class VnfLCMClient(ClientBase):
def rollback_vnf_instance(self, occ_id):
return self.post((self.vnf_lcm_op_occs_path + "/rollback") % occ_id)
@APIParamsCall
def cancel_vnf_instance(self, occ_id, body):
return self.post((self.vnf_lcm_op_occs_path + "/cancel") % occ_id,
body=body)
@APIParamsCall
def fail_vnf_instance(self, occ_id):
return self.post((self.vnf_lcm_op_occs_path + "/fail") % occ_id)
@ -1236,6 +1241,9 @@ class Client(object):
def rollback_vnf_instance(self, occ_id):
return self.vnf_lcm_client.rollback_vnf_instance(occ_id)
def cancel_vnf_instance(self, occ_id, body):
return self.vnf_lcm_client.cancel_vnf_instance(occ_id, body)
def fail_vnf_instance(self, occ_id):
return self.vnf_lcm_client.fail_vnf_instance(occ_id)