From 81628f94bad4b303212bf77752f62c03728e0168 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Tue, 17 Mar 2015 11:09:12 -0400 Subject: Fix hostname handling - always set hostname if hostname does not match openshift_hostname - Use local IP instead of public IP as hostname for workaround --- roles/openshift_common/README.md | 1 - roles/openshift_common/defaults/main.yml | 3 +-- roles/openshift_common/tasks/main.yml | 6 ++---- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/roles/openshift_common/README.md b/roles/openshift_common/README.md index c2ae609ff..79076ed19 100644 --- a/roles/openshift_common/README.md +++ b/roles/openshift_common/README.md @@ -14,7 +14,6 @@ Role Variables | Name | Default value | | |-------------------------------|------------------------------|----------------------------------------| -| openshift_bind_ip | ansible_default_ipv4.address | IP to use for local binding | | openshift_debug_level | 0 | Global openshift debug log verbosity | | openshift_hostname_workaround | True | Workaround needed to set hostname to IP address | | openshift_hostname | openshift_public_ip if openshift_hostname_workaround else ansible_fqdn | hostname to use for this instance | diff --git a/roles/openshift_common/defaults/main.yml b/roles/openshift_common/defaults/main.yml index a541591fb..eb6edbc03 100644 --- a/roles/openshift_common/defaults/main.yml +++ b/roles/openshift_common/defaults/main.yml @@ -1,8 +1,7 @@ --- -openshift_bind_ip: "{{ ansible_default_ipv4.address }}" openshift_debug_level: 0 # TODO: Once openshift stops resolving hostnames for node queries remove # this... openshift_hostname_workaround: true -openshift_hostname: "{{ openshift_public_ip if openshift_hostname_workaround else ansible_fqdn }}" +openshift_hostname: "{{ ansible_default_ipv4.address if openshift_hostname_workaround else ansible_fqdn }}" diff --git a/roles/openshift_common/tasks/main.yml b/roles/openshift_common/tasks/main.yml index 728bba4e4..07737a71f 100644 --- a/roles/openshift_common/tasks/main.yml +++ b/roles/openshift_common/tasks/main.yml @@ -1,8 +1,6 @@ --- -# fixme: Once openshift stops resolving hostnames for node queries remove this... -- name: Set hostname to IP Addr (WORKAROUND) - hostname: name={{ openshift_bind_ip }} - when: openshift_hostname_workaround +- name: Set hostname + hostname: name={{ openshift_hostname }} - name: Configure local facts file file: path=/etc/ansible/facts.d/ state=directory mode=0750 -- cgit v1.2.3 From 7035459d20dd2d278b0a0e6ff96421639f6e0e34 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Wed, 18 Mar 2015 00:05:51 -0400 Subject: Register node fixes - Set --hostname flag in node config in openshift_node role - Support some additional node attributes in openshift_node role - podCIDR - labels - annotations - Support both output types for openshift ex config view in openshift_register_node module - Support multiple api versions in openshift_register_node module - Support additional attributes in openshift_register_node module - annotations - labels - pod_cidr - external_ips (v1beta3, will be available after next kube rebase) - internal_ips (v1beta3, will be available after next kube rebase) - hostnames (v1beta3, will be available after next kube rebase) - external_id (v1beta3, will be available after next kube rebase) --- roles/openshift_node/defaults/main.yml | 8 +- .../library/openshift_register_node.py | 453 ++++++++++++++------- roles/openshift_node/tasks/main.yml | 14 +- 3 files changed, 333 insertions(+), 142 deletions(-) diff --git a/roles/openshift_node/defaults/main.yml b/roles/openshift_node/defaults/main.yml index c45524f16..e4d5ebfee 100644 --- a/roles/openshift_node/defaults/main.yml +++ b/roles/openshift_node/defaults/main.yml @@ -5,6 +5,8 @@ os_firewall_allow: - service: OpenShift kubelet port: 10250/tcp openshift_node_resources: - capacity: - cpu: - memory: + cpu: + memory: + cidr: +openshift_node_labels: {} +openshift_node_annotations: {} diff --git a/roles/openshift_node/library/openshift_register_node.py b/roles/openshift_node/library/openshift_register_node.py index 63079e59b..4922585d7 100644 --- a/roles/openshift_node/library/openshift_register_node.py +++ b/roles/openshift_node/library/openshift_register_node.py @@ -6,78 +6,315 @@ import os import multiprocessing import socket from subprocess import check_output, Popen +from decimal import * DOCUMENTATION = ''' --- -module: openshift_register_node -short_description: This module registers an openshift-node with an openshift-master -author: Jason DeTiberus -requirements: [ openshift-node ] -notes: Node resources can be specified using either the resources option or the following options: cpu, memory +module: kubernetes_register_node +short_description: Registers a kubernetes node with a master +description: + - Registers a kubernetes node with a master options: name: + default: null description: - - id for this node (usually the node fqdn) + - Identifier for this node (usually the node fqdn). required: true - hostIP: + api_verison: + choices: ['v1beta1', 'v1beta3'] + default: 'v1beta1' description: - - ip address for this node + - Kubernetes API version to use + required: true + host_ip: + default: null + description: + - IP Address to associate with the node when registering. + Available in the following API versions: v1beta1. required: false - cpu: + hostnames: + default: [] description: - - number of CPUs for this node + - Valid hostnames for this node. Available in the following API + versions: v1beta3. required: false - default: number of logical CPUs detected - memory: + external_ips: + default: [] description: - - Memory available for this node in bytes + - External IP Addresses for this node. Available in the following API + versions: v1beta3. required: false - default: 80% MemTotal - resources: + internal_ips: + default: [] description: - - A json string representing Node resources + - Internal IP Addresses for this node. Available in the following API + versions: v1beta3. + required: false + cpu: + default: null + description: + - Number of CPUs to allocate for this node. If not provided, then + the node will be registered to advertise the number of logical + CPUs available. When using the v1beta1 API, you must specify the + CPU count as a floating point number with no more than 3 decimal + places. API version v1beta3 and newer accepts arbitrary float + values. + required: false + memory: + default: null + description: + - Memory available for this node. If not provided, then the node + will be registered to advertise 80% of MemTotal as available + memory. When using the v1beta1 API, you must specify the memory + size in bytes. API version v1beta3 and newer accepts binary SI + and decimal SI values. required: false ''' EXAMPLES = ''' # Minimal node registration - openshift_register_node: name=ose3.node.example.com -# Node registration with all options (using cpu and memory options) +# Node registration using the v1beta1 API and assigning 1 CPU core and 10 GB of +# Memory - openshift_register_node: name: ose3.node.example.com + api_version: v1beta1 hostIP: 192.168.1.1 - apiVersion: v1beta1 cpu: 1 - memory: 1073741824 + memory: 500000000 -# Node registration with all options (using resources option) +# Node registration using the v1beta3 API, setting an alternate hostname, +# internalIP, externalIP and assigning 3.5 CPU cores and 1 TiB of Memory - openshift_register_node: name: ose3.node.example.com - hostIP: 192.168.1.1 - apiVersion: v1beta1 - resources: - capacity: - cpu: 1 - memory: 1073741824 + api_version: v1beta3 + external_ips: ['192.168.1.5'] + internal_ips: ['10.0.0.5'] + hostnames: ['ose2.node.internal.local'] + cpu: 3.5 + memory: 1Ti ''' + +class ClientConfigException(Exception): + pass + +class ClientConfig: + def __init__(self, client_opts, module): + _, output, error = module.run_command(["/usr/bin/openshift", "ex", + "config", "view", "-o", + "json"] + client_opts, + check_rc = True) + self.config = json.loads(output) + + if not (bool(self.config['clusters']) or + bool(self.config['contexts']) or + bool(self.config['current-context']) or + bool(self.config['users'])): + raise ClientConfigException(msg="Client config missing required " \ + "values", + output=output) + + def current_context(self): + return self.config['current-context'] + + def section_has_value(self, section_name, value): + section = self.config[section_name] + if isinstance(section, dict): + return value in section + else: + val = next((item for item in section + if item['name'] == value), None) + return val is not None + + def has_context(self, context): + return self.section_has_value('contexts', context) + + def has_user(self, user): + return self.section_has_value('users', user) + + def has_cluster(self, cluster): + return self.section_has_value('clusters', cluster) + + def get_value_for_context(self, context, attribute): + contexts = self.config['contexts'] + if isinstance(contexts, dict): + return contexts[context][attribute] + else: + return next((c['context'][attribute] for c in contexts + if c['name'] == context), None) + + def get_user_for_context(self, context): + return self.get_value_for_context(context, 'user') + + def get_cluster_for_context(self, context): + return self.get_value_for_context(context, 'cluster') + +class Util: + @staticmethod + def getLogicalCores(): + return multiprocessing.cpu_count() + + @staticmethod + def getMemoryPct(pct): + with open('/proc/meminfo', 'r') as mem: + for line in mem: + entries = line.split() + if str(entries.pop(0)) == 'MemTotal:': + mem_total_kb = Decimal(entries.pop(0)) + mem_capacity_kb = mem_total_kb * Decimal(pct) + return str(mem_capacity_kb.to_integral_value() * 1024) + + return "" + + @staticmethod + def remove_empty_elements(mapping): + if isinstance(mapping, dict): + m = mapping.copy() + for key, val in mapping.iteritems(): + if not val: + del m[key] + return m + else: + return mapping + +class NodeResources: + def __init__(self, version, cpu=None, memory=None): + if version == 'v1beta1': + self.resources = dict(capacity=dict()) + self.resources['capacity']['cpu'] = cpu if cpu else Util.getLogicalCores() + self.resources['capacity']['memory'] = memory if cpu else Util.getMemoryPct(.75) + + def get_resources(self): + return Util.remove_empty_elements(self.resources) + +class NodeSpec: + def __init__(self, version, cpu=None, memory=None, cidr=None, externalID=None): + if version == 'v1beta3': + self.spec = dict(podCIDR=cidr, externalID=externalID, + capacity=dict()) + self.spec['capacity']['cpu'] = cpu if cpu else Util.getLogicalCores() + self.spec['capacity']['memory'] = memory if memory else Util.getMemoryPct(.75) + + def get_spec(self): + return Util.remove_empty_elements(self.spec) + +class NodeStatus: + def addAddresses(self, addressType, addresses): + addressList = [] + for address in addresses: + addressList.append(dict(type=addressType, address=address)) + return addressList + + def __init__(self, version, externalIPs = [], internalIPs = [], + hostnames = []): + if version == 'v1beta3': + self.status = dict(addresses = addAddresses('ExternalIP', + externalIPs) + + addAddresses('InternalIP', + internalIPs) + + addAddresses('Hostname', + hostnames)) + + def get_status(self): + return Util.remove_empty_elements(self.status) + +class Node: + def __init__(self, module, client_opts, version='v1beta1', name=None, + hostIP = None, hostnames=[], externalIPs=[], internalIPs=[], + cpu=None, memory=None, labels=dict(), annotations=dict(), + podCIDR=None, externalID=None): + self.module = module + self.client_opts = client_opts + if version == 'v1beta1': + self.node = dict(id = name, + kind = 'Node', + apiVersion = version, + hostIP = hostIP, + resources = NodeResources(version, cpu, memory), + cidr = podCIDR, + labels = labels, + annotations = annotations + ) + elif version == 'v1beta3': + metadata = dict(name = name, + labels = labels, + annotations = annotations + ) + self.node = dict(kind = 'Node', + apiVersion = version, + metadata = metadata, + spec = NodeSpec(version, cpu, memory, podCIDR, + externalID), + status = NodeStatus(version, externalIPs, + internalIPs, hostnames), + ) + + def get_name(self): + if self.node['apiVersion'] == 'v1beta1': + return self.node['id'] + elif self.node['apiVersion'] == 'v1beta3': + return self.node['name'] + + def get_node(self): + node = self.node.copy() + if self.node['apiVersion'] == 'v1beta1': + node['resources'] = self.node['resources'].get_resources() + elif self.node['apiVersion'] == 'v1beta3': + node['spec'] = self.node['spec'].get_spec() + node['status'] = self.node['status'].get_status() + return Util.remove_empty_elements(node) + + def exists(self): + _, output, error = self.module.run_command(["/usr/bin/osc", "get", + "nodes"] + self.client_opts, + check_rc = True) + if re.search(self.module.params['name'], output, re.MULTILINE): + return True + return False + + def create(self): + cmd = ['/usr/bin/osc'] + self.client_opts + ['create', 'node', '-f', '-'] + rc, output, error = self.module.run_command(cmd, + data=self.module.jsonify(self.get_node())) + if rc != 0: + if re.search("minion \"%s\" already exists" % self.get_name(), + error): + self.module.exit_json(changed=False, + msg="node definition already exists", + node=self.get_node()) + else: + self.module.fail_json(msg="Node creation failed.", rc=rc, + output=output, error=error, + node=self.get_node()) + else: + return True + def main(): module = AnsibleModule( argument_spec = dict( - name = dict(required = True), - hostIP = dict(), - apiVersion = dict(), - cpu = dict(), - memory = dict(), - resources = dict(), - client_config = dict(), - client_cluster = dict(default = 'master'), - client_context = dict(default = 'master'), - client_user = dict(default = 'admin') + name = dict(required = True, type = 'str'), + host_ip = dict(type = 'str'), + hostnames = dict(type = 'list', default = []), + external_ips = dict(type = 'list', default = []), + internal_ips = dict(type = 'list', default = []), + api_version = dict(type = 'str', default = 'v1beta1', # TODO: after kube rebase, we can default to v1beta3 + choices = ['v1beta1', 'v1beta3']), + cpu = dict(type = 'str'), + memory = dict(type = 'str'), + labels = dict(type = 'dict', default = {}), # TODO: needs documented + annotations = dict(type = 'dict', default = {}), # TODO: needs documented + pod_cidr = dict(type = 'str'), # TODO: needs documented + external_id = dict(type = 'str'), # TODO: needs documented + client_config = dict(type = 'str'), # TODO: needs documented + client_cluster = dict(type = 'str', default = 'master'), # TODO: needs documented + client_context = dict(type = 'str', default = 'master'), # TODO: needs documented + client_user = dict(type = 'str', default = 'admin') # TODO: needs documented ), mutually_exclusive = [ - ['resources', 'cpu'], - ['resources', 'memory'] + ['host_ip', 'external_ips'], + ['host_ip', 'internal_ips'], + ['host_ip', 'hostnames'], ], supports_check_mode=True ) @@ -93,119 +330,61 @@ def main(): client_opts.append("--kubeconfig=%s" % module.params['client_config']) try: - output = check_output(["/usr/bin/openshift", "ex", "config", "view", - "-o", "json"] + client_opts, - stderr=subprocess.STDOUT) - except subprocess.CalledProcessError as e: - module.fail_json(msg="Failed to get client configuration", - command=e.cmd, returncode=e.returncode, output=e.output) - - config = json.loads(output) - if not (bool(config['clusters']) or bool(config['contexts']) or - bool(config['current-context']) or bool(config['users'])): - module.fail_json(msg="Client config missing required values", - output=output) + config = ClientConfig(client_opts, module) + except ClientConfigException as e: + module.fail_json(msg="Failed to get client configuration", exception=e) client_context = module.params['client_context'] - if client_context: - config_context = next((context for context in config['contexts'] - if context['name'] == client_context), None) - if not config_context: - module.fail_json(msg="Context %s not found in client config" % - client_context) - if not config['current-context'] or config['current-context'] != client_context: + if config.has_context(client_context): + if client_context != config.current_context(): client_opts.append("--context=%s" % client_context) + else: + module.fail_json(msg="Context %s not found in client config" % + client_context) client_user = module.params['client_user'] - if client_user: - config_user = next((user for user in config['users'] - if user['name'] == client_user), None) - if not config_user: - module.fail_json(msg="User %s not found in client config" % - client_user) - if client_user != config_context['context']['user']: + if config.has_user(client_user): + if client_user != config.get_user_for_context(client_context): client_opts.append("--user=%s" % client_user) + else: + module.fail_json(msg="User %s not found in client config" % + client_user) client_cluster = module.params['client_cluster'] - if client_cluster: - config_cluster = next((cluster for cluster in config['clusters'] - if cluster['name'] == client_cluster), None) - if not client_cluster: - module.fail_json(msg="Cluster %s not found in client config" % - client_cluster) - if client_cluster != config_context['context']['cluster']: + if config.has_cluster(client_cluster): + if client_cluster != config.get_cluster_for_context(client_cluster): client_opts.append("--cluster=%s" % client_cluster) + else: + module.fail_json(msg="Cluster %s not found in client config" % + client_cluster) - node_def = dict( - id = module.params['name'], - kind = 'Node', - apiVersion = 'v1beta1', - resources = dict( - capacity = dict() - ) - ) - - for key, value in module.params.iteritems(): - if key in ['cpu', 'memory']: - node_def['resources']['capacity'][key] = value - elif key == 'name': - node_def['id'] = value - elif key != 'client_config': - if value: - node_def[key] = value + # TODO: provide sane defaults for some (like hostname, externalIP, + # internalIP, etc) + node = Node(module, client_opts, module.params['api_version'], + module.params['name'], module.params['host_ip'], + module.params['hostnames'], module.params['external_ips'], + module.params['internal_ips'], module.params['cpu'], + module.params['memory'], module.params['labels'], + module.params['annotations'], module.params['pod_cidr'], + module.params['external_id']) - if not node_def['resources']['capacity']['cpu']: - node_def['resources']['capacity']['cpu'] = multiprocessing.cpu_count() - - if not node_def['resources']['capacity']['memory']: - with open('/proc/meminfo', 'r') as mem: - for line in mem: - entries = line.split() - if str(entries.pop(0)) == 'MemTotal:': - mem_total_kb = int(entries.pop(0)) - mem_capacity = int(mem_total_kb * 1024 * .75) - node_def['resources']['capacity']['memory'] = mem_capacity - break - - try: - output = check_output(["/usr/bin/osc", "get", "nodes"] + client_opts, - stderr=subprocess.STDOUT) - except subprocess.CalledProcessError as e: - module.fail_json(msg="Failed to get node list", command=e.cmd, - returncode=e.returncode, output=e.output) - - if re.search(module.params['name'], output, re.MULTILINE): - module.exit_json(changed=False, node_def=node_def) + # TODO: attempt to support changing node settings where possible and/or + # modifying node resources + if node.exists(): + module.exit_json(changed=False, node=node.get_node()) elif module.check_mode: - module.exit_json(changed=True, node_def=node_def) - - config_def = dict( - metadata = dict( - name = "add-node-%s" % module.params['name'] - ), - kind = 'Config', - apiVersion = 'v1beta1', - items = [node_def] - ) - - p = Popen(["/usr/bin/osc"] + client_opts + ["create", "node"] + ["-f", "-"], - stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, close_fds=True) - (out, err) = p.communicate(module.jsonify(config_def)) - ret = p.returncode - - if ret != 0: - if re.search("minion \"%s\" already exists" % module.params['name'], - err): - module.exit_json(changed=False, - msg="node definition already exists", config_def=config_def) + module.exit_json(changed=True, node=node.get_node()) + else: + if node.create(): + module.exit_json(changed=True, + msg="Node created successfully", + node=node.get_node()) else: - module.fail_json(msg="Node creation failed.", ret=ret, out=out, - err=err, config_def=config_def) + module.fail_json(msg="Unknown error creating node", + node=node.get_node()) - module.exit_json(changed=True, out=out, err=err, ret=ret, - node_def=config_def) # import module snippets from ansible.module_utils.basic import * -main() +if __name__ == '__main__': + main() diff --git a/roles/openshift_node/tasks/main.yml b/roles/openshift_node/tasks/main.yml index 6721c7401..e380ba1fb 100644 --- a/roles/openshift_node/tasks/main.yml +++ b/roles/openshift_node/tasks/main.yml @@ -21,7 +21,7 @@ lineinfile: dest: /etc/sysconfig/openshift-node regexp: '^OPTIONS=' - line: "OPTIONS=\"--master=https://{{ openshift_master_ips[0] }}:8443 --loglevel={{ openshift_node_debug_level }}\"" + line: "OPTIONS=\"--master=https://{{ openshift_master_ips[0] }}:8443 --hostname={{ openshift_hostname }} --loglevel={{ openshift_node_debug_level }}\"" notify: - restart openshift-node @@ -75,4 +75,14 @@ - name: Register node (if not already registered) openshift_register_node: name: "{{ openshift_hostname }}" - resources: "{{ openshift_node_resources }}" + api_version: v1beta1 + cpu: "{{ openshift_node_resources.cpu }}" + memory: "{{ openshift_node_resources.memory }}" + pod_cidr: "{{ openshift_node_resources.cidr }}" + host_ip: "{{ ansible_default_ipv4.address }}" + labels: "{{ openshift_node_labels }}" + annotations: "{{ openshift_node_annotations }}" + # TODO: support customizing other attributes such as: client_config, + # client_cluster, client_context, client_user + # TODO: updated for v1beta3 changes after rebase: hostnames, external_ips, + # internal_ips, external_id -- cgit v1.2.3 From 8613b70503d2d1cbe57ddebc11919edeb26eaadc Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Wed, 18 Mar 2015 17:15:19 -0400 Subject: Rename repos role to openshift_repos - Rename repos role to openshift_repos - Make openshift_repos a dependency of openshift_common - Add README and metadata for openshift_repos - Playbook updates for role rename - Verify libselinux-python is installed, otherwise some of the bulit-in modules we use fail --- playbooks/aws/openshift-master/config.yml | 1 - playbooks/aws/openshift-node/config.yml | 3 +- playbooks/gce/openshift-master/config.yml | 1 - playbooks/gce/openshift-node/config.yml | 3 +- roles/openshift_common/README.md | 1 + roles/openshift_common/meta/main.yml | 1 + roles/openshift_repos/README.md | 38 +++++++++++++ roles/openshift_repos/defaults/main.yaml | 5 ++ .../files/online/RPM-GPG-KEY-redhat-beta | 61 +++++++++++++++++++++ .../files/online/RPM-GPG-KEY-redhat-release | 63 ++++++++++++++++++++++ .../files/online/epel7-kubernetes.repo | 6 +++ .../files/online/epel7-openshift.repo | 6 +++ .../files/online/oso-rhui-rhel-7-extras.repo | 23 ++++++++ .../files/online/oso-rhui-rhel-7-server.repo | 21 ++++++++ .../files/online/rhel-7-libra-candidate.repo | 11 ++++ roles/openshift_repos/meta/main.yml | 14 +++++ roles/openshift_repos/tasks/main.yaml | 46 ++++++++++++++++ roles/openshift_repos/templates/yum_repo.j2 | 15 ++++++ roles/openshift_repos/vars/main.yml | 2 + roles/repos/defaults/main.yaml | 5 -- roles/repos/files/online/RPM-GPG-KEY-redhat-beta | 61 --------------------- .../repos/files/online/RPM-GPG-KEY-redhat-release | 63 ---------------------- roles/repos/files/online/epel7-kubernetes.repo | 6 --- roles/repos/files/online/epel7-openshift.repo | 6 --- .../repos/files/online/oso-rhui-rhel-7-extras.repo | 23 -------- .../repos/files/online/oso-rhui-rhel-7-server.repo | 21 -------- .../repos/files/online/rhel-7-libra-candidate.repo | 11 ---- roles/repos/tasks/main.yaml | 41 -------------- roles/repos/templates/yum_repo.j2 | 15 ------ roles/repos/vars/main.yml | 2 - 30 files changed, 315 insertions(+), 260 deletions(-) create mode 100644 roles/openshift_repos/README.md create mode 100644 roles/openshift_repos/defaults/main.yaml create mode 100644 roles/openshift_repos/files/online/RPM-GPG-KEY-redhat-beta create mode 100644 roles/openshift_repos/files/online/RPM-GPG-KEY-redhat-release create mode 100644 roles/openshift_repos/files/online/epel7-kubernetes.repo create mode 100644 roles/openshift_repos/files/online/epel7-openshift.repo create mode 100644 roles/openshift_repos/files/online/oso-rhui-rhel-7-extras.repo create mode 100644 roles/openshift_repos/files/online/oso-rhui-rhel-7-server.repo create mode 100644 roles/openshift_repos/files/online/rhel-7-libra-candidate.repo create mode 100644 roles/openshift_repos/meta/main.yml create mode 100644 roles/openshift_repos/tasks/main.yaml create mode 100644 roles/openshift_repos/templates/yum_repo.j2 create mode 100644 roles/openshift_repos/vars/main.yml delete mode 100644 roles/repos/defaults/main.yaml delete mode 100644 roles/repos/files/online/RPM-GPG-KEY-redhat-beta delete mode 100644 roles/repos/files/online/RPM-GPG-KEY-redhat-release delete mode 100644 roles/repos/files/online/epel7-kubernetes.repo delete mode 100644 roles/repos/files/online/epel7-openshift.repo delete mode 100644 roles/repos/files/online/oso-rhui-rhel-7-extras.repo delete mode 100644 roles/repos/files/online/oso-rhui-rhel-7-server.repo delete mode 100644 roles/repos/files/online/rhel-7-libra-candidate.repo delete mode 100644 roles/repos/tasks/main.yaml delete mode 100644 roles/repos/templates/yum_repo.j2 delete mode 100644 roles/repos/vars/main.yml diff --git a/playbooks/aws/openshift-master/config.yml b/playbooks/aws/openshift-master/config.yml index 454cd6f24..3d6238360 100644 --- a/playbooks/aws/openshift-master/config.yml +++ b/playbooks/aws/openshift-master/config.yml @@ -31,7 +31,6 @@ vars_files: - vars.yml roles: - - repos - { role: openshift_master, openshift_node_ips: "{{ hostvars['localhost'].openshift_node_ips | default(['']) }}", diff --git a/playbooks/aws/openshift-node/config.yml b/playbooks/aws/openshift-node/config.yml index 9662168c4..d39ad781f 100644 --- a/playbooks/aws/openshift-node/config.yml +++ b/playbooks/aws/openshift-node/config.yml @@ -37,8 +37,6 @@ vars_files: - vars.yml roles: - - repos - - docker - { role: openshift_node, openshift_master_ips: "{{ hostvars['localhost'].openshift_master_ips | default(['']) }}", @@ -46,4 +44,5 @@ openshift_env: "{{ oo_env }}" openshift_public_ip: "{{ ec2_ip_address }}" } + - docker - os_env_extras diff --git a/playbooks/gce/openshift-master/config.yml b/playbooks/gce/openshift-master/config.yml index ae598b622..a74250d13 100644 --- a/playbooks/gce/openshift-master/config.yml +++ b/playbooks/gce/openshift-master/config.yml @@ -31,7 +31,6 @@ vars_files: - vars.yml roles: - - repos - { role: openshift_master, openshift_node_ips: "{{ hostvars['localhost'].openshift_node_ips | default(['']) }}", diff --git a/playbooks/gce/openshift-node/config.yml b/playbooks/gce/openshift-node/config.yml index 85f34e814..78047cf40 100644 --- a/playbooks/gce/openshift-node/config.yml +++ b/playbooks/gce/openshift-node/config.yml @@ -37,8 +37,6 @@ vars_files: - vars.yml roles: - - repos - - docker - { role: openshift_node, openshift_master_ips: "{{ hostvars['localhost'].openshift_master_ips | default(['']) }}", @@ -46,4 +44,5 @@ openshift_public_ip: "{{ gce_public_ip }}", openshift_env: "{{ oo_env }}", } + - docker - os_env_extras diff --git a/roles/openshift_common/README.md b/roles/openshift_common/README.md index c2ae609ff..a055cb032 100644 --- a/roles/openshift_common/README.md +++ b/roles/openshift_common/README.md @@ -25,6 +25,7 @@ Dependencies ------------ os_firewall +openshift_repos Example Playbook ---------------- diff --git a/roles/openshift_common/meta/main.yml b/roles/openshift_common/meta/main.yml index 88b7677d0..cee4dd337 100644 --- a/roles/openshift_common/meta/main.yml +++ b/roles/openshift_common/meta/main.yml @@ -13,3 +13,4 @@ galaxy_info: - cloud dependencies: - { role: os_firewall } +- { role: openshift_repos } diff --git a/roles/openshift_repos/README.md b/roles/openshift_repos/README.md new file mode 100644 index 000000000..6713e11fc --- /dev/null +++ b/roles/openshift_repos/README.md @@ -0,0 +1,38 @@ +OpenShift Repos +================ + +Configures repositories for an OpenShift installation + +Requirements +------------ + +A RHEL 7.1 host pre-configured with access to the rhel-7-server-rpms, +rhel-7-server-extra-rpms, and rhel-7-server-ose-beta-rpms repos. + +Role Variables +-------------- + +| Name | Default value | | +|-------------------------------|---------------|----------------------------------------------| +| openshift_deployment_type | online | Possible values enterprise, origin, online | +| openshift_additional_repos | {} | TODO | + +Dependencies +------------ + +None. + +Example Playbook +---------------- + +TODO + +License +------- + +Apache License, Version 2.0 + +Author Information +------------------ + +TODO diff --git a/roles/openshift_repos/defaults/main.yaml b/roles/openshift_repos/defaults/main.yaml new file mode 100644 index 000000000..6fe2bf621 --- /dev/null +++ b/roles/openshift_repos/defaults/main.yaml @@ -0,0 +1,5 @@ +--- +# TODO: once we are able to configure/deploy origin using the openshift roles, +# then we should default to origin +openshift_deployment_type: online +openshift_additional_repos: {} diff --git a/roles/openshift_repos/files/online/RPM-GPG-KEY-redhat-beta b/roles/openshift_repos/files/online/RPM-GPG-KEY-redhat-beta new file mode 100644 index 000000000..7b40671a4 --- /dev/null +++ b/roles/openshift_repos/files/online/RPM-GPG-KEY-redhat-beta @@ -0,0 +1,61 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.2.6 (GNU/Linux) + +mQINBEmkAzABEAC2/c7bP1lHQ3XScxbIk0LQWe1YOiibQBRLwf8Si5PktgtuPibT +kKpZjw8p4D+fM7jD1WUzUE0X7tXg2l/eUlMM4dw6XJAQ1AmEOtlwSg7rrMtTvM0A +BEtI7Km6fC6sU6RtBMdcqD1cH/6dbsfh8muznVA7UlX+PRBHVzdWzj6y8h84dBjo +gzcbYu9Hezqgj/lLzicqsSZPz9UdXiRTRAIhp8V30BD8uRaaa0KDDnD6IzJv3D9P +xQWbFM4Z12GN9LyeZqmD7bpKzZmXG/3drvfXVisXaXp3M07t3NlBa3Dt8NFIKZ0D +FRXBz5bvzxRVmdH6DtkDWXDPOt+Wdm1rZrCOrySFpBZQRpHw12eo1M1lirANIov7 +Z+V1Qh/aBxj5EUu32u9ZpjAPPNtQF6F/KjaoHHHmEQAuj4DLex4LY646Hv1rcv2i +QFuCdvLKQGSiFBrfZH0j/IX3/0JXQlZzb3MuMFPxLXGAoAV9UP/Sw/WTmAuTzFVm +G13UYFeMwrToOiqcX2VcK0aC1FCcTP2z4JW3PsWvU8rUDRUYfoXovc7eg4Vn5wHt +0NBYsNhYiAAf320AUIHzQZYi38JgVwuJfFu43tJZE4Vig++RQq6tsEx9Ftz3EwRR +fJ9z9mEvEiieZm+vbOvMvIuimFVPSCmLH+bI649K8eZlVRWsx3EXCVb0nQARAQAB +tDBSZWQgSGF0LCBJbmMuIChiZXRhIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0LmNv +bT6JAjYEEwECACAFAkpSM+cCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRCT +ioDK8hVB6/9tEAC0+KmzeKceXQ/GTUoU6jy9vtkFCFrmv+c7ol4XpdTt0QhqBOwy +6m2mKWwmm8KfYfy0cADQ4y/EcoXl7FtFBwYmkCuEQGXhTDn9DvVjhooIq59LEMBQ +OW879RwwzRIZ8ebbjMUjDPF5MfPQqP2LBu9N4KvXlZp4voykwuuaJ+cbsKZR6pZ6 +0RQKPHKP+NgUFC0fff7XY9cuOZZWFAeKRhLN2K7bnRHKxp+kELWb6R9ZfrYwZjWc +MIPbTd1khE53L4NTfpWfAnJRtkPSDOKEGVlVLtLq4HEAxQt07kbslqISRWyXER3u +QOJj64D1ZiIMz6t6uZ424VE4ry9rBR0Jz55cMMx5O/ni9x3xzFUgH8Su2yM0r3jE +Rf24+tbOaPf7tebyx4OKe+JW95hNVstWUDyGbs6K9qGfI/pICuO1nMMFTo6GqzQ6 +DwLZvJ9QdXo7ujEtySZnfu42aycaQ9ZLC2DOCQCUBY350Hx6FLW3O546TAvpTfk0 +B6x+DV7mJQH7MGmRXQsE7TLBJKjq28Cn4tVp04PmybQyTxZdGA/8zY6pPl6xyVMH +V68hSBKEVT/rlouOHuxfdmZva1DhVvUC6Xj7+iTMTVJUAq/4Uyn31P1OJmA2a0PT +CAqWkbJSgKFccsjPoTbLyxhuMSNkEZFHvlZrSK9vnPzmfiRH0Orx3wYpMQ== +=21pb +-----END PGP PUBLIC KEY BLOCK----- +The following public key can be used to verify RPM packages built and +signed by Red Hat, Inc. for this beta using `rpm -K' using the GNU GPG +package. Questions about this key should be sent to security@redhat.com. + + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.0.6 (GNU/Linux) +Comment: For info see http://www.gnupg.org + +mQGiBDySTqsRBACzc7xuCIp10oj5B2PAV4XzDeVxprv/WTMreSNSK+iC0bEz0IBp +Vnn++qtyiXfH+bGIE9jqZgIEnpttWhUOaU5LhcLFzy+m8NWfngIFP9QfGmGAe9Gd +LFeAdhj4RmSG/vgr7vDd83Hz22dv403Ar/sliWO4vDOrMmZBG57WGYTWtwCgkMsi +UUQuJ6slbzKn82w+bYxOlL0EAIylWJGaTkKOTL5DqVR3ik9aT0Dt3FNVYiuhcKBe +II4E3KOIVA9kO8in1IZjx2gs6K2UV+GsoAVANdfKL7l9O+k+J8OxhE74oycvYJxW +QzCgXMZkNcvW5wyXwEMcr6TVd/5BGztcMw8oT3/l2MtAEG/vn1XaWToRSO1XDMDz ++AjUA/4m0mTkN8S4wjzJG8lqN7+quW3UOaiCe8J3SFrrrhE0XbY9cTJI/9nuXHU1 +VjqOSmXQYH2Db7UOroFTBiWhlAedA4O4yuK52AJnvSsHbnJSEmn9rpo5z1Q8F+qI +mDlzriJdrIrVLeDiUeTlpH3kpG38D7007GhXBV72k1gpMoMcpbQ3UmVkIEhhdCwg +SW5jLiAoQmV0YSBUZXN0IFNvZnR3YXJlKSA8cmF3aGlkZUByZWRoYXQuY29tPohX +BBMRAgAXBQI8l5p/BQsHCgMEAxUDAgMWAgECF4AACgkQ/TcmiYl9oHqdeQCfZjw4 +F9sir3XfRAjVe9kYNcQ8hnIAn0WgyT7H5RriWYTOCfauOmd+cAW4iEYEEBECAAYF +AjyXmqQACgkQIZGAzdtCpg5nDQCfepuRUyuVJvhuQkPWySETYvRw+WoAnjAWhx6q +0npMx4OE1JGFi8ymKXktuQENBDySTq4QBADKL/mK7S8E3synxISlu7R6fUvu07Oc +RoX96n0Di6T+BS99hC44XzHjMDhUX2ZzVvYS88EZXoUDDkB/8g7SwZrOJ/QE1zrI +JmSVciNhSYWwqeT40Evs88ajZUfDiNbS/cSC6oui98iS4vxd7sE7IPY+FSx9vuAR +xOa9vBnJY/dx0wADBQQAosm+Iltt2uigC6LJzxNOoIdB5r0GqTC1o5sHCeNqXJhU +ExAG8m74uzMlYVLOpGZi4y4NwwAWvCWC0MWWnnu+LGFy1wKiJKRjhv5F+WkFutY5 +WHV5L44vp9jSIlBCRG+84jheTh8xqhndM9wOfPwWdYYu1vxrB8Tn6kA17PcYfHSI +RgQYEQIABgUCPJJergAKCRD9NyaJiX2geiCPAJ4nEM4NtI9Uj8lONDk6FU86PmoL +yACfb68fBd2pWEzLKsOk9imIobHHpzE= +=gpIn +-----END PGP PUBLIC KEY BLOCK----- diff --git a/roles/openshift_repos/files/online/RPM-GPG-KEY-redhat-release b/roles/openshift_repos/files/online/RPM-GPG-KEY-redhat-release new file mode 100644 index 000000000..0f83b622d --- /dev/null +++ b/roles/openshift_repos/files/online/RPM-GPG-KEY-redhat-release @@ -0,0 +1,63 @@ +The following public key can be used to verify RPM packages built and +signed by Red Hat, Inc. This key is used for packages in Red Hat +products shipped after November 2009, and for all updates to those +products. + +Questions about this key should be sent to security@redhat.com. + +pub 4096R/FD431D51 2009-10-22 Red Hat, Inc. (release key 2) + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.2.6 (GNU/Linux) + +mQINBErgSTsBEACh2A4b0O9t+vzC9VrVtL1AKvUWi9OPCjkvR7Xd8DtJxeeMZ5eF +0HtzIG58qDRybwUe89FZprB1ffuUKzdE+HcL3FbNWSSOXVjZIersdXyH3NvnLLLF +0DNRB2ix3bXG9Rh/RXpFsNxDp2CEMdUvbYCzE79K1EnUTVh1L0Of023FtPSZXX0c +u7Pb5DI5lX5YeoXO6RoodrIGYJsVBQWnrWw4xNTconUfNPk0EGZtEnzvH2zyPoJh +XGF+Ncu9XwbalnYde10OCvSWAZ5zTCpoLMTvQjWpbCdWXJzCm6G+/hx9upke546H +5IjtYm4dTIVTnc3wvDiODgBKRzOl9rEOCIgOuGtDxRxcQkjrC+xvg5Vkqn7vBUyW +9pHedOU+PoF3DGOM+dqv+eNKBvh9YF9ugFAQBkcG7viZgvGEMGGUpzNgN7XnS1gj +/DPo9mZESOYnKceve2tIC87p2hqjrxOHuI7fkZYeNIcAoa83rBltFXaBDYhWAKS1 +PcXS1/7JzP0ky7d0L6Xbu/If5kqWQpKwUInXtySRkuraVfuK3Bpa+X1XecWi24JY +HVtlNX025xx1ewVzGNCTlWn1skQN2OOoQTV4C8/qFpTW6DTWYurd4+fE0OJFJZQF +buhfXYwmRlVOgN5i77NTIJZJQfYFj38c/Iv5vZBPokO6mffrOTv3MHWVgQARAQAB +tDNSZWQgSGF0LCBJbmMuIChyZWxlYXNlIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0 +LmNvbT6JAjYEEwECACAFAkrgSTsCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK +CRAZni+R/UMdUWzpD/9s5SFR/ZF3yjY5VLUFLMXIKUztNN3oc45fyLdTI3+UClKC +2tEruzYjqNHhqAEXa2sN1fMrsuKec61Ll2NfvJjkLKDvgVIh7kM7aslNYVOP6BTf +C/JJ7/ufz3UZmyViH/WDl+AYdgk3JqCIO5w5ryrC9IyBzYv2m0HqYbWfphY3uHw5 +un3ndLJcu8+BGP5F+ONQEGl+DRH58Il9Jp3HwbRa7dvkPgEhfFR+1hI+Btta2C7E +0/2NKzCxZw7Lx3PBRcU92YKyaEihfy/aQKZCAuyfKiMvsmzs+4poIX7I9NQCJpyE +IGfINoZ7VxqHwRn/d5mw2MZTJjbzSf+Um9YJyA0iEEyD6qjriWQRbuxpQXmlAJbh +8okZ4gbVFv1F8MzK+4R8VvWJ0XxgtikSo72fHjwha7MAjqFnOq6eo6fEC/75g3NL +Ght5VdpGuHk0vbdENHMC8wS99e5qXGNDued3hlTavDMlEAHl34q2H9nakTGRF5Ki +JUfNh3DVRGhg8cMIti21njiRh7gyFI2OccATY7bBSr79JhuNwelHuxLrCFpY7V25 +OFktl15jZJaMxuQBqYdBgSay2G0U6D1+7VsWufpzd/Abx1/c3oi9ZaJvW22kAggq +dzdA27UUYjWvx42w9menJwh/0jeQcTecIUd0d0rFcw/c1pvgMMl/Q73yzKgKYw== +=zbHE +-----END PGP PUBLIC KEY BLOCK----- +The following public key can be used to verify RPM packages built and +signed by Red Hat, Inc. This key is a supporting (auxiliary) key for +Red Hat products shipped after November 2006 and for all updates to +those products. + +Questions about this key should be sent to security@redhat.com. + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.2.6 (GNU/Linux) + +mQGiBEVwDGkRBACwPhZIpvkjI8wV9sFTDoqyPLx1ub8Sd/w+YuI5Ovm49mvvEQVT +VLg8FgE5JlST59AbsLDyVtRa9CxIvN5syBVrWWWtHtDnnylFBcqG/A6J3bI4E9/A +UtSL5Zxbav0+utP6f3wOpxQrxc+WIDVgpurdBKAQ3dsobGBqypeX6FXZ5wCgou6C +yZpGIBqosJaDWLzNeOfb/70D/1thLkQyhW3JJ6cHCYJHNfBShvbLWBf6S231mgmu +MyMlt8Kmipc9bw+saaAkSkVsQ/ZbfjrWB7e5kbMruKLVrH+nGhamlHYUGyAPtsPg +Uj/NUSj5BmrCsOkMpn43ngTLssE9MLhSPj2nIHGFv9B+iVLvomDdwnaBRgQ1aK8z +z6MAA/406yf5yVJ/MlTWs1/68VwDhosc9BtU1V5IE0NXgZUAfBJzzfVzzKQq6zJ2 +eZsMLhr96wbsW13zUZt1ing+ulwh2ee4meuJq6h/971JspFY/XBhcfq4qCNqVjsq +SZnWoGdCO6J8CxPIemD2IUHzjoyyeEj3RVydup6pcWZAmhzkKrQzUmVkIEhhdCwg +SW5jLiAoYXV4aWxpYXJ5IGtleSkgPHNlY3VyaXR5QHJlZGhhdC5jb20+iF4EExEC +AB4FAkVwDGkCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQRWiciC+mWOC1rQCg +ooNLCFOzNPcvhd9Za8C801HmnsYAniCw3yzrCqtjYnxDDxlufH0FVTwX +=d/bm +-----END PGP PUBLIC KEY BLOCK----- + diff --git a/roles/openshift_repos/files/online/epel7-kubernetes.repo b/roles/openshift_repos/files/online/epel7-kubernetes.repo new file mode 100644 index 000000000..1deae2939 --- /dev/null +++ b/roles/openshift_repos/files/online/epel7-kubernetes.repo @@ -0,0 +1,6 @@ +[maxamillion-epel7-kubernetes] +name=Copr repo for epel7-kubernetes owned by maxamillion +baseurl=http://copr-be.cloud.fedoraproject.org/results/maxamillion/epel7-kubernetes/epel-7-$basearch/ +skip_if_unavailable=True +gpgcheck=0 +enabled=1 diff --git a/roles/openshift_repos/files/online/epel7-openshift.repo b/roles/openshift_repos/files/online/epel7-openshift.repo new file mode 100644 index 000000000..c7629872d --- /dev/null +++ b/roles/openshift_repos/files/online/epel7-openshift.repo @@ -0,0 +1,6 @@ +[maxamillion-origin-next] +name=Copr repo for origin-next owned by maxamillion +baseurl=http://copr-be.cloud.fedoraproject.org/results/maxamillion/origin-next/epel-7-$basearch/ +skip_if_unavailable=False +gpgcheck=0 +enabled=1 diff --git a/roles/openshift_repos/files/online/oso-rhui-rhel-7-extras.repo b/roles/openshift_repos/files/online/oso-rhui-rhel-7-extras.repo new file mode 100644 index 000000000..cfe41f691 --- /dev/null +++ b/roles/openshift_repos/files/online/oso-rhui-rhel-7-extras.repo @@ -0,0 +1,23 @@ +[oso-rhui-rhel-server-extras] +name=OpenShift Online RHUI Mirror RH Enterprise Linux - Extras +baseurl=https://gce-mirror1.ops.rhcloud.com/libra/rhui-rhel-server-7-extras/ + https://mirror.ops.rhcloud.com/libra/rhui-rhel-server-7-extras/ +enabled=1 +gpgcheck=1 +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta +failovermethod=priority +sslverify=False +sslclientcert=/var/lib/yum/client-cert.pem +sslclientkey=/var/lib/yum/client-key.pem + +[oso-rhui-rhel-server-extras-htb] +name=OpenShift Online RHUI Mirror RH Enterprise Linux - Extras HTB +baseurl=https://gce-mirror1.ops.rhcloud.com/libra/rhui-rhel-server-7-extras-htb/ + https://mirror.ops.rhcloud.com/libra/rhui-rhel-server-7-extras-htb/ +enabled=0 +gpgcheck=1 +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta +failovermethod=priority +sslverify=False +sslclientcert=/var/lib/yum/client-cert.pem +sslclientkey=/var/lib/yum/client-key.pem diff --git a/roles/openshift_repos/files/online/oso-rhui-rhel-7-server.repo b/roles/openshift_repos/files/online/oso-rhui-rhel-7-server.repo new file mode 100644 index 000000000..ddc93193d --- /dev/null +++ b/roles/openshift_repos/files/online/oso-rhui-rhel-7-server.repo @@ -0,0 +1,21 @@ +[oso-rhui-rhel-server-releases] +name=OpenShift Online RHUI Mirror RH Enterprise Linux 7 +baseurl=https://gce-mirror1.ops.rhcloud.com/libra/rhui-rhel-server-7-releases/ + https://mirror.ops.rhcloud.com/libra/rhui-rhel-server-7-releases/ +enabled=1 +gpgcheck=1 +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +sslverify=False +sslclientcert=/var/lib/yum/client-cert.pem +sslclientkey=/var/lib/yum/client-key.pem + +[oso-rhui-rhel-server-releases-optional] +name=OpenShift Online RHUI Mirror RH Enterprise Linux 7 - Optional +baseurl=https://gce-mirror1.ops.rhcloud.com/libra/rhui-rhel-server-7-releases-optional/ + https://mirror.ops.rhcloud.com/libra/rhui-rhel-server-7-releases-optional/ +enabled=1 +gpgcheck=1 +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release +sslverify=False +sslclientcert=/var/lib/yum/client-cert.pem +sslclientkey=/var/lib/yum/client-key.pem diff --git a/roles/openshift_repos/files/online/rhel-7-libra-candidate.repo b/roles/openshift_repos/files/online/rhel-7-libra-candidate.repo new file mode 100644 index 000000000..b4215679f --- /dev/null +++ b/roles/openshift_repos/files/online/rhel-7-libra-candidate.repo @@ -0,0 +1,11 @@ +[rhel-7-libra-candidate] +name=rhel-7-libra-candidate - \$basearch +baseurl=https://gce-mirror1.ops.rhcloud.com/libra/rhel-7-libra-candidate/\$basearch/ + https://mirror.ops.rhcloud.com/libra/rhel-7-libra-candidate/\$basearch/ +gpgkey=https://mirror.ops.rhcloud.com/libra/RPM-GPG-KEY-redhat-openshifthosted +skip_if_unavailable=True +gpgcheck=0 +enabled=1 +sslclientcert=/var/lib/yum/client-cert.pem +sslclientkey=/var/lib/yum/client-key.pem +sslverify=False diff --git a/roles/openshift_repos/meta/main.yml b/roles/openshift_repos/meta/main.yml new file mode 100644 index 000000000..cc18c453c --- /dev/null +++ b/roles/openshift_repos/meta/main.yml @@ -0,0 +1,14 @@ +--- +galaxy_info: + author: TODO + description: OpenShift Repositories + company: Red Hat, Inc. + license: Apache License, Version 2.0 + min_ansible_version: 1.7 + platforms: + - name: EL + versions: + - 7 + categories: + - cloud +dependencies: [] diff --git a/roles/openshift_repos/tasks/main.yaml b/roles/openshift_repos/tasks/main.yaml new file mode 100644 index 000000000..6219c4906 --- /dev/null +++ b/roles/openshift_repos/tasks/main.yaml @@ -0,0 +1,46 @@ +--- +# TODO: Add flag for enabling EPEL repo, default to false + +- assert: + that: openshift_deployment_type in known_openshift_deployment_types + +# TODO: remove this when origin support actually works +- fail: msg="OpenShift Origin support is not currently enabled" + when: openshift_deployment_type == 'origin' + +- name: Ensure libselinux-python is installed + yum: + pkg: libselinux-python + state: present + +- name: Create any additional repos that are defined + template: + src: yum_repo.j2 + dest: /etc/yum.repos.d/openshift_additional.repo + when: openshift_additional_repos | length > 0 + +- name: Remove the additional repos if no longer defined + file: + dest: /etc/yum.repos.d/openshift_additional.repo + state: absent + when: openshift_additional_repos | length == 0 + +- name: Remove any yum repo files for other deployment types + file: + path: "/etc/yum.repos.d/{{ item | basename }}" + state: absent + with_fileglob: + - '*/*' + when: not (item | search("/files/" + openshift_deployment_type + "/")) and (item | search(".repo$")) + +- name: Configure gpg keys if needed + copy: src={{ item }} dest=/etc/pki/rpm-gpg/ + with_fileglob: + - "{{ openshift_deployment_type }}/*" + when: item | basename | match("RPM-GPG-KEY-") + +- name: Configure yum repositories + copy: src={{ item }} dest=/etc/yum.repos.d/ + with_fileglob: + - "{{ openshift_deployment_type }}/*" + when: item | basename | search(".*\.repo$") diff --git a/roles/openshift_repos/templates/yum_repo.j2 b/roles/openshift_repos/templates/yum_repo.j2 new file mode 100644 index 000000000..7ea2c7460 --- /dev/null +++ b/roles/openshift_repos/templates/yum_repo.j2 @@ -0,0 +1,15 @@ +# {{ ansible_managed }} +{% for repo in openshift_additional_repos %} +[{{ repo.id }}] +name={{ repo.name | default(repo.id) }} +baseurl={{ repo.baseurl }} +{% set enable_repo = repo.enabled | default('1') %} +enabled={{ 1 if ( enable_repo == 1 or enable_repo == True ) else 0 }} +{% set enable_gpg_check = repo.gpgcheck | default('1') %} +gpgcheck={{ 1 if ( enable_gpg_check == 1 or enable_gpg_check == True ) else 0 }} +{% for key, value in repo.iteritems() %} +{% if key not in ['id', 'name', 'baseurl', 'enabled', 'gpgcheck'] and value is defined %} +{{ key }}={{ value }} +{% endif %} +{% endfor %} +{% endfor %} diff --git a/roles/openshift_repos/vars/main.yml b/roles/openshift_repos/vars/main.yml new file mode 100644 index 000000000..bbb4c77e7 --- /dev/null +++ b/roles/openshift_repos/vars/main.yml @@ -0,0 +1,2 @@ +--- +known_openshift_deployment_types: ['origin', 'online', 'enterprise'] diff --git a/roles/repos/defaults/main.yaml b/roles/repos/defaults/main.yaml deleted file mode 100644 index 6fe2bf621..000000000 --- a/roles/repos/defaults/main.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -# TODO: once we are able to configure/deploy origin using the openshift roles, -# then we should default to origin -openshift_deployment_type: online -openshift_additional_repos: {} diff --git a/roles/repos/files/online/RPM-GPG-KEY-redhat-beta b/roles/repos/files/online/RPM-GPG-KEY-redhat-beta deleted file mode 100644 index 7b40671a4..000000000 --- a/roles/repos/files/online/RPM-GPG-KEY-redhat-beta +++ /dev/null @@ -1,61 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.2.6 (GNU/Linux) - -mQINBEmkAzABEAC2/c7bP1lHQ3XScxbIk0LQWe1YOiibQBRLwf8Si5PktgtuPibT -kKpZjw8p4D+fM7jD1WUzUE0X7tXg2l/eUlMM4dw6XJAQ1AmEOtlwSg7rrMtTvM0A -BEtI7Km6fC6sU6RtBMdcqD1cH/6dbsfh8muznVA7UlX+PRBHVzdWzj6y8h84dBjo -gzcbYu9Hezqgj/lLzicqsSZPz9UdXiRTRAIhp8V30BD8uRaaa0KDDnD6IzJv3D9P -xQWbFM4Z12GN9LyeZqmD7bpKzZmXG/3drvfXVisXaXp3M07t3NlBa3Dt8NFIKZ0D -FRXBz5bvzxRVmdH6DtkDWXDPOt+Wdm1rZrCOrySFpBZQRpHw12eo1M1lirANIov7 -Z+V1Qh/aBxj5EUu32u9ZpjAPPNtQF6F/KjaoHHHmEQAuj4DLex4LY646Hv1rcv2i -QFuCdvLKQGSiFBrfZH0j/IX3/0JXQlZzb3MuMFPxLXGAoAV9UP/Sw/WTmAuTzFVm -G13UYFeMwrToOiqcX2VcK0aC1FCcTP2z4JW3PsWvU8rUDRUYfoXovc7eg4Vn5wHt -0NBYsNhYiAAf320AUIHzQZYi38JgVwuJfFu43tJZE4Vig++RQq6tsEx9Ftz3EwRR -fJ9z9mEvEiieZm+vbOvMvIuimFVPSCmLH+bI649K8eZlVRWsx3EXCVb0nQARAQAB -tDBSZWQgSGF0LCBJbmMuIChiZXRhIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0LmNv -bT6JAjYEEwECACAFAkpSM+cCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRCT -ioDK8hVB6/9tEAC0+KmzeKceXQ/GTUoU6jy9vtkFCFrmv+c7ol4XpdTt0QhqBOwy -6m2mKWwmm8KfYfy0cADQ4y/EcoXl7FtFBwYmkCuEQGXhTDn9DvVjhooIq59LEMBQ -OW879RwwzRIZ8ebbjMUjDPF5MfPQqP2LBu9N4KvXlZp4voykwuuaJ+cbsKZR6pZ6 -0RQKPHKP+NgUFC0fff7XY9cuOZZWFAeKRhLN2K7bnRHKxp+kELWb6R9ZfrYwZjWc -MIPbTd1khE53L4NTfpWfAnJRtkPSDOKEGVlVLtLq4HEAxQt07kbslqISRWyXER3u -QOJj64D1ZiIMz6t6uZ424VE4ry9rBR0Jz55cMMx5O/ni9x3xzFUgH8Su2yM0r3jE -Rf24+tbOaPf7tebyx4OKe+JW95hNVstWUDyGbs6K9qGfI/pICuO1nMMFTo6GqzQ6 -DwLZvJ9QdXo7ujEtySZnfu42aycaQ9ZLC2DOCQCUBY350Hx6FLW3O546TAvpTfk0 -B6x+DV7mJQH7MGmRXQsE7TLBJKjq28Cn4tVp04PmybQyTxZdGA/8zY6pPl6xyVMH -V68hSBKEVT/rlouOHuxfdmZva1DhVvUC6Xj7+iTMTVJUAq/4Uyn31P1OJmA2a0PT -CAqWkbJSgKFccsjPoTbLyxhuMSNkEZFHvlZrSK9vnPzmfiRH0Orx3wYpMQ== -=21pb ------END PGP PUBLIC KEY BLOCK----- -The following public key can be used to verify RPM packages built and -signed by Red Hat, Inc. for this beta using `rpm -K' using the GNU GPG -package. Questions about this key should be sent to security@redhat.com. - - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.0.6 (GNU/Linux) -Comment: For info see http://www.gnupg.org - -mQGiBDySTqsRBACzc7xuCIp10oj5B2PAV4XzDeVxprv/WTMreSNSK+iC0bEz0IBp -Vnn++qtyiXfH+bGIE9jqZgIEnpttWhUOaU5LhcLFzy+m8NWfngIFP9QfGmGAe9Gd -LFeAdhj4RmSG/vgr7vDd83Hz22dv403Ar/sliWO4vDOrMmZBG57WGYTWtwCgkMsi -UUQuJ6slbzKn82w+bYxOlL0EAIylWJGaTkKOTL5DqVR3ik9aT0Dt3FNVYiuhcKBe -II4E3KOIVA9kO8in1IZjx2gs6K2UV+GsoAVANdfKL7l9O+k+J8OxhE74oycvYJxW -QzCgXMZkNcvW5wyXwEMcr6TVd/5BGztcMw8oT3/l2MtAEG/vn1XaWToRSO1XDMDz -+AjUA/4m0mTkN8S4wjzJG8lqN7+quW3UOaiCe8J3SFrrrhE0XbY9cTJI/9nuXHU1 -VjqOSmXQYH2Db7UOroFTBiWhlAedA4O4yuK52AJnvSsHbnJSEmn9rpo5z1Q8F+qI -mDlzriJdrIrVLeDiUeTlpH3kpG38D7007GhXBV72k1gpMoMcpbQ3UmVkIEhhdCwg -SW5jLiAoQmV0YSBUZXN0IFNvZnR3YXJlKSA8cmF3aGlkZUByZWRoYXQuY29tPohX -BBMRAgAXBQI8l5p/BQsHCgMEAxUDAgMWAgECF4AACgkQ/TcmiYl9oHqdeQCfZjw4 -F9sir3XfRAjVe9kYNcQ8hnIAn0WgyT7H5RriWYTOCfauOmd+cAW4iEYEEBECAAYF -AjyXmqQACgkQIZGAzdtCpg5nDQCfepuRUyuVJvhuQkPWySETYvRw+WoAnjAWhx6q -0npMx4OE1JGFi8ymKXktuQENBDySTq4QBADKL/mK7S8E3synxISlu7R6fUvu07Oc -RoX96n0Di6T+BS99hC44XzHjMDhUX2ZzVvYS88EZXoUDDkB/8g7SwZrOJ/QE1zrI -JmSVciNhSYWwqeT40Evs88ajZUfDiNbS/cSC6oui98iS4vxd7sE7IPY+FSx9vuAR -xOa9vBnJY/dx0wADBQQAosm+Iltt2uigC6LJzxNOoIdB5r0GqTC1o5sHCeNqXJhU -ExAG8m74uzMlYVLOpGZi4y4NwwAWvCWC0MWWnnu+LGFy1wKiJKRjhv5F+WkFutY5 -WHV5L44vp9jSIlBCRG+84jheTh8xqhndM9wOfPwWdYYu1vxrB8Tn6kA17PcYfHSI -RgQYEQIABgUCPJJergAKCRD9NyaJiX2geiCPAJ4nEM4NtI9Uj8lONDk6FU86PmoL -yACfb68fBd2pWEzLKsOk9imIobHHpzE= -=gpIn ------END PGP PUBLIC KEY BLOCK----- diff --git a/roles/repos/files/online/RPM-GPG-KEY-redhat-release b/roles/repos/files/online/RPM-GPG-KEY-redhat-release deleted file mode 100644 index 0f83b622d..000000000 --- a/roles/repos/files/online/RPM-GPG-KEY-redhat-release +++ /dev/null @@ -1,63 +0,0 @@ -The following public key can be used to verify RPM packages built and -signed by Red Hat, Inc. This key is used for packages in Red Hat -products shipped after November 2009, and for all updates to those -products. - -Questions about this key should be sent to security@redhat.com. - -pub 4096R/FD431D51 2009-10-22 Red Hat, Inc. (release key 2) - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.2.6 (GNU/Linux) - -mQINBErgSTsBEACh2A4b0O9t+vzC9VrVtL1AKvUWi9OPCjkvR7Xd8DtJxeeMZ5eF -0HtzIG58qDRybwUe89FZprB1ffuUKzdE+HcL3FbNWSSOXVjZIersdXyH3NvnLLLF -0DNRB2ix3bXG9Rh/RXpFsNxDp2CEMdUvbYCzE79K1EnUTVh1L0Of023FtPSZXX0c -u7Pb5DI5lX5YeoXO6RoodrIGYJsVBQWnrWw4xNTconUfNPk0EGZtEnzvH2zyPoJh -XGF+Ncu9XwbalnYde10OCvSWAZ5zTCpoLMTvQjWpbCdWXJzCm6G+/hx9upke546H -5IjtYm4dTIVTnc3wvDiODgBKRzOl9rEOCIgOuGtDxRxcQkjrC+xvg5Vkqn7vBUyW -9pHedOU+PoF3DGOM+dqv+eNKBvh9YF9ugFAQBkcG7viZgvGEMGGUpzNgN7XnS1gj -/DPo9mZESOYnKceve2tIC87p2hqjrxOHuI7fkZYeNIcAoa83rBltFXaBDYhWAKS1 -PcXS1/7JzP0ky7d0L6Xbu/If5kqWQpKwUInXtySRkuraVfuK3Bpa+X1XecWi24JY -HVtlNX025xx1ewVzGNCTlWn1skQN2OOoQTV4C8/qFpTW6DTWYurd4+fE0OJFJZQF -buhfXYwmRlVOgN5i77NTIJZJQfYFj38c/Iv5vZBPokO6mffrOTv3MHWVgQARAQAB -tDNSZWQgSGF0LCBJbmMuIChyZWxlYXNlIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0 -LmNvbT6JAjYEEwECACAFAkrgSTsCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK -CRAZni+R/UMdUWzpD/9s5SFR/ZF3yjY5VLUFLMXIKUztNN3oc45fyLdTI3+UClKC -2tEruzYjqNHhqAEXa2sN1fMrsuKec61Ll2NfvJjkLKDvgVIh7kM7aslNYVOP6BTf -C/JJ7/ufz3UZmyViH/WDl+AYdgk3JqCIO5w5ryrC9IyBzYv2m0HqYbWfphY3uHw5 -un3ndLJcu8+BGP5F+ONQEGl+DRH58Il9Jp3HwbRa7dvkPgEhfFR+1hI+Btta2C7E -0/2NKzCxZw7Lx3PBRcU92YKyaEihfy/aQKZCAuyfKiMvsmzs+4poIX7I9NQCJpyE -IGfINoZ7VxqHwRn/d5mw2MZTJjbzSf+Um9YJyA0iEEyD6qjriWQRbuxpQXmlAJbh -8okZ4gbVFv1F8MzK+4R8VvWJ0XxgtikSo72fHjwha7MAjqFnOq6eo6fEC/75g3NL -Ght5VdpGuHk0vbdENHMC8wS99e5qXGNDued3hlTavDMlEAHl34q2H9nakTGRF5Ki -JUfNh3DVRGhg8cMIti21njiRh7gyFI2OccATY7bBSr79JhuNwelHuxLrCFpY7V25 -OFktl15jZJaMxuQBqYdBgSay2G0U6D1+7VsWufpzd/Abx1/c3oi9ZaJvW22kAggq -dzdA27UUYjWvx42w9menJwh/0jeQcTecIUd0d0rFcw/c1pvgMMl/Q73yzKgKYw== -=zbHE ------END PGP PUBLIC KEY BLOCK----- -The following public key can be used to verify RPM packages built and -signed by Red Hat, Inc. This key is a supporting (auxiliary) key for -Red Hat products shipped after November 2006 and for all updates to -those products. - -Questions about this key should be sent to security@redhat.com. - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.2.6 (GNU/Linux) - -mQGiBEVwDGkRBACwPhZIpvkjI8wV9sFTDoqyPLx1ub8Sd/w+YuI5Ovm49mvvEQVT -VLg8FgE5JlST59AbsLDyVtRa9CxIvN5syBVrWWWtHtDnnylFBcqG/A6J3bI4E9/A -UtSL5Zxbav0+utP6f3wOpxQrxc+WIDVgpurdBKAQ3dsobGBqypeX6FXZ5wCgou6C -yZpGIBqosJaDWLzNeOfb/70D/1thLkQyhW3JJ6cHCYJHNfBShvbLWBf6S231mgmu -MyMlt8Kmipc9bw+saaAkSkVsQ/ZbfjrWB7e5kbMruKLVrH+nGhamlHYUGyAPtsPg -Uj/NUSj5BmrCsOkMpn43ngTLssE9MLhSPj2nIHGFv9B+iVLvomDdwnaBRgQ1aK8z -z6MAA/406yf5yVJ/MlTWs1/68VwDhosc9BtU1V5IE0NXgZUAfBJzzfVzzKQq6zJ2 -eZsMLhr96wbsW13zUZt1ing+ulwh2ee4meuJq6h/971JspFY/XBhcfq4qCNqVjsq -SZnWoGdCO6J8CxPIemD2IUHzjoyyeEj3RVydup6pcWZAmhzkKrQzUmVkIEhhdCwg -SW5jLiAoYXV4aWxpYXJ5IGtleSkgPHNlY3VyaXR5QHJlZGhhdC5jb20+iF4EExEC -AB4FAkVwDGkCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQRWiciC+mWOC1rQCg -ooNLCFOzNPcvhd9Za8C801HmnsYAniCw3yzrCqtjYnxDDxlufH0FVTwX -=d/bm ------END PGP PUBLIC KEY BLOCK----- - diff --git a/roles/repos/files/online/epel7-kubernetes.repo b/roles/repos/files/online/epel7-kubernetes.repo deleted file mode 100644 index 1deae2939..000000000 --- a/roles/repos/files/online/epel7-kubernetes.repo +++ /dev/null @@ -1,6 +0,0 @@ -[maxamillion-epel7-kubernetes] -name=Copr repo for epel7-kubernetes owned by maxamillion -baseurl=http://copr-be.cloud.fedoraproject.org/results/maxamillion/epel7-kubernetes/epel-7-$basearch/ -skip_if_unavailable=True -gpgcheck=0 -enabled=1 diff --git a/roles/repos/files/online/epel7-openshift.repo b/roles/repos/files/online/epel7-openshift.repo deleted file mode 100644 index c7629872d..000000000 --- a/roles/repos/files/online/epel7-openshift.repo +++ /dev/null @@ -1,6 +0,0 @@ -[maxamillion-origin-next] -name=Copr repo for origin-next owned by maxamillion -baseurl=http://copr-be.cloud.fedoraproject.org/results/maxamillion/origin-next/epel-7-$basearch/ -skip_if_unavailable=False -gpgcheck=0 -enabled=1 diff --git a/roles/repos/files/online/oso-rhui-rhel-7-extras.repo b/roles/repos/files/online/oso-rhui-rhel-7-extras.repo deleted file mode 100644 index cfe41f691..000000000 --- a/roles/repos/files/online/oso-rhui-rhel-7-extras.repo +++ /dev/null @@ -1,23 +0,0 @@ -[oso-rhui-rhel-server-extras] -name=OpenShift Online RHUI Mirror RH Enterprise Linux - Extras -baseurl=https://gce-mirror1.ops.rhcloud.com/libra/rhui-rhel-server-7-extras/ - https://mirror.ops.rhcloud.com/libra/rhui-rhel-server-7-extras/ -enabled=1 -gpgcheck=1 -gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta -failovermethod=priority -sslverify=False -sslclientcert=/var/lib/yum/client-cert.pem -sslclientkey=/var/lib/yum/client-key.pem - -[oso-rhui-rhel-server-extras-htb] -name=OpenShift Online RHUI Mirror RH Enterprise Linux - Extras HTB -baseurl=https://gce-mirror1.ops.rhcloud.com/libra/rhui-rhel-server-7-extras-htb/ - https://mirror.ops.rhcloud.com/libra/rhui-rhel-server-7-extras-htb/ -enabled=0 -gpgcheck=1 -gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release,file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta -failovermethod=priority -sslverify=False -sslclientcert=/var/lib/yum/client-cert.pem -sslclientkey=/var/lib/yum/client-key.pem diff --git a/roles/repos/files/online/oso-rhui-rhel-7-server.repo b/roles/repos/files/online/oso-rhui-rhel-7-server.repo deleted file mode 100644 index ddc93193d..000000000 --- a/roles/repos/files/online/oso-rhui-rhel-7-server.repo +++ /dev/null @@ -1,21 +0,0 @@ -[oso-rhui-rhel-server-releases] -name=OpenShift Online RHUI Mirror RH Enterprise Linux 7 -baseurl=https://gce-mirror1.ops.rhcloud.com/libra/rhui-rhel-server-7-releases/ - https://mirror.ops.rhcloud.com/libra/rhui-rhel-server-7-releases/ -enabled=1 -gpgcheck=1 -gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release -sslverify=False -sslclientcert=/var/lib/yum/client-cert.pem -sslclientkey=/var/lib/yum/client-key.pem - -[oso-rhui-rhel-server-releases-optional] -name=OpenShift Online RHUI Mirror RH Enterprise Linux 7 - Optional -baseurl=https://gce-mirror1.ops.rhcloud.com/libra/rhui-rhel-server-7-releases-optional/ - https://mirror.ops.rhcloud.com/libra/rhui-rhel-server-7-releases-optional/ -enabled=1 -gpgcheck=1 -gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release -sslverify=False -sslclientcert=/var/lib/yum/client-cert.pem -sslclientkey=/var/lib/yum/client-key.pem diff --git a/roles/repos/files/online/rhel-7-libra-candidate.repo b/roles/repos/files/online/rhel-7-libra-candidate.repo deleted file mode 100644 index b4215679f..000000000 --- a/roles/repos/files/online/rhel-7-libra-candidate.repo +++ /dev/null @@ -1,11 +0,0 @@ -[rhel-7-libra-candidate] -name=rhel-7-libra-candidate - \$basearch -baseurl=https://gce-mirror1.ops.rhcloud.com/libra/rhel-7-libra-candidate/\$basearch/ - https://mirror.ops.rhcloud.com/libra/rhel-7-libra-candidate/\$basearch/ -gpgkey=https://mirror.ops.rhcloud.com/libra/RPM-GPG-KEY-redhat-openshifthosted -skip_if_unavailable=True -gpgcheck=0 -enabled=1 -sslclientcert=/var/lib/yum/client-cert.pem -sslclientkey=/var/lib/yum/client-key.pem -sslverify=False diff --git a/roles/repos/tasks/main.yaml b/roles/repos/tasks/main.yaml deleted file mode 100644 index 43786da41..000000000 --- a/roles/repos/tasks/main.yaml +++ /dev/null @@ -1,41 +0,0 @@ ---- -# TODO: Add flag for enabling EPEL repo, default to false - -- assert: - that: openshift_deployment_type in known_openshift_deployment_types - -# TODO: remove this when origin support actually works -- fail: msg="OpenShift Origin support is not currently enabled" - when: openshift_deployment_type == 'origin' - -- name: Create any additional repos that are defined - template: - src: yum_repo.j2 - dest: /etc/yum.repos.d/openshift_additional.repo - when: openshift_additional_repos | length > 0 - -- name: Remove the additional repos if no longer defined - file: - dest: /etc/yum.repos.d/openshift_additional.repo - state: absent - when: openshift_additional_repos | length == 0 - -- name: Remove any yum repo files for other deployment types - file: - path: "/etc/yum.repos.d/{{ item | basename }}" - state: absent - with_fileglob: - - '*/*' - when: not (item | search("/files/" + openshift_deployment_type + "/")) and (item | search(".repo$")) - -- name: Configure gpg keys if needed - copy: src={{ item }} dest=/etc/pki/rpm-gpg/ - with_fileglob: - - "{{ openshift_deployment_type }}/*" - when: item | basename | match("RPM-GPG-KEY-") - -- name: Configure yum repositories - copy: src={{ item }} dest=/etc/yum.repos.d/ - with_fileglob: - - "{{ openshift_deployment_type }}/*" - when: item | basename | search(".*\.repo$") diff --git a/roles/repos/templates/yum_repo.j2 b/roles/repos/templates/yum_repo.j2 deleted file mode 100644 index 7ea2c7460..000000000 --- a/roles/repos/templates/yum_repo.j2 +++ /dev/null @@ -1,15 +0,0 @@ -# {{ ansible_managed }} -{% for repo in openshift_additional_repos %} -[{{ repo.id }}] -name={{ repo.name | default(repo.id) }} -baseurl={{ repo.baseurl }} -{% set enable_repo = repo.enabled | default('1') %} -enabled={{ 1 if ( enable_repo == 1 or enable_repo == True ) else 0 }} -{% set enable_gpg_check = repo.gpgcheck | default('1') %} -gpgcheck={{ 1 if ( enable_gpg_check == 1 or enable_gpg_check == True ) else 0 }} -{% for key, value in repo.iteritems() %} -{% if key not in ['id', 'name', 'baseurl', 'enabled', 'gpgcheck'] and value is defined %} -{{ key }}={{ value }} -{% endif %} -{% endfor %} -{% endfor %} diff --git a/roles/repos/vars/main.yml b/roles/repos/vars/main.yml deleted file mode 100644 index bbb4c77e7..000000000 --- a/roles/repos/vars/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -known_openshift_deployment_types: ['origin', 'online', 'enterprise'] -- cgit v1.2.3 From 3d4144c56731d3efdfd0c34083256e139f8e9571 Mon Sep 17 00:00:00 2001 From: liangxia Date: Thu, 19 Mar 2015 07:35:21 +0000 Subject: minor fix --- playbooks/aws/openshift-master/config.yml | 2 +- playbooks/aws/openshift-node/config.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/playbooks/aws/openshift-master/config.yml b/playbooks/aws/openshift-master/config.yml index 454cd6f24..0d0e6d5bf 100644 --- a/playbooks/aws/openshift-master/config.yml +++ b/playbooks/aws/openshift-master/config.yml @@ -35,7 +35,7 @@ - { role: openshift_master, openshift_node_ips: "{{ hostvars['localhost'].openshift_node_ips | default(['']) }}", - openshift_env: "{{ oo_env }}" + openshift_env: "{{ oo_env }}", openshift_public_ip: "{{ ec2_ip_address }}" } - pods diff --git a/playbooks/aws/openshift-node/config.yml b/playbooks/aws/openshift-node/config.yml index 9662168c4..317785c84 100644 --- a/playbooks/aws/openshift-node/config.yml +++ b/playbooks/aws/openshift-node/config.yml @@ -43,7 +43,7 @@ role: openshift_node, openshift_master_ips: "{{ hostvars['localhost'].openshift_master_ips | default(['']) }}", openshift_master_public_ips: "{{ hostvars['localhost'].openshift_master_public_ips | default(['']) }}", - openshift_env: "{{ oo_env }}" + openshift_env: "{{ oo_env }}", openshift_public_ip: "{{ ec2_ip_address }}" } - os_env_extras -- cgit v1.2.3 From a90bbd30c6eb962eb9b4cd281823312ee3a95416 Mon Sep 17 00:00:00 2001 From: Dan McPherson Date: Mon, 23 Mar 2015 09:54:34 -0400 Subject: Update README_GCE.md --- README_GCE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README_GCE.md b/README_GCE.md index b00598113..85736e293 100644 --- a/README_GCE.md +++ b/README_GCE.md @@ -4,7 +4,7 @@ GCE Setup Instructions Get a gce service key --------------------- -1. ask your GCE project administrator for a GCE service key +1. Ask your GCE project administrator for a GCE service key Note: If your GCE project does not show a Service Account under /APIs & auth/Credentials, you will need to use "Create new Client ID" to create a Service Account before your administrator can create the service key for you. -- cgit v1.2.3 From fceb54d257ec0e645533e9f20d002f559433662a Mon Sep 17 00:00:00 2001 From: Dan McPherson Date: Mon, 23 Mar 2015 10:14:26 -0400 Subject: Update README_GCE.md --- README_GCE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README_GCE.md b/README_GCE.md index 85736e293..209705113 100644 --- a/README_GCE.md +++ b/README_GCE.md @@ -72,5 +72,5 @@ Test The Setup 3. Try to create an instance: ``` - ./cloud.rb gce launch -n ${USER}-node1 -e int --type os3-node + ./cloud.rb gce launch -e int --type openshift-node ``` -- cgit v1.2.3 From 6bb076355db1eafdf610c96735cfc72d0dac1862 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Mon, 16 Mar 2015 16:48:41 -0400 Subject: Initialized to use tito. --- bin/openshift-ansible-cmds.spec | 34 ++++++++++++++++++++++++++++++++++ rel-eng/packages/.readme | 3 +++ rel-eng/tito.props | 5 +++++ 3 files changed, 42 insertions(+) create mode 100644 bin/openshift-ansible-cmds.spec create mode 100644 rel-eng/packages/.readme create mode 100644 rel-eng/tito.props diff --git a/bin/openshift-ansible-cmds.spec b/bin/openshift-ansible-cmds.spec new file mode 100644 index 000000000..24705ae31 --- /dev/null +++ b/bin/openshift-ansible-cmds.spec @@ -0,0 +1,34 @@ +Summary: OpenShift Operations files for mirror +Name: openshift-ansible-cmds +Version: 0.0.0 +Release: 1%{?dist} +License: ASL 2.0 +URL: https://github.com/openshift/openshift-ansible +Source0: %{name}-%{version}.tar.gz +Requires: python2 +BuildRequires: python2-devel +BuildArch: noarch + +%description +Scripts to make it nicer when working with hosts that are defined only by metadata. + +%prep +%setup -q + +%build + +%install +mkdir -p %{buildroot}/usr/bin +mkdir -p %{buildroot}%{python_sitelib}/openshift_ansible +mkdir -p %{buildroot}/etc/bash_completion.d + +cp -p ossh oscp opssh %{buildroot}/usr/bin +cp -p awsutil.py %{buildroot}%{python_sitelib}/openshift_ansible +cp -p ossh_bash_completion %{buildroot}/etc/bash_completion.d + +%files +/usr/bin/* +%{python_sitelib}/openshift_ansible/* +/etc/bash_completion.d/* + +%changelog diff --git a/rel-eng/packages/.readme b/rel-eng/packages/.readme new file mode 100644 index 000000000..8999c8dbc --- /dev/null +++ b/rel-eng/packages/.readme @@ -0,0 +1,3 @@ +the rel-eng/packages directory contains metadata files +named after their packages. Each file has the latest tagged +version and the project's relative directory. diff --git a/rel-eng/tito.props b/rel-eng/tito.props new file mode 100644 index 000000000..eab3f190d --- /dev/null +++ b/rel-eng/tito.props @@ -0,0 +1,5 @@ +[buildconfig] +builder = tito.builder.Builder +tagger = tito.tagger.VersionTagger +changelog_do_not_remove_cherrypick = 0 +changelog_format = %s (%ae) -- cgit v1.2.3 From 17c69ff4a4b8b905e2db4dac6c9c0e8d1212b23f Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Mon, 16 Mar 2015 16:50:02 -0400 Subject: Automatic commit of package [openshift-ansible-cmds] release [0.0.1-1]. --- bin/README_BUILD | 4 ++++ bin/openshift-ansible-bin.spec | 34 ++++++++++++++++++++++++++++++++++ bin/openshift-ansible-cmds.spec | 34 ---------------------------------- 3 files changed, 38 insertions(+), 34 deletions(-) create mode 100644 bin/README_BUILD create mode 100644 bin/openshift-ansible-bin.spec delete mode 100644 bin/openshift-ansible-cmds.spec diff --git a/bin/README_BUILD b/bin/README_BUILD new file mode 100644 index 000000000..48d4ff4b3 --- /dev/null +++ b/bin/README_BUILD @@ -0,0 +1,4 @@ +# How to build openshift-ansible + + +Test build diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec new file mode 100644 index 000000000..2b83a7d0b --- /dev/null +++ b/bin/openshift-ansible-bin.spec @@ -0,0 +1,34 @@ +Summary: OpenShift Operations files for mirror +Name: openshift-ansible-bin +Version: 0.0.1 +Release: 1%{?dist} +License: ASL 2.0 +URL: https://github.com/openshift/openshift-ansible +Source0: %{name}-%{version}.tar.gz +Requires: python2 +BuildRequires: python2-devel +BuildArch: noarch + +%description +Scripts to make it nicer when working with hosts that are defined only by metadata. + +%prep +%setup -q + +%build + +%install +mkdir -p %{buildroot}/usr/bin +mkdir -p %{buildroot}%{python_sitelib}/openshift_ansible +mkdir -p %{buildroot}/etc/bash_completion.d + +cp -p ossh oscp opssh %{buildroot}/usr/bin +cp -p awsutil.py %{buildroot}%{python_sitelib}/openshift_ansible +cp -p ossh_bash_completion %{buildroot}/etc/bash_completion.d + +%files +/usr/bin/* +%{python_sitelib}/openshift_ansible/* +/etc/bash_completion.d/* + +%changelog diff --git a/bin/openshift-ansible-cmds.spec b/bin/openshift-ansible-cmds.spec deleted file mode 100644 index 24705ae31..000000000 --- a/bin/openshift-ansible-cmds.spec +++ /dev/null @@ -1,34 +0,0 @@ -Summary: OpenShift Operations files for mirror -Name: openshift-ansible-cmds -Version: 0.0.0 -Release: 1%{?dist} -License: ASL 2.0 -URL: https://github.com/openshift/openshift-ansible -Source0: %{name}-%{version}.tar.gz -Requires: python2 -BuildRequires: python2-devel -BuildArch: noarch - -%description -Scripts to make it nicer when working with hosts that are defined only by metadata. - -%prep -%setup -q - -%build - -%install -mkdir -p %{buildroot}/usr/bin -mkdir -p %{buildroot}%{python_sitelib}/openshift_ansible -mkdir -p %{buildroot}/etc/bash_completion.d - -cp -p ossh oscp opssh %{buildroot}/usr/bin -cp -p awsutil.py %{buildroot}%{python_sitelib}/openshift_ansible -cp -p ossh_bash_completion %{buildroot}/etc/bash_completion.d - -%files -/usr/bin/* -%{python_sitelib}/openshift_ansible/* -/etc/bash_completion.d/* - -%changelog -- cgit v1.2.3 From a7e3b2363935fc090ce7a41853ba27ba0050dc23 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Tue, 24 Mar 2015 11:36:30 -0400 Subject: Automatic commit of package [openshift-ansible-bin] release [0.0.1-1]. --- bin/README_BUILD | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/bin/README_BUILD b/bin/README_BUILD index 48d4ff4b3..50010e562 100644 --- a/bin/README_BUILD +++ b/bin/README_BUILD @@ -1,4 +1,25 @@ -# How to build openshift-ansible +# openshift-ansible-bin RPM Build instructions +We use tito to make building and tracking revisions easy. +For more information on tito, please see the [Tito home page](http://rm-rf.ca/tito "Tito home page"). -Test build + +## Build a test package (no tagging needed) +``` +tito build --test --rpm +``` + + +## Tag a new build (bumps version number and adds log entries) +``` +tito tag +``` + +Follow the on screen tito instructions. + + + +## Build a new package based on the latest tag information +``` +tito build --rpm +``` -- cgit v1.2.3 From 7c7cb82fdd5583784fd5832b92886abf86934325 Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Fri, 6 Mar 2015 13:52:20 -0700 Subject: Use ansible playbook to initialize openshift cluster * Added playbooks/gce/openshift-cluster * Added bin/cluster (will replace cluster.sh) --- bin/cluster | 100 +++++++++++++++++++++ playbooks/gce/openshift-cluster/filter_plugins | 1 + playbooks/gce/openshift-cluster/launch.yml | 62 +++++++++++++ .../gce/openshift-cluster/launch_instances.yml | 37 ++++++++ playbooks/gce/openshift-cluster/terminate.yml | 25 ++++++ playbooks/gce/openshift-cluster/vars.yml | 1 + playbooks/gce/openshift-master/config.yml | 13 ++- playbooks/gce/openshift-master/terminate.yml | 2 +- playbooks/gce/openshift-node/config.yml | 12 ++- playbooks/gce/openshift-node/terminate.yml | 2 +- roles/docker/tasks/main.yml | 2 +- roles/openshift_common/tasks/main.yml | 3 + 12 files changed, 253 insertions(+), 7 deletions(-) create mode 100755 bin/cluster create mode 120000 playbooks/gce/openshift-cluster/filter_plugins create mode 100644 playbooks/gce/openshift-cluster/launch.yml create mode 100644 playbooks/gce/openshift-cluster/launch_instances.yml create mode 100644 playbooks/gce/openshift-cluster/terminate.yml create mode 100644 playbooks/gce/openshift-cluster/vars.yml diff --git a/bin/cluster b/bin/cluster new file mode 100755 index 000000000..7afdce0e5 --- /dev/null +++ b/bin/cluster @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# vim: expandtab:tabstop=4:shiftwidth=4 + +import argparse +import ConfigParser +import sys +import os + + +class Cluster(object): + """Python wrapper to ensure environment is correct for running ansible playbooks + """ + + def __init__(self, args): + self.args = args + + # setup ansible ssh environment + if 'ANSIBLE_SSH_ARGS' not in os.environ: + os.environ['ANSIBLE_SSH_ARGS'] = ( + '-o ForwardAgent=yes' + '-o StrictHostKeyChecking=no' + '-o UserKnownHostsFile=/dev/null' + '-o ControlMaster=auto' + '-o ControlPersist=600s' + ) + + def apply(self): + # setup ansible playbook environment + config = ConfigParser.ConfigParser() + if 'gce' == self.args.provider: + config.readfp(open('inventory/gce/gce.ini')) + + for key in config.options('gce'): + os.environ[key] = config.get('gce', key) + + inventory = '-i inventory/gce/gce.py' + elif 'aws' == self.args.provider: + config.readfp(open('inventory/aws/ec2.ini')) + + for key in config.options('ec2'): + os.environ[key] = config.get('ec2', key) + + inventory = '-i inventory/aws/ec2.py' + else: + assert False, "invalid PROVIDER {}".format(self.args.provider) + + env = {'cluster_id': self.args.cluster_id} + + if 'create' == self.args.action: + playbook = "playbooks/{}/openshift-cluster/launch.yml".format(self.args.provider) + env['masters'] = self.args.masters + env['nodes'] = self.args.nodes + + elif 'terminate' == self.args.action: + playbook = "playbooks/{}/openshift-cluster/terminate.yml".format(self.args.provider) + elif 'list' == self.args.action: + # todo: implement cluster list + argparse.ArgumentError("ACTION {} not implemented".format(self.args.action)) + elif 'update' == self.args.action: + # todo: implement cluster update + argparse.ArgumentError("ACTION {} not implemented".format(self.args.action)) + else: + assert False, "invalid ACTION {}".format(self.args.action) + + verbose = '' + if self.args.verbose > 0: + verbose = '-{}'.format('v' * self.args.verbose) + + ansible_env = '-e \'{}\''.format( + ' '.join(['%s=%s' % (key, value) for (key, value) in env.items()]) + ) + + command = 'ansible-playbook {} {} {} {}'.format( + verbose, inventory, ansible_env, playbook + ) + + if self.args.verbose > 1: + command = 'time {}'.format(command) + + if self.args.verbose > 0: + sys.stderr.write('RUN [{}]\n'.format(command)) + sys.stderr.flush() + + os.system(command) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Manage OpenShift Cluster') + parser.add_argument('-p', '--provider', default='gce', choices=['gce', 'aws'], + help='One of the supported cloud providers') + parser.add_argument('-m', '--masters', default=1, type=int, help='number of masters to create in cluster') + parser.add_argument('-n', '--nodes', default=2, type=int, help='number of nodes to create in cluster') + parser.add_argument('-v', '--verbose', action='count', help='Multiple -v options increase the verbosity') + parser.add_argument('--version', action='version', version='%(prog)s 0.1') + parser.add_argument('action', choices=['create', 'terminate', 'update', 'list']) + parser.add_argument('provider', choices=['gce', 'aws']) + parser.add_argument('cluster_id', help='prefix for cluster VM names') + args = parser.parse_args() + + Cluster(args).apply() diff --git a/playbooks/gce/openshift-cluster/filter_plugins b/playbooks/gce/openshift-cluster/filter_plugins new file mode 120000 index 000000000..99a95e4ca --- /dev/null +++ b/playbooks/gce/openshift-cluster/filter_plugins @@ -0,0 +1 @@ +../../../filter_plugins \ No newline at end of file diff --git a/playbooks/gce/openshift-cluster/launch.yml b/playbooks/gce/openshift-cluster/launch.yml new file mode 100644 index 000000000..ba9d58a74 --- /dev/null +++ b/playbooks/gce/openshift-cluster/launch.yml @@ -0,0 +1,62 @@ +--- +- name: Launch instance(s) + hosts: localhost + connection: local + gather_facts: no + + vars_files: + - vars.yml + + tasks: + - set_fact: k8s_type="master" + + - name: "Generate master instance names(s)" + set_fact: scratch="{{ cluster_id }}-{{ k8s_type }}-{{ '%05x' |format( 1048576 |random) }}" + register: instance_names_output + with_sequence: start=1 end={{ masters }} + + # These set_fact's cannot be combined + - set_fact: + instance_names_string: "{% for item in instance_names_output.results %}{{item.ansible_facts.scratch}} {% endfor %}" + + - set_fact: + master_names: "{{ instance_names_string.strip().split(' ') }}" + + - include: launch_instances.yml + vars: + instances: "{{ master_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + group_name: "tag_env-host-type-{{ cluster_id }}-openshift-master" + + - set_fact: k8s_type="node" + + - name: "Generate node instance names(s)" + set_fact: scratch="{{ cluster_id }}-{{ k8s_type }}-{{ '%05x' |format( 1048576 |random) }}" + register: instance_names_output + with_sequence: start=1 end={{ nodes }} + + # These set_fact's cannot be combined + - set_fact: + instance_names_string: "{% for item in instance_names_output.results %}{{item.ansible_facts.scratch}} {% endfor %}" + + - set_fact: + node_names: "{{ instance_names_string.strip().split(' ') }}" + + - include: launch_instances.yml + vars: + instances: "{{ node_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + group_name: "tag_env-host-type-{{ cluster_id }}-openshift-node" + + +- include: ../openshift-master/config.yml + vars: + oo_host_group_exp: "{{ master_names }}" + oo_env: "{{ cluster_id }}" + +- include: ../openshift-node/config.yml + vars: + oo_host_group_exp: "{{ node_names }}" + oo_env: "{{ cluster_id }}" diff --git a/playbooks/gce/openshift-cluster/launch_instances.yml b/playbooks/gce/openshift-cluster/launch_instances.yml new file mode 100644 index 000000000..ff19b94d8 --- /dev/null +++ b/playbooks/gce/openshift-cluster/launch_instances.yml @@ -0,0 +1,37 @@ + +- set_fact: + machine_type: "{{ lookup('env', 'gce_machine_type') |default('n1-standard-1', true) }}" + machine_image: "{{ lookup('env', 'gce_machine_image') |default('libra-rhel7', true) }}" + +- name: Launch instance(s) + gce: + instance_names: "{{ instances }}" + machine_type: "{{ machine_type }}" + image: "{{ machine_image }}" + service_account_email: "{{ lookup('env', 'gce_service_account_email_address') }}" + pem_file: "{{ lookup('env', 'gce_service_account_pem_file_path') }}" + project_id: "{{ lookup('env', 'gce_project_id') }}" + tags: + - "created-by-{{ cluster }}" + - "env-{{ cluster }}" + - "host-type-{{ type }}" + - "env-host-type-{{ cluster }}-openshift-{{ type }}" + register: gce + +- name: Add new instances public IPs + add_host: "hostname={{ item.name }} ansible_ssh_host={{ item.public_ip }} groups={{ group_name }}" + with_items: gce.instance_data + +- name: Wait for ssh + wait_for: "port=22 host={{ item.public_ip }}" + with_items: gce.instance_data + +- debug: var=gce + +- name: Wait for root user setup + command: "ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null root@{{ item.public_ip }} echo root user is setup" + register: result + until: result.rc == 0 + retries: 20 + delay: 10 + with_items: gce.instance_data diff --git a/playbooks/gce/openshift-cluster/terminate.yml b/playbooks/gce/openshift-cluster/terminate.yml new file mode 100644 index 000000000..eff52a807 --- /dev/null +++ b/playbooks/gce/openshift-cluster/terminate.yml @@ -0,0 +1,25 @@ +--- +- name: Terminate instance(s) + hosts: localhost + + vars_files: + - vars.yml + + tasks: + - debug: msg="Retrieve node names" + - debug: msg="Retrieve master names" + - debug: var=groups + +- include: ../openshift-node/terminate.yml + vars: + oo_host_group_exp: 'groups["tag_env-host-type-{{ cluster_id }}-openshift-node"]' + gce_service_account_email: "1043659492591-r0tpbf8q4fbb9dakhjfhj89e4m1ld83t@developer.gserviceaccount.com" + gce_pem_file: "~/.gce/openshift-gce-devel_priv_key.pem" + gce_project_id: "openshift-gce-devel" + +- include: ../openshift-master/terminate.yml + vars: + oo_host_group_exp: 'groups["tag_env-host-type-{{ cluster_id }}-openshift-master"]' + gce_service_account_email: "1043659492591-r0tpbf8q4fbb9dakhjfhj89e4m1ld83t@developer.gserviceaccount.com" + gce_pem_file: "~/.gce/openshift-gce-devel_priv_key.pem" + gce_project_id: "openshift-gce-devel" diff --git a/playbooks/gce/openshift-cluster/vars.yml b/playbooks/gce/openshift-cluster/vars.yml new file mode 100644 index 000000000..ed97d539c --- /dev/null +++ b/playbooks/gce/openshift-cluster/vars.yml @@ -0,0 +1 @@ +--- diff --git a/playbooks/gce/openshift-master/config.yml b/playbooks/gce/openshift-master/config.yml index a74250d13..5581e8401 100644 --- a/playbooks/gce/openshift-master/config.yml +++ b/playbooks/gce/openshift-master/config.yml @@ -1,5 +1,4 @@ ---- -- name: "populate oo_hosts_to_config host group if needed" +- name: "master/config.yml, populate oo_hosts_to_config host group if needed" hosts: localhost gather_facts: no tasks: @@ -13,6 +12,16 @@ connection: ssh user: root +- name: "Retrieve public ip" + hosts: oo_hosts_to_config + connection: ssh + user: root + gather_facts: yes + tasks: + - command: 'curl "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip" -H "Metadata-Flavor: Google"' + register: output + - set_fact: gce_public_ip="{{ output.stdout }}" + - name: "Set Origin specific facts on localhost (for later use)" hosts: localhost gather_facts: no diff --git a/playbooks/gce/openshift-master/terminate.yml b/playbooks/gce/openshift-master/terminate.yml index 76e1404b5..f1345874a 100644 --- a/playbooks/gce/openshift-master/terminate.yml +++ b/playbooks/gce/openshift-master/terminate.yml @@ -12,7 +12,7 @@ - debug: msg="{{ groups['oo_hosts_to_terminate'] }}" -- name: Terminate instances +- name: Terminate master instances hosts: localhost connection: local tasks: diff --git a/playbooks/gce/openshift-node/config.yml b/playbooks/gce/openshift-node/config.yml index 78047cf40..57b9e3198 100644 --- a/playbooks/gce/openshift-node/config.yml +++ b/playbooks/gce/openshift-node/config.yml @@ -1,5 +1,4 @@ ---- -- name: "populate oo_hosts_to_config host group if needed" +- name: "node/config.yml, populate oo_hosts_to_config host group if needed" hosts: localhost gather_facts: no tasks: @@ -12,6 +11,11 @@ hosts: "tag_env-host-type-{{ oo_env }}-openshift-master" connection: ssh user: root + gather_facts: yes + tasks: + - command: 'curl "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip" -H "Metadata-Flavor: Google"' + register: output + - set_fact: gce_public_ip="{{ output.stdout }}" - name: "Set OO sepcific facts on localhost (for later use)" hosts: localhost @@ -36,6 +40,10 @@ user: root vars_files: - vars.yml + + tasks: + - debug: var=gce_public_ip + roles: - { role: openshift_node, diff --git a/playbooks/gce/openshift-node/terminate.yml b/playbooks/gce/openshift-node/terminate.yml index 8d60f27b3..d4555084b 100644 --- a/playbooks/gce/openshift-node/terminate.yml +++ b/playbooks/gce/openshift-node/terminate.yml @@ -12,7 +12,7 @@ - debug: msg="{{ groups['oo_hosts_to_terminate'] }}" -- name: Terminate instances +- name: Terminate node instances hosts: localhost connection: local tasks: diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml index 2ecefd588..ca700db17 100644 --- a/roles/docker/tasks/main.yml +++ b/roles/docker/tasks/main.yml @@ -11,5 +11,5 @@ # From the origin rpm there exists instructions on how to # setup origin properly. The following steps come from there - name: Change root to be in the Docker group - user: name=root groups=docker append=yes + user: name=root groups=dockerroot append=yes diff --git a/roles/openshift_common/tasks/main.yml b/roles/openshift_common/tasks/main.yml index 07737a71f..656a3880d 100644 --- a/roles/openshift_common/tasks/main.yml +++ b/roles/openshift_common/tasks/main.yml @@ -2,6 +2,9 @@ - name: Set hostname hostname: name={{ openshift_hostname }} +- name: Update all packages + yum: name=* state=latest + - name: Configure local facts file file: path=/etc/ansible/facts.d/ state=directory mode=0750 -- cgit v1.2.3 From f6b2eaf7d12ff1f74551662cea46a8bad6beac33 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Fri, 13 Mar 2015 03:02:29 -0400 Subject: Add spacing to implicit string concatenation for python backwards compatibility --- bin/cluster | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/cluster b/bin/cluster index 7afdce0e5..ad6e74577 100755 --- a/bin/cluster +++ b/bin/cluster @@ -18,10 +18,10 @@ class Cluster(object): if 'ANSIBLE_SSH_ARGS' not in os.environ: os.environ['ANSIBLE_SSH_ARGS'] = ( '-o ForwardAgent=yes' - '-o StrictHostKeyChecking=no' - '-o UserKnownHostsFile=/dev/null' - '-o ControlMaster=auto' - '-o ControlPersist=600s' + ' -o StrictHostKeyChecking=no' + ' -o UserKnownHostsFile=/dev/null' + ' -o ControlMaster=auto' + ' -o ControlPersist=600s' ) def apply(self): -- cgit v1.2.3 From 33dda93c3920d9f2df371d71393fb35829c1bdd1 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Fri, 13 Mar 2015 03:49:43 -0400 Subject: add oo_prepend_strings_in_list filter --- filter_plugins/oo_filters.py | 106 +++++++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 44 deletions(-) diff --git a/filter_plugins/oo_filters.py b/filter_plugins/oo_filters.py index b57056375..caf1fd1f0 100644 --- a/filter_plugins/oo_filters.py +++ b/filter_plugins/oo_filters.py @@ -1,39 +1,42 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# vim: expandtab:tabstop=4:shiftwidth=4 + from ansible import errors, runner import json import pdb def oo_pdb(arg): - ''' This pops you into a pdb instance where arg is the data passed in from the filter. + ''' This pops you into a pdb instance where arg is the data passed in from the filter. Ex: "{{ hostvars | oo_pdb }}" - ''' - pdb.set_trace() - return arg + ''' + pdb.set_trace() + return arg def oo_len(arg): - ''' This returns the length of the argument + ''' This returns the length of the argument Ex: "{{ hostvars | oo_len }}" - ''' - return len(arg) + ''' + return len(arg) def get_attr(data, attribute=None): - ''' This looks up dictionary attributes of the form a.b.c and returns the value. + ''' This looks up dictionary attributes of the form a.b.c and returns the value. Ex: data = {'a': {'b': {'c': 5}}} attribute = "a.b.c" returns 5 - ''' - - if not attribute: - raise errors.AnsibleFilterError("|failed expects attribute to be set") + ''' + if not attribute: + raise errors.AnsibleFilterError("|failed expects attribute to be set") - ptr = data - for attr in attribute.split('.'): - ptr = ptr[attr] + ptr = data + for attr in attribute.split('.'): + ptr = ptr[attr] - return ptr + return ptr def oo_collect(data, attribute=None, filters={}): - ''' This takes a list of dict and collects all attributes specified into a list - If filter is specified then we will include all items that match _ALL_ of filters. + ''' This takes a list of dict and collects all attributes specified into a list + If filter is specified then we will include all items that match _ALL_ of filters. Ex: data = [ {'a':1, 'b':5, 'z': 'z'}, # True, return {'a':2, 'z': 'z'}, # True, return {'a':3, 'z': 'z'}, # True, return @@ -42,44 +45,59 @@ def oo_collect(data, attribute=None, filters={}): attribute = 'a' filters = {'z': 'z'} returns [1, 2, 3] - ''' + ''' - if not issubclass(type(data), list): - raise errors.AnsibleFilterError("|failed expects to filter on a List") + if not issubclass(type(data), list): + raise errors.AnsibleFilterError("|failed expects to filter on a List") - if not attribute: - raise errors.AnsibleFilterError("|failed expects attribute to be set") + if not attribute: + raise errors.AnsibleFilterError("|failed expects attribute to be set") - if filters: - retval = [get_attr(d, attribute) for d in data if all([ d[key] == filters[key] for key in filters ]) ] - else: - retval = [get_attr(d, attribute) for d in data] + if filters: + retval = [get_attr(d, attribute) for d in data if all([ d[key] == filters[key] for key in filters ]) ] + else: + retval = [get_attr(d, attribute) for d in data] - return retval + return retval def oo_select_keys(data, keys): - ''' This returns a list, which contains the value portions for the keys + ''' This returns a list, which contains the value portions for the keys Ex: data = { 'a':1, 'b':2, 'c':3 } keys = ['a', 'c'] returns [1, 3] - ''' + ''' + + if not issubclass(type(data), dict): + raise errors.AnsibleFilterError("|failed expects to filter on a Dictionary") - if not issubclass(type(data), dict): - raise errors.AnsibleFilterError("|failed expects to filter on a Dictionary") + if not issubclass(type(keys), list): + raise errors.AnsibleFilterError("|failed expects first param is a list") - if not issubclass(type(keys), list): - raise errors.AnsibleFilterError("|failed expects first param is a list") + # Gather up the values for the list of keys passed in + retval = [data[key] for key in keys] - # Gather up the values for the list of keys passed in - retval = [data[key] for key in keys] + return retval - return retval +def oo_prepend_strings_in_list(data, prepend): + ''' This takes a list of strings and prepends a string to each item in the + list + Ex: data = ['cart', 'tree'] + prepend = 'apple-' + returns ['apple-cart', 'apple-tree'] + ''' + if not issubclass(type(data), list): + raise errors.AnsibleFilterError("|failed expects first param is a list") + if not all(isinstance(x, basestring) for x in data): + raise errors.AnsibleFilterError("|failed expects first param is a list of strings") + retval = [prepend + s for s in data] + return retval class FilterModule (object): - def filters(self): - return { - "oo_select_keys": oo_select_keys, - "oo_collect": oo_collect, - "oo_len": oo_len, - "oo_pdb": oo_pdb - } + def filters(self): + return { + "oo_select_keys": oo_select_keys, + "oo_collect": oo_collect, + "oo_len": oo_len, + "oo_pdb": oo_pdb, + "oo_prepend_strings_in_list": oo_prepend_strings_in_list + } -- cgit v1.2.3 From 66332175b61a5a538aa73b76cbcf151e1882a52c Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Fri, 13 Mar 2015 03:55:04 -0400 Subject: Move yum update * to new os_update_latest role --- roles/openshift_common/tasks/main.yml | 3 --- roles/os_update_latest/tasks/main.yml | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 roles/os_update_latest/tasks/main.yml diff --git a/roles/openshift_common/tasks/main.yml b/roles/openshift_common/tasks/main.yml index 656a3880d..07737a71f 100644 --- a/roles/openshift_common/tasks/main.yml +++ b/roles/openshift_common/tasks/main.yml @@ -2,9 +2,6 @@ - name: Set hostname hostname: name={{ openshift_hostname }} -- name: Update all packages - yum: name=* state=latest - - name: Configure local facts file file: path=/etc/ansible/facts.d/ state=directory mode=0750 diff --git a/roles/os_update_latest/tasks/main.yml b/roles/os_update_latest/tasks/main.yml new file mode 100644 index 000000000..4a2c3d47a --- /dev/null +++ b/roles/os_update_latest/tasks/main.yml @@ -0,0 +1,3 @@ +--- +- name: Update all packages + yum: name=* state=latest -- cgit v1.2.3 From e337235d471468b400acadcbd56ad14f39a2a222 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Fri, 13 Mar 2015 03:56:01 -0400 Subject: add roles symlink to playbooks/gce/openshift-cluster to allow launch to call os_update_latest role --- playbooks/gce/openshift-cluster/roles | 1 + 1 file changed, 1 insertion(+) create mode 120000 playbooks/gce/openshift-cluster/roles diff --git a/playbooks/gce/openshift-cluster/roles b/playbooks/gce/openshift-cluster/roles new file mode 120000 index 000000000..20c4c58cf --- /dev/null +++ b/playbooks/gce/openshift-cluster/roles @@ -0,0 +1 @@ +../../../roles \ No newline at end of file -- cgit v1.2.3 From 9199379f94f6b11a4841e31f6c58a11c1e9f8c3a Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Fri, 13 Mar 2015 03:58:23 -0400 Subject: Various fixes - playbooks/gce/openshift-cluster: - Remove some stray debugging statements - Some minor formatting fixes - removing un-necessary quotes - cleaning up some jinja templates for readability - add a play to the launch playbook to apply the os_update_latest role on all hosts in the new environment - improve setting groups and gce_public_ip when using add_host module - set gce_public_ip as a variable for the host using the returned gce instance_data - add a group for each tag configured on the host (pre-pending tag_ to the tag name) - update the openshift-master/config.yml and openshift-node/config.yml includes to use the tag_env-host-type groups - openshift-{master,node}/config.yml - Some cleanup - remove some extraneous quotes - remove connection: ssh from remote hosts, since it is the default - remove user: root and instead set ansible_ssh_user in inventory/gce/group_vars/all - set openshift_public_ip and openshift_env to templated values in inventory/gce/group_vars/all as well - no longer set openshift_node_ips for the master host, since nodes will register themselves now when they are configured (prevent reboot on adding nodes) - move setting openshift_master_ips and openshift_public_master_ips using set_fact and instead use the vars: of the 'Configure Instances' play --- inventory/gce/group_vars/all | 4 + playbooks/gce/openshift-cluster/launch.yml | 22 +-- .../gce/openshift-cluster/launch_instances.yml | 8 +- playbooks/gce/openshift-master/config.yml | 40 +----- playbooks/gce/openshift-node/config.yml | 148 +++++++++++++++------ 5 files changed, 133 insertions(+), 89 deletions(-) create mode 100644 inventory/gce/group_vars/all diff --git a/inventory/gce/group_vars/all b/inventory/gce/group_vars/all new file mode 100644 index 000000000..4cd94c509 --- /dev/null +++ b/inventory/gce/group_vars/all @@ -0,0 +1,4 @@ +--- +ansible_ssh_user: root +openshift_public_ip: "{{ gce_public_ip }}" +openshift_env: "{{ oo_env }}" diff --git a/playbooks/gce/openshift-cluster/launch.yml b/playbooks/gce/openshift-cluster/launch.yml index ba9d58a74..c70c199c6 100644 --- a/playbooks/gce/openshift-cluster/launch.yml +++ b/playbooks/gce/openshift-cluster/launch.yml @@ -3,21 +3,19 @@ hosts: localhost connection: local gather_facts: no - vars_files: - vars.yml - tasks: - set_fact: k8s_type="master" - - name: "Generate master instance names(s)" - set_fact: scratch="{{ cluster_id }}-{{ k8s_type }}-{{ '%05x' |format( 1048576 |random) }}" + - name: Generate master instance names(s) + set_fact: scratch={{ cluster_id }}-{{ k8s_type }}-{{ '%05x' |format( 1048576 |random) }} register: instance_names_output with_sequence: start=1 end={{ masters }} # These set_fact's cannot be combined - set_fact: - instance_names_string: "{% for item in instance_names_output.results %}{{item.ansible_facts.scratch}} {% endfor %}" + instance_names_string: "{% for item in instance_names_output.results %}{{ item.ansible_facts.scratch }} {% endfor %}" - set_fact: master_names: "{{ instance_names_string.strip().split(' ') }}" @@ -31,14 +29,14 @@ - set_fact: k8s_type="node" - - name: "Generate node instance names(s)" - set_fact: scratch="{{ cluster_id }}-{{ k8s_type }}-{{ '%05x' |format( 1048576 |random) }}" + - name: Generate node instance names(s) + set_fact: scratch={{ cluster_id }}-{{ k8s_type }}-{{ '%05x' |format( 1048576 |random) }} register: instance_names_output with_sequence: start=1 end={{ nodes }} # These set_fact's cannot be combined - set_fact: - instance_names_string: "{% for item in instance_names_output.results %}{{item.ansible_facts.scratch}} {% endfor %}" + instance_names_string: "{% for item in instance_names_output.results %}{{ item.ansible_facts.scratch }} {% endfor %}" - set_fact: node_names: "{{ instance_names_string.strip().split(' ') }}" @@ -48,15 +46,17 @@ instances: "{{ node_names }}" cluster: "{{ cluster_id }}" type: "{{ k8s_type }}" - group_name: "tag_env-host-type-{{ cluster_id }}-openshift-node" +- hosts: "tag_env-{{ cluster_id }}" + roles: + - os_update_latest - include: ../openshift-master/config.yml vars: - oo_host_group_exp: "{{ master_names }}" + oo_host_group_exp: "groups[\"tag_env-host-type-{{ cluster_id }}-openshift-master\"]" oo_env: "{{ cluster_id }}" - include: ../openshift-node/config.yml vars: - oo_host_group_exp: "{{ node_names }}" + oo_host_group_exp: "groups[\"tag_env-host-type-{{ cluster_id }}-openshift-node\"]" oo_env: "{{ cluster_id }}" diff --git a/playbooks/gce/openshift-cluster/launch_instances.yml b/playbooks/gce/openshift-cluster/launch_instances.yml index ff19b94d8..443e763de 100644 --- a/playbooks/gce/openshift-cluster/launch_instances.yml +++ b/playbooks/gce/openshift-cluster/launch_instances.yml @@ -19,15 +19,17 @@ register: gce - name: Add new instances public IPs - add_host: "hostname={{ item.name }} ansible_ssh_host={{ item.public_ip }} groups={{ group_name }}" + add_host: + hostname: "{{ item.name }}" + ansible_ssh_host: "{{ item.public_ip }}" + groups: "{{ item.tags | oo_prepend_strings_in_list('tag_') | join(',') }}" + gce_public_ip: "{{ item.public_ip }}" with_items: gce.instance_data - name: Wait for ssh wait_for: "port=22 host={{ item.public_ip }}" with_items: gce.instance_data -- debug: var=gce - - name: Wait for root user setup command: "ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null root@{{ item.public_ip }} echo root user is setup" register: result diff --git a/playbooks/gce/openshift-master/config.yml b/playbooks/gce/openshift-master/config.yml index 5581e8401..812dcb91b 100644 --- a/playbooks/gce/openshift-master/config.yml +++ b/playbooks/gce/openshift-master/config.yml @@ -1,50 +1,20 @@ -- name: "master/config.yml, populate oo_hosts_to_config host group if needed" +- name: master/config.yml, populate oo_masters_to_config host group if needed hosts: localhost gather_facts: no tasks: - name: "Evaluate oo_host_group_exp if it's set" - add_host: "name={{ item }} groups=oo_hosts_to_config" + add_host: "name={{ item }} groups=oo_masters_to_config" with_items: "{{ oo_host_group_exp | default('') }}" when: oo_host_group_exp is defined - name: "Gather facts for nodes in {{ oo_env }}" hosts: "tag_env-host-type-{{ oo_env }}-openshift-node" - connection: ssh - user: root - -- name: "Retrieve public ip" - hosts: oo_hosts_to_config - connection: ssh - user: root - gather_facts: yes - tasks: - - command: 'curl "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip" -H "Metadata-Flavor: Google"' - register: output - - set_fact: gce_public_ip="{{ output.stdout }}" - -- name: "Set Origin specific facts on localhost (for later use)" - hosts: localhost - gather_facts: no - tasks: - - name: Setting openshift_node_ips fact on localhost - set_fact: - openshift_node_ips: "{{ hostvars - | oo_select_keys(groups['tag_env-host-type-' + oo_env + '-openshift-node']) - | oo_collect(attribute='ansible_default_ipv4.address') }}" - when: groups['tag_env-host-type-' + oo_env + '-openshift-node'] is defined - name: "Configure instances" - hosts: oo_hosts_to_config - connection: ssh - user: root + hosts: oo_masters_to_config vars_files: - - vars.yml + - vars.yml roles: - - { - role: openshift_master, - openshift_node_ips: "{{ hostvars['localhost'].openshift_node_ips | default(['']) }}", - openshift_public_ip: "{{ gce_public_ip }}", - openshift_env: "{{ oo_env }}", - } + - openshift_master - pods - os_env_extras diff --git a/playbooks/gce/openshift-node/config.yml b/playbooks/gce/openshift-node/config.yml index 57b9e3198..17631d578 100644 --- a/playbooks/gce/openshift-node/config.yml +++ b/playbooks/gce/openshift-node/config.yml @@ -1,56 +1,124 @@ -- name: "node/config.yml, populate oo_hosts_to_config host group if needed" +- name: node/config.yml, populate oo_nodes_to_config host group if needed hosts: localhost gather_facts: no tasks: - name: Evaluate oo_host_group_exp - add_host: "name={{ item }} groups=oo_hosts_to_config" + add_host: "name={{ item }} groups=oo_nodes_to_config" with_items: "{{ oo_host_group_exp | default('') }}" when: oo_host_group_exp is defined + - name: Find masters for env + add_host: "name={{ item }} groups=oo_masters_for_node_config" + with_items: groups['tag_env-host-type-' + oo_env + '-openshift-master'] -- name: "Gather facts for masters in {{ oo_env }}" +- name: Gather facts for masters in {{ oo_env }} hosts: "tag_env-host-type-{{ oo_env }}-openshift-master" - connection: ssh - user: root - gather_facts: yes tasks: - - command: 'curl "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip" -H "Metadata-Flavor: Google"' - register: output - - set_fact: gce_public_ip="{{ output.stdout }}" + - set_fact: + openshift_master_ip: "{{ openshift_ip }}" + openshift_master_api_url: "{{ openshift_api_url }}" + openshift_master_webui_url: "{{ openshift_webui_url }}" + openshift_master_hostname: "{{ openshift_hostname }}" + openshift_master_public_ip: "{{ openshift_public_ip }}" + openshift_master_api_public_url: "{{ openshift_api_public_url }}" + openshift_master_webui_public_url: "{{ openshift_webui_public_url }}" + openshift_master_public_hostnames: "{{ openshift_public_hostname }}" -- name: "Set OO sepcific facts on localhost (for later use)" - hosts: localhost - gather_facts: no +- name: Gather facts for hosts to configure + hosts: tag_env-host-type-{{ oo_env }}-openshift-node tasks: - - name: Setting openshift_master_ips fact on localhost - set_fact: - openshift_master_ips: "{{ hostvars - | oo_select_keys(groups['tag_env-host-type-' + oo_env + '-openshift-master']) - | oo_collect(attribute='ansible_default_ipv4.address') }}" - when: groups['tag_env-host-type-' + oo_env + '-openshift-master'] is defined - - name: Setting openshift_master_public_ips fact on localhost - set_fact: - openshift_master_public_ips: "{{ hostvars - | oo_select_keys(groups['tag_env-host-type-' + oo_env + '-openshift-master']) - | oo_collect(attribute='gce_public_ip') }}" - when: groups['tag_env-host-type-' + oo_env + '-openshift-master'] is defined - -- name: "Configure instances" - hosts: oo_hosts_to_config - connection: ssh - user: root - vars_files: - - vars.yml + - set_fact: + openshift_node_hostname: "{{ openshift_hostname }}" + openshift_node_name: "{{ openshift_hostname }}" + openshift_node_cpu: "{{ openshift_node_cpu if openshift_node_cpu else ansible_processor_cores }}" + openshift_node_memory: "{{ openshift_node_memory if openshift_node_memory else (ansible_memtotal_mb|int * 1024 * 1024 * 0.75)|int }}" + openshift_node_pod_cidr: "{{ openshift_node_pod_cidr if openshift_node_pod_cidr else None }}" + openshift_node_host_ip: "{{ openshift_ip }}" + openshift_node_labels: "{{ openshift_node_labels if openshift_node_labels else {} }}" + openshift_node_annotations: "{{ openshift_node_annotations if openshift_node_annotations else {} }}" +- name: Register nodes + hosts: tag_env-host-type-{{ oo_env }}-openshift-master[0] + vars: + openshift_node_group: tag_env-host-type-{{ oo_env }}-openshift-node + openshift_nodes: "{{ hostvars + | oo_select_keys(groups[openshift_node_group]) }}" + openshift_master_group: tag_env-host-type-{{ oo_env }}-openshift-master + openshift_master_urls: "{{ hostvars + | oo_select_keys(groups[openshift_master_group]) + | oo_collect(attribute='openshift_master_api_url') }}" + openshift_master_public_urls: "{{ hostvars + | oo_select_keys(groups[openshift_master_group]) + | oo_collect(attribute='openshift_master_api_public_url') }}" + pre_tasks: + roles: + - openshift_register_nodes tasks: - - debug: var=gce_public_ip + - name: Create local temp directory for syncing certs + local_action: command /usr/bin/mktemp -d /tmp/openshift-ansible-XXXXXXX + register: mktemp + - name: Sync master certs to localhost + synchronize: + mode: pull + checksum: yes + src: /var/lib/openshift/openshift.local.certificates + dest: "{{ mktemp.stdout }}" + +# TODO: sync generated certs between masters +# +- name: Configure instances + hosts: oo_nodes_to_config + vars_files: + - vars.yml + vars: + openshift_master_group: tag_env-host-type-{{ oo_env }}-openshift-master + openshift_master_ips: "{{ hostvars + | oo_select_keys(groups[openshift_master_group]) + | oo_collect(attribute='openshift_master_ip') }}" + openshift_master_hostnames: "{{ hostvars + | oo_select_keys(groups[openshift_master_group]) + | oo_collect(attribute='openshift_master_hostname') }}" + openshift_master_public_ips: "{{ hostvars + | oo_select_keys(groups[openshift_master_group]) + | oo_collect(attribute='openshift_master_public_ip') }}" + openshift_master_public_hostnames: "{{ hostvars + | oo_select_keys(groups[openshift_master_group]) + | oo_collect(attribute='openshift_master_public_hostname') }}" + cert_parent_rel_path: openshift.local.certificates + cert_rel_path: "{{ cert_parent_rel_path }}/node-{{ openshift_node_name }}" + cert_base_path: /var/lib/openshift + cert_parent_path: "{{ cert_base_path }}/{{ cert_parent_rel_path }}" + cert_path: "{{ cert_base_path }}/{{ cert_rel_path }}" + pre_tasks: + - name: Ensure certificate directories exists + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ cert_path }}" + - "{{ cert_parent_path }}/ca" + + # TODO: only sync to a node if it's certs have been updated + # TODO: notify restart openshift-node and/or restart openshift-sdn-node, + # possibly test service started time against certificate/config file + # timestamps in openshift-node or openshift-sdn-node to trigger notify + # TODO: also copy ca cert: /var/lib/openshift/openshift.local.certificates/ca/cert.crt + - name: Sync certs to nodes + synchronize: + checksum: yes + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: no + group: no + with_items: + - src: "{{ hostvars[groups[openshift_master_group][0]].mktemp.stdout }}/{{ cert_rel_path }}" + dest: "{{ cert_parent_path }}" + - src: "{{ hostvars[groups[openshift_master_group][0]].mktemp.stdout }}/{{ cert_parent_rel_path }}/ca/cert.crt" + dest: "{{ cert_parent_path }}/ca/cert.crt" + - local_action: file name={{ hostvars[groups[openshift_master_group][0]].mktemp.stdout }} state=absent + run_once: true roles: - - { - role: openshift_node, - openshift_master_ips: "{{ hostvars['localhost'].openshift_master_ips | default(['']) }}", - openshift_master_public_ips: "{{ hostvars['localhost'].openshift_master_public_ips | default(['']) }}", - openshift_public_ip: "{{ gce_public_ip }}", - openshift_env: "{{ oo_env }}", - } - - docker + - openshift_node - os_env_extras + - os_env_extras_node + -- cgit v1.2.3 From 3324b6c8889074ee17d7be05588de8b58aa3774f Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Fri, 6 Mar 2015 13:52:20 -0700 Subject: Use ansible playbook to initialize openshift cluster * Added playbooks/gce/openshift-cluster * Added bin/cluster (will replace cluster.sh) --- playbooks/gce/openshift-node/config.yml | 1 + roles/openshift_common/tasks/main.yml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/playbooks/gce/openshift-node/config.yml b/playbooks/gce/openshift-node/config.yml index 17631d578..7f80b90a7 100644 --- a/playbooks/gce/openshift-node/config.yml +++ b/playbooks/gce/openshift-node/config.yml @@ -53,6 +53,7 @@ roles: - openshift_register_nodes tasks: + tasks: - name: Create local temp directory for syncing certs local_action: command /usr/bin/mktemp -d /tmp/openshift-ansible-XXXXXXX register: mktemp diff --git a/roles/openshift_common/tasks/main.yml b/roles/openshift_common/tasks/main.yml index 07737a71f..656a3880d 100644 --- a/roles/openshift_common/tasks/main.yml +++ b/roles/openshift_common/tasks/main.yml @@ -2,6 +2,9 @@ - name: Set hostname hostname: name={{ openshift_hostname }} +- name: Update all packages + yum: name=* state=latest + - name: Configure local facts file file: path=/etc/ansible/facts.d/ state=directory mode=0750 -- cgit v1.2.3 From 12745f3eb1f4eb99a27f03d6b7a60cd376add580 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Mon, 16 Mar 2015 15:12:10 -0400 Subject: Use env for gce params --- playbooks/gce/openshift-cluster/terminate.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/playbooks/gce/openshift-cluster/terminate.yml b/playbooks/gce/openshift-cluster/terminate.yml index eff52a807..ee536be69 100644 --- a/playbooks/gce/openshift-cluster/terminate.yml +++ b/playbooks/gce/openshift-cluster/terminate.yml @@ -13,13 +13,13 @@ - include: ../openshift-node/terminate.yml vars: oo_host_group_exp: 'groups["tag_env-host-type-{{ cluster_id }}-openshift-node"]' - gce_service_account_email: "1043659492591-r0tpbf8q4fbb9dakhjfhj89e4m1ld83t@developer.gserviceaccount.com" - gce_pem_file: "~/.gce/openshift-gce-devel_priv_key.pem" - gce_project_id: "openshift-gce-devel" + gce_service_account_email: "{{ lookup('env', 'gce_service_account_email_address') }}" + gce_pem_file: "{{ lookup('env', 'gce_service_account_pem_file_path') }}" + gce_project_id: "{{ lookup('env', 'gce_project_id') }}" - include: ../openshift-master/terminate.yml vars: oo_host_group_exp: 'groups["tag_env-host-type-{{ cluster_id }}-openshift-master"]' - gce_service_account_email: "1043659492591-r0tpbf8q4fbb9dakhjfhj89e4m1ld83t@developer.gserviceaccount.com" - gce_pem_file: "~/.gce/openshift-gce-devel_priv_key.pem" - gce_project_id: "openshift-gce-devel" + gce_service_account_email: "{{ lookup('env', 'gce_service_account_email_address') }}" + gce_pem_file: "{{ lookup('env', 'gce_service_account_pem_file_path') }}" + gce_project_id: "{{ lookup('env', 'gce_project_id') }}" -- cgit v1.2.3 From 6ad94864f7d985f1bb671536bd398ea4bcd0f163 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Mon, 16 Mar 2015 15:13:12 -0400 Subject: add repos role to gce cluster launch so that we are applying os_update_latest after repo config --- playbooks/gce/openshift-cluster/launch.yml | 1 + roles/openshift_common/tasks/main.yml | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/playbooks/gce/openshift-cluster/launch.yml b/playbooks/gce/openshift-cluster/launch.yml index c70c199c6..70025e103 100644 --- a/playbooks/gce/openshift-cluster/launch.yml +++ b/playbooks/gce/openshift-cluster/launch.yml @@ -49,6 +49,7 @@ - hosts: "tag_env-{{ cluster_id }}" roles: + - repos - os_update_latest - include: ../openshift-master/config.yml diff --git a/roles/openshift_common/tasks/main.yml b/roles/openshift_common/tasks/main.yml index 656a3880d..07737a71f 100644 --- a/roles/openshift_common/tasks/main.yml +++ b/roles/openshift_common/tasks/main.yml @@ -2,9 +2,6 @@ - name: Set hostname hostname: name={{ openshift_hostname }} -- name: Update all packages - yum: name=* state=latest - - name: Configure local facts file file: path=/etc/ansible/facts.d/ state=directory mode=0750 -- cgit v1.2.3 From 13dc8505feb93adc311a4a2d8e714c7d1e61cf1f Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Mon, 16 Mar 2015 15:15:03 -0400 Subject: Fix openshift_master_ips and openshift_master_public_ips resolution - don't use set_fact on localhost for openshift_master_ips and openshift_master_public_ips - we are only using it for the configure play - move definition to vars section of configure play - otherwise we'd have to set openshift_master_ips and openshift_master_public_ips from hostvars['localhost'] and since we aren't refrerencing it anywhere else, might as well just do it in vars instead of set_fact on locahost. --- playbooks/gce/openshift-node/config.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/playbooks/gce/openshift-node/config.yml b/playbooks/gce/openshift-node/config.yml index 7f80b90a7..9d87c4e8f 100644 --- a/playbooks/gce/openshift-node/config.yml +++ b/playbooks/gce/openshift-node/config.yml @@ -53,7 +53,6 @@ roles: - openshift_register_nodes tasks: - tasks: - name: Create local temp directory for syncing certs local_action: command /usr/bin/mktemp -d /tmp/openshift-ansible-XXXXXXX register: mktemp @@ -69,7 +68,7 @@ # - name: Configure instances hosts: oo_nodes_to_config - vars_files: +vars_files: - vars.yml vars: openshift_master_group: tag_env-host-type-{{ oo_env }}-openshift-master -- cgit v1.2.3 From 9575258e5a1b8f9ee8ec7ffc7ad74fa5dfeabc00 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Wed, 18 Mar 2015 13:25:18 -0400 Subject: replace oo_hosts_to_config with oo_nodes_to_config and oo_masters_to_config --- playbooks/aws/openshift-master/config.yml | 6 +++--- playbooks/aws/openshift-master/launch.yml | 4 ++-- playbooks/aws/openshift-node/config.yml | 6 +++--- playbooks/aws/openshift-node/launch.yml | 4 ++-- playbooks/gce/openshift-master/launch.yml | 4 ++-- playbooks/gce/openshift-node/config.yml | 1 - playbooks/gce/openshift-node/launch.yml | 8 ++++---- 7 files changed, 16 insertions(+), 17 deletions(-) diff --git a/playbooks/aws/openshift-master/config.yml b/playbooks/aws/openshift-master/config.yml index b3227afa9..bbf1f654a 100644 --- a/playbooks/aws/openshift-master/config.yml +++ b/playbooks/aws/openshift-master/config.yml @@ -1,10 +1,10 @@ --- -- name: "populate oo_hosts_to_config host group if needed" +- name: "populate oo_masters_to_config host group if needed" hosts: localhost gather_facts: no tasks: - name: "Evaluate oo_host_group_exp if it's set" - add_host: "name={{ item }} groups=oo_hosts_to_config" + add_host: "name={{ item }} groups=oo_masters_to_config" with_items: "{{ oo_host_group_exp | default('') }}" when: oo_host_group_exp is defined @@ -25,7 +25,7 @@ when: groups['tag_env-host-type_' + oo_env + '-openshift-node'] is defined - name: "Configure instances" - hosts: oo_hosts_to_config + hosts: oo_masters_to_config connection: ssh user: root vars_files: diff --git a/playbooks/aws/openshift-master/launch.yml b/playbooks/aws/openshift-master/launch.yml index a889b93be..3d5a7f579 100644 --- a/playbooks/aws/openshift-master/launch.yml +++ b/playbooks/aws/openshift-master/launch.yml @@ -45,8 +45,8 @@ args: tags: "{{ oo_new_inst_tags }}" - - name: Add new instances public IPs to oo_hosts_to_config - add_host: "hostname={{ item.0 }} ansible_ssh_host={{ item.1.dns_name }} groupname=oo_hosts_to_config" + - name: Add new instances public IPs to oo_masters_to_config + add_host: "hostname={{ item.0 }} ansible_ssh_host={{ item.1.dns_name }} groupname=oo_masters_to_config" with_together: - oo_new_inst_names - ec2.instances diff --git a/playbooks/aws/openshift-node/config.yml b/playbooks/aws/openshift-node/config.yml index 21807b1cf..822b66464 100644 --- a/playbooks/aws/openshift-node/config.yml +++ b/playbooks/aws/openshift-node/config.yml @@ -1,10 +1,10 @@ --- -- name: "populate oo_hosts_to_config host group if needed" +- name: "populate oo_nodes_to_config host group if needed" hosts: localhost gather_facts: no tasks: - name: Evaluate oo_host_group_exp - add_host: "name={{ item }} groups=oo_hosts_to_config" + add_host: "name={{ item }} groups=oo_nodes_to_config" with_items: "{{ oo_host_group_exp | default('') }}" when: oo_host_group_exp is defined @@ -31,7 +31,7 @@ when: groups['tag_env-host-type-' + oo_env + '-openshift-master'] is defined - name: "Configure instances" - hosts: oo_hosts_to_config + hosts: oo_nodes_to_config connection: ssh user: root vars_files: diff --git a/playbooks/aws/openshift-node/launch.yml b/playbooks/aws/openshift-node/launch.yml index a889b93be..4745fc658 100644 --- a/playbooks/aws/openshift-node/launch.yml +++ b/playbooks/aws/openshift-node/launch.yml @@ -45,8 +45,8 @@ args: tags: "{{ oo_new_inst_tags }}" - - name: Add new instances public IPs to oo_hosts_to_config - add_host: "hostname={{ item.0 }} ansible_ssh_host={{ item.1.dns_name }} groupname=oo_hosts_to_config" + - name: Add new instances public IPs to oo_nodes_to_config + add_host: "hostname={{ item.0 }} ansible_ssh_host={{ item.1.dns_name }} groupname=oo_nodes_to_config" with_together: - oo_new_inst_names - ec2.instances diff --git a/playbooks/gce/openshift-master/launch.yml b/playbooks/gce/openshift-master/launch.yml index f2800b061..3512274cc 100644 --- a/playbooks/gce/openshift-master/launch.yml +++ b/playbooks/gce/openshift-master/launch.yml @@ -24,8 +24,8 @@ tags: "{{ oo_new_inst_tags }}" register: gce - - name: Add new instances public IPs to oo_hosts_to_config - add_host: "hostname={{ item.name }} ansible_ssh_host={{ item.public_ip }} groupname=oo_hosts_to_config" + - name: Add new instances public IPs to oo_masters_to_config + add_host: "hostname={{ item.name }} ansible_ssh_host={{ item.public_ip }} groupname=oo_masters_to_config" with_items: gce.instance_data - name: Wait for ssh diff --git a/playbooks/gce/openshift-node/config.yml b/playbooks/gce/openshift-node/config.yml index 9d87c4e8f..d24acb8fa 100644 --- a/playbooks/gce/openshift-node/config.yml +++ b/playbooks/gce/openshift-node/config.yml @@ -121,4 +121,3 @@ vars_files: - openshift_node - os_env_extras - os_env_extras_node - diff --git a/playbooks/gce/openshift-node/launch.yml b/playbooks/gce/openshift-node/launch.yml index 935599efd..ca2914d8a 100644 --- a/playbooks/gce/openshift-node/launch.yml +++ b/playbooks/gce/openshift-node/launch.yml @@ -24,8 +24,8 @@ tags: "{{ oo_new_inst_tags }}" register: gce - - name: Add new instances public IPs to oo_hosts_to_config - add_host: "hostname={{ item.name }} ansible_ssh_host={{ item.public_ip }} groupname=oo_hosts_to_config" + - name: Add new instances public IPs to oo_nodes_to_config + add_host: "hostname={{ item.name }} ansible_ssh_host={{ item.public_ip }} groupname=oo_nodes_to_config" with_items: gce.instance_data - name: Wait for ssh @@ -48,10 +48,10 @@ # Always bounce service to pick up new credentials #- name: "Restart instances" -# hosts: oo_hosts_to_config +# hosts: oo_nodes_to_config # connection: ssh # user: root # tasks: -# - debug: var=groups.oo_hosts_to_config +# - debug: var=groups.oo_nodes_to_config # - name: Restart OpenShift # service: name=openshift-node enabled=yes state=restarted -- cgit v1.2.3 From 011ff923489fd1dd5fa072a685ce881ab69b8f1c Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Wed, 18 Mar 2015 13:26:46 -0400 Subject: use more specific variable names in gce/openshift-cluster/launch.yml --- playbooks/gce/openshift-cluster/launch.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/playbooks/gce/openshift-cluster/launch.yml b/playbooks/gce/openshift-cluster/launch.yml index 70025e103..b30452725 100644 --- a/playbooks/gce/openshift-cluster/launch.yml +++ b/playbooks/gce/openshift-cluster/launch.yml @@ -10,15 +10,15 @@ - name: Generate master instance names(s) set_fact: scratch={{ cluster_id }}-{{ k8s_type }}-{{ '%05x' |format( 1048576 |random) }} - register: instance_names_output + register: master_names_output with_sequence: start=1 end={{ masters }} # These set_fact's cannot be combined - set_fact: - instance_names_string: "{% for item in instance_names_output.results %}{{ item.ansible_facts.scratch }} {% endfor %}" + master_names_string: "{% for item in master_names_output.results %}{{ item.ansible_facts.scratch }} {% endfor %}" - set_fact: - master_names: "{{ instance_names_string.strip().split(' ') }}" + master_names: "{{ master_names_string.strip().split(' ') }}" - include: launch_instances.yml vars: @@ -31,15 +31,15 @@ - name: Generate node instance names(s) set_fact: scratch={{ cluster_id }}-{{ k8s_type }}-{{ '%05x' |format( 1048576 |random) }} - register: instance_names_output + register: node_names_output with_sequence: start=1 end={{ nodes }} # These set_fact's cannot be combined - set_fact: - instance_names_string: "{% for item in instance_names_output.results %}{{ item.ansible_facts.scratch }} {% endfor %}" + node_names_string: "{% for item in node_names_output.results %}{{ item.ansible_facts.scratch }} {% endfor %}" - set_fact: - node_names: "{{ instance_names_string.strip().split(' ') }}" + node_names: "{{ node_names_string.strip().split(' ') }}" - include: launch_instances.yml vars: -- cgit v1.2.3 From 85e6948fca954d3c066bf5a6123ada6b96adf45c Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Thu, 19 Mar 2015 15:06:38 -0700 Subject: * Add DOCKER chain to iptables --- README.md | 2 +- playbooks/gce/openshift-cluster/terminate.yml | 5 ----- roles/os_firewall/tasks/firewall/iptables.yml | 14 ++++++++++++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ffdfee6f2..906d2e3f2 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Setup - Directory Structure: - [cloud.rb](cloud.rb) - light wrapper around Ansible - - [cluster.sh](cluster.sh) - easily create OpenShift 3 clusters + - [bin/cluster](bin/cluster) - python script to easily create OpenShift 3 clusters - [filter_plugins/](filter_plugins) - custom filters used to manipulate data in Ansible - [inventory/](inventory) - houses Ansible dynamic inventory scripts - [lib/](lib) - library components of cloud.rb diff --git a/playbooks/gce/openshift-cluster/terminate.yml b/playbooks/gce/openshift-cluster/terminate.yml index ee536be69..0281ae953 100644 --- a/playbooks/gce/openshift-cluster/terminate.yml +++ b/playbooks/gce/openshift-cluster/terminate.yml @@ -5,11 +5,6 @@ vars_files: - vars.yml - tasks: - - debug: msg="Retrieve node names" - - debug: msg="Retrieve master names" - - debug: var=groups - - include: ../openshift-node/terminate.yml vars: oo_host_group_exp: 'groups["tag_env-host-type-{{ cluster_id }}-openshift-node"]' diff --git a/roles/os_firewall/tasks/firewall/iptables.yml b/roles/os_firewall/tasks/firewall/iptables.yml index 87e77c083..3d46d6e2d 100644 --- a/roles/os_firewall/tasks/firewall/iptables.yml +++ b/roles/os_firewall/tasks/firewall/iptables.yml @@ -41,6 +41,20 @@ changed_when: "'firewalld' in result.stdout" when: pkg_check.rc == 0 +- name: Check for DOCKER chain + shell: iptables -L |grep '^Chain DOCKER' + ignore_errors: yes + register: check_for_chain + +- name: Create DOCKER chain + command: iptables -N DOCKER + register: create_chain + when: check_for_chain.rc != 0 + +- name: Persist DOCKER chain + command: service iptables save + when: create_chain.rc == 0 + - name: Add iptables allow rules os_firewall_manage_iptables: name: "{{ item.service }}" -- cgit v1.2.3 From 9fb5bbc79a6753c6125e4f3ea007040dad0482ef Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Thu, 19 Mar 2015 23:04:21 -0400 Subject: Add verify_chain action to os_firewall_manage_iptables module - Add verify_chain action to os_firewall_manage_iptables module - Update os_firewall module to use os_firewall_manage_iptables for creating the DOCKER chain. --- .../library/os_firewall_manage_iptables.py | 62 ++++++++++++++-------- roles/os_firewall/tasks/firewall/iptables.yml | 20 +++---- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/roles/os_firewall/library/os_firewall_manage_iptables.py b/roles/os_firewall/library/os_firewall_manage_iptables.py index fef710055..6a018d022 100644 --- a/roles/os_firewall/library/os_firewall_manage_iptables.py +++ b/roles/os_firewall/library/os_firewall_manage_iptables.py @@ -51,11 +51,13 @@ class IpTablesCreateJumpRuleError(IpTablesError): # exception was thrown later. for example, when the chain is created # successfully, but the add/remove rule fails. class IpTablesManager: - def __init__(self, module, ip_version, check_mode, chain): + def __init__(self, module): self.module = module - self.ip_version = ip_version - self.check_mode = check_mode - self.chain = chain + self.ip_version = module.params['ip_version'] + self.check_mode = module.check_mode + self.chain = module.params['chain'] + self.create_jump_rule = module.params['create_jump_rule'] + self.jump_rule_chain = module.params['jump_rule_chain'] self.cmd = self.gen_cmd() self.save_cmd = self.gen_save_cmd() self.output = [] @@ -70,13 +72,16 @@ class IpTablesManager: msg="Failed to save iptables rules", cmd=e.cmd, exit_code=e.returncode, output=e.output) + def verify_chain(self): + if not self.chain_exists(): + self.create_chain() + if self.create_jump_rule and not self.jump_rule_exists(): + self.create_jump() + def add_rule(self, port, proto): rule = self.gen_rule(port, proto) if not self.rule_exists(rule): - if not self.chain_exists(): - self.create_chain() - if not self.jump_rule_exists(): - self.create_jump_rule() + self.verify_chain() if self.check_mode: self.changed = True @@ -121,13 +126,13 @@ class IpTablesManager: return [self.chain, '-p', proto, '-m', 'state', '--state', 'NEW', '-m', proto, '--dport', str(port), '-j', 'ACCEPT'] - def create_jump_rule(self): + def create_jump(self): if self.check_mode: self.changed = True self.output.append("Create jump rule for chain %s" % self.chain) else: try: - cmd = self.cmd + ['-L', 'INPUT', '--line-numbers'] + cmd = self.cmd + ['-L', self.jump_rule_chain, '--line-numbers'] output = check_output(cmd, stderr=subprocess.STDOUT) # break the input rules into rows and columns @@ -144,11 +149,11 @@ class IpTablesManager: continue last_rule_target = rule[1] - # Raise an exception if we do not find a valid INPUT rule + # Raise an exception if we do not find a valid rule if not last_rule_num or not last_rule_target: raise IpTablesCreateJumpRuleError( chain=self.chain, - msg="Failed to find existing INPUT rules", + msg="Failed to find existing %s rules" % self.jump_rule_chain, cmd=None, exit_code=None, output=None) # Naively assume that if the last row is a REJECT rule, then @@ -156,19 +161,20 @@ class IpTablesManager: # assume that we can just append the rule. if last_rule_target == 'REJECT': # insert rule - cmd = self.cmd + ['-I', 'INPUT', str(last_rule_num)] + cmd = self.cmd + ['-I', self.jump_rule_chain, str(last_rule_num)] else: # append rule - cmd = self.cmd + ['-A', 'INPUT'] + cmd = self.cmd + ['-A', self.jump_rule_chain] cmd += ['-j', self.chain] output = check_output(cmd, stderr=subprocess.STDOUT) changed = True self.output.append(output) + self.save() except subprocess.CalledProcessError as e: if '--line-numbers' in e.cmd: raise IpTablesCreateJumpRuleError( chain=self.chain, - msg="Failed to query existing INPUT rules to " + msg="Failed to query existing %s rules to " % self.jump_rule_chain + "determine jump rule location", cmd=e.cmd, exit_code=e.returncode, output=e.output) @@ -192,6 +198,7 @@ class IpTablesManager: self.changed = True self.output.append("Successfully created chain %s" % self.chain) + self.save() except subprocess.CalledProcessError as e: raise IpTablesCreateChainError( chain=self.chain, @@ -200,7 +207,7 @@ class IpTablesManager: ) def jump_rule_exists(self): - cmd = self.cmd + ['-C', 'INPUT', '-j', self.chain] + cmd = self.cmd + ['-C', self.jump_rule_chain, '-j', self.chain] return True if subprocess.call(cmd) == 0 else False def chain_exists(self): @@ -220,9 +227,12 @@ def main(): module = AnsibleModule( argument_spec=dict( name=dict(required=True), - action=dict(required=True, choices=['add', 'remove']), - protocol=dict(required=True, choices=['tcp', 'udp']), - port=dict(required=True, type='int'), + action=dict(required=True, choices=['add', 'remove', 'verify_chain']), + chain=dict(required=False, default='OS_FIREWALL_ALLOW'), + create_jump_rule=dict(required=False, type='bool', default=True), + jump_rule_chain=dict(required=False, default='INPUT'), + protocol=dict(required=False, choices=['tcp', 'udp']), + port=dict(required=False, type='int'), ip_version=dict(required=False, default='ipv4', choices=['ipv4', 'ipv6']), ), @@ -232,16 +242,24 @@ def main(): action = module.params['action'] protocol = module.params['protocol'] port = module.params['port'] - ip_version = module.params['ip_version'] - chain = 'OS_FIREWALL_ALLOW' - iptables_manager = IpTablesManager(module, ip_version, module.check_mode, chain) + if action in ['add', 'remove']: + if not protocol: + error = "protocol is required when action is %s" % action + module.fail_json(msg=error) + if not port: + error = "port is required when action is %s" % action + module.fail_json(msg=error) + + iptables_manager = IpTablesManager(module) try: if action == 'add': iptables_manager.add_rule(port, protocol) elif action == 'remove': iptables_manager.remove_rule(port, protocol) + elif action == 'verify_chain': + iptables_manager.verify_chain() except IpTablesError as e: module.fail_json(msg=e.msg) diff --git a/roles/os_firewall/tasks/firewall/iptables.yml b/roles/os_firewall/tasks/firewall/iptables.yml index 3d46d6e2d..72a3401cf 100644 --- a/roles/os_firewall/tasks/firewall/iptables.yml +++ b/roles/os_firewall/tasks/firewall/iptables.yml @@ -41,19 +41,13 @@ changed_when: "'firewalld' in result.stdout" when: pkg_check.rc == 0 -- name: Check for DOCKER chain - shell: iptables -L |grep '^Chain DOCKER' - ignore_errors: yes - register: check_for_chain - -- name: Create DOCKER chain - command: iptables -N DOCKER - register: create_chain - when: check_for_chain.rc != 0 - -- name: Persist DOCKER chain - command: service iptables save - when: create_chain.rc == 0 +# Workaround for Docker 1.4 to create DOCKER chain +- name: Add DOCKER chain + os_firewall_manage_iptables: + name: "DOCKER chain" + action: verify_chain + create_jump_rule: no +# End of Docker 1.4 workaround - name: Add iptables allow rules os_firewall_manage_iptables: -- cgit v1.2.3 From 2147b1608140f2688ac9781b394824c04e55d07e Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Fri, 20 Mar 2015 09:31:05 -0700 Subject: * Updates from code reviews --- bin/cluster | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/bin/cluster b/bin/cluster index ad6e74577..ce17ee6d7 100755 --- a/bin/cluster +++ b/bin/cluster @@ -42,6 +42,7 @@ class Cluster(object): inventory = '-i inventory/aws/ec2.py' else: + # this code should never be reached assert False, "invalid PROVIDER {}".format(self.args.provider) env = {'cluster_id': self.args.cluster_id} @@ -55,11 +56,12 @@ class Cluster(object): playbook = "playbooks/{}/openshift-cluster/terminate.yml".format(self.args.provider) elif 'list' == self.args.action: # todo: implement cluster list - argparse.ArgumentError("ACTION {} not implemented".format(self.args.action)) + raise argparse.ArgumentError("ACTION {} not implemented".format(self.args.action)) elif 'update' == self.args.action: # todo: implement cluster update - argparse.ArgumentError("ACTION {} not implemented".format(self.args.action)) + raise argparse.ArgumentError("ACTION {} not implemented".format(self.args.action)) else: + # this code should never be reached assert False, "invalid ACTION {}".format(self.args.action) verbose = '' @@ -81,13 +83,14 @@ class Cluster(object): sys.stderr.write('RUN [{}]\n'.format(command)) sys.stderr.flush() - os.system(command) + error = os.system(command) + if error != 0: + raise Exception("Ansible run failed with exit code %d".format(error)) + if __name__ == '__main__': parser = argparse.ArgumentParser(description='Manage OpenShift Cluster') - parser.add_argument('-p', '--provider', default='gce', choices=['gce', 'aws'], - help='One of the supported cloud providers') parser.add_argument('-m', '--masters', default=1, type=int, help='number of masters to create in cluster') parser.add_argument('-n', '--nodes', default=2, type=int, help='number of nodes to create in cluster') parser.add_argument('-v', '--verbose', action='count', help='Multiple -v options increase the verbosity') -- cgit v1.2.3 From 14b19e665b118349327a5c8c219cc49c96ae1d52 Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Fri, 20 Mar 2015 09:36:34 -0700 Subject: * Replace asserts with raises --- bin/cluster | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/cluster b/bin/cluster index ce17ee6d7..af908155c 100755 --- a/bin/cluster +++ b/bin/cluster @@ -43,7 +43,7 @@ class Cluster(object): inventory = '-i inventory/aws/ec2.py' else: # this code should never be reached - assert False, "invalid PROVIDER {}".format(self.args.provider) + raise argparse.ArgumentError("invalid PROVIDER {}".format(self.args.provider)) env = {'cluster_id': self.args.cluster_id} @@ -62,7 +62,7 @@ class Cluster(object): raise argparse.ArgumentError("ACTION {} not implemented".format(self.args.action)) else: # this code should never be reached - assert False, "invalid ACTION {}".format(self.args.action) + raise argparse.ArgumentError("invalid ACTION {}".format(self.args.action)) verbose = '' if self.args.verbose > 0: -- cgit v1.2.3 From 8f35aff7245246de4116fcf3c81e7f095cf1be3a Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Sun, 22 Mar 2015 22:11:22 -0400 Subject: Add new role os_env_extras_node that is a subset of the docker role - Does not install or start docker, since the openshift-node role will handle that for us - Only add root to the dockerroot group and configures the enter-container script. --- playbooks/aws/openshift-node/config.yml | 2 +- roles/os_env_extras_node/README.md | 38 +++++++ roles/os_env_extras_node/files/enter-container.sh | 13 +++ roles/os_env_extras_node/meta/main.yml | 124 ++++++++++++++++++++++ roles/os_env_extras_node/tasks/main.yml | 7 ++ 5 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 roles/os_env_extras_node/README.md create mode 100755 roles/os_env_extras_node/files/enter-container.sh create mode 100644 roles/os_env_extras_node/meta/main.yml create mode 100644 roles/os_env_extras_node/tasks/main.yml diff --git a/playbooks/aws/openshift-node/config.yml b/playbooks/aws/openshift-node/config.yml index 822b66464..3cf2c58b2 100644 --- a/playbooks/aws/openshift-node/config.yml +++ b/playbooks/aws/openshift-node/config.yml @@ -44,5 +44,5 @@ openshift_env: "{{ oo_env }}", openshift_public_ip: "{{ ec2_ip_address }}" } - - docker - os_env_extras + - os_env_extras_node diff --git a/roles/os_env_extras_node/README.md b/roles/os_env_extras_node/README.md new file mode 100644 index 000000000..225dd44b9 --- /dev/null +++ b/roles/os_env_extras_node/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/roles/os_env_extras_node/files/enter-container.sh b/roles/os_env_extras_node/files/enter-container.sh new file mode 100755 index 000000000..7cf5b8d83 --- /dev/null +++ b/roles/os_env_extras_node/files/enter-container.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +if [ $# -ne 1 ] +then + echo + echo "Usage: $(basename $0) " + echo + exit 1 +fi + +PID=$(docker inspect --format '{{.State.Pid}}' $1) + +nsenter --target $PID --mount --uts --ipc --net --pid diff --git a/roles/os_env_extras_node/meta/main.yml b/roles/os_env_extras_node/meta/main.yml new file mode 100644 index 000000000..c5c362c60 --- /dev/null +++ b/roles/os_env_extras_node/meta/main.yml @@ -0,0 +1,124 @@ +--- +galaxy_info: + author: your name + description: + company: your company (optional) + # Some suggested licenses: + # - BSD (default) + # - MIT + # - GPLv2 + # - GPLv3 + # - Apache + # - CC-BY + license: license (GPLv2, CC-BY, etc) + min_ansible_version: 1.2 + # + # Below are all platforms currently available. Just uncomment + # the ones that apply to your role. If you don't see your + # platform on this list, let us know and we'll get it added! + # + #platforms: + #- name: EL + # versions: + # - all + # - 5 + # - 6 + # - 7 + #- name: GenericUNIX + # versions: + # - all + # - any + #- name: Fedora + # versions: + # - all + # - 16 + # - 17 + # - 18 + # - 19 + # - 20 + #- name: opensuse + # versions: + # - all + # - 12.1 + # - 12.2 + # - 12.3 + # - 13.1 + # - 13.2 + #- name: Amazon + # versions: + # - all + # - 2013.03 + # - 2013.09 + #- name: GenericBSD + # versions: + # - all + # - any + #- name: FreeBSD + # versions: + # - all + # - 8.0 + # - 8.1 + # - 8.2 + # - 8.3 + # - 8.4 + # - 9.0 + # - 9.1 + # - 9.1 + # - 9.2 + #- name: Ubuntu + # versions: + # - all + # - lucid + # - maverick + # - natty + # - oneiric + # - precise + # - quantal + # - raring + # - saucy + # - trusty + #- name: SLES + # versions: + # - all + # - 10SP3 + # - 10SP4 + # - 11 + # - 11SP1 + # - 11SP2 + # - 11SP3 + #- name: GenericLinux + # versions: + # - all + # - any + #- name: Debian + # versions: + # - all + # - etch + # - lenny + # - squeeze + # - wheezy + # + # Below are all categories currently available. Just as with + # the platforms above, uncomment those that apply to your role. + # + #categories: + #- cloud + #- cloud:ec2 + #- cloud:gce + #- cloud:rax + #- clustering + #- database + #- database:nosql + #- database:sql + #- development + #- monitoring + #- networking + #- packaging + #- system + #- web +dependencies: [] + # List your role dependencies here, one per line. Only + # dependencies available via galaxy should be listed here. + # Be sure to remove the '[]' above if you add dependencies + # to this list. + diff --git a/roles/os_env_extras_node/tasks/main.yml b/roles/os_env_extras_node/tasks/main.yml new file mode 100644 index 000000000..065f71f74 --- /dev/null +++ b/roles/os_env_extras_node/tasks/main.yml @@ -0,0 +1,7 @@ +--- +- copy: src=enter-container.sh dest=/usr/local/bin/enter-container.sh mode=0755 + +# From the origin rpm there exists instructions on how to +# setup origin properly. The following steps come from there +- name: Change root to be in the Docker group + user: name=root groups=dockerroot append=yes -- cgit v1.2.3 From 70c5a715debc1c1a900c6dcfe178b36b2a014ab4 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Sun, 22 Mar 2015 22:14:17 -0400 Subject: Use docker as package name instead of docker-io --- roles/docker/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml index ca700db17..593c4c877 100644 --- a/roles/docker/tasks/main.yml +++ b/roles/docker/tasks/main.yml @@ -1,7 +1,7 @@ --- # tasks file for docker - name: Install docker - yum: pkg=docker-io + yum: pkg=docker - name: enable and start the docker service service: name=docker enabled=yes state=started -- cgit v1.2.3 From 8b68846806d5294b5f43d14772d59aa2b8cf5e73 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Sun, 22 Mar 2015 22:43:00 -0400 Subject: remove os_firewall creation of DOCKER chain --- roles/os_firewall/tasks/firewall/iptables.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/roles/os_firewall/tasks/firewall/iptables.yml b/roles/os_firewall/tasks/firewall/iptables.yml index 72a3401cf..87e77c083 100644 --- a/roles/os_firewall/tasks/firewall/iptables.yml +++ b/roles/os_firewall/tasks/firewall/iptables.yml @@ -41,14 +41,6 @@ changed_when: "'firewalld' in result.stdout" when: pkg_check.rc == 0 -# Workaround for Docker 1.4 to create DOCKER chain -- name: Add DOCKER chain - os_firewall_manage_iptables: - name: "DOCKER chain" - action: verify_chain - create_jump_rule: no -# End of Docker 1.4 workaround - - name: Add iptables allow rules os_firewall_manage_iptables: name: "{{ item.service }}" -- cgit v1.2.3 From 557cc0ca9ecc22a9d90f9cf9ce549186fe286492 Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Mon, 23 Mar 2015 09:15:08 -0700 Subject: * Updates from code reviews --- bin/cluster | 14 +++++++++++--- playbooks/gce/openshift-cluster/launch_instances.yml | 2 +- playbooks/gce/openshift-master/terminate.yml | 1 + playbooks/gce/openshift-node/terminate.yml | 1 + 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/bin/cluster b/bin/cluster index af908155c..823f50671 100755 --- a/bin/cluster +++ b/bin/cluster @@ -83,9 +83,10 @@ class Cluster(object): sys.stderr.write('RUN [{}]\n'.format(command)) sys.stderr.flush() - error = os.system(command) - if error != 0: - raise Exception("Ansible run failed with exit code %d".format(error)) + status = os.system(command) + if status != 0: + sys.stderr.write("RUN [{}] failed with exit status %d".format(command, status)) + exit(status) @@ -100,4 +101,11 @@ if __name__ == '__main__': parser.add_argument('cluster_id', help='prefix for cluster VM names') args = parser.parse_args() + if 'terminate' == args.action: + sys.stderr.write("This will terminate the ENTIRE {} environment. Are you sure? [y/N] ".format(args.cluster_id)) + sys.stderr.flush() + answer = sys.stdin.read(1) + if answer not in ['y', 'Y']: + exit(0) + Cluster(args).apply() diff --git a/playbooks/gce/openshift-cluster/launch_instances.yml b/playbooks/gce/openshift-cluster/launch_instances.yml index 443e763de..20e31d990 100644 --- a/playbooks/gce/openshift-cluster/launch_instances.yml +++ b/playbooks/gce/openshift-cluster/launch_instances.yml @@ -12,7 +12,7 @@ pem_file: "{{ lookup('env', 'gce_service_account_pem_file_path') }}" project_id: "{{ lookup('env', 'gce_project_id') }}" tags: - - "created-by-{{ cluster }}" + - "created-by-{{ lookup('env', 'LOGNAME') |default(cluster, true) }}" - "env-{{ cluster }}" - "host-type-{{ type }}" - "env-host-type-{{ cluster }}-openshift-{{ type }}" diff --git a/playbooks/gce/openshift-master/terminate.yml b/playbooks/gce/openshift-master/terminate.yml index f1345874a..9e027cf41 100644 --- a/playbooks/gce/openshift-master/terminate.yml +++ b/playbooks/gce/openshift-master/terminate.yml @@ -15,6 +15,7 @@ - name: Terminate master instances hosts: localhost connection: local + gather_facts: no tasks: - name: Terminate master instances gce: diff --git a/playbooks/gce/openshift-node/terminate.yml b/playbooks/gce/openshift-node/terminate.yml index d4555084b..9aa8a48c1 100644 --- a/playbooks/gce/openshift-node/terminate.yml +++ b/playbooks/gce/openshift-node/terminate.yml @@ -15,6 +15,7 @@ - name: Terminate node instances hosts: localhost connection: local + gather_facts: no tasks: - name: Terminate node instances gce: -- cgit v1.2.3 From 461f6c1e07f36238729944a5f769600077ebf0b0 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Wed, 18 Mar 2015 17:15:19 -0400 Subject: Rename repos role to openshift_repos - Rename repos role to openshift_repos - Make openshift_repos a dependency of openshift_common - Add README and metadata for openshift_repos - Playbook updates for role rename - Verify libselinux-python is installed, otherwise some of the bulit-in modules we use fail --- playbooks/gce/openshift-master/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/gce/openshift-master/config.yml b/playbooks/gce/openshift-master/config.yml index 812dcb91b..e405e2fb4 100644 --- a/playbooks/gce/openshift-master/config.yml +++ b/playbooks/gce/openshift-master/config.yml @@ -7,7 +7,7 @@ with_items: "{{ oo_host_group_exp | default('') }}" when: oo_host_group_exp is defined -- name: "Gather facts for nodes in {{ oo_env }}" +- name: Gather facts for nodes in {{ oo_env }} hosts: "tag_env-host-type-{{ oo_env }}-openshift-node" - name: "Configure instances" -- cgit v1.2.3 From d67c5b8f79609d2d3b07cc009f58e3dc988782c5 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Mon, 23 Mar 2015 16:30:49 -0400 Subject: node registration changes - Remove default value for openshift_hostname and make it required - Remove workarounds that are no longer needed - Remove resources parameter from openshift_register_node module - pre-create node certificates for each node before registering node - distribute created node certificates to each node - Move node registration logic to a new openshift_register_nodes role - This is because we now have to run the steps on a master as opposed to on the nodes like we were previously doing. - Rename openshift_register_node module to kubernetes_register_node, one more step to genericizing enough for upstreaming, however there are still plenty of openshift specific commands that still need to be genericized. --- roles/openshift_common/README.md | 2 +- roles/openshift_common/defaults/main.yml | 2 +- roles/openshift_master/README.md | 2 +- roles/openshift_master/tasks/main.yml | 35 +- roles/openshift_node/README.md | 3 +- roles/openshift_node/defaults/main.yml | 6 - .../library/openshift_register_node.py | 390 --------------------- roles/openshift_node/tasks/main.yml | 68 +--- roles/openshift_register_nodes/README.md | 38 ++ roles/openshift_register_nodes/defaults/main.yml | 5 + .../library/kubernetes_register_node.py | 370 +++++++++++++++++++ roles/openshift_register_nodes/meta/main.yml | 128 +++++++ roles/openshift_register_nodes/tasks/main.yml | 71 ++++ roles/openshift_sdn_node/README.md | 2 +- 14 files changed, 641 insertions(+), 481 deletions(-) delete mode 100644 roles/openshift_node/library/openshift_register_node.py create mode 100644 roles/openshift_register_nodes/README.md create mode 100644 roles/openshift_register_nodes/defaults/main.yml create mode 100644 roles/openshift_register_nodes/library/kubernetes_register_node.py create mode 100644 roles/openshift_register_nodes/meta/main.yml create mode 100644 roles/openshift_register_nodes/tasks/main.yml diff --git a/roles/openshift_common/README.md b/roles/openshift_common/README.md index fce79047c..592a276f9 100644 --- a/roles/openshift_common/README.md +++ b/roles/openshift_common/README.md @@ -16,7 +16,7 @@ Role Variables |-------------------------------|------------------------------|----------------------------------------| | openshift_debug_level | 0 | Global openshift debug log verbosity | | openshift_hostname_workaround | True | Workaround needed to set hostname to IP address | -| openshift_hostname | openshift_public_ip if openshift_hostname_workaround else ansible_fqdn | hostname to use for this instance | +| openshift_hostname | UNDEF (Required) | hostname to use for this instance | | openshift_public_ip | UNDEF (Required) | Public IP address to use for this host | | openshift_env | default | Envrionment name if multiple OpenShift instances | diff --git a/roles/openshift_common/defaults/main.yml b/roles/openshift_common/defaults/main.yml index eb6edbc03..86351f6f6 100644 --- a/roles/openshift_common/defaults/main.yml +++ b/roles/openshift_common/defaults/main.yml @@ -4,4 +4,4 @@ openshift_debug_level: 0 # TODO: Once openshift stops resolving hostnames for node queries remove # this... openshift_hostname_workaround: true -openshift_hostname: "{{ ansible_default_ipv4.address if openshift_hostname_workaround else ansible_fqdn }}" + diff --git a/roles/openshift_master/README.md b/roles/openshift_master/README.md index 5a1b889b2..2f03b4990 100644 --- a/roles/openshift_master/README.md +++ b/roles/openshift_master/README.md @@ -27,7 +27,7 @@ From openshift_common: | openshift_debug_level | 0 | Global openshift debug log verbosity | | openshift_hostname_workaround | True | | | openshift_public_ip | UNDEF (Required) | Public IP address to use for this host | -| openshift_hostname | openshift_public_ip if openshift_hostname_workaround else ansible_fqdn | hostname to use for this instance | +| openshift_hostname | UNDEF (Required) | hostname to use for this instance | Dependencies ------------ diff --git a/roles/openshift_master/tasks/main.yml b/roles/openshift_master/tasks/main.yml index d5f4776dc..52f5f694c 100644 --- a/roles/openshift_master/tasks/main.yml +++ b/roles/openshift_master/tasks/main.yml @@ -1,4 +1,8 @@ --- +# TODO: allow for overriding default ports where possible +# TODO: if setting up multiple masters, will need to predistribute the certs +# to the additional masters before starting openshift-master + - name: Install OpenShift Master package yum: pkg=openshift-master state=installed @@ -6,9 +10,7 @@ lineinfile: dest: /etc/sysconfig/openshift-master regexp: '^OPTIONS=' - line: "OPTIONS=\"--public-master={{ openshift_hostname }} {% if - openshift_node_ips %} --nodes={{ openshift_node_ips - | join(',') }} {% endif %} --loglevel={{ openshift_master_debug_level }}\"" + line: "OPTIONS=\"--public-master={{ openshift_hostname }} {% if openshift_node_ips %} --nodes={{ openshift_node_ips | join(',') }} {% endif %} --loglevel={{ openshift_master_debug_level }}\"" notify: - restart openshift-master @@ -34,42 +36,15 @@ option: externally_managed value: "{{ openshift_master_manage_service_externally }}" -# TODO: remove this when origin PR #1298 has landed in OSE -- name: Workaround for openshift-master taking longer than 90 seconds to issue sdNotify signal - command: cp /usr/lib/systemd/system/openshift-master.service /etc/systemd/system/ - args: - creates: /etc/systemd/system/openshift-master.service -- ini_file: - dest: /etc/systemd/system/openshift-master.service - option: TimeoutStartSec - section: Service - value: 300 - state: present - register: result -- command: systemctl daemon-reload - when: result | changed -# End of workaround pending PR #1298 - - name: Start and enable openshift-master service: name=openshift-master enabled=yes state=started when: not openshift_master_manage_service_externally register: result -#TODO: remove this when origin PR #1204 has landed in OSE -- name: need to pause here, otherwise we attempt to copy certificates generated by the master before they are generated - pause: seconds=30 - when: result | changed -# End of workaround pending PR #1204 - - name: Disable openshift-master if openshift-master is managed externally service: name=openshift-master enabled=false when: openshift_master_manage_service_externally -# TODO: create an os_vars role that has generic env related config and move -# the root kubeconfig setting there, cannot use dependencies to force ordering -# with openshift_node and openshift_master because the way conditional -# dependencies work with current ansible would also exclude the -# openshift_common dependency. - name: Create .kube directory file: path: /root/.kube diff --git a/roles/openshift_node/README.md b/roles/openshift_node/README.md index 9210bab16..d537a35a5 100644 --- a/roles/openshift_node/README.md +++ b/roles/openshift_node/README.md @@ -21,7 +21,6 @@ From this role: | openshift_master_public_ips | UNDEF (Required) | List of the public IPs for the openhift-master hosts | | openshift_master_ips | UNDEF (Required) | List of IP addresses for the openshift-master hosts to be used for node -> master communication | | openshift_registry_url | UNDEF (Optional) | Default docker registry to use | -| openshift_node_resources | { capacity: { cpu: , memory: } } | Resource specification for this node, cpu is the number of CPUs to advertise and memory is the amount of memory in bytes to advertise. Default values chosen when not set are the number of logical CPUs for the host and 75% of total system memory | From openshift_common: | Name | Default Value | | @@ -29,7 +28,7 @@ From openshift_common: | openshift_debug_level | 0 | Global openshift debug log verbosity | | openshift_hostname_workaround | True | | | openshift_public_ip | UNDEF (Required) | Public IP address to use for this host | -| openshift_hostname | openshift_public_ip if openshift_hostname_workaround else ansible_fqdn | hostname to use for this instance | +| openshift_hostname | UNDEF (Required) | hostname to use for this instance | Dependencies ------------ diff --git a/roles/openshift_node/defaults/main.yml b/roles/openshift_node/defaults/main.yml index e4d5ebfee..6dc73a96e 100644 --- a/roles/openshift_node/defaults/main.yml +++ b/roles/openshift_node/defaults/main.yml @@ -4,9 +4,3 @@ openshift_node_debug_level: "{{ openshift_debug_level | default(0) }}" os_firewall_allow: - service: OpenShift kubelet port: 10250/tcp -openshift_node_resources: - cpu: - memory: - cidr: -openshift_node_labels: {} -openshift_node_annotations: {} diff --git a/roles/openshift_node/library/openshift_register_node.py b/roles/openshift_node/library/openshift_register_node.py deleted file mode 100644 index 4922585d7..000000000 --- a/roles/openshift_node/library/openshift_register_node.py +++ /dev/null @@ -1,390 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# vim: expandtab:tabstop=4:shiftwidth=4 - -import os -import multiprocessing -import socket -from subprocess import check_output, Popen -from decimal import * - -DOCUMENTATION = ''' ---- -module: kubernetes_register_node -short_description: Registers a kubernetes node with a master -description: - - Registers a kubernetes node with a master -options: - name: - default: null - description: - - Identifier for this node (usually the node fqdn). - required: true - api_verison: - choices: ['v1beta1', 'v1beta3'] - default: 'v1beta1' - description: - - Kubernetes API version to use - required: true - host_ip: - default: null - description: - - IP Address to associate with the node when registering. - Available in the following API versions: v1beta1. - required: false - hostnames: - default: [] - description: - - Valid hostnames for this node. Available in the following API - versions: v1beta3. - required: false - external_ips: - default: [] - description: - - External IP Addresses for this node. Available in the following API - versions: v1beta3. - required: false - internal_ips: - default: [] - description: - - Internal IP Addresses for this node. Available in the following API - versions: v1beta3. - required: false - cpu: - default: null - description: - - Number of CPUs to allocate for this node. If not provided, then - the node will be registered to advertise the number of logical - CPUs available. When using the v1beta1 API, you must specify the - CPU count as a floating point number with no more than 3 decimal - places. API version v1beta3 and newer accepts arbitrary float - values. - required: false - memory: - default: null - description: - - Memory available for this node. If not provided, then the node - will be registered to advertise 80% of MemTotal as available - memory. When using the v1beta1 API, you must specify the memory - size in bytes. API version v1beta3 and newer accepts binary SI - and decimal SI values. - required: false -''' -EXAMPLES = ''' -# Minimal node registration -- openshift_register_node: name=ose3.node.example.com - -# Node registration using the v1beta1 API and assigning 1 CPU core and 10 GB of -# Memory -- openshift_register_node: - name: ose3.node.example.com - api_version: v1beta1 - hostIP: 192.168.1.1 - cpu: 1 - memory: 500000000 - -# Node registration using the v1beta3 API, setting an alternate hostname, -# internalIP, externalIP and assigning 3.5 CPU cores and 1 TiB of Memory -- openshift_register_node: - name: ose3.node.example.com - api_version: v1beta3 - external_ips: ['192.168.1.5'] - internal_ips: ['10.0.0.5'] - hostnames: ['ose2.node.internal.local'] - cpu: 3.5 - memory: 1Ti -''' - - -class ClientConfigException(Exception): - pass - -class ClientConfig: - def __init__(self, client_opts, module): - _, output, error = module.run_command(["/usr/bin/openshift", "ex", - "config", "view", "-o", - "json"] + client_opts, - check_rc = True) - self.config = json.loads(output) - - if not (bool(self.config['clusters']) or - bool(self.config['contexts']) or - bool(self.config['current-context']) or - bool(self.config['users'])): - raise ClientConfigException(msg="Client config missing required " \ - "values", - output=output) - - def current_context(self): - return self.config['current-context'] - - def section_has_value(self, section_name, value): - section = self.config[section_name] - if isinstance(section, dict): - return value in section - else: - val = next((item for item in section - if item['name'] == value), None) - return val is not None - - def has_context(self, context): - return self.section_has_value('contexts', context) - - def has_user(self, user): - return self.section_has_value('users', user) - - def has_cluster(self, cluster): - return self.section_has_value('clusters', cluster) - - def get_value_for_context(self, context, attribute): - contexts = self.config['contexts'] - if isinstance(contexts, dict): - return contexts[context][attribute] - else: - return next((c['context'][attribute] for c in contexts - if c['name'] == context), None) - - def get_user_for_context(self, context): - return self.get_value_for_context(context, 'user') - - def get_cluster_for_context(self, context): - return self.get_value_for_context(context, 'cluster') - -class Util: - @staticmethod - def getLogicalCores(): - return multiprocessing.cpu_count() - - @staticmethod - def getMemoryPct(pct): - with open('/proc/meminfo', 'r') as mem: - for line in mem: - entries = line.split() - if str(entries.pop(0)) == 'MemTotal:': - mem_total_kb = Decimal(entries.pop(0)) - mem_capacity_kb = mem_total_kb * Decimal(pct) - return str(mem_capacity_kb.to_integral_value() * 1024) - - return "" - - @staticmethod - def remove_empty_elements(mapping): - if isinstance(mapping, dict): - m = mapping.copy() - for key, val in mapping.iteritems(): - if not val: - del m[key] - return m - else: - return mapping - -class NodeResources: - def __init__(self, version, cpu=None, memory=None): - if version == 'v1beta1': - self.resources = dict(capacity=dict()) - self.resources['capacity']['cpu'] = cpu if cpu else Util.getLogicalCores() - self.resources['capacity']['memory'] = memory if cpu else Util.getMemoryPct(.75) - - def get_resources(self): - return Util.remove_empty_elements(self.resources) - -class NodeSpec: - def __init__(self, version, cpu=None, memory=None, cidr=None, externalID=None): - if version == 'v1beta3': - self.spec = dict(podCIDR=cidr, externalID=externalID, - capacity=dict()) - self.spec['capacity']['cpu'] = cpu if cpu else Util.getLogicalCores() - self.spec['capacity']['memory'] = memory if memory else Util.getMemoryPct(.75) - - def get_spec(self): - return Util.remove_empty_elements(self.spec) - -class NodeStatus: - def addAddresses(self, addressType, addresses): - addressList = [] - for address in addresses: - addressList.append(dict(type=addressType, address=address)) - return addressList - - def __init__(self, version, externalIPs = [], internalIPs = [], - hostnames = []): - if version == 'v1beta3': - self.status = dict(addresses = addAddresses('ExternalIP', - externalIPs) + - addAddresses('InternalIP', - internalIPs) + - addAddresses('Hostname', - hostnames)) - - def get_status(self): - return Util.remove_empty_elements(self.status) - -class Node: - def __init__(self, module, client_opts, version='v1beta1', name=None, - hostIP = None, hostnames=[], externalIPs=[], internalIPs=[], - cpu=None, memory=None, labels=dict(), annotations=dict(), - podCIDR=None, externalID=None): - self.module = module - self.client_opts = client_opts - if version == 'v1beta1': - self.node = dict(id = name, - kind = 'Node', - apiVersion = version, - hostIP = hostIP, - resources = NodeResources(version, cpu, memory), - cidr = podCIDR, - labels = labels, - annotations = annotations - ) - elif version == 'v1beta3': - metadata = dict(name = name, - labels = labels, - annotations = annotations - ) - self.node = dict(kind = 'Node', - apiVersion = version, - metadata = metadata, - spec = NodeSpec(version, cpu, memory, podCIDR, - externalID), - status = NodeStatus(version, externalIPs, - internalIPs, hostnames), - ) - - def get_name(self): - if self.node['apiVersion'] == 'v1beta1': - return self.node['id'] - elif self.node['apiVersion'] == 'v1beta3': - return self.node['name'] - - def get_node(self): - node = self.node.copy() - if self.node['apiVersion'] == 'v1beta1': - node['resources'] = self.node['resources'].get_resources() - elif self.node['apiVersion'] == 'v1beta3': - node['spec'] = self.node['spec'].get_spec() - node['status'] = self.node['status'].get_status() - return Util.remove_empty_elements(node) - - def exists(self): - _, output, error = self.module.run_command(["/usr/bin/osc", "get", - "nodes"] + self.client_opts, - check_rc = True) - if re.search(self.module.params['name'], output, re.MULTILINE): - return True - return False - - def create(self): - cmd = ['/usr/bin/osc'] + self.client_opts + ['create', 'node', '-f', '-'] - rc, output, error = self.module.run_command(cmd, - data=self.module.jsonify(self.get_node())) - if rc != 0: - if re.search("minion \"%s\" already exists" % self.get_name(), - error): - self.module.exit_json(changed=False, - msg="node definition already exists", - node=self.get_node()) - else: - self.module.fail_json(msg="Node creation failed.", rc=rc, - output=output, error=error, - node=self.get_node()) - else: - return True - -def main(): - module = AnsibleModule( - argument_spec = dict( - name = dict(required = True, type = 'str'), - host_ip = dict(type = 'str'), - hostnames = dict(type = 'list', default = []), - external_ips = dict(type = 'list', default = []), - internal_ips = dict(type = 'list', default = []), - api_version = dict(type = 'str', default = 'v1beta1', # TODO: after kube rebase, we can default to v1beta3 - choices = ['v1beta1', 'v1beta3']), - cpu = dict(type = 'str'), - memory = dict(type = 'str'), - labels = dict(type = 'dict', default = {}), # TODO: needs documented - annotations = dict(type = 'dict', default = {}), # TODO: needs documented - pod_cidr = dict(type = 'str'), # TODO: needs documented - external_id = dict(type = 'str'), # TODO: needs documented - client_config = dict(type = 'str'), # TODO: needs documented - client_cluster = dict(type = 'str', default = 'master'), # TODO: needs documented - client_context = dict(type = 'str', default = 'master'), # TODO: needs documented - client_user = dict(type = 'str', default = 'admin') # TODO: needs documented - ), - mutually_exclusive = [ - ['host_ip', 'external_ips'], - ['host_ip', 'internal_ips'], - ['host_ip', 'hostnames'], - ], - supports_check_mode=True - ) - - user_has_client_config = os.path.exists(os.path.expanduser('~/.kube/.kubeconfig')) - if not (user_has_client_config or module.params['client_config']): - module.fail_json(msg="Could not locate client configuration, " - "client_config must be specified if " - "~/.kube/.kubeconfig is not present") - - client_opts = [] - if module.params['client_config']: - client_opts.append("--kubeconfig=%s" % module.params['client_config']) - - try: - config = ClientConfig(client_opts, module) - except ClientConfigException as e: - module.fail_json(msg="Failed to get client configuration", exception=e) - - client_context = module.params['client_context'] - if config.has_context(client_context): - if client_context != config.current_context(): - client_opts.append("--context=%s" % client_context) - else: - module.fail_json(msg="Context %s not found in client config" % - client_context) - - client_user = module.params['client_user'] - if config.has_user(client_user): - if client_user != config.get_user_for_context(client_context): - client_opts.append("--user=%s" % client_user) - else: - module.fail_json(msg="User %s not found in client config" % - client_user) - - client_cluster = module.params['client_cluster'] - if config.has_cluster(client_cluster): - if client_cluster != config.get_cluster_for_context(client_cluster): - client_opts.append("--cluster=%s" % client_cluster) - else: - module.fail_json(msg="Cluster %s not found in client config" % - client_cluster) - - # TODO: provide sane defaults for some (like hostname, externalIP, - # internalIP, etc) - node = Node(module, client_opts, module.params['api_version'], - module.params['name'], module.params['host_ip'], - module.params['hostnames'], module.params['external_ips'], - module.params['internal_ips'], module.params['cpu'], - module.params['memory'], module.params['labels'], - module.params['annotations'], module.params['pod_cidr'], - module.params['external_id']) - - # TODO: attempt to support changing node settings where possible and/or - # modifying node resources - if node.exists(): - module.exit_json(changed=False, node=node.get_node()) - elif module.check_mode: - module.exit_json(changed=True, node=node.get_node()) - else: - if node.create(): - module.exit_json(changed=True, - msg="Node created successfully", - node=node.get_node()) - else: - module.fail_json(msg="Unknown error creating node", - node=node.get_node()) - - -# import module snippets -from ansible.module_utils.basic import * -if __name__ == '__main__': - main() diff --git a/roles/openshift_node/tasks/main.yml b/roles/openshift_node/tasks/main.yml index e380ba1fb..c039e3f05 100644 --- a/roles/openshift_node/tasks/main.yml +++ b/roles/openshift_node/tasks/main.yml @@ -1,27 +1,29 @@ --- +- name: Test if node certs and config exist + stat: path={{ item }} + failed_when: not result.stat.exists + register: result + with_items: + - "{{ cert_path }}" + - "{{ cert_path }}/cert.crt" + - "{{ cert_path }}/key.key" + - "{{ cert_path }}/.kubeconfig" + - "{{ cert_path }}/server.crt" + - "{{ cert_path }}/server.key" + - "{{ cert_parent_path }}/ca/cert.crt" + #- "{{ cert_path }}/node.yaml" + - name: Install OpenShift Node package yum: pkg=openshift-node state=installed -- local_action: command /usr/bin/mktemp -d /tmp/openshift-ansible-XXXXXXX - register: mktemp - -- name: Retrieve OpenShift Master credentials - local_action: command /usr/bin/rsync --compress --archive --rsh 'ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' root@{{ openshift_master_public_ips[0] }}:/var/lib/openshift/openshift.local.certificates/admin/ {{ mktemp.stdout }} - ignore_errors: yes - -- file: path=/var/lib/openshift/openshift.local.certificates/admin state=directory - -- name: Store OpenShift Master credentials - local_action: command /usr/bin/rsync --compress --archive --rsh 'ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' {{ mktemp.stdout }}/ root@{{ openshift_public_ip }}:/var/lib/openshift/openshift.local.certificates/admin - ignore_errors: yes - -- local_action: file name={{ mktemp.stdout }} state=absent - +# --create-certs=false is a temporary workaround until +# https://github.com/openshift/origin/pull/1361 is merged upstream and it is +# the default for nodes - name: Configure OpenShift Node settings lineinfile: dest: /etc/sysconfig/openshift-node regexp: '^OPTIONS=' - line: "OPTIONS=\"--master=https://{{ openshift_master_ips[0] }}:8443 --hostname={{ openshift_hostname }} --loglevel={{ openshift_node_debug_level }}\"" + line: "OPTIONS=\"--hostname={{ openshift_hostname }} --loglevel={{ openshift_node_debug_level }} --create-certs=false\"" notify: - restart openshift-node @@ -47,42 +49,10 @@ option: externally_managed value: "{{ openshift_node_manage_service_externally }}" -# fixme: Once the openshift_cluster playbook is published state should be started -# Always bounce service to pick up new credentials - name: Start and enable openshift-node - service: name=openshift-node enabled=yes state=restarted + service: name=openshift-node enabled=yes state=started when: not openshift_node_manage_service_externally - name: Disable openshift-node if openshift-node is managed externally service: name=openshift-node enabled=false when: openshift_node_manage_service_externally - -# TODO: create an os_vars role that has generic env related config and move -# the root kubeconfig setting there, cannot use dependencies to force ordering -# with openshift_node and openshift_master because the way conditional -# dependencies work with current ansible would also exclude the -# openshift_common dependency. -- name: Create .kube directory - file: - path: /root/.kube - state: directory - mode: 0700 -- name: Configure root user kubeconfig - command: cp /var/lib/openshift/openshift.local.certificates/admin/.kubeconfig /root/.kube/.kubeconfig - args: - creates: /root/.kube/.kubeconfig - -- name: Register node (if not already registered) - openshift_register_node: - name: "{{ openshift_hostname }}" - api_version: v1beta1 - cpu: "{{ openshift_node_resources.cpu }}" - memory: "{{ openshift_node_resources.memory }}" - pod_cidr: "{{ openshift_node_resources.cidr }}" - host_ip: "{{ ansible_default_ipv4.address }}" - labels: "{{ openshift_node_labels }}" - annotations: "{{ openshift_node_annotations }}" - # TODO: support customizing other attributes such as: client_config, - # client_cluster, client_context, client_user - # TODO: updated for v1beta3 changes after rebase: hostnames, external_ips, - # internal_ips, external_id diff --git a/roles/openshift_register_nodes/README.md b/roles/openshift_register_nodes/README.md new file mode 100644 index 000000000..225dd44b9 --- /dev/null +++ b/roles/openshift_register_nodes/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/roles/openshift_register_nodes/defaults/main.yml b/roles/openshift_register_nodes/defaults/main.yml new file mode 100644 index 000000000..3501e8922 --- /dev/null +++ b/roles/openshift_register_nodes/defaults/main.yml @@ -0,0 +1,5 @@ +--- +openshift_kube_api_version: v1beta1 +openshift_cert_dir: openshift.local.certificates +openshift_cert_dir_parent: /var/lib/openshift +openshift_cert_dir_abs: "{{ openshift_cert_dir_parent ~ '/' ~ openshift_cert_dir }}" diff --git a/roles/openshift_register_nodes/library/kubernetes_register_node.py b/roles/openshift_register_nodes/library/kubernetes_register_node.py new file mode 100644 index 000000000..409215616 --- /dev/null +++ b/roles/openshift_register_nodes/library/kubernetes_register_node.py @@ -0,0 +1,370 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# vim: expandtab:tabstop=4:shiftwidth=4 + +import os +import multiprocessing +import socket +from subprocess import check_output, Popen +from decimal import * + +DOCUMENTATION = ''' +--- +module: kubernetes_register_node +short_description: Registers a kubernetes node with a master +description: + - Registers a kubernetes node with a master +options: + name: + default: null + description: + - Identifier for this node (usually the node fqdn). + required: true + api_verison: + choices: ['v1beta1', 'v1beta3'] + default: 'v1beta1' + description: + - Kubernetes API version to use + required: true + host_ip: + default: null + description: + - IP Address to associate with the node when registering. + Available in the following API versions: v1beta1. + required: false + hostnames: + default: [] + description: + - Valid hostnames for this node. Available in the following API + versions: v1beta3. + required: false + external_ips: + default: [] + description: + - External IP Addresses for this node. Available in the following API + versions: v1beta3. + required: false + internal_ips: + default: [] + description: + - Internal IP Addresses for this node. Available in the following API + versions: v1beta3. + required: false + cpu: + default: null + description: + - Number of CPUs to allocate for this node. When using the v1beta1 + API, you must specify the CPU count as a floating point number + with no more than 3 decimal places. API version v1beta3 and newer + accepts arbitrary float values. + required: false + memory: + default: null + description: + - Memory available for this node. When using the v1beta1 API, you + must specify the memory size in bytes. API version v1beta3 and + newer accepts binary SI and decimal SI values. + required: false +''' +EXAMPLES = ''' +# Minimal node registration +- openshift_register_node: name=ose3.node.example.com + +# Node registration using the v1beta1 API and assigning 1 CPU core and 10 GB of +# Memory +- openshift_register_node: + name: ose3.node.example.com + api_version: v1beta1 + hostIP: 192.168.1.1 + cpu: 1 + memory: 500000000 + +# Node registration using the v1beta3 API, setting an alternate hostname, +# internalIP, externalIP and assigning 3.5 CPU cores and 1 TiB of Memory +- openshift_register_node: + name: ose3.node.example.com + api_version: v1beta3 + external_ips: ['192.168.1.5'] + internal_ips: ['10.0.0.5'] + hostnames: ['ose2.node.internal.local'] + cpu: 3.5 + memory: 1Ti +''' + + +class ClientConfigException(Exception): + pass + +class ClientConfig: + def __init__(self, client_opts, module): + _, output, error = module.run_command(["/usr/bin/openshift", "ex", + "config", "view", "-o", + "json"] + client_opts, + check_rc = True) + self.config = json.loads(output) + + if not (bool(self.config['clusters']) or + bool(self.config['contexts']) or + bool(self.config['current-context']) or + bool(self.config['users'])): + raise ClientConfigException(msg="Client config missing required " \ + "values", + output=output) + + def current_context(self): + return self.config['current-context'] + + def section_has_value(self, section_name, value): + section = self.config[section_name] + if isinstance(section, dict): + return value in section + else: + val = next((item for item in section + if item['name'] == value), None) + return val is not None + + def has_context(self, context): + return self.section_has_value('contexts', context) + + def has_user(self, user): + return self.section_has_value('users', user) + + def has_cluster(self, cluster): + return self.section_has_value('clusters', cluster) + + def get_value_for_context(self, context, attribute): + contexts = self.config['contexts'] + if isinstance(contexts, dict): + return contexts[context][attribute] + else: + return next((c['context'][attribute] for c in contexts + if c['name'] == context), None) + + def get_user_for_context(self, context): + return self.get_value_for_context(context, 'user') + + def get_cluster_for_context(self, context): + return self.get_value_for_context(context, 'cluster') + +class Util: + @staticmethod + def remove_empty_elements(mapping): + if isinstance(mapping, dict): + m = mapping.copy() + for key, val in mapping.iteritems(): + if not val: + del m[key] + return m + else: + return mapping + +class NodeResources: + def __init__(self, version, cpu=None, memory=None): + if version == 'v1beta1': + self.resources = dict(capacity=dict()) + self.resources['capacity']['cpu'] = cpu + self.resources['capacity']['memory'] = memory + + def get_resources(self): + return Util.remove_empty_elements(self.resources) + +class NodeSpec: + def __init__(self, version, cpu=None, memory=None, cidr=None, externalID=None): + if version == 'v1beta3': + self.spec = dict(podCIDR=cidr, externalID=externalID, + capacity=dict()) + self.spec['capacity']['cpu'] = cpu + self.spec['capacity']['memory'] = memory + + def get_spec(self): + return Util.remove_empty_elements(self.spec) + +class NodeStatus: + def addAddresses(self, addressType, addresses): + addressList = [] + for address in addresses: + addressList.append(dict(type=addressType, address=address)) + return addressList + + def __init__(self, version, externalIPs = [], internalIPs = [], + hostnames = []): + if version == 'v1beta3': + self.status = dict(addresses = addAddresses('ExternalIP', + externalIPs) + + addAddresses('InternalIP', + internalIPs) + + addAddresses('Hostname', + hostnames)) + + def get_status(self): + return Util.remove_empty_elements(self.status) + +class Node: + def __init__(self, module, client_opts, version='v1beta1', name=None, + hostIP = None, hostnames=[], externalIPs=[], internalIPs=[], + cpu=None, memory=None, labels=dict(), annotations=dict(), + podCIDR=None, externalID=None): + self.module = module + self.client_opts = client_opts + if version == 'v1beta1': + self.node = dict(id = name, + kind = 'Node', + apiVersion = version, + hostIP = hostIP, + resources = NodeResources(version, cpu, memory), + cidr = podCIDR, + labels = labels, + annotations = annotations + ) + elif version == 'v1beta3': + metadata = dict(name = name, + labels = labels, + annotations = annotations + ) + self.node = dict(kind = 'Node', + apiVersion = version, + metadata = metadata, + spec = NodeSpec(version, cpu, memory, podCIDR, + externalID), + status = NodeStatus(version, externalIPs, + internalIPs, hostnames), + ) + + def get_name(self): + if self.node['apiVersion'] == 'v1beta1': + return self.node['id'] + elif self.node['apiVersion'] == 'v1beta3': + return self.node['name'] + + def get_node(self): + node = self.node.copy() + if self.node['apiVersion'] == 'v1beta1': + node['resources'] = self.node['resources'].get_resources() + elif self.node['apiVersion'] == 'v1beta3': + node['spec'] = self.node['spec'].get_spec() + node['status'] = self.node['status'].get_status() + return Util.remove_empty_elements(node) + + def exists(self): + _, output, error = self.module.run_command(["/usr/bin/osc", "get", + "nodes"] + self.client_opts, + check_rc = True) + if re.search(self.module.params['name'], output, re.MULTILINE): + return True + return False + + def create(self): + cmd = ['/usr/bin/osc'] + self.client_opts + ['create', 'node', '-f', '-'] + rc, output, error = self.module.run_command(cmd, + data=self.module.jsonify(self.get_node())) + if rc != 0: + if re.search("minion \"%s\" already exists" % self.get_name(), + error): + self.module.exit_json(changed=False, + msg="node definition already exists", + node=self.get_node()) + else: + self.module.fail_json(msg="Node creation failed.", rc=rc, + output=output, error=error, + node=self.get_node()) + else: + return True + +def main(): + module = AnsibleModule( + argument_spec = dict( + name = dict(required = True, type = 'str'), + host_ip = dict(type = 'str'), + hostnames = dict(type = 'list', default = []), + external_ips = dict(type = 'list', default = []), + internal_ips = dict(type = 'list', default = []), + api_version = dict(type = 'str', default = 'v1beta1', # TODO: after kube rebase, we can default to v1beta3 + choices = ['v1beta1', 'v1beta3']), + cpu = dict(type = 'str'), + memory = dict(type = 'str'), + labels = dict(type = 'dict', default = {}), # TODO: needs documented + annotations = dict(type = 'dict', default = {}), # TODO: needs documented + pod_cidr = dict(type = 'str'), # TODO: needs documented + external_id = dict(type = 'str'), # TODO: needs documented + client_config = dict(type = 'str'), # TODO: needs documented + client_cluster = dict(type = 'str', default = 'master'), # TODO: needs documented + client_context = dict(type = 'str', default = 'master'), # TODO: needs documented + client_user = dict(type = 'str', default = 'admin') # TODO: needs documented + ), + mutually_exclusive = [ + ['host_ip', 'external_ips'], + ['host_ip', 'internal_ips'], + ['host_ip', 'hostnames'], + ], + supports_check_mode=True + ) + + user_has_client_config = os.path.exists(os.path.expanduser('~/.kube/.kubeconfig')) + if not (user_has_client_config or module.params['client_config']): + module.fail_json(msg="Could not locate client configuration, " + "client_config must be specified if " + "~/.kube/.kubeconfig is not present") + + client_opts = [] + if module.params['client_config']: + client_opts.append("--kubeconfig=%s" % module.params['client_config']) + + try: + config = ClientConfig(client_opts, module) + except ClientConfigException as e: + module.fail_json(msg="Failed to get client configuration", exception=e) + + client_context = module.params['client_context'] + if config.has_context(client_context): + if client_context != config.current_context(): + client_opts.append("--context=%s" % client_context) + else: + module.fail_json(msg="Context %s not found in client config" % + client_context) + + client_user = module.params['client_user'] + if config.has_user(client_user): + if client_user != config.get_user_for_context(client_context): + client_opts.append("--user=%s" % client_user) + else: + module.fail_json(msg="User %s not found in client config" % + client_user) + + client_cluster = module.params['client_cluster'] + if config.has_cluster(client_cluster): + if client_cluster != config.get_cluster_for_context(client_cluster): + client_opts.append("--cluster=%s" % client_cluster) + else: + module.fail_json(msg="Cluster %s not found in client config" % + client_cluster) + + # TODO: provide sane defaults for some (like hostname, externalIP, + # internalIP, etc) + node = Node(module, client_opts, module.params['api_version'], + module.params['name'], module.params['host_ip'], + module.params['hostnames'], module.params['external_ips'], + module.params['internal_ips'], module.params['cpu'], + module.params['memory'], module.params['labels'], + module.params['annotations'], module.params['pod_cidr'], + module.params['external_id']) + + # TODO: attempt to support changing node settings where possible and/or + # modifying node resources + if node.exists(): + module.exit_json(changed=False, node=node.get_node()) + elif module.check_mode: + module.exit_json(changed=True, node=node.get_node()) + else: + if node.create(): + module.exit_json(changed=True, + msg="Node created successfully", + node=node.get_node()) + else: + module.fail_json(msg="Unknown error creating node", + node=node.get_node()) + + +# import module snippets +from ansible.module_utils.basic import * +if __name__ == '__main__': + main() diff --git a/roles/openshift_register_nodes/meta/main.yml b/roles/openshift_register_nodes/meta/main.yml new file mode 100644 index 000000000..7b1f0ef0a --- /dev/null +++ b/roles/openshift_register_nodes/meta/main.yml @@ -0,0 +1,128 @@ +--- +galaxy_info: + author: your name + description: + company: your company (optional) + # Some suggested licenses: + # - BSD (default) + # - MIT + # - GPLv2 + # - GPLv3 + # - Apache + # - CC-BY + license: license (GPLv2, CC-BY, etc) + min_ansible_version: 1.2 + # + # Below are all platforms currently available. Just uncomment + # the ones that apply to your role. If you don't see your + # platform on this list, let us know and we'll get it added! + # + #platforms: + #- name: EL + # versions: + # - all + # - 5 + # - 6 + # - 7 + #- name: GenericUNIX + # versions: + # - all + # - any + #- name: Fedora + # versions: + # - all + # - 16 + # - 17 + # - 18 + # - 19 + # - 20 + #- name: SmartOS + # versions: + # - all + # - any + #- name: opensuse + # versions: + # - all + # - 12.1 + # - 12.2 + # - 12.3 + # - 13.1 + # - 13.2 + #- name: Amazon + # versions: + # - all + # - 2013.03 + # - 2013.09 + #- name: GenericBSD + # versions: + # - all + # - any + #- name: FreeBSD + # versions: + # - all + # - 8.0 + # - 8.1 + # - 8.2 + # - 8.3 + # - 8.4 + # - 9.0 + # - 9.1 + # - 9.1 + # - 9.2 + #- name: Ubuntu + # versions: + # - all + # - lucid + # - maverick + # - natty + # - oneiric + # - precise + # - quantal + # - raring + # - saucy + # - trusty + #- name: SLES + # versions: + # - all + # - 10SP3 + # - 10SP4 + # - 11 + # - 11SP1 + # - 11SP2 + # - 11SP3 + #- name: GenericLinux + # versions: + # - all + # - any + #- name: Debian + # versions: + # - all + # - etch + # - lenny + # - squeeze + # - wheezy + # + # Below are all categories currently available. Just as with + # the platforms above, uncomment those that apply to your role. + # + #categories: + #- cloud + #- cloud:ec2 + #- cloud:gce + #- cloud:rax + #- clustering + #- database + #- database:nosql + #- database:sql + #- development + #- monitoring + #- networking + #- packaging + #- system + #- web +dependencies: [] + # List your role dependencies here, one per line. Only + # dependencies available via galaxy should be listed here. + # Be sure to remove the '[]' above if you add dependencies + # to this list. + diff --git a/roles/openshift_register_nodes/tasks/main.yml b/roles/openshift_register_nodes/tasks/main.yml new file mode 100644 index 000000000..59216fc87 --- /dev/null +++ b/roles/openshift_register_nodes/tasks/main.yml @@ -0,0 +1,71 @@ +--- +# TODO: support configuration for multiple masters, currently hardcoding +# the info from the first master + +# TODO: create a failed_when condition +- name: Create node server certificates + command: > + /usr/bin/openshift admin create-server-cert + --overwrite=false + --cert={{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/server.crt + --key={{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/server.key + --hostnames={{ [openshift_hostname, openshift_public_hostname, openshift_ip, openshift_public_ip]|join(",") }} + args: + chdir: "{{ openshift_cert_dir_parent }}" + creates: "{{ openshift_cert_dir_abs }}/node-{{ item.openshift_node_hostname }}/server.crt" + with_items: openshift_nodes + register: server_cert_result + +# TODO: create a failed_when condition +- name: Create node client certificates + command: > + /usr/bin/openshift admin create-node-cert + --overwrite=false + --cert={{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/cert.crt + --key={{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/key.key + --node-name={{ item.openshift_node_hostname }} + args: + chdir: "{{ openshift_cert_dir_parent }}" + creates: "{{ openshift_cert_dir_abs }}/node-{{ item.openshift_node_hostname }}/cert.crt" + with_items: openshift_nodes + register: node_cert_result + +# TODO: re-create kubeconfig if certs were regenerated, not just if +# .kubeconfig doesn't exist +# TODO: create a failed_when condition +- name: Create kubeconfigs for nodes + command: > + /usr/bin/openshift admin create-kubeconfig + --client-certificate={{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/cert.crt + --client-key={{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/key.key + --kubeconfig={{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/.kubeconfig + --master={{ openshift_master_urls[0] }} + --public-master={{ openshift_master_public_urls[0] }} + args: + chdir: "{{ openshift_cert_dir_parent }}" + creates: "{{ openshift_cert_dir_abs }}/node-{{ item.openshift_node_hostname }}/.kubeconfig" + with_items: openshift_nodes + register: kubeconfig_result + +# TODO: generate the node configs (openshift start node --write-config +# --config='{{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/node.yaml' +# --kubeconfig='{{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/.kubeconfig' +# will need to modify the generated node config as needed +# (servingInfo.{certFile,clientCA,keyFile}) + +- name: Register unregistered nodes + kubernetes_register_node: + name: "{{ item.openshift_node_name }}" + api_version: "{{ openshift_kube_api_version }}" + cpu: "{{ item.openshift_node_cpu if item.openshift_node_cpu else None }}" + memory: "{{ item.openshift_node_memory if item.openshift_node_memory else None }}" + pod_cidr: "{{ item.openshift_node_pod_cidr if item.openshift_node_pod_cidr else None }}" + host_ip: "{{ item.openshift_node_host_ip }}" + labels: "{{ item.openshift_node_labels if item.openshift_node_labels else {} }}" + annotations: "{{ item.openshift_node_annotations if item.openshift_node_annotations else {} }}" + # TODO: support customizing other attributes such as: client_config, + # client_cluster, client_context, client_user + # TODO: update for v1beta3 changes after rebase: hostnames, external_ips, + # internal_ips, external_id + with_items: openshift_nodes + register: register_result diff --git a/roles/openshift_sdn_node/README.md b/roles/openshift_sdn_node/README.md index 294550219..33197c241 100644 --- a/roles/openshift_sdn_node/README.md +++ b/roles/openshift_sdn_node/README.md @@ -29,7 +29,7 @@ From openshift_common: | openshift_debug_level | 0 | Global openshift debug log verbosity | | openshift_hostname_workaround | True | | | openshift_public_ip | UNDEF (Required) | Public IP address to use for this host | -| openshift_hostname | openshift_public_ip if openshift_hostname_workaround else ansible_fqdn | hostname to use for this instance | +| openshift_hostname | UNDEF (Required) | hostname to use for this instance | Dependencies ------------ -- cgit v1.2.3 From de1391db4309f020b5c8467597eef527b560bbaa Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Mon, 23 Mar 2015 23:36:08 -0400 Subject: remove openshift_hostname_workaround var for openshift_common, rather rely on inventory/playbook variables for openshift_hostname --- roles/openshift_common/README.md | 1 - roles/openshift_common/defaults/main.yml | 5 ----- roles/openshift_master/README.md | 1 - roles/openshift_node/README.md | 1 - roles/openshift_sdn_node/README.md | 1 - 5 files changed, 9 deletions(-) diff --git a/roles/openshift_common/README.md b/roles/openshift_common/README.md index 592a276f9..880d66e2c 100644 --- a/roles/openshift_common/README.md +++ b/roles/openshift_common/README.md @@ -15,7 +15,6 @@ Role Variables | Name | Default value | | |-------------------------------|------------------------------|----------------------------------------| | openshift_debug_level | 0 | Global openshift debug log verbosity | -| openshift_hostname_workaround | True | Workaround needed to set hostname to IP address | | openshift_hostname | UNDEF (Required) | hostname to use for this instance | | openshift_public_ip | UNDEF (Required) | Public IP address to use for this host | | openshift_env | default | Envrionment name if multiple OpenShift instances | diff --git a/roles/openshift_common/defaults/main.yml b/roles/openshift_common/defaults/main.yml index 86351f6f6..22b2c6ffd 100644 --- a/roles/openshift_common/defaults/main.yml +++ b/roles/openshift_common/defaults/main.yml @@ -1,7 +1,2 @@ --- openshift_debug_level: 0 - -# TODO: Once openshift stops resolving hostnames for node queries remove -# this... -openshift_hostname_workaround: true - diff --git a/roles/openshift_master/README.md b/roles/openshift_master/README.md index 2f03b4990..2d898bc3b 100644 --- a/roles/openshift_master/README.md +++ b/roles/openshift_master/README.md @@ -25,7 +25,6 @@ From openshift_common: | Name | Default Value | | |-------------------------------|---------------------|---------------------| | openshift_debug_level | 0 | Global openshift debug log verbosity | -| openshift_hostname_workaround | True | | | openshift_public_ip | UNDEF (Required) | Public IP address to use for this host | | openshift_hostname | UNDEF (Required) | hostname to use for this instance | diff --git a/roles/openshift_node/README.md b/roles/openshift_node/README.md index d537a35a5..c9b4eab34 100644 --- a/roles/openshift_node/README.md +++ b/roles/openshift_node/README.md @@ -26,7 +26,6 @@ From openshift_common: | Name | Default Value | | |-------------------------------|---------------------|---------------------| | openshift_debug_level | 0 | Global openshift debug log verbosity | -| openshift_hostname_workaround | True | | | openshift_public_ip | UNDEF (Required) | Public IP address to use for this host | | openshift_hostname | UNDEF (Required) | hostname to use for this instance | diff --git a/roles/openshift_sdn_node/README.md b/roles/openshift_sdn_node/README.md index 33197c241..2da2d74eb 100644 --- a/roles/openshift_sdn_node/README.md +++ b/roles/openshift_sdn_node/README.md @@ -27,7 +27,6 @@ From openshift_common: | Name | Default value | | |-------------------------------|---------------------|----------------------------------------| | openshift_debug_level | 0 | Global openshift debug log verbosity | -| openshift_hostname_workaround | True | | | openshift_public_ip | UNDEF (Required) | Public IP address to use for this host | | openshift_hostname | UNDEF (Required) | hostname to use for this instance | -- cgit v1.2.3 From 01ee65e99d39265f7d8db3ddbeca5d59ddfa2038 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Mon, 23 Mar 2015 23:37:19 -0400 Subject: gce inventory/playbook updates for node registration changes --- inventory/gce/group_vars/all | 3 +++ inventory/gce/group_vars/tag_host-type-master | 5 +++++ inventory/gce/group_vars/tag_host-type-node | 6 ++++++ inventory/gce/group_vars/tag_host-type-openshift-master | 1 + inventory/gce/group_vars/tag_host-type-openshift-node | 1 + playbooks/gce/openshift-node/config.yml | 6 +++--- 6 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 inventory/gce/group_vars/tag_host-type-master create mode 100644 inventory/gce/group_vars/tag_host-type-node create mode 120000 inventory/gce/group_vars/tag_host-type-openshift-master create mode 120000 inventory/gce/group_vars/tag_host-type-openshift-node diff --git a/inventory/gce/group_vars/all b/inventory/gce/group_vars/all index 4cd94c509..3e969df63 100644 --- a/inventory/gce/group_vars/all +++ b/inventory/gce/group_vars/all @@ -1,4 +1,7 @@ --- ansible_ssh_user: root +openshift_hostname: "{{ ansible_default_ipv4.address }}" +openshift_public_hostname: "{{ ansible_default_ipv4.address }}" +openshift_ip: "{{ ansible_default_ipv4.address }}" openshift_public_ip: "{{ gce_public_ip }}" openshift_env: "{{ oo_env }}" diff --git a/inventory/gce/group_vars/tag_host-type-master b/inventory/gce/group_vars/tag_host-type-master new file mode 100644 index 000000000..ddbdc650c --- /dev/null +++ b/inventory/gce/group_vars/tag_host-type-master @@ -0,0 +1,5 @@ +--- +openshift_api_url: https://{{ openshift_hostname }}:8443 +openshift_api_public_url: https://{{ openshift_public_hostname }}:8443 +openshift_webui_url: https://{{ openshift_hostname }}:8444 +openshift_webui_public_url: https://{{ openshift_public_hostname }}:8444 diff --git a/inventory/gce/group_vars/tag_host-type-node b/inventory/gce/group_vars/tag_host-type-node new file mode 100644 index 000000000..bb95a724d --- /dev/null +++ b/inventory/gce/group_vars/tag_host-type-node @@ -0,0 +1,6 @@ +--- +openshift_node_cpu: +openshift_node_memory: +openshift_node_pod_cidr: +openshift_node_labels: {} +openshift_node_annotations: {} diff --git a/inventory/gce/group_vars/tag_host-type-openshift-master b/inventory/gce/group_vars/tag_host-type-openshift-master new file mode 120000 index 000000000..c0c4cf370 --- /dev/null +++ b/inventory/gce/group_vars/tag_host-type-openshift-master @@ -0,0 +1 @@ +tag_host-type-master \ No newline at end of file diff --git a/inventory/gce/group_vars/tag_host-type-openshift-node b/inventory/gce/group_vars/tag_host-type-openshift-node new file mode 120000 index 000000000..ebbce6136 --- /dev/null +++ b/inventory/gce/group_vars/tag_host-type-openshift-node @@ -0,0 +1 @@ +tag_host-type-node \ No newline at end of file diff --git a/playbooks/gce/openshift-node/config.yml b/playbooks/gce/openshift-node/config.yml index d24acb8fa..bf28fc81d 100644 --- a/playbooks/gce/openshift-node/config.yml +++ b/playbooks/gce/openshift-node/config.yml @@ -6,12 +6,12 @@ add_host: "name={{ item }} groups=oo_nodes_to_config" with_items: "{{ oo_host_group_exp | default('') }}" when: oo_host_group_exp is defined - - name: Find masters for env + - name: Find masters for env add_host: "name={{ item }} groups=oo_masters_for_node_config" with_items: groups['tag_env-host-type-' + oo_env + '-openshift-master'] - name: Gather facts for masters in {{ oo_env }} - hosts: "tag_env-host-type-{{ oo_env }}-openshift-master" + hosts: tag_env-host-type-{{ oo_env }}-openshift-master tasks: - set_fact: openshift_master_ip: "{{ openshift_ip }}" @@ -68,7 +68,7 @@ # - name: Configure instances hosts: oo_nodes_to_config -vars_files: + vars_files: - vars.yml vars: openshift_master_group: tag_env-host-type-{{ oo_env }}-openshift-master -- cgit v1.2.3 From 41740bc6e177e58a0aa817e2d940e60be51d3bfe Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Tue, 24 Mar 2015 09:43:36 -0700 Subject: Revert "Jwhonce wip/cluster" --- playbooks/gce/openshift-node/config.yml | 1 - roles/docker/tasks/main.yml | 2 +- roles/os_env_extras_node/README.md | 38 ------- roles/os_env_extras_node/files/enter-container.sh | 13 --- roles/os_env_extras_node/meta/main.yml | 124 ---------------------- roles/os_env_extras_node/tasks/main.yml | 7 -- roles/os_firewall/tasks/firewall/iptables.yml | 8 ++ 7 files changed, 9 insertions(+), 184 deletions(-) delete mode 100644 roles/os_env_extras_node/README.md delete mode 100755 roles/os_env_extras_node/files/enter-container.sh delete mode 100644 roles/os_env_extras_node/meta/main.yml delete mode 100644 roles/os_env_extras_node/tasks/main.yml diff --git a/playbooks/gce/openshift-node/config.yml b/playbooks/gce/openshift-node/config.yml index bf28fc81d..e0d074572 100644 --- a/playbooks/gce/openshift-node/config.yml +++ b/playbooks/gce/openshift-node/config.yml @@ -120,4 +120,3 @@ roles: - openshift_node - os_env_extras - - os_env_extras_node diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml index 593c4c877..ca700db17 100644 --- a/roles/docker/tasks/main.yml +++ b/roles/docker/tasks/main.yml @@ -1,7 +1,7 @@ --- # tasks file for docker - name: Install docker - yum: pkg=docker + yum: pkg=docker-io - name: enable and start the docker service service: name=docker enabled=yes state=started diff --git a/roles/os_env_extras_node/README.md b/roles/os_env_extras_node/README.md deleted file mode 100644 index 225dd44b9..000000000 --- a/roles/os_env_extras_node/README.md +++ /dev/null @@ -1,38 +0,0 @@ -Role Name -========= - -A brief description of the role goes here. - -Requirements ------------- - -Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. - -Role Variables --------------- - -A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. - -Dependencies ------------- - -A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. - -Example Playbook ----------------- - -Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: - - - hosts: servers - roles: - - { role: username.rolename, x: 42 } - -License -------- - -BSD - -Author Information ------------------- - -An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/roles/os_env_extras_node/files/enter-container.sh b/roles/os_env_extras_node/files/enter-container.sh deleted file mode 100755 index 7cf5b8d83..000000000 --- a/roles/os_env_extras_node/files/enter-container.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -if [ $# -ne 1 ] -then - echo - echo "Usage: $(basename $0) " - echo - exit 1 -fi - -PID=$(docker inspect --format '{{.State.Pid}}' $1) - -nsenter --target $PID --mount --uts --ipc --net --pid diff --git a/roles/os_env_extras_node/meta/main.yml b/roles/os_env_extras_node/meta/main.yml deleted file mode 100644 index c5c362c60..000000000 --- a/roles/os_env_extras_node/meta/main.yml +++ /dev/null @@ -1,124 +0,0 @@ ---- -galaxy_info: - author: your name - description: - company: your company (optional) - # Some suggested licenses: - # - BSD (default) - # - MIT - # - GPLv2 - # - GPLv3 - # - Apache - # - CC-BY - license: license (GPLv2, CC-BY, etc) - min_ansible_version: 1.2 - # - # Below are all platforms currently available. Just uncomment - # the ones that apply to your role. If you don't see your - # platform on this list, let us know and we'll get it added! - # - #platforms: - #- name: EL - # versions: - # - all - # - 5 - # - 6 - # - 7 - #- name: GenericUNIX - # versions: - # - all - # - any - #- name: Fedora - # versions: - # - all - # - 16 - # - 17 - # - 18 - # - 19 - # - 20 - #- name: opensuse - # versions: - # - all - # - 12.1 - # - 12.2 - # - 12.3 - # - 13.1 - # - 13.2 - #- name: Amazon - # versions: - # - all - # - 2013.03 - # - 2013.09 - #- name: GenericBSD - # versions: - # - all - # - any - #- name: FreeBSD - # versions: - # - all - # - 8.0 - # - 8.1 - # - 8.2 - # - 8.3 - # - 8.4 - # - 9.0 - # - 9.1 - # - 9.1 - # - 9.2 - #- name: Ubuntu - # versions: - # - all - # - lucid - # - maverick - # - natty - # - oneiric - # - precise - # - quantal - # - raring - # - saucy - # - trusty - #- name: SLES - # versions: - # - all - # - 10SP3 - # - 10SP4 - # - 11 - # - 11SP1 - # - 11SP2 - # - 11SP3 - #- name: GenericLinux - # versions: - # - all - # - any - #- name: Debian - # versions: - # - all - # - etch - # - lenny - # - squeeze - # - wheezy - # - # Below are all categories currently available. Just as with - # the platforms above, uncomment those that apply to your role. - # - #categories: - #- cloud - #- cloud:ec2 - #- cloud:gce - #- cloud:rax - #- clustering - #- database - #- database:nosql - #- database:sql - #- development - #- monitoring - #- networking - #- packaging - #- system - #- web -dependencies: [] - # List your role dependencies here, one per line. Only - # dependencies available via galaxy should be listed here. - # Be sure to remove the '[]' above if you add dependencies - # to this list. - diff --git a/roles/os_env_extras_node/tasks/main.yml b/roles/os_env_extras_node/tasks/main.yml deleted file mode 100644 index 065f71f74..000000000 --- a/roles/os_env_extras_node/tasks/main.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -- copy: src=enter-container.sh dest=/usr/local/bin/enter-container.sh mode=0755 - -# From the origin rpm there exists instructions on how to -# setup origin properly. The following steps come from there -- name: Change root to be in the Docker group - user: name=root groups=dockerroot append=yes diff --git a/roles/os_firewall/tasks/firewall/iptables.yml b/roles/os_firewall/tasks/firewall/iptables.yml index 87e77c083..72a3401cf 100644 --- a/roles/os_firewall/tasks/firewall/iptables.yml +++ b/roles/os_firewall/tasks/firewall/iptables.yml @@ -41,6 +41,14 @@ changed_when: "'firewalld' in result.stdout" when: pkg_check.rc == 0 +# Workaround for Docker 1.4 to create DOCKER chain +- name: Add DOCKER chain + os_firewall_manage_iptables: + name: "DOCKER chain" + action: verify_chain + create_jump_rule: no +# End of Docker 1.4 workaround + - name: Add iptables allow rules os_firewall_manage_iptables: name: "{{ item.service }}" -- cgit v1.2.3 From fa746f02aa275cf8e1cbe9f90ec41fc27806a0bd Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Tue, 24 Mar 2015 10:49:15 -0700 Subject: * repos role renamed to openshift_repos --- playbooks/gce/openshift-cluster/launch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/gce/openshift-cluster/launch.yml b/playbooks/gce/openshift-cluster/launch.yml index b30452725..889d92d40 100644 --- a/playbooks/gce/openshift-cluster/launch.yml +++ b/playbooks/gce/openshift-cluster/launch.yml @@ -49,7 +49,7 @@ - hosts: "tag_env-{{ cluster_id }}" roles: - - repos + - openshift_repos - os_update_latest - include: ../openshift-master/config.yml -- cgit v1.2.3 From 96729907e131f0cef6f37bcca062e9b092e67d29 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Tue, 24 Mar 2015 13:15:53 -0400 Subject: Added spec files and tito configs. --- BUILD.md | 44 ++++++++++++++++++++++++++++++ README.md | 3 ++ bin/README_BUILD | 25 ----------------- bin/openshift-ansible-bin.spec | 14 +++++----- inventory/openshift-ansible-inventory.spec | 37 +++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 32 deletions(-) create mode 100644 BUILD.md delete mode 100644 bin/README_BUILD create mode 100644 inventory/openshift-ansible-inventory.spec diff --git a/BUILD.md b/BUILD.md new file mode 100644 index 000000000..0016c96a5 --- /dev/null +++ b/BUILD.md @@ -0,0 +1,44 @@ +# openshift-ansible RPM Build instructions +We use tito to make building and tracking revisions easy. + +For more information on tito, please see the [Tito home page](http://rm-rf.ca/tito "Tito home page"). + + +## Build openshift-ansible-bin +- Change into openshift-ansible/bin +``` +cd openshift-ansible/bin +``` +- Build a test package (no tagging needed) +``` +tito build --test --rpm +``` +- Tag a new build (bumps version number and adds log entries) +``` +tito tag +``` +- Follow the on screen tito instructions to push the tags +- Build a new package based on the latest tag information +``` +tito build --rpm +``` + + +## Build openshift-ansible-inventory +- Change into openshift-ansible/inventory +``` +cd openshift-ansible/inventory +``` +- Build a test package (no tagging needed) +``` +tito build --test --rpm +``` +- Tag a new build (bumps version number and adds log entries) +``` +tito tag +``` +- Follow the on screen tito instructions to push the tags +- Build a new package based on the latest tag information +``` +tito build --rpm +``` diff --git a/README.md b/README.md index ffdfee6f2..9a08bccd9 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,9 @@ Setup - [AWS](README_AWS.md) - [GCE](README_GCE.md) +- Build + - [How to build the openshift-ansible rpms](BUILD.md) + - Directory Structure: - [cloud.rb](cloud.rb) - light wrapper around Ansible - [cluster.sh](cluster.sh) - easily create OpenShift 3 clusters diff --git a/bin/README_BUILD b/bin/README_BUILD deleted file mode 100644 index 50010e562..000000000 --- a/bin/README_BUILD +++ /dev/null @@ -1,25 +0,0 @@ -# openshift-ansible-bin RPM Build instructions -We use tito to make building and tracking revisions easy. - -For more information on tito, please see the [Tito home page](http://rm-rf.ca/tito "Tito home page"). - - -## Build a test package (no tagging needed) -``` -tito build --test --rpm -``` - - -## Tag a new build (bumps version number and adds log entries) -``` -tito tag -``` - -Follow the on screen tito instructions. - - - -## Build a new package based on the latest tag information -``` -tito build --rpm -``` diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec index 2b83a7d0b..7ca0cbe9d 100644 --- a/bin/openshift-ansible-bin.spec +++ b/bin/openshift-ansible-bin.spec @@ -1,11 +1,11 @@ -Summary: OpenShift Operations files for mirror +Summary: OpenShift Ansible Scripts for working with metadata hosts Name: openshift-ansible-bin -Version: 0.0.1 +Version: 0.0.0 Release: 1%{?dist} License: ASL 2.0 URL: https://github.com/openshift/openshift-ansible Source0: %{name}-%{version}.tar.gz -Requires: python2 +Requires: python2, openshift-ansible-inventory BuildRequires: python2-devel BuildArch: noarch @@ -18,17 +18,17 @@ Scripts to make it nicer when working with hosts that are defined only by metada %build %install -mkdir -p %{buildroot}/usr/bin +mkdir -p %{buildroot}%{_bindir} mkdir -p %{buildroot}%{python_sitelib}/openshift_ansible mkdir -p %{buildroot}/etc/bash_completion.d -cp -p ossh oscp opssh %{buildroot}/usr/bin +cp -p ossh oscp opssh %{buildroot}%{_bindir} cp -p awsutil.py %{buildroot}%{python_sitelib}/openshift_ansible cp -p ossh_bash_completion %{buildroot}/etc/bash_completion.d %files -/usr/bin/* -%{python_sitelib}/openshift_ansible/* +%{_bindir}/* +%{python_sitelib}/openshift_ansible/ /etc/bash_completion.d/* %changelog diff --git a/inventory/openshift-ansible-inventory.spec b/inventory/openshift-ansible-inventory.spec new file mode 100644 index 000000000..156b81b86 --- /dev/null +++ b/inventory/openshift-ansible-inventory.spec @@ -0,0 +1,37 @@ +Summary: OpenShift Ansible Inventories +Name: openshift-ansible-inventory +Version: 0.0.0 +Release: 1%{?dist} +License: ASL 2.0 +URL: https://github.com/openshift/openshift-ansible +Source0: %{name}-%{version}.tar.gz +Requires: python2 +BuildRequires: python2-devel +BuildArch: noarch + +%description +Ansible Inventories used with the openshift-ansible scripts and playbooks. + +%prep +%setup -q + +%build + +%install +mkdir -p %{buildroot}/usr/share/ansible/inventory +mkdir -p %{buildroot}/usr/share/ansible/inventory/aws +mkdir -p %{buildroot}/usr/share/ansible/inventory/gce + +cp -p multi_ec2.py multi_ec2.yaml.example %{buildroot}/usr/share/ansible/inventory +cp -p aws/ec2.py aws/ec2.ini %{buildroot}/usr/share/ansible/inventory/aws +cp -p gce/gce.py %{buildroot}/usr/share/ansible/inventory/gce + +%files +%dir /usr/share/ansible/inventory +/usr/share/ansible/inventory/multi_ec2.py* +/usr/share/ansible/inventory/multi_ec2.yaml.example +/usr/share/ansible/inventory/aws/ec2.py* +%config(noreplace) /usr/share/ansible/inventory/aws/ec2.ini +/usr/share/ansible/inventory/gce/gce.py* + +%changelog -- cgit v1.2.3 From 4dc8ca74f47bcbe0fd6285b0d73cc5b193be17a9 Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Tue, 24 Mar 2015 12:40:21 -0700 Subject: * Remove DOCKER chain work around --- roles/os_firewall/tasks/firewall/iptables.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/roles/os_firewall/tasks/firewall/iptables.yml b/roles/os_firewall/tasks/firewall/iptables.yml index 72a3401cf..87e77c083 100644 --- a/roles/os_firewall/tasks/firewall/iptables.yml +++ b/roles/os_firewall/tasks/firewall/iptables.yml @@ -41,14 +41,6 @@ changed_when: "'firewalld' in result.stdout" when: pkg_check.rc == 0 -# Workaround for Docker 1.4 to create DOCKER chain -- name: Add DOCKER chain - os_firewall_manage_iptables: - name: "DOCKER chain" - action: verify_chain - create_jump_rule: no -# End of Docker 1.4 workaround - - name: Add iptables allow rules os_firewall_manage_iptables: name: "{{ item.service }}" -- cgit v1.2.3 From e7797109bb0cc162dce6f78ed57343a832330910 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Tue, 24 Mar 2015 16:14:53 -0400 Subject: Automatic commit of package [openshift-ansible-bin] release [0.0.1-1]. --- bin/openshift-ansible-bin.spec | 5 ++++- rel-eng/packages/openshift-ansible-bin | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 rel-eng/packages/openshift-ansible-bin diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec index 7ca0cbe9d..86b1d4fdf 100644 --- a/bin/openshift-ansible-bin.spec +++ b/bin/openshift-ansible-bin.spec @@ -1,6 +1,6 @@ Summary: OpenShift Ansible Scripts for working with metadata hosts Name: openshift-ansible-bin -Version: 0.0.0 +Version: 0.0.1 Release: 1%{?dist} License: ASL 2.0 URL: https://github.com/openshift/openshift-ansible @@ -32,3 +32,6 @@ cp -p ossh_bash_completion %{buildroot}/etc/bash_completion.d /etc/bash_completion.d/* %changelog +* Tue Mar 24 2015 Thomas Wiest 0.0.1-1 +- new package built with tito + diff --git a/rel-eng/packages/openshift-ansible-bin b/rel-eng/packages/openshift-ansible-bin new file mode 100644 index 000000000..098772960 --- /dev/null +++ b/rel-eng/packages/openshift-ansible-bin @@ -0,0 +1 @@ +0.0.1-1 bin/ -- cgit v1.2.3 From 43ed89371aa2fce56d5e2b41af35a3ae902e92e6 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Tue, 24 Mar 2015 16:19:46 -0400 Subject: Automatic commit of package [openshift-ansible-inventory] release [0.0.1-1]. --- inventory/openshift-ansible-inventory.spec | 5 ++++- rel-eng/packages/openshift-ansible-inventory | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 rel-eng/packages/openshift-ansible-inventory diff --git a/inventory/openshift-ansible-inventory.spec b/inventory/openshift-ansible-inventory.spec index 156b81b86..e847df189 100644 --- a/inventory/openshift-ansible-inventory.spec +++ b/inventory/openshift-ansible-inventory.spec @@ -1,6 +1,6 @@ Summary: OpenShift Ansible Inventories Name: openshift-ansible-inventory -Version: 0.0.0 +Version: 0.0.1 Release: 1%{?dist} License: ASL 2.0 URL: https://github.com/openshift/openshift-ansible @@ -35,3 +35,6 @@ cp -p gce/gce.py %{buildroot}/usr/share/ansible/inventory/gce /usr/share/ansible/inventory/gce/gce.py* %changelog +* Tue Mar 24 2015 Thomas Wiest 0.0.1-1 +- new package built with tito + diff --git a/rel-eng/packages/openshift-ansible-inventory b/rel-eng/packages/openshift-ansible-inventory new file mode 100644 index 000000000..21f4631fc --- /dev/null +++ b/rel-eng/packages/openshift-ansible-inventory @@ -0,0 +1 @@ +0.0.1-1 inventory/ -- cgit v1.2.3 From 16cac480197bfe1738b785aed55204b53d06ad57 Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Tue, 24 Mar 2015 17:05:13 -0700 Subject: * Refactor bin/cluster to use argparse.subparsers --- bin/cluster | 182 +++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 126 insertions(+), 56 deletions(-) diff --git a/bin/cluster b/bin/cluster index 823f50671..b99286b46 100755 --- a/bin/cluster +++ b/bin/cluster @@ -8,33 +8,79 @@ import os class Cluster(object): - """Python wrapper to ensure environment is correct for running ansible playbooks """ - - def __init__(self, args): - self.args = args - + Control and Configuration Interface for OpenShift Clusters + """ + def __init__(self): # setup ansible ssh environment if 'ANSIBLE_SSH_ARGS' not in os.environ: os.environ['ANSIBLE_SSH_ARGS'] = ( - '-o ForwardAgent=yes' - ' -o StrictHostKeyChecking=no' - ' -o UserKnownHostsFile=/dev/null' - ' -o ControlMaster=auto' - ' -o ControlPersist=600s' + '-o ForwardAgent=yes ' + '-o StrictHostKeyChecking=no ' + '-o UserKnownHostsFile=/dev/null ' + '-o ControlMaster=auto ' + '-o ControlPersist=600s ' ) - def apply(self): - # setup ansible playbook environment + def create(self, args): + """ + Create an OpenShift cluster for given provider + :param args: command line arguments provided by user + :return: exit status from run command + """ + env = {'cluster_id': args.cluster_id} + playbook = "playbooks/{}/openshift-cluster/launch.yml".format(args.provider) + inventory = self.setup_provider(args.provider) + + env['masters'] = args.masters + env['nodes'] = args.nodes + + return self.action(args, inventory, env, playbook) + + def terminate(self, args): + """ + Destroy OpenShift cluster + :param args: command line arguments provided by user + :return: exit status from run command + """ + env = {'cluster_id': args.cluster_id} + playbook = "playbooks/{}/openshift-cluster/terminate.yml".format(args.provider) + inventory = self.setup_provider(args.provider) + + return self.action(args, inventory, env, playbook) + + def list(self, args): + """ + List VMs in cluster + :param args: command line arguments provided by user + :return: exit status from run command + """ + raise NotImplementedError("ACTION [{}] not implemented".format(sys._getframe().f_code.co_name)) + + def update(self, args): + """ + Update OpenShift across clustered VMs + :param args: command line arguments provided by user + :return: exit status from run command + """ + raise NotImplementedError("ACTION [{}] not implemented".format(sys._getframe().f_code.co_name)) + + + def setup_provider(self, provider): + """ + Setup ansible playbook environment + :param provider: command line arguments provided by user + :return: path to inventory for given provider + """ config = ConfigParser.ConfigParser() - if 'gce' == self.args.provider: + if 'gce' == provider: config.readfp(open('inventory/gce/gce.ini')) for key in config.options('gce'): os.environ[key] = config.get('gce', key) inventory = '-i inventory/gce/gce.py' - elif 'aws' == self.args.provider: + elif 'aws' == provider: config.readfp(open('inventory/aws/ec2.ini')) for key in config.options('ec2'): @@ -43,30 +89,23 @@ class Cluster(object): inventory = '-i inventory/aws/ec2.py' else: # this code should never be reached - raise argparse.ArgumentError("invalid PROVIDER {}".format(self.args.provider)) - - env = {'cluster_id': self.args.cluster_id} - - if 'create' == self.args.action: - playbook = "playbooks/{}/openshift-cluster/launch.yml".format(self.args.provider) - env['masters'] = self.args.masters - env['nodes'] = self.args.nodes - - elif 'terminate' == self.args.action: - playbook = "playbooks/{}/openshift-cluster/terminate.yml".format(self.args.provider) - elif 'list' == self.args.action: - # todo: implement cluster list - raise argparse.ArgumentError("ACTION {} not implemented".format(self.args.action)) - elif 'update' == self.args.action: - # todo: implement cluster update - raise argparse.ArgumentError("ACTION {} not implemented".format(self.args.action)) - else: - # this code should never be reached - raise argparse.ArgumentError("invalid ACTION {}".format(self.args.action)) + raise ValueError("invalid PROVIDER {}".format(provider)) + + return inventory + + def action(self, args, inventory, env, playbook): + """ + Build ansible-playbook command line and execute + :param args: command line arguments provided by user + :param inventory: derived provider library + :param env: environment variables for kubernetes + :param playbook: ansible playbook to execute + :return: exit status from ansible-playbook command + """ verbose = '' - if self.args.verbose > 0: - verbose = '-{}'.format('v' * self.args.verbose) + if args.verbose > 0: + verbose = '-{}'.format('v' * args.verbose) ansible_env = '-e \'{}\''.format( ' '.join(['%s=%s' % (key, value) for (key, value) in env.items()]) @@ -76,36 +115,67 @@ class Cluster(object): verbose, inventory, ansible_env, playbook ) - if self.args.verbose > 1: + if args.verbose > 1: command = 'time {}'.format(command) - if self.args.verbose > 0: + if args.verbose > 0: sys.stderr.write('RUN [{}]\n'.format(command)) sys.stderr.flush() - status = os.system(command) - if status != 0: - sys.stderr.write("RUN [{}] failed with exit status %d".format(command, status)) - exit(status) - + return os.system(command) if __name__ == '__main__': - parser = argparse.ArgumentParser(description='Manage OpenShift Cluster') - parser.add_argument('-m', '--masters', default=1, type=int, help='number of masters to create in cluster') - parser.add_argument('-n', '--nodes', default=2, type=int, help='number of nodes to create in cluster') + """ + Implemented to support writing unit tests + """ + + cluster = Cluster() + + providers = ['gce', 'aws'] + parser = argparse.ArgumentParser( + description='Python wrapper to ensure proper environment for OpenShift ansible playbooks', + ) parser.add_argument('-v', '--verbose', action='count', help='Multiple -v options increase the verbosity') - parser.add_argument('--version', action='version', version='%(prog)s 0.1') - parser.add_argument('action', choices=['create', 'terminate', 'update', 'list']) - parser.add_argument('provider', choices=['gce', 'aws']) - parser.add_argument('cluster_id', help='prefix for cluster VM names') + parser.add_argument('--version', action='version', version='%(prog)s 0.2') + + meta_parser = argparse.ArgumentParser(add_help=False) + meta_parser.add_argument('provider', choices=providers, help='provider') + meta_parser.add_argument('cluster_id', help='prefix for cluster VM names') + + action_parser = parser.add_subparsers(dest='action', title='actions', description='Choose from valid actions') + + create_parser = action_parser.add_parser('create', help='Create a cluster', parents=[meta_parser]) + create_parser.add_argument('-m', '--masters', default=1, type=int, help='number of masters to create in cluster') + create_parser.add_argument('-n', '--nodes', default=2, type=int, help='number of nodes to create in cluster') + create_parser.set_defaults(func=cluster.create) + + terminate_parser = action_parser.add_parser('terminate', help='Destroy a cluster', parents=[meta_parser]) + terminate_parser.add_argument('-f', '--force', action='store_true', help='Destroy cluster without confirmation') + terminate_parser.set_defaults(func=cluster.terminate) + + update_parser = action_parser.add_parser('update', help='Update OpenShift across cluster', parents=[meta_parser]) + update_parser.add_argument('-f', '--force', action='store_true', help='Update cluster without confirmation') + update_parser.set_defaults(func=cluster.update) + + list_parser = action_parser.add_parser('list', help='List VMs in cluster', parents=[meta_parser]) + list_parser.set_defaults(func=cluster.list) + args = parser.parse_args() - if 'terminate' == args.action: - sys.stderr.write("This will terminate the ENTIRE {} environment. Are you sure? [y/N] ".format(args.cluster_id)) - sys.stderr.flush() - answer = sys.stdin.read(1) + if 'terminate' == args.action and not args.force: + answer = raw_input("This will destroy the ENTIRE {} environment. Are you sure? [y/N] ".format(args.cluster_id)) + if answer not in ['y', 'Y']: + sys.stderr.write('\nACTION [terminate] aborted by user!\n') + exit(1) + + if 'update' == args.action and not args.force: + answer = raw_input("This is destructive and could corrupt {} environment. Continue? [y/N] ".format(args.cluster_id)) if answer not in ['y', 'Y']: - exit(0) + sys.stderr.write('\nACTION [update] aborted by user!\n') + exit(1) - Cluster(args).apply() + status = args.func(args) + if status != 0: + sys.stderr.write("ACTION [{}] failed with exit status {}\n".format(args.action, status)) + exit(status) -- cgit v1.2.3 From f79f6d649a4c8599121d9cad5492afc579f0425a Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Wed, 25 Mar 2015 16:45:50 -0400 Subject: added the ability to have a config file in /etc/openshift_ansible to multi_ec2.py. --- inventory/multi_ec2.py | 17 +++++++++++++++-- inventory/openshift-ansible-inventory.spec | 6 ++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/inventory/multi_ec2.py b/inventory/multi_ec2.py index 5dee7972b..26c09d712 100755 --- a/inventory/multi_ec2.py +++ b/inventory/multi_ec2.py @@ -12,6 +12,8 @@ import json import pprint +CONFIG_FILE_NAME = 'multi_ec2.yaml' + class MultiEc2(object): def __init__(self): @@ -20,11 +22,22 @@ class MultiEc2(object): self.result = {} self.cache_path = os.path.expanduser('~/.ansible/tmp/multi_ec2_inventory.cache') self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__))) - self.config_file = os.path.join(self.file_path,"multi_ec2.yaml") + + same_dir_config_file = os.path.join(self.file_path, CONFIG_FILE_NAME) + etc_dir_config_file = os.path.join(os.path.sep, 'etc','ansible', CONFIG_FILE_NAME) + + # Prefer a file in the same directory, fall back to a file in etc + if os.path.isfile(same_dir_config_file): + self.config_file = same_dir_config_file + elif os.path.isfile(etc_dir_config_file): + self.config_file = etc_dir_config_file + else: + self.config_file = None # expect env vars + self.parse_cli_args() # load yaml - if os.path.isfile(self.config_file): + if self.config_file and os.path.isfile(self.config_file): self.config = self.load_yaml_config() elif os.environ.has_key("AWS_ACCESS_KEY_ID") and os.environ.has_key("AWS_SECRET_ACCESS_KEY"): self.config = {} diff --git a/inventory/openshift-ansible-inventory.spec b/inventory/openshift-ansible-inventory.spec index e847df189..9b721818e 100644 --- a/inventory/openshift-ansible-inventory.spec +++ b/inventory/openshift-ansible-inventory.spec @@ -18,18 +18,20 @@ Ansible Inventories used with the openshift-ansible scripts and playbooks. %build %install +mkdir -p %{buildroot}/etc/ansible mkdir -p %{buildroot}/usr/share/ansible/inventory mkdir -p %{buildroot}/usr/share/ansible/inventory/aws mkdir -p %{buildroot}/usr/share/ansible/inventory/gce -cp -p multi_ec2.py multi_ec2.yaml.example %{buildroot}/usr/share/ansible/inventory +cp -p multi_ec2.py %{buildroot}/usr/share/ansible/inventory +cp -p multi_ec2.yaml.example %{buildroot}/etc/ansible/multi_ec2.yaml cp -p aws/ec2.py aws/ec2.ini %{buildroot}/usr/share/ansible/inventory/aws cp -p gce/gce.py %{buildroot}/usr/share/ansible/inventory/gce %files +%config(noreplace) /etc/ansible/* %dir /usr/share/ansible/inventory /usr/share/ansible/inventory/multi_ec2.py* -/usr/share/ansible/inventory/multi_ec2.yaml.example /usr/share/ansible/inventory/aws/ec2.py* %config(noreplace) /usr/share/ansible/inventory/aws/ec2.ini /usr/share/ansible/inventory/gce/gce.py* -- cgit v1.2.3 From 78a45fc50509eca27164452325529cc46a99cc8c Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Thu, 26 Mar 2015 11:14:30 -0400 Subject: Automatic commit of package [openshift-ansible-inventory] release [0.0.2-1]. --- inventory/openshift-ansible-inventory.spec | 10 +++++++++- rel-eng/packages/openshift-ansible-inventory | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/inventory/openshift-ansible-inventory.spec b/inventory/openshift-ansible-inventory.spec index 9b721818e..8267e16f6 100644 --- a/inventory/openshift-ansible-inventory.spec +++ b/inventory/openshift-ansible-inventory.spec @@ -1,6 +1,6 @@ Summary: OpenShift Ansible Inventories Name: openshift-ansible-inventory -Version: 0.0.1 +Version: 0.0.2 Release: 1%{?dist} License: ASL 2.0 URL: https://github.com/openshift/openshift-ansible @@ -37,6 +37,14 @@ cp -p gce/gce.py %{buildroot}/usr/share/ansible/inventory/gce /usr/share/ansible/inventory/gce/gce.py* %changelog +* Thu Mar 26 2015 Thomas Wiest 0.0.2-1 +- added the ability to have a config file in /etc/openshift_ansible to + multi_ec2.py. (twiest@redhat.com) +- Merge pull request #97 from jwhonce/wip/cluster (jhonce@redhat.com) +- gce inventory/playbook updates for node registration changes + (jdetiber@redhat.com) +- Various fixes (jdetiber@redhat.com) + * Tue Mar 24 2015 Thomas Wiest 0.0.1-1 - new package built with tito diff --git a/rel-eng/packages/openshift-ansible-inventory b/rel-eng/packages/openshift-ansible-inventory index 21f4631fc..cf3ac87ed 100644 --- a/rel-eng/packages/openshift-ansible-inventory +++ b/rel-eng/packages/openshift-ansible-inventory @@ -1 +1 @@ -0.0.1-1 inventory/ +0.0.2-1 inventory/ -- cgit v1.2.3 From b1b462f4db3ce1a26cfc251895d5f8fe2e15c484 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Mon, 30 Mar 2015 11:25:03 -0400 Subject: added config file support to opssh, ossh, and oscp --- bin/awsutil.py | 29 ++++++++++++++++------------- bin/openshift-ansible-bin.spec | 4 ++++ bin/openshift_ansible.conf.example | 6 ++++++ bin/opssh | 32 ++++++++++++++++++++++++++++++-- bin/oscp | 25 +++++++++++++++++++++++-- bin/ossh | 23 ++++++++++++++++++++++- 6 files changed, 101 insertions(+), 18 deletions(-) create mode 100644 bin/openshift_ansible.conf.example diff --git a/bin/awsutil.py b/bin/awsutil.py index 37259b946..78421e5f5 100644 --- a/bin/awsutil.py +++ b/bin/awsutil.py @@ -6,27 +6,30 @@ import json import re class AwsUtil(object): - def __init__(self): - self.host_type_aliases = { - 'legacy-openshift-broker': ['broker', 'ex-srv'], - 'openshift-node': ['node', 'ex-node'], - 'openshift-messagebus': ['msg'], - 'openshift-customer-database': ['mongo'], - 'openshift-website-proxy': ['proxy'], - 'openshift-community-website': ['drupal'], - 'package-mirror': ['mirror'], - } + def __init__(self, inventory_path=None, host_type_aliases={}): + self.host_type_aliases = host_type_aliases + self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__))) + + if inventory_path is None: + inventory_path = os.path.realpath(os.path.join(self.file_path, \ + '..','inventory','multi_ec2.py')) + + if not os.path.isfile(inventory_path): + raise Exception("Inventory file not found [%s]" % inventory_path) + self.inventory_path = inventory_path + self.setup_host_type_alias_lookup() + + def setup_host_type_alias_lookup(self): self.alias_lookup = {} for key, values in self.host_type_aliases.iteritems(): for value in values: self.alias_lookup[value] = key - self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__))) - self.multi_ec2_path = os.path.realpath(os.path.join(self.file_path, '..','inventory','multi_ec2.py')) + def get_inventory(self,args=[]): - cmd = [self.multi_ec2_path] + cmd = [self.inventory_path] if args: cmd.extend(args) diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec index 86b1d4fdf..1bd486bff 100644 --- a/bin/openshift-ansible-bin.spec +++ b/bin/openshift-ansible-bin.spec @@ -21,15 +21,19 @@ Scripts to make it nicer when working with hosts that are defined only by metada mkdir -p %{buildroot}%{_bindir} mkdir -p %{buildroot}%{python_sitelib}/openshift_ansible mkdir -p %{buildroot}/etc/bash_completion.d +mkdir -p %{buildroot}/etc/openshift_ansible cp -p ossh oscp opssh %{buildroot}%{_bindir} cp -p awsutil.py %{buildroot}%{python_sitelib}/openshift_ansible cp -p ossh_bash_completion %{buildroot}/etc/bash_completion.d +cp -p openshift_ansible.conf.example %{buildroot}/etc/openshift_ansible/openshift_ansible.conf + %files %{_bindir}/* %{python_sitelib}/openshift_ansible/ /etc/bash_completion.d/* +%config(noreplace) /etc/openshift_ansible/ %changelog * Tue Mar 24 2015 Thomas Wiest 0.0.1-1 diff --git a/bin/openshift_ansible.conf.example b/bin/openshift_ansible.conf.example new file mode 100644 index 000000000..e891b855a --- /dev/null +++ b/bin/openshift_ansible.conf.example @@ -0,0 +1,6 @@ +#[main] +#inventory = /usr/share/ansible/inventory/multi_ec2.py + +#[host_type_aliases] +#host-type-one = aliasa,aliasb +#host-type-two = aliasfortwo diff --git a/bin/opssh b/bin/opssh index 71e5bf9f2..d64096fd4 100755 --- a/bin/opssh +++ b/bin/opssh @@ -10,16 +10,30 @@ import re import tempfile import time import subprocess +import ConfigParser -DEFAULT_PSSH_PAR=200 +DEFAULT_PSSH_PAR = 200 PSSH = '/usr/bin/pssh' +CONFIG_MAIN_SECTION = 'main' +CONFIG_HOST_TYPE_ALIAS_SECTION = 'host_type_aliases' +CONFIG_INVENTORY_OPTION = 'inventory' + class Opssh(object): def __init__(self): + self.inventory = None + self.host_type_aliases = {} self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__))) - self.aws = awsutil.AwsUtil() + + # Default the config path to /etc + self.config_path = os.path.join(os.path.sep, 'etc', \ + 'openshift_ansible', \ + 'openshift_ansible.conf') self.parse_cli_args() + self.parse_config_file() + + self.aws = awsutil.AwsUtil(self.inventory, self.host_type_aliases) if self.args.list_host_types: self.aws.print_host_types() @@ -66,6 +80,20 @@ class Opssh(object): return None + def parse_config_file(self): + if os.path.isfile(self.config_path): + config = ConfigParser.ConfigParser() + config.read(self.config_path) + + if config.has_section(CONFIG_MAIN_SECTION) and \ + config.has_option(CONFIG_MAIN_SECTION, CONFIG_INVENTORY_OPTION): + self.inventory = config.get(CONFIG_MAIN_SECTION, CONFIG_INVENTORY_OPTION) + + self.host_type_aliases = {} + if config.has_section(CONFIG_HOST_TYPE_ALIAS_SECTION): + for alias in config.options(CONFIG_HOST_TYPE_ALIAS_SECTION): + value = config.get(CONFIG_HOST_TYPE_ALIAS_SECTION, alias).split(',') + self.host_type_aliases[alias] = value def parse_cli_args(self): """Setup the command line parser with the options we want diff --git a/bin/oscp b/bin/oscp index 146bbbea5..011f37c7c 100755 --- a/bin/oscp +++ b/bin/oscp @@ -7,16 +7,28 @@ import traceback import sys import os import re +import ConfigParser + +CONFIG_MAIN_SECTION = 'main' +CONFIG_INVENTORY_OPTION = 'inventory' class Oscp(object): def __init__(self): + self.inventory = None self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__))) + + # Default the config path to /etc + self.config_path = os.path.join(os.path.sep, 'etc', \ + 'openshift_ansible', \ + 'openshift_ansible.conf') + self.parse_cli_args() + self.parse_config_file() # parse host and user self.process_host() - self.aws = awsutil.AwsUtil() + self.aws = awsutil.AwsUtil(self.inventory) # get a dict of host inventory if self.args.list: @@ -38,9 +50,18 @@ class Oscp(object): else: self.scp() + def parse_config_file(self): + if os.path.isfile(self.config_path): + config = ConfigParser.ConfigParser() + config.read(self.config_path) + + if config.has_section(CONFIG_MAIN_SECTION) and \ + config.has_option(CONFIG_MAIN_SECTION, CONFIG_INVENTORY_OPTION): + self.inventory = config.get(CONFIG_MAIN_SECTION, CONFIG_INVENTORY_OPTION) + def parse_cli_args(self): parser = argparse.ArgumentParser(description='Openshift Online SSH Tool.') - parser.add_argument('-e', '--env', + parser.add_argument('-e', '--env', action="store", help="Environment where this server exists.") parser.add_argument('-d', '--debug', default=False, action="store_true", help="debug mode") diff --git a/bin/ossh b/bin/ossh index 66a4cfb5c..134f4c46a 100755 --- a/bin/ossh +++ b/bin/ossh @@ -7,13 +7,25 @@ import traceback import sys import os import re +import ConfigParser + +CONFIG_MAIN_SECTION = 'main' +CONFIG_INVENTORY_OPTION = 'inventory' class Ossh(object): def __init__(self): + self.inventory = None self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__))) + + # Default the config path to /etc + self.config_path = os.path.join(os.path.sep, 'etc', \ + 'openshift_ansible', \ + 'openshift_ansible.conf') + self.parse_cli_args() + self.parse_config_file() - self.aws = awsutil.AwsUtil() + self.aws = awsutil.AwsUtil(self.inventory) # get a dict of host inventory if self.args.list: @@ -37,6 +49,15 @@ class Ossh(object): else: self.ssh() + def parse_config_file(self): + if os.path.isfile(self.config_path): + config = ConfigParser.ConfigParser() + config.read(self.config_path) + + if config.has_section(CONFIG_MAIN_SECTION) and \ + config.has_option(CONFIG_MAIN_SECTION, CONFIG_INVENTORY_OPTION): + self.inventory = config.get(CONFIG_MAIN_SECTION, CONFIG_INVENTORY_OPTION) + def parse_cli_args(self): parser = argparse.ArgumentParser(description='Openshift Online SSH Tool.') parser.add_argument('-e', '--env', action="store", -- cgit v1.2.3 From 1ba0619575f23e880d431ec2a15b9c02bfc5e3a9 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Mon, 30 Mar 2015 14:51:41 -0400 Subject: Automatic commit of package [openshift-ansible-bin] release [0.0.2-1]. --- bin/openshift-ansible-bin.spec | 4 +++- rel-eng/packages/openshift-ansible-bin | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec index 1bd486bff..38e0a0d59 100644 --- a/bin/openshift-ansible-bin.spec +++ b/bin/openshift-ansible-bin.spec @@ -1,6 +1,6 @@ Summary: OpenShift Ansible Scripts for working with metadata hosts Name: openshift-ansible-bin -Version: 0.0.1 +Version: 0.0.2 Release: 1%{?dist} License: ASL 2.0 URL: https://github.com/openshift/openshift-ansible @@ -36,6 +36,8 @@ cp -p openshift_ansible.conf.example %{buildroot}/etc/openshift_ansible/openshif %config(noreplace) /etc/openshift_ansible/ %changelog +* Mon Mar 30 2015 Thomas Wiest 0.0.2-1 +- added config file support to opssh, ossh, and oscp (twiest@redhat.com) * Tue Mar 24 2015 Thomas Wiest 0.0.1-1 - new package built with tito diff --git a/rel-eng/packages/openshift-ansible-bin b/rel-eng/packages/openshift-ansible-bin index 098772960..875591484 100644 --- a/rel-eng/packages/openshift-ansible-bin +++ b/rel-eng/packages/openshift-ansible-bin @@ -1 +1 @@ -0.0.1-1 bin/ +0.0.2-1 bin/ -- cgit v1.2.3 From 24ce165d9ca662f9a0438e658197ff41fd02ae03 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Mon, 30 Mar 2015 17:46:21 -0400 Subject: created a python package named openshift_ansible --- bin/awsutil.py | 141 ------------------------------------- bin/openshift-ansible-bin.spec | 2 +- bin/openshift_ansible/__init__.py | 0 bin/openshift_ansible/awsutil.py | 142 ++++++++++++++++++++++++++++++++++++++ bin/opssh | 3 +- bin/oscp | 3 +- bin/ossh | 3 +- 7 files changed, 149 insertions(+), 145 deletions(-) delete mode 100644 bin/awsutil.py create mode 100644 bin/openshift_ansible/__init__.py create mode 100644 bin/openshift_ansible/awsutil.py diff --git a/bin/awsutil.py b/bin/awsutil.py deleted file mode 100644 index 78421e5f5..000000000 --- a/bin/awsutil.py +++ /dev/null @@ -1,141 +0,0 @@ -# vim: expandtab:tabstop=4:shiftwidth=4 - -import subprocess -import os -import json -import re - -class AwsUtil(object): - def __init__(self, inventory_path=None, host_type_aliases={}): - self.host_type_aliases = host_type_aliases - self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__))) - - if inventory_path is None: - inventory_path = os.path.realpath(os.path.join(self.file_path, \ - '..','inventory','multi_ec2.py')) - - if not os.path.isfile(inventory_path): - raise Exception("Inventory file not found [%s]" % inventory_path) - - self.inventory_path = inventory_path - self.setup_host_type_alias_lookup() - - def setup_host_type_alias_lookup(self): - self.alias_lookup = {} - for key, values in self.host_type_aliases.iteritems(): - for value in values: - self.alias_lookup[value] = key - - - - def get_inventory(self,args=[]): - cmd = [self.inventory_path] - - if args: - cmd.extend(args) - - env = os.environ - - p = subprocess.Popen(cmd, stderr=subprocess.PIPE, - stdout=subprocess.PIPE, env=env) - - out,err = p.communicate() - - if p.returncode != 0: - raise RuntimeError(err) - - return json.loads(out.strip()) - - def get_environments(self): - pattern = re.compile(r'^tag_environment_(.*)') - - envs = [] - inv = self.get_inventory() - for key in inv.keys(): - m = pattern.match(key) - if m: - envs.append(m.group(1)) - - envs.sort() - return envs - - def get_host_types(self): - pattern = re.compile(r'^tag_host-type_(.*)') - - host_types = [] - inv = self.get_inventory() - for key in inv.keys(): - m = pattern.match(key) - if m: - host_types.append(m.group(1)) - - host_types.sort() - return host_types - - def get_security_groups(self): - pattern = re.compile(r'^security_group_(.*)') - - groups = [] - inv = self.get_inventory() - for key in inv.keys(): - m = pattern.match(key) - if m: - groups.append(m.group(1)) - - groups.sort() - return groups - - def build_host_dict_by_env(self, args=[]): - inv = self.get_inventory(args) - - inst_by_env = {} - for dns, host in inv['_meta']['hostvars'].items(): - # If you don't have an environment tag, we're going to ignore you - if 'ec2_tag_environment' not in host: - continue - - if host['ec2_tag_environment'] not in inst_by_env: - inst_by_env[host['ec2_tag_environment']] = {} - host_id = "%s:%s" % (host['ec2_tag_Name'],host['ec2_id']) - inst_by_env[host['ec2_tag_environment']][host_id] = host - - return inst_by_env - - # Display host_types - def print_host_types(self): - host_types = self.get_host_types() - ht_format_str = "%35s" - alias_format_str = "%-20s" - combined_format_str = ht_format_str + " " + alias_format_str - - print - print combined_format_str % ('Host Types', 'Aliases') - print combined_format_str % ('----------', '-------') - - for ht in host_types: - aliases = [] - if ht in self.host_type_aliases: - aliases = self.host_type_aliases[ht] - print combined_format_str % (ht, ", ".join(aliases)) - else: - print ht_format_str % ht - print - - # Convert host-type aliases to real a host-type - def resolve_host_type(self, host_type): - if self.alias_lookup.has_key(host_type): - return self.alias_lookup[host_type] - return host_type - - def gen_env_host_type_tag(self, host_type, env): - """Generate the environment host type tag - """ - host_type = self.resolve_host_type(host_type) - return "tag_env-host-type_%s-%s" % (env, host_type) - - def get_host_list(self, host_type, env): - """Get the list of hosts from the inventory using host-type and environment - """ - inv = self.get_inventory() - host_type_tag = self.gen_env_host_type_tag(host_type, env) - return inv[host_type_tag] diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec index 38e0a0d59..349cd3059 100644 --- a/bin/openshift-ansible-bin.spec +++ b/bin/openshift-ansible-bin.spec @@ -24,7 +24,7 @@ mkdir -p %{buildroot}/etc/bash_completion.d mkdir -p %{buildroot}/etc/openshift_ansible cp -p ossh oscp opssh %{buildroot}%{_bindir} -cp -p awsutil.py %{buildroot}%{python_sitelib}/openshift_ansible +cp -p openshift_ansible/* %{buildroot}%{python_sitelib}/openshift_ansible cp -p ossh_bash_completion %{buildroot}/etc/bash_completion.d cp -p openshift_ansible.conf.example %{buildroot}/etc/openshift_ansible/openshift_ansible.conf diff --git a/bin/openshift_ansible/__init__.py b/bin/openshift_ansible/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bin/openshift_ansible/awsutil.py b/bin/openshift_ansible/awsutil.py new file mode 100644 index 000000000..8fef0a24f --- /dev/null +++ b/bin/openshift_ansible/awsutil.py @@ -0,0 +1,142 @@ +# vim: expandtab:tabstop=4:shiftwidth=4 + +import subprocess +import os +import json +import re + +class AwsUtil(object): + def __init__(self, inventory_path=None, host_type_aliases={}): + self.host_type_aliases = host_type_aliases + self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__))) + + if inventory_path is None: + inventory_path = os.path.realpath(os.path.join(self.file_path, \ + '..', '..', 'inventory', \ + 'multi_ec2.py')) + + if not os.path.isfile(inventory_path): + raise Exception("Inventory file not found [%s]" % inventory_path) + + self.inventory_path = inventory_path + self.setup_host_type_alias_lookup() + + def setup_host_type_alias_lookup(self): + self.alias_lookup = {} + for key, values in self.host_type_aliases.iteritems(): + for value in values: + self.alias_lookup[value] = key + + + + def get_inventory(self,args=[]): + cmd = [self.inventory_path] + + if args: + cmd.extend(args) + + env = os.environ + + p = subprocess.Popen(cmd, stderr=subprocess.PIPE, + stdout=subprocess.PIPE, env=env) + + out,err = p.communicate() + + if p.returncode != 0: + raise RuntimeError(err) + + return json.loads(out.strip()) + + def get_environments(self): + pattern = re.compile(r'^tag_environment_(.*)') + + envs = [] + inv = self.get_inventory() + for key in inv.keys(): + m = pattern.match(key) + if m: + envs.append(m.group(1)) + + envs.sort() + return envs + + def get_host_types(self): + pattern = re.compile(r'^tag_host-type_(.*)') + + host_types = [] + inv = self.get_inventory() + for key in inv.keys(): + m = pattern.match(key) + if m: + host_types.append(m.group(1)) + + host_types.sort() + return host_types + + def get_security_groups(self): + pattern = re.compile(r'^security_group_(.*)') + + groups = [] + inv = self.get_inventory() + for key in inv.keys(): + m = pattern.match(key) + if m: + groups.append(m.group(1)) + + groups.sort() + return groups + + def build_host_dict_by_env(self, args=[]): + inv = self.get_inventory(args) + + inst_by_env = {} + for dns, host in inv['_meta']['hostvars'].items(): + # If you don't have an environment tag, we're going to ignore you + if 'ec2_tag_environment' not in host: + continue + + if host['ec2_tag_environment'] not in inst_by_env: + inst_by_env[host['ec2_tag_environment']] = {} + host_id = "%s:%s" % (host['ec2_tag_Name'],host['ec2_id']) + inst_by_env[host['ec2_tag_environment']][host_id] = host + + return inst_by_env + + # Display host_types + def print_host_types(self): + host_types = self.get_host_types() + ht_format_str = "%35s" + alias_format_str = "%-20s" + combined_format_str = ht_format_str + " " + alias_format_str + + print + print combined_format_str % ('Host Types', 'Aliases') + print combined_format_str % ('----------', '-------') + + for ht in host_types: + aliases = [] + if ht in self.host_type_aliases: + aliases = self.host_type_aliases[ht] + print combined_format_str % (ht, ", ".join(aliases)) + else: + print ht_format_str % ht + print + + # Convert host-type aliases to real a host-type + def resolve_host_type(self, host_type): + if self.alias_lookup.has_key(host_type): + return self.alias_lookup[host_type] + return host_type + + def gen_env_host_type_tag(self, host_type, env): + """Generate the environment host type tag + """ + host_type = self.resolve_host_type(host_type) + return "tag_env-host-type_%s-%s" % (env, host_type) + + def get_host_list(self, host_type, env): + """Get the list of hosts from the inventory using host-type and environment + """ + inv = self.get_inventory() + host_type_tag = self.gen_env_host_type_tag(host_type, env) + return inv[host_type_tag] diff --git a/bin/opssh b/bin/opssh index d64096fd4..d8137fb20 100755 --- a/bin/opssh +++ b/bin/opssh @@ -2,7 +2,6 @@ # vim: expandtab:tabstop=4:shiftwidth=4 import argparse -import awsutil import traceback import sys import os @@ -12,6 +11,8 @@ import time import subprocess import ConfigParser +from openshift_ansible import awsutil + DEFAULT_PSSH_PAR = 200 PSSH = '/usr/bin/pssh' CONFIG_MAIN_SECTION = 'main' diff --git a/bin/oscp b/bin/oscp index 011f37c7c..461ad0a0f 100755 --- a/bin/oscp +++ b/bin/oscp @@ -2,13 +2,14 @@ # vim: expandtab:tabstop=4:shiftwidth=4 import argparse -import awsutil import traceback import sys import os import re import ConfigParser +from openshift_ansible import awsutil + CONFIG_MAIN_SECTION = 'main' CONFIG_INVENTORY_OPTION = 'inventory' diff --git a/bin/ossh b/bin/ossh index 134f4c46a..c16ea6eda 100755 --- a/bin/ossh +++ b/bin/ossh @@ -2,13 +2,14 @@ # vim: expandtab:tabstop=4:shiftwidth=4 import argparse -import awsutil import traceback import sys import os import re import ConfigParser +from openshift_ansible import awsutil + CONFIG_MAIN_SECTION = 'main' CONFIG_INVENTORY_OPTION = 'inventory' -- cgit v1.2.3 From 4a6d1c328d92047fcd924dce821613c8579f1745 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Mon, 30 Mar 2015 18:13:27 -0400 Subject: Automatic commit of package [openshift-ansible-bin] release [0.0.3-1]. --- bin/openshift-ansible-bin.spec | 5 ++++- rel-eng/packages/openshift-ansible-bin | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec index 349cd3059..7cca5ffba 100644 --- a/bin/openshift-ansible-bin.spec +++ b/bin/openshift-ansible-bin.spec @@ -1,6 +1,6 @@ Summary: OpenShift Ansible Scripts for working with metadata hosts Name: openshift-ansible-bin -Version: 0.0.2 +Version: 0.0.3 Release: 1%{?dist} License: ASL 2.0 URL: https://github.com/openshift/openshift-ansible @@ -36,6 +36,9 @@ cp -p openshift_ansible.conf.example %{buildroot}/etc/openshift_ansible/openshif %config(noreplace) /etc/openshift_ansible/ %changelog +* Mon Mar 30 2015 Thomas Wiest 0.0.3-1 +- created a python package named openshift_ansible (twiest@redhat.com) + * Mon Mar 30 2015 Thomas Wiest 0.0.2-1 - added config file support to opssh, ossh, and oscp (twiest@redhat.com) * Tue Mar 24 2015 Thomas Wiest 0.0.1-1 diff --git a/rel-eng/packages/openshift-ansible-bin b/rel-eng/packages/openshift-ansible-bin index 875591484..36b150859 100644 --- a/rel-eng/packages/openshift-ansible-bin +++ b/rel-eng/packages/openshift-ansible-bin @@ -1 +1 @@ -0.0.2-1 bin/ +0.0.3-1 bin/ -- cgit v1.2.3 From d9a178298ae8b6d487baf79559f4d82b2d71e49a Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Tue, 31 Mar 2015 15:36:29 -0400 Subject: Fixed when tag was missing and added opssh completion --- bin/ossh_bash_completion | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/bin/ossh_bash_completion b/bin/ossh_bash_completion index 6a95ce6ee..1467de858 100755 --- a/bin/ossh_bash_completion +++ b/bin/ossh_bash_completion @@ -1,6 +1,7 @@ __ossh_known_hosts(){ if [[ -f ~/.ansible/tmp/multi_ec2_inventory.cache ]]; then - /usr/bin/python -c 'import json,os; z = json.loads(open("%s"%os.path.expanduser("~/.ansible/tmp/multi_ec2_inventory.cache")).read()); print "\n".join(["%s.%s" % (host["ec2_tag_Name"],host["ec2_tag_environment"]) for dns, host in z["_meta"]["hostvars"].items()])' + /usr/bin/python -c 'import json,os; z = json.loads(open("%s"%os.path.expanduser("~/.ansible/tmp/multi_ec2_inventory.cache")).read()); print "\n".join(["%s.%s" % (host["ec2_tag_Name"],host["ec2_tag_environment"]) for dns, host in z["_meta"]["hostvars"].items() if all(k in host for k in ("ec2_tag_Name", "ec2_tag_environment"))])' + fi } @@ -16,3 +17,23 @@ _ossh() return 0 } complete -F _ossh ossh oscp + +__opssh_known_hosts(){ + if [[ -f ~/.ansible/tmp/multi_ec2_inventory.cache ]]; then + /usr/bin/python -c 'import json,os; z = json.loads(open("%s"%os.path.expanduser("~/.ansible/tmp/multi_ec2_inventory.cache")).read()); print "\n".join(["%s" % (host["ec2_tag_host-type"]) for dns, host in z["_meta"]["hostvars"].items() if "ec2_tag_host-type" in host])' + fi +} + +_opssh() +{ + local cur prev known_hosts + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + known_hosts="$(__opssh_known_hosts)" + COMPREPLY=( $(compgen -W "${known_hosts}" -- ${cur})) + + return 0 +} +complete -F _opssh opssh + -- cgit v1.2.3 From 5f0b024fedc826722306c159bbf91a3c74ec3b4e Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Tue, 31 Mar 2015 16:49:13 -0400 Subject: Automatic commit of package [openshift-ansible-bin] release [0.0.4-1]. --- bin/openshift-ansible-bin.spec | 5 ++++- rel-eng/packages/openshift-ansible-bin | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec index 7cca5ffba..f87002456 100644 --- a/bin/openshift-ansible-bin.spec +++ b/bin/openshift-ansible-bin.spec @@ -1,6 +1,6 @@ Summary: OpenShift Ansible Scripts for working with metadata hosts Name: openshift-ansible-bin -Version: 0.0.3 +Version: 0.0.4 Release: 1%{?dist} License: ASL 2.0 URL: https://github.com/openshift/openshift-ansible @@ -36,6 +36,9 @@ cp -p openshift_ansible.conf.example %{buildroot}/etc/openshift_ansible/openshif %config(noreplace) /etc/openshift_ansible/ %changelog +* Tue Mar 31 2015 Thomas Wiest 0.0.4-1 +- Fixed when tag was missing and added opssh completion (kwoodson@redhat.com) + * Mon Mar 30 2015 Thomas Wiest 0.0.3-1 - created a python package named openshift_ansible (twiest@redhat.com) diff --git a/rel-eng/packages/openshift-ansible-bin b/rel-eng/packages/openshift-ansible-bin index 36b150859..a0e3e205c 100644 --- a/rel-eng/packages/openshift-ansible-bin +++ b/rel-eng/packages/openshift-ansible-bin @@ -1 +1 @@ -0.0.3-1 bin/ +0.0.4-1 bin/ -- cgit v1.2.3 From 035b498f37cdb5947d3d7c9254c23a20ca77eddd Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Wed, 1 Apr 2015 12:42:03 -0400 Subject: Adding the zabbix module along with a generic playbook to fetch current problem triggers. Also added oo_flatten to filters for arrays of arrays. --- filter_plugins/oo_filters.py | 10 ++ library/zbxapi.py | 257 ++++++++++++++++++++++++++++ playbooks/adhoc/noc/filter_plugins | 1 + playbooks/adhoc/noc/get_zabbix_problems.yml | 39 +++++ playbooks/adhoc/noc/library | 1 + 5 files changed, 308 insertions(+) create mode 100755 library/zbxapi.py create mode 120000 playbooks/adhoc/noc/filter_plugins create mode 100644 playbooks/adhoc/noc/get_zabbix_problems.yml create mode 120000 playbooks/adhoc/noc/library diff --git a/filter_plugins/oo_filters.py b/filter_plugins/oo_filters.py index caf1fd1f0..1cf02218c 100644 --- a/filter_plugins/oo_filters.py +++ b/filter_plugins/oo_filters.py @@ -34,6 +34,15 @@ def get_attr(data, attribute=None): return ptr +def oo_flatten(data): + ''' This filter plugin will flatten a list of lists + ''' + if not issubclass(type(data), list): + raise errors.AnsibleFilterError("|failed expects to flatten a List") + + return [ item for sublist in data for item in sublist ] + + def oo_collect(data, attribute=None, filters={}): ''' This takes a list of dict and collects all attributes specified into a list If filter is specified then we will include all items that match _ALL_ of filters. @@ -97,6 +106,7 @@ class FilterModule (object): return { "oo_select_keys": oo_select_keys, "oo_collect": oo_collect, + "oo_flatten": oo_flatten, "oo_len": oo_len, "oo_pdb": oo_pdb, "oo_prepend_strings_in_list": oo_prepend_strings_in_list diff --git a/library/zbxapi.py b/library/zbxapi.py new file mode 100755 index 000000000..6d752c9f0 --- /dev/null +++ b/library/zbxapi.py @@ -0,0 +1,257 @@ +#!/usr/bin/env python + +import json +import httplib2 +import sys +import os +import re + +class ZabbixAPI(object): + ''' + ZabbixAPI class + ''' + classes = { + 'Triggerprototype': ['get', 'update', 'delete', 'create'], + 'Script': ['getscriptsbyhosts', 'get', 'update', 'delete', 'execute', 'create'], + 'Templatescreenitem': ['get'], + 'Service': ['deletedependencies', 'create', 'isreadable', 'deletetimes', 'getsla', 'get', 'addtimes', 'update', 'delete', 'adddependencies', 'iswritable'], + 'Drule': ['delete', 'isreadable', 'create', 'get', 'update', 'copy', 'iswritable'], + 'Iconmap': ['create', 'update', 'isreadable', 'get', 'iswritable', 'delete'], + 'Dservice': ['get'], + 'History': ['get'], + 'Trigger': ['delete', 'deletedependencies', 'create', 'iswritable', 'isreadable', 'adddependencies', 'get', 'update'], + 'Graph': ['delete', 'get', 'update', 'create'], + 'Usergroup': ['get', 'update', 'create', 'massupdate', 'isreadable', 'delete', 'iswritable', 'massadd'], + 'Map': ['get', 'create', 'delete', 'update', 'isreadable', 'iswritable'], + 'Alert': ['get'], + 'Screenitem': ['updatebyposition', 'iswritable', 'isreadable', 'update', 'get', 'create', 'delete'], + 'Httptest': ['create', 'delete', 'get', 'iswritable', 'update', 'isreadable'], + 'Graphitem': ['get'], + 'Dcheck': ['get'], + 'Template': ['isreadable', 'massupdate', 'delete', 'iswritable', 'massremove', 'massadd', 'create', 'update', 'get'], + 'Templatescreen': ['get', 'create', 'copy', 'delete', 'isreadable', 'update', 'iswritable'], + 'Application': ['update', 'delete', 'massadd', 'get', 'create'], + 'Item': ['delete', 'get', 'iswritable', 'isreadable', 'update', 'create'], + 'Proxy': ['create', 'delete', 'update', 'iswritable', 'isreadable', 'get'], + 'Action': ['get', 'delete', 'update', 'create'], + 'Mediatype': ['update', 'delete', 'get', 'create'], + 'Maintenance': ['get', 'update', 'create', 'delete'], + 'Screen': ['delete', 'update', 'create', 'get'], + 'Dhost': ['get'], + 'Itemprototype': ['delete', 'iswritable', 'get', 'update', 'create', 'isreadable'], + 'Host': ['massadd', 'massremove', 'isreadable', 'get', 'create', 'update', 'delete', 'massupdate', 'iswritable'], + 'Event': ['acknowledge', 'get'], + 'Hostprototype': ['iswritable', 'create', 'update', 'delete', 'get', 'isreadable'], + 'Hostgroup': ['massadd', 'massupdate', 'update', 'isreadable', 'get', 'massremove', 'create', 'delete', 'iswritable'], + 'Image': ['get', 'update', 'delete', 'create'], + 'User': ['delete', 'get', 'updatemedia', 'updateprofile', 'update', 'iswritable', 'logout', 'addmedia', 'create', 'login', 'deletemedia', 'isreadable'], + 'Graphprototype': ['update', 'get', 'delete', 'create'], + 'Hostinterface': ['replacehostinterfaces', 'delete', 'get', 'massadd', 'create', 'update', 'massremove'], + 'Usermacro': ['create', 'deleteglobal', 'updateglobal', 'delete', 'update', 'createglobal', 'get'], + 'Usermedia': ['get'], + 'Configuration': ['import', 'export'], + } + + def __init__(self, data={}): + self.server = data['server'] or None + self.username = data['user'] or None + self.password = data['password'] or None + if any(map(lambda value: value == None, [self.server, self.username, self.password])): + print 'Please specify zabbix server url, username, and password.' + sys.exit(1) + + self.verbose = data.has_key('verbose') + self.use_ssl = data.has_key('use_ssl') + self.auth = None + + for class_name, method_names in self.classes.items(): + #obj = getattr(self, class_name)(self) + #obj.__dict__ + setattr(self, class_name.lower(), getattr(self, class_name)(self)) + + results = self.user.login(user=self.username, password=self.password) + + if results[0]['status'] == '200': + if results[1].has_key('result'): + self.auth = results[1]['result'] + elif results[1].has_key('error'): + print "Unable to authenticate with zabbix server. {0} ".format(results[1]['error']) + sys.exit(1) + else: + print "Error in call to zabbix. Http status: {0}.".format(results[0]['status']) + sys.exit(1) + + def perform(self, method, params): + ''' + This method calls your zabbix server. + + It requires the following parameters in order for a proper request to be processed: + + jsonrpc - the version of the JSON-RPC protocol used by the API; the Zabbix API implements JSON-RPC version 2.0; + method - the API method being called; + params - parameters that will be passed to the API method; + id - an arbitrary identifier of the request; + auth - a user authentication token; since we don't have one yet, it's set to null. + ''' + http_method = "POST" + if params.has_key("http_method"): + http_method = params['http_method'] + + jsonrpc = "2.0" + if params.has_key('jsonrpc'): + jsonrpc = params['jsonrpc'] + + rid = 1 + if params.has_key('id'): + rid = params['id'] + + http = None + if self.use_ssl: + http = httplib2.Http() + else: + http = httplib2.Http( disable_ssl_certificate_validation=True,) + + headers = params.get('headers', {}) + headers["Content-type"] = "application/json" + + body = { + "jsonrpc": jsonrpc, + "method": method, + "params": params, + "id": rid, + 'auth': self.auth, + } + + if method in ['user.login','api.version']: + del body['auth'] + + body = json.dumps(body) + + if self.verbose: + print body + print method + print headers + httplib2.debuglevel = 1 + + response, results = http.request(self.server, http_method, body, headers) + + if self.verbose: + print response + print results + + try: + results = json.loads(results) + except ValueError as e: + results = {"error": e.message} + + return response, results + + ''' + This bit of metaprogramming is where the ZabbixAPI subclasses are created. + For each of ZabbixAPI.classes we create a class from the key and methods + from the ZabbixAPI.classes values. We pass a reference to ZabbixAPI class + to each subclass in order for each to be able to call the perform method. + ''' + @staticmethod + def meta(class_name, method_names): + # This meta method allows a class to add methods to it. + def meta_method(Class, method_name): + # This template method is a stub method for each of the subclass + # methods. + def template_method(self, **params): + return self.parent.perform(class_name.lower()+"."+method_name, params) + template_method.__doc__ = "https://www.zabbix.com/documentation/2.4/manual/api/reference/%s/%s" % (class_name.lower(), method_name) + template_method.__name__ = method_name + # this is where the template method is placed inside of the subclass + # e.g. setattr(User, "create", stub_method) + setattr(Class, template_method.__name__, template_method) + + # This class call instantiates a subclass. e.g. User + Class=type(class_name, (object,), { '__doc__': "https://www.zabbix.com/documentation/2.4/manual/api/reference/%s" % class_name.lower() }) + # This init method gets placed inside of the Class + # to allow it to be instantiated. A reference to the parent class(ZabbixAPI) + # is passed in to allow each class access to the perform method. + def __init__(self, parent): + self.parent = parent + # This attaches the init to the subclass. e.g. Create + setattr(Class, __init__.__name__, __init__) + # For each of our ZabbixAPI.classes dict values + # Create a method and attach it to our subclass. + # e.g. 'User': ['delete', 'get', 'updatemedia', 'updateprofile', + # 'update', 'iswritable', 'logout', 'addmedia', 'create', + # 'login', 'deletemedia', 'isreadable'], + # User.delete + # User.get + for method_name in method_names: + meta_method(Class, method_name) + # Return our subclass with all methods attached + return Class + +# Attach all ZabbixAPI.classes to ZabbixAPI class through metaprogramming +for class_name, method_names in ZabbixAPI.classes.items(): + setattr(ZabbixAPI, class_name, ZabbixAPI.meta(class_name, method_names)) + +def main(): + + module = AnsibleModule( + argument_spec = dict( + server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), + user=dict(default=None, type='str'), + password=dict(default=None, type='str'), + zbx_class=dict( choices=ZabbixAPI.classes.keys()), + #zbx_class=dict(type='str', require=True), + action=dict(default=None, type='str'), + params=dict(), + debug=dict(default=False, type='bool'), + ), + #supports_check_mode=True + ) + + user = module.params.get('user', None) + if not user: + user = os.environ['ZABBIX_USER'] + + pw = module.params.get('password', None) + if not pw: + pw = os.environ['ZABBIX_PW'] + + server = module.params['server'] + + if module.params['debug']: + options['debug'] = True + + api_data = { + 'user': user, + 'password': pw, + 'server': server, + } + + if not user or not pw or not server: + module.fail_json('Please specify the user, password, and the zabbix server.') + + zapi = ZabbixAPI(api_data) + + zbx_class = module.params.get('zbx_class') + action = module.params.get('action') + params = module.params.get('params', {}) + + + # Get the instance we are trying to call + zbx_class_inst = zapi.__getattribute__(zbx_class.lower()) + # Get the instance's method we are trying to call + zbx_action_method = zapi.__getattribute__(zbx_class.capitalize()).__dict__[action] + # Make the call with the incoming params + results = zbx_action_method(zbx_class_inst, **params) + + # Results Section + changed_state = False + status = results[0]['status'] + if status not in ['200', '201']: + #changed_state = False + module.fail_json(msg="Http response: [%s] - Error: %s" % (str(results[0]), results[1])) + + module.exit_json(**{'results': results[1]['result']}) + +from ansible.module_utils.basic import * + +main() diff --git a/playbooks/adhoc/noc/filter_plugins b/playbooks/adhoc/noc/filter_plugins new file mode 120000 index 000000000..99a95e4ca --- /dev/null +++ b/playbooks/adhoc/noc/filter_plugins @@ -0,0 +1 @@ +../../../filter_plugins \ No newline at end of file diff --git a/playbooks/adhoc/noc/get_zabbix_problems.yml b/playbooks/adhoc/noc/get_zabbix_problems.yml new file mode 100644 index 000000000..6ac5cdcf7 --- /dev/null +++ b/playbooks/adhoc/noc/get_zabbix_problems.yml @@ -0,0 +1,39 @@ +--- +- name: 'Get current hosts who have triggers that are alerting by trigger description' + hosts: localhost + gather_facts: no + tasks: + - assert: + that: oo_desc is defined + + - zbxapi: + server: https://noc2.ops.rhcloud.com/zabbix/api_jsonrpc.php + zbx_class: Trigger + action: get + params: + only_true: true + output: extend + selectHosts: extend + searchWildCardsEnabled: 1 + search: + description: "{{ oo_desc }}" + register: problems + + - debug: var=problems + + - set_fact: + problem_hosts: "{{ problems.results | oo_collect(attribute='hosts') | oo_flatten | oo_collect(attribute='host') | difference(['aggregates']) }}" + + - debug: var=problem_hosts + + - add_host: + name: "{{ item }}" + groups: problem_hosts_group + with_items: problem_hosts + +- name: "Run on problem hosts" + hosts: problem_hosts_group + gather_facts: no + tasks: + - command: "{{ oo_cmd }}" + when: oo_cmd is defined diff --git a/playbooks/adhoc/noc/library b/playbooks/adhoc/noc/library new file mode 120000 index 000000000..ba40d2f56 --- /dev/null +++ b/playbooks/adhoc/noc/library @@ -0,0 +1 @@ +../../../library \ No newline at end of file -- cgit v1.2.3 From 2933a28c400d6c00fa59e1b368d3606f22767576 Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Wed, 1 Apr 2015 12:55:40 -0400 Subject: Adding license --- library/zbxapi.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/library/zbxapi.py b/library/zbxapi.py index 6d752c9f0..198914bcb 100755 --- a/library/zbxapi.py +++ b/library/zbxapi.py @@ -1,5 +1,22 @@ #!/usr/bin/env python +# Copyright 2015 Red Hat Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Purpose: An ansible module to communicate with zabbix. +# + import json import httplib2 import sys -- cgit v1.2.3 From 058832184a7e5b23b7c398e443bc961af0ff3b5f Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Wed, 1 Apr 2015 16:01:50 -0400 Subject: fixing naming of environment variables --- library/zbxapi.py | 70 +++++++++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/library/zbxapi.py b/library/zbxapi.py index 198914bcb..94b48ed61 100755 --- a/library/zbxapi.py +++ b/library/zbxapi.py @@ -28,45 +28,45 @@ class ZabbixAPI(object): ZabbixAPI class ''' classes = { - 'Triggerprototype': ['get', 'update', 'delete', 'create'], - 'Script': ['getscriptsbyhosts', 'get', 'update', 'delete', 'execute', 'create'], - 'Templatescreenitem': ['get'], - 'Service': ['deletedependencies', 'create', 'isreadable', 'deletetimes', 'getsla', 'get', 'addtimes', 'update', 'delete', 'adddependencies', 'iswritable'], - 'Drule': ['delete', 'isreadable', 'create', 'get', 'update', 'copy', 'iswritable'], - 'Iconmap': ['create', 'update', 'isreadable', 'get', 'iswritable', 'delete'], - 'Dservice': ['get'], - 'History': ['get'], - 'Trigger': ['delete', 'deletedependencies', 'create', 'iswritable', 'isreadable', 'adddependencies', 'get', 'update'], - 'Graph': ['delete', 'get', 'update', 'create'], - 'Usergroup': ['get', 'update', 'create', 'massupdate', 'isreadable', 'delete', 'iswritable', 'massadd'], - 'Map': ['get', 'create', 'delete', 'update', 'isreadable', 'iswritable'], + 'Action': ['create', 'delete', 'get', 'update'], 'Alert': ['get'], - 'Screenitem': ['updatebyposition', 'iswritable', 'isreadable', 'update', 'get', 'create', 'delete'], - 'Httptest': ['create', 'delete', 'get', 'iswritable', 'update', 'isreadable'], - 'Graphitem': ['get'], + 'Application': ['create', 'delete', 'get', 'massadd', 'update'], + 'Configuration': ['export', 'import'], 'Dcheck': ['get'], - 'Template': ['isreadable', 'massupdate', 'delete', 'iswritable', 'massremove', 'massadd', 'create', 'update', 'get'], - 'Templatescreen': ['get', 'create', 'copy', 'delete', 'isreadable', 'update', 'iswritable'], - 'Application': ['update', 'delete', 'massadd', 'get', 'create'], - 'Item': ['delete', 'get', 'iswritable', 'isreadable', 'update', 'create'], - 'Proxy': ['create', 'delete', 'update', 'iswritable', 'isreadable', 'get'], - 'Action': ['get', 'delete', 'update', 'create'], - 'Mediatype': ['update', 'delete', 'get', 'create'], - 'Maintenance': ['get', 'update', 'create', 'delete'], - 'Screen': ['delete', 'update', 'create', 'get'], 'Dhost': ['get'], - 'Itemprototype': ['delete', 'iswritable', 'get', 'update', 'create', 'isreadable'], - 'Host': ['massadd', 'massremove', 'isreadable', 'get', 'create', 'update', 'delete', 'massupdate', 'iswritable'], + 'Drule': ['copy', 'create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Dservice': ['get'], 'Event': ['acknowledge', 'get'], - 'Hostprototype': ['iswritable', 'create', 'update', 'delete', 'get', 'isreadable'], - 'Hostgroup': ['massadd', 'massupdate', 'update', 'isreadable', 'get', 'massremove', 'create', 'delete', 'iswritable'], - 'Image': ['get', 'update', 'delete', 'create'], - 'User': ['delete', 'get', 'updatemedia', 'updateprofile', 'update', 'iswritable', 'logout', 'addmedia', 'create', 'login', 'deletemedia', 'isreadable'], - 'Graphprototype': ['update', 'get', 'delete', 'create'], - 'Hostinterface': ['replacehostinterfaces', 'delete', 'get', 'massadd', 'create', 'update', 'massremove'], - 'Usermacro': ['create', 'deleteglobal', 'updateglobal', 'delete', 'update', 'createglobal', 'get'], + 'Graph': ['create', 'delete', 'get', 'update'], + 'Graphitem': ['get'], + 'Graphprototype': ['create', 'delete', 'get', 'update'], + 'History': ['get'], + 'Hostgroup': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massremove', 'massupdate', 'update'], + 'Hostinterface': ['create', 'delete', 'get', 'massadd', 'massremove', 'replacehostinterfaces', 'update'], + 'Host': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massremove', 'massupdate', 'update'], + 'Hostprototype': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Httptest': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Iconmap': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Image': ['create', 'delete', 'get', 'update'], + 'Item': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Itemprototype': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Maintenance': ['create', 'delete', 'get', 'update'], + 'Map': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Mediatype': ['create', 'delete', 'get', 'update'], + 'Proxy': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Screen': ['create', 'delete', 'get', 'update'], + 'Screenitem': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update', 'updatebyposition'], + 'Script': ['create', 'delete', 'execute', 'get', 'getscriptsbyhosts', 'update'], + 'Service': ['adddependencies', 'addtimes', 'create', 'delete', 'deletedependencies', 'deletetimes', 'get', 'getsla', 'isreadable', 'iswritable', 'update'], + 'Template': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massremove', 'massupdate', 'update'], + 'Templatescreen': ['copy', 'create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Templatescreenitem': ['get'], + 'Trigger': ['adddependencies', 'create', 'delete', 'deletedependencies', 'get', 'isreadable', 'iswritable', 'update'], + 'Triggerprototype': ['create', 'delete', 'get', 'update'], + 'User': ['addmedia', 'create', 'delete', 'deletemedia', 'get', 'isreadable', 'iswritable', 'login', 'logout', 'update', 'updatemedia', 'updateprofile'], + 'Usergroup': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massupdate', 'update'], + 'Usermacro': ['create', 'createglobal', 'delete', 'deleteglobal', 'get', 'update', 'updateglobal'], 'Usermedia': ['get'], - 'Configuration': ['import', 'export'], } def __init__(self, data={}): @@ -230,7 +230,7 @@ def main(): pw = module.params.get('password', None) if not pw: - pw = os.environ['ZABBIX_PW'] + pw = os.environ['ZABBIX_PASSWORD'] server = module.params['server'] -- cgit v1.2.3 From fe878255f5ac57e75a87bc2af58cedbd21d43501 Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Wed, 1 Apr 2015 16:03:04 -0400 Subject: Cleaned up space and commented code --- library/zbxapi.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/zbxapi.py b/library/zbxapi.py index 94b48ed61..f4f52909b 100755 --- a/library/zbxapi.py +++ b/library/zbxapi.py @@ -215,8 +215,7 @@ def main(): server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), user=dict(default=None, type='str'), password=dict(default=None, type='str'), - zbx_class=dict( choices=ZabbixAPI.classes.keys()), - #zbx_class=dict(type='str', require=True), + zbx_class=dict(choices=ZabbixAPI.classes.keys()), action=dict(default=None, type='str'), params=dict(), debug=dict(default=False, type='bool'), -- cgit v1.2.3 From 4712e72c912a1102bff0508c98bd97da3f33ae95 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Mon, 23 Mar 2015 23:53:17 -0400 Subject: openshift_facts role/module refactor default settings - Add openshift_facts role and module - Created new role openshift_facts that contains an openshift_facts module - Refactor openshift_* roles to use openshift_facts instead of relying on defaults - Refactor playbooks to use openshift_facts - Cleanup inventory group_vars - Update defaults - update openshift_master role firewall defaults - remove etcd peer port, since we will not be supporting clustered embedded etcd - remove 8444 since console now runs on the api port by default - add 8444 and 7001 to disabled services to ensure removal if updating - Add new role os_env_extras_node that is a subset of the docker role - previously, we were starting/enabling docker which was causing issues with some installations - Does not install or start docker, since the openshift-node role will handle that for us - Only adds root to the dockerroot group - Update playbooks to use ops_env_extras_node role instead of docker role - os_firewall bug fixes - ignore ip6tables for now, since we are not configuring any ipv6 rules - if installing package do a daemon-reload before starting/enabling service - Add aws support to bin/cluster - Add list action to bin/cluster - Add update action to bin/cluster - cleanup some stray debug statements - some variable renaming for clarity --- README_AWS.md | 26 +- README_GCE.md | 25 +- bin/cluster | 17 +- cluster.sh | 113 ----- inventory/aws/group_vars/all | 2 + inventory/gce/group_vars/all | 5 - inventory/gce/group_vars/tag_host-type-master | 5 - inventory/gce/group_vars/tag_host-type-node | 6 - .../gce/group_vars/tag_host-type-openshift-master | 1 - .../gce/group_vars/tag_host-type-openshift-node | 1 - playbooks/aws/openshift-cluster/filter_plugins | 1 + playbooks/aws/openshift-cluster/launch.yml | 62 +++ .../aws/openshift-cluster/launch_instances.yml | 62 +++ playbooks/aws/openshift-cluster/list.yml | 17 + playbooks/aws/openshift-cluster/roles | 1 + playbooks/aws/openshift-cluster/terminate.yml | 14 + playbooks/aws/openshift-cluster/update.yml | 13 + playbooks/aws/openshift-cluster/vars.yml | 1 + playbooks/aws/openshift-master/config.yml | 37 +- playbooks/aws/openshift-master/launch.yml | 9 +- playbooks/aws/openshift-master/terminate.yml | 52 +++ playbooks/aws/openshift-master/vars.yml | 1 + playbooks/aws/openshift-node/config.yml | 123 ++++-- playbooks/aws/openshift-node/launch.yml | 13 +- playbooks/aws/openshift-node/terminate.yml | 52 +++ playbooks/aws/openshift-node/vars.yml | 1 + playbooks/gce/openshift-cluster/launch.yml | 9 +- .../gce/openshift-cluster/launch_instances.yml | 7 +- playbooks/gce/openshift-cluster/list.yml | 17 + playbooks/gce/openshift-cluster/update.yml | 13 + playbooks/gce/openshift-master/config.yml | 6 +- playbooks/gce/openshift-master/launch.yml | 12 +- playbooks/gce/openshift-master/terminate.yml | 16 +- playbooks/gce/openshift-master/vars.yml | 1 + playbooks/gce/openshift-node/config.yml | 94 ++-- playbooks/gce/openshift-node/launch.yml | 22 +- playbooks/gce/openshift-node/terminate.yml | 16 +- playbooks/gce/openshift-node/vars.yml | 1 + roles/openshift_common/README.md | 17 +- roles/openshift_common/defaults/main.yml | 1 + roles/openshift_common/meta/main.yml | 1 + roles/openshift_common/tasks/main.yml | 29 +- roles/openshift_common/tasks/set_facts.yml | 9 - roles/openshift_common/vars/main.yml | 5 +- roles/openshift_facts/README.md | 34 ++ roles/openshift_facts/library/openshift_facts.py | 482 +++++++++++++++++++++ roles/openshift_facts/meta/main.yml | 15 + roles/openshift_facts/tasks/main.yml | 3 + roles/openshift_master/README.md | 28 +- roles/openshift_master/defaults/main.yml | 13 +- roles/openshift_master/handlers/main.yml | 1 - roles/openshift_master/tasks/main.yml | 50 ++- roles/openshift_master/vars/main.yml | 2 - roles/openshift_node/README.md | 3 - roles/openshift_node/defaults/main.yml | 2 - roles/openshift_node/handlers/main.yml | 2 +- roles/openshift_node/tasks/main.yml | 27 +- roles/openshift_node/vars/main.yml | 2 - roles/openshift_register_nodes/README.md | 22 +- .../library/kubernetes_register_node.py | 3 +- roles/openshift_register_nodes/meta/main.yml | 141 +----- roles/openshift_register_nodes/tasks/main.yml | 58 ++- roles/openshift_repos/defaults/main.yaml | 2 + roles/openshift_repos/meta/main.yml | 3 +- roles/openshift_repos/tasks/main.yaml | 6 + roles/openshift_sdn_master/defaults/main.yml | 2 - roles/openshift_sdn_master/meta/main.yml | 3 +- roles/openshift_sdn_master/tasks/main.yml | 18 +- roles/openshift_sdn_node/README.md | 6 - roles/openshift_sdn_node/defaults/main.yml | 2 - roles/openshift_sdn_node/meta/main.yml | 3 +- roles/openshift_sdn_node/tasks/main.yml | 23 +- roles/os_env_extras_node/tasks/main.yml | 5 + .../library/os_firewall_manage_iptables.py | 1 + roles/os_firewall/meta/main.yml | 1 + roles/os_firewall/tasks/firewall/firewalld.yml | 5 + roles/os_firewall/tasks/firewall/iptables.yml | 12 +- 77 files changed, 1290 insertions(+), 626 deletions(-) delete mode 100755 cluster.sh create mode 100644 inventory/aws/group_vars/all delete mode 100644 inventory/gce/group_vars/tag_host-type-master delete mode 100644 inventory/gce/group_vars/tag_host-type-node delete mode 120000 inventory/gce/group_vars/tag_host-type-openshift-master delete mode 120000 inventory/gce/group_vars/tag_host-type-openshift-node create mode 120000 playbooks/aws/openshift-cluster/filter_plugins create mode 100644 playbooks/aws/openshift-cluster/launch.yml create mode 100644 playbooks/aws/openshift-cluster/launch_instances.yml create mode 100644 playbooks/aws/openshift-cluster/list.yml create mode 120000 playbooks/aws/openshift-cluster/roles create mode 100644 playbooks/aws/openshift-cluster/terminate.yml create mode 100644 playbooks/aws/openshift-cluster/update.yml create mode 100644 playbooks/aws/openshift-cluster/vars.yml create mode 100644 playbooks/aws/openshift-master/terminate.yml create mode 100644 playbooks/aws/openshift-node/terminate.yml create mode 100644 playbooks/gce/openshift-cluster/list.yml create mode 100644 playbooks/gce/openshift-cluster/update.yml delete mode 100644 roles/openshift_common/tasks/set_facts.yml create mode 100644 roles/openshift_facts/README.md create mode 100755 roles/openshift_facts/library/openshift_facts.py create mode 100644 roles/openshift_facts/meta/main.yml create mode 100644 roles/openshift_facts/tasks/main.yml delete mode 100644 roles/openshift_master/vars/main.yml delete mode 100644 roles/openshift_node/vars/main.yml mode change 100644 => 100755 roles/openshift_register_nodes/library/kubernetes_register_node.py delete mode 100644 roles/openshift_sdn_master/defaults/main.yml delete mode 100644 roles/openshift_sdn_node/defaults/main.yml create mode 100644 roles/os_env_extras_node/tasks/main.yml mode change 100644 => 100755 roles/os_firewall/library/os_firewall_manage_iptables.py diff --git a/README_AWS.md b/README_AWS.md index fb9d0f895..e877f34c6 100644 --- a/README_AWS.md +++ b/README_AWS.md @@ -51,7 +51,29 @@ OSX: Test The Setup -------------- 1. cd openshift-ansible -1. Try to list all instances: +1. Try to list all instances (Passing an empty string as the cluster_id +argument will result in all ec2 instances being listed) ``` - ./cloud.rb aws list + bin/cluster list aws '' +``` + +Creating a cluster +------------------ +1. To create a cluster with one master and two nodes +``` + bin/cluster create aws +``` + +Updating a cluster +--------------------- +1. To update the cluster +``` + bin/cluster update aws +``` + +Terminating a cluster +--------------------- +1. To terminate the cluster +``` + bin/cluster terminate aws ``` diff --git a/README_GCE.md b/README_GCE.md index 209705113..f6c5138c1 100644 --- a/README_GCE.md +++ b/README_GCE.md @@ -65,12 +65,29 @@ Install Dependencies Test The Setup -------------- 1. cd openshift-ansible/ -2. Try to list all instances: +1. Try to list all instances (Passing an empty string as the cluster_id +argument will result in all gce instances being listed) ``` - ./cloud.rb gce list + bin/cluster list gce '' ``` -3. Try to create an instance: +Creating a cluster +------------------ +1. To create a cluster with one master and two nodes ``` - ./cloud.rb gce launch -e int --type openshift-node + bin/cluster create gce +``` + +Updating a cluster +--------------------- +1. To update the cluster +``` + bin/cluster update gce +``` + +Terminating a cluster +--------------------- +1. To terminate the cluster +``` + bin/cluster terminate gce ``` diff --git a/bin/cluster b/bin/cluster index b99286b46..36ab1da1b 100755 --- a/bin/cluster +++ b/bin/cluster @@ -32,8 +32,8 @@ class Cluster(object): playbook = "playbooks/{}/openshift-cluster/launch.yml".format(args.provider) inventory = self.setup_provider(args.provider) - env['masters'] = args.masters - env['nodes'] = args.nodes + env['num_masters'] = args.masters + env['num_nodes'] = args.nodes return self.action(args, inventory, env, playbook) @@ -55,16 +55,23 @@ class Cluster(object): :param args: command line arguments provided by user :return: exit status from run command """ - raise NotImplementedError("ACTION [{}] not implemented".format(sys._getframe().f_code.co_name)) + env = {'cluster_id': args.cluster_id} + playbook = "playbooks/{}/openshift-cluster/list.yml".format(args.provider) + inventory = self.setup_provider(args.provider) + + return self.action(args, inventory, env, playbook) def update(self, args): """ - Update OpenShift across clustered VMs + Update to latest OpenShift across clustered VMs :param args: command line arguments provided by user :return: exit status from run command """ - raise NotImplementedError("ACTION [{}] not implemented".format(sys._getframe().f_code.co_name)) + env = {'cluster_id': args.cluster_id} + playbook = "playbooks/{}/openshift-cluster/update.yml".format(args.provider) + inventory = self.setup_provider(args.provider) + return self.action(args, inventory, env, playbook) def setup_provider(self, provider): """ diff --git a/cluster.sh b/cluster.sh deleted file mode 100755 index 9c9aad4d2..000000000 --- a/cluster.sh +++ /dev/null @@ -1,113 +0,0 @@ -#!/bin/bash -eu - -NODES=2 -MASTERS=1 - -# If the environment variable OO_PROVDER is defined, it used for the provider -PROVIDER=${OO_PROVIDER:-''} -# Otherwise, default is gce (Google Compute Engine) -if [ "x$PROVIDER" == "x" ];then - PROVIDER=gce -fi - -UPPER_CASE_PROVIDER=$(echo $PROVIDER | tr '[:lower:]' '[:upper:]') - - -# Use OO_MASTER_PLAYBOOK/OO_NODE_PLAYBOOK environment variables for playbooks if defined, -# otherwise use openshift default values. -MASTER_PLAYBOOK=${OO_MASTER_PLAYBOOK:-'openshift-master'} -NODE_PLAYBOOK=${OO_NODE_PLAYBOOK:-'openshift-node'} - - -# @formatter:off -function usage { - cat 1>&2 <<-EOT - ${0} : [create|terminate|update|list] { ${UPPER_CASE_PROVIDER} environment tag} - - Supported environment tags: - $(grep --no-messages 'SUPPORTED_ENVS.*=' ./lib/${PROVIDER}_command.rb) - $([ $? -ne 0 ] && echo "No supported environment tags found for ${PROVIDER}") - - Optional arguments for create: - [-p|--provider, -m|--masters, -n|--nodes, --master-playbook, --node-playbook] - - Optional arguments for terminate|update: - [-p|--provider, --master-playbook, --node-playbook] -EOT -} -# @formatter:on - -function create_cluster { - ./cloud.rb "${PROVIDER}" launch -e "${ENV}" --type=$MASTER_PLAYBOOK -c $MASTERS - - ./cloud.rb "${PROVIDER}" launch -e "${ENV}" --type=$NODE_PLAYBOOK -c $NODES - - update_cluster - - echo -e "\nCreated ${MASTERS}/${MASTER_PLAYBOOK} masters and ${NODES}/${NODE_PLAYBOOK} nodes using ${PROVIDER} provider\n" -} - -function update_cluster { - ./cloud.rb "${PROVIDER}" config -e "${ENV}" --type=$MASTER_PLAYBOOK - ./cloud.rb "${PROVIDER}" config -e "${ENV}" --type=$NODE_PLAYBOOK -} - -function terminate_cluster { - ./cloud.rb "${PROVIDER}" terminate -e "${ENV}" --type=$MASTER_PLAYBOOK - ./cloud.rb "${PROVIDER}" terminate -e "${ENV}" --type=$NODE_PLAYBOOK -} - -[ -f ./cloud.rb ] || (echo 1>&2 'Cannot find ./cloud.rb' && exit 1) - -function check_argval { - if [[ $1 == -* ]]; then - echo "Invalid value: '$1'" - usage - exit 1 - fi -} - -# Using GNU getopt to support both small and long formats -OPTIONS=`getopt -o p:m:n:h --long provider:,masters:,nodes:,master-playbook:,node-playbook:,help \ - -n "$0" -- "$@"` -eval set -- "$OPTIONS" - -while true; do - case "$1" in - -h|--help) (usage; exit 1) ; shift ;; - -p|--provider) PROVIDER="$2" ; check_argval $2 ; shift 2 ;; - -m|--masters) MASTERS="$2" ; check_argval $2 ; shift 2 ;; - -n|--nodes) NODES="$2" ; check_argval $2 ; shift 2 ;; - --master-playbook) MASTER_PLAYBOOK="$2" ; check_argval $2 ; shift 2 ;; - --node-playbook) NODE_PLAYBOOK="$2" ; check_argval $2 ; shift 2 ;; - --) shift ; break ;; - *) break ;; - esac -done - -shift $((OPTIND-1)) - -[ -z "${1:-}" ] && (usage; exit 1) - -case "${1}" in - 'create') - [ -z "${2:-}" ] && (usage; exit 1) - ENV="${2}" - create_cluster ;; - 'update') - [ -z "${2:-}" ] && (usage; exit 1) - ENV="${2}" - update_cluster ;; - 'terminate') - [ -z "${2:-}" ] && (usage; exit 1) - ENV="${2}" - terminate_cluster ;; - 'list') ./cloud.rb "${PROVIDER}" list ;; - 'help') usage; exit 0 ;; - *) - echo -n 1>&2 "${1} is not a supported operation"; - usage; - exit 1 ;; -esac - -exit 0 diff --git a/inventory/aws/group_vars/all b/inventory/aws/group_vars/all new file mode 100644 index 000000000..b22da00de --- /dev/null +++ b/inventory/aws/group_vars/all @@ -0,0 +1,2 @@ +--- +ansible_ssh_user: root diff --git a/inventory/gce/group_vars/all b/inventory/gce/group_vars/all index 3e969df63..b22da00de 100644 --- a/inventory/gce/group_vars/all +++ b/inventory/gce/group_vars/all @@ -1,7 +1,2 @@ --- ansible_ssh_user: root -openshift_hostname: "{{ ansible_default_ipv4.address }}" -openshift_public_hostname: "{{ ansible_default_ipv4.address }}" -openshift_ip: "{{ ansible_default_ipv4.address }}" -openshift_public_ip: "{{ gce_public_ip }}" -openshift_env: "{{ oo_env }}" diff --git a/inventory/gce/group_vars/tag_host-type-master b/inventory/gce/group_vars/tag_host-type-master deleted file mode 100644 index ddbdc650c..000000000 --- a/inventory/gce/group_vars/tag_host-type-master +++ /dev/null @@ -1,5 +0,0 @@ ---- -openshift_api_url: https://{{ openshift_hostname }}:8443 -openshift_api_public_url: https://{{ openshift_public_hostname }}:8443 -openshift_webui_url: https://{{ openshift_hostname }}:8444 -openshift_webui_public_url: https://{{ openshift_public_hostname }}:8444 diff --git a/inventory/gce/group_vars/tag_host-type-node b/inventory/gce/group_vars/tag_host-type-node deleted file mode 100644 index bb95a724d..000000000 --- a/inventory/gce/group_vars/tag_host-type-node +++ /dev/null @@ -1,6 +0,0 @@ ---- -openshift_node_cpu: -openshift_node_memory: -openshift_node_pod_cidr: -openshift_node_labels: {} -openshift_node_annotations: {} diff --git a/inventory/gce/group_vars/tag_host-type-openshift-master b/inventory/gce/group_vars/tag_host-type-openshift-master deleted file mode 120000 index c0c4cf370..000000000 --- a/inventory/gce/group_vars/tag_host-type-openshift-master +++ /dev/null @@ -1 +0,0 @@ -tag_host-type-master \ No newline at end of file diff --git a/inventory/gce/group_vars/tag_host-type-openshift-node b/inventory/gce/group_vars/tag_host-type-openshift-node deleted file mode 120000 index ebbce6136..000000000 --- a/inventory/gce/group_vars/tag_host-type-openshift-node +++ /dev/null @@ -1 +0,0 @@ -tag_host-type-node \ No newline at end of file diff --git a/playbooks/aws/openshift-cluster/filter_plugins b/playbooks/aws/openshift-cluster/filter_plugins new file mode 120000 index 000000000..99a95e4ca --- /dev/null +++ b/playbooks/aws/openshift-cluster/filter_plugins @@ -0,0 +1 @@ +../../../filter_plugins \ No newline at end of file diff --git a/playbooks/aws/openshift-cluster/launch.yml b/playbooks/aws/openshift-cluster/launch.yml new file mode 100644 index 000000000..3561c1803 --- /dev/null +++ b/playbooks/aws/openshift-cluster/launch.yml @@ -0,0 +1,62 @@ +--- +- name: Launch instance(s) + hosts: localhost + connection: local + gather_facts: no + vars_files: + - vars.yml + tasks: + - set_fact: k8s_type="master" + + - name: Generate master instance names(s) + set_fact: scratch={{ cluster_id }}-{{ k8s_type }}-{{ '%05x' |format( 1048576 |random) }} + register: master_names_output + with_sequence: start=1 end={{ num_masters }} + + # These set_fact's cannot be combined + - set_fact: + master_names_string: "{% for item in master_names_output.results %}{{ item.ansible_facts.scratch }} {% endfor %}" + + - set_fact: + master_names: "{{ master_names_string.strip().split(' ') }}" + + - include: launch_instances.yml + vars: + instances: "{{ master_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + + - set_fact: k8s_type="node" + + - name: Generate node instance names(s) + set_fact: scratch={{ cluster_id }}-{{ k8s_type }}-{{ '%05x' |format( 1048576 |random) }} + register: node_names_output + with_sequence: start=1 end={{ num_nodes }} + + # These set_fact's cannot be combined + - set_fact: + node_names_string: "{% for item in node_names_output.results %}{{ item.ansible_facts.scratch }} {% endfor %}" + + - set_fact: + node_names: "{{ node_names_string.strip().split(' ') }}" + + - include: launch_instances.yml + vars: + instances: "{{ node_names }}" + cluster: "{{ cluster_id }}" + type: "{{ k8s_type }}" + +- hosts: "tag_env_{{ cluster_id }}" + roles: + - openshift_repos + - os_update_latest + +- include: ../openshift-master/config.yml + vars: + oo_host_group_exp: "groups[\"tag_env-host-type_{{ cluster_id }}-openshift-master\"]" + +- include: ../openshift-node/config.yml + vars: + oo_host_group_exp: "groups[\"tag_env-host-type_{{ cluster_id }}-openshift-node\"]" + +- include: list.yml diff --git a/playbooks/aws/openshift-cluster/launch_instances.yml b/playbooks/aws/openshift-cluster/launch_instances.yml new file mode 100644 index 000000000..e4d5952fd --- /dev/null +++ b/playbooks/aws/openshift-cluster/launch_instances.yml @@ -0,0 +1,62 @@ +--- +- set_fact: + machine_type: "{{ lookup('env', 'ec2_instance_type')|default('m3.large', true) }}" + machine_image: "{{ lookup('env', 'ec2_ami')|default('ami-307b3658', true) }}" + machine_region: "{{ lookup('env', 'ec2_region')|default('us-east-1', true) }}" + machine_keypair: "{{ lookup('env', 'ec2_keypair')|default('libra', true) }}" + created_by: "{{ lookup('env', 'LOGNAME')|default(cluster, true) }}" + env: "{{ cluster }}" + host_type: "{{ type }}" + env_host_type: "{{ cluster }}-openshift-{{ type }}" + +- name: Launch instance(s) + ec2: + state: present + region: "{{ machine_region }}" + keypair: "{{ machine_keypair }}" + group: ['public'] + instance_type: "{{ machine_type }}" + image: "{{ machine_image }}" + count: "{{ instances | oo_len }}" + wait: yes + instance_tags: + created-by: "{{ created_by }}" + env: "{{ env }}" + host-type: "{{ host_type }}" + env-host-type: "{{ env_host_type }}" + register: ec2 + +- name: Add Name tag to instances + ec2_tag: resource={{ item.1.id }} region={{ machine_region }} state=present + with_together: + - instances + - ec2.instances + args: + tags: + Name: "{{ item.0 }}" + +- set_fact: + instance_groups: tag_created-by_{{ created_by }}, tag_env_{{ env }}, tag_host-type_{{ host_type }}, tag_env-host-type_{{ env_host_type }} + +- name: Add new instances groups and variables + add_host: + hostname: "{{ item.0 }}" + ansible_ssh_host: "{{ item.1.dns_name }}" + groups: "{{ instance_groups }}" + ec2_private_ip_address: "{{ item.1.private_ip }}" + ec2_ip_address: "{{ item.1.public_ip }}" + with_together: + - instances + - ec2.instances + +- name: Wait for ssh + wait_for: "port=22 host={{ item.dns_name }}" + with_items: ec2.instances + +- name: Wait for root user setup + command: "ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null root@{{ item.dns_name }} echo root user is setup" + register: result + until: result.rc == 0 + retries: 20 + delay: 10 + with_items: ec2.instances diff --git a/playbooks/aws/openshift-cluster/list.yml b/playbooks/aws/openshift-cluster/list.yml new file mode 100644 index 000000000..08e9e2df4 --- /dev/null +++ b/playbooks/aws/openshift-cluster/list.yml @@ -0,0 +1,17 @@ +--- +- name: Generate oo_list_hosts group + hosts: localhost + gather_facts: no + tasks: + - set_fact: scratch_group=tag_env_{{ cluster_id }} + when: cluster_id != '' + - set_fact: scratch_group=all + when: scratch_group is not defined + - add_host: name={{ item }} groups=oo_list_hosts + with_items: groups[scratch_group] | difference(['localhost']) + +- name: List Hosts + hosts: oo_list_hosts + gather_facts: no + tasks: + - debug: msg="public:{{hostvars[inventory_hostname].ec2_ip_address}} private:{{hostvars[inventory_hostname].ec2_private_ip_address}}" diff --git a/playbooks/aws/openshift-cluster/roles b/playbooks/aws/openshift-cluster/roles new file mode 120000 index 000000000..20c4c58cf --- /dev/null +++ b/playbooks/aws/openshift-cluster/roles @@ -0,0 +1 @@ +../../../roles \ No newline at end of file diff --git a/playbooks/aws/openshift-cluster/terminate.yml b/playbooks/aws/openshift-cluster/terminate.yml new file mode 100644 index 000000000..39607633a --- /dev/null +++ b/playbooks/aws/openshift-cluster/terminate.yml @@ -0,0 +1,14 @@ +--- +- name: Terminate instance(s) + hosts: localhost + + vars_files: + - vars.yml + +- include: ../openshift-node/terminate.yml + vars: + oo_host_group_exp: 'groups["tag_env-host-type_{{ cluster_id }}-openshift-node"]' + +- include: ../openshift-master/terminate.yml + vars: + oo_host_group_exp: 'groups["tag_env-host-type_{{ cluster_id }}-openshift-master"]' diff --git a/playbooks/aws/openshift-cluster/update.yml b/playbooks/aws/openshift-cluster/update.yml new file mode 100644 index 000000000..90ecdc6ab --- /dev/null +++ b/playbooks/aws/openshift-cluster/update.yml @@ -0,0 +1,13 @@ +--- +- hosts: "tag_env_{{ cluster_id }}" + roles: + - openshift_repos + - os_update_latest + +- include: ../openshift-master/config.yml + vars: + oo_host_group_exp: "groups[\"tag_env-host-type_{{ cluster_id }}-openshift-master\"]" + +- include: ../openshift-node/config.yml + vars: + oo_host_group_exp: "groups[\"tag_env-host-type_{{ cluster_id }}-openshift-node\"]" diff --git a/playbooks/aws/openshift-cluster/vars.yml b/playbooks/aws/openshift-cluster/vars.yml new file mode 100644 index 000000000..ed97d539c --- /dev/null +++ b/playbooks/aws/openshift-cluster/vars.yml @@ -0,0 +1 @@ +--- diff --git a/playbooks/aws/openshift-master/config.yml b/playbooks/aws/openshift-master/config.yml index bbf1f654a..1c4060eee 100644 --- a/playbooks/aws/openshift-master/config.yml +++ b/playbooks/aws/openshift-master/config.yml @@ -1,5 +1,5 @@ --- -- name: "populate oo_masters_to_config host group if needed" +- name: Populate oo_masters_to_config host group if needed hosts: localhost gather_facts: no tasks: @@ -8,34 +8,17 @@ with_items: "{{ oo_host_group_exp | default('') }}" when: oo_host_group_exp is defined -- name: "Gather facts for nodes in {{ oo_env }}" - hosts: "tag_env-host-type_{{ oo_env }}-openshift-node" - connection: ssh - user: root - -- name: "Set Origin specific facts on localhost (for later use)" - hosts: localhost - gather_facts: no - tasks: - - name: Setting openshift_node_ips fact on localhost - set_fact: - openshift_node_ips: "{{ hostvars - | oo_select_keys(groups['tag_env-host-type_' + oo_env + '-openshift-node']) - | oo_collect(attribute='ansible_default_ipv4.address') }}" - when: groups['tag_env-host-type_' + oo_env + '-openshift-node'] is defined - -- name: "Configure instances" +- name: Configure instances hosts: oo_masters_to_config - connection: ssh - user: root + vars: + openshift_hostname: "{{ ec2_private_ip_address }}" + openshift_public_hostname: "{{ ec2_ip_address }}" + # TODO: this should be removed once openshift-sdn packages are available + openshift_use_openshift_sdn: False vars_files: - - vars.yml + - vars.yml roles: - - { - role: openshift_master, - openshift_node_ips: "{{ hostvars['localhost'].openshift_node_ips | default(['']) }}", - openshift_env: "{{ oo_env }}", - openshift_public_ip: "{{ ec2_ip_address }}" - } + - openshift_master + #- openshift_sdn_master - pods - os_env_extras diff --git a/playbooks/aws/openshift-master/launch.yml b/playbooks/aws/openshift-master/launch.yml index 3d5a7f579..3d87879a0 100644 --- a/playbooks/aws/openshift-master/launch.yml +++ b/playbooks/aws/openshift-master/launch.yml @@ -46,13 +46,16 @@ tags: "{{ oo_new_inst_tags }}" - name: Add new instances public IPs to oo_masters_to_config - add_host: "hostname={{ item.0 }} ansible_ssh_host={{ item.1.dns_name }} groupname=oo_masters_to_config" + add_host: + hostname: "{{ item.0 }}" + ansible_ssh_host: "{{ item.1.dns_name }}" + groupname: oo_masters_to_config + ec2_private_ip_address: "{{ item.1.private_ip }}" + ec2_ip_address: "{{ item.1.public_ip }}" with_together: - oo_new_inst_names - ec2.instances - - debug: var=ec2 - - name: Wait for ssh wait_for: "port=22 host={{ item.dns_name }}" with_items: ec2.instances diff --git a/playbooks/aws/openshift-master/terminate.yml b/playbooks/aws/openshift-master/terminate.yml new file mode 100644 index 000000000..fd15cf00f --- /dev/null +++ b/playbooks/aws/openshift-master/terminate.yml @@ -0,0 +1,52 @@ +--- +- name: Populate oo_masters_to_terminate host group if needed + hosts: localhost + gather_facts: no + tasks: + - name: Evaluate oo_host_group_exp if it's set + add_host: "name={{ item }} groups=oo_masters_to_terminate" + with_items: "{{ oo_host_group_exp | default('') }}" + when: oo_host_group_exp is defined + +- name: Gather facts for instances to terminate + hosts: oo_masters_to_terminate + +- name: Terminate instances + hosts: localhost + connection: local + gather_facts: no + vars: + host_vars: "{{ hostvars + | oo_select_keys(groups['oo_masters_to_terminate']) }}" + tasks: + - name: Terminate instances + ec2: + state: absent + instance_ids: ["{{ item.ec2_id }}"] + region: "{{ item.ec2_region }}" + ignore_errors: yes + register: ec2_term + with_items: host_vars + + # Fail if any of the instances failed to terminate with an error other + # than 403 Forbidden + - fail: msg=Terminating instance {{ item.item.ec2_id }} failed with message {{ item.msg }} + when: "item.failed and not item.msg | search(\"error: EC2ResponseError: 403 Forbidden\")" + with_items: ec2_term.results + + - name: Stop instance if termination failed + ec2: + state: stopped + instance_ids: ["{{ item.item.ec2_id }}"] + region: "{{ item.item.ec2_region }}" + register: ec2_stop + when: item.failed + with_items: ec2_term.results + + - name: Rename stopped instances + ec2_tag: resource={{ item.item.item.ec2_id }} region={{ item.item.item.ec2_region }} state=present + args: + tags: + Name: "{{ item.item.item.ec2_tag_Name }}-terminate" + with_items: ec2_stop.results + diff --git a/playbooks/aws/openshift-master/vars.yml b/playbooks/aws/openshift-master/vars.yml index fb5f4ea42..c196b2fca 100644 --- a/playbooks/aws/openshift-master/vars.yml +++ b/playbooks/aws/openshift-master/vars.yml @@ -1,2 +1,3 @@ --- openshift_debug_level: 4 +openshift_cluster_id: "{{ cluster_id }}" diff --git a/playbooks/aws/openshift-node/config.yml b/playbooks/aws/openshift-node/config.yml index 3cf2c58b2..b08ed7571 100644 --- a/playbooks/aws/openshift-node/config.yml +++ b/playbooks/aws/openshift-node/config.yml @@ -1,5 +1,5 @@ --- -- name: "populate oo_nodes_to_config host group if needed" +- name: Populate oo_nodes_to_config host group if needed hosts: localhost gather_facts: no tasks: @@ -7,42 +7,101 @@ add_host: "name={{ item }} groups=oo_nodes_to_config" with_items: "{{ oo_host_group_exp | default('') }}" when: oo_host_group_exp is defined + - add_host: + name: "{{ groups['tag_env-host-type_' ~ cluster_id ~ '-openshift-master'][0] }}" + groups: oo_first_master + when: oo_host_group_exp is defined -- name: "Gather facts for masters in {{ oo_env }}" - hosts: "tag_env-host-type_{{ oo_env }}-openshift-master" - connection: ssh - user: root -- name: "Set OO sepcific facts on localhost (for later use)" - hosts: localhost - gather_facts: no +- name: Gather and set facts for hosts to configure + hosts: oo_nodes_to_config + roles: + - openshift_facts tasks: - - name: Setting openshift_master_ips fact on localhost - set_fact: - openshift_master_ips: "{{ hostvars - | oo_select_keys(groups['tag_env-host-type_' + oo_env + '-openshift-master']) - | oo_collect(attribute='ansible_default_ipv4.address') }}" - when: groups['tag_env-host-type_' + oo_env + '-openshift-master'] is defined - - name: Setting openshift_master_public_ips fact on localhost - set_fact: - openshift_master_public_ips: "{{ hostvars - | oo_select_keys(groups['tag_env-host-type-' + oo_env + '-openshift-master']) - | oo_collect(attribute='ec2_ip_address') }}" - when: groups['tag_env-host-type-' + oo_env + '-openshift-master'] is defined - -- name: "Configure instances" + # Since the master is registering the nodes before they are configured, we + # need to make sure to set the node properties beforehand if we do not want + # the defaults + - openshift_facts: + role: "{{ item.role }}" + local_facts: "{{ item.local_facts }}" + with_items: + - role: common + local_facts: + hostname: "{{ ec2_private_ip_address }}" + public_hostname: "{{ ec2_ip_address }}" + # TODO: this should be removed once openshift-sdn packages are available + use_openshift_sdn: False + - role: node + local_facts: + external_id: "{{ openshift_node_external_id | default(None) }}" + resources_cpu: "{{ openshfit_node_resources_cpu | default(None) }}" + resources_memory: "{{ openshfit_node_resources_memory | default(None) }}" + pod_cidr: "{{ openshfit_node_pod_cidr | default(None) }}" + labels: "{{ openshfit_node_labels | default(None) }}" + annotations: "{{ openshfit_node_annotations | default(None) }}" + + +- name: Register nodes + hosts: oo_first_master + vars: + openshift_nodes: "{{ hostvars + | oo_select_keys(groups['oo_nodes_to_config']) }}" + roles: + - openshift_register_nodes + tasks: + - name: Create local temp directory for syncing certs + local_action: command /usr/bin/mktemp -d /tmp/openshift-ansible-XXXXXXX + register: mktemp + + - name: Sync master certs to localhost + synchronize: + mode: pull + checksum: yes + src: /var/lib/openshift/openshift.local.certificates + dest: "{{ mktemp.stdout }}" + + +- name: Configure instances hosts: oo_nodes_to_config - connection: ssh - user: root vars_files: - - vars.yml + - vars.yml + vars: + openshift_hostname: "{{ ec2_private_ip_address }}" + openshift_public_hostname: "{{ ec2_ip_address }}" + sync_tmpdir: "{{ hostvars[groups['oo_first_master'][0]].mktemp.stdout }}" + cert_parent_rel_path: openshift.local.certificates + cert_rel_path: "{{ cert_parent_rel_path }}/node-{{ openshift.common.hostname }}" + cert_base_path: /var/lib/openshift + cert_parent_path: "{{ cert_base_path }}/{{ cert_parent_rel_path }}" + cert_path: "{{ cert_base_path }}/{{ cert_rel_path }}" + pre_tasks: + - name: Ensure certificate directories exists + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ cert_path }}" + - "{{ cert_parent_path }}/ca" + + # TODO: notify restart openshift-node and/or restart openshift-sdn-node, + # possibly test service started time against certificate/config file + # timestamps in openshift-node or openshift-sdn-node to trigger notify + - name: Sync certs to nodes + synchronize: + checksum: yes + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: no + group: no + with_items: + - src: "{{ sync_tmpdir }}/{{ cert_rel_path }}" + dest: "{{ cert_parent_path }}" + - src: "{{ sync_tmpdir }}/{{ cert_parent_rel_path }}/ca/cert.crt" + dest: "{{ cert_parent_path }}/ca/cert.crt" + - local_action: file name={{ sync_tmpdir }} state=absent + run_once: true roles: - - { - role: openshift_node, - openshift_master_ips: "{{ hostvars['localhost'].openshift_master_ips | default(['']) }}", - openshift_master_public_ips: "{{ hostvars['localhost'].openshift_master_public_ips | default(['']) }}", - openshift_env: "{{ oo_env }}", - openshift_public_ip: "{{ ec2_ip_address }}" - } + - openshift_node + #- openshift_sdn_node - os_env_extras - os_env_extras_node diff --git a/playbooks/aws/openshift-node/launch.yml b/playbooks/aws/openshift-node/launch.yml index 4745fc658..b7ef593e7 100644 --- a/playbooks/aws/openshift-node/launch.yml +++ b/playbooks/aws/openshift-node/launch.yml @@ -27,7 +27,9 @@ register: ec2 - name: Add new instances public IPs to the atomic proxy host group - add_host: "hostname={{ item.public_ip }} groupname=new_ec2_instances" + add_host: + hostname: "{{ item.public_ip }}" + groupname: new_ec2_instances" with_items: ec2.instances - name: Add Name and environment tags to instances @@ -46,13 +48,16 @@ tags: "{{ oo_new_inst_tags }}" - name: Add new instances public IPs to oo_nodes_to_config - add_host: "hostname={{ item.0 }} ansible_ssh_host={{ item.1.dns_name }} groupname=oo_nodes_to_config" + add_host: + hostname: "{{ item.0 }}" + ansible_ssh_host: "{{ item.1.dns_name }}" + groupname: oo_nodes_to_config + ec2_private_ip_address: "{{ item.1.private_ip }}" + ec2_ip_address: "{{ item.1.public_ip }}" with_together: - oo_new_inst_names - ec2.instances - - debug: var=ec2 - - name: Wait for ssh wait_for: "port=22 host={{ item.dns_name }}" with_items: ec2.instances diff --git a/playbooks/aws/openshift-node/terminate.yml b/playbooks/aws/openshift-node/terminate.yml new file mode 100644 index 000000000..1c0c77eb7 --- /dev/null +++ b/playbooks/aws/openshift-node/terminate.yml @@ -0,0 +1,52 @@ +--- +- name: Populate oo_nodes_to_terminate host group if needed + hosts: localhost + gather_facts: no + tasks: + - name: Evaluate oo_host_group_exp if it's set + add_host: "name={{ item }} groups=oo_nodes_to_terminate" + with_items: "{{ oo_host_group_exp | default('') }}" + when: oo_host_group_exp is defined + +- name: Gather facts for instances to terminate + hosts: oo_nodes_to_terminate + +- name: Terminate instances + hosts: localhost + connection: local + gather_facts: no + vars: + host_vars: "{{ hostvars + | oo_select_keys(groups['oo_nodes_to_terminate']) }}" + tasks: + - name: Terminate instances + ec2: + state: absent + instance_ids: ["{{ item.ec2_id }}"] + region: "{{ item.ec2_region }}" + ignore_errors: yes + register: ec2_term + with_items: host_vars + + # Fail if any of the instances failed to terminate with an error other + # than 403 Forbidden + - fail: msg=Terminating instance {{ item.item.ec2_id }} failed with message {{ item.msg }} + when: "item.failed and not item.msg | search(\"error: EC2ResponseError: 403 Forbidden\")" + with_items: ec2_term.results + + - name: Stop instance if termination failed + ec2: + state: stopped + instance_ids: ["{{ item.item.ec2_id }}"] + region: "{{ item.item.ec2_region }}" + register: ec2_stop + when: item.failed + with_items: ec2_term.results + + - name: Rename stopped instances + ec2_tag: resource={{ item.item.item.ec2_id }} region={{ item.item.item.ec2_region }} state=present + args: + tags: + Name: "{{ item.item.item.ec2_tag_Name }}-terminate" + with_items: ec2_stop.results + diff --git a/playbooks/aws/openshift-node/vars.yml b/playbooks/aws/openshift-node/vars.yml index fb5f4ea42..c196b2fca 100644 --- a/playbooks/aws/openshift-node/vars.yml +++ b/playbooks/aws/openshift-node/vars.yml @@ -1,2 +1,3 @@ --- openshift_debug_level: 4 +openshift_cluster_id: "{{ cluster_id }}" diff --git a/playbooks/gce/openshift-cluster/launch.yml b/playbooks/gce/openshift-cluster/launch.yml index 889d92d40..14cdd2537 100644 --- a/playbooks/gce/openshift-cluster/launch.yml +++ b/playbooks/gce/openshift-cluster/launch.yml @@ -11,7 +11,7 @@ - name: Generate master instance names(s) set_fact: scratch={{ cluster_id }}-{{ k8s_type }}-{{ '%05x' |format( 1048576 |random) }} register: master_names_output - with_sequence: start=1 end={{ masters }} + with_sequence: start=1 end={{ num_masters }} # These set_fact's cannot be combined - set_fact: @@ -25,14 +25,13 @@ instances: "{{ master_names }}" cluster: "{{ cluster_id }}" type: "{{ k8s_type }}" - group_name: "tag_env-host-type-{{ cluster_id }}-openshift-master" - set_fact: k8s_type="node" - name: Generate node instance names(s) set_fact: scratch={{ cluster_id }}-{{ k8s_type }}-{{ '%05x' |format( 1048576 |random) }} register: node_names_output - with_sequence: start=1 end={{ nodes }} + with_sequence: start=1 end={{ num_nodes }} # These set_fact's cannot be combined - set_fact: @@ -55,9 +54,9 @@ - include: ../openshift-master/config.yml vars: oo_host_group_exp: "groups[\"tag_env-host-type-{{ cluster_id }}-openshift-master\"]" - oo_env: "{{ cluster_id }}" - include: ../openshift-node/config.yml vars: oo_host_group_exp: "groups[\"tag_env-host-type-{{ cluster_id }}-openshift-node\"]" - oo_env: "{{ cluster_id }}" + +- include: list.yml diff --git a/playbooks/gce/openshift-cluster/launch_instances.yml b/playbooks/gce/openshift-cluster/launch_instances.yml index 20e31d990..b4f33bd87 100644 --- a/playbooks/gce/openshift-cluster/launch_instances.yml +++ b/playbooks/gce/openshift-cluster/launch_instances.yml @@ -1,3 +1,7 @@ +--- +# TODO: when we are ready to go to ansible 1.9+ support only, we can update to +# the gce task to use the disk_auto_delete parameter to avoid having to delete +# the disk as a separate step on termination - set_fact: machine_type: "{{ lookup('env', 'gce_machine_type') |default('n1-standard-1', true) }}" @@ -18,12 +22,13 @@ - "env-host-type-{{ cluster }}-openshift-{{ type }}" register: gce -- name: Add new instances public IPs +- name: Add new instances to groups and set variables needed add_host: hostname: "{{ item.name }}" ansible_ssh_host: "{{ item.public_ip }}" groups: "{{ item.tags | oo_prepend_strings_in_list('tag_') | join(',') }}" gce_public_ip: "{{ item.public_ip }}" + gce_private_ip: "{{ item.private_ip }}" with_items: gce.instance_data - name: Wait for ssh diff --git a/playbooks/gce/openshift-cluster/list.yml b/playbooks/gce/openshift-cluster/list.yml new file mode 100644 index 000000000..1124b0ea3 --- /dev/null +++ b/playbooks/gce/openshift-cluster/list.yml @@ -0,0 +1,17 @@ +--- +- name: Generate oo_list_hosts group + hosts: localhost + gather_facts: no + tasks: + - set_fact: scratch_group=tag_env-{{ cluster_id }} + when: cluster_id != '' + - set_fact: scratch_group=all + when: scratch_group is not defined + - add_host: name={{ item }} groups=oo_list_hosts + with_items: groups[scratch_group] | difference(['localhost']) | difference(groups.status_terminated) + +- name: List Hosts + hosts: oo_list_hosts + gather_facts: no + tasks: + - debug: msg="public:{{hostvars[inventory_hostname].gce_public_ip}} private:{{hostvars[inventory_hostname].gce_private_ip}}" diff --git a/playbooks/gce/openshift-cluster/update.yml b/playbooks/gce/openshift-cluster/update.yml new file mode 100644 index 000000000..973e4c3ef --- /dev/null +++ b/playbooks/gce/openshift-cluster/update.yml @@ -0,0 +1,13 @@ +--- +- hosts: "tag_env-{{ cluster_id }}" + roles: + - openshift_repos + - os_update_latest + +- include: ../openshift-master/config.yml + vars: + oo_host_group_exp: "groups[\"tag_env-host-type-{{ cluster_id }}-openshift-master\"]" + +- include: ../openshift-node/config.yml + vars: + oo_host_group_exp: "groups[\"tag_env-host-type-{{ cluster_id }}-openshift-node\"]" diff --git a/playbooks/gce/openshift-master/config.yml b/playbooks/gce/openshift-master/config.yml index e405e2fb4..857da0763 100644 --- a/playbooks/gce/openshift-master/config.yml +++ b/playbooks/gce/openshift-master/config.yml @@ -1,3 +1,4 @@ +--- - name: master/config.yml, populate oo_masters_to_config host group if needed hosts: localhost gather_facts: no @@ -7,11 +8,10 @@ with_items: "{{ oo_host_group_exp | default('') }}" when: oo_host_group_exp is defined -- name: Gather facts for nodes in {{ oo_env }} - hosts: "tag_env-host-type-{{ oo_env }}-openshift-node" - - name: "Configure instances" hosts: oo_masters_to_config + vars: + openshift_hostname: "{{ gce_private_ip }}" vars_files: - vars.yml roles: diff --git a/playbooks/gce/openshift-master/launch.yml b/playbooks/gce/openshift-master/launch.yml index 3512274cc..287596002 100644 --- a/playbooks/gce/openshift-master/launch.yml +++ b/playbooks/gce/openshift-master/launch.yml @@ -1,4 +1,8 @@ --- +# TODO: when we are ready to go to ansible 1.9+ support only, we can update to +# the gce task to use the disk_auto_delete parameter to avoid having to delete +# the disk as a separate step on termination + - name: Launch instance(s) hosts: localhost connection: local @@ -25,15 +29,17 @@ register: gce - name: Add new instances public IPs to oo_masters_to_config - add_host: "hostname={{ item.name }} ansible_ssh_host={{ item.public_ip }} groupname=oo_masters_to_config" + add_host: + hostname: "{{ item.name }}" + ansible_ssh_host: "{{ item.public_ip }}" + groupname: oo_masters_to_config + gce_private_ip: "{{ item.private_ip }}" with_items: gce.instance_data - name: Wait for ssh wait_for: "port=22 host={{ item.public_ip }}" with_items: gce.instance_data - - debug: var=gce - - name: Wait for root user setup command: "ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null root@{{ item.public_ip }} echo root user is setup" register: result diff --git a/playbooks/gce/openshift-master/terminate.yml b/playbooks/gce/openshift-master/terminate.yml index 9e027cf41..8319774f8 100644 --- a/playbooks/gce/openshift-master/terminate.yml +++ b/playbooks/gce/openshift-master/terminate.yml @@ -1,17 +1,13 @@ -- name: "populate oo_hosts_to_terminate host group if needed" +--- +- name: Populate oo_masters_to_terminate host group if needed hosts: localhost gather_facts: no tasks: - - debug: var=oo_host_group_exp - - name: Evaluate oo_host_group_exp if it's set - add_host: "name={{ item }} groups=oo_hosts_to_terminate" + add_host: "name={{ item }} groups=oo_masters_to_terminate" with_items: "{{ oo_host_group_exp | default('') }}" when: oo_host_group_exp is defined - - debug: msg="{{ groups['oo_hosts_to_terminate'] }}" - - - name: Terminate master instances hosts: localhost connection: local @@ -23,12 +19,10 @@ pem_file: "{{ gce_pem_file }}" project_id: "{{ gce_project_id }}" state: 'absent' - instance_names: "{{ groups['oo_hosts_to_terminate'] }}" - disks: "{{ groups['oo_hosts_to_terminate'] }}" + instance_names: "{{ groups['oo_masters_to_terminate'] }}" + disks: "{{ groups['oo_masters_to_terminate'] }}" register: gce - - debug: var=gce - - name: Remove disks of instances gce_pd: service_account_email: "{{ gce_service_account_email }}" diff --git a/playbooks/gce/openshift-master/vars.yml b/playbooks/gce/openshift-master/vars.yml index fb5f4ea42..c196b2fca 100644 --- a/playbooks/gce/openshift-master/vars.yml +++ b/playbooks/gce/openshift-master/vars.yml @@ -1,2 +1,3 @@ --- openshift_debug_level: 4 +openshift_cluster_id: "{{ cluster_id }}" diff --git a/playbooks/gce/openshift-node/config.yml b/playbooks/gce/openshift-node/config.yml index e0d074572..771cc3a94 100644 --- a/playbooks/gce/openshift-node/config.yml +++ b/playbooks/gce/openshift-node/config.yml @@ -1,3 +1,4 @@ +--- - name: node/config.yml, populate oo_nodes_to_config host group if needed hosts: localhost gather_facts: no @@ -6,50 +7,42 @@ add_host: "name={{ item }} groups=oo_nodes_to_config" with_items: "{{ oo_host_group_exp | default('') }}" when: oo_host_group_exp is defined - - name: Find masters for env - add_host: "name={{ item }} groups=oo_masters_for_node_config" - with_items: groups['tag_env-host-type-' + oo_env + '-openshift-master'] + - add_host: + name: "{{ groups['tag_env-host-type-' ~ cluster_id ~ '-openshift-master'][0] }}" + groups: oo_first_master + when: oo_host_group_exp is defined -- name: Gather facts for masters in {{ oo_env }} - hosts: tag_env-host-type-{{ oo_env }}-openshift-master - tasks: - - set_fact: - openshift_master_ip: "{{ openshift_ip }}" - openshift_master_api_url: "{{ openshift_api_url }}" - openshift_master_webui_url: "{{ openshift_webui_url }}" - openshift_master_hostname: "{{ openshift_hostname }}" - openshift_master_public_ip: "{{ openshift_public_ip }}" - openshift_master_api_public_url: "{{ openshift_api_public_url }}" - openshift_master_webui_public_url: "{{ openshift_webui_public_url }}" - openshift_master_public_hostnames: "{{ openshift_public_hostname }}" -- name: Gather facts for hosts to configure - hosts: tag_env-host-type-{{ oo_env }}-openshift-node +- name: Gather and set facts for hosts to configure + hosts: oo_nodes_to_config + roles: + - openshift_facts tasks: - - set_fact: - openshift_node_hostname: "{{ openshift_hostname }}" - openshift_node_name: "{{ openshift_hostname }}" - openshift_node_cpu: "{{ openshift_node_cpu if openshift_node_cpu else ansible_processor_cores }}" - openshift_node_memory: "{{ openshift_node_memory if openshift_node_memory else (ansible_memtotal_mb|int * 1024 * 1024 * 0.75)|int }}" - openshift_node_pod_cidr: "{{ openshift_node_pod_cidr if openshift_node_pod_cidr else None }}" - openshift_node_host_ip: "{{ openshift_ip }}" - openshift_node_labels: "{{ openshift_node_labels if openshift_node_labels else {} }}" - openshift_node_annotations: "{{ openshift_node_annotations if openshift_node_annotations else {} }}" + # Since the master is registering the nodes before they are configured, we + # need to make sure to set the node properties beforehand if we do not want + # the defaults + - openshift_facts: + role: "{{ item.role }}" + local_facts: "{{ item.local_facts }}" + with_items: + - role: common + local_facts: + hostname: "{{ gce_private_ip }}" + - role: node + local_facts: + external_id: "{{ openshift_node_external_id | default(None) }}" + resources_cpu: "{{ openshfit_node_resources_cpu | default(None) }}" + resources_memory: "{{ openshfit_node_resources_memory | default(None) }}" + pod_cidr: "{{ openshfit_node_pod_cidr | default(None) }}" + labels: "{{ openshfit_node_labels | default(None) }}" + annotations: "{{ openshfit_node_annotations | default(None) }}" + - name: Register nodes - hosts: tag_env-host-type-{{ oo_env }}-openshift-master[0] + hosts: oo_first_master vars: - openshift_node_group: tag_env-host-type-{{ oo_env }}-openshift-node openshift_nodes: "{{ hostvars - | oo_select_keys(groups[openshift_node_group]) }}" - openshift_master_group: tag_env-host-type-{{ oo_env }}-openshift-master - openshift_master_urls: "{{ hostvars - | oo_select_keys(groups[openshift_master_group]) - | oo_collect(attribute='openshift_master_api_url') }}" - openshift_master_public_urls: "{{ hostvars - | oo_select_keys(groups[openshift_master_group]) - | oo_collect(attribute='openshift_master_api_public_url') }}" - pre_tasks: + | oo_select_keys(groups['oo_nodes_to_config']) }}" roles: - openshift_register_nodes tasks: @@ -64,28 +57,14 @@ src: /var/lib/openshift/openshift.local.certificates dest: "{{ mktemp.stdout }}" -# TODO: sync generated certs between masters -# - name: Configure instances hosts: oo_nodes_to_config vars_files: - vars.yml vars: - openshift_master_group: tag_env-host-type-{{ oo_env }}-openshift-master - openshift_master_ips: "{{ hostvars - | oo_select_keys(groups[openshift_master_group]) - | oo_collect(attribute='openshift_master_ip') }}" - openshift_master_hostnames: "{{ hostvars - | oo_select_keys(groups[openshift_master_group]) - | oo_collect(attribute='openshift_master_hostname') }}" - openshift_master_public_ips: "{{ hostvars - | oo_select_keys(groups[openshift_master_group]) - | oo_collect(attribute='openshift_master_public_ip') }}" - openshift_master_public_hostnames: "{{ hostvars - | oo_select_keys(groups[openshift_master_group]) - | oo_collect(attribute='openshift_master_public_hostname') }}" + sync_tmpdir: "{{ hostvars[groups['oo_first_master'][0]].mktemp.stdout }}" cert_parent_rel_path: openshift.local.certificates - cert_rel_path: "{{ cert_parent_rel_path }}/node-{{ openshift_node_name }}" + cert_rel_path: "{{ cert_parent_rel_path }}/node-{{ openshift.common.hostname }}" cert_base_path: /var/lib/openshift cert_parent_path: "{{ cert_base_path }}/{{ cert_parent_rel_path }}" cert_path: "{{ cert_base_path }}/{{ cert_rel_path }}" @@ -98,11 +77,9 @@ - "{{ cert_path }}" - "{{ cert_parent_path }}/ca" - # TODO: only sync to a node if it's certs have been updated # TODO: notify restart openshift-node and/or restart openshift-sdn-node, # possibly test service started time against certificate/config file # timestamps in openshift-node or openshift-sdn-node to trigger notify - # TODO: also copy ca cert: /var/lib/openshift/openshift.local.certificates/ca/cert.crt - name: Sync certs to nodes synchronize: checksum: yes @@ -111,12 +88,13 @@ owner: no group: no with_items: - - src: "{{ hostvars[groups[openshift_master_group][0]].mktemp.stdout }}/{{ cert_rel_path }}" + - src: "{{ sync_tmpdir }}/{{ cert_rel_path }}" dest: "{{ cert_parent_path }}" - - src: "{{ hostvars[groups[openshift_master_group][0]].mktemp.stdout }}/{{ cert_parent_rel_path }}/ca/cert.crt" + - src: "{{ sync_tmpdir }}/{{ cert_parent_rel_path }}/ca/cert.crt" dest: "{{ cert_parent_path }}/ca/cert.crt" - - local_action: file name={{ hostvars[groups[openshift_master_group][0]].mktemp.stdout }} state=absent + - local_action: file name={{ sync_tmpdir }} state=absent run_once: true roles: - openshift_node - os_env_extras + - os_env_extras_node diff --git a/playbooks/gce/openshift-node/launch.yml b/playbooks/gce/openshift-node/launch.yml index ca2914d8a..73d0478ab 100644 --- a/playbooks/gce/openshift-node/launch.yml +++ b/playbooks/gce/openshift-node/launch.yml @@ -1,4 +1,8 @@ --- +# TODO: when we are ready to go to ansible 1.9+ support only, we can update to +# the gce task to use the disk_auto_delete parameter to avoid having to delete +# the disk as a separate step on termination + - name: Launch instance(s) hosts: localhost connection: local @@ -25,15 +29,17 @@ register: gce - name: Add new instances public IPs to oo_nodes_to_config - add_host: "hostname={{ item.name }} ansible_ssh_host={{ item.public_ip }} groupname=oo_nodes_to_config" + add_host: + hostname: "{{ item.name }}" + ansible_ssh_host: "{{ item.public_ip }}" + groupname: oo_nodes_to_config + gce_private_ip: "{{ item.private_ip }}" with_items: gce.instance_data - name: Wait for ssh wait_for: "port=22 host={{ item.public_ip }}" with_items: gce.instance_data - - debug: var=gce - - name: Wait for root user setup command: "ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null root@{{ item.public_ip }} echo root user is setup" register: result @@ -45,13 +51,3 @@ # Apply the configs, separate so that just the configs can be run by themselves - include: config.yml - -# Always bounce service to pick up new credentials -#- name: "Restart instances" -# hosts: oo_nodes_to_config -# connection: ssh -# user: root -# tasks: -# - debug: var=groups.oo_nodes_to_config -# - name: Restart OpenShift -# service: name=openshift-node enabled=yes state=restarted diff --git a/playbooks/gce/openshift-node/terminate.yml b/playbooks/gce/openshift-node/terminate.yml index 9aa8a48c1..7d71dfcab 100644 --- a/playbooks/gce/openshift-node/terminate.yml +++ b/playbooks/gce/openshift-node/terminate.yml @@ -1,17 +1,13 @@ -- name: "populate oo_hosts_to_terminate host group if needed" +--- +- name: Populate oo_nodes_to_terminate host group if needed hosts: localhost gather_facts: no tasks: - - debug: var=oo_host_group_exp - - name: Evaluate oo_host_group_exp if it's set - add_host: "name={{ item }} groups=oo_hosts_to_terminate" + add_host: "name={{ item }} groups=oo_nodes_to_terminate" with_items: "{{ oo_host_group_exp | default('') }}" when: oo_host_group_exp is defined - - debug: msg="{{ groups['oo_hosts_to_terminate'] }}" - - - name: Terminate node instances hosts: localhost connection: local @@ -23,12 +19,10 @@ pem_file: "{{ gce_pem_file }}" project_id: "{{ gce_project_id }}" state: 'absent' - instance_names: "{{ groups['oo_hosts_to_terminate'] }}" - disks: "{{ groups['oo_hosts_to_terminate'] }}" + instance_names: "{{ groups['oo_nodes_to_terminate'] }}" + disks: "{{ groups['oo_nodes_to_terminate'] }}" register: gce - - debug: var=gce - - name: Remove disks of instances gce_pd: service_account_email: "{{ gce_service_account_email }}" diff --git a/playbooks/gce/openshift-node/vars.yml b/playbooks/gce/openshift-node/vars.yml index fb5f4ea42..c196b2fca 100644 --- a/playbooks/gce/openshift-node/vars.yml +++ b/playbooks/gce/openshift-node/vars.yml @@ -1,2 +1,3 @@ --- openshift_debug_level: 4 +openshift_cluster_id: "{{ cluster_id }}" diff --git a/roles/openshift_common/README.md b/roles/openshift_common/README.md index 880d66e2c..14c2037e4 100644 --- a/roles/openshift_common/README.md +++ b/roles/openshift_common/README.md @@ -12,17 +12,20 @@ rhel-7-server-extra-rpms, and rhel-7-server-ose-beta-rpms repos. Role Variables -------------- -| Name | Default value | | -|-------------------------------|------------------------------|----------------------------------------| -| openshift_debug_level | 0 | Global openshift debug log verbosity | -| openshift_hostname | UNDEF (Required) | hostname to use for this instance | -| openshift_public_ip | UNDEF (Required) | Public IP address to use for this host | -| openshift_env | default | Envrionment name if multiple OpenShift instances | +| Name | Default value | | +|---------------------------|-------------------|---------------------------------------------| +| openshift_cluster_id | default | Cluster name if multiple OpenShift clusters | +| openshift_debug_level | 0 | Global openshift debug log verbosity | +| openshift_hostname | UNDEF | Internal hostname to use for this host (this value will set the hostname on the system) | +| openshift_ip | UNDEF | Internal IP address to use for this host | +| openshift_public_hostname | UNDEF | Public hostname to use for this host | +| openshift_public_ip | UNDEF | Public IP address to use for this host | Dependencies ------------ os_firewall +openshift_facts openshift_repos Example Playbook @@ -38,4 +41,4 @@ Apache License, Version 2.0 Author Information ------------------ -TODO +Jason DeTiberus (jdetiber@redhat.com) diff --git a/roles/openshift_common/defaults/main.yml b/roles/openshift_common/defaults/main.yml index 22b2c6ffd..4d3e0fe9e 100644 --- a/roles/openshift_common/defaults/main.yml +++ b/roles/openshift_common/defaults/main.yml @@ -1,2 +1,3 @@ --- +openshift_cluster_id: 'default' openshift_debug_level: 0 diff --git a/roles/openshift_common/meta/main.yml b/roles/openshift_common/meta/main.yml index cee4dd337..81363ec68 100644 --- a/roles/openshift_common/meta/main.yml +++ b/roles/openshift_common/meta/main.yml @@ -13,4 +13,5 @@ galaxy_info: - cloud dependencies: - { role: os_firewall } +- { role: openshift_facts } - { role: openshift_repos } diff --git a/roles/openshift_common/tasks/main.yml b/roles/openshift_common/tasks/main.yml index 07737a71f..941190534 100644 --- a/roles/openshift_common/tasks/main.yml +++ b/roles/openshift_common/tasks/main.yml @@ -1,19 +1,16 @@ --- -- name: Set hostname - hostname: name={{ openshift_hostname }} +- name: Set common OpenShift facts + openshift_facts: + role: 'common' + local_facts: + cluster_id: "{{ openshift_cluster_id | default('default') }}" + debug_level: "{{ openshift_debug_level | default(0) }}" + hostname: "{{ openshift_hostname | default(None) }}" + ip: "{{ openshift_ip | default(None) }}" + public_hostname: "{{ openshift_public_hostname | default(None) }}" + public_ip: "{{ openshift_public_ip | default(None) }}" + use_openshift_sdn: "{{ openshift_use_openshift_sdn | default(None) }}" -- name: Configure local facts file - file: path=/etc/ansible/facts.d/ state=directory mode=0750 +- name: Set hostname + hostname: name={{ openshift.common.hostname }} -- name: Set common OpenShift facts - include: set_facts.yml - facts: - - section: common - option: env - value: "{{ openshift_env | default('default') }}" - - section: common - option: host_type - value: "{{ openshift_host_type }}" - - section: common - option: debug_level - value: "{{ openshift_debug_level }}" diff --git a/roles/openshift_common/tasks/set_facts.yml b/roles/openshift_common/tasks/set_facts.yml deleted file mode 100644 index 349eecd1d..000000000 --- a/roles/openshift_common/tasks/set_facts.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- name: "Setting local_facts" - ini_file: - dest: /etc/ansible/facts.d/openshift.fact - mode: 0640 - section: "{{ item.section }}" - option: "{{ item.option }}" - value: "{{ item.value }}" - with_items: facts diff --git a/roles/openshift_common/vars/main.yml b/roles/openshift_common/vars/main.yml index 623aed9bf..50816d319 100644 --- a/roles/openshift_common/vars/main.yml +++ b/roles/openshift_common/vars/main.yml @@ -1,6 +1,7 @@ --- -openshift_master_credentials_dir: /var/lib/openshift/openshift.local.certificates/admin/ - # TODO: Upstream kubernetes only supports iptables currently, if this changes, # then these variable should be moved to defaults +# TODO: it might be possible to still use firewalld if we wire up the created +# chains with the public zone (or the zone associated with the correct +# interfaces) os_firewall_use_firewalld: False diff --git a/roles/openshift_facts/README.md b/roles/openshift_facts/README.md new file mode 100644 index 000000000..2fd50e236 --- /dev/null +++ b/roles/openshift_facts/README.md @@ -0,0 +1,34 @@ +OpenShift Facts +=============== + +Provides the openshift_facts module + +Requirements +------------ + +None + +Role Variables +-------------- + +None + +Dependencies +------------ + +None + +Example Playbook +---------------- + +TODO + +License +------- + +Apache License, Version 2.0 + +Author Information +------------------ + +Jason DeTiberus (jdetiber@redhat.com) diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py new file mode 100755 index 000000000..0dd343443 --- /dev/null +++ b/roles/openshift_facts/library/openshift_facts.py @@ -0,0 +1,482 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# vim: expandtab:tabstop=4:shiftwidth=4 + +DOCUMENTATION = ''' +--- +module: openshift_facts +short_description: OpenShift Facts +author: Jason DeTiberus +requirements: [ ] +''' +EXAMPLES = ''' +''' + +import ConfigParser +import copy + +class OpenShiftFactsUnsupportedRoleError(Exception): + pass + +class OpenShiftFactsFileWriteError(Exception): + pass + +class OpenShiftFacts(): + known_roles = ['common', 'master', 'node', 'master_sdn', 'node_sdn'] + + def __init__(self, role, filename, local_facts): + self.changed = False + self.filename = filename + if role not in self.known_roles: + raise OpenShiftFactsUnsupportedRoleError("Role %s is not supported by this module" % role) + self.role = role + self.facts = self.generate_facts(local_facts) + + def generate_facts(self, local_facts): + local_facts = self.init_local_facts(local_facts) + roles = local_facts.keys() + + defaults = self.get_defaults(roles) + provider_facts = self.init_provider_facts() + facts = self.apply_provider_facts(defaults, provider_facts, roles) + + facts = self.merge_facts(facts, local_facts) + facts['current_config'] = self.current_config(facts) + self.set_url_facts_if_unset(facts) + return dict(openshift=facts) + + + def set_url_facts_if_unset(self, facts): + if 'master' in facts: + for (url_var, use_ssl, port, default) in [ + ('api_url', + facts['master']['api_use_ssl'], + facts['master']['api_port'], + facts['common']['hostname']), + ('public_api_url', + facts['master']['api_use_ssl'], + facts['master']['api_port'], + facts['common']['public_hostname']), + ('console_url', + facts['master']['console_use_ssl'], + facts['master']['console_port'], + facts['common']['hostname']), + ('public_console_url' 'console_use_ssl', + facts['master']['console_use_ssl'], + facts['master']['console_port'], + facts['common']['public_hostname'])]: + if url_var not in facts['master']: + scheme = 'https' if use_ssl else 'http' + netloc = default + if (scheme == 'https' and port != '443') or (scheme == 'http' and port != '80'): + netloc = "%s:%s" % (netloc, port) + facts['master'][url_var] = urlparse.urlunparse((scheme, netloc, '', '', '', '')) + + + # Query current OpenShift config and return a dictionary containing + # settings that may be valuable for determining actions that need to be + # taken in the playbooks/roles + def current_config(self, facts): + current_config=dict() + roles = [ role for role in facts if role not in ['common','provider'] ] + for role in roles: + if 'roles' in current_config: + current_config['roles'].append(role) + else: + current_config['roles'] = [role] + + # TODO: parse the /etc/sysconfig/openshift-{master,node} config to + # determine the location of files. + + # Query kubeconfig settings + kubeconfig_dir = '/var/lib/openshift/openshift.local.certificates' + if role == 'node': + kubeconfig_dir = os.path.join(kubeconfig_dir, "node-%s" % facts['common']['hostname']) + + kubeconfig_path = os.path.join(kubeconfig_dir, '.kubeconfig') + if os.path.isfile('/usr/bin/openshift') and os.path.isfile(kubeconfig_path): + try: + _, output, error = module.run_command(["/usr/bin/openshift", "ex", + "config", "view", "-o", + "json", + "--kubeconfig=%s" % kubeconfig_path], + check_rc=False) + config = json.loads(output) + + try: + for cluster in config['clusters']: + config['clusters'][cluster]['certificate-authority-data'] = 'masked' + except KeyError: + pass + try: + for user in config['users']: + config['users'][user]['client-certificate-data'] = 'masked' + config['users'][user]['client-key-data'] = 'masked' + except KeyError: + pass + + current_config['kubeconfig'] = config + except Exception: + pass + + return current_config + + + def apply_provider_facts(self, facts, provider_facts, roles): + if not provider_facts: + return facts + + use_openshift_sdn = provider_facts.get('use_openshift_sdn') + if isinstance(use_openshift_sdn, bool): + facts['common']['use_openshift_sdn'] = use_openshift_sdn + + common_vars = [('hostname', 'ip'), ('public_hostname', 'public_ip')] + for h_var, ip_var in common_vars: + ip_value = provider_facts['network'].get(ip_var) + if ip_value: + facts['common'][ip_var] = ip_value + + facts['common'][h_var] = self.choose_hostname([provider_facts['network'].get(h_var)], facts['common'][ip_var]) + + if 'node' in roles: + ext_id = provider_facts.get('external_id') + if ext_id: + facts['node']['external_id'] = ext_id + + facts['provider'] = provider_facts + return facts + + def hostname_valid(self, hostname): + if (not hostname or + hostname.startswith('localhost') or + hostname.endswith('localdomain') or + len(hostname.split('.')) < 2): + return False + + return True + + def choose_hostname(self, hostnames=[], fallback=''): + hostname = fallback + + ips = [ i for i in hostnames if i is not None and re.match(r'\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z', i) ] + hosts = [ i for i in hostnames if i is not None and i not in set(ips) ] + + for host_list in (hosts, ips): + for h in host_list: + if self.hostname_valid(h): + return h + + return hostname + + def get_defaults(self, roles): + hardware_facts = self.get_hardware_facts() + net_facts = self.get_net_facts() + base_facts = self.get_base_facts() + + defaults = dict() + + common = dict(use_openshift_sdn=True) + ip = net_facts['default_ipv4']['address'] + common['ip'] = ip + common['public_ip'] = ip + + rc, output, error = module.run_command(['hostname', '-f']) + hostname_f = output.strip() if rc == 0 else '' + hostname_values = [hostname_f, base_facts['nodename'], base_facts['fqdn']] + hostname = self.choose_hostname(hostname_values) + + common['hostname'] = hostname + common['public_hostname'] = hostname + defaults['common'] = common + + if 'master' in roles: + # TODO: provide for a better way to override just the port, or just + # the urls, instead of forcing both, also to override the hostname + # without having to re-generate these urls later + master = dict(api_use_ssl=True, api_port='8443', + console_use_ssl=True, console_path='/console', + console_port='8443', etcd_use_ssl=False, + etcd_port='4001') + defaults['master'] = master + + if 'node' in roles: + node = dict(external_id=common['hostname'], pod_cidr='', + labels={}, annotations={}) + node['resources_cpu'] = hardware_facts['processor_cores'] + node['resources_memory'] = int(int(hardware_facts['memtotal_mb']) * 1024 * 1024 * 0.75) + defaults['node'] = node + + return defaults + + def merge_facts(self, orig, new): + facts = dict() + for key, value in orig.iteritems(): + if key in new: + if isinstance(value, dict): + facts[key] = self.merge_facts(value, new[key]) + else: + facts[key] = copy.copy(new[key]) + else: + facts[key] = copy.deepcopy(value) + new_keys = set(new.keys()) - set(orig.keys()) + for key in new_keys: + facts[key] = copy.deepcopy(new[key]) + return facts + + def query_metadata(self, metadata_url, headers=None, expect_json=False): + r, info = fetch_url(module, metadata_url, headers=headers) + if info['status'] != 200: + module.fail_json(msg='Failed to query metadata', result=r, + info=info) + if expect_json: + return module.from_json(r.read()) + else: + return [line.strip() for line in r.readlines()] + + def walk_metadata(self, metadata_url, headers=None, expect_json=False): + metadata = dict() + + for line in self.query_metadata(metadata_url, headers, expect_json): + if line.endswith('/') and not line == 'public-keys/': + key = line[:-1] + metadata[key]=self.walk_metadata(metadata_url + line, headers, + expect_json) + else: + results = self.query_metadata(metadata_url + line, headers, + expect_json) + if len(results) == 1: + metadata[line] = results.pop() + else: + metadata[line] = results + return metadata + + def get_provider_metadata(self, metadata_url, supports_recursive=False, + headers=None, expect_json=False): + if supports_recursive: + metadata = self.query_metadata(metadata_url, headers, expect_json) + else: + metadata = self.walk_metadata(metadata_url, headers, expect_json) + return metadata + + def get_hardware_facts(self): + if not hasattr(self, 'hardware_facts'): + self.hardware_facts = Hardware().populate() + return self.hardware_facts + + def get_base_facts(self): + if not hasattr(self, 'base_facts'): + self.base_facts = Facts().populate() + return self.base_facts + + def get_virt_facts(self): + if not hasattr(self, 'virt_facts'): + self.virt_facts = Virtual().populate() + return self.virt_facts + + def get_net_facts(self): + if not hasattr(self, 'net_facts'): + self.net_facts = Network(module).populate() + return self.net_facts + + def guess_host_provider(self): + # TODO: cloud provider facts should probably be submitted upstream + virt_facts = self.get_virt_facts() + hardware_facts = self.get_hardware_facts() + product_name = hardware_facts['product_name'] + product_version = hardware_facts['product_version'] + virt_type = virt_facts['virtualization_type'] + virt_role = virt_facts['virtualization_role'] + provider = None + metadata = None + + # 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('/sys/devices/virtual/dmi/id/bios_vendor') + if bios_vendor == 'Google': + provider = 'gce' + metadata_url = 'http://metadata.google.internal/computeMetadata/v1/?recursive=true' + headers = {'Metadata-Flavor': 'Google'} + metadata = self.get_provider_metadata(metadata_url, True, headers, + True) + + # Filter sshKeys and serviceAccounts from gce 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): + provider = 'ec2' + metadata_url = 'http://169.254.169.254/latest/meta-data/' + metadata = self.get_provider_metadata(metadata_url) + elif re.search(r'OpenStack', product_name): + provider = 'openstack' + metadata_url = 'http://169.254.169.254/openstack/latest/meta_data.json' + metadata = self.get_provider_metadata(metadata_url, True, None, True) + ec2_compat_url = 'http://169.254.169.254/latest/meta-data/' + metadata['ec2_compat'] = self.get_provider_metadata(ec2_compat_url) + + # Filter public_keys and random_seed from openstack metadata + metadata.pop('public_keys', None) + metadata.pop('random_seed', None) + return dict(name=provider, metadata=metadata) + + def normalize_provider_facts(self, provider, metadata): + if provider is None or metadata is None: + return {} + + # TODO: test for ipv6_enabled where possible (gce, aws do not support) + # and configure ipv6 facts if available + + # TODO: add support for setting user_data if available + + facts = dict(name=provider, metadata=metadata) + network = dict(interfaces=[], ipv6_enabled=False) + if provider == 'gce': + for interface in metadata['instance']['networkInterfaces']: + int_info = dict(ips=[interface['ip']], network_type=provider) + int_info['public_ips'] = [ ac['externalIp'] for ac in interface['accessConfigs'] ] + int_info['public_ips'].extend(interface['forwardedIps']) + _, _, network_id = interface['network'].rpartition('/') + int_info['network_id'] = network_id + network['interfaces'].append(int_info) + _, _, zone = metadata['instance']['zone'].rpartition('/') + facts['zone'] = zone + facts['external_id'] = metadata['instance']['id'] + + # Default to no sdn for GCE deployments + facts['use_openshift_sdn'] = False + + # GCE currently only supports a single interface + network['ip'] = network['interfaces'][0]['ips'][0] + network['public_ip'] = network['interfaces'][0]['public_ips'][0] + network['hostname'] = metadata['instance']['hostname'] + + # TODO: attempt to resolve public_hostname + network['public_hostname'] = network['public_ip'] + elif provider == 'ec2': + for interface in sorted(metadata['network']['interfaces']['macs'].values(), + key=lambda x: x['device-number']): + int_info = dict() + var_map = {'ips': 'local-ipv4s', 'public_ips': 'public-ipv4s'} + for ips_var, int_var in var_map.iteritems(): + ips = interface[int_var] + int_info[ips_var] = [ips] if isinstance(ips, basestring) else ips + int_info['network_type'] = 'vpc' if 'vpc-id' in interface else 'classic' + int_info['network_id'] = interface['subnet-id'] if int_info['network_type'] == 'vpc' else None + network['interfaces'].append(int_info) + facts['zone'] = metadata['placement']['availability-zone'] + facts['external_id'] = metadata['instance-id'] + + # TODO: actually attempt to determine default local and public ips + # by using the ansible default ip fact and the ipv4-associations + # form the ec2 metadata + network['ip'] = metadata['local-ipv4'] + network['public_ip'] = metadata['public-ipv4'] + + # TODO: verify that local hostname makes sense and is resolvable + network['hostname'] = metadata['local-hostname'] + + # TODO: verify that public hostname makes sense and is resolvable + network['public_hostname'] = metadata['public-hostname'] + elif provider == 'openstack': + # openstack ec2 compat api does not support network interfaces and + # the version tested on did not include the info in the openstack + # metadata api, should be updated if neutron exposes this. + + facts['zone'] = metadata['availability_zone'] + facts['external_id'] = metadata['uuid'] + network['ip'] = metadata['ec2_compat']['local-ipv4'] + network['public_ip'] = metadata['ec2_compat']['public-ipv4'] + + # TODO: verify local hostname makes sense and is resolvable + network['hostname'] = metadata['hostname'] + + # TODO: verify that public hostname makes sense and is resolvable + network['public_hostname'] = metadata['ec2_compat']['public-hostname'] + + facts['network'] = network + return facts + + def init_provider_facts(self): + provider_info = self.guess_host_provider() + provider_facts = self.normalize_provider_facts( + provider_info.get('name'), + provider_info.get('metadata') + ) + return provider_facts + + def get_facts(self): + # TODO: transform facts into cleaner format (openshift_ instead + # of openshift. + return self.facts + + def init_local_facts(self, facts={}): + changed = False + + local_facts = ConfigParser.SafeConfigParser() + local_facts.read(self.filename) + + section = self.role + if not local_facts.has_section(section): + local_facts.add_section(section) + changed = True + + for key, value in facts.iteritems(): + if isinstance(value, bool): + value = str(value) + if not value: + continue + if not local_facts.has_option(section, key) or local_facts.get(section, key) != value: + local_facts.set(section, key, value) + changed = True + + if changed and not module.check_mode: + try: + fact_dir = os.path.dirname(self.filename) + if not os.path.exists(fact_dir): + os.makedirs(fact_dir) + with open(self.filename, 'w') as fact_file: + local_facts.write(fact_file) + except (IOError, OSError) as e: + raise OpenShiftFactsFileWriteError("Could not create fact file: %s, error: %s" % (self.filename, e)) + self.changed = changed + + role_facts = dict() + for section in local_facts.sections(): + role_facts[section] = dict() + for opt, val in local_facts.items(section): + role_facts[section][opt] = val + return role_facts + + +def main(): + global module + module = AnsibleModule( + argument_spec = dict( + role=dict(default='common', + choices=OpenShiftFacts.known_roles, + required=False), + local_facts=dict(default={}, type='dict', required=False), + ), + supports_check_mode=True, + add_file_common_args=True, + ) + + role = module.params['role'] + local_facts = module.params['local_facts'] + fact_file = '/etc/ansible/facts.d/openshift.fact' + + openshift_facts = OpenShiftFacts(role, fact_file, local_facts) + + file_params = module.params.copy() + file_params['path'] = fact_file + file_args = module.load_file_common_arguments(file_params) + changed = module.set_fs_attributes_if_different(file_args, + openshift_facts.changed) + + return module.exit_json(changed=changed, + ansible_facts=openshift_facts.get_facts()) + +# import module snippets +from ansible.module_utils.basic import * +from ansible.module_utils.facts import * +from ansible.module_utils.urls import * +main() diff --git a/roles/openshift_facts/meta/main.yml b/roles/openshift_facts/meta/main.yml new file mode 100644 index 000000000..0be3afd24 --- /dev/null +++ b/roles/openshift_facts/meta/main.yml @@ -0,0 +1,15 @@ +--- +galaxy_info: + author: Jason DeTiberus + description: + company: Red Hat, Inc. + license: Apache License, Version 2.0 + min_ansible_version: 1.8 + platforms: + - name: EL + versions: + - 7 + categories: + - cloud + - system +dependencies: [] diff --git a/roles/openshift_facts/tasks/main.yml b/roles/openshift_facts/tasks/main.yml new file mode 100644 index 000000000..5a7d10d25 --- /dev/null +++ b/roles/openshift_facts/tasks/main.yml @@ -0,0 +1,3 @@ +--- +- name: Gather OpenShift facts + openshift_facts: diff --git a/roles/openshift_master/README.md b/roles/openshift_master/README.md index 2d898bc3b..9f9d0a613 100644 --- a/roles/openshift_master/README.md +++ b/roles/openshift_master/README.md @@ -13,20 +13,24 @@ Role Variables -------------- From this role: -| Name | Default value | -| -|------------------------------------------|-----------------------|----------------------------------------| -| openshift_master_manage_service_externally | False | Should the openshift-master role manage the openshift-master service? | -| openshift_master_debug_level | openshift_debug_level | Verbosity of the debug logs for openshift-master | -| openshift_node_ips | [] | List of the openshift node ip addresses, that we want to pre-register to the system when openshift-master starts up | -| openshift_registry_url | UNDEF (Optional) | Default docker registry to use | +| Name | Default value | | +|-------------------------------------|-----------------------|--------------------------------------------------| +| openshift_master_debug_level | openshift_debug_level | Verbosity of the debug logs for openshift-master | +| openshift_node_ips | [] | List of the openshift node ip addresses to pre-register when openshift-master starts up | +| openshift_registry_url | UNDEF | Default docker registry to use | +| openshift_master_api_port | UNDEF | | +| openshift_master_console_port | UNDEF | | +| openshift_master_api_url | UNDEF | | +| openshift_master_console_url | UNDEF | | +| openshift_master_public_api_url | UNDEF | | +| openshift_master_public_console_url | UNDEF | | From openshift_common: -| Name | Default Value | | -|-------------------------------|---------------------|---------------------| -| openshift_debug_level | 0 | Global openshift debug log verbosity | -| openshift_public_ip | UNDEF (Required) | Public IP address to use for this host | -| openshift_hostname | UNDEF (Required) | hostname to use for this instance | +| Name | Default Value | | +|-------------------------------|----------------|----------------------------------------| +| openshift_debug_level | 0 | Global openshift debug log verbosity | +| openshift_public_ip | UNDEF | Public IP address to use for this host | +| openshift_hostname | UNDEF | hostname to use for this instance | Dependencies ------------ diff --git a/roles/openshift_master/defaults/main.yml b/roles/openshift_master/defaults/main.yml index 0159afbb5..87fb347a8 100644 --- a/roles/openshift_master/defaults/main.yml +++ b/roles/openshift_master/defaults/main.yml @@ -1,16 +1,17 @@ --- -openshift_master_manage_service_externally: false -openshift_master_debug_level: "{{ openshift_debug_level | default(0) }}" openshift_node_ips: [] + +# TODO: update setting these values based on the facts +# TODO: update for console port change os_firewall_allow: - service: etcd embedded port: 4001/tcp -- service: etcd peer - port: 7001/tcp - service: OpenShift api https port: 8443/tcp -- service: OpenShift web console https - port: 8444/tcp os_firewall_deny: - service: OpenShift api http port: 8080/tcp +- service: former OpenShift web console port + port: 8444/tcp +- service: former etcd peer port + port: 7001/tcp diff --git a/roles/openshift_master/handlers/main.yml b/roles/openshift_master/handlers/main.yml index 503d08d41..6fd4dfb51 100644 --- a/roles/openshift_master/handlers/main.yml +++ b/roles/openshift_master/handlers/main.yml @@ -1,4 +1,3 @@ --- - name: restart openshift-master service: name=openshift-master state=restarted - when: not openshift_master_manage_service_externally diff --git a/roles/openshift_master/tasks/main.yml b/roles/openshift_master/tasks/main.yml index 52f5f694c..aa615df39 100644 --- a/roles/openshift_master/tasks/main.yml +++ b/roles/openshift_master/tasks/main.yml @@ -1,19 +1,37 @@ --- -# TODO: allow for overriding default ports where possible -# TODO: if setting up multiple masters, will need to predistribute the certs -# to the additional masters before starting openshift-master +# TODO: actually have api_port, api_use_ssl, console_port, console_use_ssl, +# etcd_use_ssl actually change the master config. + +- name: Set master OpenShift facts + openshift_facts: + role: 'master' + local_facts: + debug_level: "{{ openshift_master_debug_level | default(openshift.common.debug_level) }}" + api_port: "{{ openshift_master_api_port | default(None) }}" + api_url: "{{ openshift_master_api_url | default(None) }}" + api_use_ssl: "{{ openshift_master_api_use_ssl | default(None) }}" + public_api_url: "{{ openshift_master_public_api_url | default(None) }}" + console_port: "{{ openshift_master_console_port | default(None) }}" + console_url: "{{ openshift_master_console_url | default(None) }}" + console_use_ssl: "{{ openshift_master_console_use_ssl | default(None) }}" + public_console_url: "{{ openshift_master_public_console_url | default(None) }}" + etcd_use_ssl: "{{ openshift_master_etcd_use_ssl | default(None) }}" - name: Install OpenShift Master package yum: pkg=openshift-master state=installed +# TODO: We should pre-generate the master config and point to the generated +# config rather than setting command line flags here - name: Configure OpenShift settings lineinfile: dest: /etc/sysconfig/openshift-master regexp: '^OPTIONS=' - line: "OPTIONS=\"--public-master={{ openshift_hostname }} {% if openshift_node_ips %} --nodes={{ openshift_node_ips | join(',') }} {% endif %} --loglevel={{ openshift_master_debug_level }}\"" + line: "OPTIONS=\"--master={{ openshift.common.hostname }} --public-master={{ openshift.common.public_hostname }} {% if openshift_node_ips %} --nodes={{ openshift_node_ips | join(',') }} {% endif %} --loglevel={{ openshift.master.debug_level }}\"" notify: - restart openshift-master +# TODO: should this be populated by a fact based on the deployment type +# (origin, online, enterprise)? - name: Set default registry url lineinfile: dest: /etc/sysconfig/openshift-master @@ -23,34 +41,18 @@ notify: - restart openshift-master -- name: Set master OpenShift facts - include: "{{ role_path | dirname }}/openshift_common/tasks/set_facts.yml" - facts: - - section: master - option: debug_level - value: "{{ openshift_master_debug_level }}" - - section: master - option: public_ip - value: "{{ openshift_public_ip }}" - - section: master - option: externally_managed - value: "{{ openshift_master_manage_service_externally }}" - - name: Start and enable openshift-master service: name=openshift-master enabled=yes state=started - when: not openshift_master_manage_service_externally - register: result - -- name: Disable openshift-master if openshift-master is managed externally - service: name=openshift-master enabled=false - when: openshift_master_manage_service_externally - name: Create .kube directory file: path: /root/.kube state: directory mode: 0700 + +# TODO: Update this file if the contents of the source file are not present in +# the dest file, will need to make sure to ignore things that could be added - name: Configure root user kubeconfig - command: cp /var/lib/openshift/openshift.local.certificates/admin/.kubeconfig /root/.kube/.kubeconfig + command: cp /var/lib/openshift/openshift.local.certificates/openshift-client/.kubeconfig /root/.kube/.kubeconfig args: creates: /root/.kube/.kubeconfig diff --git a/roles/openshift_master/vars/main.yml b/roles/openshift_master/vars/main.yml deleted file mode 100644 index 9a8c4bba2..000000000 --- a/roles/openshift_master/vars/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -openshift_host_type: master diff --git a/roles/openshift_node/README.md b/roles/openshift_node/README.md index c9b4eab34..83359f164 100644 --- a/roles/openshift_node/README.md +++ b/roles/openshift_node/README.md @@ -16,10 +16,7 @@ Role Variables From this role: | Name | Default value | | |------------------------------------------|-----------------------|----------------------------------------| -| openshift_node_manage_service_externally | False | Should the openshift-node role manage the openshift-node service? | | openshift_node_debug_level | openshift_debug_level | Verbosity of the debug logs for openshift-node | -| openshift_master_public_ips | UNDEF (Required) | List of the public IPs for the openhift-master hosts | -| openshift_master_ips | UNDEF (Required) | List of IP addresses for the openshift-master hosts to be used for node -> master communication | | openshift_registry_url | UNDEF (Optional) | Default docker registry to use | From openshift_common: diff --git a/roles/openshift_node/defaults/main.yml b/roles/openshift_node/defaults/main.yml index 6dc73a96e..df7ec41b6 100644 --- a/roles/openshift_node/defaults/main.yml +++ b/roles/openshift_node/defaults/main.yml @@ -1,6 +1,4 @@ --- -openshift_node_manage_service_externally: false -openshift_node_debug_level: "{{ openshift_debug_level | default(0) }}" os_firewall_allow: - service: OpenShift kubelet port: 10250/tcp diff --git a/roles/openshift_node/handlers/main.yml b/roles/openshift_node/handlers/main.yml index f7aa36d88..ca2992637 100644 --- a/roles/openshift_node/handlers/main.yml +++ b/roles/openshift_node/handlers/main.yml @@ -1,4 +1,4 @@ --- - name: restart openshift-node service: name=openshift-node state=restarted - when: not openshift_node_manage_service_externally + when: not openshift.common.use_openshift_sdn|bool diff --git a/roles/openshift_node/tasks/main.yml b/roles/openshift_node/tasks/main.yml index c039e3f05..8cfef0e15 100644 --- a/roles/openshift_node/tasks/main.yml +++ b/roles/openshift_node/tasks/main.yml @@ -1,4 +1,12 @@ --- +# TODO: allow for overriding default ports where possible +# TODO: trigger the external service when restart is needed +- name: Set node OpenShift facts + openshift_facts: + role: 'node' + local_facts: + debug_level: "{{ openshift_node_debug_level | default(openshift.common.debug_level) }}" + - name: Test if node certs and config exist stat: path={{ item }} failed_when: not result.stat.exists @@ -23,7 +31,7 @@ lineinfile: dest: /etc/sysconfig/openshift-node regexp: '^OPTIONS=' - line: "OPTIONS=\"--hostname={{ openshift_hostname }} --loglevel={{ openshift_node_debug_level }} --create-certs=false\"" + line: "OPTIONS=\"--hostname={{ openshift.common.hostname }} --loglevel={{ openshift.node.debug_level }} --create-certs=false\"" notify: - restart openshift-node @@ -36,23 +44,10 @@ notify: - restart openshift-node -- name: Set OpenShift node facts - include: "{{ role_path | dirname }}/openshift_common/tasks/set_facts.yml" - facts: - - section: node - option: debug_level - value: "{{ openshift_node_debug_level }}" - - section: node - option: public_ip - value: "{{ openshift_public_ip }}" - - section: node - option: externally_managed - value: "{{ openshift_node_manage_service_externally }}" - - name: Start and enable openshift-node service: name=openshift-node enabled=yes state=started - when: not openshift_node_manage_service_externally + when: not openshift.common.use_openshift_sdn|bool - name: Disable openshift-node if openshift-node is managed externally service: name=openshift-node enabled=false - when: openshift_node_manage_service_externally + when: openshift.common.use_openshift_sdn|bool diff --git a/roles/openshift_node/vars/main.yml b/roles/openshift_node/vars/main.yml deleted file mode 100644 index 9841d52f9..000000000 --- a/roles/openshift_node/vars/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -openshift_host_type: node diff --git a/roles/openshift_register_nodes/README.md b/roles/openshift_register_nodes/README.md index 225dd44b9..b96faa044 100644 --- a/roles/openshift_register_nodes/README.md +++ b/roles/openshift_register_nodes/README.md @@ -1,38 +1,34 @@ -Role Name -========= +OpenShift Register Nodes +======================== -A brief description of the role goes here. +TODO Requirements ------------ -Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. +TODO Role Variables -------------- -A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. +TODO Dependencies ------------ -A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. +TODO Example Playbook ---------------- -Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: - - - hosts: servers - roles: - - { role: username.rolename, x: 42 } +TODO License ------- -BSD +Apache License Version 2.0 Author Information ------------------ -An optional section for the role authors to include contact information, or a website (HTML is not allowed). +Jason DeTiberus (jdetiber@redhat.com) diff --git a/roles/openshift_register_nodes/library/kubernetes_register_node.py b/roles/openshift_register_nodes/library/kubernetes_register_node.py old mode 100644 new mode 100755 index 409215616..8ebeb087a --- a/roles/openshift_register_nodes/library/kubernetes_register_node.py +++ b/roles/openshift_register_nodes/library/kubernetes_register_node.py @@ -214,7 +214,8 @@ class Node: resources = NodeResources(version, cpu, memory), cidr = podCIDR, labels = labels, - annotations = annotations + annotations = annotations, + externalID = externalID ) elif version == 'v1beta3': metadata = dict(name = name, diff --git a/roles/openshift_register_nodes/meta/main.yml b/roles/openshift_register_nodes/meta/main.yml index 7b1f0ef0a..e40a152c1 100644 --- a/roles/openshift_register_nodes/meta/main.yml +++ b/roles/openshift_register_nodes/meta/main.yml @@ -1,128 +1,17 @@ --- galaxy_info: - author: your name - description: - company: your company (optional) - # Some suggested licenses: - # - BSD (default) - # - MIT - # - GPLv2 - # - GPLv3 - # - Apache - # - CC-BY - license: license (GPLv2, CC-BY, etc) - min_ansible_version: 1.2 - # - # Below are all platforms currently available. Just uncomment - # the ones that apply to your role. If you don't see your - # platform on this list, let us know and we'll get it added! - # - #platforms: - #- name: EL - # versions: - # - all - # - 5 - # - 6 - # - 7 - #- name: GenericUNIX - # versions: - # - all - # - any - #- name: Fedora - # versions: - # - all - # - 16 - # - 17 - # - 18 - # - 19 - # - 20 - #- name: SmartOS - # versions: - # - all - # - any - #- name: opensuse - # versions: - # - all - # - 12.1 - # - 12.2 - # - 12.3 - # - 13.1 - # - 13.2 - #- name: Amazon - # versions: - # - all - # - 2013.03 - # - 2013.09 - #- name: GenericBSD - # versions: - # - all - # - any - #- name: FreeBSD - # versions: - # - all - # - 8.0 - # - 8.1 - # - 8.2 - # - 8.3 - # - 8.4 - # - 9.0 - # - 9.1 - # - 9.1 - # - 9.2 - #- name: Ubuntu - # versions: - # - all - # - lucid - # - maverick - # - natty - # - oneiric - # - precise - # - quantal - # - raring - # - saucy - # - trusty - #- name: SLES - # versions: - # - all - # - 10SP3 - # - 10SP4 - # - 11 - # - 11SP1 - # - 11SP2 - # - 11SP3 - #- name: GenericLinux - # versions: - # - all - # - any - #- name: Debian - # versions: - # - all - # - etch - # - lenny - # - squeeze - # - wheezy - # - # Below are all categories currently available. Just as with - # the platforms above, uncomment those that apply to your role. - # - #categories: - #- cloud - #- cloud:ec2 - #- cloud:gce - #- cloud:rax - #- clustering - #- database - #- database:nosql - #- database:sql - #- development - #- monitoring - #- networking - #- packaging - #- system - #- web -dependencies: [] - # List your role dependencies here, one per line. Only - # dependencies available via galaxy should be listed here. - # Be sure to remove the '[]' above if you add dependencies - # to this list. - + author: Jason DeTiberus + description: + company: Red Hat, Inc. + license: Apache License, Version 2.0 + min_ansible_version: 1.8 + platforms: + - name: EL + versions: + - 7 + categories: + - cloud + - system +dependencies: +- { role: openshift_facts } + diff --git a/roles/openshift_register_nodes/tasks/main.yml b/roles/openshift_register_nodes/tasks/main.yml index 59216fc87..7319b88b1 100644 --- a/roles/openshift_register_nodes/tasks/main.yml +++ b/roles/openshift_register_nodes/tasks/main.yml @@ -1,18 +1,20 @@ --- -# TODO: support configuration for multiple masters, currently hardcoding -# the info from the first master +# TODO: support new create-config command to generate node certs and config +# TODO: recreate master/node configs if settings that affect the configs +# change (hostname, public_hostname, ip, public_ip, etc) # TODO: create a failed_when condition - name: Create node server certificates command: > /usr/bin/openshift admin create-server-cert --overwrite=false - --cert={{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/server.crt - --key={{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/server.key - --hostnames={{ [openshift_hostname, openshift_public_hostname, openshift_ip, openshift_public_ip]|join(",") }} + --cert={{ openshift_cert_dir }}/node-{{ item.openshift.common.hostname }}/server.crt + --key={{ openshift_cert_dir }}/node-{{ item.openshift.common.hostname }}/server.key + --hostnames={{ [item.openshift.common.hostname, + item.openshift.common.public_hostname]|unique|join(",") }} args: chdir: "{{ openshift_cert_dir_parent }}" - creates: "{{ openshift_cert_dir_abs }}/node-{{ item.openshift_node_hostname }}/server.crt" + creates: "{{ openshift_cert_dir_abs }}/node-{{ item.openshift.common.hostname }}/server.crt" with_items: openshift_nodes register: server_cert_result @@ -21,48 +23,42 @@ command: > /usr/bin/openshift admin create-node-cert --overwrite=false - --cert={{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/cert.crt - --key={{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/key.key - --node-name={{ item.openshift_node_hostname }} + --cert={{ openshift_cert_dir }}/node-{{ item.openshift.common.hostname }}/cert.crt + --key={{ openshift_cert_dir }}/node-{{ item.openshift.common.hostname }}/key.key + --node-name={{ item.openshift.common.hostname }} args: chdir: "{{ openshift_cert_dir_parent }}" - creates: "{{ openshift_cert_dir_abs }}/node-{{ item.openshift_node_hostname }}/cert.crt" + creates: "{{ openshift_cert_dir_abs }}/node-{{ item.openshift.common.hostname }}/cert.crt" with_items: openshift_nodes register: node_cert_result -# TODO: re-create kubeconfig if certs were regenerated, not just if -# .kubeconfig doesn't exist # TODO: create a failed_when condition - name: Create kubeconfigs for nodes command: > /usr/bin/openshift admin create-kubeconfig - --client-certificate={{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/cert.crt - --client-key={{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/key.key - --kubeconfig={{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/.kubeconfig - --master={{ openshift_master_urls[0] }} - --public-master={{ openshift_master_public_urls[0] }} + --client-certificate={{ openshift_cert_dir }}/node-{{ item.openshift.common.hostname }}/cert.crt + --client-key={{ openshift_cert_dir }}/node-{{ item.openshift.common.hostname }}/key.key + --kubeconfig={{ openshift_cert_dir }}/node-{{ item.openshift.common.hostname }}/.kubeconfig + --master={{ openshift.master.api_url }} + --public-master={{ openshift.master.public_api_url }} args: chdir: "{{ openshift_cert_dir_parent }}" - creates: "{{ openshift_cert_dir_abs }}/node-{{ item.openshift_node_hostname }}/.kubeconfig" + creates: "{{ openshift_cert_dir_abs }}/node-{{ item.openshift.common.hostname }}/.kubeconfig" with_items: openshift_nodes register: kubeconfig_result -# TODO: generate the node configs (openshift start node --write-config -# --config='{{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/node.yaml' -# --kubeconfig='{{ openshift_cert_dir }}/node-{{ item.openshift_node_hostname }}/.kubeconfig' -# will need to modify the generated node config as needed -# (servingInfo.{certFile,clientCA,keyFile}) - - name: Register unregistered nodes kubernetes_register_node: - name: "{{ item.openshift_node_name }}" + client_user: openshift-client + name: "{{ item.openshift.common.hostname }}" api_version: "{{ openshift_kube_api_version }}" - cpu: "{{ item.openshift_node_cpu if item.openshift_node_cpu else None }}" - memory: "{{ item.openshift_node_memory if item.openshift_node_memory else None }}" - pod_cidr: "{{ item.openshift_node_pod_cidr if item.openshift_node_pod_cidr else None }}" - host_ip: "{{ item.openshift_node_host_ip }}" - labels: "{{ item.openshift_node_labels if item.openshift_node_labels else {} }}" - annotations: "{{ item.openshift_node_annotations if item.openshift_node_annotations else {} }}" + cpu: "{{ item.openshift.node.resources_cpu | default(None) }}" + memory: "{{ item.openshift.node.resources_memory | default(None) }}" + pod_cidr: "{{ item.openshift.node.pod_cidr | default(None) }}" + host_ip: "{{ item.openshift.common.ip }}" + labels: "{{ item.openshift.node.labels | default({}) }}" + annotations: "{{ item.openshift.node.annotations | default({}) }}" + external_id: "{{ item.openshift.node.external_id }}" # TODO: support customizing other attributes such as: client_config, # client_cluster, client_context, client_user # TODO: update for v1beta3 changes after rebase: hostnames, external_ips, diff --git a/roles/openshift_repos/defaults/main.yaml b/roles/openshift_repos/defaults/main.yaml index 6fe2bf621..1730207f4 100644 --- a/roles/openshift_repos/defaults/main.yaml +++ b/roles/openshift_repos/defaults/main.yaml @@ -1,5 +1,7 @@ --- # TODO: once we are able to configure/deploy origin using the openshift roles, # then we should default to origin + +# TODO: push the defaulting of these values to the openshift_facts module openshift_deployment_type: online openshift_additional_repos: {} diff --git a/roles/openshift_repos/meta/main.yml b/roles/openshift_repos/meta/main.yml index cc18c453c..0558b822c 100644 --- a/roles/openshift_repos/meta/main.yml +++ b/roles/openshift_repos/meta/main.yml @@ -11,4 +11,5 @@ galaxy_info: - 7 categories: - cloud -dependencies: [] +dependencies: +- { role: openshift_facts } diff --git a/roles/openshift_repos/tasks/main.yaml b/roles/openshift_repos/tasks/main.yaml index 6219c4906..bb1551d37 100644 --- a/roles/openshift_repos/tasks/main.yaml +++ b/roles/openshift_repos/tasks/main.yaml @@ -1,6 +1,12 @@ --- # TODO: Add flag for enabling EPEL repo, default to false +# TODO: Add subscription-management config, with parameters +# for username, password, poolid(name), and official repos to +# enable/disable. Might need to make a module that extends the +# subscription management module to take a poolid and enable/disable the +# proper repos correctly. + - assert: that: openshift_deployment_type in known_openshift_deployment_types diff --git a/roles/openshift_sdn_master/defaults/main.yml b/roles/openshift_sdn_master/defaults/main.yml deleted file mode 100644 index da7655546..000000000 --- a/roles/openshift_sdn_master/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -openshift_sdn_master_debug_level: "{{ openshift_debug_level | default(0) }}" diff --git a/roles/openshift_sdn_master/meta/main.yml b/roles/openshift_sdn_master/meta/main.yml index e6e5514d1..5de32cc13 100644 --- a/roles/openshift_sdn_master/meta/main.yml +++ b/roles/openshift_sdn_master/meta/main.yml @@ -11,4 +11,5 @@ galaxy_info: - 7 categories: - cloud -dependencies: [] +dependencies: +- { role: openshift_common } diff --git a/roles/openshift_sdn_master/tasks/main.yml b/roles/openshift_sdn_master/tasks/main.yml index e1761afdc..f2d61043b 100644 --- a/roles/openshift_sdn_master/tasks/main.yml +++ b/roles/openshift_sdn_master/tasks/main.yml @@ -1,4 +1,13 @@ --- +# TODO: add task to set the sdn subnet if openshift-sdn-master hasn't been +# started yet + +- name: Set master sdn OpenShift facts + openshift_facts: + role: 'master_sdn' + local_facts: + debug_level: "{{ openshift_master_sdn_debug_level | default(openshift.common.debug_level) }}" + - name: Install openshift-sdn-master yum: pkg: openshift-sdn-master @@ -8,17 +17,10 @@ lineinfile: dest: /etc/sysconfig/openshift-sdn-master regexp: '^OPTIONS=' - line: "OPTIONS=\"-v={{ openshift_sdn_master_debug_level }}\"" + line: "OPTIONS=\"-v={{ openshift.master_sdn.debug_level }}\"" notify: - restart openshift-sdn-master -- name: Set openshift-sdn-master facts - include: "{{ role_path | dirname }}/openshift_common/tasks/set_facts.yml" - facts: - - section: sdn-master - option: debug_level - value: "{{ openshift_sdn_master_debug_level }}" - - name: Enable openshift-sdn-master service: name: openshift-sdn-master diff --git a/roles/openshift_sdn_node/README.md b/roles/openshift_sdn_node/README.md index 2da2d74eb..e6b6a9503 100644 --- a/roles/openshift_sdn_node/README.md +++ b/roles/openshift_sdn_node/README.md @@ -17,12 +17,6 @@ From this role: | openshift_sdn_node_debug_level | openshift_debug_level | Verbosity of the debug logs for openshift-master | -From openshift_node: -| Name | Default value | | -|-----------------------|------------------|--------------------------------------| -| openshift_master_ips | UNDEF (Required) | List of IP addresses for the openshift-master hosts to be used for node -> master communication | - - From openshift_common: | Name | Default value | | |-------------------------------|---------------------|----------------------------------------| diff --git a/roles/openshift_sdn_node/defaults/main.yml b/roles/openshift_sdn_node/defaults/main.yml deleted file mode 100644 index 9612d9d91..000000000 --- a/roles/openshift_sdn_node/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -openshift_sdn_node_debug_level: "{{ openshift_debug_level | default(0) }}" diff --git a/roles/openshift_sdn_node/meta/main.yml b/roles/openshift_sdn_node/meta/main.yml index ab45ff51e..ffe10f836 100644 --- a/roles/openshift_sdn_node/meta/main.yml +++ b/roles/openshift_sdn_node/meta/main.yml @@ -11,4 +11,5 @@ galaxy_info: - 7 categories: - cloud -dependencies: [] +dependencies: +- { role: openshift_common } diff --git a/roles/openshift_sdn_node/tasks/main.yml b/roles/openshift_sdn_node/tasks/main.yml index ff05a6972..729c28879 100644 --- a/roles/openshift_sdn_node/tasks/main.yml +++ b/roles/openshift_sdn_node/tasks/main.yml @@ -1,4 +1,10 @@ --- +- name: Set node sdn OpenShift facts + openshift_facts: + role: 'node_sdn' + local_facts: + debug_level: "{{ openshift_node_sdn_debug_level | default(openshift.common.debug_level) }}" + - name: Install openshift-sdn-node yum: pkg: openshift-sdn-node @@ -14,28 +20,19 @@ backrefs: yes with_items: - regex: '^(OPTIONS=)' - line: '\1"-v={{ openshift_sdn_node_debug_level }} -hostname={{ openshift_hostname }}"' + line: '\1"-v={{ openshift.node_sdn.debug_level }} -hostname={{ openshift.common.hostname }}"' - regex: '^(MASTER_URL=)' - line: '\1"http://{{ openshift_master_ips | first }}:4001"' + line: '\1"{{ openshift_sdn_master_url }}"' - regex: '^(MINION_IP=)' - line: '\1"{{ openshift_public_ip }}"' + line: '\1"{{ openshift.common.ip }}"' # TODO lock down the insecure-registry config to a more sane value than # 0.0.0.0/0 - regex: '^(DOCKER_OPTIONS=)' line: '\1"--insecure-registry=0.0.0.0/0 -b=lbr0 --mtu=1450 --selinux-enabled"' notify: restart openshift-sdn-node -- name: Set openshift-sdn-node facts - include: "{{ role_path | dirname }}/openshift_common/tasks/set_facts.yml" - facts: - - section: sdn-node - option: debug_level - value: "{{ openshift_sdn_node_debug_level }}" - -# fixme: Once the openshift_cluster playbook is published state should be started -# Always bounce service to pick up new credentials - name: Start and enable openshift-sdn-node service: name: openshift-sdn-node enabled: yes - state: restarted + state: started diff --git a/roles/os_env_extras_node/tasks/main.yml b/roles/os_env_extras_node/tasks/main.yml new file mode 100644 index 000000000..208065df2 --- /dev/null +++ b/roles/os_env_extras_node/tasks/main.yml @@ -0,0 +1,5 @@ +--- +# From the origin rpm there exists instructions on how to +# setup origin properly. The following steps come from there +- name: Change root to be in the Docker group + user: name=root groups=dockerroot append=yes diff --git a/roles/os_firewall/library/os_firewall_manage_iptables.py b/roles/os_firewall/library/os_firewall_manage_iptables.py old mode 100644 new mode 100755 index 6a018d022..90588d2ae --- a/roles/os_firewall/library/os_firewall_manage_iptables.py +++ b/roles/os_firewall/library/os_firewall_manage_iptables.py @@ -1,5 +1,6 @@ #!/usr/bin/python # -*- coding: utf-8 -*- +# vim: expandtab:tabstop=4:shiftwidth=4 from subprocess import call, check_output diff --git a/roles/os_firewall/meta/main.yml b/roles/os_firewall/meta/main.yml index 7a8cef6c5..8592371e8 100644 --- a/roles/os_firewall/meta/main.yml +++ b/roles/os_firewall/meta/main.yml @@ -1,3 +1,4 @@ +--- galaxy_info: author: Jason DeTiberus description: os_firewall diff --git a/roles/os_firewall/tasks/firewall/firewalld.yml b/roles/os_firewall/tasks/firewall/firewalld.yml index 469cfab6f..b6bddd5c5 100644 --- a/roles/os_firewall/tasks/firewall/firewalld.yml +++ b/roles/os_firewall/tasks/firewall/firewalld.yml @@ -3,6 +3,7 @@ yum: name: firewalld state: present + register: install_result - name: Check if iptables-services is installed command: rpm -q iptables-services @@ -20,6 +21,10 @@ - ip6tables when: pkg_check.rc == 0 +- name: Reload systemd units + command: systemctl daemon-reload + when: install_result | changed + - name: Start and enable firewalld service service: name: firewalld diff --git a/roles/os_firewall/tasks/firewall/iptables.yml b/roles/os_firewall/tasks/firewall/iptables.yml index 87e77c083..7b5c00a9b 100644 --- a/roles/os_firewall/tasks/firewall/iptables.yml +++ b/roles/os_firewall/tasks/firewall/iptables.yml @@ -6,6 +6,7 @@ with_items: - iptables - iptables-services + register: install_result - name: Check if firewalld is installed command: rpm -q firewalld @@ -20,14 +21,15 @@ enabled: no when: pkg_check.rc == 0 -- name: Start and enable iptables services +- name: Reload systemd units + command: systemctl daemon-reload + when: install_result | changed + +- name: Start and enable iptables service service: - name: "{{ item }}" + name: iptables state: started enabled: yes - with_items: - - iptables - - ip6tables register: result - name: need to pause here, otherwise the iptables service starting can sometimes cause ssh to fail -- cgit v1.2.3 From 8a4888ad30ce7c5898caac47614da2e13a759320 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Sun, 1 Mar 2015 00:27:04 -0500 Subject: Add byo playbooks and enterprise docs - added byo playbooks - added byo (example) inventory - added a README_OSE.md for getting started with Enterprise deployments - Added an ansible.cfg as an example for configuration helpful for playbooks/roles --- README_OSE.md | 142 ++++++++++++++++++++++++++ ansible.cfg | 23 +++++ inventory/byo/group_vars/all | 28 +++++ inventory/byo/hosts | 10 ++ playbooks/byo/config.yml | 6 ++ playbooks/byo/filter_plugins | 1 + playbooks/byo/openshift-master/config.yml | 9 ++ playbooks/byo/openshift-master/filter_plugins | 1 + playbooks/byo/openshift-master/roles | 1 + playbooks/byo/openshift-node/config.yml | 79 ++++++++++++++ playbooks/byo/openshift-node/filter_plugins | 1 + playbooks/byo/openshift-node/roles | 1 + playbooks/byo/roles | 1 + roles/openshift_node/tasks/main.yml | 1 + 14 files changed, 304 insertions(+) create mode 100644 README_OSE.md create mode 100644 ansible.cfg create mode 100644 inventory/byo/group_vars/all create mode 100644 inventory/byo/hosts create mode 100644 playbooks/byo/config.yml create mode 120000 playbooks/byo/filter_plugins create mode 100644 playbooks/byo/openshift-master/config.yml create mode 120000 playbooks/byo/openshift-master/filter_plugins create mode 120000 playbooks/byo/openshift-master/roles create mode 100644 playbooks/byo/openshift-node/config.yml create mode 120000 playbooks/byo/openshift-node/filter_plugins create mode 120000 playbooks/byo/openshift-node/roles create mode 120000 playbooks/byo/roles diff --git a/README_OSE.md b/README_OSE.md new file mode 100644 index 000000000..6ebdb7f99 --- /dev/null +++ b/README_OSE.md @@ -0,0 +1,142 @@ +# Installing OSEv3 from dev puddles using ansible + +* [Requirements](#requirements) +* [Caveats](#caveats) +* [Known Issues](#known-issues) +* [Configuring the host inventory](#configuring-the-host-inventory) +* [Creating the default variables for the hosts and host groups](#creating-the-default-variables-for-the-hosts-and-host-groups) +* [Running the ansible playbooks](#running-the-ansible-playbooks) +* [Post-ansible steps](#post-ansible-steps) + +## Requirements +* ansible + * Tested using ansible-1.8.2-1.fc20.noarch, but should work with version 1.8+ + * Available in Fedora channels + * Available for EL with EPEL and Optional channel +* One or more RHEL 7.1 VMs +* ssh key based auth for the root user needs to be pre-configured from the host + running ansible to the remote hosts +* A checkout of openshift-ansible from https://github.com/openshift/openshift-ansible/ + + ```sh + git clone https://github.com/openshift/openshift-ansible.git + cd openshift-ansible + ``` + +## Caveats +This ansible repo is currently under heavy revision for providing OSE support; +the following items are highly likely to change before the OSE support is +merged into the upstream repo: + * the current git branch for testing + * how the inventory file should be configured + * variables that need to be set + * bootstrapping steps + * other configuration steps + +## Known Issues +* Host subscriptions are not configurable yet, the hosts need to be + pre-registered with subscription-manager or have the RHEL base repo + pre-configured. If using subscription-manager the following commands will + disable all but the rhel-7-server rhel-7-server-extras and + rhel-server7-ose-beta repos: +```sh +subscription-manager repos --disable="*" +subscription-manager repos \ +--enable="rhel-7-server-rpms" \ +--enable="rhel-7-server-extras-rpms" \ +--enable="rhel-server-7-ose-beta-rpms" +``` +* Configuration of router is not automated yet +* Configuration of docker-registry is not automated yet +* End-to-end testing has not been completed yet using this module +* root user is used for all ansible actions; eventually we will support using + a non-root user with sudo. + +## Configuring the host inventory +[Ansible docs](http://docs.ansible.com/intro_inventory.html) + +Example inventory file for configuring one master and two nodes for the test +environment. This can be configured in the default inventory file +(/etc/ansible/hosts), or using a custom file and passing the --inventory +option to ansible-playbook. + +/etc/ansible/hosts: +```ini +# This is an example of a bring your own (byo) host inventory + +# host group for masters +[masters] +ose3-master.example.com + +# host group for nodes +[nodes] +ose3-node[1:2].example.com +``` + +The hostnames above should resolve both from the hosts themselves and +the host where ansible is running (if different). + +## Creating the default variables for the hosts and host groups +[Ansible docs](http://docs.ansible.com/intro_inventory.html#id9) + +#### Group vars for all hosts +/etc/ansible/group_vars/all: +```yaml +--- +# Assume that we want to use the root as the ssh user for all hosts +ansible_ssh_user: root + +# Default debug level for all OpenShift hosts +openshift_debug_level: 4 + +# Set the OpenShift deployment type for all hosts +openshift_deployment_type: enterprise + +# Override the default registry for development +openshift_registry_url: docker-buildvm-rhose.usersys.redhat.com:5000/openshift3_beta/ose-${component}:${version} + +# To use the latest OpenShift Enterprise Errata puddle: +#openshift_additional_repos: +#- id: ose-devel +# name: ose-devel +# baseurl: http://buildvm-devops.usersys.redhat.com/puddle/build/OpenShiftEnterpriseErrata/3.0/latest/RH7-RHOSE-3.0/$basearch/os +# enabled: 1 +# gpgcheck: 0 +# To use the latest OpenShift Enterprise Whitelist puddle: +openshift_additional_repos: +- id: ose-devel + name: ose-devel + baseurl: http://buildvm-devops.usersys.redhat.com/puddle/build/OpenShiftEnterprise/3.0/latest/RH7-RHOSE-3.0/$basearch/os + enabled: 1 + gpgcheck: 0 + +``` + +## Running the ansible playbooks +From the openshift-ansible checkout run: +```sh +ansible-playbook playbooks/byo/config.yml +``` +**Note:** this assumes that the host inventory is /etc/ansible/hosts and the +group_vars are defined in /etc/ansible/group_vars, if using a different +inventory file (and a group_vars directory that is in the same directory as +the directory as the inventory) use the -i option for ansible-playbook. + +## Post-ansible steps +#### Create the default router +On the master host: +```sh +systemctl restart openshift-sdn-master +openshift ex router --create=true \ + --credentials=/var/lib/openshift/openshift.local.certificates/openshift-client/.kubeconfig \ + --images='docker-buildvm-rhose.usersys.redhat.com:5000/openshift3_beta/ose-${component}:${version}' +``` + +#### Create the default docker-registry +On the master host: +```sh +openshift ex registry --create=true \ + --credentials=/var/lib/openshift/openshift.local.certificates/openshift-client/.kubeconfig \ + --images='docker-buildvm-rhose.usersys.redhat.com:5000/openshift3_beta/ose-${component}:${version}' \ + --mount-host=/var/lib/openshift/docker-registry +``` diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 000000000..6a7722ad8 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,23 @@ +# config file for ansible -- http://ansible.com/ +# ============================================== + +# This config file provides examples for running +# the OpenShift playbooks with the provided +# inventory scripts. Only global defaults are +# left uncommented + +[defaults] +# Add the roles directory to the roles path +roles_path = roles/ + +# Set the log_path +log_path = /tmp/ansible.log + +# Uncomment to use the provided BYO inventory +#hostfile = inventory/byo/hosts + +# Uncomment to use the provided GCE dynamic inventory script +#hostfile = inventory/gce/gce.py + +# Uncomment to use the provided AWS dynamic inventory script +#hostfile = inventory/aws/ec2.py diff --git a/inventory/byo/group_vars/all b/inventory/byo/group_vars/all new file mode 100644 index 000000000..d63e96668 --- /dev/null +++ b/inventory/byo/group_vars/all @@ -0,0 +1,28 @@ +--- +# lets assume that we want to use the root as the ssh user for all hosts +ansible_ssh_user: root + +# default debug level for all OpenShift hosts +openshift_debug_level: 4 + +# set the OpenShift deployment type for all hosts +openshift_deployment_type: enterprise + +# Override the default registry for development +openshift_registry_url: docker-buildvm-rhose.usersys.redhat.com:5000/openshift3_beta/ose-${component}:${version} + +# Use latest Errata puddle as an additional repo: +#openshift_additional_repos: +#- id: ose-devel +# name: ose-devel +# baseurl: http://buildvm-devops.usersys.redhat.com/puddle/build/OpenShiftEnterpriseErrata/3.0/latest/RH7-RHOSE-3.0/$basearch/os +# enabled: 1 +# gpgcheck: 0 + +# Use latest Whitelist puddle as an additional repo: +openshift_additional_repos: +- id: ose-devel + name: ose-devel + baseurl: http://buildvm-devops.usersys.redhat.com/puddle/build/OpenShiftEnterprise/3.0/latest/RH7-RHOSE-3.0/$basearch/os + enabled: 1 + gpgcheck: 0 diff --git a/inventory/byo/hosts b/inventory/byo/hosts new file mode 100644 index 000000000..2dd854778 --- /dev/null +++ b/inventory/byo/hosts @@ -0,0 +1,10 @@ +# This is an example of a bring your own (byo) host inventory + +# host group for masters +[masters] +ose3-master-ansible.test.example.com + +# host group for nodes +[nodes] +ose3-node[1:2]-ansible.test.example.com + diff --git a/playbooks/byo/config.yml b/playbooks/byo/config.yml new file mode 100644 index 000000000..dce49d32f --- /dev/null +++ b/playbooks/byo/config.yml @@ -0,0 +1,6 @@ +--- +- name: Run the openshift-master config playbook + include: openshift-master/config.yml + +- name: Run the openshift-node config playbook + include: openshift-node/config.yml diff --git a/playbooks/byo/filter_plugins b/playbooks/byo/filter_plugins new file mode 120000 index 000000000..a4f518f07 --- /dev/null +++ b/playbooks/byo/filter_plugins @@ -0,0 +1 @@ +../../filter_plugins \ No newline at end of file diff --git a/playbooks/byo/openshift-master/config.yml b/playbooks/byo/openshift-master/config.yml new file mode 100644 index 000000000..706f9285c --- /dev/null +++ b/playbooks/byo/openshift-master/config.yml @@ -0,0 +1,9 @@ +--- +- name: Gather facts for node hosts + hosts: nodes + +- name: Configure master instances + hosts: masters + roles: + - openshift_master + - openshift_sdn_master diff --git a/playbooks/byo/openshift-master/filter_plugins b/playbooks/byo/openshift-master/filter_plugins new file mode 120000 index 000000000..99a95e4ca --- /dev/null +++ b/playbooks/byo/openshift-master/filter_plugins @@ -0,0 +1 @@ +../../../filter_plugins \ No newline at end of file diff --git a/playbooks/byo/openshift-master/roles b/playbooks/byo/openshift-master/roles new file mode 120000 index 000000000..20c4c58cf --- /dev/null +++ b/playbooks/byo/openshift-master/roles @@ -0,0 +1 @@ +../../../roles \ No newline at end of file diff --git a/playbooks/byo/openshift-node/config.yml b/playbooks/byo/openshift-node/config.yml new file mode 100644 index 000000000..69ad7a840 --- /dev/null +++ b/playbooks/byo/openshift-node/config.yml @@ -0,0 +1,79 @@ +--- +- name: Gather facts for node hosts + hosts: nodes + roles: + - openshift_facts + tasks: + # Since the master is registering the nodes before they are configured, we + # need to make sure to set the node properties beforehand if we do not want + # the defaults + - openshift_facts: + role: 'node' + local_facts: + hostname: "{{ openshift_hostname | default(None) }}" + external_id: "{{ openshift_node_external_id | default(None) }}" + resources_cpu: "{{ openshfit_node_resources_cpu | default(None) }}" + resources_memory: "{{ openshfit_node_resources_memory | default(None) }}" + pod_cidr: "{{ openshfit_node_pod_cidr | default(None) }}" + labels: "{{ openshfit_node_labels | default(None) }}" + annotations: "{{ openshfit_node_annotations | default(None) }}" + + +- name: Register nodes + hosts: masters[0] + vars: + openshift_nodes: "{{ hostvars | oo_select_keys(groups['nodes']) }}" + roles: + - openshift_register_nodes + tasks: + - name: Create local temp directory for syncing certs + local_action: command /usr/bin/mktemp -d /tmp/openshift-ansible-XXXXXXX + register: mktemp + + - name: Sync master certs to localhost + synchronize: + mode: pull + checksum: yes + src: /var/lib/openshift/openshift.local.certificates + dest: "{{ mktemp.stdout }}" + + +- name: Configure node instances + hosts: nodes + vars: + sync_tmpdir: "{{ hostvars[groups['masters'][0]].mktemp.stdout }}" + cert_parent_rel_path: openshift.local.certificates + cert_rel_path: "{{ cert_parent_rel_path }}/node-{{ openshift.common.hostname }}" + cert_base_path: /var/lib/openshift + cert_parent_path: "{{ cert_base_path }}/{{ cert_parent_rel_path }}" + cert_path: "{{ cert_base_path }}/{{ cert_rel_path }}" + openshift_sdn_master_url: http://{{ hostvars[groups['masters'][0]].openshift.common.hostname }}:4001 + pre_tasks: + - name: Ensure certificate directories exists + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ cert_path }}" + - "{{ cert_parent_path }}/ca" + + # TODO: notify restart openshift-node and/or restart openshift-sdn-node, + # possibly test service started time against certificate/config file + # timestamps in openshift-node or openshift-sdn-node to trigger notify + - name: Sync certs to nodes + synchronize: + checksum: yes + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: no + group: no + with_items: + - src: "{{ sync_tmpdir }}/{{ cert_rel_path }}" + dest: "{{ cert_parent_path }}" + - src: "{{ sync_tmpdir }}/{{ cert_parent_rel_path }}/ca/cert.crt" + dest: "{{ cert_parent_path }}/ca/cert.crt" + - local_action: file name={{ sync_tmpdir }} state=absent + run_once: true + roles: + - openshift_node + - openshift_sdn_node diff --git a/playbooks/byo/openshift-node/filter_plugins b/playbooks/byo/openshift-node/filter_plugins new file mode 120000 index 000000000..99a95e4ca --- /dev/null +++ b/playbooks/byo/openshift-node/filter_plugins @@ -0,0 +1 @@ +../../../filter_plugins \ No newline at end of file diff --git a/playbooks/byo/openshift-node/roles b/playbooks/byo/openshift-node/roles new file mode 120000 index 000000000..20c4c58cf --- /dev/null +++ b/playbooks/byo/openshift-node/roles @@ -0,0 +1 @@ +../../../roles \ No newline at end of file diff --git a/playbooks/byo/roles b/playbooks/byo/roles new file mode 120000 index 000000000..b741aa3db --- /dev/null +++ b/playbooks/byo/roles @@ -0,0 +1 @@ +../../roles \ No newline at end of file diff --git a/roles/openshift_node/tasks/main.yml b/roles/openshift_node/tasks/main.yml index 8cfef0e15..e3c04585b 100644 --- a/roles/openshift_node/tasks/main.yml +++ b/roles/openshift_node/tasks/main.yml @@ -1,6 +1,7 @@ --- # TODO: allow for overriding default ports where possible # TODO: trigger the external service when restart is needed + - name: Set node OpenShift facts openshift_facts: role: 'node' -- cgit v1.2.3 From 185261ab927c6997c1bc3eefe2ab4cd804b8a7f0 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Tue, 7 Apr 2015 16:51:40 -0400 Subject: fixed the opssh default output behavior to be consistent with pssh. Also fixed a bug in how directories are named for --outdir and --errdir. --- bin/opssh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/bin/opssh b/bin/opssh index d8137fb20..ad1aadc29 100755 --- a/bin/opssh +++ b/bin/opssh @@ -57,13 +57,16 @@ class Opssh(object): """ # Default set of options - pssh_args = [PSSH, '-i', '-t', '0', '-p', str(self.args.par), '--user', self.args.user] + pssh_args = [PSSH, '-t', '0', '-p', str(self.args.par), '--user', self.args.user] + + if self.args.inline: + pssh_args.append("--inline") if self.args.outdir: - pssh_args.append("--outdir='%s'" % self.args.outdir) + pssh_args.extend(["--outdir", self.args.outdir]) if self.args.errdir: - pssh_args.append("--errdir='%s'" % self.args.errdir) + pssh_args.extend(["--errdir", self.args.errdir]) hosts = self.aws.get_host_list(self.args.host_type, self.args.env) with tempfile.NamedTemporaryFile(prefix='opssh-', delete=True) as f: @@ -71,8 +74,8 @@ class Opssh(object): f.write(h + os.linesep) f.flush() - pssh_args.extend(["-h", "%s" % f.name]) - pssh_args.append("%s" % self.args.command) + pssh_args.extend(["-h", f.name]) + pssh_args.append(self.args.command) print print "Running: %s" % ' '.join(pssh_args) @@ -117,6 +120,9 @@ class Opssh(object): parser.add_argument('--user', action='store', default='root', help='username') + parser.add_argument('-i', '--inline', default=False, action='store_true', + help='inline aggregated output and error for each server') + parser.add_argument('-p', '--par', action='store', default=DEFAULT_PSSH_PAR, help=('max number of parallel threads (default %s)' % DEFAULT_PSSH_PAR)) -- cgit v1.2.3 From 4fe5e4645c099c69254b0e99081732a8b6af577a Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Wed, 8 Apr 2015 11:50:11 -0400 Subject: Automatic commit of package [openshift-ansible-bin] release [0.0.5-1]. --- bin/openshift-ansible-bin.spec | 6 +++++- rel-eng/packages/openshift-ansible-bin | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec index f87002456..f509bdd79 100644 --- a/bin/openshift-ansible-bin.spec +++ b/bin/openshift-ansible-bin.spec @@ -1,6 +1,6 @@ Summary: OpenShift Ansible Scripts for working with metadata hosts Name: openshift-ansible-bin -Version: 0.0.4 +Version: 0.0.5 Release: 1%{?dist} License: ASL 2.0 URL: https://github.com/openshift/openshift-ansible @@ -36,6 +36,10 @@ cp -p openshift_ansible.conf.example %{buildroot}/etc/openshift_ansible/openshif %config(noreplace) /etc/openshift_ansible/ %changelog +* Wed Apr 08 2015 Thomas Wiest 0.0.5-1 +- fixed the opssh default output behavior to be consistent with pssh. Also + fixed a bug in how directories are named for --outdir and --errdir. + (twiest@redhat.com) * Tue Mar 31 2015 Thomas Wiest 0.0.4-1 - Fixed when tag was missing and added opssh completion (kwoodson@redhat.com) diff --git a/rel-eng/packages/openshift-ansible-bin b/rel-eng/packages/openshift-ansible-bin index a0e3e205c..99ae75e8b 100644 --- a/rel-eng/packages/openshift-ansible-bin +++ b/rel-eng/packages/openshift-ansible-bin @@ -1 +1 @@ -0.0.4-1 bin/ +0.0.5-1 bin/ -- cgit v1.2.3 From b167f7b3c4082a3d990aabeb10faac888e7172b3 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Tue, 7 Apr 2015 22:34:00 -0400 Subject: move zbxapi module to a new os_zabbix role - cleans up repo root a bit --- library/zbxapi.py | 273 ---------------------------- playbooks/adhoc/noc/get_zabbix_problems.yml | 4 +- playbooks/adhoc/noc/library | 1 - playbooks/adhoc/noc/roles | 1 + roles/os_zabbix/library/zbxapi.py | 273 ++++++++++++++++++++++++++++ 5 files changed, 277 insertions(+), 275 deletions(-) delete mode 100755 library/zbxapi.py delete mode 120000 playbooks/adhoc/noc/library create mode 120000 playbooks/adhoc/noc/roles create mode 100755 roles/os_zabbix/library/zbxapi.py diff --git a/library/zbxapi.py b/library/zbxapi.py deleted file mode 100755 index f4f52909b..000000000 --- a/library/zbxapi.py +++ /dev/null @@ -1,273 +0,0 @@ -#!/usr/bin/env python - -# Copyright 2015 Red Hat Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Purpose: An ansible module to communicate with zabbix. -# - -import json -import httplib2 -import sys -import os -import re - -class ZabbixAPI(object): - ''' - ZabbixAPI class - ''' - classes = { - 'Action': ['create', 'delete', 'get', 'update'], - 'Alert': ['get'], - 'Application': ['create', 'delete', 'get', 'massadd', 'update'], - 'Configuration': ['export', 'import'], - 'Dcheck': ['get'], - 'Dhost': ['get'], - 'Drule': ['copy', 'create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], - 'Dservice': ['get'], - 'Event': ['acknowledge', 'get'], - 'Graph': ['create', 'delete', 'get', 'update'], - 'Graphitem': ['get'], - 'Graphprototype': ['create', 'delete', 'get', 'update'], - 'History': ['get'], - 'Hostgroup': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massremove', 'massupdate', 'update'], - 'Hostinterface': ['create', 'delete', 'get', 'massadd', 'massremove', 'replacehostinterfaces', 'update'], - 'Host': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massremove', 'massupdate', 'update'], - 'Hostprototype': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], - 'Httptest': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], - 'Iconmap': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], - 'Image': ['create', 'delete', 'get', 'update'], - 'Item': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], - 'Itemprototype': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], - 'Maintenance': ['create', 'delete', 'get', 'update'], - 'Map': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], - 'Mediatype': ['create', 'delete', 'get', 'update'], - 'Proxy': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], - 'Screen': ['create', 'delete', 'get', 'update'], - 'Screenitem': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update', 'updatebyposition'], - 'Script': ['create', 'delete', 'execute', 'get', 'getscriptsbyhosts', 'update'], - 'Service': ['adddependencies', 'addtimes', 'create', 'delete', 'deletedependencies', 'deletetimes', 'get', 'getsla', 'isreadable', 'iswritable', 'update'], - 'Template': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massremove', 'massupdate', 'update'], - 'Templatescreen': ['copy', 'create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], - 'Templatescreenitem': ['get'], - 'Trigger': ['adddependencies', 'create', 'delete', 'deletedependencies', 'get', 'isreadable', 'iswritable', 'update'], - 'Triggerprototype': ['create', 'delete', 'get', 'update'], - 'User': ['addmedia', 'create', 'delete', 'deletemedia', 'get', 'isreadable', 'iswritable', 'login', 'logout', 'update', 'updatemedia', 'updateprofile'], - 'Usergroup': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massupdate', 'update'], - 'Usermacro': ['create', 'createglobal', 'delete', 'deleteglobal', 'get', 'update', 'updateglobal'], - 'Usermedia': ['get'], - } - - def __init__(self, data={}): - self.server = data['server'] or None - self.username = data['user'] or None - self.password = data['password'] or None - if any(map(lambda value: value == None, [self.server, self.username, self.password])): - print 'Please specify zabbix server url, username, and password.' - sys.exit(1) - - self.verbose = data.has_key('verbose') - self.use_ssl = data.has_key('use_ssl') - self.auth = None - - for class_name, method_names in self.classes.items(): - #obj = getattr(self, class_name)(self) - #obj.__dict__ - setattr(self, class_name.lower(), getattr(self, class_name)(self)) - - results = self.user.login(user=self.username, password=self.password) - - if results[0]['status'] == '200': - if results[1].has_key('result'): - self.auth = results[1]['result'] - elif results[1].has_key('error'): - print "Unable to authenticate with zabbix server. {0} ".format(results[1]['error']) - sys.exit(1) - else: - print "Error in call to zabbix. Http status: {0}.".format(results[0]['status']) - sys.exit(1) - - def perform(self, method, params): - ''' - This method calls your zabbix server. - - It requires the following parameters in order for a proper request to be processed: - - jsonrpc - the version of the JSON-RPC protocol used by the API; the Zabbix API implements JSON-RPC version 2.0; - method - the API method being called; - params - parameters that will be passed to the API method; - id - an arbitrary identifier of the request; - auth - a user authentication token; since we don't have one yet, it's set to null. - ''' - http_method = "POST" - if params.has_key("http_method"): - http_method = params['http_method'] - - jsonrpc = "2.0" - if params.has_key('jsonrpc'): - jsonrpc = params['jsonrpc'] - - rid = 1 - if params.has_key('id'): - rid = params['id'] - - http = None - if self.use_ssl: - http = httplib2.Http() - else: - http = httplib2.Http( disable_ssl_certificate_validation=True,) - - headers = params.get('headers', {}) - headers["Content-type"] = "application/json" - - body = { - "jsonrpc": jsonrpc, - "method": method, - "params": params, - "id": rid, - 'auth': self.auth, - } - - if method in ['user.login','api.version']: - del body['auth'] - - body = json.dumps(body) - - if self.verbose: - print body - print method - print headers - httplib2.debuglevel = 1 - - response, results = http.request(self.server, http_method, body, headers) - - if self.verbose: - print response - print results - - try: - results = json.loads(results) - except ValueError as e: - results = {"error": e.message} - - return response, results - - ''' - This bit of metaprogramming is where the ZabbixAPI subclasses are created. - For each of ZabbixAPI.classes we create a class from the key and methods - from the ZabbixAPI.classes values. We pass a reference to ZabbixAPI class - to each subclass in order for each to be able to call the perform method. - ''' - @staticmethod - def meta(class_name, method_names): - # This meta method allows a class to add methods to it. - def meta_method(Class, method_name): - # This template method is a stub method for each of the subclass - # methods. - def template_method(self, **params): - return self.parent.perform(class_name.lower()+"."+method_name, params) - template_method.__doc__ = "https://www.zabbix.com/documentation/2.4/manual/api/reference/%s/%s" % (class_name.lower(), method_name) - template_method.__name__ = method_name - # this is where the template method is placed inside of the subclass - # e.g. setattr(User, "create", stub_method) - setattr(Class, template_method.__name__, template_method) - - # This class call instantiates a subclass. e.g. User - Class=type(class_name, (object,), { '__doc__': "https://www.zabbix.com/documentation/2.4/manual/api/reference/%s" % class_name.lower() }) - # This init method gets placed inside of the Class - # to allow it to be instantiated. A reference to the parent class(ZabbixAPI) - # is passed in to allow each class access to the perform method. - def __init__(self, parent): - self.parent = parent - # This attaches the init to the subclass. e.g. Create - setattr(Class, __init__.__name__, __init__) - # For each of our ZabbixAPI.classes dict values - # Create a method and attach it to our subclass. - # e.g. 'User': ['delete', 'get', 'updatemedia', 'updateprofile', - # 'update', 'iswritable', 'logout', 'addmedia', 'create', - # 'login', 'deletemedia', 'isreadable'], - # User.delete - # User.get - for method_name in method_names: - meta_method(Class, method_name) - # Return our subclass with all methods attached - return Class - -# Attach all ZabbixAPI.classes to ZabbixAPI class through metaprogramming -for class_name, method_names in ZabbixAPI.classes.items(): - setattr(ZabbixAPI, class_name, ZabbixAPI.meta(class_name, method_names)) - -def main(): - - module = AnsibleModule( - argument_spec = dict( - server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), - user=dict(default=None, type='str'), - password=dict(default=None, type='str'), - zbx_class=dict(choices=ZabbixAPI.classes.keys()), - action=dict(default=None, type='str'), - params=dict(), - debug=dict(default=False, type='bool'), - ), - #supports_check_mode=True - ) - - user = module.params.get('user', None) - if not user: - user = os.environ['ZABBIX_USER'] - - pw = module.params.get('password', None) - if not pw: - pw = os.environ['ZABBIX_PASSWORD'] - - server = module.params['server'] - - if module.params['debug']: - options['debug'] = True - - api_data = { - 'user': user, - 'password': pw, - 'server': server, - } - - if not user or not pw or not server: - module.fail_json('Please specify the user, password, and the zabbix server.') - - zapi = ZabbixAPI(api_data) - - zbx_class = module.params.get('zbx_class') - action = module.params.get('action') - params = module.params.get('params', {}) - - - # Get the instance we are trying to call - zbx_class_inst = zapi.__getattribute__(zbx_class.lower()) - # Get the instance's method we are trying to call - zbx_action_method = zapi.__getattribute__(zbx_class.capitalize()).__dict__[action] - # Make the call with the incoming params - results = zbx_action_method(zbx_class_inst, **params) - - # Results Section - changed_state = False - status = results[0]['status'] - if status not in ['200', '201']: - #changed_state = False - module.fail_json(msg="Http response: [%s] - Error: %s" % (str(results[0]), results[1])) - - module.exit_json(**{'results': results[1]['result']}) - -from ansible.module_utils.basic import * - -main() diff --git a/playbooks/adhoc/noc/get_zabbix_problems.yml b/playbooks/adhoc/noc/get_zabbix_problems.yml index 6ac5cdcf7..02bffc1d2 100644 --- a/playbooks/adhoc/noc/get_zabbix_problems.yml +++ b/playbooks/adhoc/noc/get_zabbix_problems.yml @@ -2,7 +2,9 @@ - name: 'Get current hosts who have triggers that are alerting by trigger description' hosts: localhost gather_facts: no - tasks: + roles: + - os_zabbix + post_tasks: - assert: that: oo_desc is defined diff --git a/playbooks/adhoc/noc/library b/playbooks/adhoc/noc/library deleted file mode 120000 index ba40d2f56..000000000 --- a/playbooks/adhoc/noc/library +++ /dev/null @@ -1 +0,0 @@ -../../../library \ No newline at end of file diff --git a/playbooks/adhoc/noc/roles b/playbooks/adhoc/noc/roles new file mode 120000 index 000000000..20c4c58cf --- /dev/null +++ b/playbooks/adhoc/noc/roles @@ -0,0 +1 @@ +../../../roles \ No newline at end of file diff --git a/roles/os_zabbix/library/zbxapi.py b/roles/os_zabbix/library/zbxapi.py new file mode 100755 index 000000000..f4f52909b --- /dev/null +++ b/roles/os_zabbix/library/zbxapi.py @@ -0,0 +1,273 @@ +#!/usr/bin/env python + +# Copyright 2015 Red Hat Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Purpose: An ansible module to communicate with zabbix. +# + +import json +import httplib2 +import sys +import os +import re + +class ZabbixAPI(object): + ''' + ZabbixAPI class + ''' + classes = { + 'Action': ['create', 'delete', 'get', 'update'], + 'Alert': ['get'], + 'Application': ['create', 'delete', 'get', 'massadd', 'update'], + 'Configuration': ['export', 'import'], + 'Dcheck': ['get'], + 'Dhost': ['get'], + 'Drule': ['copy', 'create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Dservice': ['get'], + 'Event': ['acknowledge', 'get'], + 'Graph': ['create', 'delete', 'get', 'update'], + 'Graphitem': ['get'], + 'Graphprototype': ['create', 'delete', 'get', 'update'], + 'History': ['get'], + 'Hostgroup': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massremove', 'massupdate', 'update'], + 'Hostinterface': ['create', 'delete', 'get', 'massadd', 'massremove', 'replacehostinterfaces', 'update'], + 'Host': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massremove', 'massupdate', 'update'], + 'Hostprototype': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Httptest': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Iconmap': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Image': ['create', 'delete', 'get', 'update'], + 'Item': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Itemprototype': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Maintenance': ['create', 'delete', 'get', 'update'], + 'Map': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Mediatype': ['create', 'delete', 'get', 'update'], + 'Proxy': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Screen': ['create', 'delete', 'get', 'update'], + 'Screenitem': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'update', 'updatebyposition'], + 'Script': ['create', 'delete', 'execute', 'get', 'getscriptsbyhosts', 'update'], + 'Service': ['adddependencies', 'addtimes', 'create', 'delete', 'deletedependencies', 'deletetimes', 'get', 'getsla', 'isreadable', 'iswritable', 'update'], + 'Template': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massremove', 'massupdate', 'update'], + 'Templatescreen': ['copy', 'create', 'delete', 'get', 'isreadable', 'iswritable', 'update'], + 'Templatescreenitem': ['get'], + 'Trigger': ['adddependencies', 'create', 'delete', 'deletedependencies', 'get', 'isreadable', 'iswritable', 'update'], + 'Triggerprototype': ['create', 'delete', 'get', 'update'], + 'User': ['addmedia', 'create', 'delete', 'deletemedia', 'get', 'isreadable', 'iswritable', 'login', 'logout', 'update', 'updatemedia', 'updateprofile'], + 'Usergroup': ['create', 'delete', 'get', 'isreadable', 'iswritable', 'massadd', 'massupdate', 'update'], + 'Usermacro': ['create', 'createglobal', 'delete', 'deleteglobal', 'get', 'update', 'updateglobal'], + 'Usermedia': ['get'], + } + + def __init__(self, data={}): + self.server = data['server'] or None + self.username = data['user'] or None + self.password = data['password'] or None + if any(map(lambda value: value == None, [self.server, self.username, self.password])): + print 'Please specify zabbix server url, username, and password.' + sys.exit(1) + + self.verbose = data.has_key('verbose') + self.use_ssl = data.has_key('use_ssl') + self.auth = None + + for class_name, method_names in self.classes.items(): + #obj = getattr(self, class_name)(self) + #obj.__dict__ + setattr(self, class_name.lower(), getattr(self, class_name)(self)) + + results = self.user.login(user=self.username, password=self.password) + + if results[0]['status'] == '200': + if results[1].has_key('result'): + self.auth = results[1]['result'] + elif results[1].has_key('error'): + print "Unable to authenticate with zabbix server. {0} ".format(results[1]['error']) + sys.exit(1) + else: + print "Error in call to zabbix. Http status: {0}.".format(results[0]['status']) + sys.exit(1) + + def perform(self, method, params): + ''' + This method calls your zabbix server. + + It requires the following parameters in order for a proper request to be processed: + + jsonrpc - the version of the JSON-RPC protocol used by the API; the Zabbix API implements JSON-RPC version 2.0; + method - the API method being called; + params - parameters that will be passed to the API method; + id - an arbitrary identifier of the request; + auth - a user authentication token; since we don't have one yet, it's set to null. + ''' + http_method = "POST" + if params.has_key("http_method"): + http_method = params['http_method'] + + jsonrpc = "2.0" + if params.has_key('jsonrpc'): + jsonrpc = params['jsonrpc'] + + rid = 1 + if params.has_key('id'): + rid = params['id'] + + http = None + if self.use_ssl: + http = httplib2.Http() + else: + http = httplib2.Http( disable_ssl_certificate_validation=True,) + + headers = params.get('headers', {}) + headers["Content-type"] = "application/json" + + body = { + "jsonrpc": jsonrpc, + "method": method, + "params": params, + "id": rid, + 'auth': self.auth, + } + + if method in ['user.login','api.version']: + del body['auth'] + + body = json.dumps(body) + + if self.verbose: + print body + print method + print headers + httplib2.debuglevel = 1 + + response, results = http.request(self.server, http_method, body, headers) + + if self.verbose: + print response + print results + + try: + results = json.loads(results) + except ValueError as e: + results = {"error": e.message} + + return response, results + + ''' + This bit of metaprogramming is where the ZabbixAPI subclasses are created. + For each of ZabbixAPI.classes we create a class from the key and methods + from the ZabbixAPI.classes values. We pass a reference to ZabbixAPI class + to each subclass in order for each to be able to call the perform method. + ''' + @staticmethod + def meta(class_name, method_names): + # This meta method allows a class to add methods to it. + def meta_method(Class, method_name): + # This template method is a stub method for each of the subclass + # methods. + def template_method(self, **params): + return self.parent.perform(class_name.lower()+"."+method_name, params) + template_method.__doc__ = "https://www.zabbix.com/documentation/2.4/manual/api/reference/%s/%s" % (class_name.lower(), method_name) + template_method.__name__ = method_name + # this is where the template method is placed inside of the subclass + # e.g. setattr(User, "create", stub_method) + setattr(Class, template_method.__name__, template_method) + + # This class call instantiates a subclass. e.g. User + Class=type(class_name, (object,), { '__doc__': "https://www.zabbix.com/documentation/2.4/manual/api/reference/%s" % class_name.lower() }) + # This init method gets placed inside of the Class + # to allow it to be instantiated. A reference to the parent class(ZabbixAPI) + # is passed in to allow each class access to the perform method. + def __init__(self, parent): + self.parent = parent + # This attaches the init to the subclass. e.g. Create + setattr(Class, __init__.__name__, __init__) + # For each of our ZabbixAPI.classes dict values + # Create a method and attach it to our subclass. + # e.g. 'User': ['delete', 'get', 'updatemedia', 'updateprofile', + # 'update', 'iswritable', 'logout', 'addmedia', 'create', + # 'login', 'deletemedia', 'isreadable'], + # User.delete + # User.get + for method_name in method_names: + meta_method(Class, method_name) + # Return our subclass with all methods attached + return Class + +# Attach all ZabbixAPI.classes to ZabbixAPI class through metaprogramming +for class_name, method_names in ZabbixAPI.classes.items(): + setattr(ZabbixAPI, class_name, ZabbixAPI.meta(class_name, method_names)) + +def main(): + + module = AnsibleModule( + argument_spec = dict( + server=dict(default='https://localhost/zabbix/api_jsonrpc.php', type='str'), + user=dict(default=None, type='str'), + password=dict(default=None, type='str'), + zbx_class=dict(choices=ZabbixAPI.classes.keys()), + action=dict(default=None, type='str'), + params=dict(), + debug=dict(default=False, type='bool'), + ), + #supports_check_mode=True + ) + + user = module.params.get('user', None) + if not user: + user = os.environ['ZABBIX_USER'] + + pw = module.params.get('password', None) + if not pw: + pw = os.environ['ZABBIX_PASSWORD'] + + server = module.params['server'] + + if module.params['debug']: + options['debug'] = True + + api_data = { + 'user': user, + 'password': pw, + 'server': server, + } + + if not user or not pw or not server: + module.fail_json('Please specify the user, password, and the zabbix server.') + + zapi = ZabbixAPI(api_data) + + zbx_class = module.params.get('zbx_class') + action = module.params.get('action') + params = module.params.get('params', {}) + + + # Get the instance we are trying to call + zbx_class_inst = zapi.__getattribute__(zbx_class.lower()) + # Get the instance's method we are trying to call + zbx_action_method = zapi.__getattribute__(zbx_class.capitalize()).__dict__[action] + # Make the call with the incoming params + results = zbx_action_method(zbx_class_inst, **params) + + # Results Section + changed_state = False + status = results[0]['status'] + if status not in ['200', '201']: + #changed_state = False + module.fail_json(msg="Http response: [%s] - Error: %s" % (str(results[0]), results[1])) + + module.exit_json(**{'results': results[1]['result']}) + +from ansible.module_utils.basic import * + +main() -- cgit v1.2.3 From 3c521113b4b7a79d69c788600df67c460c887963 Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Wed, 8 Apr 2015 16:53:28 -0400 Subject: Adding yum_repo role for facilitating repository deployment --- roles/yum_repo/README.md | 34 ++++++++++++++++++++++++++++++++++ roles/yum_repo/defaults/main.yml | 5 +++++ roles/yum_repo/handlers/main.yml | 2 ++ roles/yum_repo/meta/main.yml | 8 ++++++++ roles/yum_repo/tasks/main.yml | 8 ++++++++ roles/yum_repo/templates/yumrepo.j2 | 5 +++++ roles/yum_repo/vars/main.yml | 2 ++ 7 files changed, 64 insertions(+) create mode 100644 roles/yum_repo/README.md create mode 100644 roles/yum_repo/defaults/main.yml create mode 100644 roles/yum_repo/handlers/main.yml create mode 100644 roles/yum_repo/meta/main.yml create mode 100644 roles/yum_repo/tasks/main.yml create mode 100644 roles/yum_repo/templates/yumrepo.j2 create mode 100644 roles/yum_repo/vars/main.yml diff --git a/roles/yum_repo/README.md b/roles/yum_repo/README.md new file mode 100644 index 000000000..7f6a615cb --- /dev/null +++ b/roles/yum_repo/README.md @@ -0,0 +1,34 @@ +Role Name +========= + +This role allows easy deployment of yum repository config files. + +Requirements +------------ + +Yum + +Role Variables +-------------- + +Dependencies +------------ + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +ASL 2.0 + +Author Information +------------------ + +openshift online operations diff --git a/roles/yum_repo/defaults/main.yml b/roles/yum_repo/defaults/main.yml new file mode 100644 index 000000000..95e78af69 --- /dev/null +++ b/roles/yum_repo/defaults/main.yml @@ -0,0 +1,5 @@ +--- +# defaults file for yum-repo +repo_enabled: "1" +repo_gpg_check: "1" + diff --git a/roles/yum_repo/handlers/main.yml b/roles/yum_repo/handlers/main.yml new file mode 100644 index 000000000..a48c89ac2 --- /dev/null +++ b/roles/yum_repo/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for yum-repo diff --git a/roles/yum_repo/meta/main.yml b/roles/yum_repo/meta/main.yml new file mode 100644 index 000000000..e0b53ce7f --- /dev/null +++ b/roles/yum_repo/meta/main.yml @@ -0,0 +1,8 @@ +--- +galaxy_info: + author: openshift operations + description: + company: RedHat + license: ASL 2.0 + min_ansible_version: 1.2 +dependencies: [] diff --git a/roles/yum_repo/tasks/main.yml b/roles/yum_repo/tasks/main.yml new file mode 100644 index 000000000..a56d1f133 --- /dev/null +++ b/roles/yum_repo/tasks/main.yml @@ -0,0 +1,8 @@ +--- +# tasks file for yum-repo + +- name: Installing yum-repo template + template: + src: yumrepo.j2 + dest: /etc/yum.repos.d/{{ repo_tag }}.repo + diff --git a/roles/yum_repo/templates/yumrepo.j2 b/roles/yum_repo/templates/yumrepo.j2 new file mode 100644 index 000000000..b06a6f41a --- /dev/null +++ b/roles/yum_repo/templates/yumrepo.j2 @@ -0,0 +1,5 @@ +[{{ repo_tag }}] +name={{ repo_name }} +baseurl={{ repo_baseurl }} +enabled={{ repo_enabled }} +gpg_check={{ repo_gpg_check }} diff --git a/roles/yum_repo/vars/main.yml b/roles/yum_repo/vars/main.yml new file mode 100644 index 000000000..48182ac8e --- /dev/null +++ b/roles/yum_repo/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for yum-repo -- cgit v1.2.3 From 9f59e1bad63fa3841c9f2a50d4b46dbd35601788 Mon Sep 17 00:00:00 2001 From: Matt Woodson Date: Thu, 9 Apr 2015 09:56:41 -0400 Subject: added more options to the yum repo --- roles/yum_repo/templates/yumrepo.j2 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/roles/yum_repo/templates/yumrepo.j2 b/roles/yum_repo/templates/yumrepo.j2 index b06a6f41a..af879be31 100644 --- a/roles/yum_repo/templates/yumrepo.j2 +++ b/roles/yum_repo/templates/yumrepo.j2 @@ -3,3 +3,7 @@ name={{ repo_name }} baseurl={{ repo_baseurl }} enabled={{ repo_enabled }} gpg_check={{ repo_gpg_check }} +sslverify={{ repo_sslverify }} +sslclientcert={{ repo_client_cert }} +sslclientkey={{ repo_client_key }} +gpgkey={{ repo_gpgkey }} -- cgit v1.2.3 From 6d0b77b9f3dbd439aa7e2d1d877e121214f284a8 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Thu, 9 Apr 2015 15:04:17 -0400 Subject: fixed bug where opssh would throw an exception if pssh returned a non-zero exit code --- bin/opssh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/bin/opssh b/bin/opssh index ad1aadc29..453da65b4 100755 --- a/bin/opssh +++ b/bin/opssh @@ -19,6 +19,7 @@ CONFIG_MAIN_SECTION = 'main' CONFIG_HOST_TYPE_ALIAS_SECTION = 'host_type_aliases' CONFIG_INVENTORY_OPTION = 'inventory' +class ArgumentMismatchError(ValueError): pass class Opssh(object): def __init__(self): @@ -36,21 +37,18 @@ class Opssh(object): self.aws = awsutil.AwsUtil(self.inventory, self.host_type_aliases) + def run(self): if self.args.list_host_types: self.aws.print_host_types() - return + return 0 if self.args.env and \ self.args.host_type and \ self.args.command: - retval = self.run_pssh() - if retval != 0: - raise ValueError("pssh run failed") - - return + return self.run_pssh() # If it makes it here, we weren't able to determine what they wanted to do - raise ValueError("Invalid combination of arguments") + raise ArgumentMismatchError("Invalid combination of arguments") def run_pssh(self): """Actually run the pssh command based off of the supplied options @@ -142,5 +140,7 @@ if __name__ == '__main__': try: opssh = Opssh() - except ValueError as e: + exitcode = opssh.run() + sys.exit(exitcode) + except ArgumentMismatchError as e: print "\nError: %s\n" % e.message -- cgit v1.2.3 From f28ff57f98140a1a22423df34d6457ee669fe714 Mon Sep 17 00:00:00 2001 From: Jason DeTiberus Date: Thu, 9 Apr 2015 12:58:43 -0400 Subject: refactor yum_repo role to handle multiple repos/files - Rename yum_repo role to yum_repos - Update yum_repos to take a more complex datastructure to describe multiple repo files and multiple repos within those files - Update the template to support multiple repos within the repo file - Update the template to allow for any key, value pair passed in instead of a hard coded list. - Add assertions to verify the repo_files variable is properly defined - Convert the legacy variables to the new repo_files variable --- roles/yum_repo/README.md | 34 ----------- roles/yum_repo/defaults/main.yml | 5 -- roles/yum_repo/handlers/main.yml | 2 - roles/yum_repo/meta/main.yml | 8 --- roles/yum_repo/tasks/main.yml | 8 --- roles/yum_repo/templates/yumrepo.j2 | 9 --- roles/yum_repo/vars/main.yml | 2 - roles/yum_repos/README.md | 113 +++++++++++++++++++++++++++++++++++ roles/yum_repos/defaults/main.yml | 3 + roles/yum_repos/meta/main.yml | 8 +++ roles/yum_repos/tasks/main.yml | 47 +++++++++++++++ roles/yum_repos/templates/yumrepo.j2 | 18 ++++++ 12 files changed, 189 insertions(+), 68 deletions(-) delete mode 100644 roles/yum_repo/README.md delete mode 100644 roles/yum_repo/defaults/main.yml delete mode 100644 roles/yum_repo/handlers/main.yml delete mode 100644 roles/yum_repo/meta/main.yml delete mode 100644 roles/yum_repo/tasks/main.yml delete mode 100644 roles/yum_repo/templates/yumrepo.j2 delete mode 100644 roles/yum_repo/vars/main.yml create mode 100644 roles/yum_repos/README.md create mode 100644 roles/yum_repos/defaults/main.yml create mode 100644 roles/yum_repos/meta/main.yml create mode 100644 roles/yum_repos/tasks/main.yml create mode 100644 roles/yum_repos/templates/yumrepo.j2 diff --git a/roles/yum_repo/README.md b/roles/yum_repo/README.md deleted file mode 100644 index 7f6a615cb..000000000 --- a/roles/yum_repo/README.md +++ /dev/null @@ -1,34 +0,0 @@ -Role Name -========= - -This role allows easy deployment of yum repository config files. - -Requirements ------------- - -Yum - -Role Variables --------------- - -Dependencies ------------- - -Example Playbook ----------------- - -Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: - - - hosts: servers - roles: - - { role: username.rolename, x: 42 } - -License -------- - -ASL 2.0 - -Author Information ------------------- - -openshift online operations diff --git a/roles/yum_repo/defaults/main.yml b/roles/yum_repo/defaults/main.yml deleted file mode 100644 index 95e78af69..000000000 --- a/roles/yum_repo/defaults/main.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -# defaults file for yum-repo -repo_enabled: "1" -repo_gpg_check: "1" - diff --git a/roles/yum_repo/handlers/main.yml b/roles/yum_repo/handlers/main.yml deleted file mode 100644 index a48c89ac2..000000000 --- a/roles/yum_repo/handlers/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# handlers file for yum-repo diff --git a/roles/yum_repo/meta/main.yml b/roles/yum_repo/meta/main.yml deleted file mode 100644 index e0b53ce7f..000000000 --- a/roles/yum_repo/meta/main.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -galaxy_info: - author: openshift operations - description: - company: RedHat - license: ASL 2.0 - min_ansible_version: 1.2 -dependencies: [] diff --git a/roles/yum_repo/tasks/main.yml b/roles/yum_repo/tasks/main.yml deleted file mode 100644 index a56d1f133..000000000 --- a/roles/yum_repo/tasks/main.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -# tasks file for yum-repo - -- name: Installing yum-repo template - template: - src: yumrepo.j2 - dest: /etc/yum.repos.d/{{ repo_tag }}.repo - diff --git a/roles/yum_repo/templates/yumrepo.j2 b/roles/yum_repo/templates/yumrepo.j2 deleted file mode 100644 index af879be31..000000000 --- a/roles/yum_repo/templates/yumrepo.j2 +++ /dev/null @@ -1,9 +0,0 @@ -[{{ repo_tag }}] -name={{ repo_name }} -baseurl={{ repo_baseurl }} -enabled={{ repo_enabled }} -gpg_check={{ repo_gpg_check }} -sslverify={{ repo_sslverify }} -sslclientcert={{ repo_client_cert }} -sslclientkey={{ repo_client_key }} -gpgkey={{ repo_gpgkey }} diff --git a/roles/yum_repo/vars/main.yml b/roles/yum_repo/vars/main.yml deleted file mode 100644 index 48182ac8e..000000000 --- a/roles/yum_repo/vars/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# vars file for yum-repo diff --git a/roles/yum_repos/README.md b/roles/yum_repos/README.md new file mode 100644 index 000000000..51ecd5d34 --- /dev/null +++ b/roles/yum_repos/README.md @@ -0,0 +1,113 @@ +Yum Repos +========= + +This role allows easy deployment of yum repository config files. + +Requirements +------------ + +Yum + +Role Variables +-------------- + +| Name | Default value | | +|-------------------|---------------|--------------------------------------------| +| repo_files | None | | +| repo_enabled | 1 | Should repos be enabled by default | +| repo_gpgcheck | 1 | Should repo gpgcheck be enabled by default | + +Dependencies +------------ + +Example Playbook +---------------- + +A single repo file containing a single repo: + - hosts: servers + roles: + - role: yum_repos + repo_files: + - id: my_repo + repos: + - id: my_repo + name: My Awesome Repo + baseurl: https://my.awesome.repo/is/available/here + skip_if_unavailable: yes + gpgkey: https://my.awesome.repo/pubkey.gpg + +A single repo file containing a single repo, disabling gpgcheck + - hosts: servers + roles: + - role: yum_repos + repo_files: + - id: my_other_repo + repos: + - id: my_other_repo + name: My Other Awesome Repo + baseurl: https://my.other.awesome.repo/is/available/here + gpgcheck: no + +A single repo file containing a single disabled repo + - hosts: servers + roles: + - role: yum_repos + repo_files: + - id: my_other_repo + repos: + - id: my_other_repo + name: My Other Awesome Repo + baseurl: https://my.other.awesome.repo/is/available/here + enabled: no + +A single repo file containing multiple repos + - hosts: servers + roles: + - role: yum_repos + repo_files: + id: my_repos + repos: + - id: my_repo + name: My Awesome Repo + baseurl: https://my.awesome.repo/is/available/here + gpgkey: https://my.awesome.repo/pubkey.gpg + - id: my_other_repo + name: My Other Awesome Repo + baseurl: https://my.other.awesome.repo/is/available/here + gpgkey: https://my.other.awesome.repo/pubkey.gpg + +Multiple repo files containing multiple repos + - hosts: servers + roles: + - role: yum_repos + repo_files: + - id: my_repos + repos: + - id: my_repo + name: My Awesome Repo + baseurl: https://my.awesome.repo/is/available/here + gpgkey: https://my.awesome.repo/pubkey.gpg + - id: my_other_repo + name: My Other Awesome Repo + baseurl: https://my.other.awesome.repo/is/available/here + gpgkey: https://my.other.awesome.repo/pubkey.gpg + - id: joes_repos + repos: + - id: joes_repo + name: Joe's Less Awesome Repo + baseurl: https://joes.repo/is/here + gpgkey: https://joes.repo/pubkey.gpg + - id: joes_otherrepo + name: Joe's Other Less Awesome Repo + baseurl: https://joes.repo/is/there + gpgkey: https://joes.repo/pubkey.gpg + +License +------- + +ASL 2.0 + +Author Information +------------------ + +openshift online operations diff --git a/roles/yum_repos/defaults/main.yml b/roles/yum_repos/defaults/main.yml new file mode 100644 index 000000000..515fb7a4a --- /dev/null +++ b/roles/yum_repos/defaults/main.yml @@ -0,0 +1,3 @@ +--- +repo_enabled: 1 +repo_gpgcheck: 1 diff --git a/roles/yum_repos/meta/main.yml b/roles/yum_repos/meta/main.yml new file mode 100644 index 000000000..6b8374da9 --- /dev/null +++ b/roles/yum_repos/meta/main.yml @@ -0,0 +1,8 @@ +--- +galaxy_info: + author: openshift operations + description: + company: Red Hat, Inc. + license: ASL 2.0 + min_ansible_version: 1.2 +dependencies: [] diff --git a/roles/yum_repos/tasks/main.yml b/roles/yum_repos/tasks/main.yml new file mode 100644 index 000000000..a9903c6c6 --- /dev/null +++ b/roles/yum_repos/tasks/main.yml @@ -0,0 +1,47 @@ +--- +# Convert old params to new params +- set_fact: + repo_files: + - id: "{{ repo_tag }}" + repos: + - id: "{{ repo_tag }}" + name: "{{ repo_name }}" + baseurl: "{{ repo_baseurl }}" + enabled: "{{ repo_enabled }}" + gpgcheck: "{{ repo_gpg_check | default(repo_gpgcheck) }}" + sslverify: "{{ repo_sslverify | default(None) }}" + sslclientcert: "{{ repo_sslclientcert | default(None) }}" + sslclientkey: "{{ repo_sslclientkey | default(None) }}" + gpgkey: "{{ repo_gpgkey | default(None) }}" + when: repo_files is not defined + +- name: Verify repo_files is a list + assert: + that: + - repo_files is iterable and repo_files is not string and repo_files is not mapping + +- name: Verify repo_files items have an id and a repos list + assert: + that: + - item is mapping + - "'id' in item" + - "'repos' in item" + - item.repos is iterable and item.repos is not string and item.repos is not mapping + with_items: repo_files + +- name: Verify that repo_files.repos have the required keys + assert: + that: + - item.1 is mapping + - "'id' in item.1" + - "'name' in item.1" + - "'baseurl' in item.1" + with_subelements: + - repo_files + - repos + +- name: Installing yum-repo template + template: + src: yumrepo.j2 + dest: /etc/yum.repos.d/{{ item.id }}.repo + with_items: repo_files diff --git a/roles/yum_repos/templates/yumrepo.j2 b/roles/yum_repos/templates/yumrepo.j2 new file mode 100644 index 000000000..0dfdbfe43 --- /dev/null +++ b/roles/yum_repos/templates/yumrepo.j2 @@ -0,0 +1,18 @@ +{% set repos = item.repos %} +{% for repo in repos %} +[{{ repo.id }}] +name={{ repo.name }} +baseurl={{ repo.baseurl }} +{% set repo_enabled_value = repo.enabled | default(repo_enabled) %} +{% set enable_repo = 1 if (repo_enabled_value | int(0) == 1 or repo_enabled_value | lower in ['true', 'yes']) else 0 %} +enabled={{ enable_repo }} +{% set repo_gpgcheck_value = repo.gpgcheck | default(repo_gpgcheck) %} +{% set enable_gpgcheck = 1 if (repo_gpgcheck_value | int(0) == 1 or repo_gpgcheck_value | lower in ['true', 'yes']) else 0 %} +gpgcheck={{ enable_gpgcheck }} +{% for key, value in repo.iteritems() %} +{% if key not in ['id', 'name', 'baseurl', 'enabled', 'gpgcheck'] and value is defined and value != '' %} +{{ key }}={{ value }} +{% endif %} +{% endfor %} + +{% endfor %} -- cgit v1.2.3 From f0ae24d8346ba8cafe6c8f9890433789b5367078 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Thu, 9 Apr 2015 15:20:31 -0400 Subject: Automatic commit of package [openshift-ansible-bin] release [0.0.6-1]. --- bin/openshift-ansible-bin.spec | 6 +++++- rel-eng/packages/openshift-ansible-bin | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec index f509bdd79..695aebc28 100644 --- a/bin/openshift-ansible-bin.spec +++ b/bin/openshift-ansible-bin.spec @@ -1,6 +1,6 @@ Summary: OpenShift Ansible Scripts for working with metadata hosts Name: openshift-ansible-bin -Version: 0.0.5 +Version: 0.0.6 Release: 1%{?dist} License: ASL 2.0 URL: https://github.com/openshift/openshift-ansible @@ -36,6 +36,10 @@ cp -p openshift_ansible.conf.example %{buildroot}/etc/openshift_ansible/openshif %config(noreplace) /etc/openshift_ansible/ %changelog +* Thu Apr 09 2015 Thomas Wiest 0.0.6-1 +- fixed bug where opssh would throw an exception if pssh returned a non-zero + exit code (twiest@redhat.com) + * Wed Apr 08 2015 Thomas Wiest 0.0.5-1 - fixed the opssh default output behavior to be consistent with pssh. Also fixed a bug in how directories are named for --outdir and --errdir. diff --git a/rel-eng/packages/openshift-ansible-bin b/rel-eng/packages/openshift-ansible-bin index 99ae75e8b..a4d727f9d 100644 --- a/rel-eng/packages/openshift-ansible-bin +++ b/rel-eng/packages/openshift-ansible-bin @@ -1 +1 @@ -0.0.5-1 bin/ +0.0.6-1 bin/ -- cgit v1.2.3 From 8022525b3c335ecd8213429da428fc04228adcf2 Mon Sep 17 00:00:00 2001 From: Matt Woodson Date: Thu, 9 Apr 2015 15:28:43 -0400 Subject: added sebools for ansible tower config --- roles/ansible_tower/tasks/main.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/roles/ansible_tower/tasks/main.yaml b/roles/ansible_tower/tasks/main.yaml index f58a5b1c2..e9bde9478 100644 --- a/roles/ansible_tower/tasks/main.yaml +++ b/roles/ansible_tower/tasks/main.yaml @@ -25,3 +25,9 @@ - name: Open firewalld port for https firewalld: port=8080/tcp permanent=true state=enabled +- name: Set (httpd_can_network_connect) flag on and keep it persistent across reboots + seboolean: name=httpd_can_network_connect state=yes persistent=yes + +- name: Set (httpd_can_network_connect_db) flag on and keep it persistent across reboots + seboolean: name=httpd_can_network_connect_db state=yes persistent=yes + -- cgit v1.2.3 From 1917cd3f88299c4dc23ef344c0e2aefc7e79db4f Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Thu, 9 Apr 2015 16:43:14 -0400 Subject: Adding a multi_ec2 yaml configure role --- roles/openshift_ansible_inventory/README.md | 41 ++++++++++++++++++++++ .../openshift_ansible_inventory/defaults/main.yml | 4 +++ .../openshift_ansible_inventory/handlers/main.yml | 2 ++ roles/openshift_ansible_inventory/meta/main.yml | 8 +++++ roles/openshift_ansible_inventory/tasks/main.yml | 11 ++++++ .../templates/multi_ec2.yaml.j2 | 11 ++++++ roles/openshift_ansible_inventory/vars/main.yml | 2 ++ 7 files changed, 79 insertions(+) create mode 100644 roles/openshift_ansible_inventory/README.md create mode 100644 roles/openshift_ansible_inventory/defaults/main.yml create mode 100644 roles/openshift_ansible_inventory/handlers/main.yml create mode 100644 roles/openshift_ansible_inventory/meta/main.yml create mode 100644 roles/openshift_ansible_inventory/tasks/main.yml create mode 100644 roles/openshift_ansible_inventory/templates/multi_ec2.yaml.j2 create mode 100644 roles/openshift_ansible_inventory/vars/main.yml diff --git a/roles/openshift_ansible_inventory/README.md b/roles/openshift_ansible_inventory/README.md new file mode 100644 index 000000000..69a07effd --- /dev/null +++ b/roles/openshift_ansible_inventory/README.md @@ -0,0 +1,41 @@ +Openshift Ansible Inventory +========= + +Install and configure openshift-ansible-inventory. + +Requirements +------------ + +None + +Role Variables +-------------- + +oo_inventory_group +oo_inventory_user +oo_inventory_accounts +oo_inventory_cache_max_age + +Dependencies +------------ + +None + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +ASL 2.0 + +Author Information +------------------ + +Openshift operations, Red Hat, Inc diff --git a/roles/openshift_ansible_inventory/defaults/main.yml b/roles/openshift_ansible_inventory/defaults/main.yml new file mode 100644 index 000000000..f53c00c80 --- /dev/null +++ b/roles/openshift_ansible_inventory/defaults/main.yml @@ -0,0 +1,4 @@ +--- +oo_inventory_group: root +oo_inventory_owner: root +oo_inventory_cache_max_age: 1800 diff --git a/roles/openshift_ansible_inventory/handlers/main.yml b/roles/openshift_ansible_inventory/handlers/main.yml new file mode 100644 index 000000000..e2db43477 --- /dev/null +++ b/roles/openshift_ansible_inventory/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for openshift_ansible_inventory diff --git a/roles/openshift_ansible_inventory/meta/main.yml b/roles/openshift_ansible_inventory/meta/main.yml new file mode 100644 index 000000000..ff3df0a7d --- /dev/null +++ b/roles/openshift_ansible_inventory/meta/main.yml @@ -0,0 +1,8 @@ +--- +galaxy_info: + author: Openshift + description: Install and configure openshift-ansible-inventory + company: Red Hat, Inc + license: ASL 2.0 + min_ansible_version: 1.2 +dependencies: [] diff --git a/roles/openshift_ansible_inventory/tasks/main.yml b/roles/openshift_ansible_inventory/tasks/main.yml new file mode 100644 index 000000000..3990d5750 --- /dev/null +++ b/roles/openshift_ansible_inventory/tasks/main.yml @@ -0,0 +1,11 @@ +--- +- yum: + name: openshift-ansible-inventory + state: present + +- template: + src: multi_ec2.yaml.j2 + dest: /etc/ansible/multi_ec2.yaml + group: "{{ oo_inventory_group }}" + owner: "{{ oo_inventory_owner }}" + mode: "0640" diff --git a/roles/openshift_ansible_inventory/templates/multi_ec2.yaml.j2 b/roles/openshift_ansible_inventory/templates/multi_ec2.yaml.j2 new file mode 100644 index 000000000..23dfe73b8 --- /dev/null +++ b/roles/openshift_ansible_inventory/templates/multi_ec2.yaml.j2 @@ -0,0 +1,11 @@ +# multi ec2 inventory configs +cache_max_age: {{ oo_inventory_cache_max_age }} +accounts: +{% for account in oo_inventory_accounts %} + - name: {{ account.name }} + provider: {{ account.provider }} + env_vars: + AWS_ACCESS_KEY_ID: {{ account.env_vars.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: {{ account.env_vars.AWS_SECRET_ACCESS_KEY }} + +{% endfor %} diff --git a/roles/openshift_ansible_inventory/vars/main.yml b/roles/openshift_ansible_inventory/vars/main.yml new file mode 100644 index 000000000..25c049282 --- /dev/null +++ b/roles/openshift_ansible_inventory/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for openshift_ansible_inventory -- cgit v1.2.3 From 9fbec064d28a72963b1566258b4bcabcd63b2c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9na=C3=AFc=20Huard?= Date: Wed, 8 Apr 2015 16:33:55 +0200 Subject: Add libvirt as a provider --- README.md | 1 + README_libvirt.md | 92 +++++++++++++++++++ bin/cluster | 6 +- inventory/libvirt/group_vars/all | 2 + inventory/libvirt/hosts | 2 + playbooks/libvirt/openshift-cluster/filter_plugins | 1 + playbooks/libvirt/openshift-cluster/launch.yml | 65 +++++++++++++ .../libvirt/openshift-cluster/launch_instances.yml | 102 +++++++++++++++++++++ playbooks/libvirt/openshift-cluster/list.yml | 43 +++++++++ playbooks/libvirt/openshift-cluster/roles | 1 + playbooks/libvirt/openshift-cluster/terminate.yml | 41 +++++++++ playbooks/libvirt/openshift-cluster/vars.yml | 7 ++ playbooks/libvirt/openshift-master/config.yml | 21 +++++ playbooks/libvirt/openshift-master/filter_plugins | 1 + playbooks/libvirt/openshift-master/roles | 1 + playbooks/libvirt/openshift-master/vars.yml | 1 + playbooks/libvirt/openshift-node/config.yml | 102 +++++++++++++++++++++ playbooks/libvirt/openshift-node/filter_plugins | 1 + playbooks/libvirt/openshift-node/roles | 1 + playbooks/libvirt/openshift-node/vars.yml | 1 + playbooks/libvirt/templates/domain.xml | 62 +++++++++++++ playbooks/libvirt/templates/meta-data | 2 + playbooks/libvirt/templates/user-data | 10 ++ 23 files changed, 564 insertions(+), 2 deletions(-) create mode 100644 README_libvirt.md create mode 100644 inventory/libvirt/group_vars/all create mode 100644 inventory/libvirt/hosts create mode 120000 playbooks/libvirt/openshift-cluster/filter_plugins create mode 100644 playbooks/libvirt/openshift-cluster/launch.yml create mode 100644 playbooks/libvirt/openshift-cluster/launch_instances.yml create mode 100644 playbooks/libvirt/openshift-cluster/list.yml create mode 120000 playbooks/libvirt/openshift-cluster/roles create mode 100644 playbooks/libvirt/openshift-cluster/terminate.yml create mode 100644 playbooks/libvirt/openshift-cluster/vars.yml create mode 100644 playbooks/libvirt/openshift-master/config.yml create mode 120000 playbooks/libvirt/openshift-master/filter_plugins create mode 120000 playbooks/libvirt/openshift-master/roles create mode 100644 playbooks/libvirt/openshift-master/vars.yml create mode 100644 playbooks/libvirt/openshift-node/config.yml create mode 120000 playbooks/libvirt/openshift-node/filter_plugins create mode 120000 playbooks/libvirt/openshift-node/roles create mode 100644 playbooks/libvirt/openshift-node/vars.yml create mode 100644 playbooks/libvirt/templates/domain.xml create mode 100644 playbooks/libvirt/templates/meta-data create mode 100644 playbooks/libvirt/templates/user-data diff --git a/README.md b/README.md index e7fa89930..87dbfc1ea 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Setup - Setup for a specific cloud: - [AWS](README_AWS.md) - [GCE](README_GCE.md) + - [local VMs](README_libvirt.md) - Build - [How to build the openshift-ansible rpms](BUILD.md) diff --git a/README_libvirt.md b/README_libvirt.md new file mode 100644 index 000000000..fd2eb57f6 --- /dev/null +++ b/README_libvirt.md @@ -0,0 +1,92 @@ + +LIBVIRT Setup instructions +========================== + +`libvirt` is an `openshift-ansible` provider that uses `libvirt` to create local Fedora VMs that are provisioned exactly the same way that cloud VMs would be provisioned. + +This makes `libvirt` useful to develop, test and debug Openshift and openshift-ansible locally on the developer’s workstation before going to the cloud. + +Install dependencies +-------------------- + +1. Install [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html) +2. Install [ebtables](http://ebtables.netfilter.org/) +3. Install [qemu](http://wiki.qemu.org/Main_Page) +4. Install [libvirt](http://libvirt.org/) +5. Enable and start the libvirt daemon, e.g: + * ``systemctl enable libvirtd`` + * ``systemctl start libvirtd`` +6. [Grant libvirt access to your user¹](https://libvirt.org/aclpolkit.html) +7. Check that your `$HOME` is accessible to the qemu user² + +#### ¹ Depending on your distribution, libvirt access may be denied by default or may require a password at each access. + +You can test it with the following command: +``` +virsh -c qemu:///system pool-list +``` + +If you have access error messages, please read https://libvirt.org/acl.html and https://libvirt.org/aclpolkit.html . + +In short, if your libvirt has been compiled with Polkit support (ex: Arch, Fedora 21), you can create `/etc/polkit-1/rules.d/50-org.libvirt.unix.manage.rules` as follows to grant full access to libvirt to `$USER` + +``` +sudo /bin/sh -c "cat - > /etc/polkit-1/rules.d/50-org.libvirt.unix.manage.rules" << EOF +polkit.addRule(function(action, subject) { + if (action.id == "org.libvirt.unix.manage" && + subject.user == "$USER") { + return polkit.Result.YES; + polkit.log("action=" + action); + polkit.log("subject=" + subject); + } +}); +EOF +``` + +If your libvirt has not been compiled with Polkit (ex: Ubuntu 14.04.1 LTS), check the permissions on the libvirt unix socket: + +``` +ls -l /var/run/libvirt/libvirt-sock +srwxrwx--- 1 root libvirtd 0 févr. 12 16:03 /var/run/libvirt/libvirt-sock + +usermod -a -G libvirtd $USER +# $USER needs to logout/login to have the new group be taken into account +``` + +(Replace `$USER` with your login name) + +#### ² Qemu will run with a specific user. It must have access to the VMs drives + +All the disk drive resources needed by the VMs (Fedora disk image, cloud-init files) are put inside `~/libvirt-storage-pool-openshift/`. + +As we’re using the `qemu:///system` instance of libvirt, qemu will run with a specific `user:group` distinct from your user. It is configured in `/etc/libvirt/qemu.conf`. That qemu user must have access to that libvirt storage pool. + +If your `$HOME` is world readable, everything is fine. If your `$HOME` is private, `ansible` will fail with an error message like: + +``` +error: Cannot access storage file '$HOME/libvirt-storage-pool-openshift/lenaic-master-216d8.qcow2' (as uid:99, gid:78): Permission denied +``` + +In order to fix that issue, you have several possibilities: +* set `libvirt_storage_pool_path` inside `playbooks/libvirt/openshift-cluster/launch.yml` and `playbooks/libvirt/openshift-cluster/terminate.yml` to a directory: + * backed by a filesystem with a lot of free disk space + * writable by your user; + * accessible by the qemu user. +* Grant the qemu user access to the storage pool. + +On Arch: + +``` +setfacl -m g:kvm:--x ~ +``` + +Test the setup +-------------- + +``` +cd openshift-ansible + +bin/cluster create -m 1 -n 3 libvirt lenaic + +bin/cluster terminate libvirt lenaic +``` diff --git a/bin/cluster b/bin/cluster index 36ab1da1b..ca227721e 100755 --- a/bin/cluster +++ b/bin/cluster @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # vim: expandtab:tabstop=4:shiftwidth=4 import argparse @@ -94,6 +94,8 @@ class Cluster(object): os.environ[key] = config.get('ec2', key) inventory = '-i inventory/aws/ec2.py' + elif 'libvirt' == provider: + inventory = '-i inventory/libvirt/hosts' else: # this code should never be reached raise ValueError("invalid PROVIDER {}".format(provider)) @@ -139,7 +141,7 @@ if __name__ == '__main__': cluster = Cluster() - providers = ['gce', 'aws'] + providers = ['gce', 'aws', 'libvirt'] parser = argparse.ArgumentParser( description='Python wrapper to ensure proper environment for OpenShift ansible playbooks', ) diff --git a/inventory/libvirt/group_vars/all b/inventory/libvirt/group_vars/all new file mode 100644 index 000000000..b22da00de --- /dev/null +++ b/inventory/libvirt/group_vars/all @@ -0,0 +1,2 @@ +--- +ansible_ssh_user: root diff --git a/inventory/libvirt/hosts b/inventory/libvirt/hosts new file mode 100644 index 000000000..6a818f268 --- /dev/null +++ b/inventory/libvirt/hosts @@ -0,0 +1,2 @@ +# Eventually we'll add the GCE, AWS, etc dynamic inventories, but for now... +localhost ansible_python_interpreter=/usr/bin/python2 diff --git a/playbooks/libvirt/openshift-cluster/filter_plugins b/playbooks/libvirt/openshift-cluster/filter_plugins new file mode 120000 index 000000000..99a95e4ca --- /dev/null +++ b/playbooks/libvirt/openshift-cluster/filter_plugins @@ -0,0 +1 @@ +../../../filter_plugins \ No newline at end of file diff --git a/playbooks/libvirt/openshift-cluster/launch.yml b/playbooks/libvirt/openshift-cluster/launch.yml new file mode 100644 index 000000000..6f2df33af --- /dev/null +++ b/playbooks/libvirt/openshift-cluster/launch.yml @@ -0,0 +1,65 @@ +- name: Launch instance(s) + hosts: localhost + connection: local + gather_facts: no + + vars: + libvirt_storage_pool_path: "{{ lookup('env','HOME') }}/libvirt-storage-pool-openshift" + libvirt_storage_pool: 'openshift' + libvirt_uri: 'qemu:///system' + + vars_files: + - vars.yml + + tasks: + - set_fact: + k8s_type: master + + - name: Generate master instance name(s) + set_fact: + scratch_name: "{{ cluster_id }}-{{ k8s_type }}-{{ '%05x' | format( 1048576 | random ) }}" + register: master_names_output + with_sequence: start=1 end='{{ num_masters }}' + + - set_fact: + master_names: "{{ master_names_output.results | oo_collect('ansible_facts') | oo_collect('scratch_name') }}" + + - include: launch_instances.yml + vars: + instances: '{{ master_names }}' + cluster: '{{ cluster_id }}' + type: '{{ k8s_type }}' + group_name: 'tag_env-host-type-{{ cluster_id }}-openshift-master' + + - set_fact: + k8s_type: node + + - name: Generate node instance name(s) + set_fact: + scratch_name: "{{ cluster_id }}-{{ k8s_type }}-{{ '%05x' | format( 1048576 | random ) }}" + register: node_names_output + with_sequence: start=1 end='{{ num_nodes }}' + + - set_fact: + node_names: "{{ node_names_output.results | oo_collect('ansible_facts') | oo_collect('scratch_name') }}" + + - include: launch_instances.yml + vars: + instances: '{{ node_names }}' + cluster: '{{ cluster_id }}' + type: '{{ k8s_type }}' + +- hosts: 'tag_env-{{ cluster_id }}' + roles: + - openshift_repos + - os_update_latest + +- include: ../openshift-master/config.yml + vars: + oo_host_group_exp: 'groups["tag_env-host-type-{{ cluster_id }}-openshift-master"]' + oo_env: '{{ cluster_id }}' + +- include: ../openshift-node/config.yml + vars: + oo_host_group_exp: 'groups["tag_env-host-type-{{ cluster_id }}-openshift-node"]' + oo_env: '{{ cluster_id }}' diff --git a/playbooks/libvirt/openshift-cluster/launch_instances.yml b/playbooks/libvirt/openshift-cluster/launch_instances.yml new file mode 100644 index 000000000..3bbcae981 --- /dev/null +++ b/playbooks/libvirt/openshift-cluster/launch_instances.yml @@ -0,0 +1,102 @@ +- name: Create the libvirt storage directory for openshift + file: + dest: '{{ libvirt_storage_pool_path }}' + state: directory + +- name: Download Base Cloud image + get_url: + url: '{{ base_image_url }}' + sha256sum: '{{ base_image_sha256 }}' + dest: '{{ libvirt_storage_pool_path }}/{{ base_image_name }}' + +- name: Create the cloud-init config drive path + file: + dest: '{{ libvirt_storage_pool_path }}/{{ item }}_configdrive/openstack/latest' + state: directory + with_items: '{{ instances }}' + +- name: Create the cloud-init config drive files + template: + src: '{{ item[1] }}' + dest: '{{ libvirt_storage_pool_path }}/{{ item[0] }}_configdrive/openstack/latest/{{ item[1] }}' + with_nested: + - '{{ instances }}' + - [ user-data, meta-data ] + +- name: Create the cloud-init config drive + command: 'genisoimage -output {{ libvirt_storage_pool_path }}/{{ item }}_cloud-init.iso -volid cidata -joliet -rock user-data meta-data' + args: + chdir: '{{ libvirt_storage_pool_path }}/{{ item }}_configdrive/openstack/latest' + creates: '{{ libvirt_storage_pool_path }}/{{ item }}_cloud-init.iso' + with_items: '{{ instances }}' + +- name: Create the libvirt storage pool for openshift + command: 'virsh -c {{ libvirt_uri }} pool-create-as {{ libvirt_storage_pool }} dir --target {{ libvirt_storage_pool_path }}' + ignore_errors: yes + +- name: Refresh the libvirt storage pool for openshift + command: 'virsh -c {{ libvirt_uri }} pool-refresh {{ libvirt_storage_pool }}' + +- name: Create VMs drives + command: 'virsh -c {{ libvirt_uri }} vol-create-as {{ libvirt_storage_pool }} {{ item }}.qcow2 10G --format qcow2 --backing-vol {{ base_image_name }} --backing-vol-format qcow2' + with_items: '{{ instances }}' + +- name: Create VMs + virt: + name: '{{ item }}' + command: define + xml: "{{ lookup('template', '../templates/domain.xml') }}" + uri: '{{ libvirt_uri }}' + with_items: '{{ instances }}' + +- name: Start VMs + virt: + name: '{{ item }}' + state: running + uri: '{{ libvirt_uri }}' + with_items: '{{ instances }}' + +- name: Collect MAC addresses of the VMs + shell: 'virsh -c {{ libvirt_uri }} dumpxml {{ item }} | xmllint --xpath "string(//domain/devices/interface/mac/@address)" -' + register: scratch_mac + with_items: '{{ instances }}' + +- name: Wait for the VMs to get an IP + command: "egrep -c '{{ scratch_mac.results | oo_collect('stdout') | join('|') }}' /proc/net/arp" + ignore_errors: yes + register: nb_allocated_ips + until: nb_allocated_ips.stdout == '{{ instances | length }}' + retries: 30 + delay: 1 + +- name: Collect IP addresses of the VMs + shell: "awk '/{{ item.stdout }}/ {print $1}' /proc/net/arp" + register: scratch_ip + with_items: '{{ scratch_mac.results }}' + +- set_fact: + ips: "{{ scratch_ip.results | oo_collect('stdout') }}" + +- name: Add new instances + add_host: + hostname: '{{ item.0 }}' + ansible_ssh_host: '{{ item.1 }}' + ansible_ssh_user: root + groups: 'tag_env-{{ cluster }}, tag_host-type-{{ type }}, tag_env-host-type-{{ cluster }}-openshift-{{ type }}' + with_together: + - instances + - ips + +- name: Wait for ssh + wait_for: + host: '{{ item }}' + port: 22 + with_items: ips + +- name: Wait for root user setup + command: 'ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null root@{{ item }} echo root user is setup' + register: result + until: result.rc == 0 + retries: 30 + delay: 1 + with_items: ips diff --git a/playbooks/libvirt/openshift-cluster/list.yml b/playbooks/libvirt/openshift-cluster/list.yml new file mode 100644 index 000000000..6bf07e3c6 --- /dev/null +++ b/playbooks/libvirt/openshift-cluster/list.yml @@ -0,0 +1,43 @@ +- name: Generate oo_list_hosts group + hosts: localhost + connection: local + gather_facts: no + + vars: + libvirt_uri: 'qemu:///system' + + tasks: + - name: List VMs + virt: + command: list_vms + register: list_vms + + - name: Collect MAC addresses of the VMs + shell: 'virsh -c {{ libvirt_uri }} dumpxml {{ item }} | xmllint --xpath "string(//domain/devices/interface/mac/@address)" -' + register: scratch_mac + with_items: '{{ list_vms.list_vms }}' + when: item|truncate(cluster_id|length+1, True) == '{{ cluster_id }}-...' + + - name: Collect IP addresses of the VMs + shell: "awk '/{{ item.stdout }}/ {print $1}' /proc/net/arp" + register: scratch_ip + with_items: '{{ scratch_mac.results }}' + when: item.skipped is not defined + + - name: Add hosts + add_host: + hostname: '{{ item[0] }}' + ansible_ssh_host: '{{ item[1].stdout }}' + ansible_ssh_user: root + groups: oo_list_hosts + with_together: + - '{{ list_vms.list_vms }}' + - '{{ scratch_ip.results }}' + when: item[1].skipped is not defined + +- name: List Hosts + hosts: oo_list_hosts + + tasks: + - debug: + msg: 'public:{{ansible_default_ipv4.address}} private:{{ansible_default_ipv4.address}}' diff --git a/playbooks/libvirt/openshift-cluster/roles b/playbooks/libvirt/openshift-cluster/roles new file mode 120000 index 000000000..20c4c58cf --- /dev/null +++ b/playbooks/libvirt/openshift-cluster/roles @@ -0,0 +1 @@ +../../../roles \ No newline at end of file diff --git a/playbooks/libvirt/openshift-cluster/terminate.yml b/playbooks/libvirt/openshift-cluster/terminate.yml new file mode 100644 index 000000000..c609169d3 --- /dev/null +++ b/playbooks/libvirt/openshift-cluster/terminate.yml @@ -0,0 +1,41 @@ +- name: Terminate instance(s) + hosts: localhost + connection: local + gather_facts: no + + vars: + libvirt_storage_pool_path: "{{ lookup('env','HOME') }}/libvirt-storage-pool-openshift" + libvirt_storage_pool: 'openshift' + libvirt_uri: 'qemu:///system' + + tasks: + - name: List VMs + virt: + command: list_vms + register: list_vms + + - name: Destroy VMs + virt: + name: '{{ item[0] }}' + command: '{{ item[1] }}' + uri: '{{ libvirt_uri }}' + with_nested: + - '{{ list_vms.list_vms }}' + - [ destroy, undefine ] + when: item[0]|truncate(cluster_id|length+1, True) == '{{ cluster_id }}-...' + + - name: Delete VMs config drive + file: + path: '{{ libvirt_storage_pool_path }}/{{ item }}_configdrive/openstack' + state: absent + with_items: '{{ list_vms.list_vms }}' + when: item|truncate(cluster_id|length+1, True) == '{{ cluster_id }}-...' + + - name: Delete VMs drives + command: 'virsh -c {{ libvirt_uri }} vol-delete --pool {{ libvirt_storage_pool }} {{ item[0] }}{{ item[1] }}' + args: + removes: '{{ libvirt_storage_pool_path }}/{{ item[0] }}{{ item[1] }}' + with_nested: + - '{{ list_vms.list_vms }}' + - [ '_configdrive', '_cloud-init.iso', '.qcow2' ] + when: item[0]|truncate(cluster_id|length+1, True) == '{{ cluster_id }}-...' diff --git a/playbooks/libvirt/openshift-cluster/vars.yml b/playbooks/libvirt/openshift-cluster/vars.yml new file mode 100644 index 000000000..4e4eecd46 --- /dev/null +++ b/playbooks/libvirt/openshift-cluster/vars.yml @@ -0,0 +1,7 @@ +# base_image_url: http://download.fedoraproject.org/pub/fedora/linux/releases/21/Cloud/Images/x86_64/Fedora-Cloud-Base-20141203-21.x86_64.qcow2 +# base_image_name: Fedora-Cloud-Base-20141203-21.x86_64.qcow2 +# base_image_sha256: 3a99bb89f33e3d4ee826c8160053cdb8a72c80cd23350b776ce73cd244467d86 + +base_image_url: http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2 +base_image_name: CentOS-7-x86_64-GenericCloud.qcow2 +base_image_sha256: e324e3ab1d24a1bbf035ddb365e7f9058c0b454acf48d7aa15c5519fae5998ab diff --git a/playbooks/libvirt/openshift-master/config.yml b/playbooks/libvirt/openshift-master/config.yml new file mode 100644 index 000000000..dd95fd57f --- /dev/null +++ b/playbooks/libvirt/openshift-master/config.yml @@ -0,0 +1,21 @@ +- name: master/config.yml, populate oo_masters_to_config host group if needed + hosts: localhost + gather_facts: no + tasks: + - name: "Evaluate oo_host_group_exp if it's set" + add_host: + name: '{{ item }}' + groups: oo_masters_to_config + with_items: "{{ oo_host_group_exp | default('') }}" + when: oo_host_group_exp is defined + +- name: Configure instances + hosts: oo_masters_to_config + vars: + openshift_hostname: '{{ ansible_default_ipv4.address }}' + vars_files: + - vars.yml + roles: + - openshift_master + - pods + - os_env_extras diff --git a/playbooks/libvirt/openshift-master/filter_plugins b/playbooks/libvirt/openshift-master/filter_plugins new file mode 120000 index 000000000..99a95e4ca --- /dev/null +++ b/playbooks/libvirt/openshift-master/filter_plugins @@ -0,0 +1 @@ +../../../filter_plugins \ No newline at end of file diff --git a/playbooks/libvirt/openshift-master/roles b/playbooks/libvirt/openshift-master/roles new file mode 120000 index 000000000..20c4c58cf --- /dev/null +++ b/playbooks/libvirt/openshift-master/roles @@ -0,0 +1 @@ +../../../roles \ No newline at end of file diff --git a/playbooks/libvirt/openshift-master/vars.yml b/playbooks/libvirt/openshift-master/vars.yml new file mode 100644 index 000000000..ad0c0fbe2 --- /dev/null +++ b/playbooks/libvirt/openshift-master/vars.yml @@ -0,0 +1 @@ +openshift_debug_level: 4 diff --git a/playbooks/libvirt/openshift-node/config.yml b/playbooks/libvirt/openshift-node/config.yml new file mode 100644 index 000000000..3244a8046 --- /dev/null +++ b/playbooks/libvirt/openshift-node/config.yml @@ -0,0 +1,102 @@ +- name: node/config.yml, populate oo_nodes_to_config host group if needed + hosts: localhost + gather_facts: no + tasks: + - name: "Evaluate oo_host_group_exp if it's set" + add_host: + name: '{{ item }}' + groups: oo_nodes_to_config + with_items: "{{ oo_host_group_exp | default('') }}" + when: oo_host_group_exp is defined + + - add_host: + name: "{{ groups['tag_env-host-type-' ~ cluster_id ~ '-openshift-master'][0] }}" + groups: oo_first_master + when: oo_host_group_exp is defined + + +- name: Gather and set facts for hosts to configure + hosts: oo_nodes_to_config + roles: + - openshift_facts + tasks: + # Since the master is registering the nodes before they are configured, we + # need to make sure to set the node properties beforehand if we do not want + # the defaults + - openshift_facts: + role: "{{ item.role }}" + local_facts: "{{ item.local_facts }}" + with_items: + - role: common + local_facts: + hostname: "{{ ansible_default_ipv4.address }}" + - role: node + local_facts: + external_id: "{{ openshift_node_external_id | default(None) }}" + resources_cpu: "{{ openshfit_node_resources_cpu | default(None) }}" + resources_memory: "{{ openshfit_node_resources_memory | default(None) }}" + pod_cidr: "{{ openshfit_node_pod_cidr | default(None) }}" + labels: "{{ openshfit_node_labels | default(None) }}" + annotations: "{{ openshfit_node_annotations | default(None) }}" + + +- name: Register nodes + hosts: oo_first_master + vars: + openshift_nodes: "{{ hostvars + | oo_select_keys(groups['oo_nodes_to_config']) }}" + roles: + - openshift_register_nodes + tasks: + - name: Create local temp directory for syncing certs + local_action: command /usr/bin/mktemp -d /tmp/openshift-ansible-XXXXXXX + register: mktemp + + - name: Sync master certs to localhost + synchronize: + mode: pull + checksum: yes + src: /var/lib/openshift/openshift.local.certificates + dest: "{{ mktemp.stdout }}" + +- name: Configure instances + hosts: oo_nodes_to_config + vars_files: + - vars.yml + vars: + sync_tmpdir: "{{ hostvars[groups['oo_first_master'][0]].mktemp.stdout }}" + cert_parent_rel_path: openshift.local.certificates + cert_rel_path: "{{ cert_parent_rel_path }}/node-{{ openshift.common.hostname }}" + cert_base_path: /var/lib/openshift + cert_parent_path: "{{ cert_base_path }}/{{ cert_parent_rel_path }}" + cert_path: "{{ cert_base_path }}/{{ cert_rel_path }}" + pre_tasks: + - name: Ensure certificate directories exists + file: + path: "{{ item }}" + state: directory + with_items: + - "{{ cert_path }}" + - "{{ cert_parent_path }}/ca" + + # TODO: notify restart openshift-node and/or restart openshift-sdn-node, + # possibly test service started time against certificate/config file + # timestamps in openshift-node or openshift-sdn-node to trigger notify + - name: Sync certs to nodes + synchronize: + checksum: yes + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: no + group: no + with_items: + - src: "{{ sync_tmpdir }}/{{ cert_rel_path }}" + dest: "{{ cert_parent_path }}" + - src: "{{ sync_tmpdir }}/{{ cert_parent_rel_path }}/ca/cert.crt" + dest: "{{ cert_parent_path }}/ca/cert.crt" + - local_action: file name={{ sync_tmpdir }} state=absent + run_once: true + roles: + - openshift_node + - os_env_extras + - os_env_extras_node diff --git a/playbooks/libvirt/openshift-node/filter_plugins b/playbooks/libvirt/openshift-node/filter_plugins new file mode 120000 index 000000000..99a95e4ca --- /dev/null +++ b/playbooks/libvirt/openshift-node/filter_plugins @@ -0,0 +1 @@ +../../../filter_plugins \ No newline at end of file diff --git a/playbooks/libvirt/openshift-node/roles b/playbooks/libvirt/openshift-node/roles new file mode 120000 index 000000000..20c4c58cf --- /dev/null +++ b/playbooks/libvirt/openshift-node/roles @@ -0,0 +1 @@ +../../../roles \ No newline at end of file diff --git a/playbooks/libvirt/openshift-node/vars.yml b/playbooks/libvirt/openshift-node/vars.yml new file mode 100644 index 000000000..ad0c0fbe2 --- /dev/null +++ b/playbooks/libvirt/openshift-node/vars.yml @@ -0,0 +1 @@ +openshift_debug_level: 4 diff --git a/playbooks/libvirt/templates/domain.xml b/playbooks/libvirt/templates/domain.xml new file mode 100644 index 000000000..da037d138 --- /dev/null +++ b/playbooks/libvirt/templates/domain.xml @@ -0,0 +1,62 @@ + + {{ item }} + 1 + 1 + 2 + + hvm + + + + + + + + + + + + + destroy + restart + restart + + /usr/bin/qemu-system-x86_64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/playbooks/libvirt/templates/meta-data b/playbooks/libvirt/templates/meta-data new file mode 100644 index 000000000..5d779519f --- /dev/null +++ b/playbooks/libvirt/templates/meta-data @@ -0,0 +1,2 @@ +instance-id: {{ item[0] }} +local-hostname: {{ item[0] }} diff --git a/playbooks/libvirt/templates/user-data b/playbooks/libvirt/templates/user-data new file mode 100644 index 000000000..985badc8e --- /dev/null +++ b/playbooks/libvirt/templates/user-data @@ -0,0 +1,10 @@ +#cloud-config + +disable_root: 0 + +system_info: + default_user: + name: root + +ssh_authorized_keys: + - {{ lookup('file', '~/.ssh/id_rsa.pub') }} -- cgit v1.2.3 From 6b74f852258b51c1558aff3967288a57ca4efb86 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Fri, 10 Apr 2015 16:30:32 -0400 Subject: added ohi --- bin/ohi | 96 ++++++++++++++++++++++++++++++++++++++++++ bin/openshift-ansible-bin.spec | 2 +- 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100755 bin/ohi diff --git a/bin/ohi b/bin/ohi new file mode 100755 index 000000000..06a375cdb --- /dev/null +++ b/bin/ohi @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# vim: expandtab:tabstop=4:shiftwidth=4 + +import argparse +import traceback +import sys +import os +import re +import tempfile +import time +import subprocess +import ConfigParser + +from openshift_ansible import awsutil + +CONFIG_MAIN_SECTION = 'main' +CONFIG_HOST_TYPE_ALIAS_SECTION = 'host_type_aliases' +CONFIG_INVENTORY_OPTION = 'inventory' + +class ArgumentMismatchError(ValueError): pass + +class Ohi(object): + def __init__(self): + self.inventory = None + self.host_type_aliases = {} + self.file_path = os.path.join(os.path.dirname(os.path.realpath(__file__))) + + # Default the config path to /etc + self.config_path = os.path.join(os.path.sep, 'etc', \ + 'openshift_ansible', \ + 'openshift_ansible.conf') + + self.parse_cli_args() + self.parse_config_file() + + self.aws = awsutil.AwsUtil(self.inventory, self.host_type_aliases) + + def run(self): + if self.args.list_host_types: + self.aws.print_host_types() + return 0 + + if self.args.env and \ + self.args.host_type: + hosts = self.aws.get_host_list(self.args.host_type, self.args.env) + for host in hosts: + print host + return 0 + + # If it makes it here, we weren't able to determine what they wanted to do + raise ArgumentMismatchError("Invalid combination of arguments") + + def parse_config_file(self): + if os.path.isfile(self.config_path): + config = ConfigParser.ConfigParser() + config.read(self.config_path) + + if config.has_section(CONFIG_MAIN_SECTION) and \ + config.has_option(CONFIG_MAIN_SECTION, CONFIG_INVENTORY_OPTION): + self.inventory = config.get(CONFIG_MAIN_SECTION, CONFIG_INVENTORY_OPTION) + + self.host_type_aliases = {} + if config.has_section(CONFIG_HOST_TYPE_ALIAS_SECTION): + for alias in config.options(CONFIG_HOST_TYPE_ALIAS_SECTION): + value = config.get(CONFIG_HOST_TYPE_ALIAS_SECTION, alias).split(',') + self.host_type_aliases[alias] = value + + def parse_cli_args(self): + """Setup the command line parser with the options we want + """ + + parser = argparse.ArgumentParser(description='Openshift Host Inventory') + + parser.add_argument('--list-host-types', default=False, action='store_true', + help='List all of the host types') + + parser.add_argument('-e', '--env', action="store", + help="Which environment to use") + + parser.add_argument('-t', '--host-type', action="store", + help="Which host type to use") + + self.args = parser.parse_args() + + +if __name__ == '__main__': + if len(sys.argv) == 1: + print "\nError: No options given. Use --help to see the available options\n" + sys.exit(0) + + try: + ohi = Ohi() + exitcode = ohi.run() + sys.exit(exitcode) + except ArgumentMismatchError as e: + print "\nError: %s\n" % e.message diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec index 695aebc28..876bca1d7 100644 --- a/bin/openshift-ansible-bin.spec +++ b/bin/openshift-ansible-bin.spec @@ -23,7 +23,7 @@ mkdir -p %{buildroot}%{python_sitelib}/openshift_ansible mkdir -p %{buildroot}/etc/bash_completion.d mkdir -p %{buildroot}/etc/openshift_ansible -cp -p ossh oscp opssh %{buildroot}%{_bindir} +cp -p ossh oscp opssh ohi %{buildroot}%{_bindir} cp -p openshift_ansible/* %{buildroot}%{python_sitelib}/openshift_ansible cp -p ossh_bash_completion %{buildroot}/etc/bash_completion.d -- cgit v1.2.3 From 8a7a455abfcf8df7ddc706d11167cb904e1b52dd Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Fri, 10 Apr 2015 17:36:22 -0400 Subject: added the ability to run opssh and ohi on all hosts in an environment, as well as all hosts of the same host-type regardless of environment --- bin/ohi | 36 +++++++++++++++++++++++++----------- bin/openshift_ansible/awsutil.py | 40 +++++++++++++++++++++++++++++++++++++--- bin/opssh | 36 ++++++++++++++++++++++++++---------- 3 files changed, 88 insertions(+), 24 deletions(-) diff --git a/bin/ohi b/bin/ohi index 06a375cdb..408961ee4 100755 --- a/bin/ohi +++ b/bin/ohi @@ -12,13 +12,12 @@ import subprocess import ConfigParser from openshift_ansible import awsutil +from openshift_ansible.awsutil import ArgumentError CONFIG_MAIN_SECTION = 'main' CONFIG_HOST_TYPE_ALIAS_SECTION = 'host_type_aliases' CONFIG_INVENTORY_OPTION = 'inventory' -class ArgumentMismatchError(ValueError): pass - class Ohi(object): def __init__(self): self.inventory = None @@ -40,15 +39,30 @@ class Ohi(object): self.aws.print_host_types() return 0 - if self.args.env and \ - self.args.host_type: - hosts = self.aws.get_host_list(self.args.host_type, self.args.env) - for host in hosts: - print host - return 0 + hosts = None + if self.args.host_type is not None and \ + self.args.env is not None: + # Both env and host-type specified + hosts = self.aws.get_host_list(host_type=self.args.host_type, \ + env=self.args.env) + + if self.args.host_type is None and \ + self.args.env is not None: + # Only env specified + hosts = self.aws.get_host_list(env=self.args.env) + + if self.args.host_type is not None and \ + self.args.env is None: + # Only host-type specified + hosts = self.aws.get_host_list(host_type=self.args.host_type) + + if hosts is None: + # We weren't able to determine what they wanted to do + raise ArgumentError("Invalid combination of arguments") - # If it makes it here, we weren't able to determine what they wanted to do - raise ArgumentMismatchError("Invalid combination of arguments") + for host in hosts: + print host + return 0 def parse_config_file(self): if os.path.isfile(self.config_path): @@ -92,5 +106,5 @@ if __name__ == '__main__': ohi = Ohi() exitcode = ohi.run() sys.exit(exitcode) - except ArgumentMismatchError as e: + except ArgumentError as e: print "\nError: %s\n" % e.message diff --git a/bin/openshift_ansible/awsutil.py b/bin/openshift_ansible/awsutil.py index 8fef0a24f..65b269930 100644 --- a/bin/openshift_ansible/awsutil.py +++ b/bin/openshift_ansible/awsutil.py @@ -5,6 +5,10 @@ import os import json import re +class ArgumentError(Exception): + def __init__(self, message): + self.message = message + class AwsUtil(object): def __init__(self, inventory_path=None, host_type_aliases={}): self.host_type_aliases = host_type_aliases @@ -128,15 +132,45 @@ class AwsUtil(object): return self.alias_lookup[host_type] return host_type + def gen_env_tag(self, env): + """Generate the environment tag + """ + return "tag_environment_%s" % env + + def gen_host_type_tag(self, host_type): + """Generate the host type tag + """ + host_type = self.resolve_host_type(host_type) + return "tag_host-type_%s" % host_type + def gen_env_host_type_tag(self, host_type, env): """Generate the environment host type tag """ host_type = self.resolve_host_type(host_type) return "tag_env-host-type_%s-%s" % (env, host_type) - def get_host_list(self, host_type, env): + def get_host_list(self, host_type=None, env=None): """Get the list of hosts from the inventory using host-type and environment """ inv = self.get_inventory() - host_type_tag = self.gen_env_host_type_tag(host_type, env) - return inv[host_type_tag] + + if host_type is not None and \ + env is not None: + # Both host type and environment were specified + env_host_type_tag = self.gen_env_host_type_tag(host_type, env) + return inv[env_host_type_tag] + + if host_type is None and \ + env is not None: + # Just environment was specified + host_type_tag = self.gen_env_tag(env) + return inv[host_type_tag] + + if host_type is not None and \ + env is None: + # Just host-type was specified + host_type_tag = self.gen_host_type_tag(host_type) + return inv[host_type_tag] + + # We should never reach here! + raise ArgumentError("Invalid combination of parameters") diff --git a/bin/opssh b/bin/opssh index 453da65b4..5fb447318 100755 --- a/bin/opssh +++ b/bin/opssh @@ -12,6 +12,7 @@ import subprocess import ConfigParser from openshift_ansible import awsutil +from openshift_ansible.awsutil import ArgumentError DEFAULT_PSSH_PAR = 200 PSSH = '/usr/bin/pssh' @@ -19,8 +20,6 @@ CONFIG_MAIN_SECTION = 'main' CONFIG_HOST_TYPE_ALIAS_SECTION = 'host_type_aliases' CONFIG_INVENTORY_OPTION = 'inventory' -class ArgumentMismatchError(ValueError): pass - class Opssh(object): def __init__(self): self.inventory = None @@ -42,13 +41,30 @@ class Opssh(object): self.aws.print_host_types() return 0 - if self.args.env and \ - self.args.host_type and \ - self.args.command: - return self.run_pssh() + hosts = None + if self.args.host_type is not None and \ + self.args.env is not None: + # Both env and host-type specified + hosts = self.aws.get_host_list(host_type=self.args.host_type, \ + env=self.args.env) + + if self.args.host_type is None and \ + self.args.env is not None: + # Only env specified + hosts = self.aws.get_host_list(env=self.args.env) + + if self.args.host_type is not None and \ + self.args.env is None: + # Only host-type specified + hosts = self.aws.get_host_list(host_type=self.args.host_type) + + if hosts is None: + # We weren't able to determine what they wanted to do + raise ArgumentError("Invalid combination of arguments") - # If it makes it here, we weren't able to determine what they wanted to do - raise ArgumentMismatchError("Invalid combination of arguments") + for host in hosts: + print host + return 0 def run_pssh(self): """Actually run the pssh command based off of the supplied options @@ -109,7 +125,7 @@ class Opssh(object): parser.add_argument('-e', '--env', action="store", help="Which environment to use") - parser.add_argument('-t', '--host-type', action="store", + parser.add_argument('-t', '--host-type', action="store", default=None, help="Which host type to use") parser.add_argument('-c', '--command', action='store', @@ -142,5 +158,5 @@ if __name__ == '__main__': opssh = Opssh() exitcode = opssh.run() sys.exit(exitcode) - except ArgumentMismatchError as e: + except ArgumentError as e: print "\nError: %s\n" % e.message -- cgit v1.2.3 From 187e11209d0b7494ffacbabde569c14a8d0ebe2f Mon Sep 17 00:00:00 2001 From: Ricardo Bernardeli Date: Mon, 13 Apr 2015 09:20:38 +1000 Subject: =?UTF-8?q?Add=20extra=20information=20for=20AWS=20README=20Make?= =?UTF-8?q?=20security=20group=20an=20environment=20variable=20with=20defa?= =?UTF-8?q?ult=20to=20=E2=80=98public=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README_AWS.md | 22 ++++++++++++++++++++-- .../aws/openshift-cluster/launch_instances.yml | 3 ++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/README_AWS.md b/README_AWS.md index e877f34c6..37f4c5f51 100644 --- a/README_AWS.md +++ b/README_AWS.md @@ -14,7 +14,7 @@ Create a credentials file export AWS_ACCESS_KEY_ID='AKIASTUFF' export AWS_SECRET_ACCESS_KEY='STUFF' ``` -1. source this file +2. source this file ``` source ~/.aws_creds ``` @@ -23,7 +23,7 @@ Note: You must source this file in each shell that you want to run cloud.rb (Optional) Setup your $HOME/.ssh/config file ------------------------------------------- -In case of a cluster creation, or any other case where you don't know the machine hostname in advance, you can use '.ssh/config' +In case of a cluster creation, or any other case where you don't know the machine hostname in advance, you can use '.ssh/config' to setup a private key file to allow ansible to connect to the created hosts. To do so, add the the following entry to your $HOME/.ssh/config file and make it point to the private key file which allows you to login on AWS. @@ -34,6 +34,24 @@ Host *.compute-1.amazonaws.com Alternatively, you can configure your ssh-agent to hold the credentials to connect to your AWS instances. +(Optional) Choose where the cluster will be launched +---------------------------------------------------- + +By default, a cluster is launched with the following configuration: + +- Instance type: m3.large +- AMI: ami-307b3658 +- Region: us-east-1 +- Keypair name: libra +- Security group: public + +If needed, these values can be changed by setting environment variables on your system. + +- export ec2_instance_type='m3.large' +- export ec2_ami='ami-307b3658' +- export ec2_region='us-east-1' +- export ec2_keypair='libra' +- export ec2_security_group='public' Install Dependencies -------------------- diff --git a/playbooks/aws/openshift-cluster/launch_instances.yml b/playbooks/aws/openshift-cluster/launch_instances.yml index e4d5952fd..9d645fbe5 100644 --- a/playbooks/aws/openshift-cluster/launch_instances.yml +++ b/playbooks/aws/openshift-cluster/launch_instances.yml @@ -5,6 +5,7 @@ machine_region: "{{ lookup('env', 'ec2_region')|default('us-east-1', true) }}" machine_keypair: "{{ lookup('env', 'ec2_keypair')|default('libra', true) }}" created_by: "{{ lookup('env', 'LOGNAME')|default(cluster, true) }}" + security_group: "{{ lookup('env', 'ec2_security_group')|default('public', true) }}" env: "{{ cluster }}" host_type: "{{ type }}" env_host_type: "{{ cluster }}-openshift-{{ type }}" @@ -14,7 +15,7 @@ state: present region: "{{ machine_region }}" keypair: "{{ machine_keypair }}" - group: ['public'] + group: "{{ security_group }}" instance_type: "{{ machine_type }}" image: "{{ machine_image }}" count: "{{ instances | oo_len }}" -- cgit v1.2.3 From 1cb4ba976599e6e4fd18568f7dc46b58db5b4161 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Mon, 13 Apr 2015 10:07:39 -0400 Subject: Automatic commit of package [openshift-ansible-bin] release [0.0.7-1]. --- bin/openshift-ansible-bin.spec | 7 ++++++- rel-eng/packages/openshift-ansible-bin | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec index 876bca1d7..04af4546c 100644 --- a/bin/openshift-ansible-bin.spec +++ b/bin/openshift-ansible-bin.spec @@ -1,6 +1,6 @@ Summary: OpenShift Ansible Scripts for working with metadata hosts Name: openshift-ansible-bin -Version: 0.0.6 +Version: 0.0.7 Release: 1%{?dist} License: ASL 2.0 URL: https://github.com/openshift/openshift-ansible @@ -36,6 +36,11 @@ cp -p openshift_ansible.conf.example %{buildroot}/etc/openshift_ansible/openshif %config(noreplace) /etc/openshift_ansible/ %changelog +* Mon Apr 13 2015 Thomas Wiest 0.0.7-1 +- added the ability to run opssh and ohi on all hosts in an environment, as + well as all hosts of the same host-type regardless of environment + (twiest@redhat.com) +- added ohi (twiest@redhat.com) * Thu Apr 09 2015 Thomas Wiest 0.0.6-1 - fixed bug where opssh would throw an exception if pssh returned a non-zero exit code (twiest@redhat.com) diff --git a/rel-eng/packages/openshift-ansible-bin b/rel-eng/packages/openshift-ansible-bin index a4d727f9d..6b4f91660 100644 --- a/rel-eng/packages/openshift-ansible-bin +++ b/rel-eng/packages/openshift-ansible-bin @@ -1 +1 @@ -0.0.6-1 bin/ +0.0.7-1 bin/ -- cgit v1.2.3 From fa08dd34159e16c574f551cd48d7194f5888a128 Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Mon, 13 Apr 2015 16:35:55 -0400 Subject: fixed bug in opssh where it wouldn't actually run pssh --- bin/opssh | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/bin/opssh b/bin/opssh index 5fb447318..a4fceb6a8 100755 --- a/bin/opssh +++ b/bin/opssh @@ -41,30 +41,12 @@ class Opssh(object): self.aws.print_host_types() return 0 - hosts = None - if self.args.host_type is not None and \ + if self.args.host_type is not None or \ self.args.env is not None: - # Both env and host-type specified - hosts = self.aws.get_host_list(host_type=self.args.host_type, \ - env=self.args.env) + return self.run_pssh() - if self.args.host_type is None and \ - self.args.env is not None: - # Only env specified - hosts = self.aws.get_host_list(env=self.args.env) - - if self.args.host_type is not None and \ - self.args.env is None: - # Only host-type specified - hosts = self.aws.get_host_list(host_type=self.args.host_type) - - if hosts is None: - # We weren't able to determine what they wanted to do - raise ArgumentError("Invalid combination of arguments") - - for host in hosts: - print host - return 0 + # We weren't able to determine what they wanted to do + raise ArgumentError("Invalid combination of arguments") def run_pssh(self): """Actually run the pssh command based off of the supplied options @@ -82,7 +64,9 @@ class Opssh(object): if self.args.errdir: pssh_args.extend(["--errdir", self.args.errdir]) - hosts = self.aws.get_host_list(self.args.host_type, self.args.env) + hosts = self.aws.get_host_list(host_type=self.args.host_type, + env=self.args.env) + with tempfile.NamedTemporaryFile(prefix='opssh-', delete=True) as f: for h in hosts: f.write(h + os.linesep) -- cgit v1.2.3 From eb64f8f819139e3901b032a4f2bfa53a3189531e Mon Sep 17 00:00:00 2001 From: Thomas Wiest Date: Mon, 13 Apr 2015 16:42:36 -0400 Subject: Automatic commit of package [openshift-ansible-bin] release [0.0.8-1]. --- bin/openshift-ansible-bin.spec | 5 ++++- rel-eng/packages/openshift-ansible-bin | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bin/openshift-ansible-bin.spec b/bin/openshift-ansible-bin.spec index 04af4546c..c7db6f684 100644 --- a/bin/openshift-ansible-bin.spec +++ b/bin/openshift-ansible-bin.spec @@ -1,6 +1,6 @@ Summary: OpenShift Ansible Scripts for working with metadata hosts Name: openshift-ansible-bin -Version: 0.0.7 +Version: 0.0.8 Release: 1%{?dist} License: ASL 2.0 URL: https://github.com/openshift/openshift-ansible @@ -36,6 +36,9 @@ cp -p openshift_ansible.conf.example %{buildroot}/etc/openshift_ansible/openshif %config(noreplace) /etc/openshift_ansible/ %changelog +* Mon Apr 13 2015 Thomas Wiest 0.0.8-1 +- fixed bug in opssh where it wouldn't actually run pssh (twiest@redhat.com) + * Mon Apr 13 2015 Thomas Wiest 0.0.7-1 - added the ability to run opssh and ohi on all hosts in an environment, as well as all hosts of the same host-type regardless of environment diff --git a/rel-eng/packages/openshift-ansible-bin b/rel-eng/packages/openshift-ansible-bin index 6b4f91660..500e1f4b1 100644 --- a/rel-eng/packages/openshift-ansible-bin +++ b/rel-eng/packages/openshift-ansible-bin @@ -1 +1 @@ -0.0.7-1 bin/ +0.0.8-1 bin/ -- cgit v1.2.3 From 7ffc6a28edad3f20604dd13e16b8f57cf670b25e Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Thu, 16 Apr 2015 13:08:42 -0400 Subject: Adding ansible-tower-cli rpm to tower --- roles/ansible_tower/tasks/main.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/ansible_tower/tasks/main.yaml b/roles/ansible_tower/tasks/main.yaml index e9bde9478..1d75a95e6 100644 --- a/roles/ansible_tower/tasks/main.yaml +++ b/roles/ansible_tower/tasks/main.yaml @@ -9,6 +9,7 @@ - ansible - telnet - ack + - python-ansible-tower-cli - name: download Tower setup get_url: url=http://releases.ansible.com/ansible-tower/setup/ansible-tower-setup-2.1.1.tar.gz dest=/opt/ force=no -- cgit v1.2.3 From 735355f75ab24d14aadbc30ec334dadc789028db Mon Sep 17 00:00:00 2001 From: Troy Dawson Date: Thu, 16 Apr 2015 16:01:26 -0500 Subject: update tower ami image to latest libra-ops-rhel7 --- playbooks/aws/ansible-tower/launch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/aws/ansible-tower/launch.yml b/playbooks/aws/ansible-tower/launch.yml index 4c29fa833..56235bc8a 100644 --- a/playbooks/aws/ansible-tower/launch.yml +++ b/playbooks/aws/ansible-tower/launch.yml @@ -6,7 +6,7 @@ vars: inst_region: us-east-1 - rhel7_ami: ami-a24e30ca + rhel7_ami: ami-906240f8 user_data_file: user_data.txt vars_files: -- cgit v1.2.3