From: Viktor Tikkanen Date: Tue, 7 May 2019 14:10:23 +0000 (+0300) Subject: Add seed code for openstack-ansible X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=commitdiff_plain;p=ta%2Fopenstack-ansible.git Add seed code for openstack-ansible Change-Id: I836b82a21eb5f5a46f57ad42be121705f2ac7cbe Signed-off-by: Viktor Tikkanen --- diff --git a/.gitreview b/.gitreview new file mode 100644 index 0000000..a69c304 --- /dev/null +++ b/.gitreview @@ -0,0 +1,5 @@ +[gerrit] +host=gerrit.akraino.org +port=29418 +project=ta/openstack-ansible +defaultremote=origin diff --git a/0001-initial.patch b/0001-initial.patch new file mode 100644 index 0000000..6528332 --- /dev/null +++ b/0001-initial.patch @@ -0,0 +1,10507 @@ +diff --git a/ansible-role-requirements.yml b/ansible-role-requirements.yml +index b2328960..e42ee418 100644 +--- a/ansible-role-requirements.yml ++++ b/ansible-role-requirements.yml +@@ -190,7 +190,3 @@ + scm: git + src: https://github.com/opendaylight/integration-packaging-ansible-opendaylight + version: 4aabce0605ef0f51eef4d6564cc7d779630706c5 +-- name: haproxy_endpoints +- scm: git +- src: https://github.com/logan2211/ansible-haproxy-endpoints +- version: 49901861b16b8afaa9bccdbc649ac956610ff22b +diff --git a/etc/openstack_deploy/env.d/baremetal.yml b/etc/openstack_deploy/env.d/baremetal.yml +new file mode 100644 +index 00000000..70f86788 +--- /dev/null ++++ b/etc/openstack_deploy/env.d/baremetal.yml +@@ -0,0 +1,88 @@ ++--- ++# This file contains an example to show how to set ++# the cinder-volume service to run in a container. ++# ++# Important note: ++# When using LVM or any iSCSI-based cinder backends, such as NetApp with ++# iSCSI protocol, the cinder-volume service *must* run on metal. ++# Reference: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1226855 ++ ++container_skel: ++ cinder_scheduler_container: ++ properties: ++ is_metal: true ++ cinder_api_container: ++ properties: ++ is_metal: true ++ galera_container: ++ properties: ++ is_metal: true ++ glance_container: ++ properties: ++ is_metal: true ++ heat_apis_container: ++ properties: ++ is_metal: true ++ heat_engine_container: ++ properties: ++ is_metal: true ++ horizon_container: ++ properties: ++ is_metal: true ++ ironic_api_container: ++ properties: ++ is_metal: true ++ ironic_conductor_container: ++ properties: ++ is_metal: true ++ ironic_server_container: ++ properties: ++ is_metal: true ++ ironic_compute_container: ++ properties: ++ is_metal: true ++ keystone_container: ++ properties: ++ is_metal: true ++ utility_container: ++ properties: ++ is_metal: true ++ memcached_container: ++ properties: ++ is_metal: true ++ swift_proxy_container: ++ properties: ++ is_metal: true ++ unbound_container: ++ properties: ++ is_metal: true ++ rsyslog_container: ++ properties: ++ is_metal: true ++ rabbit_mq_container: ++ properties: ++ is_metal: true ++ neutron_agents_container: ++ properties: ++ is_metal: true ++ neutron_server_container: ++ properties: ++ is_metal: true ++ nova_api_metadata_container: ++ properties: ++ is_metal: true ++ nova_api_os_compute_container: ++ properties: ++ is_metal: true ++ nova_api_placement_container: ++ properties: ++ is_metal: true ++ nova_conductor_container: ++ properties: ++ is_metal: true ++ nova_scheduler_container: ++ properties: ++ is_metal: true ++ nova_console_container: ++ properties: ++ is_metal: true +diff --git a/etc/openstack_deploy/openstack_user_config.yml.aio_real b/etc/openstack_deploy/openstack_user_config.yml.aio_real +new file mode 100644 +index 00000000..e4df92e6 +--- /dev/null ++++ b/etc/openstack_deploy/openstack_user_config.yml.aio_real +@@ -0,0 +1,276 @@ ++--- ++cidr_networks: ++ container: 172.29.236.0/24 ++ tunnel: 172.29.240.0/24 ++ storage: 172.29.244.0/24 ++ ++used_ips: ++ - "172.29.236.1,172.29.236.50" ++ - "172.29.240.1,172.29.240.50" ++ - "172.29.244.1,172.29.244.50" ++ ++global_overrides: ++ ntp_servers: ++ - "10.20.110.16" ++ # The external IP is quoted simply to ensure that the .aio file can be used as input ++ # dynamic inventory testing. ++ internal_lb_vip_address: "172.29.236.11" ++ external_lb_vip_address: "10.37.44.239" ++ tunnel_bridge: "vlan962" ++ management_bridge: "br-ctlplane" ++ ++ baremetal_images: ++ - name: "golden" ++ file: "/opt/ncio/overcloudimages/guest-image.img" ++ container_format: "bare" ++ disk_format: "raw" ++ - name: "ipa-kernel" ++ file: "/opt/ncio/overcloudimages/ironic-python-agent.kernel" ++ container_format: "aki" ++ disk_format: "aki" ++ - name: "ipa-ramdisk" ++ file: "/opt/ncio/overcloudimages/ironic-python-agent.initramfs" ++ container_format: "ari" ++ disk_format: "ari" ++ ++ baremetal_flavor: ++ - name: "baremetal" ++ ram: 13999 ++ vcpus: 8 ++ disk: 10 ++ extra_specs: ++ "cpu_arch": "x86_64" ++ "capabilities:boot_option": "local" ++ ++ baremetal_networks: ++ - net_name: "provisioning_net" ++ subnet_name: "provisioning_subnet" ++ provider_network_type: "flat" ++ provider_physical_network: "flat" ++ cidr: 172.29.236.0/24 ++ allocation_pool_start: 172.29.236.12 ++ allocation_pool_end: 172.29.236.50 ++ ++ baremetal_ironic_nodes: ++ - name: controller-2 ++ driver: pxe_ipmitool ++ network_interface: flat ++ properties: ++ cpu_arch: "x86_64" ++ cpus: 8 ++ ram: 16384 ++ disk_size: 40 ++ capabilities: "boot_option:local" ++ root_device: ++ name: "/dev/sda" ++ nics: ++ - mac: "24:8A:07:8E:D3:CC" ++ driver_info: ++ power: ++ ipmi_address: 10.38.223.134 ++ ipmi_username: admin ++ ipmi_password: admin ++ - name: controller-3 ++ driver: pxe_ipmitool ++ network_interface: flat ++ properties: ++ cpu_arch: "x86_64" ++ cpus: 8 ++ ram: 16384 ++ disk_size: 40 ++ capabilities: "boot_option:local" ++ root_device: ++ name: "/dev/sda" ++ nics: ++ - mac: "24:8A:07:8E:DE:54" ++ driver_info: ++ power: ++ ipmi_address: 10.38.223.133 ++ ipmi_username: admin ++ ipmi_password: admin ++ - name: compute-1 ++ driver: pxe_ipmitool ++ network_interface: flat ++ properties: ++ cpu_arch: "x86_64" ++ cpus: 8 ++ ram: 16384 ++ disk_size: 40 ++ capabilities: "boot_option:local" ++ root_device: ++ name: "/dev/sda" ++ nics: ++ - mac: "24:8A:07:56:1D:28" ++ driver_info: ++ power: ++ ipmi_address: 10.38.223.132 ++ ipmi_username: admin ++ ipmi_password: admin ++ ++ baremetal_nova_nodes: ++ - node_name: "controller-2" ++ userdata: | ++ #cloud-config ++ users: ++ - name: ncioadmin ++ sudo: ['ALL=(ALL) NOPASSWD:ALL'] ++ ssh-authorized-keys: ++ - "{{ lookup('file', ansible_env.PWD + '/.ssh/id_rsa.pub') }}" ++ flavor_name: "baremetal" ++ image_name: "golden" ++ networks_list: ++ - net-name: "provisioning_net" ++ v4-fixed-ip: "172.29.236.14" ++ - node_name: "controller-3" ++ userdata: | ++ #cloud-config ++ users: ++ - name: ncioadmin ++ sudo: ['ALL=(ALL) NOPASSWD:ALL'] ++ ssh-authorized-keys: ++ - "{{ lookup('file', ansible_env.PWD + '/.ssh/id_rsa.pub') }}" ++ flavor_name: "baremetal" ++ image_name: "golden" ++ networks_list: ++ - net-name: "provisioning_net" ++ v4-fixed-ip: "172.29.236.15" ++ - node_name: "compute-1" ++ userdata: | ++ #cloud-config ++ users: ++ - name: ncioadmin ++ sudo: ['ALL=(ALL) NOPASSWD:ALL'] ++ ssh-authorized-keys: ++ - "{{ lookup('file', ansible_env.PWD + '/.ssh/id_rsa.pub') }}" ++ flavor_name: "baremetal" ++ image_name: "golden" ++ networks_list: ++ - net-name: "provisioning_net" ++ v4-fixed-ip: "172.29.236.16" ++ swift: ++ part_power: 8 ++ storage_network: 'vlan929' ++ replication_network: 'vlan929' ++ drives: ++ - name: swift1.img ++ - name: swift2.img ++ - name: swift3.img ++ mount_point: /srv ++ storage_policies: ++ - policy: ++ name: default ++ index: 0 ++ default: True ++ provider_networks: ++ - network: ++ container_bridge: "br-ctlplane" ++ container_type: "veth" ++ container_interface: "br-ctlplane" ++ host_bind_override: "br-ctlplane" ++ type: "flat" ++ net_name: "flat" ++ is_container_address: true ++ is_ssh_address: true ++ group_binds: ++ - neutron_openvswitch_agent ++ - all_containers ++ - hosts ++ - network: ++ container_bridge: "vlan962" ++ container_type: "veth" ++ container_interface: "vlan962" ++ ip_from_q: "tunnel" ++ type: "vxlan" ++ range: "1:1000" ++ net_name: "vxlan" ++ group_binds: ++ - neutron_openvswitch_agent ++ - network: ++ container_bridge: "vlan929" ++ container_type: "veth" ++ container_interface: "vlan929" ++ ip_from_q: "storage" ++ type: "raw" ++ group_binds: ++ - glance_api ++ - cinder_api ++ - cinder_volume ++ - nova_compute ++ - swift_proxy ++ ++# galera, memcache, rabbitmq, utility ++shared-infra_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ ++log_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ ++haproxy_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++storage-infra_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ ++storage_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ container_vars: ++ cinder_backends: ++ limit_container_types: cinder_volume ++ lvm: ++ volume_group: cinder-volumes ++ volume_driver: cinder.volume.drivers.lvm.LVMVolumeDriver ++ volume_backend_name: LVM_iSCSI ++ iscsi_ip_address: "172.29.236.11" ++image_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++compute-infra_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++orchestration_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++dashboard_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ironic-infra_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++#host from where other nodes are baremetal provisioned ++baremetal-infra_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ ++# Ironic compute hosts. These compute hosts will be used to ++# facilitate ironic's interactions through nova. ++ironic-compute_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++identity_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++# neutron-server, neutron-agents ++network_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++swift-proxy_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ container_vars: ++ swift_proxy_vars: ++ limit_container_types: swift_proxy ++ read_affinity: "r1=100" ++ write_affinity: "r1" ++ write_affinity_node_count: "1 * replicas" ++swift_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ container_vars: ++ swift_vars: ++ limit_container_types: swift ++ zone: 0 ++ region: 1 +diff --git a/etc/openstack_deploy/openstack_user_config.yml.prod.example_real b/etc/openstack_deploy/openstack_user_config.yml.prod.example_real +new file mode 100644 +index 00000000..594104b7 +--- /dev/null ++++ b/etc/openstack_deploy/openstack_user_config.yml.prod.example_real +@@ -0,0 +1,365 @@ ++--- ++cidr_networks: ++ container: 172.29.236.0/24 ++ tunnel: 172.29.240.0/24 ++ storage: 172.29.244.0/24 ++ ++used_ips: ++ - "172.29.236.1,172.29.236.50" ++ - "172.29.240.1,172.29.240.50" ++ - "172.29.244.1,172.29.244.50" ++ ++global_overrides: ++ galera_initial_setup: false ++ ntp_servers: ++ - "10.20.110.16" ++ internal_lb_vip_address: 172.29.236.110 ++ external_lb_vip_address: 10.37.44.242 ++ tunnel_bridge: "vlan962" ++ management_bridge: "br-ctlplane" ++ ++ baremetal_images: ++ - name: "golden" ++ file: "/opt/ncio/overcloudimages/guest-image.img" ++ container_format: "bare" ++ disk_format: "raw" ++ - name: "ipa-kernel" ++ file: "/opt/ncio/overcloudimages/ironic-python-agent.kernel" ++ container_format: "aki" ++ disk_format: "aki" ++ - name: "ipa-ramdisk" ++ file: "/opt/ncio/overcloudimages/ironic-python-agent.initramfs" ++ container_format: "ari" ++ disk_format: "ari" ++ ++ baremetal_flavor: ++ - name: "baremetal" ++ ram: 13999 ++ vcpus: 8 ++ disk: 10 ++ extra_specs: ++ "cpu_arch": "x86_64" ++ "capabilities:boot_option": "local" ++ ++ baremetal_networks: ++ - net_name: "provisioning_net" ++ subnet_name: "provisioning_subnet" ++ provider_network_type: "flat" ++ provider_physical_network: "flat" ++ cidr: 172.29.236.0/24 ++ allocation_pool_start: 172.29.236.14 ++ allocation_pool_end: 172.29.236.50 ++ ++ swift: ++ part_power: 8 ++ storage_network: 'vlan929' ++ replication_network: 'vlan929' ++ drives: ++ - name: swift1.img ++ - name: swift2.img ++ - name: swift3.img ++ mount_point: /srv ++ storage_policies: ++ - policy: ++ name: default ++ index: 0 ++ default: True ++ provider_networks: ++ - network: ++ container_bridge: "br-ctlplane" ++ container_type: "veth" ++ container_interface: "br-ctlplane" ++ host_bind_override: "br-ctlplane" ++ type: "flat" ++ net_name: "flat" ++ is_container_address: true ++ is_ssh_address: true ++ group_binds: ++ - neutron_linuxbridge_agent ++ - all_containers ++ - hosts ++ - network: ++ container_bridge: "vlan962" ++ container_type: "veth" ++ container_interface: "vlan962" ++ ip_from_q: "tunnel" ++ type: "vxlan" ++ range: "1:1000" ++ net_name: "vxlan" ++ group_binds: ++ - neutron_linuxbridge_agent ++ - neutron-openvswitch-agent ++ - network: ++ container_bridge: "vlan929" ++ container_type: "veth" ++ container_interface: "vlan929" ++ ip_from_q: "storage" ++ type: "raw" ++ group_binds: ++ - glance_api ++ - cinder_api ++ - cinder_volume ++ - nova_compute ++ ++### ++### Infrastructure ++### ++ ++baremetal-interface_config_hosts: ++ controller-2: ++ ip: 172.29.236.14 ++ host_vars: ++ os_net_config: ++ network_config: ++ - type: ovs_bridge ++ name: br-ctlplane ++ use_dhcp: false ++ dns_servers: ++ - "172.29.236.11" ++ - "10.102.12.68" ++ addresses: ++ - ip_netmask: 172.29.236.14/24 ++ members: ++ - type: interface ++ primary: true ++ name: ens1f0 ++ ovs_extra: ++ - "br-set-external-id br-ctlplane bridge-id br-ctlplane" ++ - type: vlan ++ use_dhcp: false ++ vlan_id: 929 ++ device: ens1f0 ++ addresses: ++ - ip_netmask: 172.29.244.14/24 ++ - type: vlan ++ use_dhcp: false ++ vlan_id: 962 ++ device: ens1f0 ++ addresses: ++ - ip_netmask: 172.29.240.14/24 ++ - type: vlan ++ use_dhcp: false ++ vlan_id: 900 ++ device: ens1f1 ++ dns_servers: ++ - "10.102.12.68" ++ routes: ++ - ip_netmask: "0.0.0.0/0" ++ next_hop: "10.37.44.225" ++ addresses: ++ - ip_netmask: 10.37.44.240/27 ++ controller-3: ++ ip: 172.29.236.15 ++ host_vars: ++ os_net_config: ++ network_config: ++ - type: ovs_bridge ++ name: br-ctlplane ++ use_dhcp: false ++ dns_servers: ++ - "172.29.236.11" ++ - "10.102.12.68" ++ addresses: ++ - ip_netmask: 172.29.236.15/24 ++ members: ++ - type: interface ++ primary: true ++ name: ens1f0 ++ ovs_extra: ++ - "br-set-external-id br-ctlplane bridge-id br-ctlplane" ++ - type: vlan ++ use_dhcp: false ++ vlan_id: 929 ++ device: ens1f0 ++ addresses: ++ - ip_netmask: 172.29.244.15/24 ++ - type: vlan ++ use_dhcp: false ++ vlan_id: 962 ++ device: ens1f0 ++ addresses: ++ - ip_netmask: 172.29.240.15/24 ++ - type: vlan ++ use_dhcp: false ++ vlan_id: 900 ++ device: ens1f1 ++ dns_servers: ++ - "10.102.12.68" ++ routes: ++ - ip_netmask: "0.0.0.0/0" ++ next_hop: "10.37.44.225" ++ addresses: ++ - ip_netmask: 10.37.44.241/27 ++ compute-1: ++ ip: 172.29.236.16 ++ host_vars: ++ os_net_config: ++ network_config: ++ - type: ovs_bridge ++ name: br-ctlplane ++ use_dhcp: false ++ dns_servers: ++ - "172.29.236.11" ++ addresses: ++ - ip_netmask: 172.29.236.16/24 ++ members: ++ - type: interface ++ primary: true ++ name: ens1f0 ++ ovs_extra: ++ - "br-set-external-id br-ctlplane bridge-id br-ctlplane" ++ - type: vlan ++ use_dhcp: false ++ vlan_id: 929 ++ device: ens1f0 ++ addresses: ++ - ip_netmask: 172.29.244.16/24 ++ - type: vlan ++ use_dhcp: false ++ vlan_id: 962 ++ device: ens1f0 ++ addresses: ++ - ip_netmask: 172.29.240.16/24 ++ ++# galera, memcache, rabbitmq, utility ++shared-infra_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ controller-2: ++ ip: 172.29.236.14 ++ controller-3: ++ ip: 172.29.236.15 ++ ++# load balancer ++# Ideally the load balancer should not use the Infrastructure hosts. ++# Dedicated hardware is best for improved performance and security. ++haproxy_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ controller-2: ++ ip: 172.29.236.14 ++ controller-3: ++ ip: 172.29.236.15 ++ ++### ++### OpenStack ++### ++ ++# keystone ++identity_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ controller-2: ++ ip: 172.29.236.14 ++ controller-3: ++ ip: 172.29.236.15 ++ ++# cinder api services ++storage-infra_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ ++storage_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ container_vars: ++ cinder_backends: ++ limit_container_types: cinder_volume ++ lvm: ++ volume_group: cinder-volumes ++ volume_driver: cinder.volume.drivers.lvm.LVMVolumeDriver ++ volume_backend_name: LVM_iSCSI ++ iscsi_ip_address: "172.29.236.11" ++ ++# nova api, conductor, etc services ++compute-infra_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ controller-2: ++ ip: 172.29.236.14 ++ controller-3: ++ ip: 172.29.236.15 ++ ++# heat ++orchestration_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ controller-2: ++ ip: 172.29.236.14 ++ controller-3: ++ ip: 172.29.236.15 ++ ++# horizon ++dashboard_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ controller-2: ++ ip: 172.29.236.14 ++ controller-3: ++ ip: 172.29.236.15 ++ ++# neutron server, agents (L3, etc) ++network_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ controller-2: ++ ip: 172.29.236.14 ++ controller-3: ++ ip: 172.29.236.15 ++ ++# glance ++# As swift is deployed in this env, Glance uses swift as default backend ++image_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ controller-2: ++ ip: 172.29.236.14 ++ controller-3: ++ ip: 172.29.236.15 ++ ++# nova hypervisors ++compute_hosts: ++ compute-1: ++ ip: 172.29.236.16 ++ ++ironic-infra_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ controller-2: ++ ip: 172.29.236.14 ++ controller-3: ++ ip: 172.29.236.15 ++ ++# Ironic compute hosts. These compute hosts will be used to ++# facilitate ironic's interactions through nova. At the moment ++# there are issues if we have multiple computes. ++ironic-compute_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ ++#Swift ++#swift proxy ++swift-proxy_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ container_vars: ++ swift_proxy_vars: ++ limit_container_types: swift_proxy ++ read_affinity: "r1=100" ++ write_affinity: "r1" ++ write_affinity_node_count: "1 * replicas" ++ ++#swift hosts ++swift_hosts: ++ controller-1: ++ ip: 172.29.236.11 ++ container_vars: ++ swift_vars: ++ limit_container_types: swift ++ zone: 0 ++ region: 1 ++ ++#host from where other nodes are baremetal provisioned ++baremetal-infra_hosts: ++ controller-1: ++ ip: 172.29.236.11 +diff --git a/etc/openstack_deploy/user_variables.yml b/etc/openstack_deploy/user_variables.yml +index d024710d..9d2882fa 100644 +--- a/etc/openstack_deploy/user_variables.yml ++++ b/etc/openstack_deploy/user_variables.yml +@@ -17,10 +17,94 @@ + ### This file contains commonly used overrides for convenience. Please inspect + ### the defaults for each role to find additional override options. + ### ++openstack_service_publicuri_proto: "https" ++openstack_host_specific_kernel_modules: ++ - { name: "ebtables", pattern: "CONFIG_BRIDGE_NF_EBTABLES", group: "network_hosts" } ++ - { name: "openvswitch", pattern: "CONFIG_OPENVSWITCH=", group: "network_hosts" } ++ ++galera_wsrep_sst_method: rsync ++ ++keystone_bin: "/usr/bin" ++keystone_bind_address: "{{ ansible_host }}" ++keystone_wsgi_processes: 1 ++keystone_wsgi_threads: 1 ++ ++glance_bin: "/usr/bin" ++glance_etc_dir: "/etc/glance" ++glance_api_bind_address: "{{ ansible_host }}" ++glance_registry_bind_address: "{{ ansible_host }}" ++glance_wsgi_processes: 1 ++ ++cinder_bin: "/usr/bin" ++cinder_wsgi_processes: 1 ++ ++nova_bin: "/usr/bin" ++nova_wsgi_processes: 1 ++nova_virt_types: ++ ironic: ++ nova_compute_driver: ironic.IronicDriver ++ nova_scheduler_host_manager: ironic_host_manager ++ nova_reserved_host_memory_mb: 0 ++ nova_firewall_driver: nova.virt.firewall.NoopFirewallDriver ++ nova_scheduler_use_baremetal_filters: False ++ nova_scheduler_tracks_instance_changes: False ++ kvm: ++ nova_compute_driver: libvirt.LibvirtDriver ++ nova_scheduler_host_manager: host_manager ++ nova_reserved_host_memory_mb: 2048 ++ nova_firewall_driver: nova.virt.firewall.NoopFirewallDriver ++ nova_scheduler_use_baremetal_filters: False ++ nova_scheduler_tracks_instance_changes: True ++ lxd: ++ nova_compute_driver: lxd.LXDDriver ++ nova_scheduler_host_manager: host_manager ++ nova_reserved_host_memory_mb: 2048 ++ nova_compute_manager: nova.compute.manager.ComputeManager ++ nova_firewall_driver: nova.virt.firewall.NoopFirewallDriver ++ nova_scheduler_use_baremetal_filters: False ++ nova_scheduler_tracks_instance_changes: True ++ qemu: ++ nova_compute_driver: libvirt.LibvirtDriver ++ nova_scheduler_host_manager: host_manager ++ nova_reserved_host_memory_mb: 2048 ++ nova_firewall_driver: nova.virt.firewall.NoopFirewallDriver ++ nova_scheduler_use_baremetal_filters: False ++ nova_scheduler_tracks_instance_changes: True ++ powervm: ++ nova_compute_driver: powervm.driver.PowerVMDriver ++ nova_scheduler_host_manager: host_manager ++ nova_reserved_host_memory_mb: 8192 ++ nova_firewall_driver: nova.virt.firewall.NoopFirewallDriver ++ nova_scheduler_use_baremetal_filters: False ++ nova_scheduler_tracks_instance_changes: True ++ ++ ++neutron_bin: "/usr/bin" ++neutron_bind_address: "{{ ansible_host }}" ++neutron_plugin_type: ml2.ovs ++ ++heat_bin: "/usr/bin" ++heat_wsgi_processes: 1 ++heat_bind_host: "{{ ansible_host }}" ++ ++horizon_bin: "/usr/bin" ++horizon_lib_dir: "{{ horizon_bin | dirname }}/lib/python2.7/site-packages" ++horizon_openstack_dashboard_path: "/usr/share/openstack-dashboard" ++horizon_enable_ironic_ui: False ++ ++swift_bin: "/usr/bin" ++swift_proxy_host: "{{ ansible_host }}" ++ ++ironic_bin: "/usr/bin" ++ironic_service_host: "{{ ansible_host }}" ++ironic_service_names: ++ - "{{ ironic_conductor_program_name }}" ++ - "httpd" ++ironic_standalone: True + + ## Debug and Verbose options. + debug: false +- ++galera_ignore_cluster_state: true + ## Common Glance Overrides + # Set glance_default_store to "swift" if using Cloud Files backend + # or "rbd" if using ceph backend; the latter will trigger ceph to get +@@ -40,7 +124,7 @@ debug: false + # When nova_libvirt_images_rbd_pool is defined, ceph will be installed on nova + # hosts. + # nova_libvirt_images_rbd_pool: vms +- ++nova_console_type: novnc + # If you wish to change the dhcp_domain configured for both nova and neutron + # dhcp_domain: openstacklocal + +@@ -90,7 +174,8 @@ debug: false + # set the rabbitmq_use_ssl variable to 'false'. The default setting of 'true' + # is highly recommended for securing the contents of RabbitMQ messages. + # rabbitmq_use_ssl: false +- ++rabbitmq_use_ssl: false ++haproxy_ssl: true + # RabbitMQ management plugin is enabled by default, the guest user has been + # removed for security reasons and a new userid 'monitoring' has been created + # with the 'monitoring' user tag. In order to modify the userid, uncomment the +@@ -150,7 +235,7 @@ debug: false + # group_vars/all/keepalived.yml) in your user space if necessary. + # + # Uncomment this to disable keepalived installation (cf. documentation) +-# haproxy_use_keepalived: False ++haproxy_use_keepalived: False + # + # HAProxy Keepalived configuration (cf. documentation) + # Make sure that this is set correctly according to the CIDR used for your +@@ -173,3 +258,4 @@ debug: false + + # Keepalived default IP address used to check its alive status (IPv4 only) + # keepalived_ping_address: "193.0.14.129" ++ +diff --git a/etc/openstack_deploy/user_variables.yml_real b/etc/openstack_deploy/user_variables.yml_real +new file mode 100644 +index 00000000..40172b8c +--- /dev/null ++++ b/etc/openstack_deploy/user_variables.yml_real +@@ -0,0 +1,256 @@ ++--- ++# Copyright 2014, Rackspace US, 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. ++ ++### ++### This file contains commonly used overrides for convenience. Please inspect ++### the defaults for each role to find additional override options. ++### ++ ++openstack_host_specific_kernel_modules: ++ - { name: "ebtables", pattern: "CONFIG_BRIDGE_NF_EBTABLES", group: "network_hosts" } ++ - { name: "openvswitch", pattern: "CONFIG_OPENVSWITCH=", group: "network_hosts" } ++ ++openrc_file_dest: "{{ ansible_env.PWD }}/openrc" ++openrc_file_owner: "{{ ansible_env.SUDO_USER }}" ++openrc_file_group: "{{ ansible_env.SUDO_USER }}" ++### neutron specific config ++neutron_ml2_drivers_type: "vxlan" ++galera_wsrep_sst_method: rsync ++ ++#By default rabbitmq_management plugin is enabled in role. Override it with empty value ++rabbitmq_plugins: ++ ++keystone_bin: "/usr/bin" ++keystone_bind_address: "{{ ansible_host }}" ++keystone_wsgi_processes: 1 ++keystone_wsgi_threads: 48 ++ ++glance_bin: "/usr/bin" ++glance_api_bind_address: "{{ ansible_host }}" ++glance_registry_bind_address: "{{ ansible_host }}" ++ ++cinder_bin: "/usr/bin" ++ ++nova_bin: "/usr/bin" ++nova_scheduler_default_filters: "RetryFilter,AvailabilityZoneFilter,RamFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter,AggregateCoreFilter,AggregateDiskFilter" ++nova_virt_types: ++ ironic: ++ nova_compute_driver: ironic.IronicDriver ++ nova_scheduler_host_manager: ironic_host_manager ++ nova_reserved_host_memory_mb: 0 ++ nova_firewall_driver: nova.virt.firewall.NoopFirewallDriver ++ nova_scheduler_use_baremetal_filters: False ++ nova_scheduler_tracks_instance_changes: False ++ kvm: ++ nova_compute_driver: libvirt.LibvirtDriver ++ nova_scheduler_host_manager: host_manager ++ nova_reserved_host_memory_mb: 2048 ++ nova_firewall_driver: nova.virt.firewall.NoopFirewallDriver ++ nova_scheduler_use_baremetal_filters: False ++ nova_scheduler_tracks_instance_changes: True ++ lxd: ++ nova_compute_driver: lxd.LXDDriver ++ nova_scheduler_host_manager: host_manager ++ nova_reserved_host_memory_mb: 2048 ++ nova_compute_manager: nova.compute.manager.ComputeManager ++ nova_firewall_driver: nova.virt.firewall.NoopFirewallDriver ++ nova_scheduler_use_baremetal_filters: False ++ nova_scheduler_tracks_instance_changes: True ++ qemu: ++ nova_compute_driver: libvirt.LibvirtDriver ++ nova_scheduler_host_manager: host_manager ++ nova_reserved_host_memory_mb: 2048 ++ nova_firewall_driver: nova.virt.firewall.NoopFirewallDriver ++ nova_scheduler_use_baremetal_filters: False ++ nova_scheduler_tracks_instance_changes: True ++ powervm: ++ nova_compute_driver: powervm.driver.PowerVMDriver ++ nova_scheduler_host_manager: host_manager ++ nova_reserved_host_memory_mb: 8192 ++ nova_firewall_driver: nova.virt.firewall.NoopFirewallDriver ++ nova_scheduler_use_baremetal_filters: False ++ nova_scheduler_tracks_instance_changes: True ++ ++ ++neutron_bin: "/usr/bin" ++neutron_bind_address: "{{ ansible_host }}" ++ ++heat_bin: "/usr/bin" ++heat_bind_host: "{{ ansible_host }}" ++ ++horizon_bin: "/usr/bin" ++horizon_lib_dir: "{{ horizon_bin | dirname }}/lib/python2.7/site-packages" ++horizon_openstack_dashboard_path: "/usr/share/openstack-dashboard" ++ ++swift_bin: "/usr/bin" ++swift_proxy_host: "{{ ansible_host }}" ++ ++ironic_bin: "/usr/bin" ++ironic_service_host: "{{ ansible_host }}" ++ironic_service_names: ++ - "{{ ironic_conductor_program_name }}" ++ - "httpd" ++ironic_openstack_driver_list: ++ - agent_ipmitool ++ - pxe_ipmitool ++ - pxe_ssh ++ ++## Debug and Verbose options. ++debug: true ++galera_ignore_cluster_state: true ++## Common Glance Overrides ++# Set glance_default_store to "swift" if using Cloud Files backend ++# or "rbd" if using ceph backend; the latter will trigger ceph to get ++# installed on glance. If using a file store, a shared file store is ++# recommended. See the OpenStack-Ansible install guide and the OpenStack ++# documentation for more details. ++# Note that "swift" is automatically set as the default back-end if there ++# are any swift hosts in the environment. Use this setting to override ++# this automation if you wish for a different default back-end. ++# glance_default_store: file ++ ++## Ceph pool name for Glance to use ++# glance_rbd_store_pool: images ++# glance_rbd_store_chunk_size: 8 ++ ++## Common Nova Overrides ++# When nova_libvirt_images_rbd_pool is defined, ceph will be installed on nova ++# hosts. ++# nova_libvirt_images_rbd_pool: vms ++nova_console_type: novnc ++# If you wish to change the dhcp_domain configured for both nova and neutron ++# dhcp_domain: openstacklocal ++ ++## Common Glance Overrides when using a Swift back-end ++# By default when 'glance_default_store' is set to 'swift' the playbooks will ++# expect to use the Swift back-end that is configured in the same inventory. ++# If the Swift back-end is not in the same inventory (ie it is already setup ++# through some other means) then these settings should be used. ++# ++# NOTE: Ensure that the auth version matches your authentication endpoint. ++# ++# NOTE: If the password for glance_swift_store_key contains a dollar sign ($), ++# it must be escaped with an additional dollar sign ($$), not a backslash. For ++# example, a password of "super$ecure" would need to be entered as ++# "super$$ecure" below. See Launchpad Bug #1259729 for more details. ++# ++# glance_swift_store_auth_version: 3 ++# glance_swift_store_auth_address: "https://some.auth.url.com" ++# glance_swift_store_user: "OPENSTACK_TENANT_ID:OPENSTACK_USER_NAME" ++# glance_swift_store_key: "OPENSTACK_USER_PASSWORD" ++# glance_swift_store_container: "NAME_OF_SWIFT_CONTAINER" ++# glance_swift_store_region: "NAME_OF_REGION" ++ ++## Common Ceph Overrides ++# ceph_mons: ++# - 10.16.5.40 ++# - 10.16.5.41 ++# - 10.16.5.42 ++ ++## Custom Ceph Configuration File (ceph.conf) ++# By default, your deployment host will connect to one of the mons defined above to ++# obtain a copy of your cluster's ceph.conf. If you prefer, uncomment ceph_conf_file ++# and customise to avoid ceph.conf being copied from a mon. ++#ceph_conf_file: | ++# [global] ++# fsid = 00000000-1111-2222-3333-444444444444 ++# mon_initial_members = mon1.example.local,mon2.example.local,mon3.example.local ++# mon_host = 10.16.5.40,10.16.5.41,10.16.5.42 ++# # optionally, you can use this construct to avoid defining this list twice: ++# # mon_host = {{ ceph_mons|join(',') }} ++# auth_cluster_required = cephx ++# auth_service_required = cephx ++ ++ ++# By default, openstack-ansible configures all OpenStack services to talk to ++# RabbitMQ over encrypted connections on port 5671. To opt-out of this default, ++# set the rabbitmq_use_ssl variable to 'false'. The default setting of 'true' ++# is highly recommended for securing the contents of RabbitMQ messages. ++# rabbitmq_use_ssl: false ++rabbitmq_use_ssl: false ++haproxy_ssl: false ++# RabbitMQ management plugin is enabled by default, the guest user has been ++# removed for security reasons and a new userid 'monitoring' has been created ++# with the 'monitoring' user tag. In order to modify the userid, uncomment the ++# following and change 'monitoring' to your userid of choice. ++# rabbitmq_monitoring_userid: monitoring ++ ++ ++## Additional pinning generator that will allow for more packages to be pinned as you see fit. ++## All pins allow for package and versions to be defined. Be careful using this as versions ++## are always subject to change and updates regarding security will become your problem from this ++## point on. Pinning can be done based on a package version, release, or origin. Use "*" in the ++## package name to indicate that you want to pin all package to a particular constraint. ++# apt_pinned_packages: ++# - { package: "lxc", version: "1.0.7-0ubuntu0.1" } ++# - { package: "libvirt-bin", version: "1.2.2-0ubuntu13.1.9" } ++# - { package: "rabbitmq-server", origin: "www.rabbitmq.com" } ++# - { package: "*", release: "MariaDB" } ++ ++ ++## Environment variable settings ++# This allows users to specify the additional environment variables to be set ++# which is useful in setting where you working behind a proxy. If working behind ++# a proxy It's important to always specify the scheme as "http://". This is what ++# the underlying python libraries will handle best. This proxy information will be ++# placed both on the hosts and inside the containers. ++ ++## Example environment variable setup: ++# proxy_env_url: http://username:pa$$w0rd@10.10.10.9:9000/ ++# no_proxy_env: "localhost,127.0.0.1,{{ internal_lb_vip_address }},{{ external_lb_vip_address }},{% for host in groups['all_containers'] %}{{ hostvars[host]['container_address'] }}{% if not loop.last %},{% endif %}{% endfor %}" ++# global_environment_variables: ++# HTTP_PROXY: "{{ proxy_env_url }}" ++# HTTPS_PROXY: "{{ proxy_env_url }}" ++# NO_PROXY: "{{ no_proxy_env }}" ++# http_proxy: "{{ proxy_env_url }}" ++# https_proxy: "{{ proxy_env_url }}" ++# no_proxy: "{{ no_proxy_env }}" ++ ++ ++## SSH connection wait time ++# If an increased delay for the ssh connection check is desired, ++# uncomment this variable and set it appropriately. ++#ssh_delay: 5 ++ ++ ++## HAProxy ++# Uncomment this to disable keepalived installation (cf. documentation) ++# haproxy_use_keepalived: False ++# ++# HAProxy Keepalived configuration (cf. documentation) ++# Make sure that this is set correctly according to the CIDR used for your ++# internal and external addresses. ++haproxy_keepalived_external_vip_cidr: "{{external_lb_vip_address}}/32" ++haproxy_keepalived_internal_vip_cidr: "{{internal_lb_vip_address}}/32" ++haproxy_keepalived_external_interface: "vlan900" ++haproxy_keepalived_internal_interface: "br-ctlplane" ++ ++# Defines the default VRRP id used for keepalived with haproxy. ++# Overwrite it to your value to make sure you don't overlap ++# with existing VRRPs id on your network. Default is 10 for the external and 11 for the ++# internal VRRPs ++# haproxy_keepalived_external_virtual_router_id: ++# haproxy_keepalived_internal_virtual_router_id: ++ ++# Defines the VRRP master/backup priority. Defaults respectively to 100 and 20 ++# haproxy_keepalived_priority_master: ++# haproxy_keepalived_priority_backup: ++ ++# Keepalived default IP address used to check its alive status (IPv4 only) ++keepalived_ping_address: "10.37.44.225" ++ ++# All the previous variables are used in a var file, fed to the keepalived role. ++# To use another file to feed the role, override the following var: ++# haproxy_keepalived_vars_file: 'vars/configs/keepalived_haproxy.yml' +diff --git a/inventory/dynamic_inventory.py b/inventory/dynamic_inventory.py +deleted file mode 100755 +index d50940d5..00000000 +--- a/inventory/dynamic_inventory.py ++++ /dev/null +@@ -1,81 +0,0 @@ +-#!/opt/ansible-runtime/bin/python +-# Copyright 2014, Rackspace US, 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. +-# +-# (c) 2014, Kevin Carter +- +-import argparse +-import os +-import sys +- +-try: +- from osa_toolkit import generate +-except ImportError: +- current_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) +- lib_path = os.path.join(current_path, '..') +- sys.path.append(lib_path) +- from osa_toolkit import generate +- +- +-# Function kept in order to use relative pathing for the env.d directory +-def args(arg_list): +- """Setup argument Parsing.""" +- parser = argparse.ArgumentParser( +- usage='%(prog)s', +- description='OpenStack Inventory Generator', +- epilog='Inventory Generator Licensed "Apache 2.0"') +- +- parser.add_argument( +- '--config', +- help='Path containing the user defined configuration files', +- required=False, +- default=None +- ) +- parser.add_argument( +- '--list', +- help='List all entries', +- action='store_true' +- ) +- +- parser.add_argument( +- '--check', +- help="Configuration check only, don't generate inventory", +- action='store_true', +- ) +- +- parser.add_argument( +- '-d', +- '--debug', +- help=('Output debug messages to log file. ' +- 'File is appended to, not overwritten'), +- action='store_true', +- default=False, +- ) +- +- parser.add_argument( +- '-e', +- '--environment', +- help=('Directory that contains the base env.d directory.\n' +- 'Defaults to /inventory/.'), +- required=False, +- default=os.path.dirname(__file__), +- ) +- +- return vars(parser.parse_args(arg_list)) +- +- +-if __name__ == '__main__': +- all_args = args(sys.argv[1:]) +- output = generate.main(**all_args) +- print(output) +diff --git a/inventory/group_vars/all/glance.yml b/inventory/group_vars/all/glance.yml +index bd39c8fb..b8766a24 100644 +--- a/inventory/group_vars/all/glance.yml ++++ b/inventory/group_vars/all/glance.yml +@@ -18,7 +18,7 @@ glance_service_proto: http + glance_service_publicuri_proto: "{{ openstack_service_publicuri_proto | default(glance_service_proto) }}" + glance_service_adminuri_proto: "{{ openstack_service_adminuri_proto | default(glance_service_proto) }}" + glance_service_internaluri_proto: "{{ openstack_service_internaluri_proto | default(glance_service_proto) }}" +-glance_service_publicuri: "{{ glance_service_publicuri_proto }}://{{ external_lb_vip_address }}:{{ glance_service_port }}" ++glance_service_publicuri: "{{ glance_service_publicuri_proto }}://{{ external_lb_vip_address | ipwrap }}:{{ glance_service_port }}" + glance_service_publicurl: "{{ glance_service_publicuri }}" + glance_service_internaluri: "{{ glance_service_internaluri_proto }}://{{ internal_lb_vip_address }}:{{ glance_service_port }}" + glance_service_internalurl: "{{ glance_service_internaluri }}" +diff --git a/inventory/group_vars/all/keystone.yml b/inventory/group_vars/all/keystone.yml +index bbd1238b..e515e563 100644 +--- a/inventory/group_vars/all/keystone.yml ++++ b/inventory/group_vars/all/keystone.yml +@@ -50,5 +50,5 @@ keystone_service_publicuri_insecure: |- + {% set _insecure = not (keystone_user_ssl_cert is defined or haproxy_user_ssl_cert is defined) %} + {% endif %} + {{ _insecure }} +-keystone_service_publicuri: "{{ keystone_service_publicuri_proto }}://{{ external_lb_vip_address }}:{{ keystone_service_port }}" ++keystone_service_publicuri: "{{ keystone_service_publicuri_proto }}://{{ external_lb_vip_address | ipwrap }}:{{ keystone_service_port }}" + keystone_service_publicurl: "{{ keystone_service_publicuri }}/v3" +diff --git a/inventory/group_vars/all/ssl.yml b/inventory/group_vars/all/ssl.yml +index 9ff527b1..241fe8aa 100644 +--- a/inventory/group_vars/all/ssl.yml ++++ b/inventory/group_vars/all/ssl.yml +@@ -18,4 +18,4 @@ + # services running behind Apache (currently, Horizon and Keystone). + ssl_protocol: "ALL -SSLv2 -SSLv3" + # Cipher suite string from https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ +-ssl_cipher_suite: "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS" ++ssl_cipher_suite: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DH-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:RSA+AESGCM:!LOW:!aNULL:!eNULL:!MD5:!DSS" +diff --git a/inventory/group_vars/aodh_all.yml b/inventory/group_vars/aodh_all.yml +index 9ce0ecd3..8e693782 100644 +--- a/inventory/group_vars/aodh_all.yml ++++ b/inventory/group_vars/aodh_all.yml +@@ -21,7 +21,7 @@ aodh_connection_string: "mysql+pymysql://{{ aodh_galera_user }}:{{ aodh_containe + aodh_rabbitmq_host_group: "{{ rabbitmq_host_group }}" + + aodh_service_in_ldap: "{{ service_ldap_backend_enabled }}" +-aodh_service_publicuri: "{{ openstack_service_publicuri_proto|default(aodh_service_proto) }}://{{ external_lb_vip_address }}:{{ aodh_service_port }}" ++aodh_service_publicuri: "{{ openstack_service_publicuri_proto|default(aodh_service_proto) }}://{{ external_lb_vip_address | ipwrap }}:{{ aodh_service_port }}" + + # Ensure that the package state matches the global setting + aodh_package_state: "{{ package_state }}" +diff --git a/inventory/group_vars/cinder_all.yml b/inventory/group_vars/cinder_all.yml +index 5a79789a..7fe14155 100644 +--- a/inventory/group_vars/cinder_all.yml ++++ b/inventory/group_vars/cinder_all.yml +@@ -55,7 +55,7 @@ cinder_glance_service_port: "{{ glance_service_port }}" + # If there are Swift hosts in the environment, then use it as the default Glance store + # This is specifically duplicated from glance_all for the cinder_glance_api_version + # setting below. +-glance_default_store: "{{ ((groups['swift_all'] is defined) and (groups['swift_all'] | length > 0)) | ternary('swift', 'file') }}" ++#glance_default_store: "{{ ((groups['swift_all'] is defined) and (groups['swift_all'] | length > 0)) | ternary('swift', 'file') }}" + + # cinder_backend_lvm_inuse: True if current host has an lvm backend + cinder_backend_lvm_inuse: '{{ (cinder_backends|default("")|to_json).find("cinder.volume.drivers.lvm.LVMVolumeDriver") != -1 }}' +diff --git a/inventory/group_vars/galera_all.yml b/inventory/group_vars/galera_all.yml +index e70a42d9..07348f63 100644 +--- a/inventory/group_vars/galera_all.yml ++++ b/inventory/group_vars/galera_all.yml +@@ -30,7 +30,7 @@ galera_disable_privatedevices: "{{ ((properties.is_metal | default(false)) | boo + # By default galera_monitoring xinetd app is open to 0.0.0.0/0 + # This makes sure the monitoring is only restricted to the necessary nodes: + # the load balancers, and the galera nodes. +-galera_monitoring_allowed_source: "{% for node in groups['galera_all'] + groups['haproxy_all'] %}{{ hostvars[node]['ansible_host'] }} {% endfor %} 127.0.0.1" ++galera_monitoring_allowed_source: "{% if groups['haproxy'] | default([]) | length > 0 %} {% for node in groups['galera_all'] + groups['haproxy_all'] %}{{ hostvars[node]['ansible_host'] }} {% endfor %} 127.0.0.1 {% else %} {% for node in groups['galera_all'] %}{{ hostvars[node]['ansible_host'] }} {% endfor %} 127.0.0.1 {% endif %}" + + # Galera sessions are long lived, so if we do endpoint maintenance we will + # force kill the sessions to force a failover to the active endpoint. +diff --git a/inventory/group_vars/haproxy/haproxy.yml b/inventory/group_vars/haproxy/haproxy.yml +index 7f9fac88..d881be9f 100644 +--- a/inventory/group_vars/haproxy/haproxy.yml ++++ b/inventory/group_vars/haproxy/haproxy.yml +@@ -22,11 +22,6 @@ keepalived_selinux_compile_rules: + # Ensure that the package state matches the global setting + haproxy_package_state: "{{ package_state }}" + +-haproxy_whitelist_networks: +- - 192.168.0.0/16 +- - 172.16.0.0/12 +- - 10.0.0.0/8 +- + haproxy_galera_whitelist_networks: "{{ haproxy_whitelist_networks }}" + haproxy_glance_registry_whitelist_networks: "{{ haproxy_whitelist_networks }}" + haproxy_keystone_admin_whitelist_networks: "{{ haproxy_whitelist_networks }}" +@@ -53,36 +48,6 @@ haproxy_default_services: + - "httpchk HEAD / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck" + haproxy_whitelist_networks: "{{ haproxy_galera_whitelist_networks }}" + haproxy_service_enabled: "{{ groups['galera_all'] is defined and groups['galera_all'] | length > 0 }}" +- - service: +- haproxy_service_name: repo_git +- haproxy_backend_nodes: "{{ groups['repo_all'] | default([]) }}" +- haproxy_bind: "{{ [internal_lb_vip_address] }}" +- haproxy_port: 9418 +- haproxy_balance_type: tcp +- haproxy_backend_options: +- - tcp-check +- haproxy_whitelist_networks: "{{ haproxy_repo_git_whitelist_networks }}" +- haproxy_service_enabled: "{{ groups['repo_all'] is defined and groups['repo_all'] | length > 0 }}" +- - service: +- haproxy_service_name: repo_all +- haproxy_backend_nodes: "{{ groups['repo_all'] | default([]) }}" +- haproxy_bind: "{{ [internal_lb_vip_address] }}" +- haproxy_port: 8181 +- haproxy_balance_type: http +- haproxy_backend_options: +- - "httpchk HEAD / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck" +- haproxy_service_enabled: "{{ groups['repo_all'] is defined and groups['repo_all'] | length > 0 }}" +- - service: +- haproxy_service_name: repo_cache +- haproxy_backend_nodes: "{{ (groups['repo_all'] | default([]))[:1] }}" # list expected +- haproxy_backup_nodes: "{{ (groups['repo_all'] | default([]))[1:] }}" +- haproxy_bind: "{{ [internal_lb_vip_address] }}" +- haproxy_port: "{{ repo_pkg_cache_port }}" +- haproxy_balance_type: http +- haproxy_backend_options: +- - "httpchk HEAD /acng-report.html HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck" +- haproxy_whitelist_networks: "{{ haproxy_repo_cache_whitelist_networks }}" +- haproxy_service_enabled: "{{ groups['repo_all'] is defined and groups['repo_all'] | length > 0 }}" + - service: + haproxy_service_name: glance_api + haproxy_backend_nodes: "{{ groups['glance_api'] | default([]) }}" +@@ -187,9 +152,9 @@ haproxy_default_services: + haproxy_port: 8780 + haproxy_balance_type: http + haproxy_backend_options: +- - "httpchk GET / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck" ++ - "httpchk GET /placement HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck" + haproxy_backend_httpcheck_options: +- - "expect status 200" ++ - "expect status 401" + haproxy_whitelist_networks: "{{ haproxy_nova_placement_whitelist_networks }}" + haproxy_service_enabled: "{{ groups['nova_api_placement'] is defined and groups['nova_api_placement'] | length > 0 }}" + - service: +@@ -197,14 +162,12 @@ haproxy_default_services: + haproxy_backend_nodes: "{{ groups['nova_console'] | default([]) }}" + haproxy_ssl: "{{ haproxy_ssl }}" + haproxy_port: "{{ hostvars[(groups['nova_console'] | default(['localhost']))[0] | default('localhost')]['nova_console_port'] | default(6082) }}" +- haproxy_balance_type: http ++ haproxy_balance_type: tcp + haproxy_timeout_client: 60m + haproxy_timeout_server: 60m + haproxy_balance_alg: source + haproxy_backend_options: +- - "httpchk HEAD / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck" +- haproxy_backend_httpcheck_options: +- - "expect status 404" ++ - tcp-check + haproxy_service_enabled: "{{ groups['nova_console'] is defined and groups['nova_console'] | length > 0 }}" + - service: + haproxy_service_name: cinder_api +@@ -219,7 +182,7 @@ haproxy_default_services: + haproxy_service_name: horizon + haproxy_backend_nodes: "{{ groups['horizon_all'] | default([]) }}" + haproxy_ssl: "{{ haproxy_ssl }}" +- haproxy_ssl_all_vips: true ++ haproxy_ssl_all_vips: false + haproxy_port: "{{ haproxy_ssl | ternary(443,80) }}" + haproxy_backend_port: 80 + haproxy_redirect_http_port: 80 +@@ -270,7 +233,8 @@ haproxy_default_services: + haproxy_service_name: rabbitmq_mgmt + haproxy_backend_nodes: "{{ groups['rabbitmq'] | default([]) }}" + haproxy_ssl: "{{ haproxy_ssl }}" +- haproxy_port: 15672 ++ haproxy_bind: "{{ [internal_lb_vip_address] }}" ++ haproxy_port: 5672 + haproxy_balance_type: http + haproxy_backend_options: + - "httpchk HEAD / HTTP/1.0\\r\\nUser-agent:\\ osa-haproxy-healthcheck" +diff --git a/inventory/group_vars/haproxy/keepalived.yml b/inventory/group_vars/haproxy/keepalived.yml +index 977f8ee3..fdf2b70d 100644 +--- a/inventory/group_vars/haproxy/keepalived.yml ++++ b/inventory/group_vars/haproxy/keepalived.yml +@@ -13,7 +13,6 @@ + # See the License for the specific language governing permissions and + # limitations under the License. + +-keepalived_ping_address: "193.0.14.129" + keepalived_ping_count: 1 + keepalived_ping_interval: 10 + keepalived_ubuntu_src: "native" +@@ -36,7 +35,7 @@ keepalived_scripts: + haproxy_check_script: + check_script: "/bin/kill -0 `cat /var/run/haproxy.pid`" + pingable_check_script: +- check_script: "/bin/ping -c {{ keepalived_ping_count }} {{ keepalived_ping_address }} 1>&2" ++ check_script: "/bin/ping -c {{ keepalived_ping_count }} {{ keepalived_ping_address | default('193.0.14.129') }} 1>&2" + interval: "{{ keepalived_ping_interval }}" + fall: 2 + rise: 4 +diff --git a/osa_toolkit/manage.py b/osa_toolkit/manage.py +index 5237dfae..9f4322d9 100644 +--- a/osa_toolkit/manage.py ++++ b/osa_toolkit/manage.py +@@ -1,4 +1,4 @@ +-#!/opt/ansible-runtime/bin/python ++#!/usr/bin/env python + # + # Copyright 2014, Rackspace US, Inc. + # +diff --git a/playbooks/ansible-conf-update.yml b/playbooks/ansible-conf-update.yml +new file mode 100644 +index 00000000..213abee7 +--- /dev/null ++++ b/playbooks/ansible-conf-update.yml +@@ -0,0 +1,15 @@ ++- name: Ansible config update ++ hosts: [ management ] ++ gather_facts: True ++ become: yes ++ become_method: sudo ++ become_user: root ++ tasks: ++ - name: Change ansible configuration ++ ini_file: ++ path: "/etc/ansible/ansible.cfg" ++ section: "{{item.section}}" ++ option: "{{item.option}}" ++ value: "{{item.value}}" ++ with_items: ++ - { section: ssh_connection, option: "control_path", value: "%(directory)s/%%h" } +diff --git a/tests/test-inventory.ini b/playbooks/bootstrap-inventory.ini +similarity index 100% +rename from tests/test-inventory.ini +rename to playbooks/bootstrap-inventory.ini +diff --git a/playbooks/bootstrap-kvm-contorller-1-vars.yml b/playbooks/bootstrap-kvm-contorller-1-vars.yml +new file mode 100644 +index 00000000..73b7b976 +--- /dev/null ++++ b/playbooks/bootstrap-kvm-contorller-1-vars.yml +@@ -0,0 +1,40 @@ ++aio_hostname: "controller-1" ++bootstrap_host_loopback_cinder_size: 8 ++bootstrap_host_loopback_swift_size: 8 ++bootstrap_host_data_disk_min_size: 10 ++bootstrap_env_file: "{{ bootstrap_host_aio_config_path }}/env.d/baremetal.yml" ++sudo_user: "ncioadmin" ++# password: ncioadmin ++# Generated with command "openssl passwd -1 -salt ncioadmin ncioadmin" ++sudo_user_password: "$1$ncioadmi$vDa1mNhcMDKMBSI27RqW51" ++power_contorl_ssh_priv_key: "/tmp/id_rsa" ++os_net_config: ++ network_config: ++ - type: ovs_bridge ++ name: br-ctlplane ++ use_dhcp: false ++ dns_servers: ++ - "10.102.12.68" ++ addresses: ++ - ip_netmask: 172.29.236.11/24 ++ members: ++ - type: interface ++ primary: true ++ name: eth0 ++ ovs_extra: ++ - "br-set-external-id br-ctlplane bridge-id br-ctlplane" ++ - type: vlan ++ use_dhcp: false ++ vlan_id: 10 ++ device: eth0 ++ addresses: ++ - ip_netmask: 172.29.244.11/24 ++ - type: vlan ++ use_dhcp: false ++ vlan_id: 20 ++ device: eth0 ++ addresses: ++ - ip_netmask: 172.29.240.11/24 ++ - type: interface ++ use_dhcp: true ++ name: eth1 +diff --git a/playbooks/bootstrap-physical-contorller-1-vars.yml b/playbooks/bootstrap-physical-contorller-1-vars.yml +new file mode 100644 +index 00000000..f16defb0 +--- /dev/null ++++ b/playbooks/bootstrap-physical-contorller-1-vars.yml +@@ -0,0 +1,47 @@ ++aio_hostname: "controller-1" ++bootstrap_host_loopback_cinder_size: 8 ++bootstrap_host_loopback_swift_size: 8 ++bootstrap_host_data_disk_min_size: 10 ++bootstrap_env_file: "{{ bootstrap_host_aio_config_path }}/env.d/baremetal.yml" ++sudo_user: "ncioadmin" ++# password: ncioadmin ++# Generated with command "openssl passwd -1 -salt ncioadmin ncioadmin" ++sudo_user_password: "$1$ncioadmi$vDa1mNhcMDKMBSI27RqW51" ++bootstrap_host_aio_config_name: "openstack_user_config.yml.aio_real" ++bootstrap_host_user_variables_filename: "user_variables.yml_real" ++os_net_config: ++ network_config: ++ - type: ovs_bridge ++ name: br-ctlplane ++ use_dhcp: false ++ addresses: ++ - ip_netmask: 172.29.236.11/24 ++ members: ++ - type: interface ++ primary: true ++ name: ens255f0 ++ ovs_extra: ++ - "br-set-external-id br-ctlplane bridge-id br-ctlplane" ++ - type: vlan ++ use_dhcp: false ++ vlan_id: 978 ++ device: ens4f0 ++ addresses: ++ - ip_netmask: 172.29.244.11/24 ++ - type: vlan ++ use_dhcp: false ++ vlan_id: 1002 ++ device: ens4f0 ++ addresses: ++ - ip_netmask: 172.29.240.11/24 ++ - type: vlan ++ use_dhcp: false ++ vlan_id: 902 ++ device: ens4f0 ++ dns_servers: ++ - "10.39.12.252" ++ routes: ++ - ip_netmask: "0.0.0.0/0" ++ next_hop: "10.39.172.254" ++ addresses: ++ - ip_netmask: 10.39.172.10/24 +diff --git a/playbooks/ceph-install.yml b/playbooks/ceph-install.yml +index 088a71c1..bdb2aa98 100644 +--- a/playbooks/ceph-install.yml ++++ b/playbooks/ceph-install.yml +@@ -15,7 +15,6 @@ + + - name: Install ceph mons + hosts: ceph-mon +- user: root + pre_tasks: + - include: common-tasks/os-log-dir-setup.yml + vars: +@@ -121,7 +120,6 @@ + + - name: Install ceph osds + hosts: ceph-osd +- user: root + pre_tasks: + - include: common-tasks/os-log-dir-setup.yml + vars: +diff --git a/playbooks/common-playbooks/cinder.yml b/playbooks/common-playbooks/cinder.yml +index ca8a991d..f4d59f1f 100644 +--- a/playbooks/common-playbooks/cinder.yml ++++ b/playbooks/common-playbooks/cinder.yml +@@ -17,7 +17,6 @@ + hosts: "{{ cinder_hosts }}" + serial: "{{ cinder_serial }}" + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - cinder +diff --git a/playbooks/common-playbooks/glance.yml b/playbooks/common-playbooks/glance.yml +index f16fa1ee..21babc7b 100644 +--- a/playbooks/common-playbooks/glance.yml ++++ b/playbooks/common-playbooks/glance.yml +@@ -17,7 +17,6 @@ + hosts: "{{ glance_hosts }}" + serial: "{{ glance_serial }}" + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - glance +diff --git a/playbooks/common-playbooks/neutron.yml b/playbooks/common-playbooks/neutron.yml +index a9c7402c..bbcc7b41 100644 +--- a/playbooks/common-playbooks/neutron.yml ++++ b/playbooks/common-playbooks/neutron.yml +@@ -17,7 +17,6 @@ + hosts: "{{ neutron_hosts }}" + serial: "{{ neutron_serial }}" + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - neutron +@@ -88,6 +87,7 @@ + neutron_overlay_network: "{{ _overlay_network }}" + neutron_provider_networks: "{{ _provider_networks }}" + neutron_local_ip: "{{ tunnel_address }}" ++ when: (reinitialized_nodes is not defined and scaled_out_nodes is not defined) or (reinitialized_nodes is defined and hostname in reinitialized_nodes) or (scaled_out_nodes is defined and hostname in scaled_out_nodes) + + - role: "bird" + when: +diff --git a/playbooks/common-playbooks/nova.yml b/playbooks/common-playbooks/nova.yml +index 20fa5ea5..fb8c800a 100644 +--- a/playbooks/common-playbooks/nova.yml ++++ b/playbooks/common-playbooks/nova.yml +@@ -17,7 +17,6 @@ + hosts: "{{ nova_hosts }}" + serial: "{{ nova_serial }}" + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + vars_files: + - ../defaults/repo_packages/nova_consoles.yml +diff --git a/playbooks/common-tasks/mysql-db-user.yml b/playbooks/common-tasks/mysql-db-user.yml +index 237140f3..fb54a1de 100644 +--- a/playbooks/common-tasks/mysql-db-user.yml ++++ b/playbooks/common-tasks/mysql-db-user.yml +@@ -36,6 +36,6 @@ + priv: "{{ db_name }}.*:ALL" + append_privs: "{{ db_append_privs | default(omit) }}" + delegate_to: "{{ groups['galera_all'][0] }}" +- with_items: "{{ grant_list | default(['localhost', '%']) }}" ++ with_items: "{{ grant_list | default(['localhost', '%', galera_address, ansible_host]) }}" + tags: + - common-mysql +diff --git a/playbooks/dump_vars.yaml b/playbooks/dump_vars.yaml +new file mode 100644 +index 00000000..d38b7de1 +--- /dev/null ++++ b/playbooks/dump_vars.yaml +@@ -0,0 +1,6 @@ ++--- ++- name: dumping vars ++ hosts: base ++ tasks: ++ - name: Dump all vars ++ action: template src=dumpall.j2 dest=/tmp/ansible.all +diff --git a/playbooks/dumpall.j2 b/playbooks/dumpall.j2 +new file mode 100644 +index 00000000..e1264a30 +--- /dev/null ++++ b/playbooks/dumpall.j2 +@@ -0,0 +1,19 @@ ++Module Variables ("vars"): ++-------------------------------- ++{{ vars | to_nice_json }} ++ ++Environment Variables ("environment"): ++-------------------------------- ++{{ environment | to_nice_json }} ++ ++GROUP NAMES Variables ("group_names"): ++-------------------------------- ++{{ group_names | to_nice_json }} ++ ++GROUPS Variables ("groups"): ++-------------------------------- ++{{ groups | to_nice_json }} ++ ++HOST Variables ("hostvars"): ++-------------------------------- ++{{ hostvars | to_nice_json }} +diff --git a/playbooks/etcd-install.yml b/playbooks/etcd-install.yml +index 762fa019..03b9785e 100644 +--- a/playbooks/etcd-install.yml ++++ b/playbooks/etcd-install.yml +@@ -16,7 +16,6 @@ + - name: Install etcd server cluster + hosts: etcd_all + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + - include: common-tasks/unbound-clients.yml +diff --git a/playbooks/galera-install.yml b/playbooks/galera-install.yml +index b7a0d2b3..d339343e 100644 +--- a/playbooks/galera-install.yml ++++ b/playbooks/galera-install.yml +@@ -12,27 +12,30 @@ + # 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. ++# cmframework.requires: initial_poweroff_hosts.yml, memcached-install.yml + + - name: Galera container config + hosts: galera_all + gather_facts: "{{ osa_gather_facts | default(True) }}" + serial: 1 +- user: root + tasks: + - include: common-tasks/os-log-dir-setup.yml + vars: + log_dirs: + - src: "/openstack/log/{{ inventory_hostname }}-mysql_logs" + dest: "/var/log/mysql_logs" ++ when: reinitialized_nodes is not defined or (reinitialized_nodes is defined and hostname in reinitialized_nodes) + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + vars: + list_of_bind_mounts: "{{ galera_container_bind_mounts }}" + extra_container_config_no_restart: + - "lxc.start.order=10" ++ when: reinitialized_nodes is not defined or (reinitialized_nodes is defined and hostname in reinitialized_nodes) + - include: common-tasks/unbound-clients.yml + static: no + when: + - hostvars['localhost']['resolvconf_enabled'] | bool ++ - reinitialized_nodes is not defined or (reinitialized_nodes is defined and hostname in reinitialized_nodes) + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - galera +@@ -41,17 +44,9 @@ + hosts: galera_all + gather_facts: "{{ osa_gather_facts | default(True) }}" + serial: 1 +- user: root + roles: +- - role: haproxy_endpoints +- haproxy_state: disabled +- static: no +- when: "groups['haproxy'] | default([]) | length > 0" + - role: "galera_server" +- - role: haproxy_endpoints +- haproxy_state: enabled +- static: no +- when: "groups['haproxy'] | default([]) | length > 0" ++ when: reinitialized_nodes is not defined or (reinitialized_nodes is defined and hostname in reinitialized_nodes) + - role: "rsyslog_client" + rsyslog_client_log_rotate_file: galera_log_rotate + rsyslog_client_log_dir: "/var/log/mysql_logs" +@@ -61,12 +56,29 @@ + rsyslog_client_config_name: "99-galera-rsyslog-client.conf" + tags: + - rsyslog ++ when: reinitialized_nodes is not defined or (reinitialized_nodes is defined and hostname in reinitialized_nodes) + - role: "system_crontab_coordination" + tags: + - crontab ++ when: reinitialized_nodes is not defined or (reinitialized_nodes is defined and hostname in reinitialized_nodes) + vars: + galera_server_id: "{{ inventory_hostname | string_2_int }}" + galera_wsrep_node_name: "{{ container_name }}" + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - galera ++ ++- name: Verify Galera cluster count. ++ hosts: baremetal-infra_hosts ++ tasks: ++ - set_fact: ++ given_cluster_count: "{{ groups['galera_all'] | count }}" ++ ++ - name: Check the mysql cluster count ++ shell: mysql -e 'show status like "%wsrep_cluster_%";' | awk -F "wsrep_cluster_size" {'print $2'} |tr -d " \t\n\r" ++ register: cluster_count ++ until: cluster_count|success ++ failed_when: cluster_count.stdout != given_cluster_count ++ tags: ++ - galera ++ +diff --git a/playbooks/haproxy-install.yml b/playbooks/haproxy-install.yml +index 49eaf35b..bf16e237 100644 +--- a/playbooks/haproxy-install.yml ++++ b/playbooks/haproxy-install.yml +@@ -12,11 +12,11 @@ + # 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. ++# cmframework.requires: baremetal-interface-config.yml,provisioning_done.yml + + - name: haproxy base config + hosts: haproxy + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + - include: common-tasks/os-log-dir-setup.yml +@@ -28,12 +28,48 @@ + static: no + when: + - hostvars['localhost']['resolvconf_enabled'] | bool +- roles: +- - role: "keepalived" +- when: haproxy_use_keepalived | bool +- tags: +- - keepalived + environment: "{{ deployment_environment_variables | default({}) }}" ++ ++ tasks: ++ - name: Check if hasmanager is enabled ++ stat: ++ path: "/usr/lib/systemd/system/hasmanager.service" ++ register: stat_hasmanager ++ ++ - name: Fetch external IPs on RTE ++ shell: "ip a s {{haproxy_keepalived_external_interface}} | grep inet | awk -F ' ' {'print $2'}" ++ register: extipresult ++ ++ - name: Add External IPv4 VIP on installation controller ++ command: "ip a a {{external_lb_vip_address}}/32 dev {{haproxy_keepalived_external_interface}}" ++ when: ++ - installation_controller == inventory_hostname ++ - haproxy_use_keepalived == False ++ - stat_hasmanager.stat.exists == False ++ - external_lb_vip_address + '/32' not in extipresult.stdout_lines ++ - (external_lb_vip_address | ipv4) ++ ++ - name: Add External IPv6 VIP on installation controller ++ command: "ip a a {{external_lb_vip_address}}/128 dev {{haproxy_keepalived_external_interface}}" ++ when: ++ - installation_controller == inventory_hostname ++ - haproxy_use_keepalived == False ++ - stat_hasmanager.stat.exists == False ++ - external_lb_vip_address + '/128' not in extipresult.stdout_lines ++ - (external_lb_vip_address | ipv6) ++ ++ - name: Fetch internal IPs on RTE ++ shell: "ip -4 a s {{haproxy_keepalived_internal_interface}} | grep inet | awk -F ' ' {'print $2'}" ++ register: intipresult ++ ++ - name: Add Internal VIP on installation controller ++ command: "ip a a {{internal_lb_vip_address}}/32 dev {{haproxy_keepalived_internal_interface}}" ++ when: ++ - installation_controller == inventory_hostname ++ - haproxy_use_keepalived == False ++ - stat_hasmanager.stat.exists == False ++ - internal_lb_vip_address + '/32' not in intipresult.stdout_lines ++ + tags: + - haproxy-config + - haproxy +@@ -41,7 +77,6 @@ + - name: Install haproxy + hosts: haproxy + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - name: Remove legacy haproxy configuration files + file: +diff --git a/playbooks/hosts_config.yml b/playbooks/hosts_config.yml +new file mode 100644 +index 00000000..9e6970fa +--- /dev/null ++++ b/playbooks/hosts_config.yml +@@ -0,0 +1,33 @@ ++--- ++# Copyright 2014, Rackspace US, 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. ++# cmframework.requires: baremetal-interface-config.yml ++ ++- name: Setup /etc/hosts file ++ hosts: lxc_hosts ++ tasks: ++ - name: Fix /etc/hosts ++ lineinfile: ++ dest: /etc/hosts ++ state: present ++ line: "{{ hostvars[item]['ansible_host'] }} {{ hostvars[item]['ansible_hostname'] }} {{ hostvars[item]['ansible_hostname'].split('.')[0] }}" ++ with_items: "{{ groups['all'] }}" ++ when: ++ - item != 'localhost' ++ - name: Ensure localhost /etc/hosts entry is correct ++ lineinfile: ++ dest: /etc/hosts ++ state: present ++ line: '127.0.0.1 localhost' ++ regexp: '^127.0.0.1' +diff --git a/playbooks/memcached-install.yml b/playbooks/memcached-install.yml +index aa37e616..7e3e5b67 100644 +--- a/playbooks/memcached-install.yml ++++ b/playbooks/memcached-install.yml +@@ -12,11 +12,11 @@ + # 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. ++# cmframework.requires: baremetal-interface-config.yml + + - name: Install memcached + hosts: memcached + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + - include: common-tasks/os-log-dir-setup.yml +diff --git a/playbooks/ntp-config.yml b/playbooks/ntp-config.yml +new file mode 100644 +index 00000000..6360f977 +--- /dev/null ++++ b/playbooks/ntp-config.yml +@@ -0,0 +1,40 @@ ++--- ++# Copyright 2014, Rackspace US, 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. ++# cmframework.requires: baremetal-interface-config.yml ++ ++- name: Configure NTP service on controllers ++ hosts: shared-infra_hosts ++ gather_facts: "{{ gather_facts | default(True) }}" ++ max_fail_percentage: 20 ++ tasks: ++ - name: Set Timezone ++ timezone: ++ name: "{{ time.zone }}" ++ roles: ++ - role: "ntp" ++ ntp_config_server: "{{ ntp_servers }}" ++ ++- name: Configure NTP service on base hosts ++ hosts: [ base ] ++ gather_facts: "{{ gather_facts | default(True) }}" ++ max_fail_percentage: 20 ++ tasks: ++ - name: Set Timezone ++ timezone: ++ name: "{{ time.zone }}" ++ roles: ++ - role: "ntp" ++ ntp_config_server: "{{ groups['galera_all'] }}" ++ when: ansible_hostname not in groups['management'] +diff --git a/playbooks/openstack-hosts-setup.yml b/playbooks/openstack-hosts-setup.yml +index 4979b635..4f9405cc 100644 +--- a/playbooks/openstack-hosts-setup.yml ++++ b/playbooks/openstack-hosts-setup.yml +@@ -22,7 +22,6 @@ + - name: Install Ansible prerequisites + hosts: "{{ openstack_host_group|default('hosts') }}" + gather_facts: false +- user: root + pre_tasks: + - name: Ensure python is installed + register: result +@@ -39,7 +38,6 @@ + - name: Basic host setup + hosts: "{{ openstack_host_group|default('hosts') }}" + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - name: Check for a supported Operating System + assert: +diff --git a/playbooks/os-aodh-install.yml b/playbooks/os-aodh-install.yml +index 311f63c6..a3c91573 100644 +--- a/playbooks/os-aodh-install.yml ++++ b/playbooks/os-aodh-install.yml +@@ -13,10 +13,10 @@ + # See the License for the specific language governing permissions and + # limitations under the License. + ++# cmframework.requires: os-horizon-install.yml + - name: Install the aodh components + hosts: aodh_all + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + - include: common-tasks/rabbitmq-vhost-user.yml +@@ -48,6 +48,7 @@ + - hostvars['localhost']['resolvconf_enabled'] | bool + roles: + - role: "os_aodh" ++ when: (reinitialized_nodes is not defined and scaled_out_nodes is not defined) or (reinitialized_nodes is defined and hostname in reinitialized_nodes) or (scaled_out_nodes is defined and hostname in scaled_out_nodes) + - role: "openstack_openrc" + tags: + - openrc +diff --git a/playbooks/os-barbican-install.yml b/playbooks/os-barbican-install.yml +index 3f433894..2b5203d2 100644 +--- a/playbooks/os-barbican-install.yml ++++ b/playbooks/os-barbican-install.yml +@@ -16,7 +16,6 @@ + - name: Installation and setup of barbican + hosts: barbican_all + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + - include: common-tasks/rabbitmq-vhost-user.yml +diff --git a/playbooks/os-ceilometer-install.yml b/playbooks/os-ceilometer-install.yml +index 745a9b37..58b08bb5 100644 +--- a/playbooks/os-ceilometer-install.yml ++++ b/playbooks/os-ceilometer-install.yml +@@ -16,7 +16,6 @@ + - name: Install the ceilometer components + hosts: ceilometer_all + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + - include: common-tasks/rabbitmq-vhost-user.yml +diff --git a/playbooks/os-cinder-install.yml b/playbooks/os-cinder-install.yml +index 23f83b8e..09194d7e 100644 +--- a/playbooks/os-cinder-install.yml ++++ b/playbooks/os-cinder-install.yml +@@ -12,11 +12,11 @@ + # 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. ++# cmframework.requires: memcached-install.yml,galera-install.yml,rabbitmq-install.yml,rsyslog-install.yml,os-keystone-install.yml,os-glance-install.yml,os-nova-install.yml,os-neutron-install.yml + + - name: Prepare MQ/DB services + hosts: cinder_all + gather_facts: no +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - cinder +@@ -96,7 +96,6 @@ + - name: Refresh local facts after all software changes are made + hosts: cinder_all + gather_facts: no +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - cinder +@@ -139,7 +138,6 @@ + hosts: cinder_backup,cinder_volume,cinder_scheduler + gather_facts: no + serial: "{{ cinder_backend_serial | default(['1', '100%']) }}" +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - cinder +@@ -164,7 +162,6 @@ + hosts: cinder_api + gather_facts: no + serial: "{{ cinder_api_serial | default(['1','100%']) }}" +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - cinder +@@ -203,7 +200,6 @@ + - name: Perform online database migrations + hosts: cinder_api[0] + gather_facts: no +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - cinder +diff --git a/playbooks/os-designate-install.yml b/playbooks/os-designate-install.yml +index ed3b81da..a5174ea5 100644 +--- a/playbooks/os-designate-install.yml ++++ b/playbooks/os-designate-install.yml +@@ -19,7 +19,6 @@ + - name: Install designate server + hosts: designate_all + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + - include: common-tasks/rabbitmq-vhost-user.yml +diff --git a/playbooks/os-glance-install.yml b/playbooks/os-glance-install.yml +index fdd2b1c2..3f46655e 100644 +--- a/playbooks/os-glance-install.yml ++++ b/playbooks/os-glance-install.yml +@@ -12,11 +12,11 @@ + # 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. ++# cmframework.requires: memcached-install.yml,galera-install.yml,rabbitmq-install.yml,rsyslog-install.yml,os-keystone-install.yml + + - name: Prepare MQ/DB services + hosts: glance_all + gather_facts: no +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - glance +@@ -80,7 +80,6 @@ + - name: Refresh local facts after all software changes are made + hosts: glance_all + gather_facts: no +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - glance +@@ -122,7 +121,6 @@ + hosts: glance_api + gather_facts: no + serial: "{{ glance_api_serial | default(['1','100%']) }}" +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - glance +diff --git a/playbooks/os-gnocchi-install.yml b/playbooks/os-gnocchi-install.yml +index 247ffa23..bbad3819 100644 +--- a/playbooks/os-gnocchi-install.yml ++++ b/playbooks/os-gnocchi-install.yml +@@ -15,7 +15,6 @@ + + - name: Install Gnocchi components + hosts: gnocchi_all +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + static: no +diff --git a/playbooks/os-heat-install.yml b/playbooks/os-heat-install.yml +index aabcde88..eb0c1cde 100644 +--- a/playbooks/os-heat-install.yml ++++ b/playbooks/os-heat-install.yml +@@ -12,11 +12,11 @@ + # 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. ++# cmframework.requires: memcached-install.yml,galera-install.yml,rabbitmq-install.yml,rsyslog-install.yml,os-keystone-install.yml,os-glance-install.yml,os-nova-install.yml,os-neutron-install.yml,os-swift-install.yml,os-ironic-install.yml + + - name: Install heat server + hosts: heat_all + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + - include: common-tasks/rabbitmq-vhost-user.yml +diff --git a/playbooks/os-horizon-install.yml b/playbooks/os-horizon-install.yml +index bc538938..5020e9e9 100644 +--- a/playbooks/os-horizon-install.yml ++++ b/playbooks/os-horizon-install.yml +@@ -12,11 +12,11 @@ + # 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. ++# cmframework.requires: memcached-install.yml,galera-install.yml,rabbitmq-install.yml,rsyslog-install.yml,os-keystone-install.yml,os-glance-install.yml,os-nova-install.yml,os-neutron-install.yml,os-swift-install.yml,os-ironic-install.yml,os-heat-install.yml + + - name: Install horizon server + hosts: horizon_all + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + - include: common-tasks/os-log-dir-setup.yml +@@ -38,6 +38,7 @@ + - hostvars['localhost']['resolvconf_enabled'] | bool + roles: + - role: "os_horizon" ++ when: (reinitialized_nodes is not defined and scaled_out_nodes is not defined) or (reinitialized_nodes is defined and hostname in reinitialized_nodes) or (scaled_out_nodes is defined and hostname in scaled_out_nodes) + - role: "rsyslog_client" + rsyslog_client_log_rotate_file: horizon_log_rotate + rsyslog_client_log_dir: "/var/log/horizon" +diff --git a/playbooks/os-ironic-install.yml b/playbooks/os-ironic-install.yml +index 6c869687..c174c704 100644 +--- a/playbooks/os-ironic-install.yml ++++ b/playbooks/os-ironic-install.yml +@@ -1,3 +1,4 @@ ++#cmframework.requires: haproxy-install.yml, rabbitmq-install.yml, os-keystone-install.yml + --- + # Copyright 2016, Rackspace, Inc. + # +@@ -12,11 +13,11 @@ + # 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. ++# cmframework.requires: memcached-install.yml,galera-install.yml,rabbitmq-install.yml,rsyslog-install.yml,os-keystone-install.yml,os-glance-install.yml,os-nova-install.yml,os-neutron-install.yml,os-swift-install.yml + + - name: Installation and setup of Ironic +- hosts: ironic_all ++ hosts: baremetal_management_nodes + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + - include: common-tasks/rabbitmq-vhost-user.yml +diff --git a/playbooks/os-keystone-install.yml b/playbooks/os-keystone-install.yml +index 7d1d9a37..6de4cdb6 100644 +--- a/playbooks/os-keystone-install.yml ++++ b/playbooks/os-keystone-install.yml +@@ -12,11 +12,11 @@ + # 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. ++# cmframework.requires: memcached-install.yml,galera-install.yml,rabbitmq-install.yml,rsyslog-install.yml + + - name: Prepare MQ/DB services + hosts: keystone_all + gather_facts: no +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - keystone +@@ -62,7 +62,6 @@ + hosts: keystone_all + serial: "{{ keystone_serial | default(['1', '100%']) }}" + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - keystone +@@ -117,6 +116,7 @@ + + roles: + - role: "os_keystone" ++ when: (reinitialized_nodes is not defined and scaled_out_nodes is not defined) or ((reinitialized_nodes is defined) and ((reinitialized_nodes | intersect(groups['keystone_all'])) | length > 0)) or (scaled_out_nodes is defined and hostname in scaled_out_nodes) + - role: "openstack_openrc" + tags: + - openrc +@@ -150,7 +150,6 @@ + - name: Finalise data migrations if required + hosts: keystone_all + gather_facts: no +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - keystone +diff --git a/playbooks/os-magnum-install.yml b/playbooks/os-magnum-install.yml +index 37d3eb56..743a8131 100644 +--- a/playbooks/os-magnum-install.yml ++++ b/playbooks/os-magnum-install.yml +@@ -18,7 +18,6 @@ + + - name: Install magnum server + hosts: magnum_all +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + - include: common-tasks/os-log-dir-setup.yml +diff --git a/playbooks/os-neutron-install.yml b/playbooks/os-neutron-install.yml +index 43288f7f..b9e71250 100644 +--- a/playbooks/os-neutron-install.yml ++++ b/playbooks/os-neutron-install.yml +@@ -12,6 +12,7 @@ + # 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. ++# cmframework.requires: memcached-install.yml,galera-install.yml,rabbitmq-install.yml,rsyslog-install.yml,os-keystone-install.yml,os-glance-install.yml,os-nova-install.yml + + - name: Configure Neutron dynamic host groupings + hosts: localhost +@@ -29,7 +30,6 @@ + - name: Prepare MQ/DB services + hosts: neutron_all + gather_facts: no +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - neutron +diff --git a/playbooks/os-nova-install.yml b/playbooks/os-nova-install.yml +index be6414e9..129dbe3f 100644 +--- a/playbooks/os-nova-install.yml ++++ b/playbooks/os-nova-install.yml +@@ -12,11 +12,11 @@ + # 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. ++# cmframework.requires: memcached-install.yml,galera-install.yml,rabbitmq-install.yml,rsyslog-install.yml,os-keystone-install.yml,os-glance-install.yml + + - name: Prepare MQ/DB services + hosts: nova_conductor + gather_facts: no +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - nova +@@ -125,7 +125,6 @@ + - name: Refresh local facts after all software changes are made + hosts: nova_all + gather_facts: no +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - nova +@@ -170,7 +169,6 @@ + hosts: "nova_all:!nova_api_placement:!nova_console" + gather_facts: no + serial: "{{ nova_serial | default('100%') }}" +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - nova +@@ -194,7 +192,6 @@ + hosts: "nova_api_placement:nova_console" + gather_facts: no + serial: "{{ nova_api_serial | default(['1', '100%']) }}" +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - nova +@@ -214,7 +211,6 @@ + - name: Perform online database migrations + hosts: nova_conductor + gather_facts: no +- user: root + environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - nova +diff --git a/playbooks/os-rally-install.yml b/playbooks/os-rally-install.yml +index 2fef255d..b961ab9d 100644 +--- a/playbooks/os-rally-install.yml ++++ b/playbooks/os-rally-install.yml +@@ -16,7 +16,6 @@ + - name: Installation and setup of Rally + hosts: utility_all + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: common-tasks/unbound-clients.yml + static: no +diff --git a/playbooks/os-sahara-install.yml b/playbooks/os-sahara-install.yml +index 09dc410b..b7e0fcb0 100644 +--- a/playbooks/os-sahara-install.yml ++++ b/playbooks/os-sahara-install.yml +@@ -14,7 +14,6 @@ + - name: Install sahara server + hosts: sahara_all + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + - include: common-tasks/rabbitmq-vhost-user.yml +diff --git a/playbooks/os-swift-install.yml b/playbooks/os-swift-install.yml +index 87c11de9..5974ebef 100644 +--- a/playbooks/os-swift-install.yml ++++ b/playbooks/os-swift-install.yml +@@ -12,11 +12,11 @@ + # 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. ++# cmframework.requires: memcached-install.yml,galera-install.yml,rabbitmq-install.yml,rsyslog-install.yml,os-keystone-install.yml,os-glance-install.yml,os-nova-install.yml,os-neutron-install.yml + + - name: Installation and setup of Swift + hosts: swift_all:swift_remote_all + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + vars: +@@ -59,7 +59,6 @@ + + - name: Installation and setup of Swift + hosts: swift_all +- user: root + roles: + - role: "rsyslog_client" + rsyslog_client_log_rotate_file: swift_log_rotate +diff --git a/playbooks/os-swift-sync.yml b/playbooks/os-swift-sync.yml +index 7d9f7a2e..eafadca2 100644 +--- a/playbooks/os-swift-sync.yml ++++ b/playbooks/os-swift-sync.yml +@@ -18,7 +18,6 @@ + - name: Synchronisation of swift ring and ssh keys + hosts: swift_all:swift_remote_all + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + roles: + - role: "os_swift" + swift_do_setup: False +diff --git a/playbooks/os-tempest-install.yml b/playbooks/os-tempest-install.yml +index e8b45434..6493107c 100644 +--- a/playbooks/os-tempest-install.yml ++++ b/playbooks/os-tempest-install.yml +@@ -16,7 +16,6 @@ + - name: Installation and setup of Tempest + hosts: utility_all[0] + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + roles: + - role: "os_tempest" + - role: "rsyslog_client" +diff --git a/playbooks/os-trove-install.yml b/playbooks/os-trove-install.yml +index d62e7125..64635664 100644 +--- a/playbooks/os-trove-install.yml ++++ b/playbooks/os-trove-install.yml +@@ -19,7 +19,6 @@ + - name: Install trove server + hosts: trove_all + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + - include: common-tasks/rabbitmq-vhost-user.yml +diff --git a/playbooks/presetup-playbook.yml b/playbooks/presetup-playbook.yml +new file mode 100644 +index 00000000..0c01a6a1 +--- /dev/null ++++ b/playbooks/presetup-playbook.yml +@@ -0,0 +1,19 @@ ++- name: Presetup tasks for installation controller node ++ hosts: localhost ++ gather_facts: True ++ user: root ++ tasks: ++ - name: Change ansible configuration ++ ini_file: ++ path: "/etc/ansible/ansible.cfg" ++ section: "{{item.section}}" ++ option: "{{item.option}}" ++ value: "{{item.value}}" ++ with_items: ++ - { section: defaults, option: "hash_behaviour", value: "merge" } ++ - { section: defaults, option: "forks", value: 50 } ++ - { section: ssh_connection, option: "control_path", value: "%(directory)s/%%h" } ++ ++ - name: Setup hostname for Installation controller. ++ hostname: ++ name: "{{ installation_controller }}" +diff --git a/playbooks/rabbitmq-install.yml b/playbooks/rabbitmq-install.yml +index 8920e407..a38f205b 100644 +--- a/playbooks/rabbitmq-install.yml ++++ b/playbooks/rabbitmq-install.yml +@@ -12,12 +12,12 @@ + # 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. ++# cmframework.requires: memcached-install.yml,galera-install.yml,rabbitmq-remove-reinitialized.yml + + - name: Create and configure rabbitmq container + hosts: "{{ rabbitmq_host_group | default('rabbitmq_all') }}" + serial: 1 + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + static: +@@ -38,7 +38,6 @@ + # http://www.rabbitmq.com/clustering.html#upgrading + - name: Stop RabbitMQ nodes that are not the upgrader + hosts: "{{ rabbitmq_host_group | default('rabbitmq_all') }}[1:]" +- user: root + tasks: + - name: "Stop RabbitMQ" + service: +@@ -49,7 +48,6 @@ + - name: Install rabbitmq server + hosts: "{{ rabbitmq_host_group | default('rabbitmq_all') }}" + serial: 20% +- user: root + roles: + - role: "rabbitmq_server" + - role: "rsyslog_client" +@@ -64,7 +62,6 @@ + + - name: Ensure rabbitmq user for monitoring GUI + hosts: "{{ rabbitmq_host_group | default('rabbitmq_all') }}[0]" +- user: root + tasks: + - name: Create rabbitmq user for monitoring GUI + rabbitmq_user: +diff --git a/playbooks/rabbitmq-remove-reinitialized.yml b/playbooks/rabbitmq-remove-reinitialized.yml +new file mode 100644 +index 00000000..5bed7aed +--- /dev/null ++++ b/playbooks/rabbitmq-remove-reinitialized.yml +@@ -0,0 +1,12 @@ ++#cmframework.requires: provisioning_done.yml ++--- ++- name: Remove reinitialized nodes from rabbitmq ++ hosts: [management] ++ tasks: ++ - shell: | ++ /sbin/rabbitmqctl cluster_status | grep {{item.key}} ++ if [ $? -eq 0 ]; then ++ /sbin/rabbitmqctl forget_cluster_node rabbit@{{item.key}} ++ fi ++ with_dict: "{{ reinitialized_nodes }}" ++ when: reinitialized_nodes is defined and inventory_hostname == installation_controller +diff --git a/playbooks/repo-server.yml b/playbooks/repo-server.yml +index ddb70b31..31b4c4b4 100644 +--- a/playbooks/repo-server.yml ++++ b/playbooks/repo-server.yml +@@ -16,7 +16,6 @@ + - name: Setup repo servers + hosts: repo_all + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + pre_tasks: + + - include: common-tasks/set-upper-constraints.yml +diff --git a/playbooks/rsyslog-install.yml b/playbooks/rsyslog-install.yml +index 03a1b706..aa332669 100644 +--- a/playbooks/rsyslog-install.yml ++++ b/playbooks/rsyslog-install.yml +@@ -12,30 +12,9 @@ + # 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. ++# cmframework.requires: memcached-install.yml,galera-install.yml,rabbitmq-install.yml + + - name: Install rsyslog + hosts: rsyslog +- gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root +- pre_tasks: +- - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" +- vars: +- list_of_bind_mounts: +- - bind_dir_path: "{{ rsyslog_server_storage_directory }}" +- mount_path: "/openstack/{{ inventory_hostname }}/log-storage" +- extra_container_config_no_restart: +- - "lxc.start.order=19" +- - include: common-tasks/unbound-clients.yml +- static: no +- when: +- - hostvars['localhost']['resolvconf_enabled'] | bool +- roles: +- - role: "rsyslog_server" +- tags: +- - rsyslog +- - role: "system_crontab_coordination" +- tags: +- - crontab +- environment: "{{ deployment_environment_variables | default({}) }}" + tags: + - rsyslog +diff --git a/playbooks/security-hardening.yml b/playbooks/security-hardening.yml +index 156aca8e..c9839738 100644 +--- a/playbooks/security-hardening.yml ++++ b/playbooks/security-hardening.yml +@@ -20,7 +20,6 @@ + - name: Apply security hardening configurations + hosts: "{{ security_host_group|default('hosts') }}" + gather_facts: "{{ osa_gather_facts | default(True) }}" +- user: root + roles: + - role: "ansible-hardening" + when: apply_security_hardening | bool +diff --git a/playbooks/setup-infrastructure.yml b/playbooks/setup-infrastructure.yml +index 81f45499..dd4cec57 100644 +--- a/playbooks/setup-infrastructure.yml ++++ b/playbooks/setup-infrastructure.yml +@@ -13,17 +13,16 @@ + # See the License for the specific language governing permissions and + # limitations under the License. + +-- include: unbound-install.yml +-- include: repo-install.yml ++#- include: unbound-install.yml + - include: haproxy-install.yml + # TODO(evrardjp): Remove the following when repo_build is done + # before lxc_container_create, and haproxy is moved with it as + # second step. + - include: repo-use.yml +-- include: utility-install.yml ++#- include: utility-install.yml + - include: memcached-install.yml + - include: galera-install.yml + - include: rabbitmq-install.yml +-- include: etcd-install.yml +-- include: ceph-install.yml ++#- include: etcd-install.yml ++#- include: ceph-install.yml + - include: rsyslog-install.yml +diff --git a/tests/roles/bootstrap-host/templates/user_variables_translations.yml.j2 b/playbooks/setup-playbook.yml +similarity index 61% +rename from tests/roles/bootstrap-host/templates/user_variables_translations.yml.j2 +rename to playbooks/setup-playbook.yml +index 82cf3703..3685b5d8 100644 +--- a/tests/roles/bootstrap-host/templates/user_variables_translations.yml.j2 ++++ b/playbooks/setup-playbook.yml +@@ -1,5 +1,5 @@ + --- +-# Copyright 2017, Logan Vig ++# Copyright 2015, Rackspace US, Inc. + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. +@@ -13,10 +13,10 @@ + # See the License for the specific language governing permissions and + # limitations under the License. + +-# Trove settings for translations site. +-trove_provider_net_name: flat-db +-trove_service_net_phys_net: flat-db +-trove_service_net_setup: True +-trove_service_net_subnet_cidr: "172.29.232.0/22" +-trove_service_net_allocation_pool_start: "172.29.233.110" +-trove_service_net_allocation_pool_end: "172.29.233.200" ++- name: Bootstrap the controller-1 node ++ hosts: all:!localhost ++ gather_facts: True ++ user: root ++ roles: ++ - role: "secretsextend" ++ - role: "bootstrap-host" +diff --git a/playbooks/utility-install.yml b/playbooks/utility-install.yml +index b58fa142..9040a5f2 100644 +--- a/playbooks/utility-install.yml ++++ b/playbooks/utility-install.yml +@@ -15,7 +15,6 @@ + + - name: Setup the utility location(s) + hosts: utility_all +- user: root + pre_tasks: + - include: "common-tasks/os-{{ container_tech | default('lxc') }}-container-setup.yml" + +diff --git a/scripts/openstack-ansible b/scripts/openstack-ansible +new file mode 100755 +index 00000000..6295b2df +--- /dev/null ++++ b/scripts/openstack-ansible +@@ -0,0 +1,67 @@ ++#!/usr/bin/env bash ++# Copyright 2014, Rackspace US, 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. ++# ++# (c) 2014, Kevin Carter ++ ++# OpenStack wrapper tool to ease the use of ansible with multiple variable files. ++ ++export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin" ++ ++function info() { ++ if [ "${ANSIBLE_NOCOLOR:-0}" -eq "1" ]; then ++ echo -e "${@}" ++ else ++ echo -e "\e[0;35m${@}\e[0m" ++ fi ++} ++ ++# Figure out which Ansible binary was executed ++RUN_CMD=$(basename ${0}) ++ ++# Apply the OpenStack-Ansible configuration selectively. ++if [[ "${PWD}" == *"/opt/openstack-ansible"* ]] || [ "${RUN_CMD}" == "openstack-ansible" ]; then ++ ++ # Source the Ansible configuration. ++ . /usr/local/bin/openstack-ansible.rc ++ ++ # Check whether there are any user configuration files ++ if ls -1 /etc/openstack_deploy/user_*.yml &> /dev/null; then ++ ++ # Discover the variable files. ++ VAR1="$(for i in $(ls /etc/openstack_deploy/user_*.yml); do echo -ne "-e @$i "; done)" ++ fi ++ ++else ++ ++ # If you're not executing 'openstack-ansible' and are ++ # not in the OSA git clone root, then do not source ++ # the configuration and do not add extra vars. ++ VAR1="" ++ ++fi ++ ++VAR1=${VAR1}" --skip-tags pip,install-apt,install-yum,memcached_server-install,haproxy_package-install,galera-server-pip-packages,galera-gpg-keys,galera-repos,galera-pre-yum-packages,galera-client-install,galera_server-install,rabbitmq-yum-packages,rabbitmq-plugin-config,common-log,bird,rsyslog-yum-packages,glance-install,cinder-install,nova-install,nova-pip-packages,nova-novnc-git,calico-pip-packages,dragonflow-pip-packages,neutron-pkg-install,heat-pkg-install,horizon-pkg-install,swift-pkg-install,swift-chk-hashes,ironic-l2,ironic-pkg-install,ceph-install,package-install -e @/etc/openstack_deploy/env.d/baremetal.yml -e @/etc/openstack_deploy/user_variables.yml -e @/etc/openstack_deploy/user_secrets.yml" ++ ++# Provide information on the discovered variables. ++info "Variable files: \"${VAR1}\"" ++ ++SKIP_OPTS="" ++ ++# Execute the Ansible command. ++if [ "${RUN_CMD}" == "openstack-ansible" ] || [ "${RUN_CMD}" == "ansible-playbook" ]; then ++ /usr/bin/ansible-playbook "${@}" ${VAR1} ${SKIP_OPTS} ++else ++ /usr/bin/${RUN_CMD} "${@}" ${SKIP_OPTS} ++fi +diff --git a/scripts/openstack-ansible.rc b/scripts/openstack-ansible.rc +index a24c4a42..e8796964 100644 +--- a/scripts/openstack-ansible.rc ++++ b/scripts/openstack-ansible.rc +@@ -14,12 +14,15 @@ + + export ANSIBLE_RETRY_FILES_ENABLED="${ANSIBLE_RETRY_FILES_ENABLED:-False}" + +-export ANSIBLE_INVENTORY="${ANSIBLE_INVENTORY:-OSA_INVENTORY_PATH/dynamic_inventory.py,/etc/openstack_deploy/inventory.ini}" ++export ANSIBLE_INVENTORY="${ANSIBLE_INVENTORY:-/opt/openstack-ansible/inventory}" + + export ANSIBLE_LOG_PATH="${ANSIBLE_LOG_PATH:-/openstack/log/ansible-logging/ansible.log}" +-mkdir -p "$(dirname ${ANSIBLE_LOG_PATH})" || unset ANSIBLE_LOG_PATH ++sudo mkdir -p "$(dirname ${ANSIBLE_LOG_PATH})" || true ++sudo chmod o+rx /openstack/log || true ++sudo chown $USER:$USER "$(dirname ${ANSIBLE_LOG_PATH})" || unset ANSIBLE_LOG_PATH + +-export ANSIBLE_ROLES_PATH="${ANSIBLE_ROLES_PATH:-/etc/ansible/roles:OSA_PLAYBOOK_PATH/roles:/etc/ansible/roles/ceph-ansible/roles}" ++ ++export ANSIBLE_ROLES_PATH="${ANSIBLE_ROLES_PATH:-/etc/ansible/roles:roles:/opt/openstack-ansible/playbooks/roles}" + + export ANSIBLE_LIBRARY="${ANSIBLE_LIBRARY:-/etc/ansible/roles/plugins/library}" + export ANSIBLE_LOOKUP_PLUGINS="${ANSIBLE_LOOKUP_PLUGINS:-/etc/ansible/roles/plugins/lookup}" +@@ -58,5 +61,5 @@ export ANSIBLE_FORCE_HANDLERS="${ANSIBLE_FORCE_HANDLERS:-True}" + # Allow the usage of userspace group_vars host_vars with user + # defined precedence until this behavior is merged in the + # inventory +-export GROUP_VARS_PATH="${GROUP_VARS_PATH:-OSA_GROUP_VARS_DIR:/etc/openstack_deploy/group_vars/}" +-export HOST_VARS_PATH="${HOST_VARS_PATH:-OSA_HOST_VARS_DIR:/etc/openstack_deploy/host_vars/}" ++export GROUP_VARS_PATH="${GROUP_VARS_PATH:-/opt/openstack-ansible/inventory/group_vars/}" ++export HOST_VARS_PATH="${HOST_VARS_PATH:-/opt/openstack-ansible/inventory/host_vars/}" +diff --git a/scripts/pw-token-gen.py b/scripts/pw-token-gen.py +index 6638d027..ed47c79f 100755 +--- a/scripts/pw-token-gen.py ++++ b/scripts/pw-token-gen.py +@@ -1,4 +1,4 @@ +-#!/opt/ansible-runtime/bin/python ++#!/usr/bin/env python + # Copyright 2014, Rackspace US, Inc. + # + # Licensed under the Apache License, Version 2.0 (the "License"); +@@ -86,7 +86,7 @@ class CredentialGenerator(object): + + :param encoded_bytes: ``str`` must be at least 64 charters long + """ +- return encoded_bytes[:random.randrange(16, 64)] ++ return "Z-"+encoded_bytes[:random.randrange(14, 62)] + + def _token_gen(self, encoded_bytes): + """Returns ``str`` with a length between 48 and 64. +@@ -189,7 +189,7 @@ def main(): + print('Creating backup file [ %s ]' % user_vars_tar_file) + # Create a tarball if needed + with tarfile.open(user_vars_tar_file, 'a') as tar: +- os.chmod(user_vars_tar_file, 0o600) ++ os.chmod(user_vars_tar_file, 0o644) + basename = os.path.basename(user_vars_file) + # Time stamp the password file in UTC + utctime = datetime.datetime.utcnow() +@@ -198,7 +198,7 @@ def main(): + tar.add(user_vars_file, arcname=backup_name) + + with open(user_vars_file, 'w') as f: +- os.chmod(user_vars_file, 0o600) ++ os.chmod(user_vars_file, 0o644) + f.write( + yaml.safe_dump( + user_vars, +diff --git a/scripts/setup-controller.sh b/scripts/setup-controller.sh +new file mode 100755 +index 00000000..3dcbf4bf +--- /dev/null ++++ b/scripts/setup-controller.sh +@@ -0,0 +1,47 @@ ++#!/usr/bin/env bash ++# ++# Copyright 2014, Rackspace US, 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. ++ ++## Shell Opts ---------------------------------------------------------------- ++set -e -u ++export ANSIBLE_LIBRARY="${ANSIBLE_LIBRARY:-/etc/ansible/roles/plugins/library}" ++export ANSIBLE_LOOKUP_PLUGINS="${ANSIBLE_LOOKUP_PLUGINS:-/etc/ansible/roles/plugins/lookup}" ++export ANSIBLE_FILTER_PLUGINS="${ANSIBLE_FILTER_PLUGINS:-/etc/ansible/roles/plugins/filter}" ++export ANSIBLE_ACTION_PLUGINS="${ANSIBLE_ACTION_PLUGINS:-/etc/ansible/roles/plugins/action}" ++export ANSIBLE_CALLBACK_PLUGINS="${ANSIBLE_CALLBACK_PLUGINS:-/etc/ansible/roles/plugins/callback}" ++export ANSIBLE_TEST_PLUGINS="${ANSIBLE_TEST_PLUGINS:-/etc/ansible/roles/plugins/test}" ++ ++## Variables ----------------------------------------------------------------- ++# Extra options to pass to the AIO bootstrap process ++export BOOTSTRAP_OPTS=${BOOTSTRAP_OPTS:-''} ++ ++if [[ -v VNF_EMBEDDED_DEPLOYMENT ]] && [[ ${VNF_EMBEDDED_DEPLOYMENT} = 'true' ]]; then ++ SKIP_OPTS="--skip-tags check-requirements,deploy-confd,remove-packages,install-packages,prepare-ceph,prepare-loopback-nova,prepare-data-disk,prepare-loopback-swap,prepare-ssh-keys,prepare-networking,deploy-openstack-user-config,prepare-loopback-swift,prepare-os-net-config,ssh-key-authorized,check-disk-size" ++else ++ SKIP_OPTS="--skip-tags deploy-confd,remove-packages,install-packages,prepare-ceph,prepare-loopback-nova,prepare-data-disk,prepare-loopback-swap,prepare-ssh-keys,prepare-networking,deploy-openstack-user-config,prepare-loopback-swift" ++fi ++ ++export CONFIG_PHASE='setup' ++## Main ---------------------------------------------------------------------- ++ ++# Run AIO bootstrap playbook ++if [ -z "${BOOTSTRAP_OPTS}" ]; then ++ ansible-playbook $1 \ ++ -i /opt/cmframework/scripts/inventory.sh ${SKIP_OPTS} ++else ++ ansible-playbook $1 \ ++ -i /opt/cmframework/scripts/inventory.sh \ ++ -e "${BOOTSTRAP_OPTS}" ++fi +diff --git a/tests/openstack_inventory_aio.json b/tests/openstack_inventory_aio.json +new file mode 100644 +index 00000000..8d027878 +--- /dev/null ++++ b/tests/openstack_inventory_aio.json +@@ -0,0 +1,1546 @@ ++{ ++ "_meta": { ++ "hostvars": { ++ "controller-1": { ++ "ansible_host": "172.29.236.11", ++ "cinder_backends": { ++ "lvm": { ++ "iscsi_ip_address": "172.29.236.11", ++ "volume_backend_name": "LVM_iSCSI", ++ "volume_driver": "cinder.volume.drivers.lvm.LVMVolumeDriver", ++ "volume_group": "cinder-volumes" ++ } ++ }, ++ "component": "heat_engine", ++ "container_address": "172.29.236.11", ++ "container_name": "controller-1", ++ "container_networks": { ++ "eth0_address": { ++ "address": "172.29.236.11", ++ "bridge": "eth0", ++ "netmask": null, ++ "type": "veth" ++ }, ++ "storage_address": { ++ "bridge": "vlan10", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ }, ++ "tunnel_address": { ++ "bridge": "vlan20", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ } ++ }, ++ "container_types": "controller-1-host_containers", ++ "is_metal": true, ++ "physical_host": "controller-1", ++ "physical_host_group": "orchestration_hosts", ++ "properties": { ++ "is_metal": true, ++ "service_name": "heat" ++ }, ++ "swift_proxy_vars": { ++ "read_affinity": "r1=100", ++ "write_affinity": "r1", ++ "write_affinity_node_count": "1 * replicas" ++ }, ++ "swift_vars": { ++ "region": 1, ++ "zone": 0 ++ } ++ } ++ } ++ }, ++ "all": { ++ "vars": { ++ "baremetal_flavor": [ ++ { ++ "disk": 10, ++ "extra_specs": { ++ "capabilities:boot_option": "local", ++ "cpu_arch": "x86_64" ++ }, ++ "name": "baremetal", ++ "ram": 13999, ++ "vcpus": 8 ++ } ++ ], ++ "baremetal_images": [ ++ { ++ "container_format": "bare", ++ "disk_format": "raw", ++ "file": "/opt/ncio/overcloudimages/guest-image.img", ++ "name": "golden" ++ }, ++ { ++ "container_format": "aki", ++ "disk_format": "aki", ++ "file": "/opt/ncio/overcloudimages/ironic-python-agent.kernel", ++ "name": "ipa-kernel" ++ }, ++ { ++ "container_format": "ari", ++ "disk_format": "ari", ++ "file": "/opt/ncio/overcloudimages/ironic-python-agent.initramfs", ++ "name": "ipa-ramdisk" ++ } ++ ], ++ "baremetal_ironic_nodes": [ ++ { ++ "driver": "pxe_ssh", ++ "driver_info": { ++ "power": { ++ "ssh_address": "192.168.122.1", ++ "ssh_key_contents": "{{ lookup('file', '/tmp/id_rsa') }}", ++ "ssh_username": "root", ++ "ssh_virt_type": "virsh" ++ } ++ }, ++ "name": "controller-2", ++ "network_interface": "flat", ++ "nics": [ ++ { ++ "mac": "00:0d:4f:4a:d6:7e" ++ } ++ ], ++ "properties": { ++ "capabilities": "boot_option:local", ++ "cpu_arch": "x86_64", ++ "cpus": 8, ++ "disk_size": 40, ++ "ram": 16384, ++ "root_device": { ++ "name": "/dev/vda" ++ } ++ } ++ }, ++ { ++ "driver": "pxe_ssh", ++ "driver_info": { ++ "power": { ++ "ssh_address": "192.168.122.1", ++ "ssh_key_contents": "{{ lookup('file', '/tmp/id_rsa') }}", ++ "ssh_username": "root", ++ "ssh_virt_type": "virsh" ++ } ++ }, ++ "name": "controller-3", ++ "network_interface": "flat", ++ "nics": [ ++ { ++ "mac": "00:0d:5f:49:d6:7e" ++ } ++ ], ++ "properties": { ++ "capabilities": "boot_option:local", ++ "cpu_arch": "x86_64", ++ "cpus": 8, ++ "disk_size": 40, ++ "ram": 16384, ++ "root_device": { ++ "name": "/dev/vda" ++ } ++ } ++ }, ++ { ++ "driver": "pxe_ssh", ++ "driver_info": { ++ "power": { ++ "ssh_address": "192.168.122.1", ++ "ssh_key_contents": "{{ lookup('file', '/tmp/id_rsa') }}", ++ "ssh_username": "root", ++ "ssh_virt_type": "virsh" ++ } ++ }, ++ "name": "compute-1", ++ "network_interface": "flat", ++ "nics": [ ++ { ++ "mac": "00:0d:4f:49:d6:7e" ++ } ++ ], ++ "properties": { ++ "capabilities": "boot_option:local", ++ "cpu_arch": "x86_64", ++ "cpus": 8, ++ "disk_size": 40, ++ "ram": 16384, ++ "root_device": { ++ "name": "/dev/vda" ++ } ++ } ++ } ++ ], ++ "baremetal_networks": [ ++ { ++ "allocation_pool_end": "172.29.236.50", ++ "allocation_pool_start": "172.29.236.12", ++ "cidr": "172.29.236.0/24", ++ "net_name": "provisioning_net", ++ "provider_network_type": "flat", ++ "provider_physical_network": "flat", ++ "subnet_name": "provisioning_subnet" ++ } ++ ], ++ "baremetal_nova_nodes": [ ++ { ++ "flavor_name": "baremetal", ++ "image_name": "golden", ++ "networks_list": [ ++ { ++ "net-name": "provisioning_net", ++ "v4-fixed-ip": "172.29.236.14" ++ } ++ ], ++ "node_name": "controller-2", ++ "userdata": "#cloud-config\nusers:\n - name: ncioadmin\n sudo: ['ALL=(ALL) NOPASSWD:ALL']\n ssh-authorized-keys:\n - \"{{ lookup('file', ansible_env.PWD + '/.ssh/id_rsa.pub') }}\"\n" ++ }, ++ { ++ "flavor_name": "baremetal", ++ "image_name": "golden", ++ "networks_list": [ ++ { ++ "net-name": "provisioning_net", ++ "v4-fixed-ip": "172.29.236.15" ++ } ++ ], ++ "node_name": "controller-3", ++ "userdata": "#cloud-config\nusers:\n - name: ncioadmin\n sudo: ['ALL=(ALL) NOPASSWD:ALL']\n ssh-authorized-keys:\n - \"{{ lookup('file', ansible_env.PWD + '/.ssh/id_rsa.pub') }}\"\n" ++ }, ++ { ++ "flavor_name": "baremetal", ++ "image_name": "golden", ++ "networks_list": [ ++ { ++ "net-name": "provisioning_net", ++ "v4-fixed-ip": "172.29.236.16" ++ } ++ ], ++ "node_name": "compute-1", ++ "userdata": "#cloud-config\nusers:\n - name: ncioadmin\n sudo: ['ALL=(ALL) NOPASSWD:ALL']\n ssh-authorized-keys:\n - \"{{ lookup('file', ansible_env.PWD + '/.ssh/id_rsa.pub') }}\"\n" ++ } ++ ], ++ "container_cidr": "172.29.236.0/24", ++ "external_lb_vip_address": "192.168.122.31", ++ "internal_lb_vip_address": "172.29.236.11", ++ "management_bridge": "eth0", ++ "ntp_servers": [ ++ "10.104.45.1" ++ ], ++ "provider_networks": [ ++ { ++ "network": { ++ "container_bridge": "eth0", ++ "container_interface": "eth0", ++ "container_type": "veth", ++ "group_binds": [ ++ "neutron_linuxbridge_agent", ++ "all_containers", ++ "hosts" ++ ], ++ "host_bind_override": "eth0", ++ "is_container_address": true, ++ "is_ssh_address": true, ++ "net_name": "flat", ++ "type": "flat" ++ } ++ }, ++ { ++ "network": { ++ "container_bridge": "vlan20", ++ "container_interface": "vlan20", ++ "container_type": "veth", ++ "group_binds": [ ++ "neutron_linuxbridge_agent" ++ ], ++ "ip_from_q": "tunnel", ++ "net_name": "vxlan", ++ "range": "1:1000", ++ "type": "vxlan" ++ } ++ }, ++ { ++ "network": { ++ "container_bridge": "vlan10", ++ "container_interface": "vlan10", ++ "container_type": "veth", ++ "group_binds": [ ++ "glance_api", ++ "cinder_api", ++ "cinder_volume", ++ "nova_compute", ++ "swift_proxy" ++ ], ++ "ip_from_q": "storage", ++ "type": "raw" ++ } ++ } ++ ], ++ "swift": { ++ "drives": [ ++ { ++ "name": "swift1.img" ++ }, ++ { ++ "name": "swift2.img" ++ }, ++ { ++ "name": "swift3.img" ++ } ++ ], ++ "mount_point": "/srv", ++ "part_power": 8, ++ "replication_network": "vlan10", ++ "storage_network": "vlan10", ++ "storage_policies": [ ++ { ++ "policy": { ++ "default": true, ++ "index": 0, ++ "name": "default" ++ } ++ } ++ ] ++ }, ++ "tunnel_bridge": "vlan20" ++ } ++ }, ++ "all_containers": { ++ "children": [ ++ "unbound_containers", ++ "ceph-osd_containers", ++ "orchestration_containers", ++ "operator_containers", ++ "memcaching_containers", ++ "metering-infra_containers", ++ "trove-infra_containers", ++ "ironic-infra_containers", ++ "ceph-mon_containers", ++ "swift_containers", ++ "storage_containers", ++ "ironic-server_containers", ++ "mq_containers", ++ "shared-infra_containers", ++ "compute_containers", ++ "storage-infra_containers", ++ "swift-proxy_containers", ++ "haproxy_containers", ++ "key-manager_containers", ++ "metering-alarm_containers", ++ "magnum-infra_containers", ++ "network_containers", ++ "sahara-infra_containers", ++ "os-infra_containers", ++ "image_containers", ++ "compute-infra_containers", ++ "log_containers", ++ "ironic-compute_containers", ++ "metering-compute_containers", ++ "identity_containers", ++ "dashboard_containers", ++ "dnsaas_containers", ++ "database_containers", ++ "metrics_containers", ++ "repo-infra_containers" ++ ], ++ "hosts": [] ++ }, ++ "aodh_alarm_evaluator": { ++ "children": [], ++ "hosts": [] ++ }, ++ "aodh_alarm_notifier": { ++ "children": [], ++ "hosts": [] ++ }, ++ "aodh_all": { ++ "children": [ ++ "aodh_alarm_notifier", ++ "aodh_api", ++ "aodh_alarm_evaluator", ++ "aodh_listener" ++ ], ++ "hosts": [] ++ }, ++ "aodh_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "aodh_container": { ++ "hosts": [] ++ }, ++ "aodh_listener": { ++ "children": [], ++ "hosts": [] ++ }, ++ "barbican_all": { ++ "children": [ ++ "barbican_api" ++ ], ++ "hosts": [] ++ }, ++ "barbican_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "barbican_container": { ++ "hosts": [] ++ }, ++ "baremetal-infra_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ceilometer_agent_central": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_agent_compute": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_agent_notification": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_all": { ++ "children": [ ++ "ceilometer_agent_central", ++ "ceilometer_agent_notification", ++ "ceilometer_api", ++ "ceilometer_collector", ++ "ceilometer_agent_compute" ++ ], ++ "hosts": [] ++ }, ++ "ceilometer_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_api_container": { ++ "hosts": [] ++ }, ++ "ceilometer_collector": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_collector_container": { ++ "hosts": [] ++ }, ++ "ceph-mon": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-mon_container": { ++ "hosts": [] ++ }, ++ "ceph-mon_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-mon_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-osd": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-osd_container": { ++ "hosts": [] ++ }, ++ "ceph-osd_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-osd_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph_all": { ++ "children": [ ++ "ceph-mon", ++ "ceph-osd" ++ ], ++ "hosts": [] ++ }, ++ "cinder_all": { ++ "children": [ ++ "cinder_api", ++ "cinder_backup", ++ "cinder_volume", ++ "cinder_scheduler" ++ ], ++ "hosts": [] ++ }, ++ "cinder_api": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "cinder_api_container": { ++ "hosts": [] ++ }, ++ "cinder_backup": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "cinder_scheduler": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "cinder_scheduler_container": { ++ "hosts": [] ++ }, ++ "cinder_volume": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "cinder_volumes_container": { ++ "hosts": [] ++ }, ++ "compute-infra_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "compute-infra_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "compute-infra_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "compute_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "compute_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "dashboard_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "dashboard_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "dashboard_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "database_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "database_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_all": { ++ "children": [ ++ "designate_producer", ++ "designate_mdns", ++ "designate_api", ++ "designate_worker", ++ "designate_central", ++ "designate_sink" ++ ], ++ "hosts": [] ++ }, ++ "designate_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_central": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_container": { ++ "hosts": [] ++ }, ++ "designate_mdns": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_producer": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_sink": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_worker": { ++ "children": [], ++ "hosts": [] ++ }, ++ "dnsaas_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "dnsaas_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "galera": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "galera_all": { ++ "children": [ ++ "galera" ++ ], ++ "hosts": [] ++ }, ++ "galera_container": { ++ "hosts": [] ++ }, ++ "glance_all": { ++ "children": [ ++ "glance_registry", ++ "glance_api" ++ ], ++ "hosts": [] ++ }, ++ "glance_api": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "glance_container": { ++ "hosts": [] ++ }, ++ "glance_registry": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "gnocchi_all": { ++ "children": [ ++ "gnocchi_api", ++ "gnocchi_metricd" ++ ], ++ "hosts": [] ++ }, ++ "gnocchi_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "gnocchi_container": { ++ "hosts": [] ++ }, ++ "gnocchi_metricd": { ++ "children": [], ++ "hosts": [] ++ }, ++ "haproxy": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "haproxy_all": { ++ "children": [ ++ "haproxy" ++ ], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "haproxy_container": { ++ "hosts": [] ++ }, ++ "haproxy_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "haproxy_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "heat_all": { ++ "children": [ ++ "heat_api", ++ "heat_engine", ++ "heat_api_cloudwatch", ++ "heat_api_cfn" ++ ], ++ "hosts": [] ++ }, ++ "heat_api": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "heat_api_cfn": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "heat_api_cloudwatch": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "heat_apis_container": { ++ "hosts": [] ++ }, ++ "heat_engine": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "heat_engine_container": { ++ "hosts": [] ++ }, ++ "horizon": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "horizon_all": { ++ "children": [ ++ "horizon" ++ ], ++ "hosts": [] ++ }, ++ "horizon_container": { ++ "hosts": [] ++ }, ++ "hosts": { ++ "children": [ ++ "memcaching_hosts", ++ "metering-compute_hosts", ++ "image_hosts", ++ "shared-infra_hosts", ++ "storage_hosts", ++ "metering-infra_hosts", ++ "os-infra_hosts", ++ "ironic-server_hosts", ++ "key-manager_hosts", ++ "ceph-osd_hosts", ++ "dnsaas_hosts", ++ "network_hosts", ++ "haproxy_hosts", ++ "mq_hosts", ++ "database_hosts", ++ "swift-proxy_hosts", ++ "trove-infra_hosts", ++ "ironic-compute_hosts", ++ "metering-alarm_hosts", ++ "log_hosts", ++ "ceph-mon_hosts", ++ "compute_hosts", ++ "orchestration_hosts", ++ "compute-infra_hosts", ++ "identity_hosts", ++ "unbound_hosts", ++ "swift_hosts", ++ "sahara-infra_hosts", ++ "magnum-infra_hosts", ++ "ironic-infra_hosts", ++ "metrics_hosts", ++ "dashboard_hosts", ++ "storage-infra_hosts", ++ "operator_hosts", ++ "repo-infra_hosts" ++ ], ++ "hosts": [] ++ }, ++ "identity_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "identity_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "identity_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "image_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "image_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "image_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ironic-compute_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ironic-compute_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "ironic-compute_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ironic-infra_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ironic-infra_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "ironic-infra_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ironic-server_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ironic-server_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ironic_all": { ++ "children": [ ++ "ironic_conductor", ++ "ironic_api" ++ ], ++ "hosts": [] ++ }, ++ "ironic_api": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ironic_api_container": { ++ "hosts": [] ++ }, ++ "ironic_compute": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ironic_compute_container": { ++ "hosts": [] ++ }, ++ "ironic_conductor": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ironic_conductor_container": { ++ "hosts": [] ++ }, ++ "ironic_server": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ironic_server_container": { ++ "hosts": [] ++ }, ++ "ironic_servers": { ++ "children": [ ++ "ironic_server" ++ ], ++ "hosts": [] ++ }, ++ "key-manager_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "key-manager_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "keystone": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "keystone_all": { ++ "children": [ ++ "keystone" ++ ], ++ "hosts": [] ++ }, ++ "keystone_container": { ++ "hosts": [] ++ }, ++ "log_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "log_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "log_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "lxc_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "magnum": { ++ "children": [], ++ "hosts": [] ++ }, ++ "magnum-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "magnum-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "magnum_all": { ++ "children": [ ++ "magnum" ++ ], ++ "hosts": [] ++ }, ++ "magnum_container": { ++ "hosts": [] ++ }, ++ "memcached": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "memcached_all": { ++ "children": [ ++ "memcached" ++ ], ++ "hosts": [] ++ }, ++ "memcached_container": { ++ "hosts": [] ++ }, ++ "memcaching_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "memcaching_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-alarm_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-alarm_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-compute_container": { ++ "hosts": [] ++ }, ++ "metering-compute_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-compute_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metrics_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metrics_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "mq_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "mq_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "network_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "network_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "network_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "neutron_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "neutron_agents_container": { ++ "hosts": [] ++ }, ++ "neutron_all": { ++ "children": [ ++ "neutron_agent", ++ "neutron_metadata_agent", ++ "neutron_linuxbridge_agent", ++ "neutron_bgp_dragent", ++ "neutron_dhcp_agent", ++ "neutron_lbaas_agent", ++ "neutron_l3_agent", ++ "neutron_metering_agent", ++ "neutron_server", ++ "neutron_sriov_nic_agent", ++ "neutron_openvswitch_agent" ++ ], ++ "hosts": [] ++ }, ++ "neutron_bgp_dragent": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "neutron_dhcp_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "neutron_l3_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "neutron_lbaas_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "neutron_linuxbridge_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "neutron_metadata_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "neutron_metering_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "neutron_openvswitch_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "neutron_server": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "neutron_server_container": { ++ "hosts": [] ++ }, ++ "neutron_sriov_nic_agent": { ++ "children": [], ++ "hosts": [] ++ }, ++ "nova_all": { ++ "children": [ ++ "nova_console", ++ "nova_scheduler", ++ "ironic_compute", ++ "nova_api_placement", ++ "nova_api_metadata", ++ "nova_api_os_compute", ++ "nova_conductor", ++ "nova_compute" ++ ], ++ "hosts": [] ++ }, ++ "nova_api_metadata": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "nova_api_metadata_container": { ++ "hosts": [] ++ }, ++ "nova_api_os_compute": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "nova_api_os_compute_container": { ++ "hosts": [] ++ }, ++ "nova_api_placement": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "nova_api_placement_container": { ++ "hosts": [] ++ }, ++ "nova_compute": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "nova_compute_container": { ++ "hosts": [] ++ }, ++ "nova_conductor": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "nova_conductor_container": { ++ "hosts": [] ++ }, ++ "nova_console": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "nova_console_container": { ++ "hosts": [] ++ }, ++ "nova_scheduler": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "nova_scheduler_container": { ++ "hosts": [] ++ }, ++ "operator_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "operator_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "orchestration_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "orchestration_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "orchestration_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "os-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "os-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "pkg_repo": { ++ "children": [], ++ "hosts": [] ++ }, ++ "rabbit_mq_container": { ++ "hosts": [] ++ }, ++ "rabbitmq": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "rabbitmq_all": { ++ "children": [ ++ "rabbitmq" ++ ], ++ "hosts": [] ++ }, ++ "remote": { ++ "children": [ ++ "swift-remote_hosts" ++ ], ++ "hosts": [] ++ }, ++ "remote_containers": { ++ "children": [ ++ "swift-remote_containers" ++ ], ++ "hosts": [] ++ }, ++ "repo-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "repo-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "repo_all": { ++ "children": [ ++ "pkg_repo" ++ ], ++ "hosts": [] ++ }, ++ "repo_container": { ++ "hosts": [] ++ }, ++ "rsyslog": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "rsyslog_all": { ++ "children": [ ++ "rsyslog" ++ ], ++ "hosts": [] ++ }, ++ "rsyslog_container": { ++ "hosts": [] ++ }, ++ "sahara-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "sahara-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "sahara_all": { ++ "children": [ ++ "sahara_api", ++ "sahara_engine" ++ ], ++ "hosts": [] ++ }, ++ "sahara_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "sahara_container": { ++ "hosts": [] ++ }, ++ "sahara_engine": { ++ "children": [], ++ "hosts": [] ++ }, ++ "shared-infra_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "shared-infra_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "shared-infra_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "storage-infra_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "storage-infra_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "storage-infra_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "storage_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "storage_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "storage_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift-proxy_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift-proxy_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "swift-proxy_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift-remote_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "swift-remote_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "swift_acc": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_acc_container": { ++ "hosts": [] ++ }, ++ "swift_all": { ++ "children": [ ++ "swift_cont", ++ "swift_obj", ++ "swift_proxy", ++ "swift_acc" ++ ], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_cont": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_cont_container": { ++ "hosts": [] ++ }, ++ "swift_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "swift_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_obj": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_obj_container": { ++ "hosts": [] ++ }, ++ "swift_proxy": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_proxy_container": { ++ "hosts": [] ++ }, ++ "swift_remote": { ++ "children": [], ++ "hosts": [] ++ }, ++ "swift_remote_all": { ++ "children": [ ++ "swift_remote" ++ ], ++ "hosts": [] ++ }, ++ "swift_remote_container": { ++ "hosts": [] ++ }, ++ "trove-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove_all": { ++ "children": [ ++ "trove_conductor", ++ "trove_taskmanager", ++ "trove_api" ++ ], ++ "hosts": [] ++ }, ++ "trove_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove_api_container": { ++ "hosts": [] ++ }, ++ "trove_conductor": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove_conductor_container": { ++ "hosts": [] ++ }, ++ "trove_taskmanager": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove_taskmanager_container": { ++ "hosts": [] ++ }, ++ "unbound": { ++ "children": [], ++ "hosts": [] ++ }, ++ "unbound_all": { ++ "children": [ ++ "unbound" ++ ], ++ "hosts": [] ++ }, ++ "unbound_container": { ++ "hosts": [] ++ }, ++ "unbound_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "unbound_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "utility": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "utility_all": { ++ "children": [ ++ "utility" ++ ], ++ "hosts": [] ++ }, ++ "utility_container": { ++ "hosts": [] ++ } ++} +\ No newline at end of file +diff --git a/tests/openstack_inventory_prod.json b/tests/openstack_inventory_prod.json +new file mode 100644 +index 00000000..5ab7555c +--- /dev/null ++++ b/tests/openstack_inventory_prod.json +@@ -0,0 +1,1777 @@ ++{ ++ "_meta": { ++ "hostvars": { ++ "compute-1": { ++ "ansible_host": "172.29.236.16", ++ "component": "nova_compute", ++ "container_address": "172.29.236.16", ++ "container_name": "compute-1", ++ "container_networks": { ++ "eth0_address": { ++ "address": "172.29.236.16", ++ "bridge": "eth0", ++ "netmask": null, ++ "type": "veth" ++ }, ++ "storage_address": { ++ "bridge": "vlan10", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ }, ++ "tunnel_address": { ++ "bridge": "vlan20", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ } ++ }, ++ "container_types": "compute-1-host_containers", ++ "is_metal": true, ++ "os_net_config": { ++ "network_config": [ ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.236.16/24" ++ } ++ ], ++ "dns_servers": [ ++ "172.29.236.11" ++ ], ++ "name": "eth0", ++ "type": "interface", ++ "use_dhcp": false ++ }, ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.244.16/24" ++ } ++ ], ++ "device": "eth0", ++ "type": "vlan", ++ "use_dhcp": false, ++ "vlan_id": 10 ++ }, ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.240.16/24" ++ } ++ ], ++ "device": "eth0", ++ "type": "vlan", ++ "use_dhcp": false, ++ "vlan_id": 20 ++ } ++ ] ++ }, ++ "physical_host": "compute-1", ++ "physical_host_group": "compute_hosts", ++ "properties": { ++ "is_metal": true, ++ "service_name": "nova" ++ } ++ }, ++ "controller-1": { ++ "ansible_host": "172.29.236.11", ++ "cinder_backends": { ++ "lvm": { ++ "iscsi_ip_address": "172.29.236.11", ++ "volume_backend_name": "LVM_iSCSI", ++ "volume_driver": "cinder.volume.drivers.lvm.LVMVolumeDriver", ++ "volume_group": "cinder-volumes" ++ } ++ }, ++ "component": "heat_engine", ++ "container_address": "172.29.236.11", ++ "container_name": "controller-1", ++ "container_networks": { ++ "eth0_address": { ++ "address": "172.29.236.11", ++ "bridge": "eth0", ++ "netmask": null, ++ "type": "veth" ++ }, ++ "storage_address": { ++ "bridge": "vlan10", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ }, ++ "tunnel_address": { ++ "bridge": "vlan20", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ } ++ }, ++ "container_types": "controller-1-host_containers", ++ "is_metal": true, ++ "physical_host": "controller-1", ++ "physical_host_group": "orchestration_hosts", ++ "properties": { ++ "is_metal": true, ++ "service_name": "heat" ++ }, ++ "swift_proxy_vars": { ++ "read_affinity": "r1=100", ++ "write_affinity": "r1", ++ "write_affinity_node_count": "1 * replicas" ++ }, ++ "swift_vars": { ++ "region": 1, ++ "zone": 0 ++ } ++ }, ++ "controller-2": { ++ "ansible_host": "172.29.236.14", ++ "component": "heat_engine", ++ "container_address": "172.29.236.14", ++ "container_name": "controller-2", ++ "container_networks": { ++ "eth0_address": { ++ "address": "172.29.236.14", ++ "bridge": "eth0", ++ "netmask": null, ++ "type": "veth" ++ }, ++ "storage_address": { ++ "bridge": "vlan10", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ }, ++ "tunnel_address": { ++ "bridge": "vlan20", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ } ++ }, ++ "container_types": "controller-2-host_containers", ++ "is_metal": true, ++ "os_net_config": { ++ "network_config": [ ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.236.14/24" ++ } ++ ], ++ "dns_servers": [ ++ "172.29.236.11", ++ "10.102.12.68" ++ ], ++ "name": "eth0", ++ "type": "interface", ++ "use_dhcp": false ++ }, ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.244.14/24" ++ } ++ ], ++ "device": "eth0", ++ "type": "vlan", ++ "use_dhcp": false, ++ "vlan_id": 10 ++ }, ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.240.14/24" ++ } ++ ], ++ "device": "eth0", ++ "type": "vlan", ++ "use_dhcp": false, ++ "vlan_id": 20 ++ }, ++ { ++ "name": "eth1", ++ "type": "interface", ++ "use_dhcp": true ++ } ++ ] ++ }, ++ "physical_host": "controller-2", ++ "physical_host_group": "orchestration_hosts", ++ "properties": { ++ "is_metal": true, ++ "service_name": "heat" ++ } ++ }, ++ "controller-3": { ++ "ansible_host": "172.29.236.15", ++ "component": "heat_engine", ++ "container_address": "172.29.236.15", ++ "container_name": "controller-3", ++ "container_networks": { ++ "eth0_address": { ++ "address": "172.29.236.15", ++ "bridge": "eth0", ++ "netmask": null, ++ "type": "veth" ++ }, ++ "storage_address": { ++ "bridge": "vlan10", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ }, ++ "tunnel_address": { ++ "bridge": "vlan20", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ } ++ }, ++ "container_types": "controller-3-host_containers", ++ "is_metal": true, ++ "os_net_config": { ++ "network_config": [ ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.236.15/24" ++ } ++ ], ++ "dns_servers": [ ++ "172.29.236.11", ++ "10.102.12.68" ++ ], ++ "name": "eth0", ++ "type": "interface", ++ "use_dhcp": false ++ }, ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.244.15/24" ++ } ++ ], ++ "device": "eth0", ++ "type": "vlan", ++ "use_dhcp": false, ++ "vlan_id": 10 ++ }, ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.240.15/24" ++ } ++ ], ++ "device": "eth0", ++ "type": "vlan", ++ "use_dhcp": false, ++ "vlan_id": 20 ++ }, ++ { ++ "name": "eth1", ++ "type": "interface", ++ "use_dhcp": true ++ } ++ ] ++ }, ++ "physical_host": "controller-3", ++ "physical_host_group": "orchestration_hosts", ++ "properties": { ++ "is_metal": true, ++ "service_name": "heat" ++ } ++ } ++ } ++ }, ++ "all": { ++ "vars": { ++ "baremetal_flavor": [ ++ { ++ "disk": 10, ++ "extra_specs": { ++ "capabilities:boot_option": "local", ++ "cpu_arch": "x86_64" ++ }, ++ "name": "baremetal", ++ "ram": 13999, ++ "vcpus": 8 ++ } ++ ], ++ "baremetal_images": [ ++ { ++ "container_format": "bare", ++ "disk_format": "raw", ++ "file": "/opt/ncio/overcloudimages/guest-image.img", ++ "name": "golden" ++ }, ++ { ++ "container_format": "aki", ++ "disk_format": "aki", ++ "file": "/opt/ncio/overcloudimages/ironic-python-agent.kernel", ++ "name": "ipa-kernel" ++ }, ++ { ++ "container_format": "ari", ++ "disk_format": "ari", ++ "file": "/opt/ncio/overcloudimages/ironic-python-agent.initramfs", ++ "name": "ipa-ramdisk" ++ } ++ ], ++ "baremetal_networks": [ ++ { ++ "allocation_pool_end": "172.29.236.50", ++ "allocation_pool_start": "172.29.236.12", ++ "cidr": "172.29.236.0/24", ++ "net_name": "provisioning_net", ++ "provider_network_type": "flat", ++ "provider_physical_network": "flat", ++ "subnet_name": "provisioning_subnet" ++ } ++ ], ++ "container_cidr": "172.29.236.0/24", ++ "external_lb_vip_address": "192.168.122.10", ++ "galera_initial_setup": false, ++ "internal_lb_vip_address": "172.29.236.110", ++ "management_bridge": "eth0", ++ "ntp_servers": [ ++ "10.104.45.1" ++ ], ++ "provider_networks": [ ++ { ++ "network": { ++ "container_bridge": "eth0", ++ "container_interface": "eth0", ++ "container_type": "veth", ++ "group_binds": [ ++ "neutron_linuxbridge_agent", ++ "all_containers", ++ "hosts" ++ ], ++ "host_bind_override": "eth0", ++ "is_container_address": true, ++ "is_ssh_address": true, ++ "net_name": "flat", ++ "type": "flat" ++ } ++ }, ++ { ++ "network": { ++ "container_bridge": "vlan20", ++ "container_interface": "vlan20", ++ "container_type": "veth", ++ "group_binds": [ ++ "neutron_linuxbridge_agent", ++ "neutron-openvswitch-agent" ++ ], ++ "ip_from_q": "tunnel", ++ "net_name": "vxlan", ++ "range": "1:1000", ++ "type": "vxlan" ++ } ++ }, ++ { ++ "network": { ++ "container_bridge": "vlan10", ++ "container_interface": "vlan10", ++ "container_type": "veth", ++ "group_binds": [ ++ "glance_api", ++ "cinder_api", ++ "cinder_volume", ++ "nova_compute" ++ ], ++ "ip_from_q": "storage", ++ "type": "raw" ++ } ++ } ++ ], ++ "swift": { ++ "drives": [ ++ { ++ "name": "swift1.img" ++ }, ++ { ++ "name": "swift2.img" ++ }, ++ { ++ "name": "swift3.img" ++ } ++ ], ++ "mount_point": "/srv", ++ "part_power": 8, ++ "replication_network": "vlan10", ++ "storage_network": "vlan10", ++ "storage_policies": [ ++ { ++ "policy": { ++ "default": true, ++ "index": 0, ++ "name": "default" ++ } ++ } ++ ] ++ }, ++ "tunnel_bridge": "vlan20" ++ } ++ }, ++ "all_containers": { ++ "children": [ ++ "unbound_containers", ++ "ceph-osd_containers", ++ "orchestration_containers", ++ "operator_containers", ++ "memcaching_containers", ++ "metering-infra_containers", ++ "trove-infra_containers", ++ "ironic-infra_containers", ++ "ceph-mon_containers", ++ "swift_containers", ++ "storage_containers", ++ "ironic-server_containers", ++ "mq_containers", ++ "shared-infra_containers", ++ "compute_containers", ++ "storage-infra_containers", ++ "swift-proxy_containers", ++ "haproxy_containers", ++ "key-manager_containers", ++ "metering-alarm_containers", ++ "magnum-infra_containers", ++ "network_containers", ++ "sahara-infra_containers", ++ "os-infra_containers", ++ "image_containers", ++ "compute-infra_containers", ++ "log_containers", ++ "ironic-compute_containers", ++ "metering-compute_containers", ++ "identity_containers", ++ "dashboard_containers", ++ "dnsaas_containers", ++ "database_containers", ++ "metrics_containers", ++ "repo-infra_containers" ++ ], ++ "hosts": [] ++ }, ++ "aodh_alarm_evaluator": { ++ "children": [], ++ "hosts": [] ++ }, ++ "aodh_alarm_notifier": { ++ "children": [], ++ "hosts": [] ++ }, ++ "aodh_all": { ++ "children": [ ++ "aodh_alarm_notifier", ++ "aodh_api", ++ "aodh_alarm_evaluator", ++ "aodh_listener" ++ ], ++ "hosts": [] ++ }, ++ "aodh_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "aodh_container": { ++ "hosts": [] ++ }, ++ "aodh_listener": { ++ "children": [], ++ "hosts": [] ++ }, ++ "barbican_all": { ++ "children": [ ++ "barbican_api" ++ ], ++ "hosts": [] ++ }, ++ "barbican_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "barbican_container": { ++ "hosts": [] ++ }, ++ "baremetal-infra_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "baremetal-interface_config_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "compute-1" ++ ] ++ }, ++ "ceilometer_agent_central": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_agent_compute": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_agent_notification": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_all": { ++ "children": [ ++ "ceilometer_agent_central", ++ "ceilometer_agent_notification", ++ "ceilometer_api", ++ "ceilometer_collector", ++ "ceilometer_agent_compute" ++ ], ++ "hosts": [] ++ }, ++ "ceilometer_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_api_container": { ++ "hosts": [] ++ }, ++ "ceilometer_collector": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_collector_container": { ++ "hosts": [] ++ }, ++ "ceph-mon": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-mon_container": { ++ "hosts": [] ++ }, ++ "ceph-mon_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-mon_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-osd": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-osd_container": { ++ "hosts": [] ++ }, ++ "ceph-osd_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-osd_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph_all": { ++ "children": [ ++ "ceph-mon", ++ "ceph-osd" ++ ], ++ "hosts": [] ++ }, ++ "cinder_all": { ++ "children": [ ++ "cinder_api", ++ "cinder_backup", ++ "cinder_volume", ++ "cinder_scheduler" ++ ], ++ "hosts": [] ++ }, ++ "cinder_api": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "cinder_api_container": { ++ "hosts": [] ++ }, ++ "cinder_backup": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "cinder_scheduler": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "cinder_scheduler_container": { ++ "hosts": [] ++ }, ++ "cinder_volume": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "cinder_volumes_container": { ++ "hosts": [] ++ }, ++ "compute-infra_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "compute-infra_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "compute-infra_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "compute_all": { ++ "hosts": [ ++ "compute-1" ++ ] ++ }, ++ "compute_containers": { ++ "children": [ ++ "compute-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "compute_hosts": { ++ "hosts": [ ++ "compute-1" ++ ] ++ }, ++ "dashboard_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "dashboard_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "dashboard_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "database_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "database_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_all": { ++ "children": [ ++ "designate_producer", ++ "designate_mdns", ++ "designate_api", ++ "designate_worker", ++ "designate_central", ++ "designate_sink" ++ ], ++ "hosts": [] ++ }, ++ "designate_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_central": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_container": { ++ "hosts": [] ++ }, ++ "designate_mdns": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_producer": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_sink": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_worker": { ++ "children": [], ++ "hosts": [] ++ }, ++ "dnsaas_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "dnsaas_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "galera": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "galera_all": { ++ "children": [ ++ "galera" ++ ], ++ "hosts": [] ++ }, ++ "galera_container": { ++ "hosts": [] ++ }, ++ "glance_all": { ++ "children": [ ++ "glance_registry", ++ "glance_api" ++ ], ++ "hosts": [] ++ }, ++ "glance_api": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "glance_container": { ++ "hosts": [] ++ }, ++ "glance_registry": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "gnocchi_all": { ++ "children": [ ++ "gnocchi_api", ++ "gnocchi_metricd" ++ ], ++ "hosts": [] ++ }, ++ "gnocchi_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "gnocchi_container": { ++ "hosts": [] ++ }, ++ "gnocchi_metricd": { ++ "children": [], ++ "hosts": [] ++ }, ++ "haproxy": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "haproxy_all": { ++ "children": [ ++ "haproxy" ++ ], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "haproxy_container": { ++ "hosts": [] ++ }, ++ "haproxy_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "haproxy_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "heat_all": { ++ "children": [ ++ "heat_api", ++ "heat_engine", ++ "heat_api_cloudwatch", ++ "heat_api_cfn" ++ ], ++ "hosts": [] ++ }, ++ "heat_api": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "heat_api_cfn": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "heat_api_cloudwatch": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "heat_apis_container": { ++ "hosts": [] ++ }, ++ "heat_engine": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "heat_engine_container": { ++ "hosts": [] ++ }, ++ "horizon": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "horizon_all": { ++ "children": [ ++ "horizon" ++ ], ++ "hosts": [] ++ }, ++ "horizon_container": { ++ "hosts": [] ++ }, ++ "hosts": { ++ "children": [ ++ "memcaching_hosts", ++ "metering-compute_hosts", ++ "image_hosts", ++ "shared-infra_hosts", ++ "storage_hosts", ++ "metering-infra_hosts", ++ "os-infra_hosts", ++ "ironic-server_hosts", ++ "key-manager_hosts", ++ "ceph-osd_hosts", ++ "dnsaas_hosts", ++ "network_hosts", ++ "haproxy_hosts", ++ "mq_hosts", ++ "database_hosts", ++ "swift-proxy_hosts", ++ "trove-infra_hosts", ++ "ironic-compute_hosts", ++ "metering-alarm_hosts", ++ "log_hosts", ++ "ceph-mon_hosts", ++ "compute_hosts", ++ "orchestration_hosts", ++ "compute-infra_hosts", ++ "identity_hosts", ++ "unbound_hosts", ++ "swift_hosts", ++ "sahara-infra_hosts", ++ "magnum-infra_hosts", ++ "ironic-infra_hosts", ++ "metrics_hosts", ++ "dashboard_hosts", ++ "storage-infra_hosts", ++ "operator_hosts", ++ "repo-infra_hosts" ++ ], ++ "hosts": [] ++ }, ++ "identity_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "identity_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "identity_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "image_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "image_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "image_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "ironic-compute_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ironic-compute_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "ironic-compute_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ironic-infra_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "ironic-infra_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "ironic-infra_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "ironic-server_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ironic-server_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ironic_all": { ++ "children": [ ++ "ironic_conductor", ++ "ironic_api" ++ ], ++ "hosts": [] ++ }, ++ "ironic_api": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "ironic_api_container": { ++ "hosts": [] ++ }, ++ "ironic_compute": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ironic_compute_container": { ++ "hosts": [] ++ }, ++ "ironic_conductor": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "ironic_conductor_container": { ++ "hosts": [] ++ }, ++ "ironic_server": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ironic_server_container": { ++ "hosts": [] ++ }, ++ "ironic_servers": { ++ "children": [ ++ "ironic_server" ++ ], ++ "hosts": [] ++ }, ++ "key-manager_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "key-manager_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "keystone": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "keystone_all": { ++ "children": [ ++ "keystone" ++ ], ++ "hosts": [] ++ }, ++ "keystone_container": { ++ "hosts": [] ++ }, ++ "log_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "log_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "lxc_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1", ++ "compute-1" ++ ] ++ }, ++ "magnum": { ++ "children": [], ++ "hosts": [] ++ }, ++ "magnum-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "magnum-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "magnum_all": { ++ "children": [ ++ "magnum" ++ ], ++ "hosts": [] ++ }, ++ "magnum_container": { ++ "hosts": [] ++ }, ++ "memcached": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "memcached_all": { ++ "children": [ ++ "memcached" ++ ], ++ "hosts": [] ++ }, ++ "memcached_container": { ++ "hosts": [] ++ }, ++ "memcaching_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "memcaching_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-alarm_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-alarm_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-compute_container": { ++ "hosts": [] ++ }, ++ "metering-compute_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-compute_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metrics_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metrics_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "mq_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "mq_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "network_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "network_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "network_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_agents_container": { ++ "hosts": [] ++ }, ++ "neutron_all": { ++ "children": [ ++ "neutron_agent", ++ "neutron_metadata_agent", ++ "neutron_linuxbridge_agent", ++ "neutron_bgp_dragent", ++ "neutron_dhcp_agent", ++ "neutron_lbaas_agent", ++ "neutron_l3_agent", ++ "neutron_metering_agent", ++ "neutron_server", ++ "neutron_sriov_nic_agent", ++ "neutron_openvswitch_agent" ++ ], ++ "hosts": [] ++ }, ++ "neutron_bgp_dragent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_dhcp_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_l3_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_lbaas_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_linuxbridge_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1", ++ "compute-1" ++ ] ++ }, ++ "neutron_metadata_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_metering_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_openvswitch_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1", ++ "compute-1" ++ ] ++ }, ++ "neutron_server": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_server_container": { ++ "hosts": [] ++ }, ++ "neutron_sriov_nic_agent": { ++ "children": [], ++ "hosts": [ ++ "compute-1" ++ ] ++ }, ++ "nova_all": { ++ "children": [ ++ "nova_console", ++ "nova_scheduler", ++ "ironic_compute", ++ "nova_api_placement", ++ "nova_api_metadata", ++ "nova_api_os_compute", ++ "nova_conductor", ++ "nova_compute" ++ ], ++ "hosts": [] ++ }, ++ "nova_api_metadata": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "nova_api_metadata_container": { ++ "hosts": [] ++ }, ++ "nova_api_os_compute": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "nova_api_os_compute_container": { ++ "hosts": [] ++ }, ++ "nova_api_placement": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "nova_api_placement_container": { ++ "hosts": [] ++ }, ++ "nova_compute": { ++ "children": [], ++ "hosts": [ ++ "controller-1", ++ "compute-1" ++ ] ++ }, ++ "nova_compute_container": { ++ "hosts": [] ++ }, ++ "nova_conductor": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "nova_conductor_container": { ++ "hosts": [] ++ }, ++ "nova_console": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "nova_console_container": { ++ "hosts": [] ++ }, ++ "nova_scheduler": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "nova_scheduler_container": { ++ "hosts": [] ++ }, ++ "operator_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "operator_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "orchestration_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "orchestration_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "orchestration_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "os-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "os-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "pkg_repo": { ++ "children": [], ++ "hosts": [] ++ }, ++ "rabbit_mq_container": { ++ "hosts": [] ++ }, ++ "rabbitmq": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "rabbitmq_all": { ++ "children": [ ++ "rabbitmq" ++ ], ++ "hosts": [] ++ }, ++ "remote": { ++ "children": [ ++ "swift-remote_hosts" ++ ], ++ "hosts": [] ++ }, ++ "remote_containers": { ++ "children": [ ++ "swift-remote_containers" ++ ], ++ "hosts": [] ++ }, ++ "repo-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "repo-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "repo_all": { ++ "children": [ ++ "pkg_repo" ++ ], ++ "hosts": [] ++ }, ++ "repo_container": { ++ "hosts": [] ++ }, ++ "rsyslog": { ++ "children": [], ++ "hosts": [] ++ }, ++ "rsyslog_all": { ++ "children": [ ++ "rsyslog" ++ ], ++ "hosts": [] ++ }, ++ "rsyslog_container": { ++ "hosts": [] ++ }, ++ "sahara-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "sahara-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "sahara_all": { ++ "children": [ ++ "sahara_api", ++ "sahara_engine" ++ ], ++ "hosts": [] ++ }, ++ "sahara_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "sahara_container": { ++ "hosts": [] ++ }, ++ "sahara_engine": { ++ "children": [], ++ "hosts": [] ++ }, ++ "shared-infra_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "shared-infra_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "shared-infra_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "storage-infra_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "storage-infra_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "storage-infra_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "storage_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "storage_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "storage_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift-proxy_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift-proxy_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "swift-proxy_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift-remote_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "swift-remote_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "swift_acc": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_acc_container": { ++ "hosts": [] ++ }, ++ "swift_all": { ++ "children": [ ++ "swift_cont", ++ "swift_obj", ++ "swift_proxy", ++ "swift_acc" ++ ], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_cont": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_cont_container": { ++ "hosts": [] ++ }, ++ "swift_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "swift_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_obj": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_obj_container": { ++ "hosts": [] ++ }, ++ "swift_proxy": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_proxy_container": { ++ "hosts": [] ++ }, ++ "swift_remote": { ++ "children": [], ++ "hosts": [] ++ }, ++ "swift_remote_all": { ++ "children": [ ++ "swift_remote" ++ ], ++ "hosts": [] ++ }, ++ "swift_remote_container": { ++ "hosts": [] ++ }, ++ "trove-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove_all": { ++ "children": [ ++ "trove_conductor", ++ "trove_taskmanager", ++ "trove_api" ++ ], ++ "hosts": [] ++ }, ++ "trove_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove_api_container": { ++ "hosts": [] ++ }, ++ "trove_conductor": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove_conductor_container": { ++ "hosts": [] ++ }, ++ "trove_taskmanager": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove_taskmanager_container": { ++ "hosts": [] ++ }, ++ "unbound": { ++ "children": [], ++ "hosts": [] ++ }, ++ "unbound_all": { ++ "children": [ ++ "unbound" ++ ], ++ "hosts": [] ++ }, ++ "unbound_container": { ++ "hosts": [] ++ }, ++ "unbound_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "unbound_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "utility": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "utility_all": { ++ "children": [ ++ "utility" ++ ], ++ "hosts": [] ++ }, ++ "utility_container": { ++ "hosts": [] ++ } ++} +\ No newline at end of file +diff --git a/tests/openstack_inventory_real_prod.json b/tests/openstack_inventory_real_prod.json +new file mode 100644 +index 00000000..329dd6ac +--- /dev/null ++++ b/tests/openstack_inventory_real_prod.json +@@ -0,0 +1,1919 @@ ++{ ++ "_meta": { ++ "hostvars": { ++ "compute-1": { ++ "ansible_host": "172.29.236.16", ++ "component": "nova_compute", ++ "container_address": "172.29.236.16", ++ "container_name": "compute-1", ++ "container_networks": { ++ "ens255f0_address": { ++ "address": "172.29.236.16", ++ "bridge": "ens255f0", ++ "netmask": null, ++ "type": "veth" ++ }, ++ "storage_address": { ++ "bridge": "vlan978", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ }, ++ "tunnel_address": { ++ "bridge": "vlan1002", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ } ++ }, ++ "container_types": "compute-1-host_containers", ++ "is_metal": true, ++ "os_net_config": { ++ "network_config": [ ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.236.16/24" ++ } ++ ], ++ "dns_servers": [ ++ "172.29.236.11" ++ ], ++ "name": "ens255f0", ++ "type": "interface", ++ "use_dhcp": false ++ }, ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.244.16/24" ++ } ++ ], ++ "device": "ens4f0", ++ "type": "vlan", ++ "use_dhcp": false, ++ "vlan_id": 978 ++ }, ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.240.16/24" ++ } ++ ], ++ "device": "ens4f0", ++ "type": "vlan", ++ "use_dhcp": false, ++ "vlan_id": 1002 ++ } ++ ] ++ }, ++ "physical_host": "compute-1", ++ "physical_host_group": "compute_hosts", ++ "properties": { ++ "is_metal": true, ++ "service_name": "nova" ++ } ++ }, ++ "controller-1": { ++ "ansible_host": "172.29.236.11", ++ "cinder_backends": { ++ "lvm": { ++ "iscsi_ip_address": "172.29.236.11", ++ "volume_backend_name": "LVM_iSCSI", ++ "volume_driver": "cinder.volume.drivers.lvm.LVMVolumeDriver", ++ "volume_group": "cinder-volumes" ++ } ++ }, ++ "component": "heat_engine", ++ "container_address": "172.29.236.11", ++ "container_name": "controller-1", ++ "container_networks": { ++ "ens255f0_address": { ++ "address": "172.29.236.11", ++ "bridge": "ens255f0", ++ "netmask": null, ++ "type": "veth" ++ }, ++ "storage_address": { ++ "bridge": "vlan978", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ }, ++ "tunnel_address": { ++ "bridge": "vlan1002", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ } ++ }, ++ "container_types": "controller-1-host_containers", ++ "is_metal": true, ++ "physical_host": "controller-1", ++ "physical_host_group": "orchestration_hosts", ++ "properties": { ++ "is_metal": true, ++ "service_name": "heat" ++ }, ++ "swift_proxy_vars": { ++ "read_affinity": "r1=100", ++ "write_affinity": "r1", ++ "write_affinity_node_count": "1 * replicas" ++ }, ++ "swift_vars": { ++ "region": 1, ++ "zone": 0 ++ } ++ }, ++ "controller-2": { ++ "ansible_host": "172.29.236.14", ++ "component": "heat_engine", ++ "container_address": "172.29.236.14", ++ "container_name": "controller-2", ++ "container_networks": { ++ "ens255f0_address": { ++ "address": "172.29.236.14", ++ "bridge": "ens255f0", ++ "netmask": null, ++ "type": "veth" ++ }, ++ "storage_address": { ++ "bridge": "vlan978", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ }, ++ "tunnel_address": { ++ "bridge": "vlan1002", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ } ++ }, ++ "container_types": "controller-2-host_containers", ++ "is_metal": true, ++ "os_net_config": { ++ "network_config": [ ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.236.14/24" ++ } ++ ], ++ "dns_servers": [ ++ "172.29.236.11", ++ "10.39.12.252" ++ ], ++ "name": "ens255f0", ++ "type": "interface", ++ "use_dhcp": false ++ }, ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.244.14/24" ++ } ++ ], ++ "device": "ens4f0", ++ "type": "vlan", ++ "use_dhcp": false, ++ "vlan_id": 978 ++ }, ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.240.14/24" ++ } ++ ], ++ "device": "ens4f0", ++ "type": "vlan", ++ "use_dhcp": false, ++ "vlan_id": 1002 ++ }, ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "10.39.172.11/24" ++ } ++ ], ++ "device": "ens4f0", ++ "dns_servers": [ ++ "10.39.12.252" ++ ], ++ "routes": [ ++ { ++ "ip_netmask": "0.0.0.0/0", ++ "next_hop": "10.39.172.254" ++ } ++ ], ++ "type": "vlan", ++ "use_dhcp": false, ++ "vlan_id": 902 ++ } ++ ] ++ }, ++ "physical_host": "controller-2", ++ "physical_host_group": "orchestration_hosts", ++ "properties": { ++ "is_metal": true, ++ "service_name": "heat" ++ } ++ }, ++ "controller-3": { ++ "ansible_host": "172.29.236.15", ++ "component": "heat_engine", ++ "container_address": "172.29.236.15", ++ "container_name": "controller-3", ++ "container_networks": { ++ "ens255f0_address": { ++ "address": "172.29.236.15", ++ "bridge": "ens255f0", ++ "netmask": null, ++ "type": "veth" ++ }, ++ "storage_address": { ++ "bridge": "vlan978", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ }, ++ "tunnel_address": { ++ "bridge": "vlan1002", ++ "netmask": "255.255.255.0", ++ "type": "veth" ++ } ++ }, ++ "container_types": "controller-3-host_containers", ++ "is_metal": true, ++ "os_net_config": { ++ "network_config": [ ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.236.15/24" ++ } ++ ], ++ "dns_servers": [ ++ "172.29.236.11", ++ "10.39.12.252" ++ ], ++ "name": "ens255f0", ++ "type": "interface", ++ "use_dhcp": false ++ }, ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.244.15/24" ++ } ++ ], ++ "device": "ens4f0", ++ "type": "vlan", ++ "use_dhcp": false, ++ "vlan_id": 978 ++ }, ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "172.29.240.15/24" ++ } ++ ], ++ "device": "ens4f0", ++ "type": "vlan", ++ "use_dhcp": false, ++ "vlan_id": 1002 ++ }, ++ { ++ "addresses": [ ++ { ++ "ip_netmask": "10.39.172.12/24" ++ } ++ ], ++ "device": "ens4f0", ++ "dns_servers": [ ++ "10.39.12.252" ++ ], ++ "routes": [ ++ { ++ "ip_netmask": "0.0.0.0/0", ++ "next_hop": "10.39.172.254" ++ } ++ ], ++ "type": "vlan", ++ "use_dhcp": false, ++ "vlan_id": 902 ++ } ++ ] ++ }, ++ "physical_host": "controller-3", ++ "physical_host_group": "orchestration_hosts", ++ "properties": { ++ "is_metal": true, ++ "service_name": "heat" ++ } ++ } ++ } ++ }, ++ "all": { ++ "vars": { ++ "baremetal_flavor": [ ++ { ++ "disk": 10, ++ "extra_specs": { ++ "capabilities:boot_option": "local", ++ "cpu_arch": "x86_64" ++ }, ++ "name": "baremetal", ++ "ram": 13999, ++ "vcpus": 8 ++ } ++ ], ++ "baremetal_images": [ ++ { ++ "container_format": "bare", ++ "disk_format": "raw", ++ "file": "/opt/ncio/overcloudimages/guest-image.img", ++ "name": "golden" ++ }, ++ { ++ "container_format": "aki", ++ "disk_format": "aki", ++ "file": "/opt/ncio/overcloudimages/ironic-python-agent.kernel", ++ "name": "ipa-kernel" ++ }, ++ { ++ "container_format": "ari", ++ "disk_format": "ari", ++ "file": "/opt/ncio/overcloudimages/ironic-python-agent.initramfs", ++ "name": "ipa-ramdisk" ++ } ++ ], ++ "baremetal_ironic_nodes": [ ++ { ++ "driver": "pxe_ipmitool", ++ "driver_info": { ++ "power": { ++ "ipmi_address": "10.38.241.133", ++ "ipmi_password": "admin", ++ "ipmi_username": "admin" ++ } ++ }, ++ "name": "controller-2", ++ "network_interface": "flat", ++ "nics": [ ++ { ++ "mac": "54:AB:3A:14:11:5A" ++ } ++ ], ++ "properties": { ++ "capabilities": "boot_option:local", ++ "cpu_arch": "x86_64", ++ "cpus": 8, ++ "disk_size": 40, ++ "ram": 16384 ++ } ++ }, ++ { ++ "driver": "pxe_ipmitool", ++ "driver_info": { ++ "power": { ++ "ipmi_address": "10.38.241.132", ++ "ipmi_password": "admin", ++ "ipmi_username": "admin" ++ } ++ }, ++ "name": "controller-3", ++ "network_interface": "flat", ++ "nics": [ ++ { ++ "mac": "54:AB:3A:14:0D:2E" ++ } ++ ], ++ "properties": { ++ "capabilities": "boot_option:local", ++ "cpu_arch": "x86_64", ++ "cpus": 8, ++ "disk_size": 40, ++ "ram": 16384 ++ } ++ }, ++ { ++ "driver": "pxe_ipmitool", ++ "driver_info": { ++ "power": { ++ "ipmi_address": "10.38.241.131", ++ "ipmi_password": "admin", ++ "ipmi_username": "admin" ++ } ++ }, ++ "name": "compute-1", ++ "network_interface": "flat", ++ "nics": [ ++ { ++ "mac": "54:AB:3A:14:10:D6" ++ } ++ ], ++ "properties": { ++ "capabilities": "boot_option:local", ++ "cpu_arch": "x86_64", ++ "cpus": 8, ++ "disk_size": 40, ++ "ram": 16384 ++ } ++ } ++ ], ++ "baremetal_networks": [ ++ { ++ "allocation_pool_end": "172.29.236.50", ++ "allocation_pool_start": "172.29.236.14", ++ "cidr": "172.29.236.0/24", ++ "net_name": "provisioning_net", ++ "provider_network_type": "flat", ++ "provider_physical_network": "flat", ++ "subnet_name": "provisioning_subnet" ++ } ++ ], ++ "baremetal_nova_nodes": [ ++ { ++ "flavor_name": "baremetal", ++ "image_name": "golden", ++ "networks_list": [ ++ { ++ "net-name": "provisioning_net", ++ "v4-fixed-ip": "172.29.236.14" ++ } ++ ], ++ "node_name": "controller-2", ++ "userdata": "#cloud-config\nusers:\n - name: ncioadmin\n sudo: ['ALL=(ALL) NOPASSWD:ALL']\n ssh-authorized-keys:\n - \"{{ lookup('file', ansible_env.PWD + '/.ssh/id_rsa.pub') }}\"\n" ++ }, ++ { ++ "flavor_name": "baremetal", ++ "image_name": "golden", ++ "networks_list": [ ++ { ++ "net-name": "provisioning_net", ++ "v4-fixed-ip": "172.29.236.15" ++ } ++ ], ++ "node_name": "controller-3", ++ "userdata": "#cloud-config\nusers:\n - name: ncioadmin\n sudo: ['ALL=(ALL) NOPASSWD:ALL']\n ssh-authorized-keys:\n - \"{{ lookup('file', ansible_env.PWD + '/.ssh/id_rsa.pub') }}\"\n" ++ }, ++ { ++ "flavor_name": "baremetal", ++ "image_name": "golden", ++ "networks_list": [ ++ { ++ "net-name": "provisioning_net", ++ "v4-fixed-ip": "172.29.236.16" ++ } ++ ], ++ "node_name": "compute-1", ++ "userdata": "#cloud-config\nusers:\n - name: ncioadmin\n sudo: ['ALL=(ALL) NOPASSWD:ALL']\n ssh-authorized-keys:\n - \"{{ lookup('file', ansible_env.PWD + '/.ssh/id_rsa.pub') }}\"\n" ++ } ++ ], ++ "container_cidr": "172.29.236.0/24", ++ "external_lb_vip_address": "10.39.172.15", ++ "galera_initial_setup": false, ++ "internal_lb_vip_address": "172.29.236.110", ++ "management_bridge": "ens255f0", ++ "ntp_servers": [ ++ "10.39.172.254" ++ ], ++ "provider_networks": [ ++ { ++ "network": { ++ "container_bridge": "ens255f0", ++ "container_interface": "ens255f0", ++ "container_type": "veth", ++ "group_binds": [ ++ "neutron_linuxbridge_agent", ++ "all_containers", ++ "hosts" ++ ], ++ "host_bind_override": "ens255f0", ++ "is_container_address": true, ++ "is_ssh_address": true, ++ "net_name": "flat", ++ "type": "flat" ++ } ++ }, ++ { ++ "network": { ++ "container_bridge": "vlan1002", ++ "container_interface": "vlan1002", ++ "container_type": "veth", ++ "group_binds": [ ++ "neutron_linuxbridge_agent", ++ "neutron-openvswitch-agent" ++ ], ++ "ip_from_q": "tunnel", ++ "net_name": "vxlan", ++ "range": "1:1000", ++ "type": "vxlan" ++ } ++ }, ++ { ++ "network": { ++ "container_bridge": "vlan978", ++ "container_interface": "vlan978", ++ "container_type": "veth", ++ "group_binds": [ ++ "glance_api", ++ "cinder_api", ++ "cinder_volume", ++ "nova_compute" ++ ], ++ "ip_from_q": "storage", ++ "type": "raw" ++ } ++ } ++ ], ++ "swift": { ++ "drives": [ ++ { ++ "name": "swift1.img" ++ }, ++ { ++ "name": "swift2.img" ++ }, ++ { ++ "name": "swift3.img" ++ } ++ ], ++ "mount_point": "/srv", ++ "part_power": 8, ++ "replication_network": "vlan978", ++ "storage_network": "vlan978", ++ "storage_policies": [ ++ { ++ "policy": { ++ "default": true, ++ "index": 0, ++ "name": "default" ++ } ++ } ++ ] ++ }, ++ "tunnel_bridge": "vlan1002" ++ } ++ }, ++ "all_containers": { ++ "children": [ ++ "unbound_containers", ++ "ceph-osd_containers", ++ "orchestration_containers", ++ "operator_containers", ++ "memcaching_containers", ++ "metering-infra_containers", ++ "trove-infra_containers", ++ "ironic-infra_containers", ++ "ceph-mon_containers", ++ "swift_containers", ++ "storage_containers", ++ "ironic-server_containers", ++ "mq_containers", ++ "shared-infra_containers", ++ "compute_containers", ++ "storage-infra_containers", ++ "swift-proxy_containers", ++ "haproxy_containers", ++ "key-manager_containers", ++ "metering-alarm_containers", ++ "magnum-infra_containers", ++ "network_containers", ++ "sahara-infra_containers", ++ "os-infra_containers", ++ "image_containers", ++ "compute-infra_containers", ++ "log_containers", ++ "ironic-compute_containers", ++ "metering-compute_containers", ++ "identity_containers", ++ "dashboard_containers", ++ "dnsaas_containers", ++ "database_containers", ++ "metrics_containers", ++ "repo-infra_containers" ++ ], ++ "hosts": [] ++ }, ++ "aodh_alarm_evaluator": { ++ "children": [], ++ "hosts": [] ++ }, ++ "aodh_alarm_notifier": { ++ "children": [], ++ "hosts": [] ++ }, ++ "aodh_all": { ++ "children": [ ++ "aodh_alarm_notifier", ++ "aodh_api", ++ "aodh_alarm_evaluator", ++ "aodh_listener" ++ ], ++ "hosts": [] ++ }, ++ "aodh_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "aodh_container": { ++ "hosts": [] ++ }, ++ "aodh_listener": { ++ "children": [], ++ "hosts": [] ++ }, ++ "barbican_all": { ++ "children": [ ++ "barbican_api" ++ ], ++ "hosts": [] ++ }, ++ "barbican_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "barbican_container": { ++ "hosts": [] ++ }, ++ "baremetal-infra_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "baremetal-interface_config_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "compute-1" ++ ] ++ }, ++ "ceilometer_agent_central": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_agent_compute": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_agent_notification": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_all": { ++ "children": [ ++ "ceilometer_agent_central", ++ "ceilometer_agent_notification", ++ "ceilometer_api", ++ "ceilometer_collector", ++ "ceilometer_agent_compute" ++ ], ++ "hosts": [] ++ }, ++ "ceilometer_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_api_container": { ++ "hosts": [] ++ }, ++ "ceilometer_collector": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceilometer_collector_container": { ++ "hosts": [] ++ }, ++ "ceph-mon": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-mon_container": { ++ "hosts": [] ++ }, ++ "ceph-mon_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-mon_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-osd": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-osd_container": { ++ "hosts": [] ++ }, ++ "ceph-osd_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph-osd_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ceph_all": { ++ "children": [ ++ "ceph-mon", ++ "ceph-osd" ++ ], ++ "hosts": [] ++ }, ++ "cinder_all": { ++ "children": [ ++ "cinder_api", ++ "cinder_backup", ++ "cinder_volume", ++ "cinder_scheduler" ++ ], ++ "hosts": [] ++ }, ++ "cinder_api": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "cinder_api_container": { ++ "hosts": [] ++ }, ++ "cinder_backup": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "cinder_scheduler": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "cinder_scheduler_container": { ++ "hosts": [] ++ }, ++ "cinder_volume": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "cinder_volumes_container": { ++ "hosts": [] ++ }, ++ "compute-infra_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "compute-infra_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "compute-infra_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "compute_all": { ++ "hosts": [ ++ "compute-1" ++ ] ++ }, ++ "compute_containers": { ++ "children": [ ++ "compute-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "compute_hosts": { ++ "hosts": [ ++ "compute-1" ++ ] ++ }, ++ "dashboard_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "dashboard_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "dashboard_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "database_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "database_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_all": { ++ "children": [ ++ "designate_producer", ++ "designate_mdns", ++ "designate_api", ++ "designate_worker", ++ "designate_central", ++ "designate_sink" ++ ], ++ "hosts": [] ++ }, ++ "designate_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_central": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_container": { ++ "hosts": [] ++ }, ++ "designate_mdns": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_producer": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_sink": { ++ "children": [], ++ "hosts": [] ++ }, ++ "designate_worker": { ++ "children": [], ++ "hosts": [] ++ }, ++ "dnsaas_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "dnsaas_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "galera": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "galera_all": { ++ "children": [ ++ "galera" ++ ], ++ "hosts": [] ++ }, ++ "galera_container": { ++ "hosts": [] ++ }, ++ "glance_all": { ++ "children": [ ++ "glance_registry", ++ "glance_api" ++ ], ++ "hosts": [] ++ }, ++ "glance_api": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "glance_container": { ++ "hosts": [] ++ }, ++ "glance_registry": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "gnocchi_all": { ++ "children": [ ++ "gnocchi_api", ++ "gnocchi_metricd" ++ ], ++ "hosts": [] ++ }, ++ "gnocchi_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "gnocchi_container": { ++ "hosts": [] ++ }, ++ "gnocchi_metricd": { ++ "children": [], ++ "hosts": [] ++ }, ++ "haproxy": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "haproxy_all": { ++ "children": [ ++ "haproxy" ++ ], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "haproxy_container": { ++ "hosts": [] ++ }, ++ "haproxy_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "haproxy_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "heat_all": { ++ "children": [ ++ "heat_api", ++ "heat_engine", ++ "heat_api_cloudwatch", ++ "heat_api_cfn" ++ ], ++ "hosts": [] ++ }, ++ "heat_api": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "heat_api_cfn": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "heat_api_cloudwatch": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "heat_apis_container": { ++ "hosts": [] ++ }, ++ "heat_engine": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "heat_engine_container": { ++ "hosts": [] ++ }, ++ "horizon": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "horizon_all": { ++ "children": [ ++ "horizon" ++ ], ++ "hosts": [] ++ }, ++ "horizon_container": { ++ "hosts": [] ++ }, ++ "hosts": { ++ "children": [ ++ "memcaching_hosts", ++ "metering-compute_hosts", ++ "image_hosts", ++ "shared-infra_hosts", ++ "storage_hosts", ++ "metering-infra_hosts", ++ "os-infra_hosts", ++ "ironic-server_hosts", ++ "key-manager_hosts", ++ "ceph-osd_hosts", ++ "dnsaas_hosts", ++ "network_hosts", ++ "haproxy_hosts", ++ "mq_hosts", ++ "database_hosts", ++ "swift-proxy_hosts", ++ "trove-infra_hosts", ++ "ironic-compute_hosts", ++ "metering-alarm_hosts", ++ "log_hosts", ++ "ceph-mon_hosts", ++ "compute_hosts", ++ "orchestration_hosts", ++ "compute-infra_hosts", ++ "identity_hosts", ++ "unbound_hosts", ++ "swift_hosts", ++ "sahara-infra_hosts", ++ "magnum-infra_hosts", ++ "ironic-infra_hosts", ++ "metrics_hosts", ++ "dashboard_hosts", ++ "storage-infra_hosts", ++ "operator_hosts", ++ "repo-infra_hosts" ++ ], ++ "hosts": [] ++ }, ++ "identity_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "identity_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "identity_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "image_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "image_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "image_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "ironic-compute_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ironic-compute_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "ironic-compute_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ironic-infra_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "ironic-infra_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "ironic-infra_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "ironic-server_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ironic-server_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ironic_all": { ++ "children": [ ++ "ironic_conductor", ++ "ironic_api" ++ ], ++ "hosts": [] ++ }, ++ "ironic_api": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "ironic_api_container": { ++ "hosts": [] ++ }, ++ "ironic_compute": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "ironic_compute_container": { ++ "hosts": [] ++ }, ++ "ironic_conductor": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "ironic_conductor_container": { ++ "hosts": [] ++ }, ++ "ironic_server": { ++ "children": [], ++ "hosts": [] ++ }, ++ "ironic_server_container": { ++ "hosts": [] ++ }, ++ "ironic_servers": { ++ "children": [ ++ "ironic_server" ++ ], ++ "hosts": [] ++ }, ++ "key-manager_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "key-manager_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "keystone": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "keystone_all": { ++ "children": [ ++ "keystone" ++ ], ++ "hosts": [] ++ }, ++ "keystone_container": { ++ "hosts": [] ++ }, ++ "log_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "log_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "lxc_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1", ++ "compute-1" ++ ] ++ }, ++ "magnum": { ++ "children": [], ++ "hosts": [] ++ }, ++ "magnum-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "magnum-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "magnum_all": { ++ "children": [ ++ "magnum" ++ ], ++ "hosts": [] ++ }, ++ "magnum_container": { ++ "hosts": [] ++ }, ++ "memcached": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "memcached_all": { ++ "children": [ ++ "memcached" ++ ], ++ "hosts": [] ++ }, ++ "memcached_container": { ++ "hosts": [] ++ }, ++ "memcaching_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "memcaching_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-alarm_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-alarm_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-compute_container": { ++ "hosts": [] ++ }, ++ "metering-compute_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-compute_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metering-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metrics_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "metrics_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "mq_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "mq_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "network_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "network_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "network_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_agents_container": { ++ "hosts": [] ++ }, ++ "neutron_all": { ++ "children": [ ++ "neutron_agent", ++ "neutron_metadata_agent", ++ "neutron_linuxbridge_agent", ++ "neutron_bgp_dragent", ++ "neutron_dhcp_agent", ++ "neutron_lbaas_agent", ++ "neutron_l3_agent", ++ "neutron_metering_agent", ++ "neutron_server", ++ "neutron_sriov_nic_agent", ++ "neutron_openvswitch_agent" ++ ], ++ "hosts": [] ++ }, ++ "neutron_bgp_dragent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_dhcp_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_l3_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_lbaas_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_linuxbridge_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1", ++ "compute-1" ++ ] ++ }, ++ "neutron_metadata_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_metering_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_openvswitch_agent": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1", ++ "compute-1" ++ ] ++ }, ++ "neutron_server": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "neutron_server_container": { ++ "hosts": [] ++ }, ++ "neutron_sriov_nic_agent": { ++ "children": [], ++ "hosts": [ ++ "compute-1" ++ ] ++ }, ++ "nova_all": { ++ "children": [ ++ "nova_console", ++ "nova_scheduler", ++ "ironic_compute", ++ "nova_api_placement", ++ "nova_api_metadata", ++ "nova_api_os_compute", ++ "nova_conductor", ++ "nova_compute" ++ ], ++ "hosts": [] ++ }, ++ "nova_api_metadata": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "nova_api_metadata_container": { ++ "hosts": [] ++ }, ++ "nova_api_os_compute": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "nova_api_os_compute_container": { ++ "hosts": [] ++ }, ++ "nova_api_placement": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "nova_api_placement_container": { ++ "hosts": [] ++ }, ++ "nova_compute": { ++ "children": [], ++ "hosts": [ ++ "controller-1", ++ "compute-1" ++ ] ++ }, ++ "nova_compute_container": { ++ "hosts": [] ++ }, ++ "nova_conductor": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "nova_conductor_container": { ++ "hosts": [] ++ }, ++ "nova_console": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "nova_console_container": { ++ "hosts": [] ++ }, ++ "nova_scheduler": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "nova_scheduler_container": { ++ "hosts": [] ++ }, ++ "operator_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "operator_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "orchestration_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "orchestration_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "orchestration_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "os-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "os-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "pkg_repo": { ++ "children": [], ++ "hosts": [] ++ }, ++ "rabbit_mq_container": { ++ "hosts": [] ++ }, ++ "rabbitmq": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "rabbitmq_all": { ++ "children": [ ++ "rabbitmq" ++ ], ++ "hosts": [] ++ }, ++ "remote": { ++ "children": [ ++ "swift-remote_hosts" ++ ], ++ "hosts": [] ++ }, ++ "remote_containers": { ++ "children": [ ++ "swift-remote_containers" ++ ], ++ "hosts": [] ++ }, ++ "repo-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "repo-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "repo_all": { ++ "children": [ ++ "pkg_repo" ++ ], ++ "hosts": [] ++ }, ++ "repo_container": { ++ "hosts": [] ++ }, ++ "rsyslog": { ++ "children": [], ++ "hosts": [] ++ }, ++ "rsyslog_all": { ++ "children": [ ++ "rsyslog" ++ ], ++ "hosts": [] ++ }, ++ "rsyslog_container": { ++ "hosts": [] ++ }, ++ "sahara-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "sahara-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "sahara_all": { ++ "children": [ ++ "sahara_api", ++ "sahara_engine" ++ ], ++ "hosts": [] ++ }, ++ "sahara_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "sahara_container": { ++ "hosts": [] ++ }, ++ "sahara_engine": { ++ "children": [], ++ "hosts": [] ++ }, ++ "shared-infra_all": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "shared-infra_containers": { ++ "children": [ ++ "controller-3-host_containers", ++ "controller-2-host_containers", ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "shared-infra_hosts": { ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "storage-infra_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "storage-infra_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "storage-infra_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "storage_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "storage_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "storage_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift-proxy_all": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift-proxy_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "swift-proxy_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift-remote_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "swift-remote_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "swift_acc": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_acc_container": { ++ "hosts": [] ++ }, ++ "swift_all": { ++ "children": [ ++ "swift_cont", ++ "swift_obj", ++ "swift_proxy", ++ "swift_acc" ++ ], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_cont": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_cont_container": { ++ "hosts": [] ++ }, ++ "swift_containers": { ++ "children": [ ++ "controller-1-host_containers" ++ ], ++ "hosts": [] ++ }, ++ "swift_hosts": { ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_obj": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_obj_container": { ++ "hosts": [] ++ }, ++ "swift_proxy": { ++ "children": [], ++ "hosts": [ ++ "controller-1" ++ ] ++ }, ++ "swift_proxy_container": { ++ "hosts": [] ++ }, ++ "swift_remote": { ++ "children": [], ++ "hosts": [] ++ }, ++ "swift_remote_all": { ++ "children": [ ++ "swift_remote" ++ ], ++ "hosts": [] ++ }, ++ "swift_remote_container": { ++ "hosts": [] ++ }, ++ "trove-infra_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove-infra_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove_all": { ++ "children": [ ++ "trove_conductor", ++ "trove_taskmanager", ++ "trove_api" ++ ], ++ "hosts": [] ++ }, ++ "trove_api": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove_api_container": { ++ "hosts": [] ++ }, ++ "trove_conductor": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove_conductor_container": { ++ "hosts": [] ++ }, ++ "trove_taskmanager": { ++ "children": [], ++ "hosts": [] ++ }, ++ "trove_taskmanager_container": { ++ "hosts": [] ++ }, ++ "unbound": { ++ "children": [], ++ "hosts": [] ++ }, ++ "unbound_all": { ++ "children": [ ++ "unbound" ++ ], ++ "hosts": [] ++ }, ++ "unbound_container": { ++ "hosts": [] ++ }, ++ "unbound_containers": { ++ "children": [], ++ "hosts": [] ++ }, ++ "unbound_hosts": { ++ "children": [], ++ "hosts": [] ++ }, ++ "utility": { ++ "children": [], ++ "hosts": [ ++ "controller-3", ++ "controller-2", ++ "controller-1" ++ ] ++ }, ++ "utility_all": { ++ "children": [ ++ "utility" ++ ], ++ "hosts": [] ++ }, ++ "utility_container": { ++ "hosts": [] ++ } ++} +\ No newline at end of file +diff --git a/tests/roles/bootstrap-host/defaults/main.yml b/tests/roles/bootstrap-host/defaults/main.yml +deleted file mode 100644 +index 13033f32..00000000 +--- a/tests/roles/bootstrap-host/defaults/main.yml ++++ /dev/null +@@ -1,231 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, 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. +- +-## AIO user-space configuration options +-# Scenario used to bootstrap the host +-bootstrap_host_scenario: aio_lxc +-# +-# Boolean option to implement OpenStack-Ansible configuration for an AIO +-# Switch to no for a multi-node configuration +-bootstrap_host_aio_config: yes +-# +-# Path to the location of the bootstrapping configuration files +-bootstrap_host_aio_config_path: "{{ playbook_dir }}/../etc/openstack_deploy" +-# +-# Path to the location of the scripts the bootstrap scripts use +-bootstrap_host_aio_script_path: "{{ playbook_dir }}/../scripts" +-# +-# The user space configuration file names to use +-bootstrap_host_user_variables_filename: "user_variables.yml" +-bootstrap_host_user_secrets_filename: "user_secrets.yml" +-# +-# Paths to configuration file targets that should be created by the bootstrap +-bootstrap_host_target_config_paths: +- - /etc/openstack_deploy +- - /etc/openstack_deploy/conf.d +- - /etc/openstack_deploy/env.d +- +-# The user variables template to use +-bootstrap_user_variables_template: user_variables.aio.yml.j2 +- +-# Extra user variables files can be loaded into /etc/openstack_deploy by +-# test scenarios. The dict uses scenario as the key to load a list of extra +-# templates if necessary. +-bootstrap_user_variables_extra_templates: +- ceph: +- - src: user_variables_ceph.yml.j2 +- dest: user_variables_ceph.yml +- translations: +- - src: user_variables_translations.yml.j2 +- dest: user_variables_translations.yml +- octavia: +- - src: user_variables_octavia.yml.j2 +- dest: user_variables_octavia.yml +- +-## Swap memory +-# If there is no swap memory present, the bootstrap will create a loopback disk +-# for the purpose of having swap memory available. Swap is required for some of +-# the services deployed and is useful for AIO's built with less than 16GB memory. +-# By default the swap size is set to 8GB unless the host memory is less than 8GB, +-# in which case it is set to 4GB. +-bootstrap_host_swap_size: "{% if ansible_memory_mb['real']['total'] < 8*1024 %}4{% else %}8{% endif %}" +- +-## Loopback volumes +-# Sparse loopback disks are used for the containers if there is no secondary +-# disk available to partition for btrfs. They are also used for Ceph, Cinder, +-# Swift and Nova (instance storage). +-# The size of the loopback volumes can be customized here (in gigabytes). +-# +-# Size of the machines loopback disk in gigabytes (GB). +-bootstrap_host_loopback_machines_size: 128 +-# +-# Boolean option to deploy the loopback disk for Cinder +-bootstrap_host_loopback_cinder: yes +-# Size of the Cinder loopback disk in gigabytes (GB). +-bootstrap_host_loopback_cinder_size: 1024 +-# +-# Boolean option to deploy the loopback disk for Swift +-bootstrap_host_loopback_swift: yes +-# Size of the Swift loopback disk in gigabytes (GB). +-bootstrap_host_loopback_swift_size: 1024 +-# +-# Boolean option to deploy the loopback disk for Nova +-bootstrap_host_loopback_nova: yes +-# Size of the Nova loopback disk in gigabytes (GB). +-bootstrap_host_loopback_nova_size: 1024 +- +-# Boolean option to deploy the OSD loopback disks and cluster UUID for Ceph +-bootstrap_host_ceph: "{{ (bootstrap_host_scenario == 'ceph') | bool }}" +-# Size of the Ceph OSD loopbacks +-bootstrap_host_loopback_ceph_size: 1024 +-# Ceph OSDs to create on the AIO host +-ceph_osd_images: +- - 'ceph1' +- - 'ceph2' +- - 'ceph3' +- +-## Network configuration +-# The AIO bootstrap configures bridges for use with the AIO deployment. +-# By default, these bridges are configured to be independent of any physical +-# interfaces, and they have their 'bridge_ports' set to 'none'. However, +-# deployers can add a physical interface to 'bridge_ports' to connect the +-# bridge to a real physical interface. +-# +-# A setting of 'none' keeps the bridges as independent from physical +-# interfaces (the default). +-# +-# Setting the value to 'eth1' would mean that the bridge is directly connected +-# to the eth1 device. +-# +-# See https://wiki.debian.org/BridgeNetworkConnections for more details. +-bootstrap_host_bridge_mgmt_ports: none +-bootstrap_host_bridge_vxlan_ports: none +-bootstrap_host_bridge_storage_ports: none +-bootstrap_host_bridge_vlan_ports: "br-vlan-veth" +-# This enables the VXLAN encapsulation the traditional bridges +-# (br-mgmt, br-vxlan, br-storage) +-bootstrap_host_encapsulation_enabled: "{{ not bootstrap_host_aio_config | bool }}" +-# +-# Default network IP ranges +-mgmt_range: "172.29.236" +-vxlan_range: "172.29.240" +-storage_range: "172.29.244" +-vlan_range: "172.29.248" +-netmask: "255.255.252.0" +-# +-# NICs +-bootstrap_host_public_interface: "{{ ansible_default_ipv4.interface }}" +-bootstrap_host_encapsulation_interface: eth1 +-# +-#Encapsulations +-bootstrap_host_encapsulation_interfaces: +- encap-mgmt: +- id: 236 +- underlay_device: "{{ bootstrap_host_encapsulation_interface }}" +- friendly_name: "Encapsulation of br-mgmt with VXLAN" +- encap-vxlan: +- id: 240 +- underlay_device: "{{ bootstrap_host_encapsulation_interface }}" +- friendly_name: "Encapsulation of br-vxlan with VXLAN" +- encap-storage: +- id: 244 +- underlay_device: "{{ bootstrap_host_encapsulation_interface }}" +- friendly_name: "Encapsulation of br-storage with VXLAN" +- encap-vlan: +- id: 248 +- underlay_device: "{{ bootstrap_host_encapsulation_interface }}" +- friendly_name: "Encapsulation of br-vlan with VXLAN" +-# +-# Bridges +-bridges: +- - name: "br-mgmt" +- ip_addr: "172.29.236.100" +- netmask: "255.255.252.0" +- - name: "br-vxlan" +- ip_addr: "172.29.240.100" +- netmask: "255.255.252.0" +- - name: "br-storage" +- ip_addr: "172.29.244.100" +- netmask: "255.255.252.0" +- - name: "br-vlan" +- ip_addr: "172.29.248.100" +- alias: "172.29.248.1" +- veth_peer: "eth12" +- netmask: "255.255.252.0" +- +-bootstrap_host_bridges_interfaces: +- br-mgmt: +- ports: "{{ bootstrap_host_encapsulation_enabled | bool | ternary ('encap-mgmt', bootstrap_host_bridge_mgmt_ports) }}" +- ip_address_range: "{{ mgmt_range }}" +- ip_netmask: "{{ netmask }}" +- br-storage: +- ports: "{{ bootstrap_host_encapsulation_enabled | bool | ternary ('encap-storage', bootstrap_host_bridge_storage_ports) }}" +- ip_address_range: "{{ storage_range }}" +- ip_netmask: "{{ netmask }}" +- br-vxlan: +- ports: "{{ bootstrap_host_encapsulation_enabled | bool | ternary ('encap-vxlan', bootstrap_host_bridge_vxlan_ports) }}" +- ip_address_range: "{{ vxlan_range }}" +- ip_netmask: "{{ netmask }}" +- br-vlan: +- mode: "{{ bridge_vlan_inet_mode | default('static') }}" +- ports: "{{ bootstrap_host_encapsulation_enabled | bool | ternary ('encap-vlan', bootstrap_host_bridge_vlan_ports) }}" +- ip_address_range: "{{ vlan_range }}" +- ip_netmask: "{{ netmask }}" +- state_change_scripts: "{{ bridge_vlan_state_change_scripts }}" +-# +-# Convenience scripts +-bridge_vlan_state_change_scripts: | +- pre-up ip link add br-vlan-veth type veth peer name eth12 || true +- pre-up ip link set br-vlan-veth up +- pre-up ip link set eth12 up +- post-down ip link del br-vlan-veth || true +-bridge_iptables_rules: | +- # To ensure ssh checksum is correct +- up /sbin/iptables -A POSTROUTING -t mangle -p tcp -o {{ bootstrap_host_public_interface }} -j CHECKSUM --checksum-fill +- down /sbin/iptables -D POSTROUTING -t mangle -p tcp -o {{ bootstrap_host_public_interface }} -j CHECKSUM --checksum-fill +- # To provide internet connectivity to instances +- up /sbin/iptables -t nat -A POSTROUTING -o {{ bootstrap_host_public_interface }} -j MASQUERADE +- down /sbin/iptables -t nat -D POSTROUTING -o {{ bootstrap_host_public_interface }} -j MASQUERADE +- +-# Set the container technology in service. Options are lxc. +-container_tech: "lxc" +- +-## Extra storage +-# An AIO may optionally be built using a second storage device. If a +-# secondary disk device to use is not specified, then the AIO will be +-# built on any existing disk partitions. +-# +-# WARNING: The data on a secondary storage device specified here will +-# be destroyed and repartitioned. +-# +-# Specify the secondary disk device to use. +-bootstrap_host_data_disk_device: null +-# +-# Boolean value to force the repartitioning of the secondary device. +-bootstrap_host_data_disk_device_force: no +-# +-# If the storage capacity on this device is greater than or equal to this +-# size (in GB), the bootstrap process will use it. +-bootstrap_host_data_disk_min_size: 50 +- +-# Boolean option to build Amphora image and certs +-bootstrap_host_octavia: "{{ (bootstrap_host_scenario in ['octavia', 'translations']) | bool }}" +- +-### Optional Settings ### +- +-# Specify the public IP address for the host. +-# By default the address will be set to the ipv4 address of the +-# host's network interface that has the default route on it. +-#bootstrap_host_public_address: 0.0.0.0 +diff --git a/tests/roles/bootstrap-host/tasks/check-requirements.yml b/tests/roles/bootstrap-host/tasks/check-requirements.yml +deleted file mode 100644 +index 58782b4f..00000000 +--- a/tests/roles/bootstrap-host/tasks/check-requirements.yml ++++ /dev/null +@@ -1,97 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, 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. +- +-- name: Check for a supported Operating System +- assert: +- that: +- - (ansible_distribution == 'Ubuntu' and ansible_distribution_release == 'xenial') or +- (ansible_os_family == 'RedHat' and ansible_distribution_major_version == '7') or +- (ansible_os_family == 'Suse' and ansible_distribution_major_version == '42') +- msg: "The only supported platforms for this release are Ubuntu 16.04 LTS (Xenial), CentOS 7 (WIP) and openSUSE Leap 42.X (WIP)" +- tags: +- - check-operating-system +- +-- name: Identify the space available in / +- # NOTE(hwoarang): df does not work reliably on btrfs filesystems +- # https://btrfs.wiki.kernel.org/index.php/FAQ#How_much_free_space_do_I_have.3F +- # As such, use the btrfs tools to determine the real available size on the +- # disk +- shell: | +- if [[ $(df -T / | tail -n 1 | awk '{print $2}') == "btrfs" ]]; then +- btrfs fi usage --kbytes / | awk '/^.*Free / {print $3}'| sed 's/\..*//' +- else +- df -BK / | awk '!/^Filesystem/ {print $4}' | sed 's/K//' +- fi +- when: bootstrap_host_data_disk_device == None +- changed_when: false +- register: root_space_available +- tags: +- - check-disk-size +- +-# Convert root_space_available to bytes. +-- name: Set root disk facts +- set_fact: +- host_root_space_available_bytes: "{{ ( root_space_available.stdout | int) * 1024 | int }}" +- when: +- - bootstrap_host_data_disk_device == None +- tags: +- - check-disk-size +- +-- name: Set data disk facts +- set_fact: +- host_data_disk_sectors: "{{ (ansible_devices[bootstrap_host_data_disk_device]['sectors'] | int) }}" +- host_data_disk_sectorsize: "{{ (ansible_devices[bootstrap_host_data_disk_device]['sectorsize'] | int) }}" +- when: +- - bootstrap_host_data_disk_device != None +- tags: +- - check-disk-size +- +-# Calculate the size of the bootstrap_host_data_disk_device by muliplying sectors with sectorsize. +-- name: Calculate data disk size +- set_fact: +- host_data_disk_size_bytes: "{{ ((host_data_disk_sectors | int) * (host_data_disk_sectorsize | int)) | int }}" +- when: bootstrap_host_data_disk_device != None +- tags: +- - check-disk-size +- +-# Convert bootstrap_host_data_disk_min_size to bytes. +-- name: Set min size fact +- set_fact: +- host_data_disk_min_size_bytes: "{{ ((bootstrap_host_data_disk_min_size | int) * 1024**3) | int }}" +- tags: +- - check-disk-size +- +-- name: Fail if there is not enough space available in / +- assert: +- that: | +- (host_root_space_available_bytes | int) >= (host_data_disk_min_size_bytes | int) +- when: bootstrap_host_data_disk_device == None +- tags: +- - check-disk-size +- +-- name: Fail if there is not enough disk space available (disk specified) +- assert: +- that: | +- (host_data_disk_size_bytes | int) >= (host_data_disk_min_size_bytes | int) +- when: bootstrap_host_data_disk_device != None +- tags: +- - check-disk-size +- +-- name: Ensure that the kernel has VXLAN support +- modprobe: +- name: vxlan +- state: present +- tags: +- - check-vxlan +diff --git a/tests/roles/bootstrap-host/tasks/install_packages.yml b/tests/roles/bootstrap-host/tasks/install_packages.yml +deleted file mode 100644 +index e7ff5812..00000000 +--- a/tests/roles/bootstrap-host/tasks/install_packages.yml ++++ /dev/null +@@ -1,53 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, 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. +- +-- name: Install RDO package +- package: +- name: "{{ rdo_package }}" +- state: "present" +- register: install_cloud_rdo_package +- until: install_cloud_rdo_package | success +- retries: 5 +- delay: 2 +- when: +- - ansible_pkg_mgr in ['yum', 'dnf'] +- +-- name: Add zypper cloud repositories +- zypper_repository: +- auto_import_keys: yes +- autorefresh: yes +- name: "{{ item.name }}" +- repo: "{{ item.uri }}" +- runrefresh: yes +- with_items: "{{ opensuse_openstack_repos }}" +- retries: 5 +- delay: 2 +- when: +- - ansible_pkg_mgr == 'zypper' +- +-- name: Remove known problem packages +- package: +- name: "{{ packages_remove }}" +- state: absent +- tags: +- - remove-packages +- +-- name: Install packages +- package: +- name: "{{ packages_install }}" +- state: present +- update_cache: "{{ (ansible_pkg_mgr in ['apt', 'zypper']) | ternary('yes', omit) }}" +- tags: +- - install-packages +diff --git a/tests/roles/bootstrap-host/tasks/main.yml b/tests/roles/bootstrap-host/tasks/main.yml +deleted file mode 100644 +index e2533014..00000000 +--- a/tests/roles/bootstrap-host/tasks/main.yml ++++ /dev/null +@@ -1,126 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, 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. +- +-# Before we do anything, check the minimum requirements +-- include: check-requirements.yml +- tags: +- - check-requirements +- +-# We will look for the most specific variable files first and eventually +-# end up with the least-specific files. +-- name: Gather variables for each operating system +- include_vars: "{{ item }}" +- with_first_found: +- - "{{ ansible_distribution | lower }}-{{ ansible_distribution_version | lower }}.yml" +- - "{{ ansible_distribution | lower }}-{{ ansible_distribution_major_version | lower }}.yml" +- - "{{ ansible_os_family | lower }}-{{ ansible_distribution_major_version | lower }}.yml" +- - "{{ ansible_distribution | lower }}.yml" +- - "{{ ansible_os_family | lower }}.yml" +- tags: +- - always +- +-- name: Create the required directories +- file: +- path: "{{ item }}" +- state: directory +- with_items: +- - "/openstack" +- tags: +- - create-directories +- +-- include: install_packages.yml +- tags: +- - install-packages +- +-# Prepare the data disk, if one is provided +-- include: prepare_data_disk.yml +- when: bootstrap_host_data_disk_device != None +- tags: +- - prepare-data-disk +- +-# Prepare the Machines storage loopback disk +-# This is only necessary when there is no secondary disk +-# available to partition for btrfs +-- include: prepare_loopback_machines.yml +- when: +- - bootstrap_host_data_disk_device == None +- tags: +- - prepare-loopback-machines +- +-# Prepare the swap space loopback disk +-# This is only necessary if there isn't swap already +-- include: prepare_loopback_swap.yml +- static: no +- when: +- - ansible_swaptotal_mb < 1 +- tags: +- - prepare-loopback-swap +- +-# Prepare the Cinder LVM VG loopback disk +-# This is only necessary if bootstrap_host_loopback_cinder is set to yes +-- include: prepare_loopback_cinder.yml +- when: +- - bootstrap_host_loopback_cinder | bool +- tags: +- - prepare-loopback-cinder +- +-# Prepare the Nova instance storage loopback disk +-- include: prepare_loopback_nova.yml +- when: +- - bootstrap_host_loopback_nova | bool +- tags: +- - prepare-loopback-nova +- +-# Prepare the Swift data storage loopback disks +-- include: prepare_loopback_swift.yml +- when: +- - bootstrap_host_loopback_swift | bool +- tags: +- - prepare-loopback-swift +- +-# Prepare the Ceph cluster UUID and loopback disks +-- include: prepare_ceph.yml +- when: +- - bootstrap_host_ceph | bool +- tags: +- - prepare-ceph +- +-# Prepare the Octavia certs and image +-- include: prepare_octavia.yml +- when: +- - bootstrap_host_octavia | bool +- tags: +- - prepare-octavia +- +-# Ensure hostname/ip is consistent with inventory +-- include: prepare_hostname.yml +- tags: +- - prepare-hostname +- +-# Prepare the network interfaces +-- include: prepare_networking.yml +- tags: +- - prepare-networking +- +-# Ensure that there are both private and public ssh keys for root +-- include: prepare_ssh_keys.yml +- tags: +- - prepare-ssh-keys +- +-# Put the OpenStack-Ansible configuration for an All-In-One on the host +-- include: prepare_aio_config.yml +- when: bootstrap_host_aio_config | bool +- tags: +- - prepare-aio-config +diff --git a/tests/roles/bootstrap-host/tasks/prepare_aio_config.yml b/tests/roles/bootstrap-host/tasks/prepare_aio_config.yml +deleted file mode 100644 +index f9b0804d..00000000 +--- a/tests/roles/bootstrap-host/tasks/prepare_aio_config.yml ++++ /dev/null +@@ -1,243 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, 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. +- +- +-- name: Create the required deployment directories +- file: +- path: "{{ item }}" +- state: directory +- with_items: "{{ bootstrap_host_target_config_paths }}" +- tags: +- - create-directories +- +-- name: Deploy user conf.d configuration +- config_template: +- src: "{{ item.path | default(bootstrap_host_aio_config_path ~ '/conf.d') }}/{{ item.name }}" +- dest: "/etc/openstack_deploy/conf.d/{{ item.name | regex_replace('.aio$', '') }}" +- config_overrides: "{{ item.override | default({}) }}" +- config_type: "yaml" +- with_items: "{{ openstack_confd_entries | default([]) }}" +- tags: +- - deploy-confd +- +-- name: Deploy openstack_user_config +- config_template: +- src: "{{ bootstrap_host_aio_config_path }}/openstack_user_config.yml.aio.j2" +- dest: "/etc/openstack_deploy/openstack_user_config.yml" +- config_overrides: "{{ openstack_user_config_overrides | default({}) }}" +- config_type: "yaml" +- list_extend: false +- tags: +- - deploy-openstack-user-config +- +-- name: Deploy user_secrets file +- config_template: +- src: "{{ bootstrap_host_aio_config_path }}/user_secrets.yml" +- dest: "/etc/openstack_deploy/{{ bootstrap_host_user_secrets_filename }}" +- config_overrides: "{{ user_secrets_overrides | default({}) }}" +- config_type: "yaml" +- tags: +- - deploy-user-secrets +- +-- name: Generate any missing values in user_secrets +- command: "/opt/ansible-runtime/bin/python {{ bootstrap_host_aio_script_path }}/pw-token-gen.py --file /etc/openstack_deploy/{{ bootstrap_host_user_secrets_filename }}" +- changed_when: false +- tags: +- - generate_secrets +- +-- name: Detect whether the host is an OpenStack-CI host +- stat: +- path: /etc/nodepool +- register: nodepool_dir +- +-# OVH nodepool nodes have an issue which causes nested virt +-# instances to crash with a hardware error, then a dump. +-# We therefore detect whether we're running on OVH and +-# force it to use qemu instead. +-- name: Discover the OpenStack-Infra mirrors +- shell: | +- source /etc/ci/mirror_info.sh +- NODEPOOL_OVERRIDES="/etc/openstack_deploy/user_openstackci.yml" +- echo "uca_apt_repo_url: '${NODEPOOL_UCA_MIRROR}'" >> ${NODEPOOL_OVERRIDES} +- echo "openstack_hosts_centos_mirror_url: '${NODEPOOL_CENTOS_MIRROR}'" >> ${NODEPOOL_OVERRIDES} +- if [[ ${NODEPOOL_PYPI_MIRROR} == *.ovh.* ]]; then +- echo "nova_virt_type: 'qemu'" >> ${NODEPOOL_OVERRIDES} +- fi +- args: +- executable: /bin/bash +- when: +- - nodepool_dir.stat.exists | bool +- tags: +- - skip_ansible_lint +- +-- name: Discover the OpenStack-Infra pypi/wheel mirror +- shell: | +- source /etc/ci/mirror_info.sh +- echo "${NODEPOOL_PYPI_MIRROR}" +- echo "${NODEPOOL_WHEEL_MIRROR}" +- args: +- executable: /bin/bash +- register: _pypi_wheel_mirror +- when: +- - nodepool_dir.stat.exists | bool +- tags: +- - skip_ansible_lint +- +-- name: Discover the OpenStack-Infra LXC reverse proxy +- shell: | +- source /etc/ci/mirror_info.sh +- echo ${NODEPOOL_LXC_IMAGE_PROXY} +- register: _lxc_mirror +- args: +- executable: /bin/bash +- when: +- - nodepool_dir.stat.exists | bool +- tags: +- - skip_ansible_lint +- +-- name: Set the package cache timeout to 60 mins in OpenStack-CI +- set_fact: +- cache_timeout: 3600 +- when: +- - cache_timeout is not defined +- - nodepool_dir.stat.exists +- +-- name: Determine if the host has a global pip config file +- stat: +- path: /etc/pip.conf +- register: pip_conf_file +- +-# NOTE(mhayden): The OpenStack CI images for CentOS 7 recently set SELinux to +-# Enforcing mode by default. While I am normally a supporter of this change, +-# the SELinux policy work for CentOS 7 is not done yet. +-- name: Set SELinux to permissive mode in OpenStack-CI +- selinux: +- policy: targeted +- state: permissive +- when: +- - ansible_selinux.status is defined +- - ansible_selinux.status == "enabled" +- +-# This is a very dirty hack due to images.linuxcontainers.org +-# constantly failing to resolve in openstack-infra. +-- name: Implement hard-coded hosts entries for consistently failing name +- lineinfile: +- path: "/etc/hosts" +- line: "{{ item }}" +- state: present +- with_items: +- - "91.189.91.21 images.linuxcontainers.org us.images.linuxcontainers.org" +- - "91.189.88.37 images.linuxcontainers.org uk.images.linuxcontainers.org" +- when: +- - nodepool_dir.stat.exists +- +-- name: Determine the fastest available OpenStack-Infra wheel mirror +- command: "{{ bootstrap_host_aio_script_path }}/fastest-infra-wheel-mirror.py" +- register: fastest_wheel_mirror +- when: not pip_conf_file.stat.exists +- +-- name: Set repo_build_pip_extra_indexes fact +- set_fact: +- repo_build_pip_extra_indexes: "{{ fastest_wheel_mirror.stdout_lines }}" +- when: not pip_conf_file.stat.exists +- +-- name: Set the user_variables +- config_template: +- src: "{{ bootstrap_user_variables_template }}" +- dest: "/etc/openstack_deploy/{{ bootstrap_host_user_variables_filename }}" +- config_overrides: "{{ user_variables_overrides | default({}) }}" +- config_type: yaml +- +-- name: Drop the extra user_variables files for this scenario +- config_template: +- src: "{{ item.src }}" +- dest: "/etc/openstack_deploy/{{ item.dest }}" +- config_overrides: "{{ item.config_overrides | default({}) }}" +- config_type: yaml +- with_items: "{{ bootstrap_user_variables_extra_templates[bootstrap_host_scenario] | default([]) }}" +- +-- name: Copy modified cinder-volume env.d file for ceph scenario +- copy: +- src: "{{ playbook_dir }}/../etc/openstack_deploy/env.d/cinder-volume.yml.container.example" +- dest: "/etc/openstack_deploy/env.d/cinder-volume.yml" +- when: +- - "bootstrap_host_scenario == 'ceph'" +- +-- name: Copy modified env.d file for metal scenario +- copy: +- src: "{{ playbook_dir }}/../etc/openstack_deploy/env.d/aio_metal.yml.example" +- dest: "/etc/openstack_deploy/env.d/aio_metal.yml" +- when: +- - "bootstrap_host_scenario == 'aio_metal'" +- +-- name: Add user_conf_files to contain the list of files to copy into containers +- file: +- path: /etc/openstack_deploy/user_conf_files.yml +- state: touch +- when: pip_conf_file.stat.exists +- tags: +- - container-conf-files +- +-- name: Ensure that the first line in user_conf_files is correct +- lineinfile: +- dest: /etc/openstack_deploy/user_conf_files.yml +- line: "---" +- insertbefore: BOF +- when: pip_conf_file.stat.exists +- tags: +- - container-conf-files +- +-- name: Ensure that the second line in user_conf_files is correct +- lineinfile: +- dest: /etc/openstack_deploy/user_conf_files.yml +- line: "lxc_container_cache_files:" +- insertafter: "^---" +- when: pip_conf_file.stat.exists +- tags: +- - container-conf-files +- +-- name: Add the dict to copy the global pip config file into user_conf_files +- lineinfile: +- dest: /etc/openstack_deploy/user_conf_files.yml +- line: " - { src: '/etc/pip.conf', dest: '/etc/pip.conf' }" +- when: pip_conf_file.stat.exists +- tags: +- - container-conf-files +- +-- name: Create vars override folders if we need to test them +- file: +- path: "{{ item }}" +- state: directory +- with_items: +- - /etc/openstack_deploy/group_vars +- - /etc/openstack_deploy/host_vars +- when: "(lookup('env','ACTION') | default(false,true)) == 'varstest'" +- +-- name: Create user-space overrides +- lineinfile: +- path: "{{ item.path }}" +- state: present +- line: "{{ item.line }}" +- create: yes +- with_items: +- - path: /etc/openstack_deploy/group_vars/hosts.yml +- line: 'babar: "elephant"' +- - path: /etc/openstack_deploy/group_vars/hosts.yml +- line: 'lxc_hosts_package_state: "present"' +- - path: /etc/openstack_deploy/host_vars/localhost.yml +- line: 'security_package_state: "present"' +- - path: /etc/openstack_deploy/host_vars/localhost.yml +- line: 'tintin: "milou"' +- when: "(lookup('env','ACTION') | default(false,true)) == 'varstest'" +diff --git a/tests/roles/bootstrap-host/tasks/prepare_ceph.yml b/tests/roles/bootstrap-host/tasks/prepare_ceph.yml +deleted file mode 100644 +index efaba66b..00000000 +--- a/tests/roles/bootstrap-host/tasks/prepare_ceph.yml ++++ /dev/null +@@ -1,72 +0,0 @@ +---- +-# Copyright 2016, Logan Vig +-# +-# 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. +- +-- name: Create sparse ceph OSD files +- command: truncate -s {{ bootstrap_host_loopback_ceph_size }}G /openstack/{{ item }}.img +- args: +- creates: "/openstack/{{ item }}.img" +- with_items: "{{ ceph_osd_images }}" +- register: ceph_create +- changed_when: false +- tags: +- - ceph-file-create +- +-- name: Create the ceph loopback device +- command: losetup -f /openstack/{{ item.item }}.img --show +- with_items: "{{ ceph_create.results }}" +- register: ceph_create_loopback +- when: not item|skipped +- changed_when: false +- tags: +- - skip_ansible_lint +- +-- name: Ensure that rc.local exists +- file: +- path: "{{ rc_local }}" +- state: touch +- mode: "u+x" +- tags: +- - ceph-rc-file +- +-- name: Create ceph loopback at boot time +- lineinfile: +- dest: "{{ rc_local }}" +- line: "losetup -f /openstack/{{ item }}.img" +- insertbefore: "{{ rc_local_insert_before }}" +- with_items: "{{ ceph_osd_images }}" +- +-# TODO(logan): Move these vars to user_variables.ceph.yml.j2 once LP #1649381 +-# is fixed and eliminate this task. +-- name: Write ceph cluster config +- copy: +- content: | +- --- +- devices: {{ ceph_create_loopback.results | map(attribute='stdout') | list | to_yaml | trim }} +- cinder_backends: +- "RBD": +- volume_driver: cinder.volume.drivers.rbd.RBDDriver +- rbd_pool: volumes +- rbd_ceph_conf: /etc/ceph/ceph.conf +- rbd_store_chunk_size: 8 +- volume_backend_name: rbddriver +- rbd_user: cinder +- rbd_secret_uuid: "{% raw %}{{ cinder_ceph_client_uuid }}{% endraw %}" +- report_discard_supported: true +- dest: /etc/openstack_deploy/user_ceph_aio.yml +- force: no +- become: false +- when: not ceph_create_loopback|skipped +- tags: +- - skip_ansible_lint +diff --git a/tests/roles/bootstrap-host/tasks/prepare_data_disk.yml b/tests/roles/bootstrap-host/tasks/prepare_data_disk.yml +deleted file mode 100644 +index 0d4bc9a5..00000000 +--- a/tests/roles/bootstrap-host/tasks/prepare_data_disk.yml ++++ /dev/null +@@ -1,79 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, 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. +- +- +-# Only execute the disk partitioning process if a partition labeled +-# 'openstack-data{1,2}' is not present and that partition is not +-# formatted as ext4. This is an attempt to achieve idempotency just +-# in case these tasks are executed multiple times. +-- name: Determine whether partitions labeled openstack-data{1,2} are present +- shell: | +- parted --script -l -m | egrep -q ':ext4:openstack-data[12]:;$' +- register: data_disk_partitions +- changed_when: false +- failed_when: false +- tags: +- - check-data-disk-partitions +- +-- name: Dismount and remove fstab entries for anything on the data disk device +- mount: +- name: "{{ item.mount }}" +- src: "{{ item.device }}" +- fstype: ext4 +- state: absent +- when: +- - data_disk_partitions.rc == 1 or bootstrap_host_data_disk_device_force | bool +- - item.device | search(bootstrap_host_data_disk_device) +- with_items: +- - "{{ ansible_mounts }}" +- +-- name: Partition the whole data disk for our usage +- command: "{{ item }}" +- when: data_disk_partitions.rc == 1 or bootstrap_host_data_disk_device_force | bool +- with_items: +- - "parted --script /dev/{{ bootstrap_host_data_disk_device | regex_replace('!','/') }} mklabel gpt" +- - "parted --align optimal --script /dev/{{ bootstrap_host_data_disk_device | regex_replace('!','/') }} mkpart openstack-data1 ext4 0% 40%" +- - "parted --align optimal --script /dev/{{ bootstrap_host_data_disk_device | regex_replace('!','/') }} mkpart openstack-data2 btrfs 40% 100%" +- tags: +- - create-data-disk-partitions +- +-- name: Format the partitions +- filesystem: +- fstype: "{{ item.fstype }}" +- dev: "{{ item.dev }}" +- when: data_disk_partitions.rc == 1 or bootstrap_host_data_disk_device_force | bool +- with_items: +- - dev: "/dev/{{ bootstrap_host_data_disk_device | regex_replace('!(.*)$','/\\1p') }}1" +- fstype: "ext4" +- - dev: "/dev/{{ bootstrap_host_data_disk_device | regex_replace('!(.*)$','/\\1p') }}2" +- fstype: "btrfs" +- tags: +- - format-data-partitions +- +-- name: Create the mount points, fstab entries and mount the file systems +- mount: +- name: "{{ item.mount_point }}" +- src: "{{ item.device }}" +- fstype: "{{ item.fstype }}" +- state: mounted +- with_items: +- - mount_point: /openstack +- device: "/dev/{{ bootstrap_host_data_disk_device | regex_replace('!(.*)$','/\\1p') }}1" +- fstype: ext4 +- - mount_point: /var/lib/machines +- device: "/dev/{{ bootstrap_host_data_disk_device | regex_replace('!(.*)$','/\\1p') }}2" +- fstype: btrfs +- tags: +- - mount-data-partitions +diff --git a/tests/roles/bootstrap-host/tasks/prepare_loopback_cinder.yml b/tests/roles/bootstrap-host/tasks/prepare_loopback_cinder.yml +deleted file mode 100644 +index 38fd224c..00000000 +--- a/tests/roles/bootstrap-host/tasks/prepare_loopback_cinder.yml ++++ /dev/null +@@ -1,72 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, 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. +- +-- name: Create sparse Cinder file +- command: "truncate -s {{ bootstrap_host_loopback_cinder_size }}G /openstack/cinder.img" +- args: +- creates: /openstack/cinder.img +- register: cinder_create +- tags: +- - cinder-file-create +- +-- name: Get a loopback device for cinder file +- command: losetup -f +- when: cinder_create | changed +- register: cinder_losetup +- tags: +- - cinder-device-get +- +-- name: Create the loopback device +- command: "losetup {{ cinder_losetup.stdout }} /openstack/cinder.img" +- when: cinder_create | changed +- tags: +- - cinder-device-create +- +-- name: Ensure that rc.local exists +- file: +- path: "{{ rc_local }}" +- state: touch +- mode: "u+x" +- tags: +- - cinder-rc-file +- +-# As the cinder loopback is an LVM VG, it needs to be mounted differently +-# to the other loopback files. It requires the use of rc.local to attach +-# the loopback device on boot so that the VG becomes available immediately +-# after the boot process completes. +-- name: Create loopback devices at boot time +- lineinfile: +- dest: "{{ rc_local }}" +- line: "losetup $(losetup -f) /openstack/cinder.img" +- insertbefore: "{{ rc_local_insert_before }}" +- tags: +- - cinder-rc-config +- +-- name: Make LVM physical volume on the cinder device +- command: "{{ item }}" +- when: cinder_create | changed +- with_items: +- - "pvcreate {{ cinder_losetup.stdout }}" +- - "pvscan" +- tags: +- - cinder-lvm-pv +- +-- name: Add cinder-volumes volume group +- lvg: +- vg: cinder-volumes +- pvs: "{{ cinder_losetup.stdout }}" +- when: cinder_create | changed +- tags: +- - cinder-lvm-vg +diff --git a/tests/roles/bootstrap-host/tasks/prepare_loopback_nova.yml b/tests/roles/bootstrap-host/tasks/prepare_loopback_nova.yml +deleted file mode 100644 +index 37a6f899..00000000 +--- a/tests/roles/bootstrap-host/tasks/prepare_loopback_nova.yml ++++ /dev/null +@@ -1,39 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, 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. +- +-- name: Create sparse Nova file +- command: "truncate -s {{ bootstrap_host_loopback_nova_size }}G /openstack/nova.img" +- args: +- creates: /openstack/nova.img +- register: nova_create +- tags: +- - nova-file-create +- +-- name: Format the Nova file +- filesystem: +- fstype: ext4 +- dev: /openstack/nova.img +- when: nova_create | changed +- tags: +- - nova-format-file +- +-- name: Create the mount points, fstab entries and mount the file systems +- mount: +- name: /var/lib/nova/instances +- src: /openstack/nova.img +- fstype: ext4 +- state: mounted +- tags: +- - nova-file-mount +diff --git a/tests/roles/bootstrap-host/tasks/prepare_loopback_swap.yml b/tests/roles/bootstrap-host/tasks/prepare_loopback_swap.yml +deleted file mode 100644 +index 8143b6eb..00000000 +--- a/tests/roles/bootstrap-host/tasks/prepare_loopback_swap.yml ++++ /dev/null +@@ -1,73 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, 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. +- +-- name: Create swap file +- command: "{{ swap_create_command }}" +- args: +- creates: /openstack/swap.img +- register: swap_create +- tags: +- - swap-file-create +- +-- name: Set swap file permissions to 0600 +- file: +- path: /openstack/swap.img +- mode: 0600 +- tags: +- - swap-permissions +- +-- name: Format the swap file +- command: mkswap /openstack/swap.img +- when: swap_create | changed +- tags: +- - swap-format +- +-- name: Ensure that the swap file entry is in /etc/fstab +- mount: +- name: none +- src: /openstack/swap.img +- fstype: swap +- opts: sw +- passno: 0 +- dump: 0 +- state: present +- tags: +- - swap-fstab +- +-- name: Bring swap file online +- shell: | +- return_code=0 +- if ! grep /openstack/swap.img /proc/swaps; then +- swapon /openstack/swap.img +- return_code=2 +- fi +- exit ${return_code} +- register: _set_swap_online +- changed_when: _set_swap_online.rc == 2 +- failed_when: _set_swap_online.rc not in [0, 2] +- # We skip ansible lint testing for this task as it fails with +- # ANSIBLE0014 Environment variables don't work as part of command +- # which is nonsense. +- tags: +- - skip_ansible_lint +- - swap-online +- +-- name: Set system swappiness +- sysctl: +- name: vm.swappiness +- value: 10 +- state: present +- tags: +- - swap-sysctl +diff --git a/tests/roles/bootstrap-host/tasks/prepare_loopback_swift.yml b/tests/roles/bootstrap-host/tasks/prepare_loopback_swift.yml +deleted file mode 100644 +index 4901942d..00000000 +--- a/tests/roles/bootstrap-host/tasks/prepare_loopback_swift.yml ++++ /dev/null +@@ -1,55 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, 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. +- +-- name: Create sparse Swift files +- command: "truncate -s {{ bootstrap_host_loopback_swift_size }}G /openstack/{{ item }}.img" +- args: +- creates: "/openstack/{{ item }}.img" +- with_items: +- - 'swift1' +- - 'swift2' +- - 'swift3' +- register: swift_create +- tags: +- - swift-file-create +- +-- name: Format the Swift files +- filesystem: +- fstype: xfs +- opts: '-K' +- dev: "/openstack/{{ item }}.img" +- when: swift_create | changed +- with_items: +- - 'swift1' +- - 'swift2' +- - 'swift3' +- tags: +- - swift-format-file +- +-- name: Create the Swift mount points, fstab entries and mount the file systems +- mount: +- name: "/srv/{{ item }}.img" +- src: "/openstack/{{ item }}.img" +- fstype: xfs +- opts: 'loop,noatime,nodiratime,nobarrier,logbufs=8' +- passno: 0 +- dump: 0 +- state: mounted +- with_items: +- - 'swift1' +- - 'swift2' +- - 'swift3' +- tags: +- - swift-file-mount +diff --git a/tests/roles/bootstrap-host/tasks/prepare_networking.yml b/tests/roles/bootstrap-host/tasks/prepare_networking.yml +deleted file mode 100644 +index c7ea663e..00000000 +--- a/tests/roles/bootstrap-host/tasks/prepare_networking.yml ++++ /dev/null +@@ -1,193 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, 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. +- +-- name: Ensure that /etc/network/interfaces.d/ exists (Debian) +- file: +- path: /etc/network/interfaces.d/ +- state: directory +- tags: +- - networking-dir-create +- when: +- - ansible_pkg_mgr == 'apt' +- +-- name: Copy AIO network configuration (Debian) +- template: +- src: osa_interfaces.cfg.j2 +- dest: /etc/network/interfaces.d/osa_interfaces.cfg +- register: osa_interfaces +- when: +- - bootstrap_host_aio_config | bool +- - ansible_pkg_mgr == 'apt' +- tags: +- - networking-interfaces-file +- +-- name: Copy network configuration (RedHat) +- template: +- src: "redhat_interface_{{ item.type | default('default') }}.cfg.j2" +- dest: "/etc/sysconfig/network-scripts/ifcfg-{{ item.name | default('br-mgmt') }}" +- with_items: "{{ bridges }}" +- register: network_interfaces_rhel +- when: +- - ansible_pkg_mgr in ['yum', 'dnf'] +- +-- name: Create alias file when required (RedHat) +- template: +- src: "redhat_interface_alias.cfg.j2" +- dest: "/etc/sysconfig/network-scripts/ifcfg-{{ item.name | default('br-mgmt')}}:0" +- with_items: "{{ bridges }}" +- when: +- - ansible_pkg_mgr in ['yum', 'dnf'] +- - item.alias is defined +- +-- name: Put down post-up script for veth-peer interfaces (RedHat) +- template: +- src: "rpm_interface_{{ item[0] }}.cfg.j2" +- dest: "/etc/sysconfig/network-scripts/{{ item[0] }}-veth-{{ item[1].name | default('br-mgmt') }}-2-{{ item[1].veth_peer | default('eth1') }}" +- mode: "0755" +- with_nested: +- - [ "ifup-post", "ifdown-post" ] +- - "{{ bridges }}" +- when: +- - item[1].veth_peer is defined +- - ansible_pkg_mgr in ['yum', 'dnf'] +- +-- name: Ensure the postup/postdown scripts are loaded (RedHat) +- lineinfile: +- dest: "/etc/sysconfig/network-scripts/{{ item[0] }}" +- line: ". /etc/sysconfig/network-scripts/{{ item[0] }}-veth-{{ item[1].name | default('br-mgmt') }}-2-{{ item[1].veth_peer | default('eth1') }}" +- insertbefore: "^exit 0" +- with_nested: +- - [ "ifup-post", "ifdown-post" ] +- - "{{ bridges }}" +- when: +- - item[1].veth_peer is defined +- - ansible_pkg_mgr in ['yum', 'dnf'] +- +-- name: Copy network configuration (SUSE) +- template: +- src: "suse_interface_default.cfg.j2" +- dest: "/etc/sysconfig/network/ifcfg-{{ item.name | default('br-mgmt') }}" +- with_items: "{{ bridges }}" +- register: network_interfaces_suse +- when: +- - ansible_pkg_mgr == 'zypper' +- +-- name: Put down post-up script for veth-peer interfaces (SUSE) +- template: +- src: "rpm_interface_{{ item[0] }}.cfg.j2" +- dest: "/etc/sysconfig/network/scripts/{{ item[0] }}-veth-{{ item[1].name | default('br-mgmt') }}-2-{{ item[1].veth_peer | default('eth1') }}" +- mode: "0755" +- with_nested: +- - [ "ifup-post", "ifdown-post" ] +- - "{{ bridges }}" +- when: +- - item[1].veth_peer is defined +- - ansible_pkg_mgr == 'zypper' +- +-- name: Ensure the postup scripts are loaded (SUSE) +- lineinfile: +- dest: "/etc/sysconfig/network/ifcfg-{{ item[1].name | default('br-mgmt') }}" +- line: "POST_UP_SCRIPT=\"compat:suse:{{ item[0] }}-veth-{{ item[1].name | default('br-mgmt') }}-2-{{ item[1].veth_peer | default('eth1') }}\"" +- with_nested: +- - [ "ifup-post" ] +- - "{{ bridges }}" +- when: +- - item[1].veth_peer is defined +- - ansible_pkg_mgr == 'zypper' +- +-- name: Ensure the postdown scripts are loaded (SUSE) +- lineinfile: +- dest: "/etc/sysconfig/network/ifcfg-{{ item[1].name | default('br-mgmt') }}" +- line: "POST_DOWN_SCRIPT=\"compat:suse:{{ item[0] }}-veth-{{ item[1].name | default('br-mgmt') }}-2-{{ item[1].veth_peer | default('eth1') }}\"" +- with_nested: +- - [ "ifdown-post" ] +- - "{{ bridges }}" +- when: +- - item[1].veth_peer is defined +- - ansible_pkg_mgr == 'zypper' +- +-- name: Copy multinode network configuration (Debian) +- template: +- src: osa_interfaces_multinode.cfg.j2 +- dest: /etc/network/interfaces.d/osa_interfaces.cfg +- register: osa_multinode_interfaces +- when: +- - not bootstrap_host_aio_config | bool +- - ansible_pkg_mgr == 'apt' +- tags: +- - networking-interfaces-file +- +-- name: Ensure our interfaces.d configuration files are loaded automatically (Debian) +- lineinfile: +- dest: /etc/network/interfaces +- line: "source /etc/network/interfaces.d/*.cfg" +- when: +- - ansible_pkg_mgr == 'apt' +- tags: +- - networking-interfaces-load +- +-- name: Shut down the network interfaces +- command: "ifdown {{ item.name }}" +- when: +- - osa_interfaces | changed or osa_multinode_interfaces | changed or network_interfaces_rhel | changed +- - item.enabled | default(True) +- with_items: +- - { name: br-mgmt } +- - { name: br-storage } +- - { name: br-vlan } +- - { name: br-vxlan } +- - { name: br-dbaas, enabled: "{{ (bootstrap_host_scenario == 'translations') | bool }}" } +- - { name: br-lbaas, enabled: "{{ (bootstrap_host_scenario in ['translations', 'octavia']) | bool }}" } +- tags: +- - networking-interfaces-stop +- +-- name: Shut down the encapsulation network interfaces +- command: "ifdown {{ item.key }}" +- when: +- - osa_multinode_interfaces | changed +- - bootstrap_host_encapsulation_enabled | bool +- with_dict: "{{ bootstrap_host_encapsulation_interfaces }}" +- tags: +- - networking-interfaces-stop +- +-- name: Start the encapsulation network interfaces +- command: "ifup {{ item.key }}" +- when: +- - osa_multinode_interfaces | changed +- - bootstrap_host_encapsulation_enabled | bool +- with_dict: "{{ bootstrap_host_encapsulation_interfaces }}" +- tags: +- - networking-interfaces-start +- +-- name: Start the network interfaces +- command: "ifup {{ item.name }}" +- when: +- - osa_interfaces | changed or network_interfaces_rhel | changed or network_interfaces_suse | changed +- - item.enabled | default(True) +- with_items: +- - { name: br-mgmt } +- - { name: br-storage } +- - { name: br-vlan } +- - { name: br-vxlan } +- - { name: br-dbaas, enabled: "{{ (bootstrap_host_scenario == 'translations') | bool }}" } +- - { name: br-lbaas, enabled: "{{ (bootstrap_host_scenario in ['translations', 'octavia']) | bool }}" } +- tags: +- - networking-interfaces-start +- +-- name: Updating the facts due to net changes +- setup: +- filter: "ansible_br*" +- tags: +- - networking +diff --git a/tests/roles/bootstrap-host/tasks/prepare_octavia.yml b/tests/roles/bootstrap-host/tasks/prepare_octavia.yml +deleted file mode 100644 +index 8051b479..00000000 +--- a/tests/roles/bootstrap-host/tasks/prepare_octavia.yml ++++ /dev/null +@@ -1,80 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, 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. +- +- +-- name: Install apt packages +- apt: +- pkg: "{{ item }}" +- state: "present" +- update_cache: yes +- register: install_packages +- until: install_packages|success +- retries: 5 +- delay: 2 +- with_items: +- - qemu +- - uuid-runtime +- - curl +- - kpartx +- - git +-- name: Create Octavia tmp dir +- file: +- state: directory +- path: "/var/lib/octavia" +-- name: Set Octavia tmp dir +- set_fact: +- bootstrap_host_octavia_tmp: "/var/lib/octavia" +-- name: Install pip requirements +- pip: +- name: "{{ item }}" +- state: "present" +- extra_args: "-c {{ pip_install_upper_constraints_proto }}://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?id={{ requirements_git_install_branch | regex_replace(' #.*$','') }}" +- register: install_packages +- until: install_packages|success +- retries: 5 +- delay: 2 +- with_items: +- - argparse +- - "Babel>=1.3" +- - dib-utils +- - PyYAML +- - diskimage-builder +-- name: Clone Octavia +- git: +- repo: "https://git.openstack.org/openstack/octavia" +- dest: "{{ bootstrap_host_octavia_tmp }}/octavia" +- version: "{{ octavia_git_install_branch }}" +-# Build Octavia amphora image +-- name: Create amphora image +- shell: "./diskimage-create.sh -o {{ bootstrap_host_octavia_tmp }}/amphora-x64-haproxy.qcow2" +- args: +- chdir: "{{ bootstrap_host_octavia_tmp }}/octavia/diskimage-create" +- creates: "{{ bootstrap_host_octavia_tmp }}/amphora-x64-haproxy.qcow2" +- tags: +- - skip_ansible_lint +-- name: Change permission +- file: +- path: "{{ bootstrap_host_octavia_tmp }}/octavia/bin/create_certificates.sh" +- mode: 0755 +-- name: Generate certs +- shell: "{{ bootstrap_host_octavia_tmp }}/octavia/bin/create_certificates.sh {{ bootstrap_host_octavia_tmp }}/certs {{ bootstrap_host_octavia_tmp }}/octavia/etc/certificates/openssl.cnf" +- args: +- creates: "{{ bootstrap_host_octavia_tmp }}/certs/ca_01.pem" +- tags: +- - skip_ansible_lint +-- name: Fix certs/private directory access +- file: +- path: "{{ bootstrap_host_octavia_tmp }}/certs/private" +- mode: 0755 +diff --git a/tests/roles/bootstrap-host/tasks/prepare_ssh_keys.yml b/tests/roles/bootstrap-host/tasks/prepare_ssh_keys.yml +deleted file mode 100644 +index e3f8914a..00000000 +--- a/tests/roles/bootstrap-host/tasks/prepare_ssh_keys.yml ++++ /dev/null +@@ -1,75 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, 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. +- +-- name: Ensure root has a .ssh directory +- file: +- path: /root/.ssh +- state: directory +- owner: root +- group: root +- mode: 0700 +- tags: +- - ssh-key-dir +- +-- name: Check for existing ssh private key file +- stat: +- path: /root/.ssh/id_rsa +- register: ssh_key_private +- tags: +- - ssh-key-check +- +-- name: Check for existing ssh public key file +- stat: +- path: /root/.ssh/id_rsa.pub +- register: ssh_key_public +- tags: +- - ssh-key-check +- +-- name: Remove an existing private/public ssh keys if one is missing +- file: +- path: "/root/.ssh/{{ item }}" +- state: absent +- when: not ssh_key_public.stat.exists or not ssh_key_private.stat.exists +- with_items: +- - 'id_rsa' +- - 'id_rsa.pub' +- tags: +- - ssh-key-clean +- +-- name: Create ssh key pair for root +- user: +- name: root +- generate_ssh_key: yes +- ssh_key_bits: 2048 +- ssh_key_file: /root/.ssh/id_rsa +- tags: +- - ssh-key-generate +- +-- name: Fetch the generated public ssh key +- fetch: +- src: "/root/.ssh/id_rsa.pub" +- dest: "/tmp/id_rsa.pub" +- flat: yes +- when: inventory_hostname == groups['all'][0] +- tags: +- - ssh-key-authorized +- +-- name: Ensure root's new public ssh key is in authorized_keys +- authorized_key: +- user: root +- key: "{{ lookup('file','/tmp/id_rsa.pub') }}" +- manage_dir: no +- tags: +- - ssh-key-authorized +\ No newline at end of file +diff --git a/tests/roles/bootstrap-host/templates/osa_interfaces.cfg.j2 b/tests/roles/bootstrap-host/templates/osa_interfaces.cfg.j2 +deleted file mode 100644 +index bc21b90e..00000000 +--- a/tests/roles/bootstrap-host/templates/osa_interfaces.cfg.j2 ++++ /dev/null +@@ -1,107 +0,0 @@ +-## The default networking requires several bridges. These bridges were named to be informative +-## however they can be named what ever you like and is adaptable to any network infrastructure +-## environment. This file serves as an example of how to setup basic networking and was ONLY +-## built for the purpose of being an example and used expressly in the building of an ALL IN +-## ONE development environment. +- +-auto br-mgmt +-iface br-mgmt inet static +- bridge_stp off +- bridge_waitport 0 +- bridge_fd 0 +- # Notice the bridge port is the vlan tagged interface +- bridge_ports {{ bootstrap_host_bridge_mgmt_ports }} +- address 172.29.236.100 +- netmask 255.255.252.0 +- offload-sg off +- +-auto br-vxlan +-iface br-vxlan inet static +- bridge_stp off +- bridge_waitport 0 +- bridge_fd 0 +- bridge_ports {{ bootstrap_host_bridge_vxlan_ports }} +- address 172.29.240.100 +- netmask 255.255.252.0 +- offload-sg off +- # To ensure ssh checksum is correct +- up /sbin/iptables -A POSTROUTING -t mangle -p tcp --dport 22 -j CHECKSUM --checksum-fill +- down /sbin/iptables -D POSTROUTING -t mangle -p tcp --dport 22 -j CHECKSUM --checksum-fill +- # To provide internet connectivity to instances +- up /sbin/iptables -t nat -A POSTROUTING -o {{ bootstrap_host_public_interface }} -j MASQUERADE +- down /sbin/iptables -t nat -D POSTROUTING -o {{ bootstrap_host_public_interface }} -j MASQUERADE +- +-auto br-storage +-iface br-storage inet static +- bridge_stp off +- bridge_waitport 0 +- bridge_fd 0 +- bridge_ports {{ bootstrap_host_bridge_storage_ports }} +- address 172.29.244.100 +- netmask 255.255.252.0 +- offload-sg off +- +-auto br-vlan +-iface br-vlan inet static +- bridge_stp off +- bridge_waitport 0 +- bridge_fd 0 +- address 172.29.248.100 +- netmask 255.255.252.0 +- offload-sg off +- # Create veth pair, don't bomb if already exists +- pre-up ip link add br-vlan-veth type veth peer name eth12 || true +- # Set both ends UP +- pre-up ip link set br-vlan-veth up +- pre-up ip link set eth12 up +- # Delete veth pair on DOWN +- post-down ip link del br-vlan-veth || true +- bridge_ports br-vlan-veth +- +-{% if bootstrap_host_scenario == "translations" %} +-auto br-dbaas +-iface br-dbaas inet static +- bridge_stp off +- bridge_waitport 0 +- bridge_fd 0 +- address 172.29.232.100 +- netmask 255.255.252.0 +- offload-sg off +- # Create veth pair, don't bomb if already exists +- pre-up ip link add br-dbaas-veth type veth peer name eth13 || true +- # Set both ends UP +- pre-up ip link set br-dbaas-veth up +- pre-up ip link set eth13 up +- # Delete veth pair on DOWN +- post-down ip link del br-dbaas-veth || true +- bridge_ports br-dbaas-veth +- +-{% endif %} +-{% if bootstrap_host_scenario in ["translations", "octavia"] %} +-auto br-lbaas +-iface br-lbaas inet static +- bridge_stp off +- bridge_waitport 0 +- bridge_fd 0 +- address 172.29.252.100 +- netmask 255.255.252.0 +- offload-sg off +- # Create veth pair, don't bomb if already exists +- pre-up ip link add br-lbaas-veth type veth peer name eth14 || true +- # Set both ends UP +- pre-up ip link set br-lbaas-veth up +- pre-up ip link set eth14 up +- # Delete veth pair on DOWN +- post-down ip link del br-lbaas-veth || true +- bridge_ports br-lbaas-veth +- +-{% endif %} +- +-# Add an additional address to br-vlan +-iface br-vlan inet static +- # Flat network default gateway +- # -- This needs to exist somewhere for network reachability +- # -- from the router namespace for floating IP paths. +- # -- Putting this here is primarily for tempest to work. +- address 172.29.248.1 +- netmask 255.255.252.0 +diff --git a/tests/roles/bootstrap-host/templates/osa_interfaces_multinode.cfg.j2 b/tests/roles/bootstrap-host/templates/osa_interfaces_multinode.cfg.j2 +deleted file mode 100644 +index c31c4a43..00000000 +--- a/tests/roles/bootstrap-host/templates/osa_interfaces_multinode.cfg.j2 ++++ /dev/null +@@ -1,28 +0,0 @@ +-{% if bootstrap_host_encapsulation_enabled | bool %} +-{% for nic_name, nic_details in bootstrap_host_encapsulation_interfaces.items() %} +-# {{ nic_details.friendly_name }} +-auto {{ nic_name }} +-iface {{ nic_name }} inet manual +- pre-up ip link add {{ nic_name }} type vxlan id {{ nic_details.id }} group 239.0.0.{{ nic_details.id }} dev {{ nic_details.underlay_device }} || true +- up ip link set $IFACE up +- down ip link set $IFACE down +- post-down ip link del {{ nic_name }} || true +- +-{% endfor %} +-{% endif %} +-{%- for nic_name, nic_details in bootstrap_host_bridges_interfaces.items() -%} +-auto {{ nic_name }} +-iface {{ nic_name }} inet {{ nic_details.mode | default('static') }} +- bridge_stp off +- bridge_waitport 0 +- bridge_fd 0 +- bridge_ports {{ nic_details.ports }} +- offload-sg {{ nic_details.offload_sg | default('off') }} +- {% if nic_details.mode | default('static') == 'static' -%} +- address {{ nic_details.ip_address_range }}.{{ node_id }} +- netmask {{ nic_details.ip_netmask }} +- {% endif %} +- {%- if nic_details.state_change_scripts is defined %}{{ nic_details.state_change_scripts }} +- {% endif %} +- +-{% endfor %} +diff --git a/tests/roles/bootstrap-host/templates/redhat_interface_alias.cfg.j2 b/tests/roles/bootstrap-host/templates/redhat_interface_alias.cfg.j2 +deleted file mode 100644 +index 79a04a85..00000000 +--- a/tests/roles/bootstrap-host/templates/redhat_interface_alias.cfg.j2 ++++ /dev/null +@@ -1,5 +0,0 @@ +-# This interface is an alias +-DEVICE={{ item.name | default('br-mgmt') }}:0 +-IPADDR={{ item.alias | default('10.1.0.1') }} +-NETMASK={{ item.netmask | default('255.255.255.0') }} +-ONBOOT=yes +diff --git a/tests/roles/bootstrap-host/templates/redhat_interface_default.cfg.j2 b/tests/roles/bootstrap-host/templates/redhat_interface_default.cfg.j2 +deleted file mode 100644 +index 25c2dfac..00000000 +--- a/tests/roles/bootstrap-host/templates/redhat_interface_default.cfg.j2 ++++ /dev/null +@@ -1,12 +0,0 @@ +-{% if item.veth_peer is defined %} +-# This interface has a veth peer +-{% endif %} +-DEVICE={{ item.name | default('br-mgmt') }} +-TYPE=Bridge +-IPADDR={{ item.ip_addr | default('10.1.0.1') }} +-NETMASK={{ item.netmask | default('255.255.255.0') }} +-ONBOOT=yes +-BOOTPROTO=none +-NM_CONTROLLED=no +-DELAY=0 +-ETHTOOL_OPTS="-K ${DEVICE} sg off" +diff --git a/tests/roles/bootstrap-host/templates/rpm_interface_ifdown-post.cfg.j2 b/tests/roles/bootstrap-host/templates/rpm_interface_ifdown-post.cfg.j2 +deleted file mode 100644 +index e35945df..00000000 +--- a/tests/roles/bootstrap-host/templates/rpm_interface_ifdown-post.cfg.j2 ++++ /dev/null +@@ -1,29 +0,0 @@ +-#!/usr/bin/env bash +-# Copyright 2014, Rackspace US, 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. +- +-source /etc/os-release || source /usr/lib/os-release +- +-case "${ID}" in +- *suse*) INTERFACE="${1}"; ;; +- centos|rhel|fedora) INTERFACE="${DEVICE}"; ;; +- *) echo "Unsupported distribution ${ID}"; exit 1; +-esac +- +-_ip=$(which ip 2>/dev/null || { echo "Failed to find ip executable"; exit 1; }) +- +-if [ "${INTERFACE}" == "{{ item[1].name | default('br-mgmt') }}" ]; then +- eval $_ip link set {{ item[1].name | default('br-mgmt') }}-veth nomaster || true +- eval $_ip link del {{ item[1].name | default('br-mgmt') }}-veth || true +-fi +diff --git a/tests/roles/bootstrap-host/templates/rpm_interface_ifup-post.cfg.j2 b/tests/roles/bootstrap-host/templates/rpm_interface_ifup-post.cfg.j2 +deleted file mode 100644 +index 807b1cae..00000000 +--- a/tests/roles/bootstrap-host/templates/rpm_interface_ifup-post.cfg.j2 ++++ /dev/null +@@ -1,35 +0,0 @@ +-#!/usr/bin/env bash +-# Copyright 2014, Rackspace US, 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. +- +-source /etc/os-release || source /usr/lib/os-release +- +-case "${ID}" in +- *suse*) INTERFACE="${1}"; ;; +- centos|rhel|fedora) INTERFACE="${DEVICE}"; ;; +- *) echo "Unsupported distribution ${ID}"; exit 1; +-esac +- +-_ip=$(which ip 2>/dev/null || { echo "Failed to find ip executable"; exit 1; }) +- +-if [ "${INTERFACE}" == "{{ item[1].name | default('br-mgmt') }}" ]; then +- # Create veth pair, don't bomb if already exists +- echo "Creating veth" +- eval $_ip link add {{ item[1].name | default('br-mgmt') }}-veth type veth peer name {{ item[1].veth_peer | default('eth0') }} || true +- # Set both ends UP +- eval $_ip link set {{ item[1].name | default('br-mgmt') }}-veth up || true +- eval $_ip link set {{ item[1].veth_peer | default('eth0') }} up || true +- # add eth12 to the bridge +- eval $_ip link set {{ item[1].name | default('br-mgmt') }}-veth master {{ item[1].name | default('br-mgmt') }} || true +-fi +diff --git a/tests/roles/bootstrap-host/templates/suse_interface_default.cfg.j2 b/tests/roles/bootstrap-host/templates/suse_interface_default.cfg.j2 +deleted file mode 100644 +index f0cc3770..00000000 +--- a/tests/roles/bootstrap-host/templates/suse_interface_default.cfg.j2 ++++ /dev/null +@@ -1,9 +0,0 @@ +-{% if item.veth_peer is defined %} +-# This interface has a veth peer +-{% endif %} +-BRIDGE='yes' +-IPADDR={{ item.ip_addr | default('10.1.0.1') }} +-NETMASK={{ item.netmask | default('255.255.255.0') }} +-STARTMODE='auto' +-BOOTPROTO='static' +-ETHTOOL_OPTIONS_sg='-K iface sg off' +diff --git a/tests/roles/bootstrap-host/templates/user_variables.aio.yml.j2 b/tests/roles/bootstrap-host/templates/user_variables.aio.yml.j2 +deleted file mode 100644 +index d0489ea4..00000000 +--- a/tests/roles/bootstrap-host/templates/user_variables.aio.yml.j2 ++++ /dev/null +@@ -1,196 +0,0 @@ +---- +-# Copyright 2014, Rackspace US, 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. +- +-## General options +-debug: True +- +-## Tempest settings +-tempest_public_subnet_cidr: 172.29.248.0/22 +-tempest_public_subnet_allocation_pools: "172.29.249.110-172.29.249.200" +- +-## Galera settings +-galera_innodb_buffer_pool_size: 16M +-galera_innodb_log_buffer_size: 4M +-galera_wsrep_provider_options: +- - { option: "gcache.size", value: "4M" } +- +-## Neutron settings +-neutron_metadata_checksum_fix: True +- +-### Set workers for all services to optimise memory usage +- +-## Repo +-repo_nginx_threads: 2 +- +-## Keystone +-keystone_httpd_mpm_start_servers: 2 +-keystone_httpd_mpm_min_spare_threads: 1 +-keystone_httpd_mpm_max_spare_threads: 2 +-keystone_httpd_mpm_thread_limit: 2 +-keystone_httpd_mpm_thread_child: 1 +-keystone_wsgi_threads: 1 +-keystone_wsgi_processes_max: 2 +- +-## Barbican +-barbican_wsgi_processes: 2 +-barbican_wsgi_threads: 1 +- +-## Cinder +-cinder_wsgi_processes_max: 2 +-cinder_wsgi_threads: 1 +-cinder_wsgi_buffer_size: 16384 +-cinder_osapi_volume_workers_max: 2 +- +-## Glance +-glance_api_threads_max: 2 +-glance_api_threads: 1 +-glance_api_workers: 1 +-glance_registry_workers: 1 +- +-## Nova +-nova_wsgi_threads: 1 +-nova_wsgi_processes_max: 2 +-nova_wsgi_processes: 2 +-nova_wsgi_buffer_size: 16384 +-nova_api_threads_max: 2 +-nova_api_threads: 1 +-nova_osapi_compute_workers: 1 +-nova_conductor_workers: 1 +-nova_metadata_workers: 1 +- +-## Neutron +-neutron_rpc_workers: 1 +-neutron_metadata_workers: 1 +-neutron_api_workers: 1 +-neutron_api_threads_max: 2 +-neutron_api_threads: 2 +-neutron_num_sync_threads: 1 +- +-## Heat +-heat_api_workers: 1 +-heat_api_threads_max: 2 +-heat_api_threads: 1 +-heat_wsgi_threads: 1 +-heat_wsgi_processes_max: 2 +-heat_wsgi_processes: 1 +-heat_wsgi_buffer_size: 16384 +- +-## Horizon +-horizon_wsgi_processes: 1 +-horizon_wsgi_threads: 1 +-horizon_wsgi_threads_max: 2 +- +-## Ceilometer +-ceilometer_notification_workers_max: 2 +-ceilometer_notification_workers: 1 +- +-## AODH +-aodh_wsgi_threads: 1 +-aodh_wsgi_processes_max: 2 +-aodh_wsgi_processes: 1 +- +-## Gnocchi +-gnocchi_wsgi_threads: 1 +-gnocchi_wsgi_processes_max: 2 +-gnocchi_wsgi_processes: 1 +- +-## Swift +-swift_account_server_replicator_workers: 1 +-swift_server_replicator_workers: 1 +-swift_object_replicator_workers: 1 +-swift_account_server_workers: 1 +-swift_container_server_workers: 1 +-swift_object_server_workers: 1 +-swift_proxy_server_workers_max: 2 +-swift_proxy_server_workers_not_capped: 1 +-swift_proxy_server_workers_capped: 1 +-swift_proxy_server_workers: 1 +- +-## Ironic +-ironic_wsgi_threads: 1 +-ironic_wsgi_processes_max: 2 +-ironic_wsgi_processes: 1 +- +-## Trove +-trove_api_workers_max: 2 +-trove_api_workers: 1 +-trove_conductor_workers_max: 2 +-trove_conductor_workers: 1 +-trove_wsgi_threads: 1 +-trove_wsgi_processes_max: 2 +-trove_wsgi_processes: 1 +- +-## Sahara +-sahara_api_workers_max: 2 +-sahara_api_workers: 1 +- +-# NOTE: hpcloud-b4's eth0 uses 10.0.3.0/24, which overlaps with the +-# lxc_net_address default +-# TODO: We'll need to implement a mechanism to determine valid lxc_net_address +-# value which will not overlap with an IP already assigned to the host. +-lxc_net_address: 10.255.255.1 +-lxc_net_netmask: 255.255.255.0 +-lxc_net_dhcp_range: 10.255.255.2,10.255.255.253 +- +-{% if repo_build_pip_extra_indexes is defined and repo_build_pip_extra_indexes|length > 0 %} +-## Wheel mirrors for the repo_build to use +-repo_build_pip_extra_indexes: +-{{ repo_build_pip_extra_indexes | to_nice_yaml }} +-{% endif %} +- +-{% if _lxc_mirror is defined and _lxc_mirror.stdout_lines is defined %} +-## images.linuxcontainers.org reverse proxy +-lxc_image_cache_server_mirrors: +- - "http://{{ _lxc_mirror.stdout_lines[0] }}" +-{% endif %} +- +-{% if cache_timeout is defined %} +-## Package cache timeout +-cache_timeout: {{ cache_timeout }} +-{% endif %} +- +-# The container backing store is set to 'machinectl' to speed up the +-# AIO build time. Options are: [machinectl, overlayfs, btrfs, zfs, dir, lvm] +-lxc_container_backing_store: "machinectl" +- +-## Enable LBaaSv2 in the AIO +-neutron_plugin_base: +- - router +- - metering +- - neutron_lbaas.services.loadbalancer.plugin.LoadBalancerPluginv2 +- +-## Always setup tempest, the resources for it, then execute tests +-tempest_install: yes +-tempest_run: yes +- +-{% if nodepool_dir.stat.exists %} +-# Disable chronyd in OpenStack CI +-security_rhel7_enable_chrony: no +-{% endif %} +- +-# For testing purposes in public clouds, we need to ignore these +-# services when trying to do a reload of nova services. +-nova_service_negate: +- - "nova-agent.service" +- - "nova-resetnetwork.service" +- +-{% if _pypi_wheel_mirror is defined and _pypi_wheel_mirror.stdout_lines is defined %} +-repo_nginx_pypi_upstream: "{{ _pypi_wheel_mirror.stdout_lines[0] | netloc }}" +-repo_build_pip_extra_indexes: +- - "{{ _pypi_wheel_mirror.stdout_lines[1] }}" +-{% endif %} +- +-# Set the container tech. Options are "lxc" +-container_tech: "{{ container_tech }}" +diff --git a/tests/roles/bootstrap-host/templates/user_variables_ceph.yml.j2 b/tests/roles/bootstrap-host/templates/user_variables_ceph.yml.j2 +deleted file mode 100644 +index a9cb5dfc..00000000 +--- a/tests/roles/bootstrap-host/templates/user_variables_ceph.yml.j2 ++++ /dev/null +@@ -1,29 +0,0 @@ +---- +-# Copyright 2017, Logan Vig +-# +-# 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. +- +-## ceph-ansible AIO settings +-common_single_host_mode: true +-monitor_interface: eth1 # Management network in the AIO +-public_network: "{{ (mgmt_range ~ '.0/' ~ netmask) | ipaddr('net') }}" +-journal_size: 100 +-osd_scenario: collocated +-pool_default_pg_num: 32 +-openstack_config: true # Ceph ansible automatically creates pools & keys +-cinder_ceph_client: cinder +-cinder_default_volume_type: RBD +-glance_ceph_client: glance +-glance_default_store: rbd +-glance_rbd_store_pool: images +-nova_libvirt_images_rbd_pool: vms +diff --git a/tests/roles/bootstrap-host/templates/user_variables_octavia.yml.j2 b/tests/roles/bootstrap-host/templates/user_variables_octavia.yml.j2 +deleted file mode 100644 +index 0d737e76..00000000 +--- a/tests/roles/bootstrap-host/templates/user_variables_octavia.yml.j2 ++++ /dev/null +@@ -1,25 +0,0 @@ +---- +-# Copyright 2017, Rackspace US, 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. +- +-# Octavia specific stuff +-octavia_system_home_folder: {{ bootstrap_host_octavia_tmp }} +-neutron_lbaas_octavia: True +-octavia_amp_image_file_name: {{ bootstrap_host_octavia_tmp }}/amphora-x64-haproxy.qcow2 +-octavia_amp_image_upload_enabled: True +-octavia_glance_image_tag: +-octavia_management_net_subnet_cidr: 172.29.252.0/22 +- +-# make glance only use file +-glance_default_store: file +diff --git a/tests/roles/bootstrap-host/vars/redhat.yml b/tests/roles/bootstrap-host/vars/redhat.yml +deleted file mode 100644 +index 905610ab..00000000 +--- a/tests/roles/bootstrap-host/vars/redhat.yml ++++ /dev/null +@@ -1,39 +0,0 @@ +---- +-# Copyright 2017, Rackspace US, 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. +- +-rdo_package: "https://rdoproject.org/repos/openstack-pike/rdo-release-pike.rpm" +- +-packages_install: +- - bridge-utils +- - btrfs-progs +- - curl +- - dbus +- - ethtool +- - git +- - iputils +- - lvm2 +- - python +- - python-devel +- - sshpass +- - tmux +- - vim +- - xfsprogs +- +-packages_remove: [] +- +-swap_create_command: "dd if=/dev/zero of=/openstack/swap.img bs=1M count={{ (bootstrap_host_swap_size | int) * 1024 }}" +-rc_local: /etc/rc.d/rc.local +-rc_local_insert_before: "^touch /var/lock/subsys/local$" +- +diff --git a/tests/roles/bootstrap-host/vars/suse.yml b/tests/roles/bootstrap-host/vars/suse.yml +deleted file mode 100644 +index 19488c5c..00000000 +--- a/tests/roles/bootstrap-host/vars/suse.yml ++++ /dev/null +@@ -1,40 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, Inc. +-# Copyright 2017, SUSE LINUX GmbH. +-# +-# 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. +- +-opensuse_openstack_repos: +- - name: "OBS:Cloud:OpenStack:Pike" +- uri: "http://download.opensuse.org/repositories/Cloud:/OpenStack:/Pike/openSUSE_Leap_{{ ansible_distribution_version }}" +- +-packages_install: +- - bridge-utils +- - btrfsprogs +- - curl +- - dbus-1 +- - ethtool +- - git-core +- - lvm2 +- - python +- - python-devel +- - tmux +- - vim +- - vlan +- - xfsprogs +- +-packages_remove: [] +- +-swap_create_command: "dd if=/dev/zero of=/openstack/swap.img bs=1M count={{ (bootstrap_host_swap_size | int) * 1024 }}" +-rc_local: /etc/rc.d/boot.local +-rc_local_insert_before: EOF +diff --git a/tests/roles/bootstrap-host/vars/ubuntu.yml b/tests/roles/bootstrap-host/vars/ubuntu.yml +deleted file mode 100644 +index 2f2d35a6..00000000 +--- a/tests/roles/bootstrap-host/vars/ubuntu.yml ++++ /dev/null +@@ -1,45 +0,0 @@ +---- +-# Copyright 2015, Rackspace US, 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. +- +-packages_install: +- - apt-transport-https +- - bridge-utils +- - btrfs-tools +- - build-essential +- - curl +- - dbus +- - ethtool +- - git-core +- - iptables +- - iputils-tracepath +- - ipython +- - linux-image-extra-{{ ansible_kernel }} +- - lvm2 +- - parted +- - python2.7 +- - python-dev +- - sshpass +- - tmux +- - vim +- - vlan +- - xfsprogs +- +-packages_remove: +- - libmysqlclient18 +- - mysql-common +- +-swap_create_command: "fallocate -l {{ bootstrap_host_swap_size }}G /openstack/swap.img" +-rc_local: /etc/rc.local +-rc_local_insert_before: "^exit 0$" +diff --git a/tox.ini b/tox.ini +deleted file mode 100644 +index 7daf9712..00000000 +--- a/tox.ini ++++ /dev/null +@@ -1,160 +0,0 @@ +-[tox] +-minversion = 2.0 +-skipsdist = True +-envlist = linters,docs,releasenotes,inventory,py3-inventory +- +- +-[testenv] +-usedevelop = True +-basepython = python2.7 +-install_command = +- pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=stable/queens} {opts} {packages} +-deps = +- -r{toxinidir}/global-requirement-pins.txt +- -r{toxinidir}/test-requirements.txt +-passenv = +- HOME +- http_proxy +- HTTP_PROXY +- https_proxy +- HTTPS_PROXY +- no_proxy +- NO_PROXY +-whitelist_externals = +- bash +-setenv = +- PYTHONUNBUFFERED=1 +- PYTHONWARNINGS=default::DeprecationWarning +- VIRTUAL_ENV={envdir} +- WORKING_DIR={toxinidir} +- ANSIBLE_EXTRA_ROLE_DIRS={toxinidir}/playbooks/roles:{homedir}/.ansible/roles/ceph-ansible/roles +- ANSIBLE_ROLE_REQUIREMENTS_PATH={toxinidir}/ansible-role-requirements.yml +- TEST_PLAYBOOK={toxinidir}/tests/bootstrap-aio.yml {toxinidir}/playbooks/setup-everything.yml +- ANSIBLE_LINT_PARAMS=--exclude={homedir}/.ansible/roles +- +- +- +-[testenv:docs] +-commands= +- bash -c "rm -rf doc/build" +- doc8 doc +- python setup.py build_sphinx +- +- +- +-[testenv:deploy-guide] +-commands = sphinx-build -a -E -W -d deploy-guide/build/doctrees -b html deploy-guide/source deploy-guide/build/html +- +- +- +-[doc8] +-# Settings for doc8: +-extensions = .rst +- +- +- +-[testenv:releasenotes] +-commands = +- sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html +- +- +- +-# environment used by the -infra templated docs job +-[testenv:venv] +-commands = +- {posargs} +- +- +- +-[testenv:pep8] +-commands = +- bash -c "{toxinidir}/tests/tests-repo-clone.sh" +- bash -c "{toxinidir}/tests/common/test-pep8.sh" +- +- +- +-[flake8] +-# Ignores the following rules due to how ansible modules work in general +-# F403 'from ansible.module_utils.basic import *' used; +-# unable to detect undefined names +-ignore=F403 +- +- +- +-[testenv:bashate] +-commands = +- bash -c "{toxinidir}/tests/tests-repo-clone.sh" +- bash -c "{toxinidir}/tests/common/test-bashate.sh" +- +- +- +-# The deps URL should be set to the appropriate git URL. +-# In the tests repo itself, the variable is uniquely set to +-# the toxinidir so that the role is able to test itself, but +-# the tox config is exactly the same as other repositories. +-# +-# The value for other repositories must be: +-# http://git.openstack.org/cgit/openstack/openstack-ansible-tests/plain/test-ansible-deps.txt +-# or for a stable branch: +-# http://git.openstack.org/cgit/openstack/openstack-ansible-tests/plain/test-ansible-deps.txt?h=stable/newton +-[testenv:ansible] +-deps = +- {[testenv]deps} +- -r{toxinidir}/global-requirement-pins.txt +- -rhttps://git.openstack.org/cgit/openstack/openstack-ansible-tests/plain/test-ansible-deps.txt?h=stable/queens +- +- +- +-[testenv:ansible-syntax] +-deps = +- {[testenv:ansible]deps} +-commands = +- bash -c "{toxinidir}/tests/tests-repo-clone.sh" +- bash -c "{toxinidir}/tests/common/test-ansible-syntax.sh" +- +- +- +-[testenv:ansible-lint] +-deps = +- {[testenv:ansible]deps} +-commands = +- bash -c "{toxinidir}/tests/tests-repo-clone.sh" +- bash -c "{toxinidir}/tests/common/test-ansible-lint.sh" +- +- +- +-[testenv:inventory] +-# Use a fixed seed since some inventory tests rely on specific ordering +-setenv = +- {[testenv]setenv} +- PYTHONHASHSEED = 100 +-commands = +- coverage erase +- coverage run -a {toxinidir}/tests/test_inventory.py +- coverage run -a {toxinidir}/tests/test_manage.py +- coverage run -a {toxinidir}/tests/test_dictutils.py +- coverage run -a {toxinidir}/tests/test_ip.py +- coverage run -a {toxinidir}/tests/test_filesystem.py +- coverage report --show-missing --include={toxinidir}/inventory/*,{toxinidir}/osa_toolkit/* +- +- +- +-[testenv:py3-inventory] +-basepython = python3.5 +-setenv = +- {[testenv:inventory]setenv} +-commands = +- {[testenv:inventory]commands} +- +- +- +-[testenv:linters] +-deps = +- {[testenv:ansible]deps} +-commands = +- {[testenv:pep8]commands} +- {[testenv:bashate]commands} +- {[testenv:ansible-lint]commands} +- {[testenv:ansible-syntax]commands} +- {[testenv:inventory]commands} +- {[testenv:docs]commands} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/rpmbuild.spec b/rpmbuild.spec new file mode 100644 index 0000000..b05f6c2 --- /dev/null +++ b/rpmbuild.spec @@ -0,0 +1,88 @@ +# Copyright 2019 Nokia +# +# 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. + +Name: openstack-ansible +Version: 17.0.2 +Release: 1%{?dist}.1 +License: %{_platform_licence} and ASL 2.0 +Source0: https://github.com/openstack/%{name}/archive/%{version}.tar.gz +Patch0: 0001-initial.patch +Vendor: %{_platform_vendor} and OpenStack modified +URL: https://github.com/openstack/openstack-ansible +BuildArch: noarch +Summary: openstack-ansible +Requires: openstack-ansible + +%description +openstack-ansible + +%prep +%autosetup -n %{name}-%{version} -p 1 + +%build + +%install +mkdir -p %{buildroot}/opt/openstack-ansible +rsync -av --exclude LICENSE --exclude rpmbuild.spec --exclude inventory/env.d/ --exclude .git/ --exclude .gitreview --exclude .eggs/ . %{buildroot}/opt/openstack-ansible/ +mkdir -p %{buildroot}/usr/local/bin/ +cp -f scripts/openstack-ansible %{buildroot}/usr/local/bin/openstack-ansible +cp -f scripts/openstack-ansible.rc %{buildroot}/usr/local/bin/openstack-ansible.rc +cp -f scripts/setup-controller.sh %{buildroot}/usr/local/bin/ +# Create a dummy directory for role pip_install,apt_package_pinning are dependencies for some roles. +# They are anyway masked with --skip-tags option while running ansible. +mkdir -p %{buildroot}/etc/ansible/roles/etcd +mkdir -p %{buildroot}/etc/ansible/roles/bird +mkdir -p %{buildroot}/etc/ansible/roles/pip_install +mkdir -p %{buildroot}/etc/ansible/roles/apt_package_pinning +mkdir -p %{buildroot}%_bootstrapping_path +mkdir -p %{buildroot}%_provisioning_path +mkdir -p %{buildroot}%_postconfig_path + +%files +/opt/openstack-ansible +%attr(0755, root, root) /usr/local/bin/openstack-ansible +%attr(0755, root, root) /usr/local/bin/setup-controller.sh +/usr/local/bin/openstack-ansible.rc +/etc/ansible/roles/etcd +/etc/ansible/roles/bird +/etc/ansible/roles/pip_install +/etc/ansible/roles/apt_package_pinning +%_bootstrapping_path +%_provisioning_path +%_postconfig_path + + +%post +ln -s /opt/openstack-ansible/playbooks/galera-install.yml %_bootstrapping_path +ln -s /opt/openstack-ansible/playbooks/rabbitmq-install.yml %_bootstrapping_path +ln -s /opt/openstack-ansible/playbooks/rsyslog-install.yml %_bootstrapping_path +ln -s /opt/openstack-ansible/playbooks/os-ironic-install.yml %_bootstrapping_path + +ln -s /opt/openstack-ansible/playbooks/ntp-config.yml %_bootstrapping_path +ln -s /opt/openstack-ansible/playbooks/ntp-config.yml %_provisioning_path + +#postconfig +ln -s /opt/openstack-ansible/playbooks/galera-install.yml %_postconfig_path +ln -s /opt/openstack-ansible/playbooks/memcached-install.yml %_postconfig_path +ln -s /opt/openstack-ansible/playbooks/rabbitmq-install.yml %_postconfig_path +ln -s /opt/openstack-ansible/playbooks/rsyslog-install.yml %_postconfig_path +ln -s /opt/openstack-ansible/playbooks/haproxy-install.yml %_postconfig_path +ln -s /opt/openstack-ansible/playbooks/hosts_config.yml %_postconfig_path +ln -s /opt/openstack-ansible/playbooks/os-ironic-install.yml %_postconfig_path +ln -s /opt/openstack-ansible/playbooks/os-keystone-install.yml %_postconfig_path + +mkdir -p %_platform_etc_path/required-secrets +cp -f /opt/openstack-ansible/etc/openstack_deploy/user_secrets.yml %_platform_etc_path/required-secrets/000-user_secrets.yml + +%postun