2a83856585
This addresses a possible bug when using FreeIPA to do TLS everywhere. It is possible that the IPA server is not on the ctlplane. In this case, when the nodes start up, the registration of the node with IPA will fail, resulting in failed certificate issuance requests later on. We introduce a composable service to run in host_prep_tasks. This will always run once the networks have been set up. If the instance has already been enrolled (by cloud-init or in an update), then the script executed by the service will just exit. In this iteration, we simply execute the code that the cloud-init would have done. In later releases, we will execute all the code performed by novajoin-server here in ansible - and deprecate the novajoin server. Change-Id: I31f64c3cbd1d151e3c2a436cc3e2ec5316535087 Co-Authored-By: Juan Antonio Osorio Robles <jaosorior@redhat.com> Resolves: rhbz#1661635 Closes-Bug: #1815924
148 lines
5.2 KiB
YAML
148 lines
5.2 KiB
YAML
heat_template_version: rocky
|
|
|
|
description: Registers nodes with the IPA server
|
|
|
|
parameters:
|
|
RoleNetIpMap:
|
|
default: {}
|
|
type: json
|
|
ServiceData:
|
|
default: {}
|
|
description: Dictionary packing service data
|
|
type: json
|
|
ServiceNetMap:
|
|
default: {}
|
|
description: Mapping of service_name -> network name. Typically set
|
|
via parameter_defaults in the resource registry. This
|
|
mapping overrides those in ServiceNetMapDefaults.
|
|
type: json
|
|
DefaultPasswords:
|
|
default: {}
|
|
type: json
|
|
RoleName:
|
|
default: ''
|
|
description: Role name on which the service is applied
|
|
type: string
|
|
RoleParameters:
|
|
default: {}
|
|
description: Parameters specific to the role
|
|
type: json
|
|
EndpointMap:
|
|
default: {}
|
|
description: Mapping of service endpoint -> protocol. Typically set
|
|
via parameter_defaults in the resource registry.
|
|
type: json
|
|
|
|
outputs:
|
|
role_data:
|
|
description: Role data for the ipaclient service
|
|
value:
|
|
service_name: ipaclient
|
|
upgrade_tasks: []
|
|
step_config: ''
|
|
host_prep_tasks:
|
|
- name: enroll client in ipa and get metadata
|
|
become: yes
|
|
block:
|
|
- name: install needed packages
|
|
package:
|
|
name: "{{ item }}"
|
|
state: present
|
|
with_items:
|
|
- python-simplejson
|
|
- ipa-client
|
|
- ipa-admintools
|
|
- openldap-clients
|
|
- hostname
|
|
|
|
- name: create enrollment script
|
|
copy:
|
|
dest: /root/setup-ipa-client.sh
|
|
mode: '0700'
|
|
content: |
|
|
#!/bin/sh
|
|
set -x
|
|
|
|
function get_metadata_config_drive {
|
|
if [ -f /run/cloud-init/status.json ]; then
|
|
# Get metadata from config drive
|
|
data=`cat /run/cloud-init/status.json`
|
|
config_drive=`echo $data | python -c 'import json,re,sys;obj=json.load(sys.stdin);ds=obj.get("v1", {}).get("datasource"); print re.findall(r"source=(.*)]", ds)[0]'`
|
|
if [[ -b $config_drive ]]; then
|
|
temp_dir=`mktemp -d`
|
|
mount $config_drive $temp_dir
|
|
if [ -f $temp_dir/openstack/latest/vendor_data2.json ]; then
|
|
data=`cat $temp_dir/openstack/latest/vendor_data2.json`
|
|
umount $config_drive
|
|
rmdir $temp_dir
|
|
else
|
|
umount $config_drive
|
|
rmdir $temp_dir
|
|
fi
|
|
else
|
|
echo "Unable to retrieve metadata from config drive."
|
|
return 1
|
|
fi
|
|
else
|
|
echo "Unable to retrieve metadata from config drive."
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
function get_metadata_network {
|
|
# Get metadata over the network
|
|
data=$(timeout 300 /bin/bash -c 'data=""; while [ -z "$data" ]; do sleep $[ ( $RANDOM % 10 ) + 1 ]s; data=`curl -s http://169.254.169.254/openstack/2016-10-06/vendor_data2.json 2>/dev/null`; done; echo $data')
|
|
|
|
if [[ $? != 0 ]] ; then
|
|
echo "Unable to retrieve metadata from metadata service."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
if ! get_metadata_config_drive; then
|
|
if ! get_metadata_network; then
|
|
echo "FATAL: No metadata available"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Get the instance hostname out of the metadata
|
|
fqdn=`echo $data | python -c 'import json,sys;obj=json.load(sys.stdin);print obj.get("join", {}).get("hostname", "")'`
|
|
|
|
if [ -z "$fqdn" ]; then
|
|
echo "Unable to determine hostname"
|
|
exit 1
|
|
fi
|
|
|
|
realm=`echo $data | python -c 'import json,sys;obj=json.load(sys.stdin);print obj.get("join", {}).get("krb_realm", "")'`
|
|
otp=`echo $data | python -c 'import json,sys;obj=json.load(sys.stdin);print obj.get("join", {}).get("ipaotp", "")'`
|
|
|
|
hostname=`/bin/hostname -f`
|
|
|
|
# Force hostname to use the FQDN
|
|
hostnamectl set-hostname $fqdn
|
|
|
|
# run ipa-client-install
|
|
OPTS="-U -w $otp"
|
|
if [ $hostname != $fqdn ]; then
|
|
OPTS="$OPTS --hostname $fqdn"
|
|
fi
|
|
if [ -n "$realm" ]; then
|
|
OPTS="$OPTS --realm=$realm"
|
|
fi
|
|
|
|
# Ensure we have the proper domain in /etc/resolv.conf
|
|
domain=$(hostname -d)
|
|
if ! grep -q ${domain} /etc/resolv.conf ; then
|
|
sed -i "0,/nameserver/s/\(nameserver.*\)/search ${domain}\n\1/" /etc/resolv.conf
|
|
fi
|
|
|
|
ipa-client-install $OPTS
|
|
|
|
- name: run enrollment script
|
|
shell: /root/setup-ipa-client.sh >> /var/log/setup-ipa-client-ansible.log 2>&1
|
|
args:
|
|
creates: /etc/ipa/default.conf
|