Kaynağa Gözat

Merge branch 'master' into fix_logging_jks_gen

Eric Wolinetz 8 yıl önce
ebeveyn
işleme
066494438d
27 değiştirilmiş dosya ile 1884 ekleme ve 112 silme
  1. 1 0
      openshift-ansible.spec
  2. 65 11
      roles/lib_openshift/library/oc_edit.py
  3. 65 11
      roles/lib_openshift/library/oc_obj.py
  4. 97 18
      roles/lib_openshift/library/oc_route.py
  5. 1232 0
      roles/lib_openshift/library/oc_version.py
  6. 2 0
      roles/lib_openshift/src/ansible/oc_route.py
  7. 26 0
      roles/lib_openshift/src/ansible/oc_version.py
  8. 7 5
      roles/lib_openshift/src/class/oc_route.py
  9. 47 0
      roles/lib_openshift/src/class/oc_version.py
  10. 40 0
      roles/lib_openshift/src/doc/version
  11. 65 11
      roles/lib_openshift/src/lib/base.py
  12. 23 2
      roles/lib_openshift/src/lib/route.py
  13. 9 0
      roles/lib_openshift/src/sources.yml
  14. 24 5
      roles/lib_openshift/src/test/integration/route.yml
  15. 17 0
      roles/lib_openshift/src/test/integration/oc_version.yml
  16. 70 0
      roles/lib_openshift/src/test/unit/oc_version.py
  17. 0 14
      roles/openshift_examples/files/examples/v1.3/quickstart-templates/jenkins-ephemeral-template.json
  18. 0 14
      roles/openshift_examples/files/examples/v1.3/quickstart-templates/jenkins-persistent-template.json
  19. 1 1
      roles/openshift_loadbalancer/defaults/main.yml
  20. 22 3
      roles/openshift_loadbalancer/tasks/main.yml
  21. 17 0
      roles/openshift_loadbalancer/templates/haproxy.docker.service.j2
  22. 14 7
      roles/openshift_logging/tasks/install_logging.yaml
  23. 4 4
      roles/openshift_master_certificates/tasks/main.yml
  24. 4 0
      roles/openshift_metrics/README.md
  25. 12 4
      roles/openshift_metrics/tasks/install_metrics.yaml
  26. 18 0
      roles/openshift_metrics/tasks/install_support.yaml
  27. 2 2
      roles/openshift_node/meta/main.yml

+ 1 - 0
openshift-ansible.spec

@@ -19,6 +19,7 @@ Requires:      python-six
 Requires:      tar
 Requires:      openshift-ansible-docs = %{version}-%{release}
 Requires:      java-1.8.0-openjdk-headless
+Requires:      httpd-tools
 
 %description
 Openshift and Atomic Enterprise Ansible

+ 65 - 11
roles/lib_openshift/library/oc_edit.py

@@ -765,7 +765,7 @@ class OpenShiftCLI(object):
 
     def _replace(self, fname, force=False):
         '''replace the current object with oc replace'''
-        cmd = ['-n', self.namespace, 'replace', '-f', fname]
+        cmd = ['replace', '-f', fname]
         if force:
             cmd.append('--force')
         return self.openshift_cmd(cmd)
@@ -782,11 +782,11 @@ class OpenShiftCLI(object):
 
     def _create(self, fname):
         '''call oc create on a filename'''
-        return self.openshift_cmd(['create', '-f', fname, '-n', self.namespace])
+        return self.openshift_cmd(['create', '-f', fname])
 
     def _delete(self, resource, rname, selector=None):
         '''call oc delete on a resource'''
-        cmd = ['delete', resource, rname, '-n', self.namespace]
+        cmd = ['delete', resource, rname]
         if selector:
             cmd.append('--selector=%s' % selector)
 
@@ -800,8 +800,7 @@ class OpenShiftCLI(object):
            params: the parameters for the template
            template_data: the incoming template's data; instead of a file
         '''
-
-        cmd = ['process', '-n', self.namespace]
+        cmd = ['process']
         if template_data:
             cmd.extend(['-f', '-'])
         else:
@@ -822,17 +821,13 @@ class OpenShiftCLI(object):
 
         atexit.register(Utils.cleanup, [fname])
 
-        return self.openshift_cmd(['-n', self.namespace, 'create', '-f', fname])
+        return self.openshift_cmd(['create', '-f', fname])
 
     def _get(self, resource, rname=None, selector=None):
         '''return a resource by name '''
         cmd = ['get', resource]
         if selector:
             cmd.append('--selector=%s' % selector)
-        if self.all_namespaces:
-            cmd.extend(['--all-namespaces'])
-        elif self.namespace:
-            cmd.extend(['-n', self.namespace])
 
         cmd.extend(['-o', 'json'])
 
@@ -906,6 +901,10 @@ class OpenShiftCLI(object):
 
         return self.openshift_cmd(cmd, oadm=True, output=True, output_type='raw')
 
+    def _version(self):
+        ''' return the openshift version'''
+        return self.openshift_cmd(['version'], output=True, output_type='raw')
+
     def _import_image(self, url=None, name=None, tag=None):
         ''' perform image import '''
         cmd = ['import-image']
@@ -924,7 +923,7 @@ class OpenShiftCLI(object):
         cmd.append('--confirm')
         return self.openshift_cmd(cmd)
 
-    # pylint: disable=too-many-arguments
+    # pylint: disable=too-many-arguments,too-many-branches
     def openshift_cmd(self, cmd, oadm=False, output=False, output_type='json', input_data=None):
         '''Base command for oc '''
         cmds = []
@@ -933,6 +932,11 @@ class OpenShiftCLI(object):
         else:
             cmds = ['/usr/bin/oc']
 
+        if self.all_namespaces:
+            cmds.extend(['--all-namespaces'])
+        elif self.namespace:
+            cmds.extend(['-n', self.namespace])
+
         cmds.extend(cmd)
 
         rval = {}
@@ -1058,6 +1062,56 @@ class Utils(object):
 
         return contents
 
+    @staticmethod
+    def filter_versions(stdout):
+        ''' filter the oc version output '''
+
+        version_dict = {}
+        version_search = ['oc', 'openshift', 'kubernetes']
+
+        for line in stdout.strip().split('\n'):
+            for term in version_search:
+                if not line:
+                    continue
+                if line.startswith(term):
+                    version_dict[term] = line.split()[-1]
+
+        # horrible hack to get openshift version in Openshift 3.2
+        #  By default "oc version in 3.2 does not return an "openshift" version
+        if "openshift" not in version_dict:
+            version_dict["openshift"] = version_dict["oc"]
+
+        return version_dict
+
+    @staticmethod
+    def add_custom_versions(versions):
+        ''' create custom versions strings '''
+
+        versions_dict = {}
+
+        for tech, version in versions.items():
+            # clean up "-" from version
+            if "-" in version:
+                version = version.split("-")[0]
+
+            if version.startswith('v'):
+                versions_dict[tech + '_numeric'] = version[1:].split('+')[0]
+                # "v3.3.0.33" is what we have, we want "3.3"
+                versions_dict[tech + '_short'] = version[1:4]
+
+        return versions_dict
+
+    @staticmethod
+    def openshift_installed():
+        ''' check if openshift is installed '''
+        import yum
+
+        yum_base = yum.YumBase()
+        if yum_base.rpmdb.searchNevra(name='atomic-openshift'):
+            return True
+
+        return False
+
     # Disabling too-many-branches.  This is a yaml dictionary comparison function
     # pylint: disable=too-many-branches,too-many-return-statements,too-many-statements
     @staticmethod

+ 65 - 11
roles/lib_openshift/library/oc_obj.py

@@ -744,7 +744,7 @@ class OpenShiftCLI(object):
 
     def _replace(self, fname, force=False):
         '''replace the current object with oc replace'''
-        cmd = ['-n', self.namespace, 'replace', '-f', fname]
+        cmd = ['replace', '-f', fname]
         if force:
             cmd.append('--force')
         return self.openshift_cmd(cmd)
@@ -761,11 +761,11 @@ class OpenShiftCLI(object):
 
     def _create(self, fname):
         '''call oc create on a filename'''
-        return self.openshift_cmd(['create', '-f', fname, '-n', self.namespace])
+        return self.openshift_cmd(['create', '-f', fname])
 
     def _delete(self, resource, rname, selector=None):
         '''call oc delete on a resource'''
-        cmd = ['delete', resource, rname, '-n', self.namespace]
+        cmd = ['delete', resource, rname]
         if selector:
             cmd.append('--selector=%s' % selector)
 
@@ -779,8 +779,7 @@ class OpenShiftCLI(object):
            params: the parameters for the template
            template_data: the incoming template's data; instead of a file
         '''
