#!/bin/sh

# Test PuppetDB & Puppet integration
# Configure PuppetDB and Puppet master to talk to each other, do a client run
# and check the results.

. "$(dirname $0)/common.sh"

set -e

trap 'cleanup' EXIT

certname="$(puppet config print certname)"

# if system fdqn is missing domain part, add explicit certname entry in hosts
if [ "$certname" != "$(hostname -f)" ]; then
    puppet resource host "$certname" ip=127.0.0.1
fi

# bring up puppetserver

puppet config set --section=server autosign true
puppet config set --section=server reports puppetdb
puppet config set --section=server storeconfigs true
puppet config set --section=server storeconfigs_backend puppetdb

echo "Starting Puppet Server ..."
systemctl start puppetserver

# generate ssl certs

echo "Bootstrapping SSL certificates ..."
puppet ssl bootstrap

# bring up puppetdb

echo "Setting up SSL for PuppetDB ..."
puppetdb ssl-setup

if systemctl --quiet is-active puppetdb.service; then
    echo "Restarting PuppetDB ..."
    systemctl restart puppetdb
else
    echo "Starting PuppetDB ..."
    systemctl start puppetdb
fi

cp /usr/share/doc/puppet-terminus-puppetdb/routes.yaml.example /etc/puppet/routes.yaml
cat >/etc/puppet/puppetdb.conf <<-EOF
	[main]
	server_urls = https://${certname}:8081
EOF

# create test production environment

mkdir -p /etc/puppet/code/environments/production/manifests

cat >/etc/puppet/code/environments/production/manifests/default.pp <<-EOF
	node "$certname" {
	  file { '/tmp/testfile' :
	    ensure  => present,
	    content => "autopkgtest\n",
	  }
      @@file { '/tmp/exported':
        ensure  => present,
        content => "autopkgtest\n",
      }
	}
    node collector.example.com {
      File <<| |>>
    }
EOF

# run the test

echo "Running puppet agent"
puppet agent --test --server "$certname" && [ $? -eq 2 ]

echo "Checking for /tmp/testfile"
test -f /tmp/testfile

echo "Running puppet agent (collector)"
puppet config set certname collector.example.com
puppet agent --test --server "$certname" && [ $? -eq 2 ]

echo "Checking for /tmp/exported"
test -f /tmp/exported

sleep 5 # Let PuppetDB commit stuff to the database

echo "Checking for node existence"
query "nodes/${certname}" | jq -e ".certname == \"${certname}\""

echo "Checking the fqdn fact"
query "nodes/${certname}/facts/networking" | jq -e ".[0].value.fqdn == \"${certname}\""

echo "Checking the node's catalog"
query "catalogs/${certname}" | jq -e 'has("catalog_uuid")'

echo "Checking the node's report"
query "reports" | jq -e "(map(select(.certname == \"${certname}\")) | length) >= 1"

echo "Checking 'puppet node status ${certname}'"
puppet node status "$certname" | grep -qi "\bactive\b"

echo "Deactivating node"
puppet node deactivate "$certname"

sleep 2 # Let PuppetDB process everything

echo "Checking 'puppet node status ${certname}' again"
puppet node status "$certname" | grep -qi "Deactivated"
