Sfoglia il codice sorgente

Add a sample inventory for openstack provisioning

Tomas Sedovic 7 anni fa
parent
commit
5328475c0e

+ 5 - 0
playbooks/provisioning/openstack/sample-inventory/clouds.yaml

@@ -0,0 +1,5 @@
+ansible:
+  use_hostnames: True
+  expand_hostvars: True
+  fail_on_errors: True
+

+ 10 - 0
playbooks/provisioning/openstack/sample-inventory/group_vars/OSEv3.yml

@@ -0,0 +1,10 @@
+---
+openshift_deployment_type: openshift-enterprise
+openshift_release: v3.5
+openshift_master_default_subdomain: "apps.openshift.example.com"
+
+# NOTE(shadower): do not remove this line, otherwise the default node labels
+# won't be set up.
+openshift_node_labels: "{{ openstack.metadata.node_labels }}"
+
+osm_default_node_selector: 'region=primary'

+ 39 - 0
playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml

@@ -0,0 +1,39 @@
+env_id: "openshift"
+openstack_dns_domain: "example.com"
+openstack_nameservers: ["192.168.1.1"]
+openstack_ssh_public_key: "openshift"
+openstack_default_image_name: "rhel73"
+openstack_default_flavor: "m1.medium"
+openstack_external_network_name: "public"
+
+openstack_num_masters: 1
+openstack_num_infra: 1
+openstack_num_nodes: 2
+
+docker_volume_size: "15"
+
+# TODO(shadower): this is identical to `openstack_dns_domain`.
+# We should make it so it's not duplicated here.
+dns_domain: "example.com"
+
+# TODO(shadower): this is identical to `openstack_nameservers`.
+# We should make it so it's not duplicated here.
+public_dns_forwarder: "192.168.1.1"
+
+openstack_subnet_prefix: "192.168.99"
+
+# # Red Hat subscription
+# rhsm_register: True
+# rhsm_repos:
+#  - "rhel-7-server-rpms"
+#  - "rhel-7-server-ose-3.5-rpms"
+#  - "rhel-7-server-extras-rpms"
+#  - "rhel-7-fast-datapath-rpms"
+# rhsm_username: '<username>'
+# rhsm_password: '<password>'
+# rhsm_pool: '<pool id>'
+
+
+# NOTE(shadower): Do not change this value. The Ansible user is currently
+# hardcoded to `openshift`.
+ansible_user: openshift

+ 44 - 0
playbooks/provisioning/openstack/sample-inventory/hosts

@@ -0,0 +1,44 @@
+#[all:vars]
+# For all group_vars, see ./group_vars/all.yml
+
+# Create an OSEv3 group that contains the master, nodes, etcd, and lb groups.
+# The lb group lets Ansible configure HAProxy as the load balancing solution.
+# Comment lb out if your load balancer is pre-configured.
+[cluster_hosts:children]
+OSEv3
+dns
+
+[OSEv3:children]
+masters
+nodes
+etcd
+
+# Set variables common for all OSEv3 hosts
+#[OSEv3:vars]
+
+# For OSEv3 normal group vars, see ./group_vars/OSEv3.yml
+
+# Host Groups
+
+[masters:children]
+masters.openshift.example.com
+
+[etcd:children]
+etcd.openshift.example.com
+
+[nodes:children]
+masters
+infra.openshift.example.com
+nodes.openshift.example.com
+
+[infra_hosts:children]
+infra.openshift.example.com
+
+[dns:children]
+dns.openshift.example.com
+
+[masters.openshift.example.com]
+[etcd.openshift.example.com]
+[infra.openshift.example.com]
+[nodes.openshift.example.com]
+[dns.openshift.example.com]

+ 252 - 0
playbooks/provisioning/openstack/sample-inventory/openstack.py