-
-        cmd = ['process', '-n', self.namespace]
+        cmd = ['process']
         if template_data:
             cmd.extend(['-f', '-'])
         else:
@@ -801,17 +800,13 @@ class OpenShiftCLI(object):
 
         atexit.register(Utils.cleanup, [fname])
 
-        return self.openshift_cmd(['-n', self.namespace, 'create', '-f', fname])
+        return self.openshift_cmd(['create', '-f', fname])
 
     def _get(self, resource, rname=None, selector=None):
         '''return a resource by name '''
         cmd = ['get', resource]
         if selector:
             cmd.append('--selector=%s' % selector)
-        if self.all_namespaces:
-            cmd.extend(['--all-namespaces'])
-        elif self.namespace:
-            cmd.extend(['-n', self.namespace])
 
         cmd.extend(['-o', 'json'])
 
@@ -885,6 +880,10 @@ class OpenShiftCLI(object):
 
         return self.openshift_cmd(cmd, oadm=True, output=True, output_type='raw')
 
+    def _version(self):
+        ''' return the openshift version'''
+        return self.openshift_cmd(['version'], output=True, output_type='raw')
+
     def _import_image(self, url=None, name=None, tag=None):
         ''' perform image import '''
         cmd = ['import-image']
@@ -903,7 +902,7 @@ class OpenShiftCLI(object):
         cmd.append('--confirm')
         return self.openshift_cmd(cmd)
 
-    # pylint: disable=too-many-arguments
+    # pylint: disable=too-many-arguments,too-many-branches
     def openshift_cmd(self, cmd, oadm=False, output=False, output_type='json', input_data=None):
         '''Base command for oc '''
         cmds = []
@@ -912,6 +911,11 @@ class OpenShiftCLI(object):
         else:
             cmds = ['/usr/bin/oc']
 
+        if self.all_namespaces:
+            cmds.extend(['--all-namespaces'])
+        elif self.namespace:
+            cmds.extend(['-n', self.namespace])
+
         cmds.extend(cmd)
 
         rval = {}
@@ -1037,6 +1041,56 @@ class Utils(object):
 
         return contents
 
+    @staticmethod
+    def filter_versions(stdout):
+        ''' filter the oc version output '''
+
+        version_dict = {}
+        version_search = ['oc', 'openshift', 'kubernetes']
+
+        for line in stdout.strip().split('\n'):
+            for term in version_search:
+                if not line:
+                    continue
+                if line.startswith(term):
+                    version_dict[term] = line.split()[-1]
+
+        # horrible hack to get openshift version in Openshift 3.2
+        #  By default "oc version in 3.2 does not return an "openshift" version
+        if "openshift" not in version_dict:
+            version_dict["openshift"] = version_dict["oc"]
+
+        return version_dict
+
+    @staticmethod
+    def add_custom_versions(versions):
+        ''' create custom versions strings '''
+
+        versions_dict = {}
+
+        for tech, version in versions.items():
+            # clean up "-" from version
+            if "-" in version:
+                version = version.split("-")[0]
+
+            if version.startswith('v'):
+                versions_dict[tech + '_numeric'] = version[1:].split('+')[0]
+                # "v3.3.0.33" is what we have, we want "3.3"
+                versions_dict[tech + '_short'] = version[1:4]
+
+        return versions_dict
+
+    @staticmethod
+    def openshift_installed():
+        ''' check if openshift is installed '''
+        import yum
+
+        yum_base = yum.YumBase()
+        if yum_base.rpmdb.searchNevra(name='atomic-openshift'):
+            return True
+
+        return False
+
     # Disabling too-many-branches.  This is a yaml dictionary comparison function
     # pylint: disable=too-many-branches,too-many-return-statements,too-many-statements
     @staticmethod

+ 97 - 18
roles/lib_openshift/library/oc_route.py

@@ -769,7 +769,7 @@ class OpenShiftCLI(object):
 
     def _replace(self, fname, force=False):
         '''replace the current object with oc replace'''
-        cmd = ['-n', self.namespace, 'replace', '-f', fname]
+        cmd = ['replace', '-f', fname]
         if force:
             cmd.append('--force')
         return self.openshift_cmd(cmd)
