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
  PythonInterpreter:
    type: string
    description: The python interpreter to use for python and ansible actions
    default: /usr/bin/python
  MakeHomeDir:
    type: boolean
    description: Configure PAM to create a users home directory if it does not exist.
    default: False
  IdMDomain:
    default: ''
    description: IDM domain to register IDM client. Typically, this is discovered
                 through DNS and does not have to be set explicitly.
    type: string
  IdMNoNtpSetup:
    default: False
    description: Set to true to add --no-ntp to the IDM client install call.
                 This will cause IDM client install not to set up NTP.
    type: boolean

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
          vars:
            python_interpreter: {get_param: PythonInterpreter}
            makehomedir: {get_param: MakeHomeDir}
            idm_domain: {get_param: IdMDomain}
            idm_no_ntp: {get_param: IdMNoNtpSetup}
          block:
          - name: install needed packages
            package:
              name: "{{ item }}"
              state: present
            with_items:
              - ipa-client
              - ipa-admintools
              - 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_interpreter }} -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
                }

                function get_fqdn {
                    # Get the instance hostname out of the metadata
                    fqdn=`echo $data | {{ python_interpreter }} -c 'import json,sys;obj=json.load(sys.stdin);print(obj.get("join", {}).get("hostname", ""))'`
                    if [ -z "$fqdn"]; then
                        echo "Unable to determine hostname"
                        return 1
                    fi
                    return 0
                }

                if ! get_metadata_config_drive || ! get_fqdn; then
                   if ! get_metadata_network || ! get_fqdn; then
                       echo "FATAL: No metadata available or could not read the hostname from the metadata"
                       exit 1
                   fi
                fi

                realm=`echo $data | {{ python_interpreter }} -c 'import json,sys;obj=json.load(sys.stdin);print(obj.get("join", {}).get("krb_realm", ""))'`
                otp=`echo $data | {{ python_interpreter }} -c 'import json,sys;obj=json.load(sys.stdin);print(obj.get("join", {}).get("ipaotp", ""))'`

                # Force hostname to use the FQDN
                hostnamectl set-hostname $fqdn

                makehomedir={{ makehomedir }}
                idm_no_ntp={{ idm_no_ntp }}
                idm_domain={{ idm_domain }}

                # run ipa-client-install
                OPTS="-U -w $otp --hostname $fqdn"

                if [ -n "$realm" ]; then
                    OPTS="$OPTS --realm=$realm"
                fi
                if [ -n "$idm_domain" ]; then
                    OPTS="$OPTS --domain=$idm_domain"
                fi
                if [ "${makehomedir,,}" = "true" ]; then
                    OPTS="$OPTS --mkhomedir"
                fi
                if [ "${idm_no_ntp,,}" = "true" ]; then
                    OPTS="$OPTS --no-ntp"
                fi


                # Ensure we have the proper domain in /etc/resolv.conf
                domain=$(hostname -d)
                if [ -n "$idm_domain" ]; then
                    domain = "$domain $idm_domain"
                fi
                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: determine if client is already enrolled
            stat:
              path: /etc/ipa/default.conf
            register: ipa_default_conf

          - block:
            - name: run enrollment script
              shell: /root/setup-ipa-client.sh >> /var/log/setup-ipa-client-ansible.log 2>&1

            - name: restart certmonger service
              systemd:
                state: restarted
                daemon_reload: true
                name: certmonger.service
            when: ipa_default_conf.stat.exists == False
