From b13a6e53197bb01a857442680faa78938f1b614e Mon Sep 17 00:00:00 2001 From: Jack Lucas Date: Tue, 31 Jul 2018 21:10:25 +0000 Subject: Fix k8splugin to accept intervals as strings Also update type file to point to new plugin version Add unit tests for parsing interval Change RE to be non-Python specific Use uppercase for RE constant and unit conversion factors Issue-ID: DCAEGEN2-649 Change-Id: I1de728b3efd0725d4a3da996d95ec61e68f56ab4 Signed-off-by: Jack Lucas --- k8s/k8s-node-type.yaml | 2 +- k8s/k8sclient/k8sclient.py | 30 ++++++++++++++-- k8s/pom.xml | 2 +- k8s/setup.py | 2 +- k8s/tests/test_k8sclient.py | 86 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 k8s/tests/test_k8sclient.py diff --git a/k8s/k8s-node-type.yaml b/k8s/k8s-node-type.yaml index 7d64500..13caffc 100644 --- a/k8s/k8s-node-type.yaml +++ b/k8s/k8s-node-type.yaml @@ -25,7 +25,7 @@ plugins: k8s: executor: 'central_deployment_agent' package_name: k8splugin - package_version: 1.4.0 + package_version: 1.4.1 data_types: diff --git a/k8s/k8sclient/k8sclient.py b/k8s/k8sclient/k8sclient.py index e388fb5..1c30534 100644 --- a/k8s/k8sclient/k8sclient.py +++ b/k8s/k8sclient/k8sclient.py @@ -18,6 +18,7 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. import os +import re import uuid from msb import msb from kubernetes import config, client, stream @@ -26,6 +27,11 @@ from kubernetes import config, client, stream PROBE_DEFAULT_PERIOD = 15 PROBE_DEFAULT_TIMEOUT = 1 +# Regular expression for interval/timeout specification +INTERVAL_SPEC = re.compile("^([0-9]+)(s|m|h)?$") +# Conversion factors to seconds +FACTORS = {None: 1, "s": 1, "m": 60, "h": 3600} + def _create_deployment_name(component_name): return "dep-{0}".format(component_name) @@ -58,12 +64,32 @@ def _configure_api(): environ=localenv ).load_and_set() +def _parse_interval(t): + """ + Parse an interval specification + t can be + - a simple integer quantity, interpreted as seconds + - a string representation of a decimal integer, interpreted as seconds + - a string consisting of a represention of an decimal integer followed by a unit, + with "s" representing seconds, "m" representing minutes, + and "h" representing hours + Used for compatibility with the Docker plugin, where time intervals + for health checks were specified as strings with a number and a unit. + See 'intervalspec' above for the regular expression that's accepted. + """ + m = INTERVAL_SPEC.match(str(t)) + if m: + time = int(m.group(1)) * FACTORS[m.group(2)] + else: + raise ValueError("Bad interval specification: {0}".format(t)) + return time + def _create_probe(hc, port): ''' Create a Kubernetes probe based on info in the health check dictionary hc ''' probe_type = hc['type'] probe = None - period = hc.get('interval', PROBE_DEFAULT_PERIOD) - timeout = hc.get('timeout', PROBE_DEFAULT_TIMEOUT) + period = _parse_interval(hc.get('interval', PROBE_DEFAULT_PERIOD)) + timeout = _parse_interval(hc.get('timeout', PROBE_DEFAULT_TIMEOUT)) if probe_type in ['http', 'https']: probe = client.V1Probe( failure_threshold = 1, diff --git a/k8s/pom.xml b/k8s/pom.xml index cd5a8d2..1fbff3e 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. org.onap.dcaegen2.platform.plugins k8s k8s-plugin - 1.4.0-SNAPSHOT + 1.4.1-SNAPSHOT http://maven.apache.org UTF-8 diff --git a/k8s/setup.py b/k8s/setup.py index 7991584..54ecbad 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.0", + version="1.4.1", author='J. F. Lucas, Michael Hwang, Tommy Carpenter', packages=['k8splugin','k8sclient','msb','configure'], zip_safe=False, diff --git a/k8s/tests/test_k8sclient.py b/k8s/tests/test_k8sclient.py new file mode 100644 index 0000000..00ccfdb --- /dev/null +++ b/k8s/tests/test_k8sclient.py @@ -0,0 +1,86 @@ +# ============LICENSE_START======================================================= +# org.onap.dcae +# ================================================================================ +# Copyright (c) 2018 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========================================================= + +import pytest + +def test_parse_interval(): + from k8sclient.k8sclient import _parse_interval + + good_intervals = [{"in": input, "ex": expected} + for (input, expected) in [ + (30, 30), + ("30", 30), + ("30s", 30), + ("2m", 2 * 60), + ("2h", 2 * 60 * 60), + ("24h", 24 * 60 * 60), + (354123, 354123), + ("354123", 354123), + ("354123s", 354123), + (1234567890123456789012345678901234567890L,1234567890123456789012345678901234567890L), + ("1234567890123456789012345678901234567890",1234567890123456789012345678901234567890L), + ("1234567890123456789012345678901234567890s",1234567890123456789012345678901234567890L), + ("05s", 5), + ("00000000000000000000000000000000005m", 5 * 60) + ] + ] + + bad_intervals = [ + -99, + "-99", + "-99s", + "-99m", + "-99h", + "30d", + "30w", + "30y", + "3 0s", + "3 5m", + 30.0, + "30.0s", + "30.0m", + "30.0h", + "a 30s", + "30s a", + "a 30s a", + "a 30", + "30 a", + "a 30 a", + "i want an interval of 30s", + "thirty seconds", + "30 s", + "30 m", + "30 h", + 10E0, + "10E0", + 3.14159, + "3.14159s" + "3:05", + "3m05s", + "3seconds", + "3S", + "1minute", + "1stanbul" + ] + + for test_case in good_intervals: + assert _parse_interval(test_case["in"]) == test_case["ex"] + + for interval in bad_intervals: + with pytest.raises(ValueError): + _parse_interval(interval) \ No newline at end of file -- cgit 1.2.3-korg