heat_template_version: rocky

description: Configure hieradata overrides for specific nodes

parameters:
  server:
    description: ID of the controller node to apply this config to
    type: string

  # Config specific parameters, to be provided via parameter_defaults
  # This would be a lookup of the node UUID as provided by dmidecode
  # to the json required for the node-specific hieradata
  # Note this needs to be a json blob e.g:
  #      parameter_defaults:
  #        NodeDataLookup:
  #          {"AB4114B1-9C9D-409A-BEFB-D88C151BF2C3": {"foo": "bar"},
  #           "8CF1A7EA-7B4B-4433-AC83-17675514B1B8": {"foo2": "bar2"}}
  NodeDataLookup:
    type: json
    default: {}
    description: json containing per-node configuration map

resources:
  NodeSpecificConfig:
    type: OS::Heat::SoftwareConfig
    properties:
      group: script
      inputs:
      - name: node_lookup
      config: |
        #!/bin/sh
        node_id=$(dmidecode --s system-uuid | awk 'match($0, \
                /[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}/) \
                { print substr($0, RSTART, RLENGTH) }' | tr '[:upper:]' '[:lower:]')
        # thanks to dmidecode 3.1, we have to handle both the upper case
        # and lower case versions of the UUID from dmidecode. LP#1816652
        # upper for dmidecode < 3.1 and lower for dmidecode >= 3.1
        node_id_upper=$(echo $node_id | tr '[:lower:]' '[:upper:]')

        # needed to handle where python lives
        function get_python() {
          command -v python3 || command -v python2 || command -v python || exit 1
        }
        # Create a /etc/puppet/hieradata/UUID.json file to provide
        # the data of the NodeDataLookup parameter that matches the
        # system UUID
        echo $node_lookup | $(get_python) -c "
        import json
        import sys
        input = sys.stdin.readline() or '{}'
        cnt = json.loads(input)
        print json.dumps(cnt.get('${node_id}', {}))
        " > /etc/puppet/hieradata/${node_id}.json
        # handle upper case node id LP#1816652
        echo $node_lookup | $(get_python) -c "
        import json
        import sys
        input = sys.stdin.readline() or '{}'
        cnt = json.loads(input)
        print json.dumps(cnt.get('${node_id_upper}', {}))
        " > /etc/puppet/hieradata/${node_id_upper}.json

  NodeSpecificDeployment:
    type: OS::Heat::SoftwareDeployment
    properties:
      name: NodeSpecificDeployment
      config: {get_resource: NodeSpecificConfig}
      server: {get_param: server}
      input_values:
        node_lookup: {get_param: NodeDataLookup}

outputs:
  deploy_stdout:
    description: Deployment reference, used to trigger puppet apply on changes
    value: {get_attr: [NodeSpecificDeployment, deploy_stdout]}
