Repository: openshift/openshift-ansible

Issue:
[healthchecks] the package_version check always checks for master/node packages regardless of host group
#### Description

When running `playbooks/byo/openshift-preflight/check.yml`, the `package_version` check reports failures on hosts that can't access the `atomic-openshift-{master,node}` packages even when this is expected, e.g. on etcd or lb hosts.


##### Version

```
openshift-ansible-3.5.3-1-521-g3125e72
```

##### Steps To Reproduce
1. Have a cluster with `[etcd]`, `[lb]` and/or additional "auxiliary" host groups
2. Run the `playbooks/byo/openshift-preflight/check.yml` playbook


##### Expected Results
Hosts would not report a failure when they have access to the packages they need.

##### Observed Results
Hosts that don't have access to `atomic-openshift-{master,node}` packages in their configured repos are reported as failed, even when the hosts don't need these packages.
Describe what is actually happening.

```
$ ansible-playbook playbooks/byo/openshift-preflight/check.yml
[...]
Failure summary:

  1. Host:     etcd2.example.com
     Play:     run OpenShift health checks
     Task:     openshift_health_check
     Message:  One or more checks failed
     Details:  {'package_availability': {'_ansible_parsed': True,
                                         u'changed': False,
                                         u'invocation': {u'module_args': {u'packages': []}}},
                'package_update': {'_ansible_parsed': True,
                                   u'changed': False,
                                   u'invocation': {u'module_args': {u'packages': []}}},
                'package_version': {'_ansible_parsed': True,
                                    u'failed': True,
                                    u'invocation': {u'module_args': {u'prefix': u'atomic-openshift',
                                                                     u'version': u'v3.4'}},
                                    u'msg': u'Not all of the required packages are available at requested version 3.4:\n  atomic-openshift\n  atomic-openshift-master\n  atomic-openshift-node\nPlease check your subscriptions and enabled repositories.'}}
```

##### Additional Information

The inventory file used here has:

```
[OSEv3:children]
masters
nodes
etcd
lb
dns

# [...]

[etcd]
etcd2.example.com
# [...]

[lb]
lb.example.com
```

the hosts in *etcd*, *lb* and *dns* groups all fail the check.





Discussion:

Resolving patch:
diff --git a/roles/openshift_health_checker/openshift_checks/package_version.py b/roles/openshift_health_checker/openshift_checks/package_version.py
--- a/roles/openshift_health_checker/openshift_checks/package_version.py
+++ b/roles/openshift_health_checker/openshift_checks/package_version.py
@@ -9,6 +9,13 @@ class PackageVersion(NotContainerizedMixin, OpenShiftCheck):
     name = "package_version"
     tags = ["preflight"]
 
+    @classmethod
+    def is_active(cls, task_vars):
+        """Skip hosts that do not have package requirements."""
+        group_names = get_var(task_vars, "group_names", default=[])
+        master_or_node = 'masters' in group_names or 'nodes' in group_names
+        return super(PackageVersion, cls).is_active(task_vars) and master_or_node
+
     def run(self, tmp, task_vars):
         rpm_prefix = get_var(task_vars, "openshift", "common", "service_type")
         openshift_release = get_var(task_vars, "openshift_release")


Test patch:
diff --git a/roles/openshift_health_checker/test/package_version_test.py b/roles/openshift_health_checker/test/package_version_test.py
--- a/roles/openshift_health_checker/test/package_version_test.py
+++ b/roles/openshift_health_checker/test/package_version_test.py
@@ -1,3 +1,5 @@
+import pytest
+
 from openshift_checks.package_version import PackageVersion
 
 
@@ -19,3 +21,23 @@ def execute_module(module_name=None, module_args=None, tmp=None, task_vars=None)
     check = PackageVersion(execute_module=execute_module)
     result = check.run(tmp=None, task_vars=task_vars)
     assert result is return_value
+
+
+@pytest.mark.parametrize('group_names,is_containerized,is_active', [
+    (['masters'], False, True),
+    # ensure check is skipped on containerized installs
+    (['masters'], True, False),
+    (['nodes'], False, True),
+    (['masters', 'nodes'], False, True),
+    (['masters', 'etcd'], False, True),
+    ([], False, False),
+    (['etcd'], False, False),
+    (['lb'], False, False),
+    (['nfs'], False, False),
+])
+def test_package_version_skip_when_not_master_nor_node(group_names, is_containerized, is_active):
+    task_vars = dict(
+        group_names=group_names,
+        openshift=dict(common=dict(is_containerized=is_containerized)),
+    )
+    assert PackageVersion.is_active(task_vars=task_vars) == is_active