@@ -0,0 +1,252 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2012, Marco Vito Moscaritolo <marco@agavee.com>
+# Copyright (c) 2013, Jesse Keating <jesse.keating@rackspace.com>
+# Copyright (c) 2015, Hewlett-Packard Development Company, L.P.
+# Copyright (c) 2016, Rackspace Australia
+#
+# This module is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this software.  If not, see <http://www.gnu.org/licenses/>.
+
+# The OpenStack Inventory module uses os-client-config for configuration.
+# https://github.com/stackforge/os-client-config
+# This means it will either:
+#  - Respect normal OS_* environment variables like other OpenStack tools
+#  - Read values from a clouds.yaml file.
+# If you want to configure via clouds.yaml, you can put the file in:
+#  - Current directory
+#  - ~/.config/openstack/clouds.yaml
+#  - /etc/openstack/clouds.yaml
+#  - /etc/ansible/openstack.yml
+# The clouds.yaml file can contain entries for multiple clouds and multiple
+# regions of those clouds. If it does, this inventory module will connect to
+# all of them and present them as one contiguous inventory.
+#
+# See the adjacent openstack.yml file for an example config file
+# There are two ansible inventory specific options that can be set in
+# the inventory section.
+# expand_hostvars controls whether or not the inventory will make extra API
+#                 calls to fill out additional information about each server
+# use_hostnames changes the behavior from registering every host with its UUID
+#               and making a group of its hostname to only doing this if the
+#               hostname in question has more than one server
+# fail_on_errors causes the inventory to fail and return no hosts if one cloud
+#                has failed (for example, bad credentials or being offline).
+#                When set to False, the inventory will return hosts from
+#                whichever other clouds it can contact. (Default: True)
+
+import argparse
+import collections
+import os
+import sys
+import time
+from distutils.version import StrictVersion
+
+try:
+    import json
+except:
+    import simplejson as json
+
+import os_client_config
+import shade
+import shade.inventory
+
+CONFIG_FILES = ['/etc/ansible/openstack.yaml', '/etc/ansible/openstack.yml']
+
+
+def get_groups_from_server(server_vars, namegroup=True):
+    groups = []
+
+    region = server_vars['region']
+    cloud = server_vars['cloud']
+    metadata = server_vars.get('metadata', {})
+
+    # Create a group for the cloud
+    groups.append(cloud)
+
+    # Create a group on region
+    groups.append(region)
+
+    # And one by cloud_region
+    groups.append("%s_%s" % (cloud, region))
+
+    # Check if group metadata key in servers' metadata
+    if 'group' in metadata:
+        groups.append(metadata['group'])
+
+    for extra_group in metadata.get('groups', '').split(','):
+        if extra_group:
+            groups.append(extra_group.strip())
+
+    groups.append('instance-%s' % server_vars['id'])
+    if namegroup:
+        groups.append(server_vars['name'])
+
+    for key in ('flavor', 'image'):
+        if 'name' in server_vars[key]:
+            groups.append('%s-%s' % (key, server_vars[key]['name']))
+
+    for key, value in iter(metadata.items()):
+        groups.append('meta-%s_%s' % (key, value))
+
+    az = server_vars.get('az', None)
+    if az:
+        # Make groups for az, region_az and cloud_region_az
+        groups.append(az)
+        groups.append('%s_%s' % (region, az))
+        groups.append('%s_%s_%s' % (cloud, region, az))
+    return groups
+
+
+def get_host_groups(inventory, refresh=False):
+    (cache_file, cache_expiration_time) = get_cache_settings()
+    if is_cache_stale(cache_file, cache_expiration_time, refresh=refresh):
+        groups = to_json(get_host_groups_from_cloud(inventory))
+        open(cache_file, 'w').write(groups)
+    else:
+        groups = open(cache_file, 'r').read()
+    return groups
+
+
+def append_hostvars(hostvars, groups, key, server, namegroup=False):
+    hostvars[key] = dict(
+        ansible_ssh_host=server['interface_ip'],
+        openshift_hostname=server['name'],
+        openshift_public_hostname=server['name'],
+        openstack=server)
+    for group in get_groups_from_server(server, namegroup=namegroup):
+        groups[group].append(key)
+
+
+def get_host_groups_from_cloud(inventory):
+    groups = collections.defaultdict(list)
+    firstpass = collections.defaultdict(list)
+    hostvars = {}
+    list_args = {}
+    if hasattr(inventory, 'extra_config'):
+        use_hostnames = inventory.extra_config['use_hostnames']
+        list_args['expand'] = inventory.extra_config['expand_hostvars']
+        if StrictVersion(shade.__version__) >= StrictVersion("1.6.0"):
+            list_args['fail_on_cloud_config'] = \
+                inventory.extra_config['fail_on_errors']
+    else:
+        use_hostnames = False
+
+    for server in inventory.list_hosts(**list_args):
+
+        if 'interface_ip' not in server:
+            continue
+        try:
+          if server["metadata"][os.environ['OS_INV_FILTER_KEY']] == os.environ['OS_INV_FILTER_VALUE']:
+            firstpass[server['name']].append(server)
+        except:
+          firstpass[server['name']].append(server)
+    for name, servers in firstpass.items():
+        if len(servers) == 1 and use_hostnames:
+            append_hostvars(hostvars, groups, name, servers[0])
+        else:
+            server_ids = set()
+            # Trap for duplicate results
+            for server in servers:
+                server_ids.add(server['id'])
+            if len(server_ids) == 1 and use_hostnames:
+                append_hostvars(hostvars, groups, name, servers[0])
+            else:
+                for server in servers:
+                    append_hostvars(
+                        hostvars, groups, server['id'], server,
+                        namegroup=True)
+    groups['_meta'] = {'hostvars': hostvars}
+    return groups
+
+
+def is_cache_stale(cache_file, cache_expiration_time, refresh=False):
+    ''' Determines if cache file has expired, or if it is still valid '''
+    if refresh:
+        return True
+    if os.path.isfile(cache_file) and os.path.getsize(cache_file) > 0:
+        mod_time = os.path.getmtime(cache_file)
+        current_time = time.time()
+        if (mod_time + cache_expiration_time) > current_time:
+            return False
+    return True
+
+
+def get_cache_settings():
+    config = os_client_config.config.OpenStackConfig(
+        config_files=os_client_config.config.CONFIG_FILES + CONFIG_FILES)
+    # For inventory-wide caching
+    cache_expiration_time = config.get_cache_expiration_time()
+    cache_path = config.get_cache_path()
+    if not os.path.exists(cache_path):
+        os.makedirs(cache_path)
+    cache_file = os.path.join(cache_path, 'ansible-inventory.cache')
+    return (cache_file, cache_expiration_time)
+
+
+def to_json(in_dict):
+    return json.dumps(in_dict, sort_keys=True, indent=2)
+
+
+def parse_args():
+    parser = argparse.ArgumentParser(description='OpenStack Inventory Module')
+    parser.add_argument('--private',
+                        action='store_true',
+                        help='Use private address for ansible host')
+    parser.add_argument('--refresh', action='store_true',
+                        help='Refresh cached information')
+    parser.add_argument('--debug', action='store_true', default=False,
+                        help='Enable debug output')
+    group = parser.add_mutually_exclusive_group(required=True)
+    group.add_argument('--list', action='store_true',
+                       help='List active servers')
+    group.add_argument('--host', help='List details about the specific host')
+
+    return parser.parse_args()
+
+
+def main():
+    args = parse_args()
+    try:
+        config_files = os_client_config.config.CONFIG_FILES + CONFIG_FILES
+        shade.simple_logging(debug=args.debug)
+        inventory_args = dict(
+            refresh=args.refresh,
+            config_files=config_files,
+            private=args.private,
+        )
+        if hasattr(shade.inventory.OpenStackInventory, 'extra_config'):
+            inventory_args.update(dict(
+                config_key='ansible',
+                config_defaults={
+                    'use_hostnames': False,
+                    'expand_hostvars': True,
+                    'fail_on_errors': True,
+                }
+            ))
+
+        inventory = shade.inventory.OpenStackInventory(**inventory_args)
+
+        if args.list:
+            output = get_host_groups(inventory, refresh=args.refresh)
+        elif args.host:
+            output = to_json(inventory.get_host(args.host))
+        print(output)
+    except shade.OpenStackCloudException as e:
+        sys.stderr.write('%s\n' % e.message)
+        sys.exit(1)
+    sys.exit(0)
+
+
+if __name__ == '__main__':
+    main()