diff options
-rw-r--r-- | yardstick/benchmark/contexts/kubernetes.py | 13 | ||||
-rw-r--r-- | yardstick/common/exceptions.py | 10 | ||||
-rw-r--r-- | yardstick/orchestrator/kubernetes.py | 24 | ||||
-rw-r--r-- | yardstick/tests/unit/benchmark/contexts/test_kubernetes.py | 16 | ||||
-rw-r--r-- | yardstick/tests/unit/orchestrator/test_kubernetes.py | 44 |
5 files changed, 87 insertions, 20 deletions
diff --git a/yardstick/benchmark/contexts/kubernetes.py b/yardstick/benchmark/contexts/kubernetes.py index 704c4a022..7534c4ea5 100644 --- a/yardstick/benchmark/contexts/kubernetes.py +++ b/yardstick/benchmark/contexts/kubernetes.py @@ -166,8 +166,8 @@ class KubernetesContext(ctx_base.Context): def _get_server(self, name): node_ports = self._get_service_ports(name) for sn_port in (sn_port for sn_port in node_ports - if sn_port.port == constants.SSH_PORT): - node_port = sn_port.node_port + if sn_port['port'] == constants.SSH_PORT): + node_port = sn_port['node_port'] break else: raise exceptions.KubernetesSSHPortNotDefined() @@ -224,4 +224,11 @@ class KubernetesContext(ctx_base.Context): service = k8s_utils.get_service_by_name(service_name) if not service: raise exceptions.KubernetesServiceObjectNotDefined() - return service.ports + ports = [] + for port in service.ports: + ports.append({'name': port.name, + 'node_port': port.node_port, + 'port': port.port, + 'protocol': port.protocol, + 'target_port': port.target_port}) + return ports diff --git a/yardstick/common/exceptions.py b/yardstick/common/exceptions.py index 51db552ee..1f749adc1 100644 --- a/yardstick/common/exceptions.py +++ b/yardstick/common/exceptions.py @@ -231,6 +231,16 @@ class KubernetesServiceObjectNotDefined(YardstickException): message = 'ServiceObject is not defined' +class KubernetesServiceObjectDefinitionError(YardstickException): + message = ('Kubernetes Service object definition error, missing ' + 'parameters: %(missing_parameters)s') + + +class KubernetesServiceObjectNameError(YardstickException): + message = ('Kubernetes Service object name "%(name)s" does not comply' + 'naming convention') + + class KubernetesCRDObjectDefinitionError(YardstickException): message = ('Kubernetes Custom Resource Definition Object error, missing ' 'parameters: %(missing_parameters)s') diff --git a/yardstick/orchestrator/kubernetes.py b/yardstick/orchestrator/kubernetes.py index ec3588371..bee4d4a78 100644 --- a/yardstick/orchestrator/kubernetes.py +++ b/yardstick/orchestrator/kubernetes.py @@ -8,6 +8,7 @@ ############################################################################## import copy +import re from oslo_serialization import jsonutils @@ -240,6 +241,9 @@ class ReplicationControllerObject(object): class ServiceNodePortObject(object): + MANDATORY_PARAMETERS = {'port', 'name'} + NAME_REGEX = re.compile(r'^[a-z0-9]([-a-z0-9]*[a-z0-9])?$') + def __init__(self, name, **kwargs): """Service kind "NodePort" object @@ -257,19 +261,27 @@ class ServiceNodePortObject(object): } } - self._add_port(22, protocol='TCP') + self._add_port(22, 'ssh', protocol='TCP') node_ports = copy.deepcopy(kwargs.get('node_ports', [])) for port in node_ports: + if not self.MANDATORY_PARAMETERS.issubset(port.keys()): + missing_parameters = ', '.join( + str(param) for param in + (self.MANDATORY_PARAMETERS - set(port.keys()))) + raise exceptions.KubernetesServiceObjectDefinitionError( + missing_parameters=missing_parameters) port_number = port.pop('port') - self._add_port(port_number, **port) + name = port.pop('name') + if not self.NAME_REGEX.match(name): + raise exceptions.KubernetesServiceObjectNameError(name=name) + self._add_port(port_number, name, **port) - def _add_port(self, port, protocol=None, name=None, targetPort=None, + def _add_port(self, port, name, protocol=None, targetPort=None, nodePort=None): - _port = {'port': port} + _port = {'port': port, + 'name': name} if protocol: _port['protocol'] = protocol - if name: - _port['name'] = name if targetPort: _port['targetPort'] = targetPort if nodePort: diff --git a/yardstick/tests/unit/benchmark/contexts/test_kubernetes.py b/yardstick/tests/unit/benchmark/contexts/test_kubernetes.py index bace37653..b526e7cc7 100644 --- a/yardstick/tests/unit/benchmark/contexts/test_kubernetes.py +++ b/yardstick/tests/unit/benchmark/contexts/test_kubernetes.py @@ -57,6 +57,9 @@ class NodePort(object): def __init__(self): self.node_port = 30000 self.port = constants.SSH_PORT + self.name = 'port_name' + self.protocol = 'TCP' + self.target_port = constants.SSH_PORT class Service(object): @@ -152,8 +155,10 @@ class KubernetesTestCase(unittest.TestCase): def test_get_server(self, mock_get_node_ip, mock_get_pod_by_name): mock_get_pod_by_name.return_value = Pod() mock_get_node_ip.return_value = '172.16.10.131' - with mock.patch.object(self.k8s_context, '_get_service_ports', - return_value=[NodePort()]): + with mock.patch.object(self.k8s_context, '_get_service_ports') as \ + mock_get_sports: + mock_get_sports.return_value = [ + {'port': constants.SSH_PORT, 'node_port': 30000}] server = self.k8s_context._get_server('server_name') self.assertEqual('server_name', server['name']) self.assertEqual(30000, server['ssh_port']) @@ -253,7 +258,12 @@ class KubernetesTestCase(unittest.TestCase): name = 'rc_name' service_ports = self.k8s_context._get_service_ports(name) mock_get_service_by_name.assert_called_once_with(name + '-service') - self.assertEqual(30000, service_ports[0].node_port) + expected = {'node_port': 30000, + 'port': constants.SSH_PORT, + 'name': 'port_name', + 'protocol': 'TCP', + 'target_port': constants.SSH_PORT} + self.assertEqual(expected, service_ports[0]) @mock.patch.object(k8s_utils, 'get_service_by_name', return_value=None) diff --git a/yardstick/tests/unit/orchestrator/test_kubernetes.py b/yardstick/tests/unit/orchestrator/test_kubernetes.py index 394ab58d5..1317308cc 100644 --- a/yardstick/tests/unit/orchestrator/test_kubernetes.py +++ b/yardstick/tests/unit/orchestrator/test_kubernetes.py @@ -524,24 +524,52 @@ class ServiceNodePortObjectTestCase(base.BaseUnitTestCase): def test__init(self): with mock.patch.object(kubernetes.ServiceNodePortObject, '_add_port') \ as mock_add_port: - kubernetes.ServiceNodePortObject('fake_name', - node_ports=[{'port': 80}]) + kubernetes.ServiceNodePortObject( + 'fake_name', node_ports=[{'port': 80, 'name': 'web'}]) - mock_add_port.assert_has_calls([mock.call(22, protocol='TCP'), - mock.call(80)]) + mock_add_port.assert_has_calls([mock.call(22, 'ssh', protocol='TCP'), + mock.call(80, 'web')]) + + @mock.patch.object(kubernetes.ServiceNodePortObject, '_add_port') + def test__init_missing_mandatory_parameters(self, *args): + with self.assertRaises( + exceptions.KubernetesServiceObjectDefinitionError): + kubernetes.ServiceNodePortObject( + 'fake_name', node_ports=[{'port': 80}]) + with self.assertRaises( + exceptions.KubernetesServiceObjectDefinitionError): + kubernetes.ServiceNodePortObject( + 'fake_name', node_ports=[{'name': 'web'}]) + + @mock.patch.object(kubernetes.ServiceNodePortObject, '_add_port') + def test__init_missing_bad_name(self, *args): + with self.assertRaises( + exceptions.KubernetesServiceObjectNameError): + kubernetes.ServiceNodePortObject( + 'fake_name', node_ports=[{'port': 80, 'name': '-web'}]) + with self.assertRaises( + exceptions.KubernetesServiceObjectNameError): + kubernetes.ServiceNodePortObject( + 'fake_name', node_ports=[{'port': 80, 'name': 'Web'}]) + with self.assertRaises( + exceptions.KubernetesServiceObjectNameError): + kubernetes.ServiceNodePortObject( + 'fake_name', node_ports=[{'port': 80, 'name': 'web-'}]) def test__add_port(self): nodeport_object = kubernetes.ServiceNodePortObject('fake_name') - port_ssh = {'port': 22, - 'protocol': 'TCP',} + port_ssh = {'name': 'ssh', + 'port': 22, + 'protocol': 'TCP'} port_definition = {'port': 80, 'protocol': 'TCP', 'name': 'web', 'targetPort': 10080, 'nodePort': 30080} port = copy.deepcopy(port_definition) - port.pop('port') - nodeport_object._add_port(80, **port) + _port = port.pop('port') + name = port.pop('name') + nodeport_object._add_port(_port, name, **port) self.assertEqual([port_ssh, port_definition], nodeport_object.template['spec']['ports']) |