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
|
Name: Files/kubernetes/token-review.yaml
|
||||||
Content-Type: test-data
|
Content-Type: test-data
|
||||||
Algorithm: SHA-256
|
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_serialization import jsonutils
|
||||||
from oslo_utils import uuidutils
|
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 fields
|
||||||
|
from tacker.objects import vnf_lcm_op_occs
|
||||||
from tacker.tests.functional import base
|
from tacker.tests.functional import base
|
||||||
from tacker.tests import utils
|
from tacker.tests import utils
|
||||||
|
|
||||||
@ -112,6 +120,8 @@ class VnfLcmTest(base.BaseTackerTest):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(VnfLcmTest, self).setUp()
|
super(VnfLcmTest, self).setUp()
|
||||||
self.base_url = "/vnflcm/v1/vnf_instances"
|
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()
|
vim_list = self.client.list_vims()
|
||||||
if not vim_list:
|
if not vim_list:
|
||||||
@ -1045,3 +1055,92 @@ class VnfLcmTest(base.BaseTackerTest):
|
|||||||
|
|
||||||
self._terminate_vnf_instance(vnf_instance['id'], terminate_req_body)
|
self._terminate_vnf_instance(vnf_instance['id'], terminate_req_body)
|
||||||
self._delete_vnf_instance(vnf_instance['id'])
|
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
|
access_info = vim_connection_info.access_info
|
||||||
self._vnf_manager.invoke(vim_connection_info.vim_type,
|
self._vnf_manager.invoke(vim_connection_info.vim_type,
|
||||||
'delete', plugin=self, context=context,
|
'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,
|
self._vnf_manager.invoke(vim_connection_info.vim_type,
|
||||||
'delete_wait', plugin=self, context=context,
|
'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
|
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.common import utils
|
||||||
from tacker.extensions import vnfm
|
from tacker.extensions import vnfm
|
||||||
from tacker import objects
|
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 as vnf_package_obj
|
||||||
from tacker.objects import vnf_package_vnfd as vnfd_obj
|
from tacker.objects import vnf_package_vnfd as vnfd_obj
|
||||||
from tacker.objects import vnf_resources as vnf_resource_obj
|
from tacker.objects import vnf_resources as vnf_resource_obj
|
||||||
@ -1511,6 +1512,7 @@ class Kubernetes(abstract_driver.VnfAbstractDriver,
|
|||||||
k8s_objs = transformer.\
|
k8s_objs = transformer.\
|
||||||
get_k8s_objs_from_yaml(target_k8s_files, vnf_package_path)
|
get_k8s_objs_from_yaml(target_k8s_files, vnf_package_path)
|
||||||
k8s_objs = transformer.deploy_k8s(k8s_objs)
|
k8s_objs = transformer.deploy_k8s(k8s_objs)
|
||||||
|
vnfd_dict['current_error_point'] = EP.POST_VIM_CONTROL
|
||||||
k8s_objs = self.create_wait_k8s(
|
k8s_objs = self.create_wait_k8s(
|
||||||
k8s_objs, k8s_client_dict, vnf_instance)
|
k8s_objs, k8s_client_dict, vnf_instance)
|
||||||
for k8s_obj in k8s_objs:
|
for k8s_obj in k8s_objs:
|
||||||
|
Loading…
Reference in New Issue
Block a user