From d82066b0d47b35c56da95cf75649b75de0ccdaff Mon Sep 17 00:00:00 2001 From: Tomas Sedovic Date: Fri, 12 Jan 2018 14:14:30 +0100 Subject: Move the OpenStack dynamic inventory from sample Keeping the dynamic inventory in the `sample-inventory` alongside the `group_vars` poses a problem: when we update the inventory, our users won't get the latest version. The dynamic inventory should be independent of the OpenShift or OpenStack configuration and the users should be able to either pass it explicitly or create a symlink if they want. --- playbooks/openstack/inventory.py | 119 ++++++++++++++++++++++ playbooks/openstack/sample-inventory/inventory.py | 119 ---------------------- 2 files changed, 119 insertions(+), 119 deletions(-) create mode 100755 playbooks/openstack/inventory.py delete mode 100755 playbooks/openstack/sample-inventory/inventory.py (limited to 'playbooks') diff --git a/playbooks/openstack/inventory.py b/playbooks/openstack/inventory.py new file mode 100755 index 000000000..76e658eb7 --- /dev/null +++ b/playbooks/openstack/inventory.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +""" +This is an Ansible dynamic inventory for OpenStack. + +It requires your OpenStack credentials to be set in clouds.yaml or your shell +environment. + +""" + +from __future__ import print_function + +from collections import Mapping +import json + +import shade + + +def build_inventory(): + '''Build the dynamic inventory.''' + cloud = shade.openstack_cloud() + + inventory = {} + + # TODO(shadower): filter the servers based on the `OPENSHIFT_CLUSTER` + # environment variable. + cluster_hosts = [ + server for server in cloud.list_servers() + if 'metadata' in server and 'clusterid' in server.metadata] + + masters = [server.name for server in cluster_hosts + if server.metadata['host-type'] == 'master'] + + etcd = [server.name for server in cluster_hosts + if server.metadata['host-type'] == 'etcd'] + if not etcd: + etcd = masters + + infra_hosts = [server.name for server in cluster_hosts + if server.metadata['host-type'] == 'node' and + server.metadata['sub-host-type'] == 'infra'] + + app = [server.name for server in cluster_hosts + if server.metadata['host-type'] == 'node' and + server.metadata['sub-host-type'] == 'app'] + + cns = [server.name for server in cluster_hosts + if server.metadata['host-type'] == 'cns'] + + nodes = list(set(masters + infra_hosts + app + cns)) + + dns = [server.name for server in cluster_hosts + if server.metadata['host-type'] == 'dns'] + + load_balancers = [server.name for server in cluster_hosts + if server.metadata['host-type'] == 'lb'] + + osev3 = list(set(nodes + etcd + load_balancers)) + + inventory['cluster_hosts'] = {'hosts': [s.name for s in cluster_hosts]} + inventory['OSEv3'] = {'hosts': osev3} + inventory['masters'] = {'hosts': masters} + inventory['etcd'] = {'hosts': etcd} + inventory['nodes'] = {'hosts': nodes} + inventory['infra_hosts'] = {'hosts': infra_hosts} + inventory['app'] = {'hosts': app} + inventory['glusterfs'] = {'hosts': cns} + inventory['dns'] = {'hosts': dns} + inventory['lb'] = {'hosts': load_balancers} + + for server in cluster_hosts: + if 'group' in server.metadata: + group = server.metadata.group + if group not in inventory: + inventory[group] = {'hosts': []} + inventory[group]['hosts'].append(server.name) + + inventory['_meta'] = {'hostvars': {}} + + for server in cluster_hosts: + ssh_ip_address = server.public_v4 or server.private_v4 + hostvars = { + 'ansible_host': ssh_ip_address + } + + public_v4 = server.public_v4 or server.private_v4 + if public_v4: + hostvars['public_v4'] = server.public_v4 + hostvars['openshift_public_ip'] = server.public_v4 + # TODO(shadower): what about multiple networks? + if server.private_v4: + hostvars['private_v4'] = server.private_v4 + hostvars['openshift_ip'] = server.private_v4 + + # NOTE(shadower): Yes, we set both hostname and IP to the private + # IP address for each node. OpenStack doesn't resolve nodes by + # name at all, so using a hostname here would require an internal + # DNS which would complicate the setup and potentially introduce + # performance issues. + hostvars['openshift_hostname'] = server.metadata.get( + 'openshift_hostname', server.private_v4) + hostvars['openshift_public_hostname'] = server.name + + if server.metadata['host-type'] == 'cns': + hostvars['glusterfs_devices'] = ['/dev/nvme0n1'] + + node_labels = server.metadata.get('node_labels') + # NOTE(shadower): the node_labels value must be a dict not string + if not isinstance(node_labels, Mapping): + node_labels = json.loads(node_labels) + + if node_labels: + hostvars['openshift_node_labels'] = node_labels + + inventory['_meta']['hostvars'][server.name] = hostvars + return inventory + + +if __name__ == '__main__': + print(json.dumps(build_inventory(), indent=4, sort_keys=True)) diff --git a/playbooks/openstack/sample-inventory/inventory.py b/playbooks/openstack/sample-inventory/inventory.py deleted file mode 100755 index 76e658eb7..000000000 --- a/playbooks/openstack/sample-inventory/inventory.py +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env python -""" -This is an Ansible dynamic inventory for OpenStack. - -It requires your OpenStack credentials to be set in clouds.yaml or your shell -environment. - -""" - -from __future__ import print_function - -from collections import Mapping -import json - -import shade - - -def build_inventory(): - '''Build the dynamic inventory.''' - cloud = shade.openstack_cloud() - - inventory = {} - - # TODO(shadower): filter the servers based on the `OPENSHIFT_CLUSTER` - # environment variable. - cluster_hosts = [ - server for server in cloud.list_servers() - if 'metadata' in server and 'clusterid' in server.metadata] - - masters = [server.name for server in cluster_hosts - if server.metadata['host-type'] == 'master'] - - etcd = [server.name for server in cluster_hosts - if server.metadata['host-type'] == 'etcd'] - if not etcd: - etcd = masters - - infra_hosts = [server.name for server in cluster_hosts - if server.metadata['host-type'] == 'node' and - server.metadata['sub-host-type'] == 'infra'] - - app = [server.name for server in cluster_hosts - if server.metadata['host-type'] == 'node' and - server.metadata['sub-host-type'] == 'app'] - - cns = [server.name for server in cluster_hosts - if server.metadata['host-type'] == 'cns'] - - nodes = list(set(masters + infra_hosts + app + cns)) - - dns = [server.name for server in cluster_hosts - if server.metadata['host-type'] == 'dns'] - - load_balancers = [server.name for server in cluster_hosts - if server.metadata['host-type'] == 'lb'] - - osev3 = list(set(nodes + etcd + load_balancers)) - - inventory['cluster_hosts'] = {'hosts': [s.name for s in cluster_hosts]} - inventory['OSEv3'] = {'hosts': osev3} - inventory['masters'] = {'hosts': masters} - inventory['etcd'] = {'hosts': etcd} - inventory['nodes'] = {'hosts': nodes} - inventory['infra_hosts'] = {'hosts': infra_hosts} - inventory['app'] = {'hosts': app} - inventory['glusterfs'] = {'hosts': cns} - inventory['dns'] = {'hosts': dns} - inventory['lb'] = {'hosts': load_balancers} - - for server in cluster_hosts: - if 'group' in server.metadata: - group = server.metadata.group - if group not in inventory: - inventory[group] = {'hosts': []} - inventory[group]['hosts'].append(server.name) - - inventory['_meta'] = {'hostvars': {}} - - for server in cluster_hosts: - ssh_ip_address = server.public_v4 or server.private_v4 - hostvars = { - 'ansible_host': ssh_ip_address - } - - public_v4 = server.public_v4 or server.private_v4 - if public_v4: - hostvars['public_v4'] = server.public_v4 - hostvars['openshift_public_ip'] = server.public_v4 - # TODO(shadower): what about multiple networks? - if server.private_v4: - hostvars['private_v4'] = server.private_v4 - hostvars['openshift_ip'] = server.private_v4 - - # NOTE(shadower): Yes, we set both hostname and IP to the private - # IP address for each node. OpenStack doesn't resolve nodes by - # name at all, so using a hostname here would require an internal - # DNS which would complicate the setup and potentially introduce - # performance issues. - hostvars['openshift_hostname'] = server.metadata.get( - 'openshift_hostname', server.private_v4) - hostvars['openshift_public_hostname'] = server.name - - if server.metadata['host-type'] == 'cns': - hostvars['glusterfs_devices'] = ['/dev/nvme0n1'] - - node_labels = server.metadata.get('node_labels') - # NOTE(shadower): the node_labels value must be a dict not string - if not isinstance(node_labels, Mapping): - node_labels = json.loads(node_labels) - - if node_labels: - hostvars['openshift_node_labels'] = node_labels - - inventory['_meta']['hostvars'][server.name] = hostvars - return inventory - - -if __name__ == '__main__': - print(json.dumps(build_inventory(), indent=4, sort_keys=True)) -- cgit v1.2.3 From 54502cee66db02a659e58aab64fb97ca6f728ca0 Mon Sep 17 00:00:00 2001 From: Tomas Sedovic Date: Fri, 12 Jan 2018 14:16:56 +0100 Subject: Document the inventory change --- playbooks/openstack/README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'playbooks') diff --git a/playbooks/openstack/README.md b/playbooks/openstack/README.md index 2e5cacc76..fb621f898 100644 --- a/playbooks/openstack/README.md +++ b/playbooks/openstack/README.md @@ -183,7 +183,9 @@ Then run the provision + install playbook -- this will create the OpenStack resources: ```bash -$ ansible-playbook --user openshift -i inventory \ +$ ansible-playbook --user openshift \ + -i openshift-ansible/playbooks/openstack/inventory.py + -i inventory \ openshift-ansible/playbooks/openstack/openshift-cluster/provision_install.yml \ -e openshift_repos_enable_testing=true ``` @@ -191,6 +193,11 @@ $ ansible-playbook --user openshift -i inventory \ Note, you may want to use the testing repo for development purposes only. Normally, `openshift_repos_enable_testing` should not be specified. +In addition to *your* inventory with your OpenShift and OpenStack +configuration, we are also supplying the [dynamic inventory][dynamic] from +`openshift-ansible/inventory`. It's a script that will look at the Nova servers +and other resources that will be created and let Ansible know about them. + If you're using multiple inventories, make sure you pass the path to the right one to `-i`. @@ -233,3 +240,4 @@ advanced configuration: [loadbalancer]: ./advanced-configuration.md#multi-master-configuration [external-dns]: ./advanced-configuration.md#dns-configuration-variables [cinder-registry]: ./advanced-configuration.md#creating-and-using-a-cinder-volume-for-the-openshift-registry +[dynamic]: http://docs.ansible.com/ansible/latest/intro_dynamic_inventory.html -- cgit v1.2.3