diff options
54 files changed, 4551 insertions, 294 deletions
diff --git a/.travis.yml b/.travis.yml index 001bfdc39..c88214bc2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,4 @@ install: script: # TODO(rhcarvalho): check syntax of other important entrypoint playbooks - ansible-playbook --syntax-check playbooks/byo/config.yml - # TODO(rhcarvalho): update make ci to pick up these tests - - nosetests --tests=test - cd utils && make ci diff --git a/callback_plugins/default.py b/callback_plugins/default.py index c64145b5c..97ad77724 100644 --- a/callback_plugins/default.py +++ b/callback_plugins/default.py @@ -30,7 +30,7 @@ DEFAULT_MODULE = imp.load_source( try: from ansible.plugins.callback import CallbackBase BASECLASS = CallbackBase -except ImportError: # < ansible 2.1 +except ImportError: # < ansible 2.1 BASECLASS = DEFAULT_MODULE.CallbackModule @@ -46,6 +46,7 @@ class CallbackModule(DEFAULT_MODULE.CallbackModule): # pylint: disable=too-few- CALLBACK_NAME = 'default' def __init__(self, *args, **kwargs): + # pylint: disable=non-parent-init-called BASECLASS.__init__(self, *args, **kwargs) def _dump_results(self, result): @@ -57,7 +58,7 @@ class CallbackModule(DEFAULT_MODULE.CallbackModule): # pylint: disable=too-few- if key in result: save[key] = result.pop(key) - output = BASECLASS._dump_results(self, result) # pylint: disable=protected-access + output = BASECLASS._dump_results(self, result) # pylint: disable=protected-access for key in ['stdout', 'stderr', 'msg']: if key in save and save[key]: diff --git a/filter_plugins/oo_filters.py b/filter_plugins/oo_filters.py index 997634777..c3f94feff 100644 --- a/filter_plugins/oo_filters.py +++ b/filter_plugins/oo_filters.py @@ -1,32 +1,32 @@ #!/usr/bin/python # -*- coding: utf-8 -*- # vim: expandtab:tabstop=4:shiftwidth=4 +# pylint: disable=no-name-in-module, import-error, wrong-import-order, ungrouped-imports """ Custom filters for use in openshift-ansible """ +import os +import pdb +import pkg_resources +import re +import json +import yaml from ansible import errors from collections import Mapping from distutils.util import strtobool from distutils.version import LooseVersion from operator import itemgetter +from ansible.parsing.yaml.dumper import AnsibleDumper +from urlparse import urlparse -HAS_OPENSSL=False +HAS_OPENSSL = False try: import OpenSSL.crypto - HAS_OPENSSL=True + HAS_OPENSSL = True except ImportError: pass -import os -import pdb -import pkg_resources -import re -import json -import yaml -from ansible.parsing.yaml.dumper import AnsibleDumper -from urlparse import urlparse - try: # ansible-2.2 # ansible.utils.unicode.to_unicode is deprecated in ansible-2.2, @@ -36,6 +36,7 @@ except ImportError: # ansible-2.1 from ansible.utils.unicode import to_unicode as to_text + # Disabling too-many-public-methods, since filter methods are necessarily # public # pylint: disable=too-many-public-methods @@ -74,7 +75,6 @@ class FilterModule(object): return ptr - @staticmethod def oo_flatten(data): """ This filter plugin will flatten a list of lists @@ -163,7 +163,7 @@ class FilterModule(object): else: retval = [FilterModule.get_attr(d, attribute) for d in data] - retval = [val for val in retval if val != None] + retval = [val for val in retval if val is not None] return retval @@ -241,6 +241,7 @@ class FilterModule(object): arrange them as a string 'key=value key=value' """ if not isinstance(data, dict): + # pylint: disable=line-too-long raise errors.AnsibleFilterError("|failed expects first param is a dict [oo_combine_dict]. Got %s. Type: %s" % (str(data), str(type(data)))) return out_joiner.join([in_joiner.join([k, str(v)]) for k, v in data.items()]) @@ -293,6 +294,7 @@ class FilterModule(object): } """ if not isinstance(data, dict): + # pylint: disable=line-too-long raise errors.AnsibleFilterError("|failed expects first param is a dict [oo_ec2_volume_def]. Got %s. Type: %s" % (str(data), str(type(data)))) if host_type not in ['master', 'node', 'etcd']: raise errors.AnsibleFilterError("|failed expects etcd, master or node" @@ -427,7 +429,6 @@ class FilterModule(object): return [n for n in nodes if label_filter(n)] - @staticmethod def oo_parse_heat_stack_outputs(data): """ Formats the HEAT stack output into a usable form @@ -592,8 +593,8 @@ class FilterModule(object): returns 'value2' """ for tag in tags: - if tag[:len(prefix)+len(key)] == prefix + key: - return tag[len(prefix)+len(key)+1:] + if tag[:len(prefix) + len(key)] == prefix + key: + return tag[len(prefix) + len(key) + 1:] raise KeyError(key) def _add_host(clusters, @@ -675,7 +676,7 @@ class FilterModule(object): return facts @staticmethod - # pylint: disable=too-many-branches + # pylint: disable=too-many-branches, too-many-nested-blocks def oo_persistent_volumes(hostvars, groups, persistent_volumes=None): """ Generate list of persistent volumes based on oo_openshift_env storage options set in host variables. @@ -684,10 +685,10 @@ class FilterModule(object): raise errors.AnsibleFilterError("|failed expects hostvars is a dict") if not issubclass(type(groups), dict): raise errors.AnsibleFilterError("|failed expects groups is a dict") - if persistent_volumes != None and not issubclass(type(persistent_volumes), list): + if persistent_volumes is not None and not issubclass(type(persistent_volumes), list): raise errors.AnsibleFilterError("|failed expects persistent_volumes is a list") - if persistent_volumes == None: + if persistent_volumes is None: persistent_volumes = [] if 'hosted' in hostvars['openshift']: for component in hostvars['openshift']['hosted']: @@ -695,10 +696,10 @@ class FilterModule(object): params = hostvars['openshift']['hosted'][component]['storage'] kind = params['kind'] create_pv = params['create_pv'] - if kind != None and create_pv: + if kind is not None and create_pv: if kind == 'nfs': host = params['host'] - if host == None: + if host is None: if 'oo_nfs_to_config' in groups and len(groups['oo_nfs_to_config']) > 0: host = groups['oo_nfs_to_config'][0] else: @@ -746,10 +747,10 @@ class FilterModule(object): """ if not issubclass(type(hostvars), dict): raise errors.AnsibleFilterError("|failed expects hostvars is a dict") - if persistent_volume_claims != None and not issubclass(type(persistent_volume_claims), list): + if persistent_volume_claims is not None and not issubclass(type(persistent_volume_claims), list): raise errors.AnsibleFilterError("|failed expects persistent_volume_claims is a list") - if persistent_volume_claims == None: + if persistent_volume_claims is None: persistent_volume_claims = [] if 'hosted' in hostvars['openshift']: for component in hostvars['openshift']['hosted']: @@ -785,7 +786,7 @@ class FilterModule(object): rpms_31 = [] for rpm in rpms: - if not 'atomic' in rpm: + if 'atomic' not in rpm: rpm = rpm.replace("openshift", "atomic-openshift") if openshift_version: rpm = rpm + openshift_version @@ -816,7 +817,7 @@ class FilterModule(object): for container in pod['spec']['containers']: if re.search(image_regex, container['image']): matching_pods.append(pod) - break # stop here, don't add a pod more than once + break # stop here, don't add a pod more than once return matching_pods @@ -827,7 +828,7 @@ class FilterModule(object): for host in hosts: try: retval.append(hostvars[host]) - except errors.AnsibleError as _: + except errors.AnsibleError: # host does not exist pass @@ -869,6 +870,7 @@ class FilterModule(object): # netloc wasn't parsed, assume url was missing scheme and path return parse_result.path + # pylint: disable=invalid-name, missing-docstring, unused-argument @staticmethod def oo_openshift_loadbalancer_frontends(api_port, servers_hostvars, use_nuage=False, nuage_rest_port=None): loadbalancer_frontends = [{'name': 'atomic-openshift-api', @@ -884,6 +886,7 @@ class FilterModule(object): 'default_backend': 'nuage-monitor'}) return loadbalancer_frontends + # pylint: disable=invalid-name, missing-docstring @staticmethod def oo_openshift_loadbalancer_backends(api_port, servers_hostvars, use_nuage=False, nuage_rest_port=None): loadbalancer_backends = [{'name': 'atomic-openshift-api', @@ -892,6 +895,7 @@ class FilterModule(object): 'balance': 'source', 'servers': FilterModule.oo_haproxy_backend_masters(servers_hostvars, api_port)}] if bool(strtobool(str(use_nuage))) and nuage_rest_port is not None: + # pylint: disable=line-too-long loadbalancer_backends.append({'name': 'nuage-monitor', 'mode': 'tcp', 'option': 'tcplog', diff --git a/filter_plugins/oo_zabbix_filters.py b/filter_plugins/oo_zabbix_filters.py index fcfe43777..1c1854b29 100644 --- a/filter_plugins/oo_zabbix_filters.py +++ b/filter_plugins/oo_zabbix_filters.py @@ -7,6 +7,7 @@ Custom zabbix filters for use in openshift-ansible import pdb + class FilterModule(object): ''' Custom zabbix ansible filters ''' @@ -107,7 +108,7 @@ class FilterModule(object): for results in data: if cluster == results['item'][0]: results = results['results'] - if results and len(results) > 0 and all([results[0].has_key(_key) for _key in keys]): + if results and len(results) > 0 and all([_key in results[0] for _key in keys]): tmp = {} tmp['clusterid'] = cluster for key in keys: diff --git a/filter_plugins/openshift_master.py b/filter_plugins/openshift_master.py index 8d3f31169..57b1f7d82 100644 --- a/filter_plugins/openshift_master.py +++ b/filter_plugins/openshift_master.py @@ -9,20 +9,21 @@ import sys import yaml from ansible import errors -from distutils.version import LooseVersion -# pylint: disable=no-name-in-module,import-error +# pylint: disable=no-name-in-module,import-error,wrong-import-order +from distutils.version import LooseVersion try: # ansible-2.1 from ansible.plugins.filter.core import to_bool as ansible_bool except ImportError: try: - #ansible-2.0.x + # ansible-2.0.x from ansible.runner.filter_plugins.core import bool as ansible_bool except ImportError: # ansible-1.9.x from ansible.plugins.filter.core import bool as ansible_bool + class IdentityProviderBase(object): """ IdentityProviderBase @@ -388,7 +389,6 @@ class OpenIDIdentityProvider(IdentityProviderOauthBase): val = ansible_bool(self._idp['extraAuthorizeParameters'].pop('include_granted_scopes')) self._idp['extraAuthorizeParameters']['include_granted_scopes'] = val - def validate(self): ''' validate this idp instance ''' IdentityProviderOauthBase.validate(self) @@ -495,7 +495,6 @@ class FilterModule(object): idp_inst.set_provider_items() idp_list.append(idp_inst) - IdentityProviderBase.validate_idp_list(idp_list, openshift_version, deployment_type) return yaml.safe_dump([idp.to_dict() for idp in idp_list], default_flow_style=False) @@ -575,7 +574,6 @@ class FilterModule(object): htpasswd_entries[user] = passwd return htpasswd_entries - def filters(self): ''' returns a mapping of filters to methods ''' return {"translate_idps": self.translate_idps, diff --git a/filter_plugins/openshift_node.py b/filter_plugins/openshift_node.py index 22670cf79..8c7302052 100644 --- a/filter_plugins/openshift_node.py +++ b/filter_plugins/openshift_node.py @@ -6,6 +6,7 @@ Custom filters for use in openshift-node ''' from ansible import errors + class FilterModule(object): ''' Custom ansible filters for use by openshift_node role''' @@ -23,7 +24,7 @@ class FilterModule(object): raise errors.AnsibleFilterError("|failed expects hostvars is a dict") # We always use what they've specified if they've specified a value - if openshift_dns_ip != None: + if openshift_dns_ip is not None: return openshift_dns_ip if bool(hostvars['openshift']['common']['use_dnsmasq']): diff --git a/git/parent.py b/git/parent.py index 154a02350..92f57df3e 100755 --- a/git/parent.py +++ b/git/parent.py @@ -1,4 +1,6 @@ #!/usr/bin/env python +# flake8: noqa +# pylint: skip-file ''' Script to determine if this commit has also been merged through the stage branch @@ -93,4 +95,3 @@ def main(): if __name__ == '__main__': main() - diff --git a/git/yaml_validation.py b/git/yaml_validation.py index 69fd455a5..6672876bb 100755 --- a/git/yaml_validation.py +++ b/git/yaml_validation.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# flake8: noqa # # python yaml validator for a git commit # @@ -70,4 +71,3 @@ def main(): if __name__ == "__main__": main() - diff --git a/inventory/aws/hosts/ec2.py b/inventory/aws/hosts/ec2.py index 8b878cafd..7dfcd7889 100755 --- a/inventory/aws/hosts/ec2.py +++ b/inventory/aws/hosts/ec2.py @@ -1,4 +1,5 @@ #!/usr/bin/env python2 +# pylint: skip-file ''' EC2 external inventory script @@ -482,7 +483,7 @@ class Ec2Inventory(object): if e.error_code == 'AuthFailure': error = self.get_auth_error_message() else: - backend = 'Eucalyptus' if self.eucalyptus else 'AWS' + backend = 'Eucalyptus' if self.eucalyptus else 'AWS' error = "Error connecting to %s backend.\n%s" % (backend, e.message) self.fail_with_error(error, 'getting EC2 instances') @@ -700,7 +701,7 @@ class Ec2Inventory(object): if self.nested_groups: self.push_group(self.inventory, 'security_groups', key) except AttributeError: - self.fail_with_error('\n'.join(['Package boto seems a bit older.', + self.fail_with_error('\n'.join(['Package boto seems a bit older.', 'Please upgrade boto >= 2.3.0.'])) # Inventory: Group by tag keys @@ -798,7 +799,7 @@ class Ec2Inventory(object): self.push_group(self.inventory, 'security_groups', key) except AttributeError: - self.fail_with_error('\n'.join(['Package boto seems a bit older.', + self.fail_with_error('\n'.join(['Package boto seems a bit older.', 'Please upgrade boto >= 2.3.0.'])) diff --git a/inventory/gce/hosts/gce.py b/inventory/gce/hosts/gce.py index 99746cdbf..cce3c5f35 100755 --- a/inventory/gce/hosts/gce.py +++ b/inventory/gce/hosts/gce.py @@ -1,4 +1,5 @@ #!/usr/bin/env python2 +# pylint: skip-file # Copyright 2013 Google Inc. # # This file is part of Ansible diff --git a/inventory/libvirt/hosts/libvirt_generic.py b/inventory/libvirt/hosts/libvirt_generic.py index 1c9c17308..ac2f0430a 100755 --- a/inventory/libvirt/hosts/libvirt_generic.py +++ b/inventory/libvirt/hosts/libvirt_generic.py @@ -1,4 +1,5 @@ #!/usr/bin/env python2 +# pylint: skip-file ''' libvirt external inventory script diff --git a/inventory/openstack/hosts/openstack.py b/inventory/openstack/hosts/openstack.py index 0d92eae11..deefd3b5d 100755 --- a/inventory/openstack/hosts/openstack.py +++ b/inventory/openstack/hosts/openstack.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# pylint: skip-file # Copyright (c) 2012, Marco Vito Moscaritolo <marco@agavee.com> # Copyright (c) 2013, Jesse Keating <jesse.keating@rackspace.com> diff --git a/library/modify_yaml.py b/library/modify_yaml.py index 63b507a72..000c7d9a2 100755 --- a/library/modify_yaml.py +++ b/library/modify_yaml.py @@ -30,7 +30,7 @@ def set_key(yaml_data, yaml_key, yaml_value): ptr[key] = {} ptr = ptr[key] elif key == yaml_key.split('.')[-1]: - if (key in ptr and module.safe_eval(ptr[key]) != yaml_value) or (key not in ptr): + if (key in ptr and module.safe_eval(ptr[key]) != yaml_value) or (key not in ptr): # noqa: F405 ptr[key] = yaml_value changes.append((yaml_key, yaml_value)) else: @@ -49,7 +49,7 @@ def main(): # redefined-outer-name global module - module = AnsibleModule( + module = AnsibleModule( # noqa: F405 argument_spec=dict( dest=dict(required=True), yaml_key=dict(required=True), @@ -94,10 +94,11 @@ def main(): except Exception, e: return module.fail_json(msg=str(e)) + # ignore pylint errors related to the module_utils import -# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import +# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, wrong-import-position # import module snippets -from ansible.module_utils.basic import * +from ansible.module_utils.basic import * # noqa: F402,F403 if __name__ == '__main__': main() diff --git a/library/rpm_q.py b/library/rpm_q.py index ca3d0dd89..3dec50fc2 100644 --- a/library/rpm_q.py +++ b/library/rpm_q.py @@ -9,7 +9,7 @@ available. """ # pylint: disable=redefined-builtin,wildcard-import,unused-wildcard-import -from ansible.module_utils.basic import * +from ansible.module_utils.basic import * # noqa: F403 DOCUMENTATION = """ --- @@ -35,16 +35,17 @@ EXAMPLES = """ RPM_BINARY = '/bin/rpm' + def main(): """ Checks rpm -q for the named package and returns the installed packages or None if not installed. """ - module = AnsibleModule( + module = AnsibleModule( # noqa: F405 argument_spec=dict( name=dict(required=True), state=dict(default='present', choices=['present', 'absent']) - ), + ), supports_check_mode=True ) @@ -66,5 +67,6 @@ def main(): else: module.fail_json(msg="%s is installed", installed_versions=installed) + if __name__ == '__main__': main() diff --git a/lookup_plugins/oo_option.py b/lookup_plugins/oo_option.py index bca545771..7909d0092 100644 --- a/lookup_plugins/oo_option.py +++ b/lookup_plugins/oo_option.py @@ -30,9 +30,11 @@ except ImportError: def __init__(self, basedir=None, runner=None, **kwargs): self.runner = runner self.basedir = self.runner.basedir + def get_basedir(self, variables): return self.basedir + # Reason: disable too-few-public-methods because the `run` method is the only # one required by the Ansible API # Status: permanently disabled diff --git a/playbooks/adhoc/grow_docker_vg/filter_plugins/oo_filters.py b/playbooks/adhoc/grow_docker_vg/filter_plugins/oo_filters.py index d0264cde9..c19274e06 100644 --- a/playbooks/adhoc/grow_docker_vg/filter_plugins/oo_filters.py +++ b/playbooks/adhoc/grow_docker_vg/filter_plugins/oo_filters.py @@ -33,7 +33,6 @@ class FilterModule(object): return None - def filters(self): ''' returns a mapping of filters to methods ''' return { diff --git a/playbooks/aws/openshift-cluster/library/ec2_ami_find.py b/playbooks/aws/openshift-cluster/library/ec2_ami_find.py index 2b1db62d8..99d0f44f0 100644 --- a/playbooks/aws/openshift-cluster/library/ec2_ami_find.py +++ b/playbooks/aws/openshift-cluster/library/ec2_ami_find.py @@ -1,5 +1,6 @@ #!/usr/bin/python #pylint: skip-file +# flake8: noqa # # This file is part of Ansible # diff --git a/playbooks/byo/openshift-cluster/config.yml b/playbooks/byo/openshift-cluster/config.yml index fccb03982..7216a151f 100644 --- a/playbooks/byo/openshift-cluster/config.yml +++ b/playbooks/byo/openshift-cluster/config.yml @@ -14,6 +14,7 @@ name: "{{ item }}" groups: l_oo_all_hosts with_items: "{{ g_all_hosts | default([]) }}" + changed_when: no - name: Create initial host groups for all hosts hosts: l_oo_all_hosts diff --git a/playbooks/byo/openshift-cluster/upgrades/docker/docker_upgrade.yml b/playbooks/byo/openshift-cluster/upgrades/docker/docker_upgrade.yml index 834461e14..12c5566c4 100644 --- a/playbooks/byo/openshift-cluster/upgrades/docker/docker_upgrade.yml +++ b/playbooks/byo/openshift-cluster/upgrades/docker/docker_upgrade.yml @@ -42,6 +42,5 @@ command: > {{ openshift.common.client_binary }} adm manage-node {{ openshift.node.nodename }} --schedulable=true delegate_to: "{{ groups.oo_first_master.0 }}" - when: openshift.node.schedulable | bool when: l_docker_upgrade is defined and l_docker_upgrade | bool and inventory_hostname in groups.oo_nodes_to_upgrade and openshift.node.schedulable | bool diff --git a/playbooks/common/openshift-cluster/config.yml b/playbooks/common/openshift-cluster/config.yml index 801c8065d..0f226f5f9 100644 --- a/playbooks/common/openshift-cluster/config.yml +++ b/playbooks/common/openshift-cluster/config.yml @@ -12,6 +12,8 @@ - node - include: initialize_openshift_version.yml + tags: + - always - name: Set oo_option facts hosts: oo_all_hosts diff --git a/playbooks/common/openshift-cluster/evaluate_groups.yml b/playbooks/common/openshift-cluster/evaluate_groups.yml index b3e02fb97..65b45886a 100644 --- a/playbooks/common/openshift-cluster/evaluate_groups.yml +++ b/playbooks/common/openshift-cluster/evaluate_groups.yml @@ -36,6 +36,7 @@ ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" ansible_become: "{{ g_sudo | default(omit) }}" with_items: "{{ g_all_hosts | default([]) }}" + changed_when: no - name: Evaluate oo_masters add_host: @@ -44,6 +45,7 @@ ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" ansible_become: "{{ g_sudo | default(omit) }}" with_items: "{{ g_master_hosts | union(g_new_master_hosts) | default([]) }}" + changed_when: no - name: Evaluate oo_etcd_to_config add_host: @@ -52,6 +54,7 @@ ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" ansible_become: "{{ g_sudo | default(omit) }}" with_items: "{{ g_etcd_hosts | default([]) }}" + changed_when: no - name: Evaluate oo_masters_to_config add_host: @@ -60,6 +63,7 @@ ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" ansible_become: "{{ g_sudo | default(omit) }}" with_items: "{{ g_new_master_hosts | default(g_master_hosts | default([], true), true) }}" + changed_when: no - name: Evaluate oo_nodes_to_config add_host: @@ -68,9 +72,10 @@ ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" ansible_become: "{{ g_sudo | default(omit) }}" with_items: "{{ g_new_node_hosts | default(g_node_hosts | default([], true), true) }}" + changed_when: no # Skip adding the master to oo_nodes_to_config when g_new_node_hosts is - - name: Evaluate oo_nodes_to_config + - name: Add master to oo_nodes_to_config add_host: name: "{{ item }}" groups: oo_nodes_to_config @@ -78,6 +83,7 @@ ansible_become: "{{ g_sudo | default(omit) }}" with_items: "{{ g_master_hosts | default([]) }}" when: g_nodeonmaster | default(false) | bool and not g_new_node_hosts | default(false) | bool + changed_when: no - name: Evaluate oo_first_etcd add_host: @@ -85,6 +91,7 @@ groups: oo_first_etcd ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" when: g_etcd_hosts|length > 0 + changed_when: no - name: Evaluate oo_first_master add_host: @@ -93,6 +100,7 @@ ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" ansible_become: "{{ g_sudo | default(omit) }}" when: g_master_hosts|length > 0 + changed_when: no - name: Evaluate oo_lb_to_config add_host: @@ -101,6 +109,7 @@ ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" ansible_become: "{{ g_sudo | default(omit) }}" with_items: "{{ g_lb_hosts | default([]) }}" + changed_when: no - name: Evaluate oo_nfs_to_config add_host: @@ -109,3 +118,4 @@ ansible_ssh_user: "{{ g_ssh_user | default(omit) }}" ansible_become: "{{ g_sudo | default(omit) }}" with_items: "{{ g_nfs_hosts | default([]) }}" + changed_when: no diff --git a/playbooks/common/openshift-cluster/upgrades/library/openshift_upgrade_config.py b/playbooks/common/openshift-cluster/upgrades/library/openshift_upgrade_config.py index 9a065fd1c..1238acb05 100755 --- a/playbooks/common/openshift-cluster/upgrades/library/openshift_upgrade_config.py +++ b/playbooks/common/openshift-cluster/upgrades/library/openshift_upgrade_config.py @@ -17,6 +17,7 @@ requirements: [ ] EXAMPLES = ''' ''' + def modify_api_levels(level_list, remove, ensure, msg_prepend='', msg_append=''): """ modify_api_levels """ @@ -62,7 +63,6 @@ def upgrade_master_3_0_to_3_1(ansible_module, config_base, backup): config = yaml.safe_load(master_cfg_file.read()) master_cfg_file.close() - # Remove unsupported api versions and ensure supported api versions from # master config unsupported_levels = ['v1beta1', 'v1beta2', 'v1beta3'] @@ -118,7 +118,7 @@ def main(): # redefined-outer-name global module - module = AnsibleModule( + module = AnsibleModule( # noqa: F405 argument_spec=dict( config_base=dict(required=True), from_version=dict(required=True, choices=['3.0']), @@ -149,10 +149,11 @@ def main(): except Exception, e: return module.fail_json(msg=str(e)) + # ignore pylint errors related to the module_utils import -# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import +# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, wrong-import-position # import module snippets -from ansible.module_utils.basic import * +from ansible.module_utils.basic import * # noqa: E402,F403 if __name__ == '__main__': main() diff --git a/playbooks/common/openshift-cluster/verify_ansible_version.yml b/playbooks/common/openshift-cluster/verify_ansible_version.yml index d75b23bf7..8be8fbf04 100644 --- a/playbooks/common/openshift-cluster/verify_ansible_version.yml +++ b/playbooks/common/openshift-cluster/verify_ansible_version.yml @@ -1,11 +1,11 @@ --- -- name: Verify Ansible version is greater than or equal to 2.1.0.0 +- name: Verify Ansible version is greater than or equal to 2.2.0 hosts: localhost connection: local become: no gather_facts: no tasks: - - name: Verify Ansible version is greater than or equal to 2.1.0.0 + - name: Verify Ansible version is greater than or equal to 2.2.0 fail: msg: "Unsupported ansible version: {{ ansible_version.full }} found" - when: not ansible_version.full | version_compare('2.1.0.0', 'ge') + when: not ansible_version.full | version_compare('2.2.0', 'ge') diff --git a/roles/etcd_common/library/delegated_serial_command.py b/roles/etcd_common/library/delegated_serial_command.py index 84d4f97c2..0cab1ca88 100755 --- a/roles/etcd_common/library/delegated_serial_command.py +++ b/roles/etcd_common/library/delegated_serial_command.py @@ -24,12 +24,9 @@ ''' delegated_serial_command ''' -import copy -import sys import datetime +import errno import glob -import traceback -import re import shlex import os import fcntl @@ -133,6 +130,7 @@ OPTIONS = {'chdir': None, 'lockfile': None, 'timeout': None} + def check_command(commandline): ''' Check provided command ''' arguments = {'chown': 'owner', 'chmod': 'mode', 'chgrp': 'group', @@ -160,7 +158,7 @@ def check_command(commandline): # pylint: disable=too-many-statements,too-many-branches,too-many-locals def main(): ''' Main module function ''' - module = AnsibleModule( + module = AnsibleModule( # noqa: F405 argument_spec=dict( _uses_shell=dict(type='bool', default=False), command=dict(required=True), @@ -220,9 +218,9 @@ def main(): ) if removes: - # do not run the command if the line contains removes=filename - # and the filename does not exist. This allows idempotence - # of command executions. + # do not run the command if the line contains removes=filename + # and the filename does not exist. This allows idempotence + # of command executions. path = os.path.expanduser(removes) if not glob.glob(path): module.exit_json( @@ -268,7 +266,9 @@ def main(): iterated=iterated ) + # import module snippets -from ansible.module_utils.basic import * +# pylint: disable=wrong-import-position +from ansible.module_utils.basic import * # noqa: F402,F403 main() diff --git a/roles/kube_nfs_volumes/library/partitionpool.py b/roles/kube_nfs_volumes/library/partitionpool.py index 9bd3228c1..2cd454274 100644 --- a/roles/kube_nfs_volumes/library/partitionpool.py +++ b/roles/kube_nfs_volumes/library/partitionpool.py @@ -52,7 +52,7 @@ options: partitions. On 1 TiB disk, 10 partitions will be created. - Example 2: size=100G:1,10G:1 says that ratio of space occupied by 100 GiB - partitions and 10 GiB partitions is 1:1. Therefore, on 1 TiB disk, 500 GiB + partitions and 10 GiB partitions is 1:1. Therefore, on 1 TiB disk, 500 GiB will be split into five 100 GiB partition and 500 GiB will be split into fifty 10GiB partitions. - size=100G:1,10G:1 = 5x 100 GiB and 50x 10 GiB partitions (on 1 TiB disk). @@ -73,7 +73,7 @@ options: and eight 50 GiB partitions (again, 400 GiB). - size=200G:1,100G:1,50G:1 = 1x 200 GiB, 4x 100 GiB and 8x 50 GiB partitions (on 1 TiB disk). - + force: description: - If True, it will always overwite partition table on the disk and create new one. @@ -81,6 +81,7 @@ options: """ + # It's not class, it's more a simple struct with almost no functionality. # pylint: disable=too-few-public-methods class PartitionSpec(object): @@ -98,6 +99,7 @@ class PartitionSpec(object): """ Set count of parititions of this specification. """ self.count = count + def assign_space(total_size, specs): """ Satisfy all the PartitionSpecs according to their weight. @@ -113,6 +115,7 @@ def assign_space(total_size, specs): total_size -= num_blocks * spec.size total_weight -= spec.weight + def partition(diskname, specs, force=False, check_mode=False): """ Create requested partitions. @@ -161,16 +164,17 @@ def partition(diskname, specs, force=False, check_mode=False): pass return count + def parse_spec(text): """ Parse string with partition specification. """ tokens = text.split(",") specs = [] for token in tokens: - if not ":" in token: + if ":" not in token: token += ":1" (sizespec, weight) = token.split(':') - weight = float(weight) # throws exception with reasonable error string + weight = float(weight) # throws exception with reasonable error string units = {"m": 1, "g": 1 << 10, "t": 1 << 20, "p": 1 << 30} unit = units.get(sizespec[-1].lower(), None) @@ -184,6 +188,7 @@ def parse_spec(text): specs.append(spec) return specs + def get_partitions(diskpath): """ Return array of partition names for given disk """ dev = parted.getDevice(diskpath) @@ -198,7 +203,7 @@ def get_partitions(diskpath): def main(): """ Ansible module main method. """ - module = AnsibleModule( + module = AnsibleModule( # noqa: F405 argument_spec=dict( disks=dict(required=True, type='str'), force=dict(required=False, default="no", type='bool'), @@ -227,14 +232,14 @@ def main(): except Exception, ex: err = "Error creating partitions on " + disk + ": " + str(ex) raise - #module.fail_json(msg=err) + # module.fail_json(msg=err) partitions += get_partitions(disk) module.exit_json(changed=(changed_count > 0), ansible_facts={"partition_pool": partitions}) + # ignore pylint errors related to the module_utils import -# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import +# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, wrong-import-order, wrong-import-position # import module snippets -from ansible.module_utils.basic import * +from ansible.module_utils.basic import * # noqa: E402,F403 main() - diff --git a/roles/openshift_certificate_expiry/filter_plugins/oo_cert_expiry.py b/roles/openshift_certificate_expiry/filter_plugins/oo_cert_expiry.py index 2e2430ee6..bedd23fe8 100644 --- a/roles/openshift_certificate_expiry/filter_plugins/oo_cert_expiry.py +++ b/roles/openshift_certificate_expiry/filter_plugins/oo_cert_expiry.py @@ -5,29 +5,6 @@ Custom filters for use in openshift-ansible """ -from ansible import errors -from collections import Mapping -from distutils.util import strtobool -from distutils.version import LooseVersion -from operator import itemgetter -import OpenSSL.crypto -import os -import pdb -import pkg_resources -import re -import json -import yaml -from ansible.parsing.yaml.dumper import AnsibleDumper -from urlparse import urlparse - -try: - # ansible-2.2 - # ansible.utils.unicode.to_unicode is deprecated in ansible-2.2, - # ansible.module_utils._text.to_text should be used instead. - from ansible.module_utils._text import to_text -except ImportError: - # ansible-2.1 - from ansible.utils.unicode import to_unicode as to_text # Disabling too-many-public-methods, since filter methods are necessarily # public @@ -80,7 +57,6 @@ Example playbook usage: return json_result - def filters(self): """ returns a mapping of filters to methods """ return { diff --git a/roles/openshift_certificate_expiry/library/openshift_cert_expiry.py b/roles/openshift_certificate_expiry/library/openshift_cert_expiry.py index 2cdb87dc1..e838eb2d4 100644 --- a/roles/openshift_certificate_expiry/library/openshift_cert_expiry.py +++ b/roles/openshift_certificate_expiry/library/openshift_cert_expiry.py @@ -628,10 +628,11 @@ an OpenShift Container Platform cluster changed=False ) + ###################################################################### # It's just the way we do things in Ansible. So disable this warning # # pylint: disable=wrong-import-position,import-error -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule # noqa: E402 if __name__ == '__main__': main() diff --git a/roles/openshift_cli/library/openshift_container_binary_sync.py b/roles/openshift_cli/library/openshift_container_binary_sync.py index 9ff738d14..4ed3e1f01 100644 --- a/roles/openshift_cli/library/openshift_container_binary_sync.py +++ b/roles/openshift_cli/library/openshift_container_binary_sync.py @@ -10,7 +10,7 @@ import shutil import os.path # pylint: disable=redefined-builtin,wildcard-import,unused-wildcard-import -from ansible.module_utils.basic import * +from ansible.module_utils.basic import * # noqa: F403 DOCUMENTATION = ''' @@ -40,7 +40,7 @@ class BinarySyncer(object): self.bin_dir = '/usr/local/bin' self.image = image self.tag = tag - self.temp_dir = None # TBD + self.temp_dir = None # TBD def sync(self): container_name = "openshift-cli-%s" % random.randint(1, 100000) @@ -110,7 +110,7 @@ class BinarySyncer(object): def main(): - module = AnsibleModule( + module = AnsibleModule( # noqa: F405 argument_spec=dict( image=dict(required=True), tag=dict(required=True), diff --git a/roles/openshift_examples/examples-sync.sh b/roles/openshift_examples/examples-sync.sh index d8c45dbc6..b139cc599 100755 --- a/roles/openshift_examples/examples-sync.sh +++ b/roles/openshift_examples/examples-sync.sh @@ -5,7 +5,7 @@ # # This script should be run from openshift-ansible/roles/openshift_examples -XPAAS_VERSION=ose-v1.3.3 +XPAAS_VERSION=ose-v1.3.5 ORIGIN_VERSION=${1:-v1.4} EXAMPLES_BASE=$(pwd)/files/examples/${ORIGIN_VERSION} find ${EXAMPLES_BASE} -name '*.json' -delete diff --git a/roles/openshift_examples/files/examples/v1.3/xpaas-streams/fis-image-streams.json b/roles/openshift_examples/files/examples/v1.3/xpaas-streams/fis-image-streams.json index 65060cc2c..ed0e94bed 100644 --- a/roles/openshift_examples/files/examples/v1.3/xpaas-streams/fis-image-streams.json +++ b/roles/openshift_examples/files/examples/v1.3/xpaas-streams/fis-image-streams.json @@ -20,23 +20,13 @@ { "name": "1.0", "annotations": { - "description": "JBoss Fuse Integration Services 1.0 Java S2I images.", + "description": "JBoss Fuse Integration Services 6.2.1 Java S2I images.", "iconClass": "icon-jboss", "tags": "builder,jboss-fuse,java,xpaas", "supports":"jboss-fuse:6.2.1,java:8,xpaas:1.2", "version": "1.0" } - }, - { - "name": "2.0", - "annotations": { - "description": "JBoss Fuse Integration Services 2.0 Java S2I images.", - "iconClass": "icon-jboss", - "tags": "builder,jboss-fuse,java,xpaas", - "supports":"jboss-fuse:6.3.0,java:8,xpaas:1.2", - "version": "2.0" - } - } + } ] } }, @@ -52,23 +42,13 @@ { "name": "1.0", "annotations": { - "description": "JBoss Fuse Integration Services 1.0 Karaf S2I images.", + "description": "JBoss Fuse Integration Services 6.2.1 Karaf S2I images.", "iconClass": "icon-jboss", "tags": "builder,jboss-fuse,java,karaf,xpaas", "supports":"jboss-fuse:6.2.1,java:8,xpaas:1.2", "version": "1.0" } - }, - { - "name": "2.0", - "annotations": { - "description": "JBoss Fuse Integration Services 2.0 Karaf S2I images.", - "iconClass": "icon-jboss", - "tags": "builder,jboss-fuse,java,karaf,xpaas", - "supports":"jboss-fuse:6.3.0,java:8,xpaas:1.2", - "version": "2.0" - } - } + } ] } } diff --git a/roles/openshift_examples/files/examples/v1.3/xpaas-streams/jboss-image-streams.json b/roles/openshift_examples/files/examples/v1.3/xpaas-streams/jboss-image-streams.json index 4edc97f41..a7cb12867 100644 --- a/roles/openshift_examples/files/examples/v1.3/xpaas-streams/jboss-image-streams.json +++ b/roles/openshift_examples/files/examples/v1.3/xpaas-streams/jboss-image-streams.json @@ -283,6 +283,28 @@ "kind": "ImageStream", "apiVersion": "v1", "metadata": { + "name": "jboss-datavirt63-openshift" + }, + "spec": { + "dockerImageRepository": "registry.access.redhat.com/jboss-datavirt-6/datavirt63-openshift", + "tags": [ + { + "name": "1.0", + "annotations": { + "description": "Red Hat JBoss Data Virtualization 6.3 S2I images.", + "iconClass": "icon-jboss", + "tags": "datavirt,java,jboss,xpaas", + "supports":"datavirt:6.3,java:8,xpaas:1.4", + "version": "1.0" + } + } + ] + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { "name": "jboss-amq-62" }, "spec": { diff --git a/roles/openshift_examples/files/examples/v1.3/xpaas-templates/datavirt63-basic-s2i.json b/roles/openshift_examples/files/examples/v1.3/xpaas-templates/datavirt63-basic-s2i.json new file mode 100644 index 000000000..7d64dac98 --- /dev/null +++ b/roles/openshift_examples/files/examples/v1.3/xpaas-templates/datavirt63-basic-s2i.json @@ -0,0 +1,415 @@ +{ + "kind": "Template", + "apiVersion": "v1", + "metadata": { + "annotations": { + "iconClass": "icon-jboss", + "description": "Application template for JBoss Data Virtualization 6.3 services built using S2I.", + "tags": "jdv,datavirt,jboss,xpaas", + "version": "1.4.0" + }, + "name": "datavirt63-basic-s2i" + }, + "labels": { + "template": "datavirt63-basic-s2i", + "xpaas": "1.4.0" + }, + "message": "A new data service has been created in your project. The username/password for accessing the service is ${TEIID_USERNAME}/${TEIID_PASSWORD}. Please be sure to create the \"${SERVICE_ACCOUNT_NAME}\" service account and the secret named ${CONFIGURATION_NAME} containing the datasource configuration details required by the deployed VDB(s).", + "parameters": [ + { + "description": "The name for the application.", + "displayName": "Application Name", + "name": "APPLICATION_NAME", + "value": "datavirt-app", + "required": true + }, + { + "description": "The name of the secret containing configuration properties for the data sources.", + "displayName": "Configuration Secret Name", + "name": "CONFIGURATION_NAME", + "value": "datavirt-app-config", + "required": true + }, + { + "description": "Specify a custom hostname for the http route. Leave blank to use default hostname, e.g.: <service-name>-<project>.<default-domain-suffix>", + "displayName": "Custom http Route Hostname", + "name": "HOSTNAME_HTTP", + "value": "", + "required": false + }, + { + "description": "The URL of the repository with your application source code.", + "displayName": "Git Repository URL", + "name": "SOURCE_REPOSITORY_URL", + "value": "https://github.com/jboss-openshift/openshift-quickstarts", + "required": true + }, + { + "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch.", + "displayName": "Git Reference", + "name": "SOURCE_REPOSITORY_REF", + "value": "master", + "required": false + }, + { + "description": "Set this to the relative path to your project if it is not in the root of your repository.", + "displayName": "Context Directory", + "name": "CONTEXT_DIR", + "value": "datavirt/dynamicvdb-datafederation/app", + "required": false + }, + { + "description": "The name of the service account to use for the deployment. The service account should be configured to allow usage of the secret specified by CONFIGURATION_NAME.", + "name": "SERVICE_ACCOUNT_NAME", + "value": "datavirt-service-account", + "required": true + }, + { + "description": "Username associated with Teiid data service.", + "displayName": "Teiid Username", + "name": "TEIID_USERNAME", + "from": "[\\a]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Password for Teiid user.", + "displayName": "Teiid User Password", + "name": "TEIID_PASSWORD", + "from": "[\\a\\A]{8}[\\d]{1}[\\A]{1}", + "generate": "expression", + "required": true + }, + { + "description": "Username associated with ModeShape.", + "displayName": "ModeShape Username", + "name": "MODESHAPE_USERNAME", + "from": "[\\a]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Password for ModeShape user.", + "displayName": "ModeShape User Password", + "name": "MODESHAPE_PASSWORD", + "from": "[\\a\\A]{8}[\\d]{1}[\\A]{1}", + "generate": "expression", + "required": true + }, + { + "description": "A secret string used to configure the GitHub webhook.", + "displayName": "Github Webhook Secret", + "name": "GITHUB_WEBHOOK_SECRET", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "A secret string used to configure the Generic webhook.", + "displayName": "Generic Webhook Secret", + "name": "GENERIC_WEBHOOK_SECRET", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Namespace in which the ImageStreams for Red Hat Middleware images are installed. These ImageStreams are normally installed in the openshift namespace. You should only need to modify this if you've installed the ImageStreams in a different namespace/project.", + "displayName": "ImageStream Namespace", + "name": "IMAGE_STREAM_NAMESPACE", + "value": "openshift", + "required": true + }, + { + "description": "Password used by JGroups to authenticate nodes in the cluster.", + "displayName": "JGroups Cluster Password", + "name": "JGROUPS_CLUSTER_PASSWORD", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Controls whether exploded deployment content should be automatically deployed", + "displayName": "Deploy Exploded Archives", + "name": "AUTO_DEPLOY_EXPLODED", + "value": "false", + "required": false + } + ], + "objects": [ + { + "kind": "Service", + "apiVersion": "v1", + "spec": { + "ports": [ + { + "name": "http", + "port": 8080, + "targetPort": "http" + }, + { + "name": "jdbc", + "port": 31000, + "targetPort": "jdbc" + } + ], + "selector": { + "deploymentConfig": "${APPLICATION_NAME}" + } + }, + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "The data virtualization services." + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "id": "${APPLICATION_NAME}-http", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "Route for application's http (REST) service." + } + }, + "spec": { + "host": "${HOSTNAME_HTTP}", + "port": { + "targetPort": "http" + }, + "to": { + "name": "${APPLICATION_NAME}" + } + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + } + }, + { + "kind": "BuildConfig", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "source": { + "type": "Git", + "git": { + "uri": "${SOURCE_REPOSITORY_URL}", + "ref": "${SOURCE_REPOSITORY_REF}" + }, + "contextDir": "${CONTEXT_DIR}" + }, + "strategy": { + "type": "Source", + "sourceStrategy": { + "forcePull": true, + "from": { + "kind": "ImageStreamTag", + "namespace": "${IMAGE_STREAM_NAMESPACE}", + "name": "jboss-datavirt63-openshift:1.0" + } + } + }, + "output": { + "to": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}:latest" + } + }, + "triggers": [ + { + "type": "GitHub", + "github": { + "secret": "${GITHUB_WEBHOOK_SECRET}" + } + }, + { + "type": "Generic", + "generic": { + "secret": "${GENERIC_WEBHOOK_SECRET}" + } + }, + { + "type": "ImageChange", + "imageChange": {} + }, + { + "type": "ConfigChange" + } + ] + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "strategy": { + "type": "Recreate" + }, + "triggers": [ + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "${APPLICATION_NAME}" + ], + "from": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}:latest" + } + } + }, + { + "type": "ConfigChange" + } + ], + "replicas": 1, + "selector": { + "deploymentConfig": "${APPLICATION_NAME}" + }, + "template": { + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "deploymentConfig": "${APPLICATION_NAME}", + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "serviceAccountName": "${SERVICE_ACCOUNT_NAME}", + "terminationGracePeriodSeconds": 60, + "containers": [ + { + "name": "${APPLICATION_NAME}", + "image": "${APPLICATION_NAME}", + "imagePullPolicy": "Always", + "volumeMounts": [ + { + "name": "configuration", + "mountPath": "/etc/datavirt-environment", + "readOnly": true + } + ], + "livenessProbe": { + "exec": { + "command": [ + "/bin/bash", + "-c", + "/opt/eap/bin/livenessProbe.sh" + ] + } + }, + "readinessProbe": { + "exec": { + "command": [ + "/bin/bash", + "-c", + "/opt/eap/bin/readinessProbe.sh" + ] + } + }, + "ports": [ + { + "name": "jolokia", + "containerPort": 8778, + "protocol": "TCP" + }, + { + "name": "http", + "containerPort": 8080, + "protocol": "TCP" + }, + { + "name": "jdbc", + "containerPort": 31000, + "protocol": "TCP" + }, + { + "name": "ping", + "containerPort": 8888, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "OPENSHIFT_KUBE_PING_LABELS", + "value": "application=${APPLICATION_NAME}" + }, + { + "name": "OPENSHIFT_KUBE_PING_NAMESPACE", + "valueFrom": { + "fieldRef": { + "fieldPath": "metadata.namespace" + } + } + }, + { + "name": "JGROUPS_CLUSTER_PASSWORD", + "value": "${JGROUPS_CLUSTER_PASSWORD}" + }, + { + "name": "AUTO_DEPLOY_EXPLODED", + "value": "${AUTO_DEPLOY_EXPLODED}" + }, + { + "name": "TEIID_USERNAME", + "value": "${TEIID_USERNAME}" + }, + { + "name": "TEIID_PASSWORD", + "value": "${TEIID_PASSWORD}" + }, + { + "name": "MODESHAPE_USERNAME", + "value": "${MODESHAPE_USERNAME}" + }, + { + "name": "MODESHAPE_PASSWORD", + "value": "${MODESHAPE_PASSWORD}" + }, + { + "name": "ENV_FILES", + "value": "/etc/datavirt-environment/*" + } + ] + } + ], + "volumes": [ + { + "name": "configuration", + "secret": { + "secretName": "${CONFIGURATION_NAME}" + } + } + ] + } + } + } + } + ] +} diff --git a/roles/openshift_examples/files/examples/v1.3/xpaas-templates/datavirt63-extensions-support-s2i.json b/roles/openshift_examples/files/examples/v1.3/xpaas-templates/datavirt63-extensions-support-s2i.json new file mode 100644 index 000000000..1e7c03b99 --- /dev/null +++ b/roles/openshift_examples/files/examples/v1.3/xpaas-templates/datavirt63-extensions-support-s2i.json @@ -0,0 +1,763 @@ +{ + "kind": "Template", + "apiVersion": "v1", + "metadata": { + "annotations": { + "iconClass": "icon-jboss", + "description": "Application template for JBoss Data Virtualization 6.3 services built using S2I. Includes support for installing extensions (e.g. third-party DB drivers) and the ability to configure certificates for serving secure content.", + "tags": "jdv,datavirt,jboss,xpaas", + "version": "1.4.0" + }, + "name": "datavirt63-extensions-support-s2i" + }, + "labels": { + "template": "datavirt63-extensions-support-s2i", + "xpaas": "1.4.0" + }, + "message": "A new data service has been created in your project. The username/password for accessing the service is ${TEIID_USERNAME}/${TEIID_PASSWORD}. Please be sure to create the \"${SERVICE_ACCOUNT_NAME}\" service account and the following secrets: \"${CONFIGURATION_NAME}\" containing the datasource configuration details required by the deployed VDB(s); \"${HTTPS_SECRET}\" containing the ${HTTPS_KEYSTORE} file used for serving secure content; \"${JGROUPS_ENCRYPT_SECRET}\" containing the ${JGROUPS_ENCRYPT_KEYSTORE} file used for securing JGroups communications.", + "parameters": [ + { + "description": "The name for the application.", + "displayName": "Application Name", + "name": "APPLICATION_NAME", + "value": "datavirt-app", + "required": true + }, + { + "description": "The name of the secret containing configuration properties for the data sources.", + "displayName": "Configuration Secret Name", + "name": "CONFIGURATION_NAME", + "value": "datavirt-app-config", + "required": true + }, + { + "description": "Specify a custom hostname for the http route. Leave blank to use default hostname, e.g.: <service-name>-<project>.<default-domain-suffix>", + "displayName": "Custom http Route Hostname", + "name": "HOSTNAME_HTTP", + "value": "", + "required": false + }, + { + "description": "Specify a custom hostname for the https route. Leave blank to use default hostname, e.g.: secure-<service-name>-<project>.<default-domain-suffix>", + "displayName": "Custom https Route Hostname", + "name": "HOSTNAME_HTTPS", + "value": "", + "required": false + }, + { + "description": "Specify a custom hostname for the JDBC route. Leave blank to use default hostname, e.g.: secure-<service-name>-<project>.<default-domain-suffix>", + "displayName": "Custom JDBC Route Hostname", + "name": "HOSTNAME_JDBC", + "value": "", + "required": false + }, + { + "description": "The URL of the repository with your application source code.", + "displayName": "Git Repository URL", + "name": "SOURCE_REPOSITORY_URL", + "value": "https://github.com/jboss-openshift/openshift-quickstarts", + "required": true + }, + { + "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch.", + "displayName": "Git Reference", + "name": "SOURCE_REPOSITORY_REF", + "value": "master", + "required": false + }, + { + "description": "Set this to the relative path to your project if it is not in the root of your repository.", + "displayName": "Context Directory", + "name": "CONTEXT_DIR", + "value": "datavirt/dynamicvdb-datafederation/app", + "required": false + }, + { + "description": "The URL of the repository with source code for the extensions image. The image should have all modules, etc., placed in the \"/extensions/\" directory in the image. If the contents are in a different directory, the sourcePath for the ImageSource in the BuildConfig must be modified.", + "displayName": "Extensions Git Repository URL", + "name": "EXTENSIONS_REPOSITORY_URL", + "value": "https://github.com/jboss-openshift/openshift-quickstarts", + "required": true + }, + { + "description": "Set this to a branch name, tag or other ref of your extensions repository if you are not using the default branch.", + "displayName": "Extensions Git Reference", + "name": "EXTENSIONS_REPOSITORY_REF", + "value": "master", + "required": false + }, + { + "description": "Set this to the relative path to your project if it is not in the root of your extensions repository.", + "displayName": "Extensions Context Directory", + "name": "EXTENSIONS_DIR", + "value": "datavirt/derby-driver-image", + "required": false + }, + { + "description": "Set this to the relative path to the Dockerfile in your extensions directory.", + "displayName": "Extensions Dockerfile", + "name": "EXTENSIONS_DOCKERFILE", + "value": "Dockerfile", + "required": false + }, + { + "description": "The name of the service account to use for the deployment. The service account should be configured to allow usage of the secret(s) specified by CONFIGURATION_NAME, HTTPS_SECRET and JGROUPS_ENCRYPT_SECRET.", + "name": "SERVICE_ACCOUNT_NAME", + "value": "datavirt-service-account", + "required": true + }, + { + "description": "The name of the secret containing the keystore to be used for serving secure content.", + "displayName": "Server Keystore Secret Name", + "name": "HTTPS_SECRET", + "value": "datavirt-app-secret", + "required": true + }, + { + "description": "The name of the keystore file within the secret.", + "displayName": "Server Keystore Filename", + "name": "HTTPS_KEYSTORE", + "value": "keystore.jks", + "required": false + }, + { + "description": "The type of the keystore file (JKS or JCEKS).", + "displayName": "Server Keystore Type", + "name": "HTTPS_KEYSTORE_TYPE", + "value": "", + "required": false + }, + { + "description": "The name associated with the server certificate.", + "displayName": "Server Certificate Name", + "name": "HTTPS_NAME", + "value": "jboss", + "required": false + }, + { + "description": "The password for the keystore and certificate", + "displayName": "Server Keystore Password", + "name": "HTTPS_PASSWORD", + "value": "mykeystorepass", + "required": false + }, + { + "description": "Username associated with Teiid data service.", + "displayName": "Teiid Username", + "name": "TEIID_USERNAME", + "from": "[\\a]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Password for Teiid user.", + "displayName": "Teiid User Password", + "name": "TEIID_PASSWORD", + "from": "[\\a\\A]{8}[\\d]{1}[\\A]{1}", + "generate": "expression", + "required": true + }, + { + "description": "Username associated with ModeShape.", + "displayName": "ModeShape Username", + "name": "MODESHAPE_USERNAME", + "from": "[\\a]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Password for ModeShape user.", + "displayName": "ModeShape User Password", + "name": "MODESHAPE_PASSWORD", + "from": "[\\a\\A]{8}[\\d]{1}[\\A]{1}", + "generate": "expression", + "required": true + }, + { + "description": "A secret string used to configure the GitHub webhook.", + "displayName": "Github Webhook Secret", + "name": "GITHUB_WEBHOOK_SECRET", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "A secret string used to configure the Generic webhook.", + "displayName": "Generic Webhook Secret", + "name": "GENERIC_WEBHOOK_SECRET", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Namespace in which the ImageStreams for Red Hat Middleware images are installed. These ImageStreams are normally installed in the openshift namespace. You should only need to modify this if you've installed the ImageStreams in a different namespace/project.", + "displayName": "ImageStream Namespace", + "name": "IMAGE_STREAM_NAMESPACE", + "value": "openshift", + "required": true + }, + { + "description": "The name of the secret containing the keystore to be used for securing JGroups communications.", + "displayName": "JGroups Secret Name", + "name": "JGROUPS_ENCRYPT_SECRET", + "value": "datavirt-app-secret", + "required": false + }, + { + "description": "The name of the keystore file within the JGroups secret.", + "displayName": "JGroups Keystore Filename", + "name": "JGROUPS_ENCRYPT_KEYSTORE", + "value": "jgroups.jceks", + "required": false + }, + { + "description": "The name associated with the JGroups server certificate", + "displayName": "JGroups Certificate Name", + "name": "JGROUPS_ENCRYPT_NAME", + "value": "secret-key", + "required": false + }, + { + "description": "The password for the keystore and certificate", + "displayName": "JGroups Keystore Password", + "name": "JGROUPS_ENCRYPT_PASSWORD", + "value": "password", + "required": false + }, + { + "description": "Password used by JGroups to authenticate nodes in the cluster.", + "displayName": "JGroups Cluster Password", + "name": "JGROUPS_CLUSTER_PASSWORD", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Controls whether exploded deployment content should be automatically deployed", + "displayName": "Deploy Exploded Archives", + "name": "AUTO_DEPLOY_EXPLODED", + "value": "false", + "required": false + } + ], + "objects": [ + { + "kind": "Service", + "apiVersion": "v1", + "spec": { + "ports": [ + { + "name": "http", + "port": 8080, + "targetPort": "http" + }, + { + "name": "https", + "port": 8443, + "targetPort": "https" + }, + { + "name": "jdbc", + "port": 31000, + "targetPort": "jdbc" + }, + { + "name": "jdbcs", + "port": 31443, + "targetPort": "jdbcs" + } + ], + "selector": { + "deploymentConfig": "${APPLICATION_NAME}" + } + }, + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "The data virtualization services." + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "id": "${APPLICATION_NAME}-http", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "Route for application's http (REST) service." + } + }, + "spec": { + "host": "${HOSTNAME_HTTP}", + "port": { + "targetPort": "http" + }, + "to": { + "name": "${APPLICATION_NAME}" + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "id": "${APPLICATION_NAME}-https", + "metadata": { + "name": "secure-${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "Route for application's https (REST) service." + } + }, + "spec": { + "host": "${HOSTNAME_HTTPS}", + "port": { + "targetPort": "https" + }, + "to": { + "name": "${APPLICATION_NAME}" + }, + "tls": { + "termination": "passthrough" + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "id": "${APPLICATION_NAME}-jdbc", + "metadata": { + "name": "jdbc-${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "Route for application's JDBC service." + } + }, + "spec": { + "host": "${HOSTNAME_JDBC}", + "port": { + "targetPort": "jdbcs" + }, + "to": { + "name": "${APPLICATION_NAME}" + }, + "tls": { + "termination": "passthrough" + } + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}-ext", + "labels": { + "application": "${APPLICATION_NAME}" + } + } + }, + { + "kind": "BuildConfig", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}-ext", + "labels": { + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "source": { + "type": "Git", + "git": { + "uri": "${EXTENSIONS_REPOSITORY_URL}", + "ref": "${EXTENSIONS_REPOSITORY_REF}" + }, + "contextDir": "${EXTENSIONS_DIR}" + }, + "strategy": { + "type": "Docker", + "dockerStrategy": { + "dockerfilePath": "${EXTENSIONS_DOCKERFILE}" + } + }, + "output": { + "to": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}-ext:latest" + } + }, + "triggers": [ + { + "type": "GitHub", + "github": { + "secret": "${GITHUB_WEBHOOK_SECRET}" + } + }, + { + "type": "Generic", + "generic": { + "secret": "${GENERIC_WEBHOOK_SECRET}" + } + }, + { + "type": "ConfigChange" + } + ] + } + }, + { + "kind": "BuildConfig", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "source": { + "type": "Git", + "git": { + "uri": "${SOURCE_REPOSITORY_URL}", + "ref": "${SOURCE_REPOSITORY_REF}" + }, + "contextDir": "${CONTEXT_DIR}", + "images": [ + { + "from": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}-ext:latest" + }, + "paths": [ + { + "destinationDir": "./${CONTEXT_DIR}/extensions/extras", + "sourcePath": "/extensions/." + } + ] + } + ] + }, + "strategy": { + "type": "Source", + "sourceStrategy": { + "forcePull": true, + "from": { + "kind": "ImageStreamTag", + "namespace": "${IMAGE_STREAM_NAMESPACE}", + "name": "jboss-datavirt63-openshift:1.0" + }, + "env": [ + { + "name": "CUSTOM_INSTALL_DIRECTORIES", + "value": "extensions/*" + } + ] + } + }, + "output": { + "to": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}:latest" + } + }, + "triggers": [ + { + "type": "GitHub", + "github": { + "secret": "${GITHUB_WEBHOOK_SECRET}" + } + }, + { + "type": "Generic", + "generic": { + "secret": "${GENERIC_WEBHOOK_SECRET}" + } + }, + { + "type": "ImageChange", + "imageChange": {} + }, + { + "type": "ImageChange", + "imageChange": { + "from": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}-ext:latest" + } + } + }, + { + "type": "ConfigChange" + } + ] + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "strategy": { + "type": "Recreate" + }, + "triggers": [ + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "${APPLICATION_NAME}" + ], + "from": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}:latest" + } + } + }, + { + "type": "ConfigChange" + } + ], + "replicas": 1, + "selector": { + "deploymentConfig": "${APPLICATION_NAME}" + }, + "template": { + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "deploymentConfig": "${APPLICATION_NAME}", + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "serviceAccountName": "${SERVICE_ACCOUNT_NAME}", + "terminationGracePeriodSeconds": 60, + "containers": [ + { + "name": "${APPLICATION_NAME}", + "image": "${APPLICATION_NAME}", + "imagePullPolicy": "Always", + "volumeMounts": [ + { + "name": "configuration", + "mountPath": "/etc/datavirt-environment", + "readOnly": true + }, + { + "name": "datavirt-keystore-volume", + "mountPath": "/etc/datavirt-secret-volume", + "readOnly": true + }, + { + "name": "datavirt-jgroups-keystore-volume", + "mountPath": "/etc/jgroups-encrypt-secret-volume", + "readOnly": true + } + ], + "livenessProbe": { + "exec": { + "command": [ + "/bin/bash", + "-c", + "/opt/eap/bin/livenessProbe.sh" + ] + } + }, + "readinessProbe": { + "exec": { + "command": [ + "/bin/bash", + "-c", + "/opt/eap/bin/readinessProbe.sh" + ] + } + }, + "ports": [ + { + "name": "jolokia", + "containerPort": 8778, + "protocol": "TCP" + }, + { + "name": "http", + "containerPort": 8080, + "protocol": "TCP" + }, + { + "name": "https", + "containerPort": 8443, + "protocol": "TCP" + }, + { + "name": "jdbc", + "containerPort": 31000, + "protocol": "TCP" + }, + { + "name": "jdbcs", + "containerPort": 31443, + "protocol": "TCP" + }, + { + "name": "ping", + "containerPort": 8888, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "OPENSHIFT_KUBE_PING_LABELS", + "value": "application=${APPLICATION_NAME}" + }, + { + "name": "OPENSHIFT_KUBE_PING_NAMESPACE", + "valueFrom": { + "fieldRef": { + "fieldPath": "metadata.namespace" + } + } + }, + { + "name": "HTTPS_KEYSTORE_DIR", + "value": "/etc/datavirt-secret-volume" + }, + { + "name": "HTTPS_KEYSTORE", + "value": "${HTTPS_KEYSTORE}" + }, + { + "name": "HTTPS_KEYSTORE_TYPE", + "value": "${HTTPS_KEYSTORE_TYPE}" + }, + { + "name": "HTTPS_NAME", + "value": "${HTTPS_NAME}" + }, + { + "name": "HTTPS_PASSWORD", + "value": "${HTTPS_PASSWORD}" + }, + { + "name": "JGROUPS_ENCRYPT_SECRET", + "value": "${JGROUPS_ENCRYPT_SECRET}" + }, + { + "name": "JGROUPS_ENCRYPT_KEYSTORE_DIR", + "value": "/etc/jgroups-encrypt-secret-volume" + }, + { + "name": "JGROUPS_ENCRYPT_KEYSTORE", + "value": "${JGROUPS_ENCRYPT_KEYSTORE}" + }, + { + "name": "JGROUPS_ENCRYPT_NAME", + "value": "${JGROUPS_ENCRYPT_NAME}" + }, + { + "name": "JGROUPS_ENCRYPT_PASSWORD", + "value": "${JGROUPS_ENCRYPT_PASSWORD}" + }, + { + "name": "JGROUPS_CLUSTER_PASSWORD", + "value": "${JGROUPS_CLUSTER_PASSWORD}" + }, + { + "name": "AUTO_DEPLOY_EXPLODED", + "value": "${AUTO_DEPLOY_EXPLODED}" + }, + { + "name": "TEIID_USERNAME", + "value": "${TEIID_USERNAME}" + }, + { + "name": "TEIID_PASSWORD", + "value": "${TEIID_PASSWORD}" + }, + { + "name": "MODESHAPE_USERNAME", + "value": "${MODESHAPE_USERNAME}" + }, + { + "name": "MODESHAPE_PASSWORD", + "value": "${MODESHAPE_PASSWORD}" + }, + { + "name": "ENV_FILES", + "value": "/etc/datavirt-environment/*" + }, + { + "name": "DATAVIRT_TRANSPORT_KEYSTORE", + "value": "/etc/datavirt-secret-volume/${HTTPS_KEYSTORE}" + }, + { + "name": "DATAVIRT_TRANSPORT_KEYSTORE_TYPE", + "value": "${HTTPS_KEYSTORE_TYPE}" + }, + { + "name": "DATAVIRT_TRANSPORT_KEY_ALIAS", + "value": "${HTTPS_NAME}" + }, + { + "name": "DATAVIRT_TRANSPORT_KEYSTORE_PASSWORD", + "value": "${HTTPS_PASSWORD}" + }, + { + "name": "QS_DB_TYPE", + "value": "derby", + "description": "Used soley by the quickstart and set here to ensure the template can be instatiated with its default parameter values, i.e. so itworks ootb." + } + ] + } + ], + "volumes": [ + { + "name": "configuration", + "secret": { + "secretName": "${CONFIGURATION_NAME}" + } + }, + { + "name": "datavirt-keystore-volume", + "secret": { + "secretName": "${HTTPS_SECRET}" + } + }, + { + "name": "datavirt-jgroups-keystore-volume", + "secret": { + "secretName": "${JGROUPS_ENCRYPT_SECRET}" + } + } + ] + } + } + } + } + ] +} diff --git a/roles/openshift_examples/files/examples/v1.3/xpaas-templates/datavirt63-secure-s2i.json b/roles/openshift_examples/files/examples/v1.3/xpaas-templates/datavirt63-secure-s2i.json new file mode 100644 index 000000000..07f926ff3 --- /dev/null +++ b/roles/openshift_examples/files/examples/v1.3/xpaas-templates/datavirt63-secure-s2i.json @@ -0,0 +1,642 @@ +{ + "kind": "Template", + "apiVersion": "v1", + "metadata": { + "annotations": { + "iconClass": "icon-jboss", + "description": "Application template for JBoss Data Virtualization 6.3 services built using S2I. Includes ability to configure certificates for serving secure content.", + "tags": "jdv,datavirt,jboss,xpaas", + "version": "1.4.0" + }, + "name": "datavirt63-secure-s2i" + }, + "labels": { + "template": "datavirt63-secure-s2i", + "xpaas": "1.4.0" + }, + "message": "A new data service has been created in your project. The username/password for accessing the service is ${TEIID_USERNAME}/${TEIID_PASSWORD}. Please be sure to create the \"${SERVICE_ACCOUNT_NAME}\" service account and the following secrets: \"${CONFIGURATION_NAME}\" containing the datasource configuration details required by the deployed VDB(s); \"${HTTPS_SECRET}\" containing the ${HTTPS_KEYSTORE} file used for serving secure content; \"${JGROUPS_ENCRYPT_SECRET}\" containing the ${JGROUPS_ENCRYPT_KEYSTORE} file used for securing JGroups communications.", + "parameters": [ + { + "description": "The name for the application.", + "displayName": "Application Name", + "name": "APPLICATION_NAME", + "value": "datavirt-app", + "required": true + }, + { + "description": "The name of the secret containing configuration properties for the data sources.", + "displayName": "Configuration Secret Name", + "name": "CONFIGURATION_NAME", + "value": "datavirt-app-config", + "required": true + }, + { + "description": "Specify a custom hostname for the http route. Leave blank to use default hostname, e.g.: <service-name>-<project>.<default-domain-suffix>", + "displayName": "Custom http Route Hostname", + "name": "HOSTNAME_HTTP", + "value": "", + "required": false + }, + { + "description": "Specify a custom hostname for the https route. Leave blank to use default hostname, e.g.: secure-<service-name>-<project>.<default-domain-suffix>", + "displayName": "Custom https Route Hostname", + "name": "HOSTNAME_HTTPS", + "value": "", + "required": false + }, + { + "description": "Specify a custom hostname for the JDBC route. Leave blank to use default hostname, e.g.: secure-<service-name>-<project>.<default-domain-suffix>", + "displayName": "Custom JDBC Route Hostname", + "name": "HOSTNAME_JDBC", + "value": "", + "required": false + }, + { + "description": "The URL of the repository with your application source code.", + "displayName": "Git Repository URL", + "name": "SOURCE_REPOSITORY_URL", + "value": "https://github.com/jboss-openshift/openshift-quickstarts", + "required": true + }, + { + "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch.", + "displayName": "Git Reference", + "name": "SOURCE_REPOSITORY_REF", + "value": "master", + "required": false + }, + { + "description": "Set this to the relative path to your project if it is not in the root of your repository.", + "displayName": "Context Directory", + "name": "CONTEXT_DIR", + "value": "datavirt/dynamicvdb-datafederation/app", + "required": false + }, + { + "description": "The name of the service account to use for the deployment. The service account should be configured to allow usage of the secret(s) specified by CONFIGURATION_NAME, HTTPS_SECRET and JGROUPS_ENCRYPT_SECRET.", + "name": "SERVICE_ACCOUNT_NAME", + "value": "datavirt-service-account", + "required": true + }, + { + "description": "The name of the secret containing the keystore to be used for serving secure content.", + "displayName": "Server Keystore Secret Name", + "name": "HTTPS_SECRET", + "value": "datavirt-app-secret", + "required": true + }, + { + "description": "The name of the keystore file within the secret.", + "displayName": "Server Keystore Filename", + "name": "HTTPS_KEYSTORE", + "value": "keystore.jks", + "required": false + }, + { + "description": "The type of the keystore file (JKS or JCEKS).", + "displayName": "Server Keystore Type", + "name": "HTTPS_KEYSTORE_TYPE", + "value": "", + "required": false + }, + { + "description": "The name associated with the server certificate.", + "displayName": "Server Certificate Name", + "name": "HTTPS_NAME", + "value": "jboss", + "required": false + }, + { + "description": "The password for the keystore and certificate", + "displayName": "Server Keystore Password", + "name": "HTTPS_PASSWORD", + "value": "mykeystorepass", + "required": false + }, + { + "description": "Username associated with Teiid data service.", + "displayName": "Teiid Username", + "name": "TEIID_USERNAME", + "from": "[\\a]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Password for Teiid user.", + "displayName": "Teiid User Password", + "name": "TEIID_PASSWORD", + "from": "[\\a\\A]{8}[\\d]{1}[\\A]{1}", + "generate": "expression", + "required": true + }, + { + "description": "Username associated with ModeShape.", + "displayName": "ModeShape Username", + "name": "MODESHAPE_USERNAME", + "from": "[\\a]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Password for ModeShape user.", + "displayName": "ModeShape User Password", + "name": "MODESHAPE_PASSWORD", + "from": "[\\a\\A]{8}[\\d]{1}[\\A]{1}", + "generate": "expression", + "required": true + }, + { + "description": "A secret string used to configure the GitHub webhook.", + "displayName": "Github Webhook Secret", + "name": "GITHUB_WEBHOOK_SECRET", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "A secret string used to configure the Generic webhook.", + "displayName": "Generic Webhook Secret", + "name": "GENERIC_WEBHOOK_SECRET", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Namespace in which the ImageStreams for Red Hat Middleware images are installed. These ImageStreams are normally installed in the openshift namespace. You should only need to modify this if you've installed the ImageStreams in a different namespace/project.", + "displayName": "ImageStream Namespace", + "name": "IMAGE_STREAM_NAMESPACE", + "value": "openshift", + "required": true + }, + { + "description": "The name of the secret containing the keystore to be used for securing JGroups communications.", + "displayName": "JGroups Secret Name", + "name": "JGROUPS_ENCRYPT_SECRET", + "value": "datavirt-app-secret", + "required": false + }, + { + "description": "The name of the keystore file within the JGroups secret.", + "displayName": "JGroups Keystore Filename", + "name": "JGROUPS_ENCRYPT_KEYSTORE", + "value": "jgroups.jceks", + "required": false + }, + { + "description": "The name associated with the JGroups server certificate", + "displayName": "JGroups Certificate Name", + "name": "JGROUPS_ENCRYPT_NAME", + "value": "secret-key", + "required": false + }, + { + "description": "The password for the keystore and certificate", + "displayName": "JGroups Keystore Password", + "name": "JGROUPS_ENCRYPT_PASSWORD", + "value": "password", + "required": false + }, + { + "description": "Password used by JGroups to authenticate nodes in the cluster.", + "displayName": "JGroups Cluster Password", + "name": "JGROUPS_CLUSTER_PASSWORD", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Controls whether exploded deployment content should be automatically deployed", + "displayName": "Deploy Exploded Archives", + "name": "AUTO_DEPLOY_EXPLODED", + "value": "false", + "required": false + } + ], + "objects": [ + { + "kind": "Service", + "apiVersion": "v1", + "spec": { + "ports": [ + { + "name": "http", + "port": 8080, + "targetPort": "http" + }, + { + "name": "https", + "port": 8443, + "targetPort": "https" + }, + { + "name": "jdbc", + "port": 31000, + "targetPort": "jdbc" + }, + { + "name": "jdbcs", + "port": 31443, + "targetPort": "jdbcs" + } + ], + "selector": { + "deploymentConfig": "${APPLICATION_NAME}" + } + }, + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "The data virtualization services." + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "id": "${APPLICATION_NAME}-http", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "Route for application's http (REST) service." + } + }, + "spec": { + "host": "${HOSTNAME_HTTP}", + "port": { + "targetPort": "http" + }, + "to": { + "name": "${APPLICATION_NAME}" + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "id": "${APPLICATION_NAME}-https", + "metadata": { + "name": "secure-${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "Route for application's https (REST) service." + } + }, + "spec": { + "host": "${HOSTNAME_HTTPS}", + "port": { + "targetPort": "https" + }, + "to": { + "name": "${APPLICATION_NAME}" + }, + "tls": { + "termination": "passthrough" + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "id": "${APPLICATION_NAME}-jdbc", + "metadata": { + "name": "jdbc-${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "Route for application's JDBC service." + } + }, + "spec": { + "host": "${HOSTNAME_JDBC}", + "port": { + "targetPort": "jdbcs" + }, + "to": { + "name": "${APPLICATION_NAME}" + }, + "tls": { + "termination": "passthrough" + } + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + } + }, + { + "kind": "BuildConfig", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "source": { + "type": "Git", + "git": { + "uri": "${SOURCE_REPOSITORY_URL}", + "ref": "${SOURCE_REPOSITORY_REF}" + }, + "contextDir": "${CONTEXT_DIR}" + }, + "strategy": { + "type": "Source", + "sourceStrategy": { + "forcePull": true, + "from": { + "kind": "ImageStreamTag", + "namespace": "${IMAGE_STREAM_NAMESPACE}", + "name": "jboss-datavirt63-openshift:1.0" + } + } + }, + "output": { + "to": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}:latest" + } + }, + "triggers": [ + { + "type": "GitHub", + "github": { + "secret": "${GITHUB_WEBHOOK_SECRET}" + } + }, + { + "type": "Generic", + "generic": { + "secret": "${GENERIC_WEBHOOK_SECRET}" + } + }, + { + "type": "ImageChange", + "imageChange": {} + }, + { + "type": "ConfigChange" + } + ] + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "strategy": { + "type": "Recreate" + }, + "triggers": [ + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "${APPLICATION_NAME}" + ], + "from": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}:latest" + } + } + }, + { + "type": "ConfigChange" + } + ], + "replicas": 1, + "selector": { + "deploymentConfig": "${APPLICATION_NAME}" + }, + "template": { + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "deploymentConfig": "${APPLICATION_NAME}", + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "serviceAccountName": "${SERVICE_ACCOUNT_NAME}", + "terminationGracePeriodSeconds": 60, + "containers": [ + { + "name": "${APPLICATION_NAME}", + "image": "${APPLICATION_NAME}", + "imagePullPolicy": "Always", + "volumeMounts": [ + { + "name": "configuration", + "mountPath": "/etc/datavirt-environment", + "readOnly": true + }, + { + "name": "datavirt-keystore-volume", + "mountPath": "/etc/datavirt-secret-volume", + "readOnly": true + }, + { + "name": "datavirt-jgroups-keystore-volume", + "mountPath": "/etc/jgroups-encrypt-secret-volume", + "readOnly": true + } + ], + "livenessProbe": { + "exec": { + "command": [ + "/bin/bash", + "-c", + "/opt/eap/bin/livenessProbe.sh" + ] + } + }, + "readinessProbe": { + "exec": { + "command": [ + "/bin/bash", + "-c", + "/opt/eap/bin/readinessProbe.sh" + ] + } + }, + "ports": [ + { + "name": "jolokia", + "containerPort": 8778, + "protocol": "TCP" + }, + { + "name": "http", + "containerPort": 8080, + "protocol": "TCP" + }, + { + "name": "https", + "containerPort": 8443, + "protocol": "TCP" + }, + { + "name": "jdbc", + "containerPort": 31000, + "protocol": "TCP" + }, + { + "name": "jdbcs", + "containerPort": 31443, + "protocol": "TCP" + }, + { + "name": "ping", + "containerPort": 8888, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "OPENSHIFT_KUBE_PING_LABELS", + "value": "application=${APPLICATION_NAME}" + }, + { + "name": "OPENSHIFT_KUBE_PING_NAMESPACE", + "valueFrom": { + "fieldRef": { + "fieldPath": "metadata.namespace" + } + } + }, + { + "name": "HTTPS_KEYSTORE_DIR", + "value": "/etc/datavirt-secret-volume" + }, + { + "name": "HTTPS_KEYSTORE", + "value": "${HTTPS_KEYSTORE}" + }, + { + "name": "HTTPS_KEYSTORE_TYPE", + "value": "${HTTPS_KEYSTORE_TYPE}" + }, + { + "name": "HTTPS_NAME", + "value": "${HTTPS_NAME}" + }, + { + "name": "HTTPS_PASSWORD", + "value": "${HTTPS_PASSWORD}" + }, + { + "name": "JGROUPS_ENCRYPT_SECRET", + "value": "${JGROUPS_ENCRYPT_SECRET}" + }, + { + "name": "JGROUPS_ENCRYPT_KEYSTORE_DIR", + "value": "/etc/jgroups-encrypt-secret-volume" + }, + { + "name": "JGROUPS_ENCRYPT_KEYSTORE", + "value": "${JGROUPS_ENCRYPT_KEYSTORE}" + }, + { + "name": "JGROUPS_ENCRYPT_NAME", + "value": "${JGROUPS_ENCRYPT_NAME}" + }, + { + "name": "JGROUPS_ENCRYPT_PASSWORD", + "value": "${JGROUPS_ENCRYPT_PASSWORD}" + }, + { + "name": "JGROUPS_CLUSTER_PASSWORD", + "value": "${JGROUPS_CLUSTER_PASSWORD}" + }, + { + "name": "AUTO_DEPLOY_EXPLODED", + "value": "${AUTO_DEPLOY_EXPLODED}" + }, + { + "name": "TEIID_USERNAME", + "value": "${TEIID_USERNAME}" + }, + { + "name": "TEIID_PASSWORD", + "value": "${TEIID_PASSWORD}" + }, + { + "name": "MODESHAPE_USERNAME", + "value": "${MODESHAPE_USERNAME}" + }, + { + "name": "MODESHAPE_PASSWORD", + "value": "${MODESHAPE_PASSWORD}" + }, + { + "name": "ENV_FILES", + "value": "/etc/datavirt-environment/*" + }, + { + "name": "DATAVIRT_TRANSPORT_KEYSTORE", + "value": "/etc/datavirt-secret-volume/${HTTPS_KEYSTORE}" + }, + { + "name": "DATAVIRT_TRANSPORT_KEYSTORE_TYPE", + "value": "${HTTPS_KEYSTORE_TYPE}" + }, + { + "name": "DATAVIRT_TRANSPORT_KEY_ALIAS", + "value": "${HTTPS_NAME}" + }, + { + "name": "DATAVIRT_TRANSPORT_KEYSTORE_PASSWORD", + "value": "${HTTPS_PASSWORD}" + } + ] + } + ], + "volumes": [ + { + "name": "configuration", + "secret": { + "secretName": "${CONFIGURATION_NAME}" + } + }, + { + "name": "datavirt-keystore-volume", + "secret": { + "secretName": "${HTTPS_SECRET}" + } + }, + { + "name": "datavirt-jgroups-keystore-volume", + "secret": { + "secretName": "${JGROUPS_ENCRYPT_SECRET}" + } + } + ] + } + } + } + } + ] +} diff --git a/roles/openshift_examples/files/examples/v1.4/xpaas-streams/jboss-image-streams.json b/roles/openshift_examples/files/examples/v1.4/xpaas-streams/jboss-image-streams.json index 4edc97f41..a7cb12867 100644 --- a/roles/openshift_examples/files/examples/v1.4/xpaas-streams/jboss-image-streams.json +++ b/roles/openshift_examples/files/examples/v1.4/xpaas-streams/jboss-image-streams.json @@ -283,6 +283,28 @@ "kind": "ImageStream", "apiVersion": "v1", "metadata": { + "name": "jboss-datavirt63-openshift" + }, + "spec": { + "dockerImageRepository": "registry.access.redhat.com/jboss-datavirt-6/datavirt63-openshift", + "tags": [ + { + "name": "1.0", + "annotations": { + "description": "Red Hat JBoss Data Virtualization 6.3 S2I images.", + "iconClass": "icon-jboss", + "tags": "datavirt,java,jboss,xpaas", + "supports":"datavirt:6.3,java:8,xpaas:1.4", + "version": "1.0" + } + } + ] + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { "name": "jboss-amq-62" }, "spec": { diff --git a/roles/openshift_examples/files/examples/v1.4/xpaas-templates/datavirt63-basic-s2i.json b/roles/openshift_examples/files/examples/v1.4/xpaas-templates/datavirt63-basic-s2i.json new file mode 100644 index 000000000..7d64dac98 --- /dev/null +++ b/roles/openshift_examples/files/examples/v1.4/xpaas-templates/datavirt63-basic-s2i.json @@ -0,0 +1,415 @@ +{ + "kind": "Template", + "apiVersion": "v1", + "metadata": { + "annotations": { + "iconClass": "icon-jboss", + "description": "Application template for JBoss Data Virtualization 6.3 services built using S2I.", + "tags": "jdv,datavirt,jboss,xpaas", + "version": "1.4.0" + }, + "name": "datavirt63-basic-s2i" + }, + "labels": { + "template": "datavirt63-basic-s2i", + "xpaas": "1.4.0" + }, + "message": "A new data service has been created in your project. The username/password for accessing the service is ${TEIID_USERNAME}/${TEIID_PASSWORD}. Please be sure to create the \"${SERVICE_ACCOUNT_NAME}\" service account and the secret named ${CONFIGURATION_NAME} containing the datasource configuration details required by the deployed VDB(s).", + "parameters": [ + { + "description": "The name for the application.", + "displayName": "Application Name", + "name": "APPLICATION_NAME", + "value": "datavirt-app", + "required": true + }, + { + "description": "The name of the secret containing configuration properties for the data sources.", + "displayName": "Configuration Secret Name", + "name": "CONFIGURATION_NAME", + "value": "datavirt-app-config", + "required": true + }, + { + "description": "Specify a custom hostname for the http route. Leave blank to use default hostname, e.g.: <service-name>-<project>.<default-domain-suffix>", + "displayName": "Custom http Route Hostname", + "name": "HOSTNAME_HTTP", + "value": "", + "required": false + }, + { + "description": "The URL of the repository with your application source code.", + "displayName": "Git Repository URL", + "name": "SOURCE_REPOSITORY_URL", + "value": "https://github.com/jboss-openshift/openshift-quickstarts", + "required": true + }, + { + "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch.", + "displayName": "Git Reference", + "name": "SOURCE_REPOSITORY_REF", + "value": "master", + "required": false + }, + { + "description": "Set this to the relative path to your project if it is not in the root of your repository.", + "displayName": "Context Directory", + "name": "CONTEXT_DIR", + "value": "datavirt/dynamicvdb-datafederation/app", + "required": false + }, + { + "description": "The name of the service account to use for the deployment. The service account should be configured to allow usage of the secret specified by CONFIGURATION_NAME.", + "name": "SERVICE_ACCOUNT_NAME", + "value": "datavirt-service-account", + "required": true + }, + { + "description": "Username associated with Teiid data service.", + "displayName": "Teiid Username", + "name": "TEIID_USERNAME", + "from": "[\\a]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Password for Teiid user.", + "displayName": "Teiid User Password", + "name": "TEIID_PASSWORD", + "from": "[\\a\\A]{8}[\\d]{1}[\\A]{1}", + "generate": "expression", + "required": true + }, + { + "description": "Username associated with ModeShape.", + "displayName": "ModeShape Username", + "name": "MODESHAPE_USERNAME", + "from": "[\\a]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Password for ModeShape user.", + "displayName": "ModeShape User Password", + "name": "MODESHAPE_PASSWORD", + "from": "[\\a\\A]{8}[\\d]{1}[\\A]{1}", + "generate": "expression", + "required": true + }, + { + "description": "A secret string used to configure the GitHub webhook.", + "displayName": "Github Webhook Secret", + "name": "GITHUB_WEBHOOK_SECRET", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "A secret string used to configure the Generic webhook.", + "displayName": "Generic Webhook Secret", + "name": "GENERIC_WEBHOOK_SECRET", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Namespace in which the ImageStreams for Red Hat Middleware images are installed. These ImageStreams are normally installed in the openshift namespace. You should only need to modify this if you've installed the ImageStreams in a different namespace/project.", + "displayName": "ImageStream Namespace", + "name": "IMAGE_STREAM_NAMESPACE", + "value": "openshift", + "required": true + }, + { + "description": "Password used by JGroups to authenticate nodes in the cluster.", + "displayName": "JGroups Cluster Password", + "name": "JGROUPS_CLUSTER_PASSWORD", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Controls whether exploded deployment content should be automatically deployed", + "displayName": "Deploy Exploded Archives", + "name": "AUTO_DEPLOY_EXPLODED", + "value": "false", + "required": false + } + ], + "objects": [ + { + "kind": "Service", + "apiVersion": "v1", + "spec": { + "ports": [ + { + "name": "http", + "port": 8080, + "targetPort": "http" + }, + { + "name": "jdbc", + "port": 31000, + "targetPort": "jdbc" + } + ], + "selector": { + "deploymentConfig": "${APPLICATION_NAME}" + } + }, + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "The data virtualization services." + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "id": "${APPLICATION_NAME}-http", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "Route for application's http (REST) service." + } + }, + "spec": { + "host": "${HOSTNAME_HTTP}", + "port": { + "targetPort": "http" + }, + "to": { + "name": "${APPLICATION_NAME}" + } + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + } + }, + { + "kind": "BuildConfig", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "source": { + "type": "Git", + "git": { + "uri": "${SOURCE_REPOSITORY_URL}", + "ref": "${SOURCE_REPOSITORY_REF}" + }, + "contextDir": "${CONTEXT_DIR}" + }, + "strategy": { + "type": "Source", + "sourceStrategy": { + "forcePull": true, + "from": { + "kind": "ImageStreamTag", + "namespace": "${IMAGE_STREAM_NAMESPACE}", + "name": "jboss-datavirt63-openshift:1.0" + } + } + }, + "output": { + "to": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}:latest" + } + }, + "triggers": [ + { + "type": "GitHub", + "github": { + "secret": "${GITHUB_WEBHOOK_SECRET}" + } + }, + { + "type": "Generic", + "generic": { + "secret": "${GENERIC_WEBHOOK_SECRET}" + } + }, + { + "type": "ImageChange", + "imageChange": {} + }, + { + "type": "ConfigChange" + } + ] + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "strategy": { + "type": "Recreate" + }, + "triggers": [ + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "${APPLICATION_NAME}" + ], + "from": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}:latest" + } + } + }, + { + "type": "ConfigChange" + } + ], + "replicas": 1, + "selector": { + "deploymentConfig": "${APPLICATION_NAME}" + }, + "template": { + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "deploymentConfig": "${APPLICATION_NAME}", + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "serviceAccountName": "${SERVICE_ACCOUNT_NAME}", + "terminationGracePeriodSeconds": 60, + "containers": [ + { + "name": "${APPLICATION_NAME}", + "image": "${APPLICATION_NAME}", + "imagePullPolicy": "Always", + "volumeMounts": [ + { + "name": "configuration", + "mountPath": "/etc/datavirt-environment", + "readOnly": true + } + ], + "livenessProbe": { + "exec": { + "command": [ + "/bin/bash", + "-c", + "/opt/eap/bin/livenessProbe.sh" + ] + } + }, + "readinessProbe": { + "exec": { + "command": [ + "/bin/bash", + "-c", + "/opt/eap/bin/readinessProbe.sh" + ] + } + }, + "ports": [ + { + "name": "jolokia", + "containerPort": 8778, + "protocol": "TCP" + }, + { + "name": "http", + "containerPort": 8080, + "protocol": "TCP" + }, + { + "name": "jdbc", + "containerPort": 31000, + "protocol": "TCP" + }, + { + "name": "ping", + "containerPort": 8888, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "OPENSHIFT_KUBE_PING_LABELS", + "value": "application=${APPLICATION_NAME}" + }, + { + "name": "OPENSHIFT_KUBE_PING_NAMESPACE", + "valueFrom": { + "fieldRef": { + "fieldPath": "metadata.namespace" + } + } + }, + { + "name": "JGROUPS_CLUSTER_PASSWORD", + "value": "${JGROUPS_CLUSTER_PASSWORD}" + }, + { + "name": "AUTO_DEPLOY_EXPLODED", + "value": "${AUTO_DEPLOY_EXPLODED}" + }, + { + "name": "TEIID_USERNAME", + "value": "${TEIID_USERNAME}" + }, + { + "name": "TEIID_PASSWORD", + "value": "${TEIID_PASSWORD}" + }, + { + "name": "MODESHAPE_USERNAME", + "value": "${MODESHAPE_USERNAME}" + }, + { + "name": "MODESHAPE_PASSWORD", + "value": "${MODESHAPE_PASSWORD}" + }, + { + "name": "ENV_FILES", + "value": "/etc/datavirt-environment/*" + } + ] + } + ], + "volumes": [ + { + "name": "configuration", + "secret": { + "secretName": "${CONFIGURATION_NAME}" + } + } + ] + } + } + } + } + ] +} diff --git a/roles/openshift_examples/files/examples/v1.4/xpaas-templates/datavirt63-extensions-support-s2i.json b/roles/openshift_examples/files/examples/v1.4/xpaas-templates/datavirt63-extensions-support-s2i.json new file mode 100644 index 000000000..1e7c03b99 --- /dev/null +++ b/roles/openshift_examples/files/examples/v1.4/xpaas-templates/datavirt63-extensions-support-s2i.json @@ -0,0 +1,763 @@ +{ + "kind": "Template", + "apiVersion": "v1", + "metadata": { + "annotations": { + "iconClass": "icon-jboss", + "description": "Application template for JBoss Data Virtualization 6.3 services built using S2I. Includes support for installing extensions (e.g. third-party DB drivers) and the ability to configure certificates for serving secure content.", + "tags": "jdv,datavirt,jboss,xpaas", + "version": "1.4.0" + }, + "name": "datavirt63-extensions-support-s2i" + }, + "labels": { + "template": "datavirt63-extensions-support-s2i", + "xpaas": "1.4.0" + }, + "message": "A new data service has been created in your project. The username/password for accessing the service is ${TEIID_USERNAME}/${TEIID_PASSWORD}. Please be sure to create the \"${SERVICE_ACCOUNT_NAME}\" service account and the following secrets: \"${CONFIGURATION_NAME}\" containing the datasource configuration details required by the deployed VDB(s); \"${HTTPS_SECRET}\" containing the ${HTTPS_KEYSTORE} file used for serving secure content; \"${JGROUPS_ENCRYPT_SECRET}\" containing the ${JGROUPS_ENCRYPT_KEYSTORE} file used for securing JGroups communications.", + "parameters": [ + { + "description": "The name for the application.", + "displayName": "Application Name", + "name": "APPLICATION_NAME", + "value": "datavirt-app", + "required": true + }, + { + "description": "The name of the secret containing configuration properties for the data sources.", + "displayName": "Configuration Secret Name", + "name": "CONFIGURATION_NAME", + "value": "datavirt-app-config", + "required": true + }, + { + "description": "Specify a custom hostname for the http route. Leave blank to use default hostname, e.g.: <service-name>-<project>.<default-domain-suffix>", + "displayName": "Custom http Route Hostname", + "name": "HOSTNAME_HTTP", + "value": "", + "required": false + }, + { + "description": "Specify a custom hostname for the https route. Leave blank to use default hostname, e.g.: secure-<service-name>-<project>.<default-domain-suffix>", + "displayName": "Custom https Route Hostname", + "name": "HOSTNAME_HTTPS", + "value": "", + "required": false + }, + { + "description": "Specify a custom hostname for the JDBC route. Leave blank to use default hostname, e.g.: secure-<service-name>-<project>.<default-domain-suffix>", + "displayName": "Custom JDBC Route Hostname", + "name": "HOSTNAME_JDBC", + "value": "", + "required": false + }, + { + "description": "The URL of the repository with your application source code.", + "displayName": "Git Repository URL", + "name": "SOURCE_REPOSITORY_URL", + "value": "https://github.com/jboss-openshift/openshift-quickstarts", + "required": true + }, + { + "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch.", + "displayName": "Git Reference", + "name": "SOURCE_REPOSITORY_REF", + "value": "master", + "required": false + }, + { + "description": "Set this to the relative path to your project if it is not in the root of your repository.", + "displayName": "Context Directory", + "name": "CONTEXT_DIR", + "value": "datavirt/dynamicvdb-datafederation/app", + "required": false + }, + { + "description": "The URL of the repository with source code for the extensions image. The image should have all modules, etc., placed in the \"/extensions/\" directory in the image. If the contents are in a different directory, the sourcePath for the ImageSource in the BuildConfig must be modified.", + "displayName": "Extensions Git Repository URL", + "name": "EXTENSIONS_REPOSITORY_URL", + "value": "https://github.com/jboss-openshift/openshift-quickstarts", + "required": true + }, + { + "description": "Set this to a branch name, tag or other ref of your extensions repository if you are not using the default branch.", + "displayName": "Extensions Git Reference", + "name": "EXTENSIONS_REPOSITORY_REF", + "value": "master", + "required": false + }, + { + "description": "Set this to the relative path to your project if it is not in the root of your extensions repository.", + "displayName": "Extensions Context Directory", + "name": "EXTENSIONS_DIR", + "value": "datavirt/derby-driver-image", + "required": false + }, + { + "description": "Set this to the relative path to the Dockerfile in your extensions directory.", + "displayName": "Extensions Dockerfile", + "name": "EXTENSIONS_DOCKERFILE", + "value": "Dockerfile", + "required": false + }, + { + "description": "The name of the service account to use for the deployment. The service account should be configured to allow usage of the secret(s) specified by CONFIGURATION_NAME, HTTPS_SECRET and JGROUPS_ENCRYPT_SECRET.", + "name": "SERVICE_ACCOUNT_NAME", + "value": "datavirt-service-account", + "required": true + }, + { + "description": "The name of the secret containing the keystore to be used for serving secure content.", + "displayName": "Server Keystore Secret Name", + "name": "HTTPS_SECRET", + "value": "datavirt-app-secret", + "required": true + }, + { + "description": "The name of the keystore file within the secret.", + "displayName": "Server Keystore Filename", + "name": "HTTPS_KEYSTORE", + "value": "keystore.jks", + "required": false + }, + { + "description": "The type of the keystore file (JKS or JCEKS).", + "displayName": "Server Keystore Type", + "name": "HTTPS_KEYSTORE_TYPE", + "value": "", + "required": false + }, + { + "description": "The name associated with the server certificate.", + "displayName": "Server Certificate Name", + "name": "HTTPS_NAME", + "value": "jboss", + "required": false + }, + { + "description": "The password for the keystore and certificate", + "displayName": "Server Keystore Password", + "name": "HTTPS_PASSWORD", + "value": "mykeystorepass", + "required": false + }, + { + "description": "Username associated with Teiid data service.", + "displayName": "Teiid Username", + "name": "TEIID_USERNAME", + "from": "[\\a]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Password for Teiid user.", + "displayName": "Teiid User Password", + "name": "TEIID_PASSWORD", + "from": "[\\a\\A]{8}[\\d]{1}[\\A]{1}", + "generate": "expression", + "required": true + }, + { + "description": "Username associated with ModeShape.", + "displayName": "ModeShape Username", + "name": "MODESHAPE_USERNAME", + "from": "[\\a]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Password for ModeShape user.", + "displayName": "ModeShape User Password", + "name": "MODESHAPE_PASSWORD", + "from": "[\\a\\A]{8}[\\d]{1}[\\A]{1}", + "generate": "expression", + "required": true + }, + { + "description": "A secret string used to configure the GitHub webhook.", + "displayName": "Github Webhook Secret", + "name": "GITHUB_WEBHOOK_SECRET", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "A secret string used to configure the Generic webhook.", + "displayName": "Generic Webhook Secret", + "name": "GENERIC_WEBHOOK_SECRET", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Namespace in which the ImageStreams for Red Hat Middleware images are installed. These ImageStreams are normally installed in the openshift namespace. You should only need to modify this if you've installed the ImageStreams in a different namespace/project.", + "displayName": "ImageStream Namespace", + "name": "IMAGE_STREAM_NAMESPACE", + "value": "openshift", + "required": true + }, + { + "description": "The name of the secret containing the keystore to be used for securing JGroups communications.", + "displayName": "JGroups Secret Name", + "name": "JGROUPS_ENCRYPT_SECRET", + "value": "datavirt-app-secret", + "required": false + }, + { + "description": "The name of the keystore file within the JGroups secret.", + "displayName": "JGroups Keystore Filename", + "name": "JGROUPS_ENCRYPT_KEYSTORE", + "value": "jgroups.jceks", + "required": false + }, + { + "description": "The name associated with the JGroups server certificate", + "displayName": "JGroups Certificate Name", + "name": "JGROUPS_ENCRYPT_NAME", + "value": "secret-key", + "required": false + }, + { + "description": "The password for the keystore and certificate", + "displayName": "JGroups Keystore Password", + "name": "JGROUPS_ENCRYPT_PASSWORD", + "value": "password", + "required": false + }, + { + "description": "Password used by JGroups to authenticate nodes in the cluster.", + "displayName": "JGroups Cluster Password", + "name": "JGROUPS_CLUSTER_PASSWORD", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Controls whether exploded deployment content should be automatically deployed", + "displayName": "Deploy Exploded Archives", + "name": "AUTO_DEPLOY_EXPLODED", + "value": "false", + "required": false + } + ], + "objects": [ + { + "kind": "Service", + "apiVersion": "v1", + "spec": { + "ports": [ + { + "name": "http", + "port": 8080, + "targetPort": "http" + }, + { + "name": "https", + "port": 8443, + "targetPort": "https" + }, + { + "name": "jdbc", + "port": 31000, + "targetPort": "jdbc" + }, + { + "name": "jdbcs", + "port": 31443, + "targetPort": "jdbcs" + } + ], + "selector": { + "deploymentConfig": "${APPLICATION_NAME}" + } + }, + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "The data virtualization services." + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "id": "${APPLICATION_NAME}-http", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "Route for application's http (REST) service." + } + }, + "spec": { + "host": "${HOSTNAME_HTTP}", + "port": { + "targetPort": "http" + }, + "to": { + "name": "${APPLICATION_NAME}" + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "id": "${APPLICATION_NAME}-https", + "metadata": { + "name": "secure-${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "Route for application's https (REST) service." + } + }, + "spec": { + "host": "${HOSTNAME_HTTPS}", + "port": { + "targetPort": "https" + }, + "to": { + "name": "${APPLICATION_NAME}" + }, + "tls": { + "termination": "passthrough" + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "id": "${APPLICATION_NAME}-jdbc", + "metadata": { + "name": "jdbc-${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "Route for application's JDBC service." + } + }, + "spec": { + "host": "${HOSTNAME_JDBC}", + "port": { + "targetPort": "jdbcs" + }, + "to": { + "name": "${APPLICATION_NAME}" + }, + "tls": { + "termination": "passthrough" + } + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}-ext", + "labels": { + "application": "${APPLICATION_NAME}" + } + } + }, + { + "kind": "BuildConfig", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}-ext", + "labels": { + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "source": { + "type": "Git", + "git": { + "uri": "${EXTENSIONS_REPOSITORY_URL}", + "ref": "${EXTENSIONS_REPOSITORY_REF}" + }, + "contextDir": "${EXTENSIONS_DIR}" + }, + "strategy": { + "type": "Docker", + "dockerStrategy": { + "dockerfilePath": "${EXTENSIONS_DOCKERFILE}" + } + }, + "output": { + "to": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}-ext:latest" + } + }, + "triggers": [ + { + "type": "GitHub", + "github": { + "secret": "${GITHUB_WEBHOOK_SECRET}" + } + }, + { + "type": "Generic", + "generic": { + "secret": "${GENERIC_WEBHOOK_SECRET}" + } + }, + { + "type": "ConfigChange" + } + ] + } + }, + { + "kind": "BuildConfig", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "source": { + "type": "Git", + "git": { + "uri": "${SOURCE_REPOSITORY_URL}", + "ref": "${SOURCE_REPOSITORY_REF}" + }, + "contextDir": "${CONTEXT_DIR}", + "images": [ + { + "from": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}-ext:latest" + }, + "paths": [ + { + "destinationDir": "./${CONTEXT_DIR}/extensions/extras", + "sourcePath": "/extensions/." + } + ] + } + ] + }, + "strategy": { + "type": "Source", + "sourceStrategy": { + "forcePull": true, + "from": { + "kind": "ImageStreamTag", + "namespace": "${IMAGE_STREAM_NAMESPACE}", + "name": "jboss-datavirt63-openshift:1.0" + }, + "env": [ + { + "name": "CUSTOM_INSTALL_DIRECTORIES", + "value": "extensions/*" + } + ] + } + }, + "output": { + "to": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}:latest" + } + }, + "triggers": [ + { + "type": "GitHub", + "github": { + "secret": "${GITHUB_WEBHOOK_SECRET}" + } + }, + { + "type": "Generic", + "generic": { + "secret": "${GENERIC_WEBHOOK_SECRET}" + } + }, + { + "type": "ImageChange", + "imageChange": {} + }, + { + "type": "ImageChange", + "imageChange": { + "from": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}-ext:latest" + } + } + }, + { + "type": "ConfigChange" + } + ] + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "strategy": { + "type": "Recreate" + }, + "triggers": [ + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "${APPLICATION_NAME}" + ], + "from": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}:latest" + } + } + }, + { + "type": "ConfigChange" + } + ], + "replicas": 1, + "selector": { + "deploymentConfig": "${APPLICATION_NAME}" + }, + "template": { + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "deploymentConfig": "${APPLICATION_NAME}", + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "serviceAccountName": "${SERVICE_ACCOUNT_NAME}", + "terminationGracePeriodSeconds": 60, + "containers": [ + { + "name": "${APPLICATION_NAME}", + "image": "${APPLICATION_NAME}", + "imagePullPolicy": "Always", + "volumeMounts": [ + { + "name": "configuration", + "mountPath": "/etc/datavirt-environment", + "readOnly": true + }, + { + "name": "datavirt-keystore-volume", + "mountPath": "/etc/datavirt-secret-volume", + "readOnly": true + }, + { + "name": "datavirt-jgroups-keystore-volume", + "mountPath": "/etc/jgroups-encrypt-secret-volume", + "readOnly": true + } + ], + "livenessProbe": { + "exec": { + "command": [ + "/bin/bash", + "-c", + "/opt/eap/bin/livenessProbe.sh" + ] + } + }, + "readinessProbe": { + "exec": { + "command": [ + "/bin/bash", + "-c", + "/opt/eap/bin/readinessProbe.sh" + ] + } + }, + "ports": [ + { + "name": "jolokia", + "containerPort": 8778, + "protocol": "TCP" + }, + { + "name": "http", + "containerPort": 8080, + "protocol": "TCP" + }, + { + "name": "https", + "containerPort": 8443, + "protocol": "TCP" + }, + { + "name": "jdbc", + "containerPort": 31000, + "protocol": "TCP" + }, + { + "name": "jdbcs", + "containerPort": 31443, + "protocol": "TCP" + }, + { + "name": "ping", + "containerPort": 8888, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "OPENSHIFT_KUBE_PING_LABELS", + "value": "application=${APPLICATION_NAME}" + }, + { + "name": "OPENSHIFT_KUBE_PING_NAMESPACE", + "valueFrom": { + "fieldRef": { + "fieldPath": "metadata.namespace" + } + } + }, + { + "name": "HTTPS_KEYSTORE_DIR", + "value": "/etc/datavirt-secret-volume" + }, + { + "name": "HTTPS_KEYSTORE", + "value": "${HTTPS_KEYSTORE}" + }, + { + "name": "HTTPS_KEYSTORE_TYPE", + "value": "${HTTPS_KEYSTORE_TYPE}" + }, + { + "name": "HTTPS_NAME", + "value": "${HTTPS_NAME}" + }, + { + "name": "HTTPS_PASSWORD", + "value": "${HTTPS_PASSWORD}" + }, + { + "name": "JGROUPS_ENCRYPT_SECRET", + "value": "${JGROUPS_ENCRYPT_SECRET}" + }, + { + "name": "JGROUPS_ENCRYPT_KEYSTORE_DIR", + "value": "/etc/jgroups-encrypt-secret-volume" + }, + { + "name": "JGROUPS_ENCRYPT_KEYSTORE", + "value": "${JGROUPS_ENCRYPT_KEYSTORE}" + }, + { + "name": "JGROUPS_ENCRYPT_NAME", + "value": "${JGROUPS_ENCRYPT_NAME}" + }, + { + "name": "JGROUPS_ENCRYPT_PASSWORD", + "value": "${JGROUPS_ENCRYPT_PASSWORD}" + }, + { + "name": "JGROUPS_CLUSTER_PASSWORD", + "value": "${JGROUPS_CLUSTER_PASSWORD}" + }, + { + "name": "AUTO_DEPLOY_EXPLODED", + "value": "${AUTO_DEPLOY_EXPLODED}" + }, + { + "name": "TEIID_USERNAME", + "value": "${TEIID_USERNAME}" + }, + { + "name": "TEIID_PASSWORD", + "value": "${TEIID_PASSWORD}" + }, + { + "name": "MODESHAPE_USERNAME", + "value": "${MODESHAPE_USERNAME}" + }, + { + "name": "MODESHAPE_PASSWORD", + "value": "${MODESHAPE_PASSWORD}" + }, + { + "name": "ENV_FILES", + "value": "/etc/datavirt-environment/*" + }, + { + "name": "DATAVIRT_TRANSPORT_KEYSTORE", + "value": "/etc/datavirt-secret-volume/${HTTPS_KEYSTORE}" + }, + { + "name": "DATAVIRT_TRANSPORT_KEYSTORE_TYPE", + "value": "${HTTPS_KEYSTORE_TYPE}" + }, + { + "name": "DATAVIRT_TRANSPORT_KEY_ALIAS", + "value": "${HTTPS_NAME}" + }, + { + "name": "DATAVIRT_TRANSPORT_KEYSTORE_PASSWORD", + "value": "${HTTPS_PASSWORD}" + }, + { + "name": "QS_DB_TYPE", + "value": "derby", + "description": "Used soley by the quickstart and set here to ensure the template can be instatiated with its default parameter values, i.e. so itworks ootb." + } + ] + } + ], + "volumes": [ + { + "name": "configuration", + "secret": { + "secretName": "${CONFIGURATION_NAME}" + } + }, + { + "name": "datavirt-keystore-volume", + "secret": { + "secretName": "${HTTPS_SECRET}" + } + }, + { + "name": "datavirt-jgroups-keystore-volume", + "secret": { + "secretName": "${JGROUPS_ENCRYPT_SECRET}" + } + } + ] + } + } + } + } + ] +} diff --git a/roles/openshift_examples/files/examples/v1.4/xpaas-templates/datavirt63-secure-s2i.json b/roles/openshift_examples/files/examples/v1.4/xpaas-templates/datavirt63-secure-s2i.json new file mode 100644 index 000000000..07f926ff3 --- /dev/null +++ b/roles/openshift_examples/files/examples/v1.4/xpaas-templates/datavirt63-secure-s2i.json @@ -0,0 +1,642 @@ +{ + "kind": "Template", + "apiVersion": "v1", + "metadata": { + "annotations": { + "iconClass": "icon-jboss", + "description": "Application template for JBoss Data Virtualization 6.3 services built using S2I. Includes ability to configure certificates for serving secure content.", + "tags": "jdv,datavirt,jboss,xpaas", + "version": "1.4.0" + }, + "name": "datavirt63-secure-s2i" + }, + "labels": { + "template": "datavirt63-secure-s2i", + "xpaas": "1.4.0" + }, + "message": "A new data service has been created in your project. The username/password for accessing the service is ${TEIID_USERNAME}/${TEIID_PASSWORD}. Please be sure to create the \"${SERVICE_ACCOUNT_NAME}\" service account and the following secrets: \"${CONFIGURATION_NAME}\" containing the datasource configuration details required by the deployed VDB(s); \"${HTTPS_SECRET}\" containing the ${HTTPS_KEYSTORE} file used for serving secure content; \"${JGROUPS_ENCRYPT_SECRET}\" containing the ${JGROUPS_ENCRYPT_KEYSTORE} file used for securing JGroups communications.", + "parameters": [ + { + "description": "The name for the application.", + "displayName": "Application Name", + "name": "APPLICATION_NAME", + "value": "datavirt-app", + "required": true + }, + { + "description": "The name of the secret containing configuration properties for the data sources.", + "displayName": "Configuration Secret Name", + "name": "CONFIGURATION_NAME", + "value": "datavirt-app-config", + "required": true + }, + { + "description": "Specify a custom hostname for the http route. Leave blank to use default hostname, e.g.: <service-name>-<project>.<default-domain-suffix>", + "displayName": "Custom http Route Hostname", + "name": "HOSTNAME_HTTP", + "value": "", + "required": false + }, + { + "description": "Specify a custom hostname for the https route. Leave blank to use default hostname, e.g.: secure-<service-name>-<project>.<default-domain-suffix>", + "displayName": "Custom https Route Hostname", + "name": "HOSTNAME_HTTPS", + "value": "", + "required": false + }, + { + "description": "Specify a custom hostname for the JDBC route. Leave blank to use default hostname, e.g.: secure-<service-name>-<project>.<default-domain-suffix>", + "displayName": "Custom JDBC Route Hostname", + "name": "HOSTNAME_JDBC", + "value": "", + "required": false + }, + { + "description": "The URL of the repository with your application source code.", + "displayName": "Git Repository URL", + "name": "SOURCE_REPOSITORY_URL", + "value": "https://github.com/jboss-openshift/openshift-quickstarts", + "required": true + }, + { + "description": "Set this to a branch name, tag or other ref of your repository if you are not using the default branch.", + "displayName": "Git Reference", + "name": "SOURCE_REPOSITORY_REF", + "value": "master", + "required": false + }, + { + "description": "Set this to the relative path to your project if it is not in the root of your repository.", + "displayName": "Context Directory", + "name": "CONTEXT_DIR", + "value": "datavirt/dynamicvdb-datafederation/app", + "required": false + }, + { + "description": "The name of the service account to use for the deployment. The service account should be configured to allow usage of the secret(s) specified by CONFIGURATION_NAME, HTTPS_SECRET and JGROUPS_ENCRYPT_SECRET.", + "name": "SERVICE_ACCOUNT_NAME", + "value": "datavirt-service-account", + "required": true + }, + { + "description": "The name of the secret containing the keystore to be used for serving secure content.", + "displayName": "Server Keystore Secret Name", + "name": "HTTPS_SECRET", + "value": "datavirt-app-secret", + "required": true + }, + { + "description": "The name of the keystore file within the secret.", + "displayName": "Server Keystore Filename", + "name": "HTTPS_KEYSTORE", + "value": "keystore.jks", + "required": false + }, + { + "description": "The type of the keystore file (JKS or JCEKS).", + "displayName": "Server Keystore Type", + "name": "HTTPS_KEYSTORE_TYPE", + "value": "", + "required": false + }, + { + "description": "The name associated with the server certificate.", + "displayName": "Server Certificate Name", + "name": "HTTPS_NAME", + "value": "jboss", + "required": false + }, + { + "description": "The password for the keystore and certificate", + "displayName": "Server Keystore Password", + "name": "HTTPS_PASSWORD", + "value": "mykeystorepass", + "required": false + }, + { + "description": "Username associated with Teiid data service.", + "displayName": "Teiid Username", + "name": "TEIID_USERNAME", + "from": "[\\a]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Password for Teiid user.", + "displayName": "Teiid User Password", + "name": "TEIID_PASSWORD", + "from": "[\\a\\A]{8}[\\d]{1}[\\A]{1}", + "generate": "expression", + "required": true + }, + { + "description": "Username associated with ModeShape.", + "displayName": "ModeShape Username", + "name": "MODESHAPE_USERNAME", + "from": "[\\a]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Password for ModeShape user.", + "displayName": "ModeShape User Password", + "name": "MODESHAPE_PASSWORD", + "from": "[\\a\\A]{8}[\\d]{1}[\\A]{1}", + "generate": "expression", + "required": true + }, + { + "description": "A secret string used to configure the GitHub webhook.", + "displayName": "Github Webhook Secret", + "name": "GITHUB_WEBHOOK_SECRET", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "A secret string used to configure the Generic webhook.", + "displayName": "Generic Webhook Secret", + "name": "GENERIC_WEBHOOK_SECRET", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Namespace in which the ImageStreams for Red Hat Middleware images are installed. These ImageStreams are normally installed in the openshift namespace. You should only need to modify this if you've installed the ImageStreams in a different namespace/project.", + "displayName": "ImageStream Namespace", + "name": "IMAGE_STREAM_NAMESPACE", + "value": "openshift", + "required": true + }, + { + "description": "The name of the secret containing the keystore to be used for securing JGroups communications.", + "displayName": "JGroups Secret Name", + "name": "JGROUPS_ENCRYPT_SECRET", + "value": "datavirt-app-secret", + "required": false + }, + { + "description": "The name of the keystore file within the JGroups secret.", + "displayName": "JGroups Keystore Filename", + "name": "JGROUPS_ENCRYPT_KEYSTORE", + "value": "jgroups.jceks", + "required": false + }, + { + "description": "The name associated with the JGroups server certificate", + "displayName": "JGroups Certificate Name", + "name": "JGROUPS_ENCRYPT_NAME", + "value": "secret-key", + "required": false + }, + { + "description": "The password for the keystore and certificate", + "displayName": "JGroups Keystore Password", + "name": "JGROUPS_ENCRYPT_PASSWORD", + "value": "password", + "required": false + }, + { + "description": "Password used by JGroups to authenticate nodes in the cluster.", + "displayName": "JGroups Cluster Password", + "name": "JGROUPS_CLUSTER_PASSWORD", + "from": "[a-zA-Z0-9]{8}", + "generate": "expression", + "required": true + }, + { + "description": "Controls whether exploded deployment content should be automatically deployed", + "displayName": "Deploy Exploded Archives", + "name": "AUTO_DEPLOY_EXPLODED", + "value": "false", + "required": false + } + ], + "objects": [ + { + "kind": "Service", + "apiVersion": "v1", + "spec": { + "ports": [ + { + "name": "http", + "port": 8080, + "targetPort": "http" + }, + { + "name": "https", + "port": 8443, + "targetPort": "https" + }, + { + "name": "jdbc", + "port": 31000, + "targetPort": "jdbc" + }, + { + "name": "jdbcs", + "port": 31443, + "targetPort": "jdbcs" + } + ], + "selector": { + "deploymentConfig": "${APPLICATION_NAME}" + } + }, + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "The data virtualization services." + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "id": "${APPLICATION_NAME}-http", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "Route for application's http (REST) service." + } + }, + "spec": { + "host": "${HOSTNAME_HTTP}", + "port": { + "targetPort": "http" + }, + "to": { + "name": "${APPLICATION_NAME}" + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "id": "${APPLICATION_NAME}-https", + "metadata": { + "name": "secure-${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "Route for application's https (REST) service." + } + }, + "spec": { + "host": "${HOSTNAME_HTTPS}", + "port": { + "targetPort": "https" + }, + "to": { + "name": "${APPLICATION_NAME}" + }, + "tls": { + "termination": "passthrough" + } + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "id": "${APPLICATION_NAME}-jdbc", + "metadata": { + "name": "jdbc-${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + }, + "annotations": { + "description": "Route for application's JDBC service." + } + }, + "spec": { + "host": "${HOSTNAME_JDBC}", + "port": { + "targetPort": "jdbcs" + }, + "to": { + "name": "${APPLICATION_NAME}" + }, + "tls": { + "termination": "passthrough" + } + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + } + }, + { + "kind": "BuildConfig", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "source": { + "type": "Git", + "git": { + "uri": "${SOURCE_REPOSITORY_URL}", + "ref": "${SOURCE_REPOSITORY_REF}" + }, + "contextDir": "${CONTEXT_DIR}" + }, + "strategy": { + "type": "Source", + "sourceStrategy": { + "forcePull": true, + "from": { + "kind": "ImageStreamTag", + "namespace": "${IMAGE_STREAM_NAMESPACE}", + "name": "jboss-datavirt63-openshift:1.0" + } + } + }, + "output": { + "to": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}:latest" + } + }, + "triggers": [ + { + "type": "GitHub", + "github": { + "secret": "${GITHUB_WEBHOOK_SECRET}" + } + }, + { + "type": "Generic", + "generic": { + "secret": "${GENERIC_WEBHOOK_SECRET}" + } + }, + { + "type": "ImageChange", + "imageChange": {} + }, + { + "type": "ConfigChange" + } + ] + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "strategy": { + "type": "Recreate" + }, + "triggers": [ + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "${APPLICATION_NAME}" + ], + "from": { + "kind": "ImageStreamTag", + "name": "${APPLICATION_NAME}:latest" + } + } + }, + { + "type": "ConfigChange" + } + ], + "replicas": 1, + "selector": { + "deploymentConfig": "${APPLICATION_NAME}" + }, + "template": { + "metadata": { + "name": "${APPLICATION_NAME}", + "labels": { + "deploymentConfig": "${APPLICATION_NAME}", + "application": "${APPLICATION_NAME}" + } + }, + "spec": { + "serviceAccountName": "${SERVICE_ACCOUNT_NAME}", + "terminationGracePeriodSeconds": 60, + "containers": [ + { + "name": "${APPLICATION_NAME}", + "image": "${APPLICATION_NAME}", + "imagePullPolicy": "Always", + "volumeMounts": [ + { + "name": "configuration", + "mountPath": "/etc/datavirt-environment", + "readOnly": true + }, + { + "name": "datavirt-keystore-volume", + "mountPath": "/etc/datavirt-secret-volume", + "readOnly": true + }, + { + "name": "datavirt-jgroups-keystore-volume", + "mountPath": "/etc/jgroups-encrypt-secret-volume", + "readOnly": true + } + ], + "livenessProbe": { + "exec": { + "command": [ + "/bin/bash", + "-c", + "/opt/eap/bin/livenessProbe.sh" + ] + } + }, + "readinessProbe": { + "exec": { + "command": [ + "/bin/bash", + "-c", + "/opt/eap/bin/readinessProbe.sh" + ] + } + }, + "ports": [ + { + "name": "jolokia", + "containerPort": 8778, + "protocol": "TCP" + }, + { + "name": "http", + "containerPort": 8080, + "protocol": "TCP" + }, + { + "name": "https", + "containerPort": 8443, + "protocol": "TCP" + }, + { + "name": "jdbc", + "containerPort": 31000, + "protocol": "TCP" + }, + { + "name": "jdbcs", + "containerPort": 31443, + "protocol": "TCP" + }, + { + "name": "ping", + "containerPort": 8888, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "OPENSHIFT_KUBE_PING_LABELS", + "value": "application=${APPLICATION_NAME}" + }, + { + "name": "OPENSHIFT_KUBE_PING_NAMESPACE", + "valueFrom": { + "fieldRef": { + "fieldPath": "metadata.namespace" + } + } + }, + { + "name": "HTTPS_KEYSTORE_DIR", + "value": "/etc/datavirt-secret-volume" + }, + { + "name": "HTTPS_KEYSTORE", + "value": "${HTTPS_KEYSTORE}" + }, + { + "name": "HTTPS_KEYSTORE_TYPE", + "value": "${HTTPS_KEYSTORE_TYPE}" + }, + { + "name": "HTTPS_NAME", + "value": "${HTTPS_NAME}" + }, + { + "name": "HTTPS_PASSWORD", + "value": "${HTTPS_PASSWORD}" + }, + { + "name": "JGROUPS_ENCRYPT_SECRET", + "value": "${JGROUPS_ENCRYPT_SECRET}" + }, + { + "name": "JGROUPS_ENCRYPT_KEYSTORE_DIR", + "value": "/etc/jgroups-encrypt-secret-volume" + }, + { + "name": "JGROUPS_ENCRYPT_KEYSTORE", + "value": "${JGROUPS_ENCRYPT_KEYSTORE}" + }, + { + "name": "JGROUPS_ENCRYPT_NAME", + "value": "${JGROUPS_ENCRYPT_NAME}" + }, + { + "name": "JGROUPS_ENCRYPT_PASSWORD", + "value": "${JGROUPS_ENCRYPT_PASSWORD}" + }, + { + "name": "JGROUPS_CLUSTER_PASSWORD", + "value": "${JGROUPS_CLUSTER_PASSWORD}" + }, + { + "name": "AUTO_DEPLOY_EXPLODED", + "value": "${AUTO_DEPLOY_EXPLODED}" + }, + { + "name": "TEIID_USERNAME", + "value": "${TEIID_USERNAME}" + }, + { + "name": "TEIID_PASSWORD", + "value": "${TEIID_PASSWORD}" + }, + { + "name": "MODESHAPE_USERNAME", + "value": "${MODESHAPE_USERNAME}" + }, + { + "name": "MODESHAPE_PASSWORD", + "value": "${MODESHAPE_PASSWORD}" + }, + { + "name": "ENV_FILES", + "value": "/etc/datavirt-environment/*" + }, + { + "name": "DATAVIRT_TRANSPORT_KEYSTORE", + "value": "/etc/datavirt-secret-volume/${HTTPS_KEYSTORE}" + }, + { + "name": "DATAVIRT_TRANSPORT_KEYSTORE_TYPE", + "value": "${HTTPS_KEYSTORE_TYPE}" + }, + { + "name": "DATAVIRT_TRANSPORT_KEY_ALIAS", + "value": "${HTTPS_NAME}" + }, + { + "name": "DATAVIRT_TRANSPORT_KEYSTORE_PASSWORD", + "value": "${HTTPS_PASSWORD}" + } + ] + } + ], + "volumes": [ + { + "name": "configuration", + "secret": { + "secretName": "${CONFIGURATION_NAME}" + } + }, + { + "name": "datavirt-keystore-volume", + "secret": { + "secretName": "${HTTPS_SECRET}" + } + }, + { + "name": "datavirt-jgroups-keystore-volume", + "secret": { + "secretName": "${JGROUPS_ENCRYPT_SECRET}" + } + } + ] + } + } + } + } + ] +} diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py index ad4b1e47b..95a9d668a 100755 --- a/roles/openshift_facts/library/openshift_facts.py +++ b/roles/openshift_facts/library/openshift_facts.py @@ -14,20 +14,35 @@ except ImportError: # python3 import configparser as ConfigParser +# pylint: disable=no-name-in-module, import-error, wrong-import-order import copy +import errno +import json +import re import io import os import yaml -from distutils.util import strtobool -from distutils.version import LooseVersion import struct import socket +from distutils.util import strtobool +from distutils.version import LooseVersion + +# ignore pylint errors related to the module_utils import +# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import +# import module snippets +from ansible.module_utils.basic import * # noqa: F403 +from ansible.module_utils.facts import * # noqa: F403 +from ansible.module_utils.urls import * # noqa: F403 +from ansible.module_utils.six import iteritems, itervalues +from ansible.module_utils.six.moves.urllib.parse import urlparse, urlunparse +from ansible.module_utils._text import to_native + +HAVE_DBUS = False -HAVE_DBUS=False try: from dbus import SystemBus, Interface from dbus.exceptions import DBusException - HAVE_DBUS=True + HAVE_DBUS = True except ImportError: pass @@ -58,6 +73,7 @@ def migrate_docker_facts(facts): } if 'docker' not in facts: facts['docker'] = {} + # pylint: disable=consider-iterating-dictionary for role in params.keys(): if role in facts: for param in params[role]: @@ -76,6 +92,7 @@ def migrate_docker_facts(facts): return facts + # TODO: We should add a generic migration function that takes source and destination # paths and does the right thing rather than one function for common, one for node, etc. def migrate_common_facts(facts): @@ -86,6 +103,7 @@ def migrate_common_facts(facts): } if 'common' not in facts: facts['common'] = {} + # pylint: disable=consider-iterating-dictionary for role in params.keys(): if role in facts: for param in params[role]: @@ -93,6 +111,7 @@ def migrate_common_facts(facts): facts['common'][param] = facts[role].pop(param) return facts + def migrate_node_facts(facts): """ Migrate facts from various roles into node """ params = { @@ -100,6 +119,7 @@ def migrate_node_facts(facts): } if 'node' not in facts: facts['node'] = {} + # pylint: disable=consider-iterating-dictionary for role in params.keys(): if role in facts: for param in params[role]: @@ -125,7 +145,9 @@ def migrate_hosted_facts(facts): facts['hosted']['registry']['selector'] = facts['master'].pop('registry_selector') return facts + def migrate_admission_plugin_facts(facts): + """ Apply migrations for admission plugin facts """ if 'master' in facts: if 'kube_admission_plugin_config' in facts['master']: if 'admission_plugin_config' not in facts['master']: @@ -139,6 +161,7 @@ def migrate_admission_plugin_facts(facts): facts['master'].pop('kube_admission_plugin_config', None) return facts + def migrate_local_facts(facts): """ Apply migrations of local facts """ migrated_facts = copy.deepcopy(facts) @@ -149,6 +172,7 @@ def migrate_local_facts(facts): migrated_facts = migrate_admission_plugin_facts(migrated_facts) return migrated_facts + def first_ip(network): """ Return the first IPv4 address in network @@ -157,13 +181,14 @@ def first_ip(network): Returns: str: first IPv4 address """ - atoi = lambda addr: struct.unpack("!I", socket.inet_aton(addr))[0] - itoa = lambda addr: socket.inet_ntoa(struct.pack("!I", addr)) + atoi = lambda addr: struct.unpack("!I", socket.inet_aton(addr))[0] # noqa: E731 + itoa = lambda addr: socket.inet_ntoa(struct.pack("!I", addr)) # noqa: E731 (address, netmask) = network.split('/') netmask_i = (0xffffffff << (32 - atoi(netmask))) & 0xffffffff return itoa((atoi(address) & netmask_i) + 1) + def hostname_valid(hostname): """ Test if specified hostname should be considered valid @@ -201,11 +226,8 @@ def choose_hostname(hostnames=None, fallback=''): return hostname ip_regex = r'\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z' - ips = [i for i in hostnames - if (i is not None and isinstance(i, basestring) - and re.match(ip_regex, i))] - hosts = [i for i in hostnames - if i is not None and i != '' and i not in ips] + ips = [i for i in hostnames if i is not None and isinstance(i, basestring) and re.match(ip_regex, i)] + hosts = [i for i in hostnames if i is not None and i != '' and i not in ips] for host_list in (hosts, ips): for host in host_list: @@ -225,11 +247,11 @@ def query_metadata(metadata_url, headers=None, expect_json=False): Returns: dict or list: metadata request result """ - result, info = fetch_url(module, metadata_url, headers=headers) + result, info = fetch_url(module, metadata_url, headers=headers) # noqa: F405 if info['status'] != 200: raise OpenShiftFactsMetadataUnavailableError("Metadata unavailable") if expect_json: - return module.from_json(to_native(result.read())) + return module.from_json(to_native(result.read())) # noqa: F405 else: return [to_native(line.strip()) for line in result.readlines()] @@ -390,7 +412,7 @@ def normalize_openstack_facts(metadata, facts): facts['network']['ip'] = local_ipv4 facts['network']['public_ip'] = metadata['ec2_compat']['public-ipv4'] - for f_var, h_var, ip_var in [('hostname', 'hostname', 'local-ipv4'), + for f_var, h_var, ip_var in [('hostname', 'hostname', 'local-ipv4'), ('public_hostname', 'public-hostname', 'public-ipv4')]: try: if socket.gethostbyname(metadata['ec2_compat'][h_var]) == metadata['ec2_compat'][ip_var]: @@ -431,6 +453,7 @@ def normalize_provider_facts(provider, metadata): facts = normalize_openstack_facts(metadata, facts) return facts + def set_flannel_facts_if_unset(facts): """ Set flannel facts if not already present in facts dict dict: the facts dict updated with the flannel facts if @@ -448,6 +471,7 @@ def set_flannel_facts_if_unset(facts): facts['common']['use_flannel'] = use_flannel return facts + def set_nuage_facts_if_unset(facts): """ Set nuage facts if not already present in facts dict dict: the facts dict updated with the nuage facts if @@ -465,6 +489,7 @@ def set_nuage_facts_if_unset(facts): facts['common']['use_nuage'] = use_nuage return facts + def set_node_schedulability(facts): """ Set schedulable facts if not already present in facts dict Args: @@ -482,6 +507,7 @@ def set_node_schedulability(facts): facts['node']['schedulable'] = True return facts + def set_selectors(facts): """ Set selectors facts if not already present in facts dict Args: @@ -518,6 +544,7 @@ def set_selectors(facts): return facts + def set_dnsmasq_facts_if_unset(facts): """ Set dnsmasq facts if not already present in facts Args: @@ -537,6 +564,7 @@ def set_dnsmasq_facts_if_unset(facts): return facts + def set_project_cfg_facts_if_unset(facts): """ Set Project Configuration facts if not already present in facts dict dict: @@ -564,6 +592,7 @@ def set_project_cfg_facts_if_unset(facts): return facts + def set_identity_providers_if_unset(facts): """ Set identity_providers fact if not already present in facts dict @@ -590,6 +619,7 @@ def set_identity_providers_if_unset(facts): return facts + def set_url_facts_if_unset(facts): """ Set url facts if not already present in facts dict @@ -649,7 +679,6 @@ def set_url_facts_if_unset(facts): host, ports[prefix])) - r_lhn = "{0}:{1}".format(hostname, ports['api']).replace('.', '-') r_lhu = "system:openshift-master/{0}:{1}".format(api_hostname, ports['api']).replace('.', '-') facts['master'].setdefault('loopback_cluster_name', r_lhn) @@ -665,6 +694,7 @@ def set_url_facts_if_unset(facts): return facts + def set_aggregate_facts(facts): """ Set aggregate facts @@ -760,6 +790,7 @@ def set_etcd_facts_if_unset(facts): return facts + def set_deployment_facts_if_unset(facts): """ Set Facts that vary based on deployment_type. This currently includes common.service_type, common.config_base, master.registry_url, @@ -840,6 +871,7 @@ def set_deployment_facts_if_unset(facts): return facts + def set_version_facts_if_unset(facts): """ Set version facts. This currently includes common.version and common.version_gte_3_1_or_1_1. @@ -851,21 +883,23 @@ def set_version_facts_if_unset(facts): """ if 'common' in facts: deployment_type = facts['common']['deployment_type'] - version = get_openshift_version(facts) - if version: - facts['common']['version'] = version + openshift_version = get_openshift_version(facts) + if openshift_version: + version = LooseVersion(openshift_version) + facts['common']['version'] = openshift_version + facts['common']['short_version'] = '.'.join([str(x) for x in version.version[0:2]]) if deployment_type == 'origin': - version_gte_3_1_or_1_1 = LooseVersion(version) >= LooseVersion('1.1.0') - version_gte_3_1_1_or_1_1_1 = LooseVersion(version) >= LooseVersion('1.1.1') - version_gte_3_2_or_1_2 = LooseVersion(version) >= LooseVersion('1.2.0') - version_gte_3_3_or_1_3 = LooseVersion(version) >= LooseVersion('1.3.0') - version_gte_3_4_or_1_4 = LooseVersion(version) >= LooseVersion('1.4.0') + version_gte_3_1_or_1_1 = version >= LooseVersion('1.1.0') + version_gte_3_1_1_or_1_1_1 = version >= LooseVersion('1.1.1') + version_gte_3_2_or_1_2 = version >= LooseVersion('1.2.0') + version_gte_3_3_or_1_3 = version >= LooseVersion('1.3.0') + version_gte_3_4_or_1_4 = version >= LooseVersion('1.4.0') else: - version_gte_3_1_or_1_1 = LooseVersion(version) >= LooseVersion('3.0.2.905') - version_gte_3_1_1_or_1_1_1 = LooseVersion(version) >= LooseVersion('3.1.1') - version_gte_3_2_or_1_2 = LooseVersion(version) >= LooseVersion('3.1.1.901') - version_gte_3_3_or_1_3 = LooseVersion(version) >= LooseVersion('3.3.0') - version_gte_3_4_or_1_4 = LooseVersion(version) >= LooseVersion('3.4.0') + version_gte_3_1_or_1_1 = version >= LooseVersion('3.0.2.905') + version_gte_3_1_1_or_1_1_1 = version >= LooseVersion('3.1.1') + version_gte_3_2_or_1_2 = version >= LooseVersion('3.1.1.901') + version_gte_3_3_or_1_3 = version >= LooseVersion('3.3.0') + version_gte_3_4_or_1_4 = version >= LooseVersion('3.4.0') else: version_gte_3_1_or_1_1 = True version_gte_3_1_1_or_1_1_1 = True @@ -878,7 +912,6 @@ def set_version_facts_if_unset(facts): facts['common']['version_gte_3_3_or_1_3'] = version_gte_3_3_or_1_3 facts['common']['version_gte_3_4_or_1_4'] = version_gte_3_4_or_1_4 - if version_gte_3_4_or_1_4: examples_content_version = 'v1.4' elif version_gte_3_3_or_1_3: @@ -894,6 +927,7 @@ def set_version_facts_if_unset(facts): return facts + def set_manageiq_facts_if_unset(facts): """ Set manageiq facts. This currently includes common.use_manageiq. @@ -914,6 +948,7 @@ def set_manageiq_facts_if_unset(facts): return facts + def set_sdn_facts_if_unset(facts, system_facts): """ Set sdn facts if not already present in facts dict @@ -924,6 +959,7 @@ def set_sdn_facts_if_unset(facts, system_facts): dict: the facts dict updated with the generated sdn facts if they were not already present """ + # pylint: disable=too-many-branches if 'common' in facts: use_sdn = facts['common']['use_openshift_sdn'] if not (use_sdn == '' or isinstance(use_sdn, bool)): @@ -973,7 +1009,9 @@ def set_sdn_facts_if_unset(facts, system_facts): return facts + def set_nodename(facts): + """ set nodename """ if 'node' in facts and 'common' in facts: if 'cloudprovider' in facts and facts['cloudprovider']['kind'] == 'openstack': facts['node']['nodename'] = facts['provider']['metadata']['hostname'].replace('.novalocal', '') @@ -981,6 +1019,7 @@ def set_nodename(facts): facts['node']['nodename'] = facts['common']['hostname'].lower() return facts + def migrate_oauth_template_facts(facts): """ Migrate an old oauth template fact to a newer format if it's present. @@ -1000,6 +1039,7 @@ def migrate_oauth_template_facts(facts): facts['master']['oauth_templates']['login'] = facts['master']['oauth_template'] return facts + def format_url(use_ssl, hostname, port, path=''): """ Format url based on ssl flag, hostname, port and path @@ -1022,6 +1062,7 @@ def format_url(use_ssl, hostname, port, path=''): url = urlunparse((scheme, netloc, path, '', '', '')) return url + def get_current_config(facts): """ Get current openshift config @@ -1051,10 +1092,9 @@ def get_current_config(facts): ) kubeconfig_path = os.path.join(kubeconfig_dir, '.kubeconfig') - if (os.path.isfile('/usr/bin/openshift') - and os.path.isfile(kubeconfig_path)): + if os.path.isfile('/usr/bin/openshift') and os.path.isfile(kubeconfig_path): try: - _, output, _ = module.run_command( + _, output, _ = module.run_command( # noqa: F405 ["/usr/bin/openshift", "ex", "config", "view", "-o", "json", "--kubeconfig=%s" % kubeconfig_path], check_rc=False @@ -1085,6 +1125,7 @@ def get_current_config(facts): return current_config + def build_kubelet_args(facts): """Build node kubelet_args @@ -1129,6 +1170,7 @@ values provided as a list. Hence the gratuitous use of ['foo'] below. # # map() seems to be returning an itertools.imap object # instead of a list. We cast it to a list ourselves. + # pylint: disable=unnecessary-lambda labels_str = list(map(lambda x: '='.join(x), facts['node']['labels'].items())) if labels_str != '': kubelet_args['node-labels'] = labels_str @@ -1139,6 +1181,7 @@ values provided as a list. Hence the gratuitous use of ['foo'] below. facts = merge_facts({'node': {'kubelet_args': kubelet_args}}, facts, [], []) return facts + def build_controller_args(facts): """ Build master controller_args """ cloud_cfg_path = os.path.join(facts['common']['config_base'], @@ -1160,6 +1203,7 @@ def build_controller_args(facts): facts = merge_facts({'master': {'controller_args': controller_args}}, facts, [], []) return facts + def build_api_server_args(facts): """ Build master api_server_args """ cloud_cfg_path = os.path.join(facts['common']['config_base'], @@ -1181,6 +1225,7 @@ def build_api_server_args(facts): facts = merge_facts({'master': {'api_server_args': api_server_args}}, facts, [], []) return facts + def is_service_running(service): """ Queries systemd through dbus to see if the service is running """ service_running = False @@ -1200,6 +1245,7 @@ def is_service_running(service): return service_running + def get_version_output(binary, version_cmd): """ runs and returns the version output for a command """ cmd = [] @@ -1210,9 +1256,10 @@ def get_version_output(binary, version_cmd): cmd.append(item) if os.path.isfile(cmd[0]): - _, output, _ = module.run_command(cmd) + _, output, _ = module.run_command(cmd) # noqa: F405 return output + def get_docker_version_info(): """ Parses and returns the docker version info """ result = None @@ -1225,6 +1272,7 @@ def get_docker_version_info(): } return result + def get_hosted_registry_insecure(): """ Parses OPTIONS from /etc/sysconfig/docker to determine if the registry is currently insecure. @@ -1239,10 +1287,12 @@ def get_hosted_registry_insecure(): options = config.get('root', 'OPTIONS') if 'insecure-registry' in options: hosted_registry_insecure = True + # pylint: disable=bare-except except: pass return hosted_registry_insecure + def get_openshift_version(facts): """ Get current version of openshift on the host. @@ -1264,7 +1314,7 @@ def get_openshift_version(facts): return chomp_commit_offset(facts['common']['version']) if os.path.isfile('/usr/bin/openshift'): - _, output, _ = module.run_command(['/usr/bin/openshift', 'version']) + _, output, _ = module.run_command(['/usr/bin/openshift', 'version']) # noqa: F405 version = parse_openshift_version(output) elif 'common' in facts and 'is_containerized' in facts['common']: version = get_container_openshift_version(facts) @@ -1273,7 +1323,7 @@ def get_openshift_version(facts): # This can be very slow and may get re-run multiple times, so we only use this # if other methods failed to find a version. if not version and os.path.isfile('/usr/local/bin/openshift'): - _, output, _ = module.run_command(['/usr/local/bin/openshift', 'version']) + _, output, _ = module.run_command(['/usr/local/bin/openshift', 'version']) # noqa: F405 version = parse_openshift_version(output) return chomp_commit_offset(version) @@ -1363,9 +1413,10 @@ def apply_provider_facts(facts, provider_facts): facts['provider'] = provider_facts return facts + # Disabling pylint too many branches. This function needs refactored # but is a very core part of openshift_facts. -# pylint: disable=too-many-branches +# pylint: disable=too-many-branches, too-many-nested-blocks def merge_facts(orig, new, additive_facts_to_overwrite, protected_facts_to_overwrite): """ Recursively merge facts dicts @@ -1434,16 +1485,18 @@ def merge_facts(orig, new, additive_facts_to_overwrite, protected_facts_to_overw elif key in protected_facts and key not in [x.split('.')[-1] for x in protected_facts_to_overwrite]: # The master count (int) can only increase unless it # has been passed as a protected fact to overwrite. - if key == 'master_count': + if key == 'master_count' and new[key] is not None and new[key] is not '': if int(value) <= int(new[key]): facts[key] = copy.deepcopy(new[key]) else: - module.fail_json(msg='openshift_facts received a lower value for openshift.master.master_count') + # pylint: disable=line-too-long + module.fail_json(msg='openshift_facts received a lower value for openshift.master.master_count') # noqa: F405 # ha (bool) can not change unless it has been passed # as a protected fact to overwrite. if key == 'ha': if safe_get_bool(value) != safe_get_bool(new[key]): - module.fail_json(msg='openshift_facts received a different value for openshift.master.ha') + # pylint: disable=line-too-long + module.fail_json(msg='openshift_facts received a different value for openshift.master.ha') # noqa: F405 else: facts[key] = value # No other condition has been met. Overwrite the old fact @@ -1463,6 +1516,7 @@ def merge_facts(orig, new, additive_facts_to_overwrite, protected_facts_to_overw facts[key] = copy.deepcopy(new[key]) return facts + def save_local_facts(filename, facts): """ Save local facts @@ -1478,7 +1532,7 @@ def save_local_facts(filename, facts): if exception.errno != errno.EEXIST: # but it is okay if it is already there raise # pass any other exceptions up the chain with open(filename, 'w') as fact_file: - fact_file.write(module.jsonify(facts)) + fact_file.write(module.jsonify(facts)) # noqa: F405 os.chmod(filename, 0o600) except (IOError, OSError) as ex: raise OpenShiftFactsFileWriteError( @@ -1514,6 +1568,7 @@ def get_local_facts_from_file(filename): return local_facts + def sort_unique(alist): """ Sorts and de-dupes a list @@ -1531,6 +1586,7 @@ def sort_unique(alist): return out + def safe_get_bool(fact): """ Get a boolean fact safely. @@ -1541,6 +1597,7 @@ def safe_get_bool(fact): """ return bool(strtobool(str(fact))) + def set_proxy_facts(facts): """ Set global proxy facts and promote defaults from http_proxy, https_proxy, no_proxy to the more specific builddefaults and builddefaults_git vars. @@ -1556,13 +1613,11 @@ def set_proxy_facts(facts): if 'common' in facts: common = facts['common'] if 'http_proxy' in common or 'https_proxy' in common: - if 'no_proxy' in common and \ - isinstance(common['no_proxy'], basestring): + if 'no_proxy' in common and isinstance(common['no_proxy'], basestring): common['no_proxy'] = common['no_proxy'].split(",") elif 'no_proxy' not in common: common['no_proxy'] = [] - if 'generate_no_proxy_hosts' in common and \ - safe_get_bool(common['generate_no_proxy_hosts']): + if 'generate_no_proxy_hosts' in common and safe_get_bool(common['generate_no_proxy_hosts']): if 'no_proxy_internal_hostnames' in common: common['no_proxy'].extend(common['no_proxy_internal_hostnames'].split(',')) # We always add local dns domain and ourselves no matter what @@ -1593,13 +1648,14 @@ def set_proxy_facts(facts): # into admission_plugin_config if 'admission_plugin_config' not in facts['master']: facts['master']['admission_plugin_config'] = dict() - if 'config' in builddefaults and ('http_proxy' in builddefaults or \ - 'https_proxy' in builddefaults): + if 'config' in builddefaults and ('http_proxy' in builddefaults or + 'https_proxy' in builddefaults): facts['master']['admission_plugin_config'].update(builddefaults['config']) facts['builddefaults'] = builddefaults return facts + # pylint: disable=too-many-statements def set_container_facts_if_unset(facts): """ Set containerized facts. @@ -1671,6 +1727,7 @@ def set_container_facts_if_unset(facts): return facts + def set_installed_variant_rpm_facts(facts): """ Set RPM facts of installed variant Args: @@ -1685,7 +1742,7 @@ def set_installed_variant_rpm_facts(facts): ['{0}-{1}'.format(base_rpm, r) for r in optional_rpms] + \ ['tuned-profiles-%s-node' % base_rpm] for rpm in variant_rpms: - exit_code, _, _ = module.run_command(['rpm', '-q', rpm]) + exit_code, _, _ = module.run_command(['rpm', '-q', rpm]) # noqa: F405 if exit_code == 0: installed_rpms.append(rpm) @@ -1693,7 +1750,6 @@ def set_installed_variant_rpm_facts(facts): return facts - class OpenShiftFactsInternalError(Exception): """Origin Facts Error""" pass @@ -1761,12 +1817,12 @@ class OpenShiftFacts(object): try: # ansible-2.1 # pylint: disable=too-many-function-args,invalid-name - self.system_facts = ansible_facts(module, ['hardware', 'network', 'virtual', 'facter']) + self.system_facts = ansible_facts(module, ['hardware', 'network', 'virtual', 'facter']) # noqa: F405 for (k, v) in self.system_facts.items(): self.system_facts["ansible_%s" % k.replace('-', '_')] = v except UnboundLocalError: # ansible-2.2 - self.system_facts = get_all_facts(module)['ansible_facts'] + self.system_facts = get_all_facts(module)['ansible_facts'] # noqa: F405 self.facts = self.generate_facts(local_facts, additive_facts_to_overwrite, @@ -1799,7 +1855,6 @@ class OpenShiftFacts(object): protected_facts_to_overwrite) roles = local_facts.keys() - if 'common' in local_facts and 'deployment_type' in local_facts['common']: deployment_type = local_facts['common']['deployment_type'] else: @@ -1854,7 +1909,7 @@ class OpenShiftFacts(object): """ defaults = {} ip_addr = self.system_facts['ansible_default_ipv4']['address'] - exit_code, output, _ = module.run_command(['hostname', '-f']) + exit_code, output, _ = module.run_command(['hostname', '-f']) # noqa: F405 hostname_f = output.strip() if exit_code == 0 else '' hostname_values = [hostname_f, self.system_facts['ansible_nodename'], self.system_facts['ansible_fqdn']] @@ -1873,22 +1928,6 @@ class OpenShiftFacts(object): debug_level=2) if 'master' in roles: - scheduler_predicates = [ - {"name": "MatchNodeSelector"}, - {"name": "PodFitsResources"}, - {"name": "PodFitsPorts"}, - {"name": "NoDiskConflict"}, - {"name": "NoVolumeZoneConflict"}, - {"name": "MaxEBSVolumeCount"}, - {"name": "MaxGCEPDVolumeCount"}, - {"name": "Region", "argument": {"serviceAffinity" : {"labels" : ["region"]}}} - ] - scheduler_priorities = [ - {"name": "LeastRequestedPriority", "weight": 1}, - {"name": "SelectorSpreadPriority", "weight": 1}, - {"name": "Zone", "weight" : 2, "argument": {"serviceAntiAffinity" : {"label": "zone"}}} - ] - defaults['master'] = dict(api_use_ssl=True, api_port='8443', controllers_port='8444', console_use_ssl=True, @@ -1905,8 +1944,6 @@ class OpenShiftFacts(object): access_token_max_seconds=86400, auth_token_max_seconds=500, oauth_grant_method='auto', - scheduler_predicates=scheduler_predicates, - scheduler_priorities=scheduler_priorities, dynamic_provisioning_enabled=True, max_requests_inflight=500) @@ -1930,7 +1967,7 @@ class OpenShiftFacts(object): defaults['docker'] = docker if 'clock' in roles: - exit_code, _, _ = module.run_command(['rpm', '-q', 'chrony']) + exit_code, _, _ = module.run_command(['rpm', '-q', 'chrony']) # noqa: F405 chrony_installed = bool(exit_code == 0) defaults['clock'] = dict( enabled=True, @@ -2015,7 +2052,7 @@ class OpenShiftFacts(object): # TODO: this is not exposed through module_utils/facts.py in ansible, # need to create PR for ansible to expose it - bios_vendor = get_file_content( + bios_vendor = get_file_content( # noqa: F405 '/sys/devices/virtual/dmi/id/bios_vendor' ) if bios_vendor == 'Google': @@ -2030,8 +2067,7 @@ class OpenShiftFacts(object): if metadata: metadata['project']['attributes'].pop('sshKeys', None) metadata['instance'].pop('serviceAccounts', None) - elif (virt_type == 'xen' and virt_role == 'guest' - and re.match(r'.*\.amazon$', product_version)): + elif virt_type == 'xen' and virt_role == 'guest' and re.match(r'.*\.amazon$', product_version): provider = 'aws' metadata_url = 'http://169.254.169.254/latest/meta-data/' metadata = get_provider_metadata(metadata_url) @@ -2092,7 +2128,7 @@ class OpenShiftFacts(object): # Determine if any of the provided variable structures match the fact. matching_structure = None - if openshift_env_structures != None: + if openshift_env_structures is not None: for structure in openshift_env_structures: if re.match(structure, openshift_env_fact): matching_structure = structure @@ -2116,7 +2152,7 @@ class OpenShiftFacts(object): # Disabling too-many-branches and too-many-locals. # This should be cleaned up as a TODO item. - #pylint: disable=too-many-branches, too-many-locals + # pylint: disable=too-many-branches, too-many-locals def init_local_facts(self, facts=None, additive_facts_to_overwrite=None, openshift_env=None, @@ -2144,7 +2180,7 @@ class OpenShiftFacts(object): if facts is not None: facts_to_set[self.role] = facts - if openshift_env != {} and openshift_env != None: + if openshift_env != {} and openshift_env is not None: for fact, value in iteritems(openshift_env): oo_env_facts = dict() current_level = oo_env_facts @@ -2173,7 +2209,7 @@ class OpenShiftFacts(object): if 'docker' in new_local_facts: # remove duplicate and empty strings from registry lists - for cat in ['additional', 'blocked', 'insecure']: + for cat in ['additional', 'blocked', 'insecure']: key = '{0}_registries'.format(cat) if key in new_local_facts['docker']: val = new_local_facts['docker'][key] @@ -2190,7 +2226,7 @@ class OpenShiftFacts(object): if new_local_facts != local_facts: self.validate_local_facts(new_local_facts) changed = True - if not module.check_mode: + if not module.check_mode: # noqa: F405 save_local_facts(self.filename, new_local_facts) self.changed = changed @@ -2223,10 +2259,10 @@ class OpenShiftFacts(object): invalid_facts = self.validate_master_facts(facts, invalid_facts) if invalid_facts: msg = 'Invalid facts detected:\n' + # pylint: disable=consider-iterating-dictionary for key in invalid_facts.keys(): msg += '{0}: {1}\n'.format(key, invalid_facts[key]) - module.fail_json(msg=msg, - changed=self.changed) + module.fail_json(msg=msg, changed=self.changed) # noqa: F405 # disabling pylint errors for line-too-long since we're dealing # with best effort reduction of error messages here. @@ -2278,13 +2314,14 @@ class OpenShiftFacts(object): 'Secrets must be 16, 24, or 32 characters in length.') return invalid_facts + def main(): """ main """ # disabling pylint errors for global-variable-undefined and invalid-name # for 'global module' usage, since it is required to use ansible_facts # pylint: disable=global-variable-undefined, invalid-name global module - module = AnsibleModule( + module = AnsibleModule( # noqa: F405 argument_spec=dict( role=dict(default='common', required=False, choices=OpenShiftFacts.known_roles), @@ -2299,18 +2336,18 @@ def main(): ) if not HAVE_DBUS: - module.fail_json(msg="This module requires dbus python bindings") + module.fail_json(msg="This module requires dbus python bindings") # noqa: F405 - module.params['gather_subset'] = ['hardware', 'network', 'virtual', 'facter'] - module.params['gather_timeout'] = 10 - module.params['filter'] = '*' + module.params['gather_subset'] = ['hardware', 'network', 'virtual', 'facter'] # noqa: F405 + module.params['gather_timeout'] = 10 # noqa: F405 + module.params['filter'] = '*' # noqa: F405 - role = module.params['role'] - local_facts = module.params['local_facts'] - additive_facts_to_overwrite = module.params['additive_facts_to_overwrite'] - openshift_env = module.params['openshift_env'] - openshift_env_structures = module.params['openshift_env_structures'] - protected_facts_to_overwrite = module.params['protected_facts_to_overwrite'] + role = module.params['role'] # noqa: F405 + local_facts = module.params['local_facts'] # noqa: F405 + additive_facts_to_overwrite = module.params['additive_facts_to_overwrite'] # noqa: F405 + openshift_env = module.params['openshift_env'] # noqa: F405 + openshift_env_structures = module.params['openshift_env_structures'] # noqa: F405 + protected_facts_to_overwrite = module.params['protected_facts_to_overwrite'] # noqa: F405 fact_file = '/etc/ansible/facts.d/openshift.fact' @@ -2322,24 +2359,15 @@ def main(): openshift_env_structures, protected_facts_to_overwrite) - file_params = module.params.copy() + file_params = module.params.copy() # noqa: F405 file_params['path'] = fact_file - file_args = module.load_file_common_arguments(file_params) - changed = module.set_fs_attributes_if_different(file_args, + file_args = module.load_file_common_arguments(file_params) # noqa: F405 + changed = module.set_fs_attributes_if_different(file_args, # noqa: F405 openshift_facts.changed) - return module.exit_json(changed=changed, + return module.exit_json(changed=changed, # noqa: F405 ansible_facts=openshift_facts.facts) -# ignore pylint errors related to the module_utils import -# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import -# import module snippets -from ansible.module_utils.basic import * -from ansible.module_utils.facts import * -from ansible.module_utils.urls import * -from ansible.module_utils.six import iteritems, itervalues -from ansible.module_utils._text import to_native -from ansible.module_utils.six import b if __name__ == '__main__': main() diff --git a/roles/openshift_master/vars/main.yml b/roles/openshift_master/vars/main.yml index 7c1d5a212..4dce63630 100644 --- a/roles/openshift_master/vars/main.yml +++ b/roles/openshift_master/vars/main.yml @@ -1,17 +1,14 @@ --- -openshift_master_config_dir: "{{ openshift.common.config_base }}/master" -openshift_master_config_file: "{{ openshift_master_config_dir }}/master-config.yaml" openshift_master_loopback_config: "{{ openshift_master_config_dir }}/openshift-master.kubeconfig" loopback_context_string: "current-context: {{ openshift.master.loopback_context_name }}" -openshift_master_scheduler_conf: "{{ openshift_master_config_dir }}/scheduler.json" openshift_master_session_secrets_file: "{{ openshift_master_config_dir }}/session-secrets.yaml" openshift_master_policy: "{{ openshift_master_config_dir }}/policy.json" scheduler_config: kind: Policy apiVersion: v1 - predicates: "{{ openshift.master.scheduler_predicates }}" - priorities: "{{ openshift.master.scheduler_priorities }}" + predicates: "{{ openshift_master_scheduler_predicates }}" + priorities: "{{ openshift_master_scheduler_priorities }}" openshift_master_valid_grant_methods: - auto diff --git a/roles/openshift_master_facts/lookup_plugins/openshift_master_facts_default_predicates.py b/roles/openshift_master_facts/lookup_plugins/openshift_master_facts_default_predicates.py new file mode 100644 index 000000000..05b62a7a6 --- /dev/null +++ b/roles/openshift_master_facts/lookup_plugins/openshift_master_facts_default_predicates.py @@ -0,0 +1,96 @@ +# pylint: disable=missing-docstring + +import re +from ansible.errors import AnsibleError +from ansible.plugins.lookup import LookupBase + + +class LookupModule(LookupBase): + # pylint: disable=too-many-branches,too-many-statements + + def run(self, terms, variables=None, regions_enabled=True, **kwargs): + if 'openshift' not in variables: + raise AnsibleError("This lookup module requires openshift_facts to be run prior to use") + if 'master' not in variables['openshift']: + raise AnsibleError("This lookup module is meant to be run against an OpenShift master host only") + + if 'openshift_master_scheduler_predicates' in variables: + return variables['openshift_master_scheduler_predicates'] + elif 'scheduler_predicates' in variables['openshift']['master']: + return variables['openshift']['master']['scheduler_predicates'] + else: + predicates = [] + + if 'deployment_type' not in variables['openshift']['common']: + raise AnsibleError("This lookup module requires that the deployment_type be set") + + deployment_type = variables['openshift']['common']['deployment_type'] + + if 'short_version' in variables['openshift']['common']: + short_version = variables['openshift']['common']['short_version'] + elif 'openshift_release' in variables: + release = variables['openshift_release'] + if release.startswith('v'): + short_version = release[1:] + else: + short_version = release + elif 'openshift_version' in variables: + version = variables['openshift_version'] + short_version = '.'.join(version.split('.')[0:2]) + else: + # pylint: disable=line-too-long + raise AnsibleError("Either OpenShift needs to be installed or openshift_release needs to be specified") + if deployment_type not in ['origin', 'openshift-enterprise']: + raise AnsibleError("Unknown deployment_type %s" % deployment_type) + + if deployment_type == 'origin': + if short_version not in ['1.1', '1.2', '1.3', '1.4']: + raise AnsibleError("Unknown short_version %s" % short_version) + elif deployment_type == 'openshift_enterprise': + if short_version not in ['3.1', '3.2', '3.3', '3.4']: + raise AnsibleError("Unknown short_version %s" % short_version) + + if deployment_type == 'openshift-enterprise': + # convert short_version to origin short_version + short_version = re.sub('^3.', '1.', short_version) + + if short_version in ['1.1', '1.2']: + predicates.append({'name': 'PodFitsHostPorts'}) + predicates.append({'name': 'PodFitsResources'}) + + # applies to all known versions + predicates.append({'name': 'NoDiskConflict'}) + + # only 1.1 didn't include NoVolumeZoneConflict + if short_version != '1.1': + predicates.append({'name': 'NoVolumeZoneConflict'}) + + if short_version in ['1.1', '1.2']: + predicates.append({'name': 'MatchNodeSelector'}) + predicates.append({'name': 'Hostname'}) + + if short_version != '1.1': + predicates.append({'name': 'MaxEBSVolumeCount'}) + predicates.append({'name': 'MaxGCEPDVolumeCount'}) + + if short_version not in ['1.1', '1.2']: + predicates.append({'name': 'GeneralPredicates'}) + predicates.append({'name': 'PodToleratesNodeTaints'}) + predicates.append({'name': 'CheckNodeMemoryPressure'}) + + if short_version not in ['1.1', '1.2', '1.3']: + predicates.append({'name': 'CheckNodeDiskPressure'}) + predicates.append({'name': 'MatchInterPodAffinity'}) + + if regions_enabled: + region_predicate = { + 'name': 'Region', + 'argument': { + 'serviceAffinity': { + 'labels': ['region'] + } + } + } + predicates.append(region_predicate) + + return predicates diff --git a/roles/openshift_master_facts/lookup_plugins/openshift_master_facts_default_priorities.py b/roles/openshift_master_facts/lookup_plugins/openshift_master_facts_default_priorities.py new file mode 100644 index 000000000..3329d26b0 --- /dev/null +++ b/roles/openshift_master_facts/lookup_plugins/openshift_master_facts_default_priorities.py @@ -0,0 +1,87 @@ +# pylint: disable=missing-docstring + +import re +from ansible.errors import AnsibleError +from ansible.plugins.lookup import LookupBase + + +class LookupModule(LookupBase): + # pylint: disable=too-many-branches + + def run(self, terms, variables=None, zones_enabled=True, **kwargs): + if 'openshift' not in variables: + raise AnsibleError("This lookup module requires openshift_facts to be run prior to use") + if 'master' not in variables['openshift']: + raise AnsibleError("This lookup module is meant to be run against an OpenShift master host only") + + if 'openshift_master_scheduler_priorities' in variables: + return variables['openshift_master_scheduler_priorities'] + elif 'scheduler_priorities' in variables['openshift']['master']: + return variables['openshift']['master']['scheduler_priorities'] + else: + priorities = [ + {'name': 'LeastRequestedPriority', 'weight': 1}, + {'name': 'BalancedResourceAllocation', 'weight': 1}, + {'name': 'SelectorSpreadPriority', 'weight': 1} + ] + + if 'deployment_type' not in variables['openshift']['common']: + raise AnsibleError("This lookup module requires that the deployment_type be set") + + deployment_type = variables['openshift']['common']['deployment_type'] + + if 'short_version' in variables['openshift']['common']: + short_version = variables['openshift']['common']['short_version'] + elif 'openshift_release' in variables: + release = variables['openshift_release'] + if release.startswith('v'): + short_version = release[1:] + else: + short_version = release + elif 'openshift_version' in variables: + version = variables['openshift_version'] + short_version = '.'.join(version.split('.')[0:2]) + else: + # pylint: disable=line-too-long + raise AnsibleError("Either OpenShift needs to be installed or openshift_release needs to be specified") + + if deployment_type not in ['origin', 'openshift-enterprise']: + raise AnsibleError("Unknown deployment_type %s" % deployment_type) + + if deployment_type == 'origin': + if short_version not in ['1.1', '1.2', '1.3', '1.4']: + raise AnsibleError("Unknown short_version %s" % short_version) + elif deployment_type == 'openshift_enterprise': + if short_version not in ['3.1', '3.2', '3.3', '3.4']: + raise AnsibleError("Unknown short_version %s" % short_version) + + if deployment_type == 'openshift-enterprise': + # convert short_version to origin short_version + short_version = re.sub('^3.', '1.', short_version) + + if short_version == '1.4': + priorities.append({'name': 'NodePreferAvoidPodsPriority', 'weight': 10000}) + + # only 1.1 didn't include NodeAffinityPriority + if short_version != '1.1': + priorities.append({'name': 'NodeAffinityPriority', 'weight': 1}) + + if short_version not in ['1.1', '1.2']: + priorities.append({'name': 'TaintTolerationPriority', 'weight': 1}) + + if short_version not in ['1.1', '1.2', '1.3']: + priorities.append({'name': 'InterPodAffinityPriority', 'weight': 1}) + + if zones_enabled: + zone_priority = { + 'name': 'Zone', + 'argument': { + 'serviceAntiAffinity': { + 'label': 'zone' + } + }, + 'weight': 2 + } + priorities.append(zone_priority) + + return priorities diff --git a/roles/openshift_master_facts/tasks/main.yml b/roles/openshift_master_facts/tasks/main.yml index 1f27a2c1d..170861484 100644 --- a/roles/openshift_master_facts/tasks/main.yml +++ b/roles/openshift_master_facts/tasks/main.yml @@ -64,8 +64,6 @@ master_count: "{{ openshift_master_count | default(None) }}" controller_lease_ttl: "{{ osm_controller_lease_ttl | default(None) }}" master_image: "{{ osm_image | default(None) }}" - scheduler_predicates: "{{ openshift_master_scheduler_predicates | default(None) }}" - scheduler_priorities: "{{ openshift_master_scheduler_priorities | default(None) }}" admission_plugin_config: "{{openshift_master_admission_plugin_config | default(None) }}" kube_admission_plugin_config: "{{openshift_master_kube_admission_plugin_config | default(None) }}" # deprecated, merged with admission_plugin_config oauth_template: "{{ openshift_master_oauth_template | default(None) }}" # deprecated in origin 1.2 / OSE 3.2 @@ -79,3 +77,38 @@ audit_config: "{{ openshift_master_audit_config | default(None) }}" metrics_public_url: "{% if openshift_hosted_metrics_deploy | default(false) %}https://{{ metrics_hostname }}/hawkular/metrics{% endif %}" scheduler_args: "{{ openshift_master_scheduler_args | default(None) }}" + +- name: Determine if scheduler config present + stat: + path: "{{ openshift_master_scheduler_conf }}" + register: scheduler_config_stat + +- block: + - set_fact: + openshift_master_scheduler_predicates: "{{ lookup('openshift_master_facts_default_predicates') }}" + when: "{{ openshift_master_scheduler_predicates is not defined }}" + + - set_fact: + openshift_master_scheduler_priorities: "{{ lookup('openshift_master_facts_default_priorities') }}" + when: "{{ openshift_master_scheduler_priorities is not defined }}" + when: "{{ not scheduler_config_stat.stat.exists }}" + +- block: + - name: Retrieve current scheduler config + slurp: + src: "{{ openshift_master_scheduler_conf }}" + register: current_scheduler_config + + - fail: + msg: "Could not decode scheduler config" + when: "{{ (current_scheduler_config.content | b64decode | from_json).apiVersion | default(none) != 'v1' }}" + + - set_fact: + openshift_master_scheduler_predicates: "{{ (current_scheduler_config.content | b64decode | from_json).predicates }}" + when: "{{ openshift_master_scheduler_predicates is not defined }}" + + - set_fact: + openshift_master_scheduler_priorities: "{{ (current_scheduler_config.content | b64decode | from_json).priorities }}" + when: "{{ openshift_master_scheduler_priorities is not defined }}" + + when: "{{ scheduler_config_stat.stat.exists }}" diff --git a/roles/openshift_master_facts/test/openshift_master_facts_default_predicates_tests.py b/roles/openshift_master_facts/test/openshift_master_facts_default_predicates_tests.py new file mode 100644 index 000000000..6f2a916d0 --- /dev/null +++ b/roles/openshift_master_facts/test/openshift_master_facts_default_predicates_tests.py @@ -0,0 +1,174 @@ +import copy +import os +import sys + +from ansible.errors import AnsibleError +from nose.tools import raises, assert_equal + +sys.path = [os.path.abspath(os.path.dirname(__file__) + "/../lookup_plugins/")] + sys.path + +from openshift_master_facts_default_predicates import LookupModule # noqa: E402 + +DEFAULT_PREDICATES_1_1 = [ + {'name': 'PodFitsHostPorts'}, + {'name': 'PodFitsResources'}, + {'name': 'NoDiskConflict'}, + {'name': 'MatchNodeSelector'}, + {'name': 'Hostname'} +] + +DEFAULT_PREDICATES_1_2 = [ + {'name': 'PodFitsHostPorts'}, + {'name': 'PodFitsResources'}, + {'name': 'NoDiskConflict'}, + {'name': 'NoVolumeZoneConflict'}, + {'name': 'MatchNodeSelector'}, + {'name': 'Hostname'}, + {'name': 'MaxEBSVolumeCount'}, + {'name': 'MaxGCEPDVolumeCount'} +] + +DEFAULT_PREDICATES_1_3 = [ + {'name': 'NoDiskConflict'}, + {'name': 'NoVolumeZoneConflict'}, + {'name': 'MaxEBSVolumeCount'}, + {'name': 'MaxGCEPDVolumeCount'}, + {'name': 'GeneralPredicates'}, + {'name': 'PodToleratesNodeTaints'}, + {'name': 'CheckNodeMemoryPressure'} +] + +DEFAULT_PREDICATES_1_4 = [ + {'name': 'NoDiskConflict'}, + {'name': 'NoVolumeZoneConflict'}, + {'name': 'MaxEBSVolumeCount'}, + {'name': 'MaxGCEPDVolumeCount'}, + {'name': 'GeneralPredicates'}, + {'name': 'PodToleratesNodeTaints'}, + {'name': 'CheckNodeMemoryPressure'}, + {'name': 'CheckNodeDiskPressure'}, + {'name': 'MatchInterPodAffinity'} +] + +REGION_PREDICATE = { + 'name': 'Region', + 'argument': { + 'serviceAffinity': { + 'labels': ['region'] + } + } +} + + +class TestOpenShiftMasterFactsDefaultPredicates(object): + def setUp(self): + self.lookup = LookupModule() + self.default_facts = { + 'openshift': { + 'master': {}, + 'common': {} + } + } + + @raises(AnsibleError) + def test_missing_short_version_and_missing_openshift_release(self): + facts = copy.deepcopy(self.default_facts) + facts['openshift']['common']['deployment_type'] = 'origin' + self.lookup.run(None, variables=facts) + + def check_defaults(self, release, deployment_type, default_predicates, + regions_enabled, short_version): + facts = copy.deepcopy(self.default_facts) + if short_version: + facts['openshift']['common']['short_version'] = release + else: + facts['openshift_release'] = release + facts['openshift']['common']['deployment_type'] = deployment_type + results = self.lookup.run(None, variables=facts, + regions_enabled=regions_enabled) + if regions_enabled: + assert_equal(results, default_predicates + [REGION_PREDICATE]) + else: + assert_equal(results, default_predicates) + + def test_openshift_release_defaults(self): + test_vars = [ + ('1.1', 'origin', DEFAULT_PREDICATES_1_1), + ('3.1', 'openshift-enterprise', DEFAULT_PREDICATES_1_1), + ('1.2', 'origin', DEFAULT_PREDICATES_1_2), + ('3.2', 'openshift-enterprise', DEFAULT_PREDICATES_1_2), + ('1.3', 'origin', DEFAULT_PREDICATES_1_3), + ('3.3', 'openshift-enterprise', DEFAULT_PREDICATES_1_3), + ('1.4', 'origin', DEFAULT_PREDICATES_1_4), + ('3.4', 'openshift-enterprise', DEFAULT_PREDICATES_1_4) + ] + + for regions_enabled in (True, False): + for release, deployment_type, default_predicates in test_vars: + for prepend_v in (True, False): + if prepend_v: + release = 'v' + release + yield self.check_defaults, release, deployment_type, default_predicates, regions_enabled, False + + def test_short_version_defaults(self): + test_vars = [ + ('1.1', 'origin', DEFAULT_PREDICATES_1_1), + ('3.1', 'openshift-enterprise', DEFAULT_PREDICATES_1_1), + ('1.2', 'origin', DEFAULT_PREDICATES_1_2), + ('3.2', 'openshift-enterprise', DEFAULT_PREDICATES_1_2), + ('1.3', 'origin', DEFAULT_PREDICATES_1_3), + ('3.3', 'openshift-enterprise', DEFAULT_PREDICATES_1_3), + ('1.4', 'origin', DEFAULT_PREDICATES_1_4), + ('3.4', 'openshift-enterprise', DEFAULT_PREDICATES_1_4) + ] + for regions_enabled in (True, False): + for short_version, deployment_type, default_predicates in test_vars: + yield self.check_defaults, short_version, deployment_type, default_predicates, regions_enabled, True + + @raises(AnsibleError) + def test_unknown_deployment_types(self): + facts = copy.deepcopy(self.default_facts) + facts['openshift']['common']['short_version'] = '1.1' + facts['openshift']['common']['deployment_type'] = 'bogus' + self.lookup.run(None, variables=facts) + + @raises(AnsibleError) + def test_missing_deployment_type(self): + facts = copy.deepcopy(self.default_facts) + facts['openshift']['common']['short_version'] = '10.10' + self.lookup.run(None, variables=facts) + + @raises(AnsibleError) + def testMissingOpenShiftFacts(self): + facts = {} + self.lookup.run(None, variables=facts) + + @raises(AnsibleError) + def testMissingMasterRole(self): + facts = {'openshift': {}} + self.lookup.run(None, variables=facts) + + def testPreExistingPredicates(self): + facts = { + 'openshift': { + 'master': { + 'scheduler_predicates': [ + {'name': 'pred_a'}, + {'name': 'pred_b'} + ] + } + } + } + result = self.lookup.run(None, variables=facts) + assert_equal(result, facts['openshift']['master']['scheduler_predicates']) + + def testDefinedPredicates(self): + facts = { + 'openshift': {'master': {}}, + 'openshift_master_scheduler_predicates': [ + {'name': 'pred_a'}, + {'name': 'pred_b'} + ] + } + result = self.lookup.run(None, variables=facts) + assert_equal(result, facts['openshift_master_scheduler_predicates']) diff --git a/roles/openshift_master_facts/test/openshift_master_facts_default_priorities_tests.py b/roles/openshift_master_facts/test/openshift_master_facts_default_priorities_tests.py new file mode 100644 index 000000000..d63f06904 --- /dev/null +++ b/roles/openshift_master_facts/test/openshift_master_facts_default_priorities_tests.py @@ -0,0 +1,164 @@ +import copy +import os +import sys + +from ansible.errors import AnsibleError +from nose.tools import raises, assert_equal + +sys.path = [os.path.abspath(os.path.dirname(__file__) + "/../lookup_plugins/")] + sys.path + +from openshift_master_facts_default_priorities import LookupModule # noqa: E402 + +DEFAULT_PRIORITIES_1_1 = [ + {'name': 'LeastRequestedPriority', 'weight': 1}, + {'name': 'BalancedResourceAllocation', 'weight': 1}, + {'name': 'SelectorSpreadPriority', 'weight': 1} +] + +DEFAULT_PRIORITIES_1_2 = [ + {'name': 'LeastRequestedPriority', 'weight': 1}, + {'name': 'BalancedResourceAllocation', 'weight': 1}, + {'name': 'SelectorSpreadPriority', 'weight': 1}, + {'name': 'NodeAffinityPriority', 'weight': 1} +] + +DEFAULT_PRIORITIES_1_3 = [ + {'name': 'LeastRequestedPriority', 'weight': 1}, + {'name': 'BalancedResourceAllocation', 'weight': 1}, + {'name': 'SelectorSpreadPriority', 'weight': 1}, + {'name': 'NodeAffinityPriority', 'weight': 1}, + {'name': 'TaintTolerationPriority', 'weight': 1} +] + +DEFAULT_PRIORITIES_1_4 = [ + {'name': 'LeastRequestedPriority', 'weight': 1}, + {'name': 'BalancedResourceAllocation', 'weight': 1}, + {'name': 'SelectorSpreadPriority', 'weight': 1}, + {'name': 'NodePreferAvoidPodsPriority', 'weight': 10000}, + {'name': 'NodeAffinityPriority', 'weight': 1}, + {'name': 'TaintTolerationPriority', 'weight': 1}, + {'name': 'InterPodAffinityPriority', 'weight': 1} +] + +ZONE_PRIORITY = { + 'name': 'Zone', + 'argument': { + 'serviceAntiAffinity': { + 'label': 'zone' + } + }, + 'weight': 2 +} + + +class TestOpenShiftMasterFactsDefaultPredicates(object): + def setUp(self): + self.lookup = LookupModule() + self.default_facts = { + 'openshift': { + 'master': {}, + 'common': {} + } + } + + @raises(AnsibleError) + def test_missing_short_version_and_missing_openshift_release(self): + facts = copy.deepcopy(self.default_facts) + facts['openshift']['common']['deployment_type'] = 'origin' + self.lookup.run(None, variables=facts) + + def check_defaults(self, release, deployment_type, default_priorities, + zones_enabled, short_version): + facts = copy.deepcopy(self.default_facts) + if short_version: + facts['openshift']['common']['short_version'] = release + else: + facts['openshift_release'] = release + facts['openshift']['common']['deployment_type'] = deployment_type + results = self.lookup.run(None, variables=facts, zones_enabled=zones_enabled) + if zones_enabled: + assert_equal(results, default_priorities + [ZONE_PRIORITY]) + else: + assert_equal(results, default_priorities) + + def test_openshift_release_defaults(self): + test_vars = [ + ('1.1', 'origin', DEFAULT_PRIORITIES_1_1), + ('3.1', 'openshift-enterprise', DEFAULT_PRIORITIES_1_1), + ('1.2', 'origin', DEFAULT_PRIORITIES_1_2), + ('3.2', 'openshift-enterprise', DEFAULT_PRIORITIES_1_2), + ('1.3', 'origin', DEFAULT_PRIORITIES_1_3), + ('3.3', 'openshift-enterprise', DEFAULT_PRIORITIES_1_3), + ('1.4', 'origin', DEFAULT_PRIORITIES_1_4), + ('3.4', 'openshift-enterprise', DEFAULT_PRIORITIES_1_4) + ] + + for zones_enabled in (True, False): + for release, deployment_type, default_priorities in test_vars: + for prepend_v in (True, False): + if prepend_v: + release = 'v' + release + yield self.check_defaults, release, deployment_type, default_priorities, zones_enabled, False + + def test_short_version_defaults(self): + test_vars = [ + ('1.1', 'origin', DEFAULT_PRIORITIES_1_1), + ('3.1', 'openshift-enterprise', DEFAULT_PRIORITIES_1_1), + ('1.2', 'origin', DEFAULT_PRIORITIES_1_2), + ('3.2', 'openshift-enterprise', DEFAULT_PRIORITIES_1_2), + ('1.3', 'origin', DEFAULT_PRIORITIES_1_3), + ('3.3', 'openshift-enterprise', DEFAULT_PRIORITIES_1_3), + ('1.4', 'origin', DEFAULT_PRIORITIES_1_4), + ('3.4', 'openshift-enterprise', DEFAULT_PRIORITIES_1_4) + ] + for zones_enabled in (True, False): + for short_version, deployment_type, default_priorities in test_vars: + yield self.check_defaults, short_version, deployment_type, default_priorities, zones_enabled, True + + @raises(AnsibleError) + def test_unknown_deployment_types(self): + facts = copy.deepcopy(self.default_facts) + facts['openshift']['common']['short_version'] = '1.1' + facts['openshift']['common']['deployment_type'] = 'bogus' + self.lookup.run(None, variables=facts) + + @raises(AnsibleError) + def test_missing_deployment_type(self): + facts = copy.deepcopy(self.default_facts) + facts['openshift']['common']['short_version'] = '10.10' + self.lookup.run(None, variables=facts) + + @raises(AnsibleError) + def test_missing_openshift_facts(self): + facts = {} + self.lookup.run(None, variables=facts) + + @raises(AnsibleError) + def test_missing_master_role(self): + facts = {'openshift': {}} + self.lookup.run(None, variables=facts) + + def test_pre_existing_priorities(self): + facts = { + 'openshift': { + 'master': { + 'scheduler_priorities': [ + {'name': 'pri_a', 'weight': 1}, + {'name': 'pri_b', 'weight': 1} + ] + } + } + } + result = self.lookup.run(None, variables=facts) + assert_equal(result, facts['openshift']['master']['scheduler_priorities']) + + def testDefinedPredicates(self): + facts = { + 'openshift': {'master': {}}, + 'openshift_master_scheduler_priorities': [ + {'name': 'pri_a', 'weight': 1}, + {'name': 'pri_b', 'weight': 1} + ] + } + result = self.lookup.run(None, variables=facts) + assert_equal(result, facts['openshift_master_scheduler_priorities']) diff --git a/roles/openshift_master_facts/vars/main.yml b/roles/openshift_master_facts/vars/main.yml index 406d50c24..3f328dcfe 100644 --- a/roles/openshift_master_facts/vars/main.yml +++ b/roles/openshift_master_facts/vars/main.yml @@ -1,3 +1,8 @@ +--- +openshift_master_config_dir: "{{ openshift.common.config_base }}/master" +openshift_master_config_file: "{{ openshift_master_config_dir }}/master-config.yaml" +openshift_master_scheduler_conf: "{{ openshift_master_config_dir }}/scheduler.json" + builddefaults_yaml: BuildDefaults: configuration: diff --git a/roles/os_firewall/library/os_firewall_manage_iptables.py b/roles/os_firewall/library/os_firewall_manage_iptables.py index 37bb16f35..b60e52dfe 100755 --- a/roles/os_firewall/library/os_firewall_manage_iptables.py +++ b/roles/os_firewall/library/os_firewall_manage_iptables.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # vim: expandtab:tabstop=4:shiftwidth=4 # pylint: disable=fixme, missing-docstring -from subprocess import call, check_output +import subprocess DOCUMENTATION = ''' --- @@ -29,7 +29,10 @@ class IpTablesAddRuleError(IpTablesError): class IpTablesRemoveRuleError(IpTablesError): - pass + def __init__(self, chain, msg, cmd, exit_code, output): # pylint: disable=too-many-arguments, line-too-long, redefined-outer-name + super(IpTablesRemoveRuleError, self).__init__(msg, cmd, exit_code, + output) + self.chain = chain class IpTablesSaveError(IpTablesError): @@ -37,14 +40,14 @@ class IpTablesSaveError(IpTablesError): class IpTablesCreateChainError(IpTablesError): - def __init__(self, chain, msg, cmd, exit_code, output): # pylint: disable=too-many-arguments, line-too-long, redefined-outer-name + def __init__(self, chain, msg, cmd, exit_code, output): # pylint: disable=too-many-arguments, line-too-long, redefined-outer-name super(IpTablesCreateChainError, self).__init__(msg, cmd, exit_code, output) self.chain = chain class IpTablesCreateJumpRuleError(IpTablesError): - def __init__(self, chain, msg, cmd, exit_code, output): # pylint: disable=too-many-arguments, line-too-long, redefined-outer-name + def __init__(self, chain, msg, cmd, exit_code, output): # pylint: disable=too-many-arguments, line-too-long, redefined-outer-name super(IpTablesCreateJumpRuleError, self).__init__(msg, cmd, exit_code, output) self.chain = chain @@ -53,7 +56,7 @@ class IpTablesCreateJumpRuleError(IpTablesError): # TODO: implement rollbacks for any events that were successful and an # exception was thrown later. For example, when the chain is created # successfully, but the add/remove rule fails. -class IpTablesManager(object): # pylint: disable=too-many-instance-attributes +class IpTablesManager(object): # pylint: disable=too-many-instance-attributes def __init__(self, module): self.module = module self.ip_version = module.params['ip_version'] @@ -68,8 +71,7 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes def save(self): try: - self.output.append(check_output(self.save_cmd, - stderr=subprocess.STDOUT)) + self.output.append(subprocess.check_output(self.save_cmd, stderr=subprocess.STDOUT)) except subprocess.CalledProcessError as ex: raise IpTablesSaveError( msg="Failed to save iptables rules", @@ -92,7 +94,7 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes else: cmd = self.cmd + ['-A'] + rule try: - self.output.append(check_output(cmd)) + self.output.append(subprocess.check_output(cmd)) self.changed = True self.save() except subprocess.CalledProcessError as ex: @@ -112,7 +114,7 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes else: cmd = self.cmd + ['-D'] + rule try: - self.output.append(check_output(cmd)) + self.output.append(subprocess.check_output(cmd)) self.changed = True self.save() except subprocess.CalledProcessError as ex: @@ -123,7 +125,7 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes def rule_exists(self, rule): check_cmd = self.cmd + ['-C'] + rule - return True if call(check_cmd) == 0 else False + return True if subprocess.call(check_cmd) == 0 else False def gen_rule(self, port, proto): return [self.chain, '-p', proto, '-m', 'state', '--state', 'NEW', @@ -136,7 +138,7 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes else: try: cmd = self.cmd + ['-L', self.jump_rule_chain, '--line-numbers'] - output = check_output(cmd, stderr=subprocess.STDOUT) + output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) # break the input rules into rows and columns input_rules = [s.split() for s in to_native(output).split('\n')] @@ -155,8 +157,7 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes # Naively assume that if the last row is a REJECT or DROP rule, # then we can insert our rule right before it, otherwise we # assume that we can just append the rule. - if (last_rule_num and last_rule_target - and last_rule_target in ['REJECT', 'DROP']): + if (last_rule_num and last_rule_target and last_rule_target in ['REJECT', 'DROP']): # insert rule cmd = self.cmd + ['-I', self.jump_rule_chain, str(last_rule_num)] @@ -164,7 +165,7 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes # append rule cmd = self.cmd + ['-A', self.jump_rule_chain] cmd += ['-j', self.chain] - output = check_output(cmd, stderr=subprocess.STDOUT) + output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) self.changed = True self.output.append(output) self.save() @@ -192,8 +193,7 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes else: try: cmd = self.cmd + ['-N', self.chain] - self.output.append(check_output(cmd, - stderr=subprocess.STDOUT)) + self.output.append(subprocess.check_output(cmd, stderr=subprocess.STDOUT)) self.changed = True self.output.append("Successfully created chain %s" % self.chain) @@ -203,26 +203,26 @@ class IpTablesManager(object): # pylint: disable=too-many-instance-attributes chain=self.chain, msg="Failed to create chain: %s" % self.chain, cmd=ex.cmd, exit_code=ex.returncode, output=ex.output - ) + ) def jump_rule_exists(self): cmd = self.cmd + ['-C', self.jump_rule_chain, '-j', self.chain] - return True if call(cmd) == 0 else False + return True if subprocess.call(cmd) == 0 else False def chain_exists(self): cmd = self.cmd + ['-L', self.chain] - return True if call(cmd) == 0 else False + return True if subprocess.call(cmd) == 0 else False def gen_cmd(self): cmd = 'iptables' if self.ip_version == 'ipv4' else 'ip6tables' return ["/usr/sbin/%s" % cmd] - def gen_save_cmd(self): # pylint: disable=no-self-use + def gen_save_cmd(self): # pylint: disable=no-self-use return ['/usr/libexec/iptables/iptables.init', 'save'] def main(): - module = AnsibleModule( + module = AnsibleModule( # noqa: F405 argument_spec=dict( name=dict(required=True), action=dict(required=True, choices=['add', 'remove', @@ -266,9 +266,9 @@ def main(): output=iptables_manager.output) -# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import +# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, wrong-import-position # import module snippets -from ansible.module_utils.basic import * -from ansible.module_utils._text import to_native +from ansible.module_utils.basic import * # noqa: F403,E402 +from ansible.module_utils._text import to_native # noqa: E402 if __name__ == '__main__': main() diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index dd2913b35..000000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[nosetests] -tests=test,utils diff --git a/test/modify_yaml_tests.py b/test/modify_yaml_tests.py index 24cce4855..0dc25df82 100644 --- a/test/modify_yaml_tests.py +++ b/test/modify_yaml_tests.py @@ -8,7 +8,8 @@ import unittest sys.path = [os.path.abspath(os.path.dirname(__file__) + "/../library/")] + sys.path # pylint: disable=import-error -from modify_yaml import set_key +from modify_yaml import set_key # noqa: E402 + class ModifyYamlTests(unittest.TestCase): @@ -34,4 +35,3 @@ class ModifyYamlTests(unittest.TestCase): self.assertEquals(yaml_value, cfg['masterClients'] ['externalKubernetesClientConnectionOverrides'] ['acceptContentTypes']) - diff --git a/utils/Makefile b/utils/Makefile index 62f08f74b..ee6b885e6 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -31,8 +31,6 @@ ASCII2MAN = a2x -D $(dir $@) -d manpage -f manpage $< MANPAGES := docs/man/man1/atomic-openshift-installer.1 VERSION := 1.3 -PEPEXCLUDES := E501,E121,E124 - sdist: clean python setup.py sdist rm -fR $(SHORTNAME).egg-info @@ -66,7 +64,7 @@ virtualenv: @echo "# Creating a virtualenv" @echo "#############################################" virtualenv $(NAME)env - . $(NAME)env/bin/activate && pip install setuptools==17.1.1 + . $(NAME)env/bin/activate && pip install setuptools==17.1.1 . $(NAME)env/bin/activate && pip install -r test-requirements.txt # If there are any special things to install do it here # . $(NAME)env/bin/activate && INSTALL STUFF @@ -75,14 +73,14 @@ ci-unittests: @echo "#############################################" @echo "# Running Unit Tests in virtualenv" @echo "#############################################" - . $(NAME)env/bin/activate && nosetests -v --with-coverage --cover-html --cover-min-percentage=70 --cover-package=$(SHORTNAME) test/ + . $(NAME)env/bin/activate && python setup.py nosetests @echo "VIEW CODE COVERAGE REPORT WITH 'xdg-open cover/index.html' or run 'make viewcover'" ci-pylint: @echo "#############################################" @echo "# Running PyLint Tests in virtualenv" @echo "#############################################" - . $(NAME)env/bin/activate && python -m pylint --rcfile ../git/.pylintrc src/ooinstall/cli_installer.py src/ooinstall/oo_config.py src/ooinstall/openshift_ansible.py src/ooinstall/variants.py ../callback_plugins/openshift_quick_installer.py ../roles/openshift_certificate_expiry/library/openshift_cert_expiry.py + . $(NAME)env/bin/activate && python -m pylint --rcfile ../git/.pylintrc $(shell find ../ -name $(NAME)env -prune -o -name test -prune -o -name "*.py" -print) ci-list-deps: @echo "#############################################" @@ -90,23 +88,12 @@ ci-list-deps: @echo "#############################################" . $(NAME)env/bin/activate && pip freeze -ci-pyflakes: - @echo "#################################################" - @echo "# Running Pyflakes Compliance Tests in virtualenv" - @echo "#################################################" - . $(NAME)env/bin/activate && pyflakes src/ooinstall/*.py - . $(NAME)env/bin/activate && pyflakes ../callback_plugins/openshift_quick_installer.py - . $(NAME)env/bin/activate && pyflakes ../roles/openshift_certificate_expiry/library/openshift_cert_expiry.py - -ci-pep8: +ci-flake8: @echo "#############################################" - @echo "# Running PEP8 Compliance Tests in virtualenv" + @echo "# Running Flake8 Compliance Tests in virtualenv" @echo "#############################################" - . $(NAME)env/bin/activate && pep8 --ignore=$(PEPEXCLUDES) src/$(SHORTNAME)/ - . $(NAME)env/bin/activate && pep8 --ignore=$(PEPEXCLUDES) ../callback_plugins/openshift_quick_installer.py -# This one excludes E402 because it is an ansible module and the -# boilerplate import statement is expected to be at the bottom - . $(NAME)env/bin/activate && pep8 --ignore=$(PEPEXCLUDES),E402 ../roles/openshift_certificate_expiry/library/openshift_cert_expiry.py + . $(NAME)env/bin/activate && flake8 --config=setup.cfg ../ --exclude="utils,../inventory" + . $(NAME)env/bin/activate && python setup.py flake8 -ci: clean virtualenv ci-list-deps ci-pep8 ci-pylint ci-pyflakes ci-unittests +ci: clean virtualenv ci-list-deps ci-flake8 ci-pylint ci-unittests : diff --git a/utils/setup.cfg b/utils/setup.cfg index 79bc67848..f5f0d8aad 100644 --- a/utils/setup.cfg +++ b/utils/setup.cfg @@ -3,3 +3,16 @@ # 3. If at all possible, it is good practice to do this. If you cannot, you # will need to generate wheels for each Python version that you support. universal=1 + +[nosetests] +tests=../,../roles/openshift_master_facts/test/,test/ +verbosity=2 +with_coverage=1 +cover_html=1 +cover_package=ooinstall +cover_min_percentage=70 + +[flake8] +max-line-length=120 +exclude=tests/*,setup.py +ignore=E501,E121,E124 diff --git a/utils/setup.py b/utils/setup.py index 7909321c9..3518581e7 100644 --- a/utils/setup.py +++ b/utils/setup.py @@ -47,7 +47,7 @@ setup( # your project is installed. For an analysis of "install_requires" vs pip's # requirements files see: # https://packaging.python.org/en/latest/requirements.html - install_requires=['click', 'PyYAML'], + install_requires=['click', 'PyYAML', 'ansible'], # List additional groups of dependencies here (e.g. development # dependencies). You can install these using the following syntax, diff --git a/utils/src/ooinstall/utils.py b/utils/src/ooinstall/utils.py index 85a77c75e..c9e3e25e5 100644 --- a/utils/src/ooinstall/utils.py +++ b/utils/src/ooinstall/utils.py @@ -1,3 +1,5 @@ +# pylint: disable=missing-docstring,invalid-name + import logging import re @@ -8,6 +10,7 @@ installer_log = logging.getLogger('installer') def debug_env(env): for k in sorted(env.keys()): if k.startswith("OPENSHIFT") or k.startswith("ANSIBLE") or k.startswith("OO"): + # pylint: disable=logging-format-interpolation installer_log.debug("{key}: {value}".format( key=k, value=env[k])) diff --git a/utils/test-requirements.txt b/utils/test-requirements.txt index af91ab6a7..eeaf106ec 100644 --- a/utils/test-requirements.txt +++ b/utils/test-requirements.txt @@ -1,7 +1,7 @@ +ansible enum configparser pylint -pep8 nose coverage mock |