Extend vim register function for helm in v2 API

In v2 API, when using vim with `ETSINFV.HELM.V_3` type, you must
set the `ssl_ca_cert` information. Currently, when registering vim
with kubernetes type and use_helm parameter, it will succeed even
if you don't set `ssl_ca_cert` information. This causes v2 APIs to
fail when you use the vimConnectionInfo stored in the database.

This patch added a check in register vim to fix this issue. If the
helm is used to register the vim of kubernetes type, the
`ssl_ca_cert` parameter will be checked. If it's not set, the
registration will fail.

At the same time, FT test items have been added to verify that
v2 API operations perform properly when using the `ETSINFV.HELM.V_3`
type vim that exists in the database.

Implements: blueprint helmchart-k8s-vim
Change-Id: I629e347413b242ab9e1a5db16c52ca222adc3873
This commit is contained in:
Shuwen Cai 2023-01-11 14:49:09 +09:00
parent f88b95e3e0
commit 2cbd84c56f
8 changed files with 110 additions and 26 deletions

View File

@ -125,11 +125,14 @@
dest={{ zuul_work_dir }}/tools/test-setup-k8s-vim.sh
mode=0755
- name: Copy test k8s vim file
- name: Copy test k8s vim files
copy:
remote_src=True
src={{ devstack_base_dir }}/tacker/tacker/tests/etc/samples/local-k8s-vim.yaml
dest={{ zuul_work_dir }}/tacker/tests/etc/samples/local-k8s-vim.yaml
src={{ devstack_base_dir }}/tacker/{{ item }}
dest={{ zuul_work_dir }}/{{ item }}
with_items:
- "tacker/tests/etc/samples/local-k8s-vim.yaml"
- "tacker/tests/etc/samples/local-k8s-vim-helm.yaml"
- name: Copy test k8s vim file for oidc
copy:
@ -175,13 +178,14 @@
when:
- p.stat.exists
- name: Replace k8s auth uri in local-k8s-vim.yaml
- name: Replace k8s auth uri in k8s vim files
replace:
path: "{{ item }}"
regexp: "https://127.0.0.1:6443"
replace: "{{ kuryr_k8s_api_url }}"
with_items:
- "{{ zuul_work_dir }}/tacker/tests/etc/samples/local-k8s-vim.yaml"
- "{{ zuul_work_dir }}/tacker/tests/etc/samples/local-k8s-vim-helm.yaml"
when:
- p.stat.exists
@ -207,13 +211,14 @@
- p.stat.exists
- keycloak_host is defined
- name: Replace k8s auth token in local-k8s-vim.yaml
- name: Replace k8s auth token in k8s vim files
replace:
path: "{{ item }}"
regexp: "secret_token"
replace: "{{ hostvars['controller-k8s'].admin_token.stdout }}"
with_items:
- "{{ zuul_work_dir }}/tacker/tests/etc/samples/local-k8s-vim.yaml"
- "{{ zuul_work_dir }}/tacker/tests/etc/samples/local-k8s-vim-helm.yaml"
when:
- p.stat.exists
@ -249,7 +254,7 @@
shell: test -f /tmp/agg.crt && cat /tmp/agg.crt
register: ssl_ca_cert
- name: Replace ssl_ca_cert in local-k8s-vim.yaml and local-k8s-vim-oidc.yaml
- name: Replace ssl_ca_cert in local-k8s-vim yaml files
replace:
path: "{{ item }}"
regexp: "ssl_ca_cert: .*$"
@ -257,6 +262,7 @@
with_items:
- "{{ zuul_work_dir }}/tacker/tests/etc/samples/local-k8s-vim.yaml"
- "{{ zuul_work_dir }}/tacker/tests/etc/samples/local-k8s-vim-oidc.yaml"
- "{{ zuul_work_dir }}/tacker/tests/etc/samples/local-k8s-vim-helm.yaml"
when:
- p.stat.exists
- ssl_ca_cert.rc == 0 and ssl_ca_cert.stdout != ""

View File

