From 85d1813e0329bf44eae35de3d4a67f63fdcf9444 Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Tue, 1 May 2018 16:38:13 +0100 Subject: xci: osa: Add initial dynamic inventory from PDF/IDF files The PDF and IDF files contain all the information we need for the virtual XCI deployment, so we can use it to create a dynamic inventory and get rid of all the static ones which could easily get outdated as PDF and IDF files evolve over time. This inital version of the dynamic inventory contains a lot of unnecessary generated information but we do that in order to ease the migration from static files to the dynamic inventory. The dynamic inventory will be improved in the future as we consume more and more information from the PDF and IDF files. Change-Id: Id9f07a61c67a5cffcbc18079a341e5d395020a27 Signed-off-by: Markos Chandras --- xci/installer/osa/deploy.sh | 4 +- xci/installer/osa/files/aio/flavor-vars.yml | 3 - xci/installer/osa/files/aio/inventory | 2 - xci/installer/osa/files/ha/flavor-vars.yml | 39 ------ xci/installer/osa/files/ha/inventory | 15 -- xci/installer/osa/files/mini/flavor-vars.yml | 21 --- xci/installer/osa/files/mini/inventory | 12 -- xci/installer/osa/files/noha/flavor-vars.yml | 27 ---- xci/installer/osa/files/noha/inventory | 13 -- .../osa/playbooks/configure-opnfvhost.yml | 2 - .../osa/playbooks/configure-targethosts.yml | 1 - xci/playbooks/dynamic_inventory.py | 153 +++++++++++++++++++++ .../roles/bootstrap-host/tasks/network_debian.yml | 8 +- .../roles/bootstrap-host/tasks/network_redhat.yml | 8 +- .../roles/bootstrap-host/tasks/network_suse.yml | 8 +- 15 files changed, 167 insertions(+), 149 deletions(-) delete mode 100644 xci/installer/osa/files/aio/flavor-vars.yml delete mode 100644 xci/installer/osa/files/aio/inventory delete mode 100644 xci/installer/osa/files/ha/flavor-vars.yml delete mode 100644 xci/installer/osa/files/ha/inventory delete mode 100644 xci/installer/osa/files/mini/flavor-vars.yml delete mode 100644 xci/installer/osa/files/mini/inventory delete mode 100644 xci/installer/osa/files/noha/flavor-vars.yml delete mode 100644 xci/installer/osa/files/noha/inventory create mode 100755 xci/playbooks/dynamic_inventory.py diff --git a/xci/installer/osa/deploy.sh b/xci/installer/osa/deploy.sh index 6dada3f5..c3a6eb84 100755 --- a/xci/installer/osa/deploy.sh +++ b/xci/installer/osa/deploy.sh @@ -58,7 +58,7 @@ echo "Info: Configuring opnfv deployment host for openstack-ansible" echo "-----------------------------------------------------------------------" cd $OSA_XCI_PLAYBOOKS ansible-galaxy install -r ${XCI_PATH}/xci/files/requirements.yml -p $HOME/.ansible/roles -ansible-playbook ${XCI_ANSIBLE_PARAMS} -i ${XCI_FLAVOR_ANSIBLE_FILE_PATH}/inventory \ +ansible-playbook ${XCI_ANSIBLE_PARAMS} -i ${XCI_PLAYBOOKS}/dynamic_inventory.py \ configure-opnfvhost.yml echo "-----------------------------------------------------------------------" echo "Info: Configured opnfv deployment host for openstack-ansible" @@ -78,7 +78,7 @@ if [[ $XCI_FLAVOR != "aio" ]]; then echo "Info: Configuring target hosts for openstack-ansible" echo "-----------------------------------------------------------------------" cd $OSA_XCI_PLAYBOOKS - ansible-playbook ${XCI_ANSIBLE_PARAMS} -i ${XCI_FLAVOR_ANSIBLE_FILE_PATH}/inventory \ + ansible-playbook ${XCI_ANSIBLE_PARAMS} -i ${XCI_PLAYBOOKS}/dynamic_inventory.py \ configure-targethosts.yml echo "-----------------------------------------------------------------------" echo "Info: Configured target hosts" diff --git a/xci/installer/osa/files/aio/flavor-vars.yml b/xci/installer/osa/files/aio/flavor-vars.yml deleted file mode 100644 index 6ac1e0fe..00000000 --- a/xci/installer/osa/files/aio/flavor-vars.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -# this file is added intentionally in order to simplify putting files in place -# in future, it might contain vars specific to this flavor diff --git a/xci/installer/osa/files/aio/inventory b/xci/installer/osa/files/aio/inventory deleted file mode 100644 index fa2a1009..00000000 --- a/xci/installer/osa/files/aio/inventory +++ /dev/null @@ -1,2 +0,0 @@ -[deployment] -opnfv ansible_ssh_host=192.168.122.2 diff --git a/xci/installer/osa/files/ha/flavor-vars.yml b/xci/installer/osa/files/ha/flavor-vars.yml deleted file mode 100644 index 167502c9..00000000 --- a/xci/installer/osa/files/ha/flavor-vars.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- -host_info: { - 'opnfv': { - 'VLAN_IP': '192.168.122.2', - 'MGMT_IP': '172.29.236.10', - 'VXLAN_IP': '172.29.240.10', - 'STORAGE_IP': '172.29.244.10' - }, - 'controller00': { - 'VLAN_IP': '192.168.122.3', - 'MGMT_IP': '172.29.236.11', - 'VXLAN_IP': '172.29.240.11', - 'STORAGE_IP': '172.29.244.11' - }, - 'controller01': { - 'VLAN_IP': '192.168.122.4', - 'MGMT_IP': '172.29.236.12', - 'VXLAN_IP': '172.29.240.12', - 'STORAGE_IP': '172.29.244.12' - }, - 'controller02': { - 'VLAN_IP': '192.168.122.5', - 'MGMT_IP': '172.29.236.13', - 'VXLAN_IP': '172.29.240.13', - 'STORAGE_IP': '172.29.244.13' - }, - 'compute00': { - 'VLAN_IP': '192.168.122.6', - 'MGMT_IP': '172.29.236.14', - 'VXLAN_IP': '172.29.240.14', - 'STORAGE_IP': '172.29.244.14' - }, - 'compute01': { - 'VLAN_IP': '192.168.122.7', - 'MGMT_IP': '172.29.236.15', - 'VXLAN_IP': '172.29.240.15', - 'STORAGE_IP': '172.29.244.15' - } -} diff --git a/xci/installer/osa/files/ha/inventory b/xci/installer/osa/files/ha/inventory deleted file mode 100644 index f5d882ef..00000000 --- a/xci/installer/osa/files/ha/inventory +++ /dev/null @@ -1,15 +0,0 @@ -[deployment] -opnfv ansible_ssh_host=192.168.122.2 - -[controller] -controller00 ansible_ssh_host=192.168.122.3 -controller01 ansible_ssh_host=192.168.122.4 -controller02 ansible_ssh_host=192.168.122.5 - -[compute] -compute00 ansible_ssh_host=192.168.122.6 -compute01 ansible_ssh_host=192.168.122.7 - -[openstack:children] -controller -compute diff --git a/xci/installer/osa/files/mini/flavor-vars.yml b/xci/installer/osa/files/mini/flavor-vars.yml deleted file mode 100644 index 0d446ba2..00000000 --- a/xci/installer/osa/files/mini/flavor-vars.yml +++ /dev/null @@ -1,21 +0,0 @@ ---- -host_info: { - 'opnfv': { - 'VLAN_IP': '192.168.122.2', - 'MGMT_IP': '172.29.236.10', - 'VXLAN_IP': '172.29.240.10', - 'STORAGE_IP': '172.29.244.10' - }, - 'controller00': { - 'VLAN_IP': '192.168.122.3', - 'MGMT_IP': '172.29.236.11', - 'VXLAN_IP': '172.29.240.11', - 'STORAGE_IP': '172.29.244.11' - }, - 'compute00': { - 'VLAN_IP': '192.168.122.4', - 'MGMT_IP': '172.29.236.12', - 'VXLAN_IP': '172.29.240.12', - 'STORAGE_IP': '172.29.244.12' - }, -} diff --git a/xci/installer/osa/files/mini/inventory b/xci/installer/osa/files/mini/inventory deleted file mode 100644 index 4224131f..00000000 --- a/xci/installer/osa/files/mini/inventory +++ /dev/null @@ -1,12 +0,0 @@ -[deployment] -opnfv ansible_ssh_host=192.168.122.2 - -[controller] -controller00 ansible_ssh_host=192.168.122.3 - -[compute] -compute00 ansible_ssh_host=192.168.122.4 - -[openstack:children] -controller -compute diff --git a/xci/installer/osa/files/noha/flavor-vars.yml b/xci/installer/osa/files/noha/flavor-vars.yml deleted file mode 100644 index 3c69a34b..00000000 --- a/xci/installer/osa/files/noha/flavor-vars.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- -host_info: { - 'opnfv': { - 'VLAN_IP': '192.168.122.2', - 'MGMT_IP': '172.29.236.10', - 'VXLAN_IP': '172.29.240.10', - 'STORAGE_IP': '172.29.244.10' - }, - 'controller00': { - 'VLAN_IP': '192.168.122.3', - 'MGMT_IP': '172.29.236.11', - 'VXLAN_IP': '172.29.240.11', - 'STORAGE_IP': '172.29.244.11' - }, - 'compute00': { - 'VLAN_IP': '192.168.122.4', - 'MGMT_IP': '172.29.236.12', - 'VXLAN_IP': '172.29.240.12', - 'STORAGE_IP': '172.29.244.12' - }, - 'compute01': { - 'VLAN_IP': '192.168.122.5', - 'MGMT_IP': '172.29.236.13', - 'VXLAN_IP': '172.29.240.13', - 'STORAGE_IP': '172.29.244.13' - } -} diff --git a/xci/installer/osa/files/noha/inventory b/xci/installer/osa/files/noha/inventory deleted file mode 100644 index 0e3b8d84..00000000 --- a/xci/installer/osa/files/noha/inventory +++ /dev/null @@ -1,13 +0,0 @@ -[deployment] -opnfv ansible_ssh_host=192.168.122.2 - -[controller] -controller00 ansible_ssh_host=192.168.122.3 - -[compute] -compute00 ansible_ssh_host=192.168.122.4 -compute01 ansible_ssh_host=192.168.122.5 - -[openstack:children] -controller -compute diff --git a/xci/installer/osa/playbooks/configure-opnfvhost.yml b/xci/installer/osa/playbooks/configure-opnfvhost.yml index e2770989..c92abd97 100644 --- a/xci/installer/osa/playbooks/configure-opnfvhost.yml +++ b/xci/installer/osa/playbooks/configure-opnfvhost.yml @@ -26,7 +26,6 @@ file: "{{ item }}" with_items: - "{{ xci_path }}/xci/var/{{ ansible_os_family }}.yml" - - "{{ xci_flavor_ansible_file_path }}/flavor-vars.yml" - name: Set facts for remote deployment set_fact: remote_xci_path: "{{ ansible_env.HOME }}/releng-xci" @@ -74,7 +73,6 @@ - { src: "{{ openstack_osa_path }}/etc/openstack_deploy/env.d", dest: "{{ openstack_osa_etc_path }}" } - { src: "{{ openstack_osa_path }}/etc/openstack_deploy/conf.d", dest: "{{ openstack_osa_etc_path }}" } - { src: "{{ openstack_osa_path }}/etc/openstack_deploy/user_secrets.yml", dest: "{{ openstack_osa_etc_path }}" } - - { src: "{{ remote_xci_flavor_files }}/inventory", dest: "{{ remote_xci_playbooks }}" } - { src: "{{ remote_xci_flavor_files }}/openstack_user_config.yml", dest: "{{ openstack_osa_etc_path }}" } - { src: "{{ remote_xci_flavor_files }}/user_variables.yml", dest: "{{ openstack_osa_etc_path }}" } - { src: "{{ remote_xci_flavor_files }}/ceph.yml", dest: "{{ openstack_osa_etc_path }}/conf.d/", cond: xci_ceph_enabled } diff --git a/xci/installer/osa/playbooks/configure-targethosts.yml b/xci/installer/osa/playbooks/configure-targethosts.yml index cb817cfc..a5d2923c 100644 --- a/xci/installer/osa/playbooks/configure-targethosts.yml +++ b/xci/installer/osa/playbooks/configure-targethosts.yml @@ -17,7 +17,6 @@ file: "{{ item }}" with_items: - "{{ xci_path }}/xci/var/{{ ansible_os_family }}.yml" - - "{{ xci_flavor_ansible_file_path }}/flavor-vars.yml" roles: - role: peru.proxy_settings proxy_settings_http_proxy: "{{ lookup('env','http_proxy') }}" diff --git a/xci/playbooks/dynamic_inventory.py b/xci/playbooks/dynamic_inventory.py new file mode 100755 index 00000000..8f498742 --- /dev/null +++ b/xci/playbooks/dynamic_inventory.py @@ -0,0 +1,153 @@ +#!/usr/bin/python +# coding utf-8 + +# SPDX-license-identifier: Apache-2.0 +############################################################################## +# Copyright (c) 2018 SUSE LINUX GmbH. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +# +# Based on https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/cobbler.py + +import argparse +import os +import sys +import yaml +import json + + +class XCIInventory(object): + def __init__(self): + super(XCIInventory, self).__init__() + self.inventory = {} + self.inventory['all'] = {} + self.inventory['all']['hosts'] = [] + self.inventory['all']['vars'] = {} + self.inventory['_meta'] = {} + self.inventory['_meta']['hostvars'] = {} + self.installer = os.environ.get('INSTALLER_TYPE', 'osa') + self.flavor = os.environ.get('XCI_FLAVOR', 'mini') + + # Static information for opnfv host for now + self.add_host('opnfv') + self.add_hostvar('opnfv', 'ansible_ssh_host', '192.168.122.2') + self.add_to_group('deployment', 'opnfv') + self.add_to_group('opnfv', 'opnfv') + + self.opnfv_networks = {} + self.opnfv_networks['opnfv'] = {} + self.opnfv_networks['opnfv']['admin'] = '172.29.236.10' + self.opnfv_networks['opnfv']['public'] = '192.168.122.2' + self.opnfv_networks['opnfv']['private'] = '172.29.240.10' + self.opnfv_networks['opnfv']['storage'] = '172.29.244.10' + + self.read_pdf_idf() + + self.parse_args() + + if self.args.host: + self.dump(self.get_host_info(self.args.host)) + else: + self.dump(self.inventory) + + def parse_args(self): + parser = argparse.ArgumentParser(description='Produce an Ansible inventory based on PDF/IDF XCI files') + parser.add_argument('--list', action='store_true', default=True, help='List XCI hosts (default: True)') + parser.add_argument('--host', action='store', help='Get all the variables about a specific host') + self.args = parser.parse_args() + + def read_pdf_idf(self): + pdf_file = os.path.dirname(os.path.realpath(__file__)) + "/../var/pdf.yml" + idf_file = os.path.dirname(os.path.realpath(__file__)) + "/../var/idf.yml" + nodes = [] + host_networks = {} + + with open(pdf_file) as f: + try: + pdf = yaml.safe_load(f) + except yaml.YAMLError as e: + print(e) + sys.exit(1) + + with open(idf_file) as f: + try: + idf = yaml.safe_load(f) + except yaml.YAMLError as e: + print(e) + sys.exit(1) + + valid_host = (host for host in idf['xci'][self.installer]['nodes_roles'] \ + if host in idf['xci']['flavors'][self.flavor] \ + and host != 'opnfv') + + for host in valid_host: + nodes.append(host) + hostname = idf['xci'][self.installer]['hostnames'][host] + self.add_host(hostname) + for role in idf['xci'][self.installer]['nodes_roles'][host]: + self.add_to_group(role, hostname) + + pdf_host_info = filter(lambda x: x['name'] == host, pdf['nodes'])[0] + native_vlan_if = filter(lambda x: x['vlan'] == 'native', pdf_host_info['interfaces']) + self.add_hostvar(hostname, 'ansible_host', native_vlan_if[0]['address']) + host_networks[hostname] = {} + # And now record the rest of the information + for network in idf['idf']['net_config'].keys(): + network_interface_num = idf['idf']['net_config'][network]['interface'] + host_networks[hostname][network] = pdf_host_info['interfaces'][int(network_interface_num)]['address'] + + host_networks.update(self.opnfv_networks) + + self.add_groupvar('all', 'host_info', host_networks) + + # Now add the additional groups + for parent in idf['xci'][self.installer]['groups'].keys(): + map(lambda x: self.add_group(x, parent), idf['xci'][self.installer]['groups'][parent]) + + def dump(self, data): + print (json.dumps(data, sort_keys=True, indent=2)) + + def add_host(self, host): + self.inventory['all']['hosts'].append(host) + + def hosts(self): + return self.inventory['all']['hosts'] + + def add_group(self, group, parent = 'all'): + if parent not in self.inventory.keys(): + self.inventory[parent] = {} + if 'children' not in self.inventory[parent]: + self.inventory[parent]['children'] = [] + self.inventory[parent]['children'].append(group) + + def add_to_group(self, group, host): + if group not in self.inventory.keys(): + self.inventory[group] = [] + self.inventory[group].append(host) + + def add_hostvar(self, host, param, value): + if host not in self.hostvars(): + self.inventory['_meta']['hostvars'][host] = {} + self.inventory['_meta']['hostvars'][host].update({param: value}) + + def add_groupvar(self, group, param, value): + if group not in self.groupvars(group): + self.inventory[group]['vars'] = {} + self.inventory[group]['vars'].update({param: value}) + + def hostvars(self): + return iter(self.inventory['_meta']['hostvars'].keys()) + + def groupvars(self, group): + return iter(self.inventory[group]['vars'].keys()) + + def get_host_info(self, host): + return self.inventory['_meta']['hostvars'][host] + +if __name__ == '__main__': + XCIInventory() + +# vim: set ts=4 sw=4 expandtab: diff --git a/xci/playbooks/roles/bootstrap-host/tasks/network_debian.yml b/xci/playbooks/roles/bootstrap-host/tasks/network_debian.yml index ddca58b0..380e4c52 100644 --- a/xci/playbooks/roles/bootstrap-host/tasks/network_debian.yml +++ b/xci/playbooks/roles/bootstrap-host/tasks/network_debian.yml @@ -45,10 +45,10 @@ - { name: "{{ ansible_local.xci.network.xci_interface }}.10", vlan_id: 10 } - { name: "{{ ansible_local.xci.network.xci_interface }}.30", vlan_id: 30 } - { name: "{{ ansible_local.xci.network.xci_interface }}.20", vlan_id: 20 } - - { name: "br-mgmt", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}.10", ip: "{{ host_info[inventory_hostname].MGMT_IP }}", prefix: "255.255.252.0" } - - { name: "br-vxlan", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}.30", ip: "{{ host_info[inventory_hostname].VXLAN_IP }}", prefix: "255.255.252.0" } - - { name: "br-vlan", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}", ip: "{{ host_info[inventory_hostname].VLAN_IP }}", prefix: "255.255.255.0", gateway: "192.168.122.1" } - - { name: "br-storage", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}.20", ip: "{{ host_info[inventory_hostname].STORAGE_IP }}", prefix: "255.255.252.0" } + - { name: "br-mgmt", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}.10", ip: "{{ host_info[inventory_hostname].admin }}", prefix: "255.255.252.0" } + - { name: "br-vxlan", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}.30", ip: "{{ host_info[inventory_hostname].private }}", prefix: "255.255.252.0" } + - { name: "br-vlan", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}", ip: "{{ host_info[inventory_hostname].public }}", prefix: "255.255.255.0", gateway: "192.168.122.1" } + - { name: "br-storage", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}.20", ip: "{{ host_info[inventory_hostname].storage }}", prefix: "255.255.252.0" } loop_control: label: "{{ item.name }}" diff --git a/xci/playbooks/roles/bootstrap-host/tasks/network_redhat.yml b/xci/playbooks/roles/bootstrap-host/tasks/network_redhat.yml index 8c98203a..9dce50b6 100644 --- a/xci/playbooks/roles/bootstrap-host/tasks/network_redhat.yml +++ b/xci/playbooks/roles/bootstrap-host/tasks/network_redhat.yml @@ -17,10 +17,10 @@ - { name: "{{ ansible_local.xci.network.xci_interface }}.10", bridge: "br-mgmt" , vlan_id: 10 } - { name: "{{ ansible_local.xci.network.xci_interface }}.20", bridge: "br-storage", vlan_id: 20 } - { name: "{{ ansible_local.xci.network.xci_interface }}.30", bridge: "br-vxlan" , vlan_id: 30 } - - { name: "br-vlan" , ip: "{{ host_info[inventory_hostname].VLAN_IP }}", prefix: 24 } - - { name: "br-mgmt" , ip: "{{ host_info[inventory_hostname].MGMT_IP }}", prefix: 22 } - - { name: "br-storage", ip: "{{ host_info[inventory_hostname].STORAGE_IP }}", prefix: 22 } - - { name: "br-vxlan" , ip: "{{ host_info[inventory_hostname].VXLAN_IP }}", prefix: 22 } + - { name: "br-vlan" , ip: "{{ host_info[inventory_hostname].public }}", prefix: 24 } + - { name: "br-mgmt" , ip: "{{ host_info[inventory_hostname].admin }}", prefix: 22 } + - { name: "br-storage", ip: "{{ host_info[inventory_hostname].storage }}", prefix: 22 } + - { name: "br-vxlan" , ip: "{{ host_info[inventory_hostname].private}}", prefix: 22 } loop_control: label: "{{ item.name }}" diff --git a/xci/playbooks/roles/bootstrap-host/tasks/network_suse.yml b/xci/playbooks/roles/bootstrap-host/tasks/network_suse.yml index 6ad13169..b1059c81 100644 --- a/xci/playbooks/roles/bootstrap-host/tasks/network_suse.yml +++ b/xci/playbooks/roles/bootstrap-host/tasks/network_suse.yml @@ -17,10 +17,10 @@ - { name: "{{ ansible_local.xci.network.xci_interface }}.10", vlan_id: 10 } - { name: "{{ ansible_local.xci.network.xci_interface }}.30", vlan_id: 30 } - { name: "{{ ansible_local.xci.network.xci_interface }}.20", vlan_id: 20 } - - { name: "br-mgmt", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}.10", ip: "{{ host_info[inventory_hostname].MGMT_IP }}/22" } - - { name: "br-vxlan", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}.30", ip: "{{ host_info[inventory_hostname].VXLAN_IP }}/22" } - - { name: "br-vlan", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}", ip: "{{ host_info[inventory_hostname].VLAN_IP }}/24" } - - { name: "br-storage", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}.20", ip: "{{ host_info[inventory_hostname].STORAGE_IP }}/22" } + - { name: "br-mgmt", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}.10", ip: "{{ host_info[inventory_hostname].admin }}/22" } + - { name: "br-vxlan", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}.30", ip: "{{ host_info[inventory_hostname].private }}/22" } + - { name: "br-vlan", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}", ip: "{{ host_info[inventory_hostname].public }}/24" } + - { name: "br-storage", bridge_ports: "{{ ansible_local.xci.network.xci_interface }}.20", ip: "{{ host_info[inventory_hostname].storage }}/22" } loop_control: label: "{{ item.name }}" -- cgit 1.2.3-korg