#!/bin/bash # If things break, take out the hammer and remove the hash below: #set -x function usage { echo "Usage: generate_tripleo_hostfile.sh" echo " [-t | --tripleo_ip_address [-l | --localhost]]" echo " [-o | --overcloud_stack_name ]" echo " [-u | --user ]" echo " [-c | --ceph_stack_name ]" echo " [-h | --help]" echo "Generates ssh config file to use with an TripleO undercloud host as a jumpbox and creates ansible inventory file." } user="stack" uncomment_localhost=false tripleo_ip_address= overcloud_name="overcloud" ceph_stack_name=$overcloud_name while [ "$1" != "" ]; do case $1 in -l | --localhost ) uncomment_localhost=true tripleo_ip_address="localhost" ;; -t | --tripleo_ip_address ) shift tripleo_ip_address=$1 ;; -u | --user ) shift user=$1 ;; -o | --overcloud_stack_name ) shift overcloud_name=$1 ;; -c | --ceph_stack_name ) shift ceph_stack_name=$1 ;; -h | --help ) usage exit ;; * ) usage exit 1 esac shift done if [ -z "$tripleo_ip_address" ]; then usage exit 1 fi ansible_inventory_file='hosts' DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" ssh_config_file=${DIR}'/ssh-config' # "Hackish" copy ssh key to self if we are on directly on the undercloud machine: if [[ "${tripleo_ip_address}" == "localhost" ]]; then cat "${HOME}/.ssh/id_rsa.pub" >> "${HOME}/.ssh/authorized_keys" chmod 0600 "${HOME}/.ssh/authorized_keys" sudo bash -c "cat ${HOME}/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys" sudo bash -c "chmod 0600 /root/.ssh/authorized_keys" fi # Check if there are any clouds built. clouds=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack list | grep -i -E '$overcloud_name'") if [ ${#clouds} -gt 0 ]; then nodes=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack server list 2>/dev/null | grep -i -E 'active|running'") if [ ${#nodes} -lt 1 ]; then echo "ERROR: nova list failed to execute properly, please check the openstack-nova-api on the undercloud." exit 1 fi ironic_uuids=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack baremetal node list > >(grep -i -E 'active|running') 2>/dev/null") controller_id=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource show $overcloud_name Controller -c physical_resource_id -f value" | tr '\r' ' ') if [ ${#controller_id} -lt 3 ]; then echo "Error: Controller ID is not reporting correctly. Please see check the openstack-heat-api on the undercloud." exit 1 fi controller_ids=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource list ${controller_id} -c resource_name -f value" | tr '\r' ' ') if [ ${#controller_ids} -lt 1 ]; then echo "Error: Controller IDs is not reporting correctly. Please see check the openstack-heat-api on the undercloud." exit 1 fi networker_id=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource show $overcloud_name Networker -c physical_resource_id -f value" | tr '\r' ' ') if [ ${#networker_id} -lt 3 ]; then echo "Info: No Networker resources." else networker_ids=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource list ${networker_id} -c resource_name -f value" | tr '\r' ' ') if [ ${#networker_ids} -lt 1 ]; then echo "Info: No Networker resources." fi fi blockstorage_id=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource show $overcloud_name BlockStorage -c physical_resource_id -f value" | tr '\r' ' ') if [ ${#blockstorage_id} -lt 3 ]; then echo "Info: No BlockStorage resources." else #blockstorage_ids=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource list ${blockstorage_id} > >(grep -i blockstorage) 2>/dev/null" | awk '{print $2}') blockstorage_ids=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource list ${blockstorage_id} -c resource_name -f value" | tr '\r' ' ') if [ ${#blockstorage_ids} -lt 1 ]; then echo "Info: No BlockStorage resources." fi fi objectstorage_id=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource show $overcloud_name ObjectStorage -c physical_resource_id -f value" | tr '\r' ' ') if [ ${#objectstorage_id} -lt 3 ]; then echo "Info: No ObjectStorage resources." else objectstorage_ids=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource list ${objectstorage_id} -c resource_name -f value" | tr '\r' ' ') if [ ${#objectstorage_ids} -lt 1 ]; then echo "Info: No ObjectStorage resources." fi fi cephstorage_id=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource show $ceph_stack_name CephStorage -c physical_resource_id -f value" | tr '\r' ' ') if [ ${#cephstorage_id} -lt 3 ]; then echo "Info: No CephStorage resources." else cephstorage_ids=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource list ${cephstorage_id} -c resource_name -f value" | tr '\r' ' ') if [ ${#cephstorage_ids} -lt 1 ]; then echo "Info: No CephStorage resources." fi fi compute_resources=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource list $overcloud_name" | awk '{print $2}' | egrep -i 'Compute$|hci$') for resource in $compute_resources; do compute_resources_arr+=($(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource show $overcloud_name $resource | grep physical_resource_id")); done compute_resource_ids=$(for id in ${compute_resources_arr[@]}; do echo $id | grep -v '|' | grep -v physical_resource_id; done) if [ ${#compute_resource_ids} -lt 3 ]; then echo "Info: No compute resources" else for compute_id in $compute_resource_ids; do compute_ids+=($(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource list ${compute_id} > >(grep -i compute) 2>/dev/null" | awk '{print $2}')) done compute_ids=$(for id in ${compute_ids[@]}; do echo $id; done) if [ ${#compute_ids} -lt 1 ]; then echo "Info: No compute resources" fi fi controller_uuids=() for controller in ${controller_ids} do controller_uuids+=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource show -c attributes -f json ${controller_id} ${controller} | jq .attributes.nova_server_resource") done networker_uuids=() for networker in ${networker_ids} do networker_uuids+=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource show -c attributes -f json ${networker_id} ${networker} | jq .attributes.nova_server_resource") done blockstorage_uuids=() for blockstorage in ${blockstorage_ids} do blockstorage_uuids+=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource show -c attributes -f json ${blockstorage_id} ${blockstorage} | jq .attributes.nova_server_resource") done objectstorage_uuids=() for objectstorage in ${objectstorage_ids} do objectstorage_uuids+=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource show -c attributes -f json ${objectstorage_id} ${objectstorage} | jq .attributes.nova_server_resource") done cephstorage_uuids=() for cephstorage in ${cephstorage_ids} do cephstorage_uuids+=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource show -c attributes -f json ${cephstorage_id} ${cephstorage} | jq .attributes.nova_server_resource") done compute_uuids=() for compute in ${compute_ids} do for compute_id in $compute_resource_ids; do compute_uuids+=$(ssh -tt -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" ${user}@${tripleo_ip_address} ". ~/stackrc; openstack stack resource show -c attributes -f json ${compute_id} ${compute} | jq .attributes.nova_server_resource") done done fi echo "" echo "---------------------------" echo "Creating ssh config file:" echo "---------------------------" echo "" echo "# Generated by generate_tripleo_hostfile.sh from browbeat" | tee ${ssh_config_file} echo "" | tee -a ${ssh_config_file} echo "Host undercloud" | tee -a ${ssh_config_file} echo " Hostname ${tripleo_ip_address}" | tee -a ${ssh_config_file} echo " IdentityFile ~/.ssh/id_rsa" | tee -a ${ssh_config_file} echo " StrictHostKeyChecking no" | tee -a ${ssh_config_file} echo " UserKnownHostsFile=/dev/null" | tee -a ${ssh_config_file} echo "" | tee -a ${ssh_config_file} echo "Host undercloud-root" | tee -a ${ssh_config_file} echo " Hostname ${tripleo_ip_address}" | tee -a ${ssh_config_file} echo " User root" | tee -a ${ssh_config_file} echo " IdentityFile ~/.ssh/id_rsa" | tee -a ${ssh_config_file} echo " StrictHostKeyChecking no" | tee -a ${ssh_config_file} echo " UserKnownHostsFile=/dev/null" | tee -a ${ssh_config_file} echo "" | tee -a ${ssh_config_file} echo "Host undercloud-stack" | tee -a ${ssh_config_file} echo " Hostname ${tripleo_ip_address}" | tee -a ${ssh_config_file} echo " User stack" | tee -a ${ssh_config_file} echo " IdentityFile ~/.ssh/id_rsa" | tee -a ${ssh_config_file} echo " StrictHostKeyChecking no" | tee -a ${ssh_config_file} echo " UserKnownHostsFile=/dev/null" | tee -a ${ssh_config_file} blockstorage_hn=() cephstorage_hn=() compute_hn=() controller_hn=() networker_hn=() objectstorage_hn=() IFS=$'\n' for line in $nodes; do uuid=$(echo $line | awk '{print $2}') host=$(echo $line | awk '{print $4}') IP=$(echo $line | awk '{print $8}' | cut -d "=" -f2) if grep -q $uuid <<< {$controller_uuids}; then controller_hn+=("$host") elif grep -q $uuid <<< {$networker_uuids}; then networker_hn+=("$host") elif grep -q $uuid <<< {$blockstorage_uuids}; then blockstorage_hn+=("$host") elif grep -q $uuid <<< {$objectstorage_uuids}; then objectstorage_hn+=("$host") elif grep -q $uuid <<< {$cephstorage_uuids}; then cephstorage_hn+=("$host") elif grep -q $uuid <<< {$compute_uuids}; then compute_hn+=("$host") else other_hn+=("$host") fi echo "" | tee -a ${ssh_config_file} echo "Host ${host}" | tee -a ${ssh_config_file} echo " ProxyCommand ssh -F ${ssh_config_file} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=60 -i ~/.ssh/id_rsa ${user}@${tripleo_ip_address} -W ${IP}:22" | tee -a ${ssh_config_file} echo " User heat-admin" | tee -a ${ssh_config_file} echo " IdentityFile ${DIR}/heat-admin-id_rsa" | tee -a ${ssh_config_file} echo " StrictHostKeyChecking no" | tee -a ${ssh_config_file} echo " UserKnownHostsFile=/dev/null" | tee -a ${ssh_config_file} # Substitute the nova instance id for the host name so we can attach the ironic uuid as a host var ironic_uuids=${ironic_uuids/$uuid/$host} done # Sort Host Types controller_hn=( $( for item in "${controller_hn[@]}" do echo "$item" done | sort) ) networker_hn=( $( for item in "${networker_hn[@]}" do echo "$item" done | sort) ) blockstorage_hn=( $( for item in "${blockstorage_hn[@]}" do echo "$item" done | sort) ) objectstorage_hn=( $( for item in "${objectstorage_hn[@]}" do echo "$item" done | sort) ) cephstorage_hn=( $( for item in "${cephstorage_hn[@]}" do echo "$item" done | sort) ) compute_hn=( $( for item in "${compute_hn[@]}" do echo "$item" done | sort) ) echo "" echo "---------------------------" echo "Creating ansible inventory file:" echo "---------------------------" echo "" echo "[Browbeat]" | tee ${ansible_inventory_file} echo "# Pick host depending on desired install" | tee -a ${ansible_inventory_file} if [ "${uncomment_localhost}" = true ]; then echo "localhost" | tee -a ${ansible_inventory_file} echo "#undercloud" | tee -a ${ansible_inventory_file} else echo "#localhost" | tee -a ${ansible_inventory_file} echo "undercloud ansible_user=${user}" | tee -a ${ansible_inventory_file} fi echo "" | tee -a ${ansible_inventory_file} echo "[Undercloud]" | tee -a ${ansible_inventory_file} echo "undercloud ansible_user=${user}" | tee -a ${ansible_inventory_file} echo "" | tee -a ${ansible_inventory_file} echo "[Controller]" | tee -a ${ansible_inventory_file} if [[ ${#controller_hn} -gt 0 ]]; then for ct in ${controller_hn[@]}; do ironic_uuid='' for line in ${ironic_uuids}; do uuid=$(echo $line | awk '{print $2}') host=$(echo $line | awk '{print $6}') if [ "$host" == "$ct" ]; then ironic_uuid=$uuid break fi done echo "${ct} ironic_uuid=${ironic_uuid}" | tee -a ${ansible_inventory_file} done fi echo "" | tee -a ${ansible_inventory_file} echo "[Networker]" | tee -a ${ansible_inventory_file} if [[ ${#networker_hn} -gt 0 ]]; then for networker in ${networker_hn[@]}; do ironic_uuid='' for line in ${ironic_uuids}; do uuid=$(echo $line | awk '{print $2}') host=$(echo $line | awk '{print $6}') if [ "$host" == "$networker" ]; then ironic_uuid=$uuid break fi done echo "${networker} ironic_uuid=${ironic_uuid}" | tee -a ${ansible_inventory_file} done fi echo "" | tee -a ${ansible_inventory_file} echo "[BlockStorage]" | tee -a ${ansible_inventory_file} if [[ ${#blockstorage_hn} -gt 0 ]]; then for blockstorage in ${blockstorage_hn[@]}; do ironic_uuid='' for line in ${ironic_uuids}; do uuid=$(echo $line | awk '{print $2}') host=$(echo $line | awk '{print $6}') if [ "$host" == "$blockstorage" ]; then ironic_uuid=$uuid break fi done echo "${blockstorage} ironic_uuid=${ironic_uuid}" | tee -a ${ansible_inventory_file} done fi echo "" | tee -a ${ansible_inventory_file} echo "[ObjectStorage]" | tee -a ${ansible_inventory_file} if [[ ${#objectstorage_hn} -gt 0 ]]; then for objectstorage in ${objectstorage_hn[@]}; do ironic_uuid='' for line in ${ironic_uuids}; do uuid=$(echo $line | awk '{print $2}') host=$(echo $line | awk '{print $6}') if [ "$host" == "$objectstorage" ]; then ironic_uuid=$uuid break fi done echo "${objectstorage} ironic_uuid=${ironic_uuid}" | tee -a ${ansible_inventory_file} done fi echo "" | tee -a ${ansible_inventory_file} echo "[CephStorage]" | tee -a ${ansible_inventory_file} if [[ ${#cephstorage_hn} -gt 0 ]]; then for cephstorage in ${cephstorage_hn[@]}; do ironic_uuid='' for line in ${ironic_uuids}; do uuid=$(echo $line | awk '{print $2}') host=$(echo $line | awk '{print $6}') if [ "$host" == "$cephstorage" ]; then ironic_uuid=$uuid break fi done echo "${cephstorage} ironic_uuid=${ironic_uuid}" | tee -a ${ansible_inventory_file} done fi echo "" | tee -a ${ansible_inventory_file} echo "[Compute]" | tee -a ${ansible_inventory_file} if [[ ${#compute_hn} -gt 0 ]]; then for compute in ${compute_hn[@]}; do ironic_uuid='' for line in ${ironic_uuids}; do uuid=$(echo $line | awk '{print $2}') host=$(echo $line | awk '{print $6}') if [ "$host" == "$compute" ]; then ironic_uuid=$uuid break fi done echo "${compute} ironic_uuid=${ironic_uuid}" | tee -a ${ansible_inventory_file} done fi if [[ ${#controller_hn} -gt 0 ]] || [[ ${#blockstorage_hn} -gt 0 ]] || [[ ${#objectstorage_hn} -gt 0 ]] || [[ ${#cephstorage_hn} -gt 0 ]] || [[ ${#compute_hn} -gt 0 ]]; then echo "" | tee -a ${ansible_inventory_file} echo "[overcloud:children]" | tee -a ${ansible_inventory_file} if [[ ${#controller_hn} -gt 0 ]]; then echo "Controller" | tee -a ${ansible_inventory_file} fi if [[ ${#networker_hn} -gt 0 ]]; then echo "Networker" | tee -a ${ansible_inventory_file} fi if [[ ${#blockstorage_hn} -gt 0 ]]; then echo "BlockStorage" | tee -a ${ansible_inventory_file} fi if [[ ${#objectstorage_hn} -gt 0 ]]; then echo "ObjectStorage" | tee -a ${ansible_inventory_file} fi if [[ ${#cephstorage_hn} -gt 0 ]]; then echo "CephStorage" | tee -a ${ansible_inventory_file} fi if [[ ${#compute_hn} -gt 0 ]]; then echo "Compute" | tee -a ${ansible_inventory_file} fi echo "" | tee -a ${ansible_inventory_file} echo "[overcloud:vars]" | tee -a ${ansible_inventory_file} echo "ansible_user=heat-admin" | tee -a ${ansible_inventory_file} fi echo "" | tee -a ${ansible_inventory_file} echo "[other]" | tee -a ${ansible_inventory_file} if [[ ${#other_hn} -gt 0 ]]; then for other in ${other_hn[@]}; do echo "${other}" | tee -a ${ansible_inventory_file} done fi echo "" | tee -a ${ansible_inventory_file} echo "[Graphite]" | tee -a ${ansible_inventory_file} echo "## example host entry." | tee -a ${ansible_inventory_file} echo "#host-01" | tee -a ${ansible_inventory_file} echo "" | tee -a ${ansible_inventory_file} echo "[Grafana]" | tee -a ${ansible_inventory_file} echo "## example host entry." | tee -a ${ansible_inventory_file} echo "#host-02" | tee -a ${ansible_inventory_file} echo "---------------------------" echo "IMPORTANT: If you plan on deploying graphite and grafana, update hosts and make sure" echo " the [graphite] and [grafana] hosts entries are updated with valid hosts." echo " You will need to have passwordless access to root on these hosts." echo "---------------------------" echo "" | tee -a ${ansible_inventory_file} echo "[elk-client]" | tee -a ${ansible_inventory_file} echo "## example host entry." | tee -a ${ansible_inventory_file} echo "#host-02" | tee -a ${ansible_inventory_file} echo "" | tee -a ${ansible_inventory_file} echo "[Stockpile]" | tee -a ${ansible_inventory_file} echo "undercloud ansible_user=${user}" | tee -a ${ansible_inventory_file} echo "---------------------------" echo "IMPORTANT: If you plan on deploying ELK clients, update hosts and make sure" echo " the [elk-client] hosts entries are updated with valid hosts." echo " You will need to have passwordless access to root on these hosts." echo "---------------------------" # Before referencing a host in ~/.ssh/config, ensure correct permissions on ssh config file chmod 0600 ${ssh_config_file} # Copy heat-admin key so we can use jumpbox echo "" echo "---------------------------" echo "Copying heat-admin key to local machine(~/.ssh/heat-admin-id_rsa) to for use with ssh config file" echo "---------------------------" echo "" scp -o "UserKnownHostsFile /dev/null" -o "StrictHostKeyChecking no" "${user}@${tripleo_ip_address}":/home/${user}/.ssh/id_rsa heat-admin-id_rsa