@@ -786,11 +786,11 @@ class OpenShiftCLI(object):
 
     def _create(self, fname):
         '''call oc create on a filename'''
-        return self.openshift_cmd(['create', '-f', fname, '-n', self.namespace])
+        return self.openshift_cmd(['create', '-f', fname])
 
     def _delete(self, resource, rname, selector=None):
         '''call oc delete on a resource'''
-        cmd = ['delete', resource, rname, '-n', self.namespace]
+        cmd = ['delete', resource, rname]
         if selector:
             cmd.append('--selector=%s' % selector)
 
@@ -804,8 +804,7 @@ class OpenShiftCLI(object):
            params: the parameters for the template
            template_data: the incoming template's data; instead of a file
         '''
-
-        cmd = ['process', '-n', self.namespace]
+        cmd = ['process']
         if template_data:
             cmd.extend(['-f', '-'])
         else:
@@ -826,17 +825,13 @@ class OpenShiftCLI(object):
 
         atexit.register(Utils.cleanup, [fname])
 
-        return self.openshift_cmd(['-n', self.namespace, 'create', '-f', fname])
+        return self.openshift_cmd(['create', '-f', fname])
 
     def _get(self, resource, rname=None, selector=None):
         '''return a resource by name '''
         cmd = ['get', resource]
         if selector:
             cmd.append('--selector=%s' % selector)
-        if self.all_namespaces:
-            cmd.extend(['--all-namespaces'])
-        elif self.namespace:
-            cmd.extend(['-n', self.namespace])
 
         cmd.extend(['-o', 'json'])
 
@@ -910,6 +905,10 @@ class OpenShiftCLI(object):
 
         return self.openshift_cmd(cmd, oadm=True, output=True, output_type='raw')
 
+    def _version(self):
+        ''' return the openshift version'''
+        return self.openshift_cmd(['version'], output=True, output_type='raw')
+
     def _import_image(self, url=None, name=None, tag=None):
         ''' perform image import '''
         cmd = ['import-image']
@@ -928,7 +927,7 @@ class OpenShiftCLI(object):
         cmd.append('--confirm')
         return self.openshift_cmd(cmd)
 
-    # pylint: disable=too-many-arguments
+    # pylint: disable=too-many-arguments,too-many-branches
     def openshift_cmd(self, cmd, oadm=False, output=False, output_type='json', input_data=None):
         '''Base command for oc '''
         cmds = []
@@ -937,6 +936,11 @@ class OpenShiftCLI(object):
         else:
             cmds = ['/usr/bin/oc']
 
+        if self.all_namespaces:
+            cmds.extend(['--all-namespaces'])
+        elif self.namespace:
+            cmds.extend(['-n', self.namespace])
+
         cmds.extend(cmd)
 
         rval = {}
@@ -1062,6 +1066,56 @@ class Utils(object):
 
         return contents
 
+    @staticmethod
+    def filter_versions(stdout):
+        ''' filter the oc version output '''
+
+        version_dict = {}
+        version_search = ['oc', 'openshift', 'kubernetes']
+
+        for line in stdout.strip().split('\n'):
+            for term in version_search:
+                if not line:
+                    continue
+                if line.startswith(term):
+                    version_dict[term] = line.split()[-1]
+
+        # horrible hack to get openshift version in Openshift 3.2
+        #  By default "oc version in 3.2 does not return an "openshift" version
+        if "openshift" not in version_dict:
+            version_dict["openshift"] = version_dict["oc"]
+
+        return version_dict
+
+    @staticmethod
+    def add_custom_versions(versions):
+        ''' create custom versions strings '''
+
+        versions_dict = {}
+
+        for tech, version in versions.items():
+            # clean up "-" from version
+            if "-" in version:
+                version = version.split("-")[0]
+
+            if version.startswith('v'):
+                versions_dict[tech + '_numeric'] = version[1:].split('+')[0]
+                # "v3.3.0.33" is what we have, we want "3.3"
+                versions_dict[tech + '_short'] = version[1:4]
+
+        return versions_dict
+
+    @staticmethod
+    def openshift_installed():
+        ''' check if openshift is installed '''
+        import yum
+
+        yum_base = yum.YumBase()
+        if yum_base.rpmdb.searchNevra(name='atomic-openshift'):
+            return True
+
+        return False
+
     # Disabling too-many-branches.  This is a yaml dictionary comparison function
     # pylint: disable=too-many-branches,too-many-return-statements,too-many-statements
     @staticmethod
@@ -1204,7 +1258,9 @@ class RouteConfig(object):
                  key=None,
                  host=None,
                  tls_termination=None,
-                 service_name=None):
+                 service_name=None,
+                 wildcard_policy=None,
+                 weight=None):
         ''' constructor for handling route options '''
         self.kubeconfig = kubeconfig
         self.name = sname
@@ -1217,6 +1273,12 @@ class RouteConfig(object):
         self.key = key
         self.service_name = service_name
         self.data = {}
+        self.wildcard_policy = wildcard_policy
+        if wildcard_policy is None:
+            self.wildcard_policy = 'None'
+        self.weight = weight
+        if weight is None:
+            self.weight = 100
 
         self.create_dict()
 
@@ -1241,14 +1303,19 @@ class RouteConfig(object):
             self.data['spec']['tls']['certificate'] = self.cert
             self.data['spec']['tls']['termination'] = self.tls_termination
 
-        self.data['spec']['to'] = {'kind': 'Service', 'name': self.service_name}
+        self.data['spec']['to'] = {'kind': 'Service',
+                                   'name': self.service_name,
+                                   'weight': self.weight}
 
+        self.data['spec']['wildcardPolicy'] = self.wildcard_policy
 
 # pylint: disable=too-many-instance-attributes,too-many-public-methods
 class Route(Yedit):
     ''' Class to wrap the oc command line tools '''
+    wildcard_policy = "spec.wildcardPolicy"
     host_path = "spec.host"
     service_path = "spec.to.name"
+    weight_path = "spec.to.weight"
     cert_path = "spec.tls.certificate"
     cacert_path = "spec.tls.caCertificate"
     destcacert_path = "spec.tls.destinationCACertificate"
@@ -1280,6 +1347,10 @@ class Route(Yedit):
         ''' return service name '''
         return self.get(Route.service_path)
 
+    def get_weight(self):
+        ''' return service weight '''
+        return self.get(Route.weight_path)
+
     def get_termination(self):
         ''' return tls termination'''
         return self.get(Route.termination_path)
@@ -1288,6 +1359,10 @@ class Route(Yedit):
         ''' return host '''
         return self.get(Route.host_path)
 
+    def get_wildcard_policy(self):
+        ''' return wildcardPolicy '''
+        return self.get(Route.wildcard_policy)
+
 
 # pylint: disable=too-many-instance-attributes
 class OCRoute(OpenShiftCLI):
@@ -1375,7 +1450,9 @@ class OCRoute(OpenShiftCLI):
                               files['key']['value'],
                               params['host'],
                               params['tls_termination'],
-                              params['service_name'])
+                              params['service_name'],
+                              params['wildcard_policy'],
+                              params['weight'])
 
         oc_route = OCRoute(rconfig, verbose=params['debug'])
 
@@ -1418,13 +1495,13 @@ class OCRoute(OpenShiftCLI):
                 api_rval = oc_route.create()
 
                 if api_rval['returncode'] != 0:
-                    return {'failed': True, 'results': api_rval, 'state': "present"}  # noqa: E501
+                    return {'failed': True, 'msg': api_rval, 'state': "present"}  # noqa: E501
 
                 # return the created object
                 api_rval = oc_route.get()
 
                 if api_rval['returncode'] != 0:
-                    return {'failed': True, 'results': api_rval, 'state': "present"}  # noqa: E501
+                    return {'failed': True, 'msg': api_rval, 'state': "present"}  # noqa: E501
 
                 return {'changed': True, 'results': api_rval, 'state': "present"}  # noqa: E501
 
@@ -1439,13 +1516,13 @@ class OCRoute(OpenShiftCLI):
                 api_rval = oc_route.update()
 
                 if api_rval['returncode'] != 0:
-                    return {'failed': True, 'results': api_rval, 'state': "present"}  # noqa: E501
+                    return {'failed': True, 'msg': api_rval, 'state': "present"}  # noqa: E501
 
                 # return the created object
                 api_rval = oc_route.get()
 
                 if api_rval['returncode'] != 0:
-                    return {'failed': True, 'results': api_rval, 'state': "present"}  # noqa: E501
+                    return {'failed': True, 'msg': api_rval, 'state': "present"}  # noqa: E501
 
                 return {'changed': True, 'results': api_rval, 'state': "present"}  # noqa: E501
 
@@ -1493,6 +1570,8 @@ def main():
             key_content=dict(default=None, type='str'),
             service_name=dict(default=None, type='str'),
             host=dict(default=None, type='str'),
+            wildcard_policy=dict(default=None, type='str'),
+            weight=dict(default=None, type='int'),
         ),
         mutually_exclusive=[('dest_cacert_path', 'dest_cacert_content'),
                             ('cacert_path', 'cacert_content'),

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1232 - 0
roles/lib_openshift/library/oc_version.py


+ 2 - 0
roles/lib_openshift/src/ansible/oc_route.py

@@ -40,6 +40,8 @@ def main():
             key_content=dict(default=None, type='str'),
             service_name=dict(default=None, type='str'),
             host=dict(default=None, type='str'),
+            wildcard_policy=dict(default=None, type='str'),
+            weight=dict(default=None, type='int'),
         ),
         mutually_exclusive=[('dest_cacert_path', 'dest_cacert_content'),
                             ('cacert_path', 'cacert_content'),

+ 26 - 0
roles/lib_openshift/src/ansible/oc_version.py

@@ -0,0 +1,26 @@
+# pylint: skip-file
+# flake8: noqa
+
+def main():
+    ''' ansible oc module for version '''
+
+    module = AnsibleModule(
+        argument_spec=dict(
+            kubeconfig=dict(default='/etc/origin/master/admin.kubeconfig', type='str'),
+            state=dict(default='list', type='str',
+                       choices=['list']),
+            debug=dict(default=False, type='bool'),
+        ),
+        supports_check_mode=True,
+    )
+
+    rval = OCVersion.run_ansible(module.params)
+    if 'failed' in rval:
+        module.fail_json(**rval)
+
+
+    module.exit_json(**rval)
+
+
+if __name__ == '__main__':
+    main()

+ 7 - 5
roles/lib_openshift/src/class/oc_route.py

@@ -88,7 +88,9 @@ class OCRoute(OpenShiftCLI):
                               files['key']['value'],
                               params['host'],
                               params['tls_termination'],
-                              params['service_name'])
+                              params['service_name'],
+                              params['wildcard_policy'],
+                              params['weight'])
 
         oc_route = OCRoute(rconfig, verbose=params['debug'])
 
@@ -131,13 +133,13 @@ class OCRoute(OpenShiftCLI):
                 api_rval = oc_route.create()
 
                 if api_rval['returncode'] != 0:
-                    return {'failed': True, 'results': api_rval, 'state': "present"}  # noqa: E501
+                    return {'failed': True, 'msg': api_rval, 'state': "present"}  # noqa: E501
 
                 # return the created object
                 api_rval = oc_route.get()
 
                 if api_rval['returncode'] != 0:
-                    return {'failed': True, 'results': api_rval, 'state': "present"}  # noqa: E501
+                    return {'failed': True, 'msg': api_rval, 'state': "present"}  # noqa: E501
 
                 return {'changed': True, 'results': api_rval, 'state': "present"}  # noqa: E501
 
@@ -152,13 +154,13 @@ class OCRoute(OpenShiftCLI):
                 api_rval = oc_route.update()
 
                 if api_rval['returncode'] != 0:
-                    return {'failed': True, 'results': api_rval, 'state': "present"}  # noqa: E501
+                    return {'failed': True, 'msg': api_rval, 'state': "present"}  # noqa: E501
 
                 # return the created object
                 api_rval = oc_route.get()
 
                 if api_rval['returncode'] != 0:
-                    return {'failed': True, 'results': api_rval, 'state': "present"}  # noqa: E501
+                    return {'failed': True, 'msg': api_rval, 'state': "present"}  # noqa: E501
 
                 return {'changed': True, 'results': api_rval, 'state': "present"}  # noqa: E501
 

+ 47 - 0
roles/lib_openshift/src/class/oc_version.py

@@ -0,0 +1,47 @@
+# flake8: noqa
+# pylint: skip-file
+
+
+# pylint: disable=too-many-instance-attributes
+class OCVersion(OpenShiftCLI):
+    ''' Class to wrap the oc command line tools '''
+    # pylint allows 5
+    # pylint: disable=too-many-arguments
+    def __init__(self,
+                 config,
+                 debug):
+        ''' Constructor for OCVersion '''
+        super(OCVersion, self).__init__(None, config)
+        self.debug = debug
+
+    def get(self):
+        '''get and return version information '''
+
+        results = {}
+
+        version_results = self._version()
+
+        if version_results['returncode'] == 0:
+            filtered_vers = Utils.filter_versions(version_results['results'])
+            custom_vers = Utils.add_custom_versions(filtered_vers)
+
+            results['returncode'] = version_results['returncode']
+            results.update(filtered_vers)
+            results.update(custom_vers)
+
+            return results
+
+        raise OpenShiftCLIError('Problem detecting openshift version.')
+
+    @staticmethod
+    def run_ansible(params):
+        '''run the idempotent ansible code'''
+        oc_version = OCVersion(params['kubeconfig'], params['debug'])
+
+        if params['state'] == 'list':
+
+            #pylint: disable=protected-access
+            result = oc_version.get()
+            return {'state': params['state'],
+                    'results': result,
+                    'changed': False}

+ 40 - 0
roles/lib_openshift/src/doc/version

@@ -0,0 +1,40 @@
+# flake8: noqa
+# pylint: skip-file
+
+DOCUMENTATION = '''
+---
+module: oc_version
+short_description: Return the current openshift version
+description:
+  - Return the openshift installed version.  `oc version`
+options:
+  state:
+    description:
+    - Currently list is only supported state.
+    required: true
+    default: list
+    choices: ["list"]
+    aliases: []
+  kubeconfig:
+    description:
+    - The path for the kubeconfig file to use for authentication
+    required: false
+    default: /etc/origin/master/admin.kubeconfig
+    aliases: []
+  debug:
+    description:
+    - Turn on debug output.
+    required: false
+    default: False
+    aliases: []
+author:
+- "Kenny Woodson <kwoodson@redhat.com>"
+extends_documentation_fragment: []
+'''
+
+EXAMPLES = '''
+oc_version:
+- name: get oc version
+  oc_version:
+  register: oc_version
+'''

+ 65 - 11
roles/lib_openshift/src/lib/base.py

@@ -48,7 +48,7 @@ class OpenShiftCLI(object):
 
     def _replace(self, fname, force=False):
         '''replace the current object with oc replace'''
-        cmd = ['-n', self.namespace, 'replace', '-f', fname]
+        cmd = ['replace', '-f', fname]
         if force:
             cmd.append('--force')
         return self.openshift_cmd(cmd)
@@ -65,11 +65,11 @@ class OpenShiftCLI(object):
 
     def _create(self, fname):
         '''call oc create on a filename'''
-        return self.openshift_cmd(['create', '-f', fname, '-n', self.namespace])
+        return self.openshift_cmd(['create', '-f', fname])
 
     def _delete(self, resource, rname, selector=None):
         '''call oc delete on a resource'''
-        cmd = ['delete', resource, rname, '-n', self.namespace]
+        cmd = ['delete', resource, rname]
         if selector:
             cmd.append('--selector=%s' % selector)
 
@@ -83,8 +83,7 @@ class OpenShiftCLI(object):
            params: the parameters for the template
            template_data: the incoming template's data; instead of a file
         '''
