Browse Source

Merge pull request #3130 from kwoodson/lib_openshift_version

Adding oc_version to lib_openshift.
Kenny Woodson 8 years ago
parent
commit
30b1000c0f

+ 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'),

File diff suppressed because it is too large
+ 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()