From 3b43905b749b65bd229db8f3f1ce10c29f9b9e37 Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Sat, 5 May 2018 19:06:06 +0100 Subject: Add "securityContext" parameter in Kubernetes context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This new parameter, "securityContext", will allow the user to define the privilege and access control settings for a pod or a container [1]. Example of "securityContext" definition in the pod (if only one container is defined): context:   type: Kubernetes   servers:     host:       image: ...       securityContext:         runAsUser: 1000         fsGroup: 2000  Example of "securityContext" definition in the pod and the container (if several containers are defined):      context:   type: Kubernetes   servers:     host:       securityContext:         runAsUser: 1000         fsGroup: 2000        containers:         - image: ...           securityContext:             allowPrivilegeEscalation: false         - image: ... [1] https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ JIRA: YARDSTICK-1156 Change-Id: I597a300c68cd834522a284b1cca0faa918493342 Signed-off-by: Rodolfo Alonso Hernandez --- yardstick/orchestrator/kubernetes.py | 22 ++++++++--- .../tests/unit/orchestrator/test_kubernetes.py | 43 ++++++++++++++++++++++ 2 files changed, 60 insertions(+), 5 deletions(-) (limited to 'yardstick') diff --git a/yardstick/orchestrator/kubernetes.py b/yardstick/orchestrator/kubernetes.py index 8ccb98853..25adff7d4 100644 --- a/yardstick/orchestrator/kubernetes.py +++ b/yardstick/orchestrator/kubernetes.py @@ -27,6 +27,7 @@ class ContainerObject(object): self._command = [kwargs.get('command', self.COMMAND_DEFAULT)] self._args = kwargs.get('args', []) self._volume_mounts = kwargs.get('volumeMounts', []) + self._security_context = kwargs.get('securityContext') def _create_volume_mounts(self): """Return all "volumeMounts" items per container""" @@ -47,11 +48,14 @@ class ContainerObject(object): def get_container_item(self): """Create a "container" item""" container_name = '{}-container'.format(self._name) - return {'args': self._args, - 'command': self._command, - 'image': self._image, - 'name': container_name, - 'volumeMounts': self._create_volume_mounts()} + container = {'args': self._args, + 'command': self._command, + 'image': self._image, + 'name': container_name, + 'volumeMounts': self._create_volume_mounts()} + if self._security_context: + container['securityContext'] = self._security_context + return container class KubernetesObject(object): @@ -65,6 +69,7 @@ class KubernetesObject(object): self.node_selector = parameters.pop('nodeSelector', {}) self.ssh_key = parameters.pop('ssh_key', self.SSHKEY_DEFAULT) self._volumes = parameters.pop('volumes', []) + self._security_context = parameters.pop('securityContext', None) containers = parameters.pop('containers', None) if containers: @@ -102,6 +107,7 @@ class KubernetesObject(object): self._add_containers() self._add_node_selector() self._add_volumes() + self._add_security_context() def get_template(self): return self.template @@ -153,6 +159,12 @@ class KubernetesObject(object): return {'name': name, type_name: type_data} + def _add_security_context(self): + if self._security_context: + utils.set_dict_value(self.template, + 'spec.template.spec.securityContext', + self._security_context) + class ServiceObject(object): diff --git a/yardstick/tests/unit/orchestrator/test_kubernetes.py b/yardstick/tests/unit/orchestrator/test_kubernetes.py index 4323c026a..99aca0426 100644 --- a/yardstick/tests/unit/orchestrator/test_kubernetes.py +++ b/yardstick/tests/unit/orchestrator/test_kubernetes.py @@ -180,6 +180,34 @@ class KubernetesObjectTestCase(base.BaseUnitTestCase): with self.assertRaises(exceptions.KubernetesTemplateInvalidVolumeType): kubernetes.KubernetesObject._create_volume_item(volume) + def test__add_security_context(self): + k8s_obj = kubernetes.KubernetesObject('pod_name') + self.assertNotIn('securityContext', + k8s_obj.template['spec']['template']['spec']) + + k8s_obj._security_context = {'key_pod': 'value_pod'} + k8s_obj._add_security_context() + self.assertEqual( + {'key_pod': 'value_pod'}, + k8s_obj.template['spec']['template']['spec']['securityContext']) + + def test__add_security_context_by_init(self): + containers = [] + for i in range(5): + containers.append( + {'securityContext': {'key%s' % i: 'value%s' % i}}) + _kwargs = {'containers': containers, + 'securityContext': {'key_pod': 'value_pod'}} + k8s_obj = kubernetes.KubernetesObject('pod_name', **_kwargs) + self.assertEqual( + {'key_pod': 'value_pod'}, + k8s_obj.template['spec']['template']['spec']['securityContext']) + for i in range(5): + container = ( + k8s_obj.template['spec']['template']['spec']['containers'][i]) + self.assertEqual({'key%s' % i: 'value%s' % i}, + container['securityContext']) + class ContainerObjectTestCase(base.BaseUnitTestCase): @@ -227,3 +255,18 @@ class ContainerObjectTestCase(base.BaseUnitTestCase): 'name': 'cname-container', 'volumeMounts': container_obj._create_volume_mounts()} self.assertEqual(expected, container_obj.get_container_item()) + + def test_get_container_item_with_security_context(self): + volume_mount = {'name': 'fake_name', + 'mountPath': 'fake_path'} + args = ['arg1', 'arg2'] + container_obj = kubernetes.ContainerObject( + 'cname', ssh_key='fake_sshkey', volumeMount=[volume_mount], + args=args, securityContext={'key': 'value'}) + expected = {'args': args, + 'command': [kubernetes.ContainerObject.COMMAND_DEFAULT], + 'image': kubernetes.ContainerObject.IMAGE_DEFAULT, + 'name': 'cname-container', + 'volumeMounts': container_obj._create_volume_mounts(), + 'securityContext': {'key': 'value'}} + self.assertEqual(expected, container_obj.get_container_item()) -- cgit 1.2.3-korg