@ -66,6 +66,14 @@ class Kubernetes_Driver(abstract_vim_driver.VimAbstractDriver):
self._validate_vim(auth_cred, file_descriptor)
self.clean_authenticate_vim(auth_cred, file_descriptor)
def _check_extra_field(self, vim_obj):
if vim_obj.get('extra') and vim_obj['extra'].get('use_helm'):
if not vim_obj['auth_cred'].get('ssl_ca_cert'):
error_message = ('If you want to register kubernetes vim with'
' helm, please set ssl_ca_cert.')
LOG.error(error_message)
raise nfvo.VimUnauthorizedException(message=error_message)
def _get_auth_creds(self, vim_obj):
auth_cred = vim_obj['auth_cred']
file_descriptor = self._create_ssl_ca_file(auth_cred)
@ -135,6 +143,7 @@ class Kubernetes_Driver(abstract_vim_driver.VimAbstractDriver):
vim_obj['auth_cred'].pop('key_type')
if 'secret_uuid' in vim_obj['auth_cred']:
vim_obj['auth_cred'].pop('secret_uuid')
self._check_extra_field(vim_obj)
self.authenticate_vim(vim_obj)
self.discover_placement_attr(vim_obj)
self.encode_vim_auth(vim_obj['id'],

View File

@ -0,0 +1,7 @@
auth_url: "https://127.0.0.1:6443"
bearer_token: "secret_token"
project_name: "default"
ssl_ca_cert: None
type: "kubernetes"
extra:
use_helm: true

View File

@ -122,14 +122,16 @@ class BaseVnfLcmKubernetesV2Test(base.BaseTestCase):
return vim_info
@classmethod
def get_k8s_vim_id(cls):
def get_k8s_vim_id(cls, use_helm=False):
vim_list = cls.list_vims(cls)
if len(vim_list.values()) == 0:
assert False, "vim_list is Empty: Default VIM is missing"
for vim_list in vim_list.values():
for vim in vim_list:
if vim['name'] == 'vim-kubernetes':
if vim['name'] == 'vim-kubernetes' and not use_helm:
return vim['id']
if vim['name'] == 'vim-kubernetes-helm' and use_helm:
return vim['id']
return None

View File

@ -318,19 +318,25 @@ def test_helm_instantiate_create(vnfd_id):
}
def helm_instantiate(auth_url, bearer_token, ssl_ca_cert):
vim_id_1 = uuidutils.generate_uuid()
vim_1 = {
"vimId": vim_id_1,
"vimType": "ETSINFV.HELM.V_3",
"interfaceInfo": {
"endpoint": auth_url,
"ssl_ca_cert": ssl_ca_cert
},
"accessInfo": {
"bearer_token": bearer_token
def helm_instantiate(auth_url=None, bearer_token=None, ssl_ca_cert=None,
vim_id=None):
if not vim_id:
vim_1 = {
"vimId": uuidutils.generate_uuid(),
"vimType": "ETSINFV.HELM.V_3",
"interfaceInfo": {
"endpoint": auth_url,
"ssl_ca_cert": ssl_ca_cert
},
"accessInfo": {
"bearer_token": bearer_token
}
}
else:
vim_1 = {
"vimId": vim_id,
"vimType": "ETSINFV.HELM.V_3",
}
}
return {
"flavourId": "simple",
"vimConnectionInfo": {

View File

@ -37,6 +37,7 @@ class VnfLcmHelmTest(base_v2.BaseVnfLcmKubernetesV2Test):
cur_dir, "samples/test_helm_change_vnf_pkg")
cls.vnf_pkg_2, cls.vnfd_id_2 = cls.create_vnf_package(
test_helm_change_vnf_pkg_path)
cls.helm_vim_id = cls.get_k8s_vim_id(use_helm=True)
@classmethod
def tearDownClass(cls):
@ -49,6 +50,12 @@ class VnfLcmHelmTest(base_v2.BaseVnfLcmKubernetesV2Test):
super(VnfLcmHelmTest, self).setUp()
def test_basic_lcms(self):
self._get_basic_lcms_procedure()
def test_basic_lcms_with_register_helm_vim(self):
self._get_basic_lcms_procedure(use_register_vim=True)
def _get_basic_lcms_procedure(self, use_register_vim=False):
"""Test basic LCM operations
* About LCM operations:
@ -101,8 +108,12 @@ class VnfLcmHelmTest(base_v2.BaseVnfLcmKubernetesV2Test):
self.assertEqual('IN_USE', usage_state)
# 2. Instantiate a VNF instance
instantiate_req = paramgen.helm_instantiate(
self.auth_url, self.bearer_token, self.ssl_ca_cert)
if not use_register_vim:
instantiate_req = paramgen.helm_instantiate(
self.auth_url, self.bearer_token, self.ssl_ca_cert)
else:
instantiate_req = paramgen.helm_instantiate(
vim_id=self.helm_vim_id)
resp, body = self.instantiate_vnf_instance(inst_id, instantiate_req)
self.assertEqual(202, resp.status_code)
self.check_resp_headers_in_operation_task(resp)

View File

@ -18,6 +18,7 @@ from unittest import mock
from oslo_config import cfg
from tacker import context as t_context
from tacker.extensions import nfvo
from tacker.nfvo.drivers.vim import kubernetes_driver
from tacker.tests.unit import base
@ -134,7 +135,8 @@ class TestKubernetes_Driver(base.TestCase):
get_core_api_client.assert_called_once_with(auth_obj)
def _test_register_vim(self, vim_obj, mock_k8s_client,
mock_k8s_coreV1Client):
mock_k8s_coreV1Client,
fernet_obj_encrypt_called_count=1):
self.kubernetes_api. \
get_core_api_client.return_value = mock_k8s_client
self.kubernetes_api. \
@ -147,7 +149,8 @@ class TestKubernetes_Driver(base.TestCase):
self.kubernetes_api.create_ca_cert_tmp_file.\
return_value = ('file_descriptor', 'file_path')
self.kubernetes_driver.register_vim(vim_obj)
mock_fernet_obj.encrypt.assert_called_once_with(mock.ANY)
self.assertEqual(mock_fernet_obj.encrypt.call_count,
fernet_obj_encrypt_called_count)
def test_deregister_vim_barbican(self):
self.keymgr.delete.return_value = None
@ -177,3 +180,36 @@ class TestKubernetes_Driver(base.TestCase):
'barbican_key')
self.assertEqual(vim_obj['auth_cred']['secret_uuid'],
'fake-secret-uuid')
def test_register_vim_with_use_helm_parameter(self):
name_value = {'name': 'default'}
name = namedtuple("name", name_value.keys())(*name_value.values())
metadata_value = {'metadata': name}
metadata = namedtuple(
"metadata", metadata_value.keys())(*metadata_value.values())
items_value = {'items': [metadata]}
namespaces = namedtuple(
"namespace", items_value.keys())(*items_value.values())
attrs = {'list_namespace.return_value': namespaces}
mock_k8s_client = mock.Mock()
mock_k8s_coreV1Client = mock.Mock(**attrs)
auth_obj = {'username': 'test_user',
'password': 'test_password',
'ssl_ca_cert': 'ABC',
'ca_cert_file': 'file_path',
'auth_url': 'https://localhost:6443'}
self.vim_obj['extra'] = {'use_helm': True}
self.vim_obj['auth_cred']['ssl_ca_cert'] = 'ABC'
self._test_register_vim(self.vim_obj, mock_k8s_client,
mock_k8s_coreV1Client,
fernet_obj_encrypt_called_count=2)
mock_k8s_coreV1Client.list_namespace.assert_called_once_with()
self.kubernetes_api. \
get_core_api_client.assert_called_once_with(auth_obj)
def test_register_vim_with_use_helm_parameter_and_not_set_ssl_ca_cert(
self):
self.vim_obj['extra'] = {'use_helm': True}
del self.vim_obj['auth_cred']['ssl_ca_cert']
self.assertRaises(nfvo.VimUnauthorizedException,
self.kubernetes_driver.register_vim, self.vim_obj)

View File

@ -30,11 +30,18 @@ register_vim() {
$2
}
# regiter vim with bearer token
# register vim with bearer token
register_vim $conf_dir/local-k8s-vim.yaml vim-kubernetes
# regiter vim with OpenID Connect info
# register vim with OpenID Connect info
if [ -f /tmp/keycloak.crt ]
then
register_vim $conf_dir/local-k8s-vim-oidc.yaml vim-kubernetes-oidc
fi
# register vim with extra used helm
if [ -f $conf_dir/local-k8s-vim-helm.yaml ]
then
register_vim $conf_dir/local-k8s-vim-helm.yaml vim-kubernetes-helm
fi