Merge "Fix cnf rollback after instantiation failure"

This commit is contained in:
Zuul 2021-09-15 10:36:48 +00:00 committed by Gerrit Code Review
commit 28df9a4eae
5 changed files with 147 additions and 3 deletions

View File

@ -0,0 +1,36 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: vdu2-fail
namespace: default
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes:
- ReadWriteOnce
storageClassName: "curry-sc-local-fail"
resources:
requests:
storage: 1Gi

View File

@ -136,4 +136,9 @@ Hash: ef937e9c90c1cb6093092ba2043c11e353d572736b04f798a49b785049fec552
Name: Files/kubernetes/token-review.yaml
Content-Type: test-data
Algorithm: SHA-256
Hash: 468d9d53a3125c5850c6473d324c94f00b91a1e3536d1a62c7c7eb80fd7aa6d2
Hash: 468d9d53a3125c5850c6473d324c94f00b91a1e3536d1a62c7c7eb80fd7aa6d2
Name: Files/kubernetes/statefulset_fail.yaml
Content-Type: test-data
Algorithm: SHA-256
Hash: 71a99017964b8ce1dfbbade92f3cdf42f1e5b774c6e7edb7aa83c5eee42e5d5e

View File

@ -20,8 +20,16 @@ import unittest
from oslo_serialization import jsonutils
from oslo_utils import uuidutils
from sqlalchemy import desc
from sqlalchemy.orm import joinedload
from tacker.common import exceptions
from tacker import context
from tacker.db import api as db_api
from tacker.db.db_sqlalchemy import api
from tacker.db.db_sqlalchemy import models
from tacker.objects import fields
from tacker.objects import vnf_lcm_op_occs
from tacker.tests.functional import base
from tacker.tests import utils
@ -112,6 +120,8 @@ class VnfLcmTest(base.BaseTackerTest):
def setUp(self):
super(VnfLcmTest, self).setUp()
self.base_url = "/vnflcm/v1/vnf_instances"
self.base_vnf_lcm_op_occs_url = "/vnflcm/v1/vnf_lcm_op_occs"
self.context = context.get_admin_context()
vim_list = self.client.list_vims()
if not vim_list:
@ -1045,3 +1055,92 @@ class VnfLcmTest(base.BaseTackerTest):
self._terminate_vnf_instance(vnf_instance['id'], terminate_req_body)
self._delete_vnf_instance(vnf_instance['id'])
@db_api.context_manager.reader
def _vnf_notify_get_by_id(self, context, vnf_instance_id,
columns_to_join=None):
query = api.model_query(
context, models.VnfLcmOpOccs,
read_deleted="no", project_only=True).filter_by(
vnf_instance_id=vnf_instance_id).order_by(
desc("created_at"))
if columns_to_join:
for column in columns_to_join:
query = query.options(joinedload(column))
db_vnflcm_op_occ = query.first()
if not db_vnflcm_op_occ:
raise exceptions.VnfInstanceNotFound(id=vnf_instance_id)
vnflcm_op_occ = vnf_lcm_op_occs.VnfLcmOpOcc.obj_from_db_obj(
context, db_vnflcm_op_occ)
return vnflcm_op_occ
def _wait_vnflcm_op_occs(
self, context, vnf_instance_id,
operation_state='COMPLETED'):
timeout = VNF_INSTANTIATE_TIMEOUT
start_time = int(time.time())
while True:
vnflcm_op_occ = self._vnf_notify_get_by_id(
context, vnf_instance_id)
if vnflcm_op_occ.operation_state == operation_state:
break
if ((int(time.time()) - start_time) > timeout):
raise Exception("Failed to wait instantiate instance")
time.sleep(RETRY_WAIT_TIME)
def _instantiate_vnf_instance_wait_fail(self, id, request_body):
url = os.path.join(self.base_url, id, "instantiate")
resp, body = self.http_client.do_request(
url, "POST", body=jsonutils.dumps(request_body))
self.assertEqual(202, resp.status_code)
# wait vnflcm_op_occs.operation_state become FAILED_TEMP
self._wait_vnflcm_op_occs(self.context, id, "FAILED_TEMP")
def _rollback_vnf_instance(self, vnf_lcm_op_occ_id):
url = os.path.join(
self.base_vnf_lcm_op_occs_url, vnf_lcm_op_occ_id, "rollback")
# generate body
resp, body = self.http_client.do_request(url, "POST")
self.assertEqual(202, resp.status_code)
def test_rollback_cnf_after_instantiate_fail(self):
vnf_instance_name = "vnf_rollback_cnf_after_instantiate_fail"
vnf_instance_description = "vnf rollback cnf after instantiate fail"
resp, vnf_instance = self._create_vnf_instance(
self.vnfd_id_resource,
vnf_instance_name=vnf_instance_name,
vnf_instance_description=vnf_instance_description)
self.assertIsNotNone(vnf_instance['id'])
self.assertEqual(201, resp.status_code)
additional_param = {
"lcm-kubernetes-def-files": [
"Files/kubernetes/statefulset_fail.yaml",
]
}
request_body = self._instantiate_vnf_instance_request(
"simple", vim_id=self.vim_id, additional_param=additional_param)
self._instantiate_vnf_instance_wait_fail(
vnf_instance['id'], request_body)
# get vnflcm_op_occ id for rollback
vnflcm_op_occ = self._vnf_notify_get_by_id(
self.context, vnf_instance['id'])
vnf_lcm_op_occ_id = vnflcm_op_occ.id
# rollback operation
self._rollback_vnf_instance(vnf_lcm_op_occ_id)
# wait vnflcm_op_occs.operation_state become ROLLED_BACK
self._wait_vnflcm_op_occs(
self.context, vnf_instance['id'], "ROLLED_BACK")
self._delete_vnf_instance(vnf_instance['id'])

View File

@ -1600,11 +1600,13 @@ class VnfLcmDriver(abstract_driver.VnfInstanceAbstractDriver):
access_info = vim_connection_info.access_info
self._vnf_manager.invoke(vim_connection_info.vim_type,
'delete', plugin=self, context=context,
vnf_id=instance_id, auth_attr=access_info)
vnf_id=instance_id, auth_attr=access_info,
vnf_instance=vnf_instance)
self._vnf_manager.invoke(vim_connection_info.vim_type,
'delete_wait', plugin=self, context=context,
vnf_id=instance_id, auth_attr=access_info)
vnf_id=instance_id, auth_attr=access_info,
vnf_instance=vnf_instance)
vnf_lcm_op_occs.error_point = EP.PRE_VIM_CONTROL

View File

@ -33,6 +33,7 @@ from tacker.common import log
from tacker.common import utils
from tacker.extensions import vnfm
from tacker import objects
from tacker.objects.fields import ErrorPoint as EP
from tacker.objects import vnf_package as vnf_package_obj
from tacker.objects import vnf_package_vnfd as vnfd_obj
from tacker.objects import vnf_resources as vnf_resource_obj
@ -1511,6 +1512,7 @@ class Kubernetes(abstract_driver.VnfAbstractDriver,
k8s_objs = transformer.\
get_k8s_objs_from_yaml(target_k8s_files, vnf_package_path)
k8s_objs = transformer.deploy_k8s(k8s_objs)
vnfd_dict['current_error_point'] = EP.POST_VIM_CONTROL
k8s_objs = self.create_wait_k8s(
k8s_objs, k8s_client_dict, vnf_instance)
for k8s_obj in k8s_objs: