Merge "Add "volumeMounts" parameter in Kubernetes context"
authorRodolfo Alonso Hernandez <rodolfo.alonso.hernandez@intel.com>
Mon, 25 Jun 2018 11:19:12 +0000 (11:19 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Mon, 25 Jun 2018 11:19:12 +0000 (11:19 +0000)
yardstick/orchestrator/kubernetes.py
yardstick/tests/unit/orchestrator/test_kubernetes.py

index ae6c945..e05c971 100644 (file)
@@ -16,15 +16,21 @@ from yardstick.common import kubernetes_utils as k8s_utils
 
 class KubernetesObject(object):
 
+    SSH_MOUNT_PATH = '/tmp/.ssh/'
+    IMAGE_DEFAULT = 'openretriever/yardstick'
+    COMMAND_DEFAULT = '/bin/bash'
+    SSHKEY_DEFAULT = 'yardstick_key'
+
     def __init__(self, name, **kwargs):
         super(KubernetesObject, self).__init__()
         self.name = name
-        self.image = kwargs.get('image', 'openretriever/yardstick')
-        self.command = [kwargs.get('command', '/bin/bash')]
+        self.image = kwargs.get('image', self.IMAGE_DEFAULT)
+        self.command = [kwargs.get('command', self.COMMAND_DEFAULT)]
         self.args = kwargs.get('args', [])
-        self.ssh_key = kwargs.get('ssh_key', 'yardstick_key')
+        self.ssh_key = kwargs.get('ssh_key', self.SSHKEY_DEFAULT)
         self.node_selector = kwargs.get('nodeSelector', {})
         self._volumes = kwargs.get('volumes', [])
+        self._volume_mounts = kwargs.get('volumeMounts', [])
 
         self.template = {
             "apiVersion": "v1",
@@ -65,29 +71,19 @@ class KubernetesObject(object):
                              name)
 
     def _add_containers(self):
-        containers = [self._add_container()]
+        containers = [self._create_container_item()]
         utils.set_dict_value(self.template,
                              'spec.template.spec.containers',
                              containers)
 
-    def _add_container(self):
+    def _create_container_item(self):
+        """Create a "container" item"""
         container_name = '{}-container'.format(self.name)
-        ssh_key_mount_path = '/tmp/.ssh/'
-
-        container = {
-            "args": self.args,
-            "command": self.command,
-            "image": self.image,
-            "name": container_name,
-            "volumeMounts": [
-                {
-                    "mountPath": ssh_key_mount_path,
-                    "name": self.ssh_key
-                }
-            ]
-        }
-
-        return container
+        return {'args': self.args,
+                'command': self.command,
+                'image': self.image,
+                'name': container_name,
+                'volumeMounts': self._create_volume_mounts()}
 
     def _add_node_selector(self):
         utils.set_dict_value(self.template,
@@ -96,7 +92,7 @@ class KubernetesObject(object):
 
     def _add_volumes(self):
         """Add "volume" items to container specs, including the SSH one"""
-        volume_items = [self._create_volume(vol) for vol in self._volumes]
+        volume_items = [self._create_volume_item(vol) for vol in self._volumes]
         volume_items.append(self._create_ssh_key_volume())
         utils.set_dict_value(self.template,
                              'spec.template.spec.volumes',
@@ -108,7 +104,7 @@ class KubernetesObject(object):
                 'configMap': {'name': self.ssh_key}}
 
     @staticmethod
-    def _create_volume(volume):
+    def _create_volume_item(volume):
         """Create a "volume" item"""
         volume = copy.deepcopy(volume)
         name = volume.pop('name')
@@ -122,6 +118,22 @@ class KubernetesObject(object):
         return {'name': name,
                 type_name: type_data}
 
+    def _create_volume_mounts(self):
+        """Return all "volumeMounts" items per container"""
+        volume_mounts_items = [self._create_volume_mounts_item(vol)
+                               for vol in self._volume_mounts]
+        ssh_vol = {'name': self.ssh_key,
+                   'mountPath': self.SSH_MOUNT_PATH}
+        volume_mounts_items.append(self._create_volume_mounts_item(ssh_vol))
+        return volume_mounts_items
+
+    @staticmethod
+    def _create_volume_mounts_item(volume_mount):
+        """Create a "volumeMounts" item"""
+        return {'name': volume_mount['name'],
+                'mountPath': volume_mount['mountPath'],
+                'readOnly': volume_mount.get('readOnly', False)}
+
 
 class ServiceObject(object):
 
index e3e5516..21a12a0 100644 (file)
@@ -7,6 +7,8 @@
 # http://www.apache.org/licenses/LICENSE-2.0
 ##############################################################################
 
+import copy
+
 import mock
 
 from yardstick.common import exceptions
@@ -48,7 +50,8 @@ service ssh restart;while true ; do sleep 10000; done"
                                 "volumeMounts": [
                                     {
                                         "mountPath": "/tmp/.ssh/",
-                                        "name": "k8s-86096c30-key"
+                                        "name": "k8s-86096c30-key",
+                                        "readOnly": False
                                     }
                                 ]
                             }
@@ -133,15 +136,61 @@ class KubernetesObjectTestCase(base.BaseUnitTestCase):
         k8s_obj = kubernetes.KubernetesObject('name', ssh_key='fake_sshkey')
         self.assertEqual(expected, k8s_obj._create_ssh_key_volume())
 
-    def test__create_volume(self):
+    def test__create_volume_item(self):
         for vol_type in kubernetes_utils.get_volume_types():
             volume = {'name': 'vol_name',
                       vol_type: 'data'}
             self.assertEqual(
-                volume, kubernetes.KubernetesObject._create_volume(volume))
+                volume,
+                kubernetes.KubernetesObject._create_volume_item(volume))
 
-    def test__create_volume_invalid_type(self):
+    def test__create_volume_item_invalid_type(self):
         volume = {'name': 'vol_name',
                   'invalid_type': 'data'}
         with self.assertRaises(exceptions.KubernetesTemplateInvalidVolumeType):
-            kubernetes.KubernetesObject._create_volume(volume)
+            kubernetes.KubernetesObject._create_volume_item(volume)
+
+    def test__create_volume_mounts(self):
+        volume_mount = {'name': 'fake_name',
+                        'mountPath': 'fake_path'}
+        ssh_vol = {'name': kubernetes.KubernetesObject.SSHKEY_DEFAULT,
+                   'mountPath': kubernetes.KubernetesObject.SSH_MOUNT_PATH,
+                   'readOnly': False}
+        expected = copy.deepcopy(volume_mount)
+        expected['readOnly'] = False
+        expected = [expected, ssh_vol]
+        k8s_obj = kubernetes.KubernetesObject('name',
+                                              volumeMounts=[volume_mount])
+        output = k8s_obj._create_volume_mounts()
+        self.assertEqual(expected, output)
+
+    def test__create_volume_mounts_no_volume_mounts(self):
+        ssh_vol = {'name': kubernetes.KubernetesObject.SSHKEY_DEFAULT,
+                   'mountPath': kubernetes.KubernetesObject.SSH_MOUNT_PATH,
+                   'readOnly': False}
+        k8s_obj = kubernetes.KubernetesObject('name')
+        output = k8s_obj._create_volume_mounts()
+        self.assertEqual([ssh_vol], output)
+
+    def test__create_volume_mounts_item(self):
+        volume_mount = {'name': 'fake_name',
+                        'mountPath': 'fake_path'}
+        expected = copy.deepcopy(volume_mount)
+        expected['readOnly'] = False
+        output = kubernetes.KubernetesObject._create_volume_mounts_item(
+            volume_mount)
+        self.assertEqual(expected, output)
+
+    def test__create_container_item(self):
+        volume_mount = {'name': 'fake_name',
+                        'mountPath': 'fake_path'}
+        args = ['arg1', 'arg2']
+        k8s_obj = kubernetes.KubernetesObject(
+            'cname', ssh_key='fake_sshkey', volumeMount=[volume_mount],
+            args=args)
+        expected = {'args': args,
+                    'command': [kubernetes.KubernetesObject.COMMAND_DEFAULT],
+                    'image': kubernetes.KubernetesObject.IMAGE_DEFAULT,
+                    'name': 'cname-container',
+                    'volumeMounts': k8s_obj._create_volume_mounts()}
+        self.assertEqual(expected, k8s_obj._create_container_item())