-
-        cmd = ['process', '-n', self.namespace]
+        cmd = ['process']
         if template_data:
             cmd.extend(['-f', '-'])
         else:
@@ -105,17 +104,13 @@ class OpenShiftCLI(object):
 
         atexit.register(Utils.cleanup, [fname])
 
-        return self.openshift_cmd(['-n', self.namespace, 'create', '-f', fname])
+        return self.openshift_cmd(['create', '-f', fname])
 
     def _get(self, resource, rname=None, selector=None):
         '''return a resource by name '''
         cmd = ['get', resource]
         if selector:
             cmd.append('--selector=%s' % selector)
-        if self.all_namespaces:
-            cmd.extend(['--all-namespaces'])
-        elif self.namespace:
-            cmd.extend(['-n', self.namespace])
 
         cmd.extend(['-o', 'json'])
 
@@ -189,6 +184,10 @@ class OpenShiftCLI(object):
 
         return self.openshift_cmd(cmd, oadm=True, output=True, output_type='raw')
 
+    def _version(self):
+        ''' return the openshift version'''
+        return self.openshift_cmd(['version'], output=True, output_type='raw')
+
     def _import_image(self, url=None, name=None, tag=None):
         ''' perform image import '''
         cmd = ['import-image']
@@ -207,7 +206,7 @@ class OpenShiftCLI(object):
         cmd.append('--confirm')
         return self.openshift_cmd(cmd)
 
-    # pylint: disable=too-many-arguments
+    # pylint: disable=too-many-arguments,too-many-branches
     def openshift_cmd(self, cmd, oadm=False, output=False, output_type='json', input_data=None):
         '''Base command for oc '''
         cmds = []
@@ -216,6 +215,11 @@ class OpenShiftCLI(object):
         else:
             cmds = ['/usr/bin/oc']
 
+        if self.all_namespaces:
+            cmds.extend(['--all-namespaces'])
+        elif self.namespace:
+            cmds.extend(['-n', self.namespace])
+
         cmds.extend(cmd)
 
         rval = {}
@@ -341,6 +345,56 @@ class Utils(object):
 
         return contents
 
+    @staticmethod
+    def filter_versions(stdout):
+        ''' filter the oc version output '''
+
+        version_dict = {}
+        version_search = ['oc', 'openshift', 'kubernetes']
+
+        for line in stdout.strip().split('\n'):
+            for term in version_search:
+                if not line:
+                    continue
+                if line.startswith(term):
+                    version_dict[term] = line.split()[-1]
+
+        # horrible hack to get openshift version in Openshift 3.2
+        #  By default "oc version in 3.2 does not return an "openshift" version
+        if "openshift" not in version_dict:
+            version_dict["openshift"] = version_dict["oc"]
+
+        return version_dict
+
+    @staticmethod
+    def add_custom_versions(versions):
+        ''' create custom versions strings '''
+
+        versions_dict = {}
+
+        for tech, version in versions.items():
+            # clean up "-" from version
+            if "-" in version:
+                version = version.split("-")[0]
+
+            if version.startswith('v'):
+                versions_dict[tech + '_numeric'] = version[1:].split('+')[0]
+                # "v3.3.0.33" is what we have, we want "3.3"
+                versions_dict[tech + '_short'] = version[1:4]
+
+        return versions_dict
+
+    @staticmethod
+    def openshift_installed():
+        ''' check if openshift is installed '''
+        import yum
+
+        yum_base = yum.YumBase()
+        if yum_base.rpmdb.searchNevra(name='atomic-openshift'):
+            return True
+
+        return False
+
     # Disabling too-many-branches.  This is a yaml dictionary comparison function
     # pylint: disable=too-many-branches,too-many-return-statements,too-many-statements
     @staticmethod

+ 23 - 2
roles/lib_openshift/src/lib/route.py

@@ -17,7 +17,9 @@ class RouteConfig(object):
                  key=None,
                  host=None,
                  tls_termination=None,
-                 service_name=None):
+                 service_name=None,
+                 wildcard_policy=None,
+                 weight=None):
         ''' constructor for handling route options '''
         self.kubeconfig = kubeconfig
         self.name = sname
@@ -30,6 +32,12 @@ class RouteConfig(object):
         self.key = key
         self.service_name = service_name
         self.data = {}
+        self.wildcard_policy = wildcard_policy
+        if wildcard_policy is None:
+            self.wildcard_policy = 'None'
+        self.weight = weight
+        if weight is None:
+            self.weight = 100
 
         self.create_dict()
 
@@ -54,14 +62,19 @@ class RouteConfig(object):
             self.data['spec']['tls']['certificate'] = self.cert
             self.data['spec']['tls']['termination'] = self.tls_termination
 
-        self.data['spec']['to'] = {'kind': 'Service', 'name': self.service_name}
+        self.data['spec']['to'] = {'kind': 'Service',
+                                   'name': self.service_name,
+                                   'weight': self.weight}
 
+        self.data['spec']['wildcardPolicy'] = self.wildcard_policy
 
 # pylint: disable=too-many-instance-attributes,too-many-public-methods
 class Route(Yedit):
     ''' Class to wrap the oc command line tools '''
+    wildcard_policy = "spec.wildcardPolicy"
     host_path = "spec.host"
     service_path = "spec.to.name"
+    weight_path = "spec.to.weight"
     cert_path = "spec.tls.certificate"
     cacert_path = "spec.tls.caCertificate"
     destcacert_path = "spec.tls.destinationCACertificate"
@@ -93,6 +106,10 @@ class Route(Yedit):
         ''' return service name '''
         return self.get(Route.service_path)
 
+    def get_weight(self):
+        ''' return service weight '''
+        return self.get(Route.weight_path)
+
     def get_termination(self):
         ''' return tls termination'''
         return self.get(Route.termination_path)
@@ -100,3 +117,7 @@ class Route(Yedit):
     def get_host(self):
         ''' return host '''
         return self.get(Route.host_path)
+
+    def get_wildcard_policy(self):
+        ''' return wildcardPolicy '''
+        return self.get(Route.wildcard_policy)

+ 9 - 0
roles/lib_openshift/src/sources.yml

@@ -27,3 +27,12 @@ oc_route.py:
 - lib/route.py
 - class/oc_route.py
 - ansible/oc_route.py
+oc_version.py:
+- doc/generated
+- doc/license
+- lib/import.py
+- doc/version
+- ../../lib_utils/src/class/yedit.py
+- lib/base.py
+- class/oc_version.py
+- ansible/oc_version.py

+ 24 - 5
roles/lib_openshift/src/test/integration/route.yml

@@ -1,5 +1,5 @@
-#!/usr/bin/ansible-playbook
-# ./route.yml -M ../../../library -e "cli_master_test=$OPENSHIFT_MASTER
+#!/usr/bin/ansible-playbook --module-path=../../../library/
+# ./oc_route.yml -M ../../../library -e "cli_master_test=$OPENSHIFT_MASTER
 ---
 - hosts: "{{ cli_master_test }}"
   gather_facts: no
@@ -8,15 +8,20 @@
   - name: create route
     oc_route:
       name: test
-      namespace: test
+      namespace: default
       tls_termination: edge
       cert_content: testing cert
       cacert_content: testing cacert
+      key_content: key content
       service_name: test
       host: test.example
     register: routeout
   - debug: var=routeout
 
+  - assert:
+      that: "routeout.results.results[0]['metadata']['name'] == 'test'"
+      msg: route create failed
+
   - name: get route
     oc_route:
       state: list
@@ -25,6 +30,10 @@
     register: routeout
   - debug: var=routeout
 
+  - assert:
+      that: "routeout.results[0]['metadata']['name'] == 'test'"
+      msg: get route failed
+
   - name: delete route
     oc_route:
       state: absent
@@ -33,13 +42,18 @@
     register: routeout
   - debug: var=routeout
 
+  - assert:
+      that: "routeout.results.returncode == 0"
+      msg: delete route failed
+
   - name: create route
     oc_route:
       name: test
-      namespace: test
+      namespace: default
       tls_termination: edge
       cert_content: testing cert
       cacert_content: testing cacert
+      key_content: testing key
       service_name: test
       host: test.example
     register: routeout
@@ -48,11 +62,16 @@
   - name: create route noop
     oc_route:
       name: test
-      namespace: test
+      namespace: default
       tls_termination: edge
       cert_content: testing cert
       cacert_content: testing cacert
+      key_content: testing key
       service_name: test
       host: test.example
     register: routeout
   - debug: var=routeout
+
+  - assert:
+      that: "routeout.changed == False"
+      msg: Route create not idempotent

+ 17 - 0
roles/lib_openshift/src/test/integration/oc_version.yml

@@ -0,0 +1,17 @@
+#!/usr/bin/ansible-playbook --module-path=../../../library/
+# ./oc_version.yml -e "cli_master_test=$OPENSHIFT_MASTER
+---
+- hosts: "{{ cli_master_test }}"
+  gather_facts: no
+  user: root
+  tasks:
+  - name: Get openshift version
+    oc_version:
+    register: versionout
+
+  - debug: var=versionout
+
+  - assert:
+      that:
+      - "'oc_numeric' in versionout.results.keys()"
+      msg: "Did not find 'oc_numeric' in version results."

+ 70 - 0
roles/lib_openshift/src/test/unit/oc_version.py

@@ -0,0 +1,70 @@
+#!/usr/bin/env python2
+'''
+ Unit tests for oc version
+'''
+# To run
+# python -m unittest version
+#
+# .
+# Ran 1 test in 0.597s
+#
+# OK
+
+import os
+import sys
+import unittest
+
+# Removing invalid variable names for tests so that I can
+# keep them brief
+# pylint: disable=invalid-name,no-name-in-module
+# Disable import-error b/c our libraries aren't loaded in jenkins
+# pylint: disable=import-error,wrong-import-position
+# place class in our python path
+module_path = os.path.join('/'.join(os.path.realpath(__file__).split('/')[:-4]), 'library')  # noqa: E501
+sys.path.insert(0, module_path)
+from oc_version import OCVersion  # noqa: E402
+
+
+# pylint: disable=unused-argument
+def oc_cmd_mock(cmd, oadm=False, output=False, output_type='json', input_data=None):
+    '''mock command for openshift_cmd'''
+    version = '''oc v3.4.0.39
+kubernetes v1.4.0+776c994
+features: Basic-Auth GSSAPI Kerberos SPNEGO
+
+Server https://internal.api.opstest.openshift.com
+openshift v3.4.0.39
+kubernetes v1.4.0+776c994
+'''
+    if 'version' in cmd:
+        return {'stderr': None,
+                'stdout': version,
+                'returncode': 0,
+                'results': version,
+                'cmd': cmd}
+
+
+class OCVersionTest(unittest.TestCase):
+    '''
+     Test class for OCVersion
+    '''
+
+    def setUp(self):
+        ''' setup method will create a file and set to known configuration '''
+        self.oc_ver = OCVersion(None, False)
+        self.oc_ver.openshift_cmd = oc_cmd_mock
+
+    def test_get(self):
+        ''' Testing a get '''
+        results = self.oc_ver.get()
+        self.assertEqual(results['oc_short'], '3.4')
+        self.assertEqual(results['oc_numeric'], '3.4.0.39')
+        self.assertEqual(results['kubernetes_numeric'], '1.4.0')
+
+    def tearDown(self):
+        '''TearDown method'''
+        pass
+
+
+if __name__ == "__main__":
+    unittest.main()

+ 0 - 14
roles/openshift_examples/files/examples/v1.3/quickstart-templates/jenkins-ephemeral-template.json

@@ -98,14 +98,6 @@
                 },
                 "env": [
                   {
-                    "name": "OPENSHIFT_ENABLE_OAUTH",
-                    "value": "${ENABLE_OAUTH}"
-                  },
-                  {
-                    "name": "OPENSHIFT_ENABLE_REDIRECT_PROMPT",
-                    "value": "true"
-                  },
-                  {
                     "name": "KUBERNETES_MASTER",
                     "value": "https://kubernetes.default:443"
                   },
@@ -245,12 +237,6 @@
       "value": "jenkins-jnlp"
     },
     {
-      "name": "ENABLE_OAUTH",
-      "displayName": "Enable OAuth in Jenkins",
-      "description": "Whether to enable OAuth OpenShift integration. If false, the static account 'admin' will be initialized with the password 'password'.",
-      "value": "true"
-    },
-    {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
       "description": "Maximum amount of memory the container can use.",

+ 0 - 14
roles/openshift_examples/files/examples/v1.3/quickstart-templates/jenkins-persistent-template.json

@@ -115,14 +115,6 @@
                 },
                 "env": [
                   {
-                    "name": "OPENSHIFT_ENABLE_OAUTH",
-                    "value": "${ENABLE_OAUTH}"
-                  },
-                  {
-                    "name": "OPENSHIFT_ENABLE_REDIRECT_PROMPT",
-                    "value": "true"
-                  },
-                  {
                     "name": "KUBERNETES_MASTER",
                     "value": "https://kubernetes.default:443"
                   },
@@ -262,12 +254,6 @@
       "value": "jenkins-jnlp"
     },
     {
-      "name": "ENABLE_OAUTH",
-      "displayName": "Enable OAuth in Jenkins",
-      "description": "Whether to enable OAuth OpenShift integration. If false, the static account 'admin' will be initialized with the password 'password'.",
-      "value": "true"
-    },
-    {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
       "description": "Maximum amount of memory the container can use.",

+ 1 - 1
roles/openshift_loadbalancer/defaults/main.yml

@@ -2,7 +2,7 @@
 haproxy_frontends:
 - name: main
   binds:
-  - "*:8443"
+  - "*:{{ openshift_master_api_port | default(8443) }}"
   default_backend: default
 
 haproxy_backends:

+ 22 - 3
roles/openshift_loadbalancer/tasks/main.yml

@@ -1,14 +1,31 @@
 ---
-- fail: msg="Cannot use containerized=true for load balancer hosts."
-  when: openshift.common.is_containerized | bool
-
 - name: Install haproxy
   package: name=haproxy state=present
+  when: not openshift.common.is_containerized | bool
+
+- name: Pull haproxy image
+  command: >
+    docker pull {{ openshift.common.router_image }}:{{ openshift_image_tag }}
+  when: openshift.common.is_containerized | bool
+
+- name: Create config directory for haproxy
+  file:
+    path: /etc/haproxy
+    state: directory
+  when: openshift.common.is_containerized | bool
+
+- name: Create the systemd unit files
+  template:
+    src: "haproxy.docker.service.j2"
+    dest: "{{ containerized_svc_dir }}/haproxy.service"
+  when: openshift.common.is_containerized | bool
+  notify: restart haproxy
 
 - name: Configure systemd service directory for haproxy
   file:
     path: /etc/systemd/system/haproxy.service.d
     state: directory
+  when: not openshift.common.is_containerized | bool
 
 # Work around ini_file create option in 2.2 which defaults to no
 - name: Create limits.conf file
@@ -19,6 +36,7 @@
     owner: root
     group: root
   changed_when: false
+  when: not openshift.common.is_containerized | bool
 
 - name: Configure the nofile limits for haproxy
   ini_file:
@@ -27,6 +45,7 @@
     option: LimitNOFILE
     value: "{{ openshift_loadbalancer_limit_nofile | default(100000) }}"
   notify: restart haproxy
+  when: not openshift.common.is_containerized | bool
 
 - name: Configure haproxy
   template:

+ 17 - 0
roles/openshift_loadbalancer/templates/haproxy.docker.service.j2

@@ -0,0 +1,17 @@
+[Unit]
+After=docker.service
+Requires=docker.service
+PartOf=docker.service
+
+[Service]
+ExecStartPre=-/usr/bin/docker rm -f openshift_loadbalancer
+ExecStart=/usr/bin/docker run --rm --name openshift_loadbalancer -p {{ openshift_master_api_port | default(8443) }}:{{ openshift_master_api_port | default(8443) }} -v /etc/haproxy/haproxy.cfg:/etc/haproxy/haproxy.cfg:ro --entrypoint="haproxy -f /etc/haproxy/haproxy.cfg" {{ openshift.common.router_image }}:{{ openshift_image_tag }}
+ExecStartPost=/usr/bin/sleep 10
+ExecStop=/usr/bin/docker stop openshift_loadbalancer
+LimitNOFILE={{ openshift_loadbalancer_limit_nofile | default(100000) }}
+LimitCORE=infinity
+Restart=always
+RestartSec=5s
+
+[Install]
+WantedBy=docker.service

+ 14 - 7
roles/openshift_logging/tasks/install_logging.yaml

@@ -23,23 +23,30 @@
   loop_control:
     loop_var: install_component
 
+- find: paths={{ mktemp.stdout }}/templates patterns=*.yaml
+  register: object_def_files
+  changed_when: no
+
+- slurp: src={{item}}
+  register: object_defs
+  with_items: "{{object_def_files.files | map(attribute='path') | list | sort}}"
+  changed_when: no
+
 - name: Create objects
   include: oc_apply.yaml
   vars:
     - kubeconfig: "{{ mktemp.stdout }}/admin.kubeconfig"
     - namespace: "{{ openshift_logging_namespace }}"
-    - file_name: "{{ file }}"
-    - file_content: "{{ lookup('file', file) | from_yaml }}"
-  with_fileglob:
-    - "{{ mktemp.stdout }}/templates/*.yaml"
+    - file_name: "{{ file.source }}"
+    - file_content: "{{ file.content | b64decode | from_yaml }}"
+  with_items: "{{ object_defs.results }}"
   loop_control:
     loop_var: file
   when: not ansible_check_mode
 
 - name: Printing out objects to create
-  debug: msg="{{lookup('file', file)|quote}}"
-  with_fileglob:
-    - "{{mktemp.stdout}}/templates/*.yaml"
+  debug: msg={{file.content | b64decode }}
+  with_items: "{{ object_defs.results }}"
   loop_control:
     loop_var: file
   when: ansible_check_mode

+ 4 - 4
roles/openshift_master_certificates/tasks/main.yml

@@ -105,7 +105,7 @@
 
 - name: Create local temp directory for syncing certs
   local_action: command mktemp -d /tmp/openshift-ansible-XXXXXXX
-  register: g_master_mktemp
+  register: g_master_certs_mktemp
   changed_when: False
   when: master_certs_missing | bool
   delegate_to: localhost
@@ -123,7 +123,7 @@
 - name: Retrieve the master cert tarball from the master
   fetch:
     src: "{{ openshift_master_generated_config_dir }}.tgz"
-    dest: "{{ g_master_mktemp.stdout }}/"
+    dest: "{{ g_master_certs_mktemp.stdout }}/"
     flat: yes
     fail_on_missing: yes
     validate_checksum: yes
@@ -138,11 +138,11 @@
 
 - name: Unarchive the tarball on the master
   unarchive:
-    src: "{{ g_master_mktemp.stdout }}/{{ openshift_master_cert_subdir }}.tgz"
+    src: "{{ g_master_certs_mktemp.stdout }}/{{ openshift_master_cert_subdir }}.tgz"
     dest: "{{ openshift_master_config_dir }}"
   when: master_certs_missing | bool and inventory_hostname != openshift_ca_host
 
-- file: name={{ g_master_mktemp.stdout }} state=absent
+- file: name={{ g_master_certs_mktemp.stdout }} state=absent
   changed_when: False
   when: master_certs_missing | bool
   delegate_to: localhost

+ 4 - 0
roles/openshift_metrics/README.md

@@ -5,6 +5,10 @@ OpenShift Metrics Installation
 
 Requirements
 ------------
+This role has the following dependencies:
+
+- Java is required on the control node to generate keystores for the Java components
+- httpd-tools is required on the control node to generate various passwords for the metrics components
 
 The following variables need to be set and will be validated:
 

+ 12 - 4
roles/openshift_metrics/tasks/install_metrics.yaml

@@ -20,15 +20,23 @@
   loop_control:
     loop_var: include_file
 
+- find: paths={{ mktemp.stdout }}/templates patterns=*.yaml
+  register: object_def_files
+  changed_when: no
+
+- slurp: src={{item.path}}
+  register: object_defs
+  with_items: "{{object_def_files.files}}"
+  changed_when: no
+
 - name: Create objects
   include: oc_apply.yaml
   vars:
     kubeconfig: "{{ mktemp.stdout }}/admin.kubeconfig"
     namespace: "{{ openshift_metrics_project }}"
-    file_name: "{{ item }}"
-    file_content: "{{ lookup('file',item) | from_yaml }}"
-  with_fileglob:
-    - "{{ mktemp.stdout }}/templates/*.yaml"
+    file_name: "{{ item.source }}"
+    file_content: "{{ item.content | b64decode | from_yaml }}"
+  with_items: "{{ object_defs.results }}"
 
 - name: Scaling up cluster
   include: start_metrics.yaml

+ 18 - 0
roles/openshift_metrics/tasks/install_support.yaml

@@ -1,4 +1,22 @@
 ---
+- name: Check control node to see if htpasswd is installed
+  local_action: command which htpasswd
+  register: htpasswd_check
+  failed_when: no
+  changed_when: no
+
+- fail: msg="'htpasswd' is unavailable. Please install httpd-tools on the control node"
+  when: htpasswd_check.rc  == 1
+
+- name: Check control node to see if keytool is installed
+  local_action: command which htpasswd
+  register: keytool_check
+  failed_when: no
+  changed_when: no
+
+- fail: msg="'keytool' is unavailable. Please install java-1.8.0-openjdk-headless on the control node"
+  when: keytool_check.rc  == 1
+
 - include: generate_certificates.yaml
 - include: generate_serviceaccounts.yaml
 - include: generate_services.yaml

+ 2 - 2
roles/openshift_node/meta/main.yml

@@ -17,8 +17,6 @@ dependencies:
 - role: openshift_docker
 - role: openshift_node_certificates
 - role: openshift_cloud_provider
-- role: openshift_node_dnsmasq
-  when: openshift.common.use_dnsmasq | bool
 - role: os_firewall
   os_firewall_allow:
   - service: Kubernetes kubelet
@@ -43,3 +41,5 @@ dependencies:
   - service: Kubernetes service NodePort UDP
     port: "{{ openshift_node_port_range | default('') }}/udp"
   when: openshift_node_port_range is defined
+- role: openshift_node_dnsmasq
+  when: openshift.common.use_dnsmasq | bool