Browse Source

package_version check: tolerate release version 3.7

Addresses issue https://github.com/openshift/openshift-ansible/issues/4967

For now, any version >= 3.6 is handled as if it were 3.6. We may want to
keep that or fine-tune it later.

Also, the ovs_version check is not updated. This is a post-install
health check (does not block install/upgrade) with an update already in
progress so will be addressed there.
Luke Meyer 7 years ago
parent
commit
65583d894b

+ 54 - 54
roles/openshift_health_checker/openshift_checks/package_version.py

@@ -1,4 +1,7 @@
 """Check that available RPM packages match the required versions."""
+
+import re
+
 from openshift_checks import OpenShiftCheck, OpenShiftCheckException
 from openshift_checks.mixins import NotContainerizedMixin
 
@@ -9,23 +12,25 @@ class PackageVersion(NotContainerizedMixin, OpenShiftCheck):
     name = "package_version"
     tags = ["preflight"]
 
+    # NOTE: versions outside those specified are mapped to least/greatest
     openshift_to_ovs_version = {
-        "3.6": ["2.6", "2.7"],
-        "3.5": ["2.6", "2.7"],
-        "3.4": "2.4",
+        (3, 4): "2.4",
+        (3, 5): ["2.6", "2.7"],
+        (3, 6): ["2.6", "2.7"],
     }
 
     openshift_to_docker_version = {
-        "3.1": "1.8",
-        "3.2": "1.10",
-        "3.3": "1.10",
-        "3.4": "1.12",
+        (3, 1): "1.8",
+        (3, 2): "1.10",
+        (3, 3): "1.10",
+        (3, 4): "1.12",
+        (3, 5): "1.12",
+        (3, 6): "1.12",
     }
 
