Merge "Fix cnf rollback after instantiation failure"
This commit is contained in:
commit
28df9a4eae
@ -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
|
@ -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
|
||||
|
@ -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'])
|
||||
|
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user