summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lucas <jflucas@research.att.com>2019-06-25 18:52:55 -0400
committerJack Lucas <jflucas@research.att.com>2019-07-01 11:07:30 -0400
commit9c094d0581c46d3d107facdc55cb2cc7a1d9f765 (patch)
tree7bb29d659b23295d3a3f67f7e1be054a8eb51544
parenta9e0e1c94d9b1fee783ce2db3df962b6fec5149b (diff)
Add TLS support for client-only apps
Also enhance unit tests to do more robust checking of results. Issue-ID: DCAEGEN2-1550 Change-Id: Icf6e5357d828e19db73bb58b98fd60e9f111d0dc Signed-off-by: Jack Lucas <jflucas@research.att.com>
-rw-r--r--k8s/configure/configure.py14
-rw-r--r--k8s/k8s-node-type.yaml5
-rw-r--r--k8s/k8sclient/k8sclient.py53
-rw-r--r--k8s/k8splugin/tasks.py10
-rw-r--r--k8s/pom.xml2
-rw-r--r--k8s/setup.py2
-rw-r--r--k8s/tests/common.py135
-rw-r--r--k8s/tests/conftest.py53
-rw-r--r--k8s/tests/test_k8sclient.py100
-rw-r--r--k8s/tests/test_k8sclient_deploy.py48
10 files changed, 290 insertions, 132 deletions
diff --git a/k8s/configure/configure.py b/k8s/configure/configure.py
index e15939a..9f7929e 100644
--- a/k8s/configure/configure.py
+++ b/k8s/configure/configure.py
@@ -35,6 +35,10 @@ FB_IMAGE = "docker.elastic.co/beats/filebeat:5.5.0"
TLS_CERT_PATH = "/opt/tls/shared"
TLS_IMAGE = "nexus3.onap.org:10001/onap/org.onap.dcaegen2.deployments.tls-init-container:1.0.0"
+TLS_CA_CERT_PATH = "/opt/dcae/cacert/cacert.pem"
+TLS_CA_CONFIGMAP = "dcae-cacert-configmap"
+
+CBS_BASE_URL = "https://config-binding-service:10443/service_component_all"
def _set_defaults():
""" Set default configuration parameters """
@@ -51,10 +55,16 @@ def _set_defaults():
"config_map" : FB_CONFIG_MAP, # ConfigMap holding the filebeat configuration
"image": FB_IMAGE # Docker image to use for filebeat
},
- "tls": { # Configuration for setting up TLS init container
+ "tls": { # Configuration for setting up TLS
"cert_path" : TLS_CERT_PATH, # mount point for certificate volume in TLS init container
- "image": TLS_IMAGE # Docker image to use for TLS init container
+ "image": TLS_IMAGE, # Docker image to use for TLS init container
+ "component_ca_cert_path": TLS_CA_CERT_PATH, # Mount point for CA cert for components that are clients only
+ "ca_cert_configmap": TLS_CA_CONFIGMAP # ConfigMap holding CA cert for components that are clients only
+ },
+ "cbs": {
+ "base_url" : CBS_BASE_URL # URL prefix for accessing config binding service
}
+
}
def configure(config_path=_CONFIG_PATH, key = _CONSUL_KEY):
diff --git a/k8s/k8s-node-type.yaml b/k8s/k8s-node-type.yaml
index 273da7a..c32d834 100644
--- a/k8s/k8s-node-type.yaml
+++ b/k8s/k8s-node-type.yaml
@@ -18,14 +18,11 @@
tosca_definitions_version: cloudify_dsl_1_3
-imports:
- - http://www.getcloudify.org/spec/cloudify/3.4/types.yaml
-
plugins:
k8s:
executor: 'central_deployment_agent'
package_name: k8splugin
- package_version: 1.4.13
+ package_version: 1.5.0
data_types:
diff --git a/k8s/k8sclient/k8sclient.py b/k8s/k8sclient/k8sclient.py
index 681ea6b..273b9f3 100644
--- a/k8s/k8sclient/k8sclient.py
+++ b/k8s/k8sclient/k8sclient.py
@@ -93,7 +93,7 @@ def _parse_interval(t):
raise ValueError("Bad interval specification: {0}".format(t))
return time
-def _create_probe(hc, port, use_tls=False):
+def _create_probe(hc, port):
''' Create a Kubernetes probe based on info in the health check dictionary hc '''
probe_type = hc['type']
probe = None
@@ -133,7 +133,7 @@ def _create_resources(resources=None):
else:
return None
-def _create_container_object(name, image, always_pull, use_tls=False, env={}, container_ports=[], volume_mounts = [], resources = None, readiness = None, liveness = None):
+def _create_container_object(name, image, always_pull, env={}, container_ports=[], volume_mounts = [], resources = None, readiness = None, liveness = None):
# Set up environment variables
# Copy any passed in environment variables
env_vars = [client.V1EnvVar(name=k, value=env[k]) for k in env.keys()]
@@ -150,12 +150,12 @@ def _create_container_object(name, image, always_pull, use_tls=False, env={}, co
hc_port = None
if len(container_ports) > 0:
(hc_port, proto) = container_ports[0]
- probe = _create_probe(readiness, hc_port, use_tls)
+ probe = _create_probe(readiness, hc_port)
if liveness:
hc_port = None
if len(container_ports) > 0:
(hc_port, proto) = container_ports[0]
- live_probe = _create_probe(liveness, hc_port, use_tls)
+ live_probe = _create_probe(liveness, hc_port)
if resources:
resources_obj = _create_resources(resources)
@@ -376,9 +376,11 @@ def deploy(namespace, component_name, image, replicas, always_pull, k8sconfig, r
"config_subpath" : subpath for config data in filebeat container
"config_map" : ConfigMap holding the filebeat configuration
"image": Docker image to use for filebeat
- - tls: a dictionary of TLS init container parameters:
+ - tls: a dictionary of TLS-related information:
"cert_path": mount point for certificate volume in init container
"image": Docker image to use for TLS init container
+ "component_ca_cert_path" : mount point for CA cert for client-only containers
+ "ca_cert_configmap": the name of the ConfigMap where the CA cert is stored
kwargs may have:
- volumes: array of volume objects, where a volume object is:
{"host":{"path": "/path/on/host"}, "container":{"bind":"/path/on/container","mode":"rw_or_ro"}
@@ -453,7 +455,7 @@ def deploy(namespace, component_name, image, replicas, always_pull, k8sconfig, r
sidecar_volume_mounts.append(client.V1VolumeMount(name="filebeat-data", mount_path=fb["data_path"]))
# Create the container for the sidecar
- containers.append(_create_container_object("filebeat", fb["image"], False, False, {}, [], sidecar_volume_mounts))
+ containers.append(_create_container_object("filebeat", fb["image"], False, {}, [], sidecar_volume_mounts))
# Create the volume for the sidecar configuration data and the volume mount for it
# The configuration data is in a k8s ConfigMap that should be created when DCAE is installed.
@@ -462,25 +464,44 @@ def deploy(namespace, component_name, image, replicas, always_pull, k8sconfig, r
sidecar_volume_mounts.append(
client.V1VolumeMount(name="filebeat-conf", mount_path=fb["config_path"], sub_path=fb["config_subpath"]))
- # Set up the TLS init container, if needed
- tls_info = kwargs.get("tls_info")
- use_tls = False
- if tls_info and "use_tls" in tls_info and tls_info["use_tls"]:
- if "cert_directory" in tls_info and len(tls_info["cert_directory"]) > 0:
- use_tls = True
- tls_config = k8sconfig["tls"]
+ # Set up TLS information
+ # Two different ways of doing this, depending on whether the container will act as a TLS server or as a client only
+ # If a server, then tls_info will be passed, and tls_info["use_tls"] will be set to true. We create an InitContainer
+ # that sets up the CA cert, the server cert, and the keys.
+ # If a client only, only the CA cert is needed. We mount the CA cert from a ConfigMap that has been created as part
+ # of the installation process. If there is cert_directory information in tls_info, we use that directory in the mount path.
+ # Otherwise, we use the configured default path in tls_config.
+ tls_info = kwargs.get("tls_info")
+ tls_config = k8sconfig["tls"]
+ tls_server = False
+ cert_directory = None
+
+ if tls_info and "cert_directory" in tls_info and len(tls_info["cert_directory"]) > 0:
+ cert_directory = tls_info["cert_directory"]
+ if tls_info and tls_info.get("use_tls", False):
+ tls_server = True
+ # Use an InitContainer to set up the certificate information
# Create the certificate volume and volume mounts
volumes.append(client.V1Volume(name="tls-info", empty_dir=client.V1EmptyDirVolumeSource()))
- volume_mounts.append(client.V1VolumeMount(name="tls-info", mount_path=tls_info["cert_directory"]))
+ volume_mounts.append(client.V1VolumeMount(name="tls-info", mount_path=cert_directory))
init_volume_mounts = [client.V1VolumeMount(name="tls-info", mount_path=tls_config["cert_path"])]
# Create the init container
- init_containers.append(_create_container_object("init-tls", tls_config["image"], False, False, {}, [], init_volume_mounts))
+ init_containers.append(_create_container_object("init-tls", tls_config["image"], False, {}, [], init_volume_mounts))
+
+ if not tls_server:
+ # Use a config map
+ # Create the CA cert volume
+ volumes.append(client.V1Volume(name="tls-cacert", config_map=client.V1ConfigMapVolumeSource(name=tls_config["ca_cert_configmap"])))
+
+ # Create the volume mount
+ mount_path= cert_directory if cert_directory else os.path.dirname(tls_config["component_ca_cert_path"])
+ volume_mounts.append(client.V1VolumeMount(name="tls-cacert", mount_path=mount_path))
# Create the container for the component
# Make it the first container in the pod
- containers.insert(0, _create_container_object(component_name, image, always_pull, use_tls, kwargs.get("env", {}), container_ports, volume_mounts, resources, kwargs["readiness"], kwargs.get("liveness")))
+ containers.insert(0, _create_container_object(component_name, image, always_pull, kwargs.get("env", {}), container_ports, volume_mounts, resources, kwargs["readiness"], kwargs.get("liveness")))
# Build the k8s Deployment object
labels = kwargs.get("labels", {})
diff --git a/k8s/k8splugin/tasks.py b/k8s/k8splugin/tasks.py
index ab72b57..ecd3ffa 100644
--- a/k8s/k8splugin/tasks.py
+++ b/k8s/k8splugin/tasks.py
@@ -44,6 +44,8 @@ CONSUL_INTERNAL_NAME = plugin_conf.get("consul_dns_name")
DCAE_NAMESPACE = plugin_conf.get("namespace")
DEFAULT_MAX_WAIT = plugin_conf.get("max_wait", 1800)
DEFAULT_K8S_LOCATION = plugin_conf.get("default_k8s_location")
+COMPONENT_CA_CERT_PATH = plugin_conf.get("tls").get("component_ca_cert_path")
+CBS_BASE_URL = plugin_conf.get("cbs").get("base_url")
# Used to construct delivery urls for data router subscribers. Data router in FTL
# requires https but this author believes that ONAP is to be defaulted to http.
@@ -279,13 +281,19 @@ def _create_and_start_container(container_name, image, **kwargs):
- msb_list: array of msb objects, where an msb object is as described in msb/msb.py.
- log_info: an object with info for setting up ELK logging, with the form:
{"log_directory": "/path/to/container/log/directory", "alternate_fb_path" : "/alternate/sidecar/log/path"}"
+ - tls_info: an object with information for setting up the component to act as a TLS server, with the form:
+ {"use_tls" : true_or_false, "cert_directory": "/path/to/directory_where_certs_should_be_placed" }
- replicas: number of replicas to be launched initially
- readiness: object with information needed to create a readiness check
- liveness: object with information needed to create a liveness check
- k8s_location: name of the Kubernetes location (cluster) where the component is to be deployed
'''
+ tls_info = kwargs.get("tls_info")
env = { "CONSUL_HOST": CONSUL_INTERNAL_NAME,
- "CONFIG_BINDING_SERVICE": "config-binding-service" }
+ "CONFIG_BINDING_SERVICE": "config-binding-service",
+ "DCAE_CA_CERTPATH" : "{0}/cacert.pem".format(tls_info["cert_directory"]) if (tls_info and tls_info["cert_directory"]) else COMPONENT_CA_CERT_PATH,
+ "CBS_CONFIG_URL" : "{0}/{1}".format(CBS_BASE_URL, container_name)
+ }
env.update(kwargs.get("envs", {}))
ctx.logger.info("Starting k8s deployment for {}, image: {}, env: {}, kwargs: {}".format(container_name, image, env, kwargs))
ctx.logger.info("Passing k8sconfig: {}".format(plugin_conf))
diff --git a/k8s/pom.xml b/k8s/pom.xml
index b99816a..d96ebe1 100644
--- a/k8s/pom.xml
+++ b/k8s/pom.xml
@@ -28,7 +28,7 @@ ECOMP is a trademark and service mark of AT&T Intellectual Property.
<groupId>org.onap.dcaegen2.platform.plugins</groupId>
<artifactId>k8s</artifactId>
<name>k8s-plugin</name>
- <version>1.4.13-SNAPSHOT</version>
+ <version>1.5.0-SNAPSHOT</version>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
diff --git a/k8s/setup.py b/k8s/setup.py
index 6a9dcac..5d27438 100644
--- a/k8s/setup.py
+++ b/k8s/setup.py
@@ -23,7 +23,7 @@ from setuptools import setup
setup(
name='k8splugin',
description='Cloudify plugin for containerized components deployed using Kubernetes',
- version="1.4.13",
+ version="1.5.0",
author='J. F. Lucas, Michael Hwang, Tommy Carpenter',
packages=['k8splugin','k8sclient','msb','configure'],
zip_safe=False,
diff --git a/k8s/tests/common.py b/k8s/tests/common.py
new file mode 100644
index 0000000..67f70a6
--- /dev/null
+++ b/k8s/tests/common.py
@@ -0,0 +1,135 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2019 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+
+# Common functions for unit testing
+def _set_k8s_configuration():
+ ''' Set up the basic k8s configuration '''
+ return {
+ "image_pull_secrets" : ["secret0", "secret1"],
+ "filebeat" : {
+ "log_path": "/var/log/onap",
+ "data_path": "/usr/share/filebeat/data",
+ "config_path": "/usr/share/filebeat/filebeat.yml",
+ "config_subpath": "filebeat.yml",
+ "image" : "filebeat-repo/filebeat:latest",
+ "config_map" : "dcae-filebeat-configmap"
+ },
+ "tls" : {
+ "cert_path": "/opt/certs",
+ "image": "tlsrepo/tls-init-container:1.2.3",
+ "component_ca_cert_path": "/opt/dcae/cacert/cacert.pem",
+ "ca_cert_configmap": "dcae-cacert-configmap"
+ },
+ "cbs": {
+ "base_url": "https://config-binding-service:10443/service_component_all/test-component"
+ }
+ }
+
+def _set_resources():
+ ''' Set resources '''
+ return {
+ "limits": {
+ "cpu" : 0.5,
+ "memory" : "2Gi"
+ },
+ "requests": {
+ "cpu" : 0.5,
+ "memory" : "2Gi"
+ }
+ }
+
+def _set_common_kwargs():
+ ''' Set kwargs common to all test cases '''
+ return {
+ "volumes": [
+ {"host":{"path": "/path/on/host"}, "container":{"bind":"/path/on/container","mode":"rw"}}
+ ],
+ "ports": ["80:0", "443:0"],
+ "env": {"NAME0": "value0", "NAME1": "value1"},
+ "log_info": {"log_directory": "/path/to/container/log/directory"},
+ "readiness": {"type": "http", "endpoint" : "/ready"}
+ }
+
+def _get_item_by_name(list, name):
+ ''' Search a list of k8s API objects with the specified name '''
+ for item in list:
+ if item.name == name:
+ return item
+ return None
+
+def check_env_var(env_list, name, value):
+ e = _get_item_by_name(env_list, name)
+ assert e and e.value == value
+
+def verify_common(dep, deployment_description):
+ ''' Check results common to all test cases '''
+ assert deployment_description["deployment"] == "dep-testcomponent"
+ assert deployment_description["namespace"] == "k8stest"
+ assert deployment_description["services"][0] == "testcomponent"
+
+ # For unit test purposes, we want to make sure that the deployment object
+ # we're passing to the k8s API is correct
+ app_container = dep.spec.template.spec.containers[0]
+ assert app_container.image == "example.com/testcomponent:1.4.3"
+ assert app_container.image_pull_policy == "IfNotPresent"
+ assert len(app_container.ports) == 2
+ assert app_container.ports[0].container_port == 80
+ assert app_container.ports[1].container_port == 443
+ assert app_container.readiness_probe.http_get.path == "/ready"
+ assert app_container.readiness_probe.http_get.scheme == "HTTP"
+ assert len(app_container.volume_mounts) == 3
+ assert app_container.volume_mounts[0].mount_path == "/path/on/container"
+ assert app_container.volume_mounts[1].mount_path == "/path/to/container/log/directory"
+
+ # Check environment variables
+ env = app_container.env
+ check_env_var(env, "NAME0", "value0")
+ check_env_var(env, "NAME1", "value1")
+
+ # Should have a log container with volume mounts
+ log_container = dep.spec.template.spec.containers[1]
+ assert log_container.image == "filebeat-repo/filebeat:latest"
+ assert log_container.volume_mounts[0].mount_path == "/var/log/onap/testcomponent"
+ assert log_container.volume_mounts[0].name == "component-log"
+ assert log_container.volume_mounts[1].mount_path == "/usr/share/filebeat/data"
+ assert log_container.volume_mounts[1].name == "filebeat-data"
+ assert log_container.volume_mounts[2].mount_path == "/usr/share/filebeat/filebeat.yml"
+ assert log_container.volume_mounts[2].name == "filebeat-conf"
+
+ # Needs to be correctly labeled so that the Service can find it
+ assert dep.spec.template.metadata.labels["app"] == "testcomponent"
+
+
+def do_deploy(tls_info=None):
+ ''' Common deployment operations '''
+ import k8sclient.k8sclient
+
+ k8s_test_config = _set_k8s_configuration()
+
+ resources = _set_resources()
+
+ kwargs = _set_common_kwargs()
+ if tls_info:
+ kwargs["tls_info"] = tls_info
+
+ dep, deployment_description = k8sclient.k8sclient.deploy("k8stest","testcomponent","example.com/testcomponent:1.4.3",1,False, k8s_test_config, resources, **kwargs)
+
+ # Make sure all of the basic k8s parameters are correct
+ verify_common(dep, deployment_description)
+
+ return dep, deployment_description \ No newline at end of file
diff --git a/k8s/tests/conftest.py b/k8s/tests/conftest.py
index 572a510..4716b5a 100644
--- a/k8s/tests/conftest.py
+++ b/k8s/tests/conftest.py
@@ -1,7 +1,7 @@
# ============LICENSE_START=======================================================
# org.onap.dcae
# ================================================================================
-# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2018-2019 AT&T Intellectual Property. All rights reserved.
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -22,13 +22,48 @@ import pytest
@pytest.fixture()
def mockconfig(monkeypatch):
+ from configure import configure
""" Override the regular configure() routine that reads a file and calls Consul"""
def altconfig():
- return {
- "consul_host": "consul",
- "namespace":"dcae",
- "consul_dns_name" : "consul",
- "image_pull_secrets" : []
- }
- from configure import configure
- monkeypatch.setattr(configure, 'configure', altconfig) \ No newline at end of file
+ config = configure._set_defaults()
+ config["consul_host"] = config["consul_dns_name"]
+ return config
+ monkeypatch.setattr(configure, 'configure', altconfig)
+
+@pytest.fixture()
+def mockk8sapi(monkeypatch):
+ import k8sclient.k8sclient
+ from kubernetes import client
+
+ # We need to patch the kubernetes 'client' module
+ # Awkward because of the way it requires a function call
+ # to get an API object
+ core = client.CoreV1Api()
+ ext = client.ExtensionsV1beta1Api()
+
+ def pseudo_deploy(namespace, dep):
+ return dep
+
+ def pseudo_service(namespace, svc):
+ return svc
+
+ # patched_core returns a CoreV1Api object with the
+ # create_namespaced_service method stubbed out so that there
+ # is no attempt to call the k8s API server
+ def patched_core():
+ monkeypatch.setattr(core, "create_namespaced_service", pseudo_service)
+ return core
+
+ # patched_ext returns an ExtensionsV1beta1Api object with the
+ # create_namespaced_deployment method stubbed out so that there
+ # is no attempt to call the k8s API server
+ def patched_ext():
+ monkeypatch.setattr(ext,"create_namespaced_deployment", pseudo_deploy)
+ return ext
+
+ def pseudo_configure(loc):
+ pass
+
+ monkeypatch.setattr(k8sclient.k8sclient,"_configure_api", pseudo_configure)
+ monkeypatch.setattr(client, "CoreV1Api", patched_core)
+ monkeypatch.setattr(client,"ExtensionsV1beta1Api", patched_ext)
diff --git a/k8s/tests/test_k8sclient.py b/k8s/tests/test_k8sclient.py
index 70ebf05..079748c 100644
--- a/k8s/tests/test_k8sclient.py
+++ b/k8s/tests/test_k8sclient.py
@@ -16,6 +16,8 @@
# limitations under the License.
# ============LICENSE_END=========================================================
+# Basic sanity tests for k8sclient functions
+
import pytest
def test_parse_interval():
@@ -174,101 +176,3 @@ def test_create_probe():
for hc in script_checks:
probe = _create_probe(hc, 13131)
assert probe._exec.command[0] == hc["script"]
-
-def test_deploy(monkeypatch):
- import k8sclient.k8sclient
- from kubernetes import client
-
- # We need to patch the kubernetes 'client' module
- # Awkward because of the way it requires a function call
- # to get an API object
- core = client.CoreV1Api()
- ext = client.ExtensionsV1beta1Api()
-
- def pseudo_deploy(namespace, dep):
- return dep
-
- def pseudo_service(namespace, svc):
- return svc
-
- # patched_core returns a CoreV1Api object with the
- # create_namespaced_service method stubbed out so that there
- # is no attempt to call the k8s API server
- def patched_core():
- monkeypatch.setattr(core, "create_namespaced_service", pseudo_service)
- return core
-
- # patched_ext returns an ExtensionsV1beta1Api object with the
- # create_namespaced_deployment method stubbed out so that there
- # is no attempt to call the k8s API server
- def patched_ext():
- monkeypatch.setattr(ext,"create_namespaced_deployment", pseudo_deploy)
- return ext
-
- def pseudo_configure(loc):
- pass
-
- monkeypatch.setattr(k8sclient.k8sclient,"_configure_api", pseudo_configure)
- monkeypatch.setattr(client, "CoreV1Api", patched_core)
- monkeypatch.setattr(client,"ExtensionsV1beta1Api", patched_ext)
-
- k8s_test_config = {
- "image_pull_secrets" : ["secret0", "secret1"],
- "filebeat" : {
- "log_path": "/var/log/onap",
- "data_path": "/usr/share/filebeat/data",
- "config_path": "/usr/share/filebeat/filebeat.yml",
- "config_subpath": "filebeat.yml",
- "image" : "filebeat-repo/filebeat:latest",
- "config_map" : "dcae-filebeat-configmap"
- },
- "tls" : {
- "cert_path": "/opt/certs",
- "image": "tlsrepo/tls-init-container:1.2.3"
- }
- }
-
- resources = {
- "limits": {
- "cpu" : 0.5,
- "memory" : "2Gi"
- },
- "requests": {
- "cpu" : 0.5,
- "memory" : "2Gi"
- }
- }
-
- kwargs = {
- "volumes": [
- {"host":{"path": "/path/on/host"}, "container":{"bind":"/path/on/container","mode":"rw"}}
- ],
- "ports": ["80:0", "443:0"],
- "env": {"name0": "value0", "name1": "value1"},
- "log_info": {"log_directory": "/path/to/container/log/directory"},
- "tls_info": {"use_tls": True, "cert_directory": "/path/to/container/cert/directory" },
- "readiness": {"type": "http", "endpoint" : "/ready"}
- }
- dep, deployment_description = k8sclient.k8sclient.deploy("k8stest","testcomponent","example.com/testcomponent:1.4.3",1,False, k8s_test_config, resources, **kwargs)
-
- assert deployment_description["deployment"] == "dep-testcomponent"
- assert deployment_description["namespace"] == "k8stest"
- assert deployment_description["services"][0] == "testcomponent"
-
- # For unit test purposes, we want to make sure that the deployment object
- # we're passing to the k8s API is correct
- app_container = dep.spec.template.spec.containers[0]
- assert app_container.image == "example.com/testcomponent:1.4.3"
- assert app_container.image_pull_policy == "IfNotPresent"
- assert len(app_container.ports) == 2
- assert app_container.ports[0].container_port == 80
- assert app_container.ports[1].container_port == 443
- assert app_container.readiness_probe.http_get.path == "/ready"
- assert app_container.readiness_probe.http_get.scheme == "HTTP"
- assert len(app_container.volume_mounts) == 3
- assert app_container.volume_mounts[0].mount_path == "/path/on/container"
- assert app_container.volume_mounts[1].mount_path == "/path/to/container/log/directory"
- assert app_container.volume_mounts[2].mount_path == "/path/to/container/cert/directory"
-
- # Needs to be correctly labeled so that the Service can find it
- assert dep.spec.template.metadata.labels["app"] == "testcomponent"
diff --git a/k8s/tests/test_k8sclient_deploy.py b/k8s/tests/test_k8sclient_deploy.py
new file mode 100644
index 0000000..4e8a11d
--- /dev/null
+++ b/k8s/tests/test_k8sclient_deploy.py
@@ -0,0 +1,48 @@
+# ============LICENSE_START=======================================================
+# org.onap.dcae
+# ================================================================================
+# Copyright (c) 2018-2019 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+
+# Test k8sclient deployment functions
+# Verify that for a given configuration and set of inputs, k8sclient generates the proper
+# Kubernetes entities
+
+import pytest
+from common import do_deploy
+
+def test_deploy_full_tls(mockk8sapi):
+ ''' Deploy component with a full TLS configuration, to act as a server '''
+
+ dep, deployment_description = do_deploy({"use_tls": True, "cert_directory": "/path/to/container/cert/directory" })
+
+ app_container = dep.spec.template.spec.containers[0]
+ assert app_container.volume_mounts[2].mount_path == "/path/to/container/cert/directory"
+
+def test_deploy_tls_off(mockk8sapi):
+ ''' TLS client only, but with cert directory configured '''
+
+ dep, deployment_description = do_deploy({"use_tls": False, "cert_directory": "/path/to/container/cert/directory" })
+
+ app_container = dep.spec.template.spec.containers[0]
+ assert app_container.volume_mounts[2].mount_path == "/path/to/container/cert/directory"
+
+def test_deploy_no_tls_info(mockk8sapi):
+ ''' TLS client only, but with cert directory configured '''
+
+ dep, deployment_description = do_deploy()
+
+ app_container = dep.spec.template.spec.containers[0]
+ assert app_container.volume_mounts[2].mount_path == "/opt/dcae/cacert"