Merge "Fix SSL certificate setting error"
This commit is contained in:
commit
7eeba89aea
|
@ -522,6 +522,7 @@
|
|||
controller_worker:
|
||||
amp_active_retries: 9999
|
||||
kuryr_k8s_api_url: "https://{{ hostvars['controller-k8s']['nodepool']['private_ipv4'] }}:6443"
|
||||
k8s_ssl_verify: true
|
||||
helm_version: "3.5.4"
|
||||
test_matrix_configs: [neutron]
|
||||
zuul_work_dir: src/opendev.org/openstack/tacker
|
||||
|
|
|
@ -97,6 +97,14 @@
|
|||
become: yes
|
||||
become_user: stack
|
||||
|
||||
- name: Fetch k8s's CA Certificate
|
||||
fetch:
|
||||
src: "/etc/kubernetes/pki/ca.crt"
|
||||
dest: "/tmp/"
|
||||
flat: true
|
||||
when:
|
||||
- k8s_ssl_verify
|
||||
|
||||
when:
|
||||
- inventory_hostname == 'controller-k8s'
|
||||
- kuryr_k8s_api_url is defined
|
||||
|
@ -171,6 +179,32 @@
|
|||
when:
|
||||
- p.stat.exists
|
||||
|
||||
- name: Copy k8s's CA Certificate to tacker
|
||||
copy:
|
||||
src: "/tmp/ca.crt"
|
||||
dest: "/tmp/"
|
||||
when:
|
||||
- p.stat.exists
|
||||
- k8s_ssl_verify
|
||||
|
||||
- name: Get k8s's CA Certificate
|
||||
command: cat "/tmp/ca.crt"
|
||||
register: ssl_ca_cert
|
||||
when:
|
||||
- p.stat.exists
|
||||
- k8s_ssl_verify
|
||||
|
||||
- name: Replace k8s CA Certificate in local-k8s-vim.yaml
|
||||
replace:
|
||||
path: "{{ item }}"
|
||||
regexp: "ssl_ca_cert: .*$"
|
||||
replace: "ssl_ca_cert: '{{ ssl_ca_cert.stdout }}'"
|
||||
with_items:
|
||||
- "{{ zuul_work_dir }}/tacker/tests/etc/samples/local-k8s-vim.yaml"
|
||||
when:
|
||||
- p.stat.exists
|
||||
- k8s_ssl_verify
|
||||
|
||||
- name: Replace the config file path in the test-setup-k8s-vim.sh
|
||||
replace:
|
||||
path: "{{ zuul_work_dir }}/tools/test-setup-k8s-vim.sh"
|
||||
|
|
|
@ -131,6 +131,23 @@ keyvalue_pairs = {
|
|||
'additionalProperties': False
|
||||
}
|
||||
|
||||
keyvalue_pairs_no_length_limit = {
|
||||
'type': 'object',
|
||||
'patternProperties': {
|
||||
'^[a-zA-Z0-9-_:. /]+$': {
|
||||
'anyOf': [
|
||||
{'type': 'array'},
|
||||
{'type': 'string'},
|
||||
{'type': 'object'},
|
||||
{'type': 'null'},
|
||||
{'type': 'boolean'},
|
||||
{'type': 'number'}
|
||||
]
|
||||
}
|
||||
},
|
||||
'additionalProperties': False
|
||||
}
|
||||
|
||||
description = {
|
||||
'type': 'string', 'minLength': 0, 'maxLength': 1024,
|
||||
'pattern': valid_description_regex,
|
||||
|
|
|
@ -61,9 +61,9 @@ VimConnectionInfo = {
|
|||
'properties': {
|
||||
'vimId': {'type': 'string', 'maxLength': 255},
|
||||
'vimType': {'type': 'string', 'minLength': 1, 'maxLength': 255},
|
||||
'interfaceInfo': parameter_types.keyvalue_pairs,
|
||||
'accessInfo': parameter_types.keyvalue_pairs,
|
||||
'extra': parameter_types.keyvalue_pairs,
|
||||
'interfaceInfo': parameter_types.keyvalue_pairs_no_length_limit,
|
||||
'accessInfo': parameter_types.keyvalue_pairs_no_length_limit,
|
||||
'extra': parameter_types.keyvalue_pairs_no_length_limit,
|
||||
},
|
||||
'required': ['vimType'],
|
||||
'additionalProperties': True,
|
||||
|
|
|
@ -63,17 +63,26 @@ class Kubernetes(object):
|
|||
|
||||
# deploy k8s resources with sorted resources
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
k8s_client = kubernetes_utils.KubernetesClient(vim_info)
|
||||
created_k8s_reses = k8s_client.create_k8s_resource(
|
||||
sorted_k8s_reses, namespace)
|
||||
# This is Context Manager for creation and deletion
|
||||
# of CA certificate temp file
|
||||
with kubernetes_utils.CaCertFileContextManager(
|
||||
vim_info.interfaceInfo.get('ssl_ca_cert')) as ca_cert_cm:
|
||||
|
||||
# wait k8s resource create complete
|
||||
k8s_client.wait_k8s_res_create(created_k8s_reses)
|
||||
# add an item ca_cert_file:file_path into vim_info.interfaceInfo,
|
||||
# and will be deleted in KubernetesClient
|
||||
vim_info.interfaceInfo['ca_cert_file'] = ca_cert_cm.file_path
|
||||
|
||||
# make instantiated info
|
||||
all_pods = k8s_client.list_namespaced_pods(namespace)
|
||||
self._make_cnf_instantiated_info(
|
||||
req, inst, vnfd, namespace, created_k8s_reses, all_pods)
|
||||
k8s_client = kubernetes_utils.KubernetesClient(vim_info)
|
||||
created_k8s_reses = k8s_client.create_k8s_resource(
|
||||
sorted_k8s_reses, namespace)
|
||||
|
||||
# wait k8s resource create complete
|
||||
k8s_client.wait_k8s_res_create(created_k8s_reses)
|
||||
|
||||
# make instantiated info
|
||||
all_pods = k8s_client.list_namespaced_pods(namespace)
|
||||
self._make_cnf_instantiated_info(
|
||||
req, inst, vnfd, namespace, created_k8s_reses, all_pods)
|
||||
|
||||
def terminate(self, req, inst, grant_req, grant, vnfd):
|
||||
target_k8s_files = inst.metadata.get('lcm-kubernetes-def-files')
|
||||
|
@ -88,11 +97,20 @@ class Kubernetes(object):
|
|||
|
||||
# delete k8s resources with sorted resources
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
k8s_client = kubernetes_utils.KubernetesClient(vim_info)
|
||||
k8s_client.delete_k8s_resource(req, sorted_k8s_reses, namespace)
|
||||
# This is Context Manager for creation and deletion
|
||||
# of CA certificate temp file
|
||||
with kubernetes_utils.CaCertFileContextManager(
|
||||
vim_info.interfaceInfo.get('ssl_ca_cert')) as ca_cert_cm:
|
||||
|
||||
# wait k8s resource delete complete
|
||||
k8s_client.wait_k8s_res_delete(sorted_k8s_reses, namespace)
|
||||
# add an item ca_cert_file:file_path into vim_info.interfaceInfo,
|
||||
# and will be deleted in KubernetesClient
|
||||
vim_info.interfaceInfo['ca_cert_file'] = ca_cert_cm.file_path
|
||||
|
||||
k8s_client = kubernetes_utils.KubernetesClient(vim_info)
|
||||
k8s_client.delete_k8s_resource(req, sorted_k8s_reses, namespace)
|
||||
|
||||
# wait k8s resource delete complete
|
||||
k8s_client.wait_k8s_res_delete(sorted_k8s_reses, namespace)
|
||||
|
||||
def change_vnfpkg(self, req, inst, grant_req, grant, vnfd):
|
||||
if req.additionalParams.get('upgrade_type') == 'RollingUpdate':
|
||||
|
@ -103,43 +121,56 @@ class Kubernetes(object):
|
|||
|
||||
# check deployment exists in kubernetes
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
k8s_client = kubernetes_utils.KubernetesClient(vim_info)
|
||||
k8s_client.check_deployment_exist(deployment_names, namespace)
|
||||
# This is Context Manager for creation and deletion
|
||||
# of CA certificate temp file
|
||||
with kubernetes_utils.CaCertFileContextManager(
|
||||
vim_info.interfaceInfo.get('ssl_ca_cert')) as ca_cert_cm:
|
||||
|
||||
# get new deployment body
|
||||
new_deploy_reses = kubernetes_utils.get_new_deployment_body(
|
||||
req, inst, vnfd, deployment_names, operation='CHANGE_VNFPKG')
|
||||
# add an item ca_cert_file:file_path
|
||||
# into vim_info.interfaceInfo,
|
||||
# and will be deleted in KubernetesClient
|
||||
vim_info.interfaceInfo['ca_cert_file'] = ca_cert_cm.file_path
|
||||
|
||||
# apply new deployment
|
||||
k8s_client.update_k8s_resource(new_deploy_reses, namespace)
|
||||
k8s_client = kubernetes_utils.KubernetesClient(vim_info)
|
||||
k8s_client.check_deployment_exist(deployment_names, namespace)
|
||||
|
||||
# wait k8s resource update complete
|
||||
old_pods_names = [vnfc.computeResource.resourceId for vnfc in
|
||||
inst.instantiatedVnfInfo.vnfcResourceInfo]
|
||||
try:
|
||||
k8s_client.wait_k8s_res_update(
|
||||
new_deploy_reses, namespace, old_pods_names)
|
||||
except sol_ex.UpdateK8SResourceFailed as ex:
|
||||
# get new deployment body
|
||||
new_deploy_reses = kubernetes_utils.get_new_deployment_body(
|
||||
req, inst, vnfd, deployment_names,
|
||||
operation='CHANGE_VNFPKG')
|
||||
|
||||
# apply new deployment
|
||||
k8s_client.update_k8s_resource(new_deploy_reses, namespace)
|
||||
|
||||
# wait k8s resource update complete
|
||||
old_pods_names = [vnfc.computeResource.resourceId for vnfc in
|
||||
inst.instantiatedVnfInfo.vnfcResourceInfo]
|
||||
try:
|
||||
k8s_client.wait_k8s_res_update(
|
||||
new_deploy_reses, namespace, old_pods_names)
|
||||
except sol_ex.UpdateK8SResourceFailed as ex:
|
||||
self._update_cnf_instantiated_info(
|
||||
inst, deployment_names,
|
||||
k8s_client.list_namespaced_pods(
|
||||
namespace=namespace))
|
||||
raise ex
|
||||
|
||||
# execute coordinate vnf script
|
||||
try:
|
||||
self._execute_coordinate_vnf_script(
|
||||
req, inst, grant_req, grant, vnfd, 'CHANGE_VNFPKG',
|
||||
namespace, new_deploy_reses)
|
||||
except sol_ex.CoordinateVNFExecutionFailed as ex:
|
||||
self._update_cnf_instantiated_info(
|
||||
inst, deployment_names,
|
||||
k8s_client.list_namespaced_pods(
|
||||
namespace=namespace))
|
||||
raise ex
|
||||
|
||||
# update cnf instantiated info
|
||||
all_pods = k8s_client.list_namespaced_pods(namespace)
|
||||
self._update_cnf_instantiated_info(
|
||||
inst, deployment_names, k8s_client.list_namespaced_pods(
|
||||
namespace=namespace))
|
||||
raise ex
|
||||
|
||||
# execute coordinate vnf script
|
||||
try:
|
||||
self._execute_coordinate_vnf_script(
|
||||
req, inst, grant_req, grant, vnfd, 'CHANGE_VNFPKG',
|
||||
namespace, new_deploy_reses)
|
||||
except sol_ex.CoordinateVNFExecutionFailed as ex:
|
||||
self._update_cnf_instantiated_info(
|
||||
inst, deployment_names, k8s_client.list_namespaced_pods(
|
||||
namespace=namespace))
|
||||
raise ex
|
||||
|
||||
# update cnf instantiated info
|
||||
all_pods = k8s_client.list_namespaced_pods(namespace)
|
||||
self._update_cnf_instantiated_info(
|
||||
inst, deployment_names, all_pods)
|
||||
inst, deployment_names, all_pods)
|
||||
|
||||
else:
|
||||
# TODO(YiFeng): Blue-Green type will be supported in next version.
|
||||
|
@ -169,31 +200,41 @@ class Kubernetes(object):
|
|||
|
||||
# apply old deployment
|
||||
vim_info = inst_utils.select_vim_info(inst.vimConnectionInfo)
|
||||
k8s_client = kubernetes_utils.KubernetesClient(vim_info)
|
||||
k8s_client.update_k8s_resource(old_deploy_reses, namespace)
|
||||
# This is Context Manager for creation and deletion
|
||||
# of CA certificate temp file
|
||||
with kubernetes_utils.CaCertFileContextManager(
|
||||
vim_info.interfaceInfo.get('ssl_ca_cert')) as ca_cert_cm:
|
||||
|
||||
# wait k8s resource update complete
|
||||
old_pods_names = [vnfc.computeResource.resourceId for vnfc in
|
||||
inst.instantiatedVnfInfo.vnfcResourceInfo]
|
||||
try:
|
||||
k8s_client.wait_k8s_res_update(
|
||||
old_deploy_reses, namespace, old_pods_names)
|
||||
except sol_ex.UpdateK8SResourceFailed as ex:
|
||||
raise ex
|
||||
# add an item ca_cert_file:file_path
|
||||
# into vim_info.interfaceInfo,
|
||||
# and will be deleted in KubernetesClient
|
||||
vim_info.interfaceInfo['ca_cert_file'] = ca_cert_cm.file_path
|
||||
|
||||
# execute coordinate vnf script
|
||||
try:
|
||||
self._execute_coordinate_vnf_script(
|
||||
req, inst, grant_req, grant, vnfd,
|
||||
'CHANGE_VNFPKG_ROLLBACK',
|
||||
namespace, old_deploy_reses)
|
||||
except sol_ex.CoordinateVNFExecutionFailed as ex:
|
||||
raise ex
|
||||
k8s_client = kubernetes_utils.KubernetesClient(vim_info)
|
||||
k8s_client.update_k8s_resource(old_deploy_reses, namespace)
|
||||
|
||||
# update cnf instantiated info
|
||||
all_pods = k8s_client.list_namespaced_pods(namespace)
|
||||
self._update_cnf_instantiated_info(
|
||||
inst, deployment_names, all_pods)
|
||||
# wait k8s resource update complete
|
||||
old_pods_names = [vnfc.computeResource.resourceId for vnfc in
|
||||
inst.instantiatedVnfInfo.vnfcResourceInfo]
|
||||
try:
|
||||
k8s_client.wait_k8s_res_update(
|
||||
old_deploy_reses, namespace, old_pods_names)
|
||||
except sol_ex.UpdateK8SResourceFailed as ex:
|
||||
raise ex
|
||||
|
||||
# execute coordinate vnf script
|
||||
try:
|
||||
self._execute_coordinate_vnf_script(
|
||||
req, inst, grant_req, grant, vnfd,
|
||||
'CHANGE_VNFPKG_ROLLBACK',
|
||||
namespace, old_deploy_reses)
|
||||
except sol_ex.CoordinateVNFExecutionFailed as ex:
|
||||
raise ex
|
||||
|
||||
# update cnf instantiated info
|
||||
all_pods = k8s_client.list_namespaced_pods(namespace)
|
||||
self._update_cnf_instantiated_info(
|
||||
inst, deployment_names, all_pods)
|
||||
|
||||
else:
|
||||
# TODO(YiFeng): Blue-Green type will be supported in next version.
|
||||
|
|
|
@ -17,6 +17,7 @@ import copy
|
|||
import ipaddress
|
||||
import os
|
||||
import re
|
||||
import tempfile
|
||||
import time
|
||||
from urllib.parse import urlparse
|
||||
import urllib.request as urllib2
|
||||
|
@ -583,6 +584,9 @@ def init_k8s_api_client(vim_info):
|
|||
k8s_config = client.Configuration()
|
||||
k8s_config.host = vim_info.interfaceInfo['endpoint']
|
||||
|
||||
ca_cert_file = (vim_info.interfaceInfo.pop('ca_cert_file')
|
||||
if 'ca_cert_file' in vim_info.interfaceInfo else None)
|
||||
|
||||
if ('username' in vim_info.accessInfo and 'password'
|
||||
in vim_info.accessInfo and vim_info.accessInfo.get(
|
||||
'password') is not None):
|
||||
|
@ -596,8 +600,8 @@ def init_k8s_api_client(vim_info):
|
|||
k8s_config.api_key['authorization'] = vim_info.accessInfo[
|
||||
'bearer_token']
|
||||
|
||||
if 'ssl_ca_cert' in vim_info.accessInfo:
|
||||
k8s_config.ssl_ca_cert = vim_info.accessInfo['ssl_ca_cert']
|
||||
if 'ssl_ca_cert' in vim_info.interfaceInfo and ca_cert_file:
|
||||
k8s_config.ssl_ca_cert = ca_cert_file
|
||||
k8s_config.verify_ssl = True
|
||||
else:
|
||||
k8s_config.verify_ssl = False
|
||||
|
@ -724,3 +728,27 @@ def get_new_deployment_body(
|
|||
new_deploy_reses.append(k8s_res)
|
||||
|
||||
return new_deploy_reses
|
||||
|
||||
|
||||
class CaCertFileContextManager:
|
||||
def __init__(self, ca_cert_str):
|
||||
self._file_descriptor = None
|
||||
self.file_path = None
|
||||
self.ca_cert_str = ca_cert_str
|
||||
|
||||
def __enter__(self):
|
||||
if not self.ca_cert_str:
|
||||
return self
|
||||
self._file_descriptor, self.file_path = tempfile.mkstemp()
|
||||
ca_cert = re.sub(r'\s', '\n', self.ca_cert_str)
|
||||
ca_cert = re.sub(r'BEGIN\nCERT', r'BEGIN CERT', ca_cert)
|
||||
ca_cert = re.sub(r'END\nCERT', r'END CERT', ca_cert)
|
||||
# write ca cert file
|
||||
os.write(self._file_descriptor, ca_cert.encode())
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, exc_traceback):
|
||||
if not self.ca_cert_str:
|
||||
return
|
||||
os.close(self._file_descriptor)
|
||||
os.remove(self.file_path)
|
||||
|
|
|
@ -49,6 +49,7 @@ class BaseVnfLcmKubernetesV2Test(base.BaseTestCase):
|
|||
k8s_vim_info = cls.get_k8s_vim_info()
|
||||
cls.auth_url = k8s_vim_info.interfaceInfo['endpoint']
|
||||
cls.bearer_token = k8s_vim_info.accessInfo['bearer_token']
|
||||
cls.ssl_ca_cert = k8s_vim_info.interfaceInfo['ssl_ca_cert']
|
||||
|
||||
vim_info = cls.get_vim_info()
|
||||
auth = http_client.KeystonePasswordAuthHandle(
|
||||
|
@ -85,7 +86,10 @@ class BaseVnfLcmKubernetesV2Test(base.BaseTestCase):
|
|||
vim_params = yaml.safe_load(base_utils.read_file('local-k8s-vim.yaml'))
|
||||
|
||||
vim_info = objects.VimConnectionInfo(
|
||||
interfaceInfo={'endpoint': vim_params['auth_url']},
|
||||
interfaceInfo={
|
||||
'endpoint': vim_params['auth_url'],
|
||||
'ssl_ca_cert': vim_params.get('ssl_ca_cert')
|
||||
},
|
||||
accessInfo={
|
||||
'region': 'RegionOne',
|
||||
'bearer_token': vim_params['bearer_token']
|
||||
|
|
|
@ -47,7 +47,7 @@ def test_instantiate_cnf_resources_terminate():
|
|||
}
|
||||
|
||||
|
||||
def max_sample_instantiate(auth_url, bearer_token):
|
||||
def max_sample_instantiate(auth_url, bearer_token, ssl_ca_cert=None):
|
||||
# All attributes are set.
|
||||
# NOTE: All of the following cardinality attributes are set.
|
||||
# In addition, 0..N or 1..N attributes are set to 2 or more.
|
||||
|
@ -78,6 +78,9 @@ def max_sample_instantiate(auth_url, bearer_token):
|
|||
},
|
||||
"extra": {"dummy-key": "dummy-val"}
|
||||
}
|
||||
if ssl_ca_cert:
|
||||
vim_1["interfaceInfo"]["ssl_ca_cert"] = ssl_ca_cert
|
||||
vim_2["interfaceInfo"]["ssl_ca_cert"] = ssl_ca_cert
|
||||
return {
|
||||
"flavourId": "simple",
|
||||
"vimConnectionInfo": {
|
||||
|
|
|
@ -98,7 +98,7 @@ class VnfLcmKubernetesTest(base_v2.BaseVnfLcmKubernetesV2Test):
|
|||
|
||||
# 2. Instantiate a VNF instance
|
||||
instantiate_req = paramgen.max_sample_instantiate(
|
||||
self.auth_url, self.bearer_token)
|
||||
self.auth_url, self.bearer_token, ssl_ca_cert=self.ssl_ca_cert)
|
||||
resp, body = self.instantiate_vnf_instance(inst_id, instantiate_req)
|
||||
self.assertEqual(202, resp.status_code)
|
||||
self.check_resp_headers_in_operation_task(resp)
|
||||
|
|
|
@ -146,7 +146,7 @@ class TestKubernetes(base.BaseTestCase):
|
|||
_instantiate_req_example)
|
||||
req.additionalParams['lcm-kubernetes-def-files'].append(
|
||||
'Files/kubernetes/namespace.yaml')
|
||||
req.vimConnectionInfo['vim1']['interfaceInfo']['ssl_ca_cert '] = 'test'
|
||||
req.vimConnectionInfo['vim1']['interfaceInfo']['ssl_ca_cert'] = 'test'
|
||||
req.additionalParams['namespace'] = 'curry'
|
||||
inst = objects.VnfInstanceV2(
|
||||
vimConnectionInfo=req.vimConnectionInfo
|
||||
|
@ -1009,6 +1009,7 @@ class TestKubernetes(base.BaseTestCase):
|
|||
# prepare instantiate
|
||||
req = objects.InstantiateVnfRequest.from_dict(
|
||||
_instantiate_req_example)
|
||||
req.vimConnectionInfo['vim1']['interfaceInfo']['ssl_ca_cert'] = 'test'
|
||||
inst = objects.VnfInstanceV2(
|
||||
vimConnectionInfo=req.vimConnectionInfo
|
||||
)
|
||||
|
@ -1302,6 +1303,7 @@ class TestKubernetes(base.BaseTestCase):
|
|||
# prepare instantiate
|
||||
req = objects.InstantiateVnfRequest.from_dict(
|
||||
_instantiate_req_example)
|
||||
req.vimConnectionInfo['vim1']['interfaceInfo']['ssl_ca_cert'] = 'test'
|
||||
inst = objects.VnfInstanceV2(
|
||||
id=uuidutils.generate_uuid(),
|
||||
vimConnectionInfo=req.vimConnectionInfo
|
||||
|
|
Loading…
Reference in New Issue