-    # map major release versions across releases
-    # to a common major version
-    openshift_major_release_version = {
-        "1": "3",
+    # map major OpenShift release versions across releases to a common major version
+    map_major_release_version = {
+        1: 3,
     }
 
     def is_active(self):
@@ -73,54 +78,49 @@ class PackageVersion(NotContainerizedMixin, OpenShiftCheck):
         return self.execute_module("aos_version", args)
 
     def get_required_ovs_version(self):
-        """Return the correct Open vSwitch version for the current OpenShift version.
-        If the current OpenShift version is >= 3.5, ensure Open vSwitch version 2.6,
-        Else ensure Open vSwitch version 2.4"""
-        openshift_version = self.get_openshift_version()
+        """Return the correct Open vSwitch version(s) for the current OpenShift version."""
+        openshift_version = self.get_openshift_version_tuple()
 
-        if float(openshift_version) < 3.5:
-            return self.openshift_to_ovs_version["3.4"]
+        earliest = min(self.openshift_to_ovs_version)
+        latest = max(self.openshift_to_ovs_version)
+        if openshift_version < earliest:
+            return self.openshift_to_ovs_version[earliest]
+        if openshift_version > latest:
+            return self.openshift_to_ovs_version[latest]
 
-        ovs_version = self.openshift_to_ovs_version.get(str(openshift_version))
-        if ovs_version:
-            return ovs_version
+        ovs_version = self.openshift_to_ovs_version.get(openshift_version)
+        if not ovs_version:
+            msg = "There is no recommended version of Open vSwitch for the current version of OpenShift: {}"
+            raise OpenShiftCheckException(msg.format(".".join(str(comp) for comp in openshift_version)))
 
-        msg = "There is no recommended version of Open vSwitch for the current version of OpenShift: {}"
-        raise OpenShiftCheckException(msg.format(openshift_version))
+        return ovs_version
 
     def get_required_docker_version(self):
-        """Return the correct Docker version for the current OpenShift version.
-        If the OpenShift version is 3.1, ensure Docker version 1.8.
-        If the OpenShift version is 3.2 or 3.3, ensure Docker version 1.10.
-        If the current OpenShift version is >= 3.4, ensure Docker version 1.12."""
-        openshift_version = self.get_openshift_version()
-
-        if float(openshift_version) >= 3.4:
-            return self.openshift_to_docker_version["3.4"]
-
-        docker_version = self.openshift_to_docker_version.get(str(openshift_version))
-        if docker_version:
-            return docker_version
-
-        msg = "There is no recommended version of Docker for the current version of OpenShift: {}"
-        raise OpenShiftCheckException(msg.format(openshift_version))
-
-    def get_openshift_version(self):
-        """Return received image tag as a normalized X.Y minor version string."""
-        openshift_version = self.get_var("openshift_image_tag")
-        if openshift_version and openshift_version[0] == 'v':
-            openshift_version = openshift_version[1:]
-
-        return self.parse_version(openshift_version)
-
-    def parse_version(self, version):
-        """Return a normalized X.Y minor version string."""
-        components = version.split(".")
-        if not components or len(components) < 2:
+        """Return the correct Docker version(s) for the current OpenShift version."""
+        openshift_version = self.get_openshift_version_tuple()
+
+        earliest = min(self.openshift_to_docker_version)
+        latest = max(self.openshift_to_docker_version)
+        if openshift_version < earliest:
+            return self.openshift_to_docker_version[earliest]
+        if openshift_version > latest:
+            return self.openshift_to_docker_version[latest]
+
+        docker_version = self.openshift_to_docker_version.get(openshift_version)
+        if not docker_version:
+            msg = "There is no recommended version of Docker for the current version of OpenShift: {}"
+            raise OpenShiftCheckException(msg.format(".".join(str(comp) for comp in openshift_version)))
+
+        return docker_version
+
+    def get_openshift_version_tuple(self):
+        """Return received image tag as a normalized (X, Y) minor version tuple."""
+        version = self.get_var("openshift_image_tag")
+        comps = [int(component) for component in re.findall(r'\d+', version)]
+
+        if len(comps) < 2:
             msg = "An invalid version of OpenShift was found for this host: {}"
             raise OpenShiftCheckException(msg.format(version))
 
-        if components[0] in self.openshift_major_release_version:
-            components[0] = self.openshift_major_release_version[components[0]]
-
-        return '.'.join(components[:2])
+        comps[0] = self.map_major_release_version.get(comps[0], comps[0])
+        return tuple(comps[0:2])

+ 26 - 36
roles/openshift_health_checker/test/package_version_test.py

@@ -3,58 +3,53 @@ import pytest
 from openshift_checks.package_version import PackageVersion, OpenShiftCheckException
 
 
-@pytest.mark.parametrize('openshift_release, extra_words', [
-    ('111.7.0', ["no recommended version of Open vSwitch"]),
-    ('0.0.0', ["no recommended version of Docker"]),
-])
-def test_openshift_version_not_supported(openshift_release, extra_words):
-    def execute_module(*_):
-        return {}
-
-    task_vars = dict(
-        openshift=dict(common=dict(service_type='origin')),
+def task_vars_for(openshift_release, deployment_type):
+    return dict(
+        openshift=dict(common=dict(service_type=deployment_type)),
         openshift_release=openshift_release,
         openshift_image_tag='v' + openshift_release,
-        openshift_deployment_type='origin',
+        openshift_deployment_type=deployment_type,
     )
 
-    check = PackageVersion(execute_module, task_vars)
+
+def test_openshift_version_not_supported():
+    check = PackageVersion(None, task_vars_for("1.2.3", 'origin'))
+    check.get_openshift_version_tuple = lambda: (3, 4, 1)  # won't be in the dict
+
     with pytest.raises(OpenShiftCheckException) as excinfo:
-        check.run()
+        check.get_required_ovs_version()
+    assert "no recommended version of Open vSwitch" in str(excinfo.value)
 
-    for word in extra_words:
-        assert word in str(excinfo.value)
+    with pytest.raises(OpenShiftCheckException) as excinfo:
+        check.get_required_docker_version()
+    assert "no recommended version of Docker" in str(excinfo.value)
 
 
 def test_invalid_openshift_release_format():
-    def execute_module(*_):
-        return {}
-
     task_vars = dict(
         openshift=dict(common=dict(service_type='origin')),
         openshift_image_tag='v0',
         openshift_deployment_type='origin',
     )
 
-    check = PackageVersion(execute_module, task_vars)
+    check = PackageVersion(lambda *_: {}, task_vars)
     with pytest.raises(OpenShiftCheckException) as excinfo:
         check.run()
     assert "invalid version" in str(excinfo.value)
 
 
 @pytest.mark.parametrize('openshift_release', [
-    "3.5",
+    "111.7.0",
+    "3.7",
     "3.6",
+    "3.5.1.2.3",
+    "3.5",
     "3.4",
     "3.3",
+    "2.1.0",
 ])
 def test_package_version(openshift_release):
-    task_vars = dict(
-        openshift=dict(common=dict(service_type='origin')),
-        openshift_release=openshift_release,
-        openshift_image_tag='v' + openshift_release,
-        openshift_deployment_type='origin',
-    )
+
     return_value = object()
 
     def execute_module(module_name=None, module_args=None, tmp=None, task_vars=None, *_):
@@ -67,26 +62,21 @@ def test_package_version(openshift_release):
 
         return return_value
 
-    check = PackageVersion(execute_module, task_vars)
+    check = PackageVersion(execute_module, task_vars_for(openshift_release, 'origin'))
     result = check.run()
     assert result is return_value
 
 
 @pytest.mark.parametrize('deployment_type,openshift_release,expected_docker_version', [
     ("origin", "3.5", "1.12"),
+    ("origin", "1.3", "1.10"),
+    ("origin", "1.1", "1.8"),
     ("openshift-enterprise", "3.4", "1.12"),
-    ("origin", "3.3", "1.10"),
     ("openshift-enterprise", "3.2", "1.10"),
-    ("origin", "3.1", "1.8"),
     ("openshift-enterprise", "3.1", "1.8"),
 ])
 def test_docker_package_version(deployment_type, openshift_release, expected_docker_version):
-    task_vars = dict(
-        openshift=dict(common=dict(service_type='origin')),
-        openshift_release=openshift_release,
-        openshift_image_tag='v' + openshift_release,
-        openshift_deployment_type=deployment_type,
-    )
+
     return_value = object()
 
     def execute_module(module_name=None, module_args=None, *_):
@@ -99,7 +89,7 @@ def test_docker_package_version(deployment_type, openshift_release, expected_doc
 
         return return_value
 
-    check = PackageVersion(execute_module, task_vars)
+    check = PackageVersion(execute_module, task_vars_for(openshift_release, deployment_type))
     result = check.run()
     assert result is return_value