From 70200cd28fe9b35670f574e77d49e747f23072f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Floure?= Date: Tue, 21 Jan 2020 10:06:09 +0100 Subject: [PATCH] Refactor __consul_agent type to support distribution packages --- cdist/conf/type/__consul_agent/man.rst | 3 + cdist/conf/type/__consul_agent/manifest | 373 +++++++++++------- .../type/__consul_agent/parameter/boolean | 1 + 3 files changed, 225 insertions(+), 152 deletions(-) diff --git a/cdist/conf/type/__consul_agent/man.rst b/cdist/conf/type/__consul_agent/man.rst index 966abc60..62ee70bb 100644 --- a/cdist/conf/type/__consul_agent/man.rst +++ b/cdist/conf/type/__consul_agent/man.rst @@ -116,6 +116,9 @@ verify-incoming verify-outgoing enforce the use of TLS and verify the peers authenticity on outgoing connections +use-distribution-package + uses distribution package instead of upstream binary + EXAMPLES -------- diff --git a/cdist/conf/type/__consul_agent/manifest b/cdist/conf/type/__consul_agent/manifest index e00f29ec..599f15b4 100755 --- a/cdist/conf/type/__consul_agent/manifest +++ b/cdist/conf/type/__consul_agent/manifest @@ -2,6 +2,7 @@ # # 2015 Steven Armstrong (steven-cdist at armstrong.cc) # 2015-2019 Nico Schottelius (nico-cdist at schottelius.org) +# 2019 Timothée Floure (timothee.floure at ungleich.ch) # # This file is part of cdist. # @@ -19,133 +20,64 @@ # along with cdist. If not, see . # - os=$(cat "$__global/explorer/os") -case "$os" in - alpine|scientific|centos|debian|devuan|redhat|ubuntu) - # whitelist safeguard - : - ;; - *) - echo "Your operating system ($os) is currently not supported by this type (${__type##*/})." >&2 - echo "Please contribute an implementation for it if you can." >&2 - exit 1 - ;; -esac +### +# Type parameters. state="$(cat "$__object/parameter/state")" user="$(cat "$__object/parameter/user")" group="$(cat "$__object/parameter/group")" +release=$(cat "$__global/explorer/lsb_release") +if [ -f "$__object/parameter/use-distribution-package" ]; then + use_distribution_package=1 +fi + +### +# Those are default that might be overriden by os-specific logic. + data_dir="/var/lib/consul" conf_dir="/etc/consul/conf.d" conf_file="config.json" +tls_dir="$conf_dir/tls" -# FIXME: there has got to be a better way to handle the dependencies in this case -case "$state" in - present) - __group "$group" --system --state "$state" - require="__group/$group" \ - __user "$user" --system --gid "$group" \ - --home "$data_dir" --state "$state" - export require="__user/consul" - ;; - absent) - echo "Sorry, state=absent currently not supported :-(" >&2 - exit 1 - require="$__object_name" \ - __user "$user" --system --gid "$group" --state "$state" - require="__user/$user" \ - __group "$group" --system --state "$state" - ;; -esac +### +# Sane deployment, based on distribution package when available. -__directory /etc/consul \ - --owner root --group "$group" --mode 750 --state "$state" -require="__directory/etc/consul" \ - __directory "$conf_dir" \ - --owner root --group "$group" --mode 750 --state "$state" +distribution_setup () { + case "$os" in + debian) + # consul is only available starting Debian 10 (buster). + # See https://packages.debian.org/buster/consul + if [ $release -lt 10 ]; then + echo "Consul is not available for your debian release." >&2 + echo "Please use the 'manual' (i.e. non-package) installation or \ + upgrade the target system." >&2 + exit 1 + fi -if [ -f "$__object/parameter/ca-file-source" ] || [ -f "$__object/parameter/cert-file-source" ] || [ -f "$__object/parameter/key-file-source" ]; then - # create directory for ssl certs - require="__directory/etc/consul" \ - __directory /etc/consul/ssl \ - --owner root --group "$group" --mode 750 --state "$state" -fi + # Override previously defined environment to match debian packaging. + conf_dir='/etc/consul.d' + user='consul' + grou='consul' + ;; + *) + echo "Your operating system ($os) is currently not supported with the \ + --use-distribution-package flag (${__type##*/})." >&2 + echo "Please use non-package installation or contribute an \ + implementation for if you can." >&2 + exit 1 + ;; + esac -__directory "$data_dir" \ - --owner "$user" --group "$group" --mode 770 --state "$state" + # Install consul package. + __package consul --state $state + export config_deployment_requires="__package/consul" +} -# Generate json config file -( -echo "{" - -# parameters we define ourself -printf ' "data_dir": "%s"\n' "$data_dir" - -cd "$__object/parameter/" -for param in *; do - case "$param" in - state|user|group|json-config) continue ;; - ca-file-source|cert-file-source|key-file-source) - source="$(cat "$__object/parameter/$param")" - destination="/etc/consul/ssl/${source##*/}" - require="__directory/etc/consul/ssl" \ - __file "$destination" \ - --owner root --group consul --mode 640 \ - --source "$source" \ - --state "$state" - key="$(echo "${param%-*}" | tr '-' '_')" - printf ' ,"%s": "%s"\n' "$key" "$destination" - ;; - disable-remote-exec|disable-update-check|leave-on-terminate|rejoin-after-leave|server|enable-syslog|verify-incoming|verify-outgoing) - # handle boolean parameters - key="$(echo "$param" | tr '-' '_')" - printf ' ,"%s": true\n' "$key" - ;; - retry-join) - # join multiple parameters into json array - retry_join="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join")" - # remove trailing , - printf ' ,"retry_join": [%s]\n' "${retry_join%*,}" - ;; - retry-join-wan) - # join multiple parameters into json array over wan - retry_join_wan="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join-wan")" - # remove trailing , - printf ' ,"retry_join_wan": [%s]\n' "${retry_join_wan%*,}" - ;; - bootstrap-expect) - # integer key=value parameters - key="$(echo "$param" | tr '-' '_')" - printf ' ,"%s": %s\n' "$key" "$(cat "$__object/parameter/$param")" - ;; - *) - # string key=value parameters - key="$(echo "$param" | tr '-' '_')" - printf ' ,"%s": "%s"\n' "$key" "$(cat "$__object/parameter/$param")" - ;; - esac -done -if [ -f "$__object/parameter/json-config" ]; then - json_config="$(cat "$__object/parameter/json-config")" - if [ "$json_config" = "-" ]; then - json_config="$__object/stdin" - fi - # remove leading and trailing whitespace and commas from first and last line - # indent each line with 3 spaces for consistency - json=$(sed -e 's/^[ \t]*/ /' -e '1s/^[ \t,]*//' -e '$s/[ \t,]*$//' "$json_config") - printf ' ,%s\n' "$json" -fi -echo "}" -) | \ -require="__directory${conf_dir}" \ - __config_file "${conf_dir}/${conf_file}" \ - --owner root --group "$group" --mode 640 \ - --state "$state" \ - --onchange 'service consul status >/dev/null && service consul reload || true' \ - --source - +### +# LEGACY manual deployment, kept for compatibility reasons. init_sysvinit() { @@ -179,47 +111,184 @@ init_upstart() require="__file/etc/init/consul.conf" __start_on_boot consul } -# Install init script to start on boot -case "$os" in - devuan) - init_sysvinit debian - ;; - centos|redhat) - os_version="$(sed 's/[^0-9.]//g' "$__global/explorer/os_version")" - major_version="${os_version%%.*}" - case "$major_version" in - [456]) - init_sysvinit redhat - ;; - 7) - init_systemd - ;; - *) - echo "Unsupported CentOS/Redhat version: $os_version" >&2 - exit 1 - ;; - esac - ;; +manual_setup () { + case "$os" in + alpine|scientific|centos|debian|devuan|redhat|ubuntu) + # whitelist safeguard + : + ;; + *) + echo "Your operating system ($os) is currently not supported by this \ + type (${__type##*/})." >&2 + echo "Please contribute an implementation for it if you can." >&2 + exit 1 + ;; + esac - debian) - os_version=$(cat "$__global/explorer/os_version") - major_version="${os_version%%.*}" + # FIXME: there has got to be a better way to handle the dependencies in this case + case "$state" in + present) + __group "$group" --system --state "$state" + require="__group/$group" __user "$user" \ + --system --gid "$group" --home "$data_dir" --state "$state" + ;; + *) + echo "The $state state is not (yet?) supported by this type." >&2 + exit 1 + ;; + esac - case "$major_version" in - [567]) - init_sysvinit debian - ;; - [89]|10) - init_systemd - ;; - *) - echo "Unsupported Debian version $os_version" >&2 - exit 1 - ;; - esac - ;; + # Create data directory. + require="__user/consul"__directory "$data_dir" \ + --owner "$user" --group "$group" --mode 770 --state "$state" - ubuntu) - init_upstart + # Create config directory. + require="__user/consul" __directory "$conf_dir" \ + --parents --owner root --group "$group" --mode 750 --state "$state" + + # Install init script to start on boot + case "$os" in + devuan) + init_sysvinit debian + ;; + centos|redhat) + os_version="$(sed 's/[^0-9.]//g' "$__global/explorer/os_version")" + major_version="${os_version%%.*}" + case "$major_version" in + [456]) + init_sysvinit redhat + ;; + 7) + init_systemd + ;; + *) + echo "Unsupported CentOS/Redhat version: $os_version" >&2 + exit 1 + ;; + esac + ;; + + debian) + os_version=$(cat "$__global/explorer/os_version") + major_version="${os_version%%.*}" + + case "$major_version" in + [567]) + init_sysvinit debian + ;; + [89]|10) + init_systemd + ;; + *) + echo "Unsupported Debian version $os_version" >&2 + exit 1 + ;; + esac + ;; + + ubuntu) + init_upstart + ;; + esac + + config_deployment_requires="__user/consul __directory/$conf_dir" +} + +### +# Trigger requested installation method. +if [ $use_distribution_package ]; then + distribution_setup +else + manual_setup +fi + +### +# Generate and deploy configuration. +json_configuration=$( + echo "{" + + # parameters we define ourself + printf ' "data_dir": "%s"\n' "$data_dir" + + cd "$__object/parameter/" + for param in *; do + case "$param" in + state|user|group|json-config|use-distribution-package) continue ;; + ca-file-source|cert-file-source|key-file-source) + source="$(cat "$__object/parameter/$param")" + destination="/etc/consul/ssl/${source##*/}" + require="__directory/etc/consul/ssl" \ + __file "$destination" \ + --owner root --group consul --mode 640 \ + --source "$source" \ + --state "$state" + key="$(echo "${param%-*}" | tr '-' '_')" + printf ' ,"%s": "%s"\n' "$key" "$destination" ;; -esac + disable-remote-exec|disable-update-check|leave-on-terminate\ + |rejoin-after-leave|server|enable-syslog|verify-incoming|verify-outgoing) + # handle boolean parameters + key="$(echo "$param" | tr '-' '_')" + printf ' ,"%s": true\n' "$key" + ;; + retry-join) + # join multiple parameters into json array + retry_join="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join")" + # remove trailing , + printf ' ,"retry_join": [%s]\n' "${retry_join%*,}" + ;; + retry-join-wan) + # join multiple parameters into json array over wan + retry_join_wan="$(awk '{printf "\""$1"\","}' "$__object/parameter/retry-join-wan")" + # remove trailing , + printf ' ,"retry_join_wan": [%s]\n' "${retry_join_wan%*,}" + ;; + bootstrap-expect) + # integer key=value parameters + key="$(echo "$param" | tr '-' '_')" + printf ' ,"%s": %s\n' "$key" "$(cat "$__object/parameter/$param")" + ;; + *) + # string key=value parameters + key="$(echo "$param" | tr '-' '_')" + printf ' ,"%s": "%s"\n' "$key" "$(cat "$__object/parameter/$param")" + ;; + esac + done + if [ -f "$__object/parameter/json-config" ]; then + json_config="$(cat "$__object/parameter/json-config")" + if [ "$json_config" = "-" ]; then + json_config="$__object/stdin" + fi + # remove leading and trailing whitespace and commas from first and last line + # indent each line with 3 spaces for consistency + json=$(sed -e 's/^[ \t]*/ /' -e '1s/^[ \t,]*//' -e '$s/[ \t,]*$//' "$json_config") + printf ' ,%s\n' "$json" + fi + echo "}" +) +echo "$json_configuration" | require="$config_deployment_requires" \ + __file "$conf_dir/$conf_file" \ + --owner root --group "$group" --mode 640 \ + --state "$state" \ + --source - + +# Set configuration deployment as requirement for service restart. +restart_requires="__file/$conf_dir/$conf_file" + +### +# Install TLS certificates. +if [ -f "$__object/parameter/ca-file-source" ] || \ + [ -f "$__object/parameter/cert-file-source" ] || \ + [ -f "$__object/parameter/key-file-source" ]; then + + requires="__file/$conf_dir/$conf_file" __directory $conf_dir/tls \ + --owner root --group "$group" --mode 750 --state "$state" + + # Append to service restart requirements. + restart_requires="$restart_requires __directory/$conf_dir/tls" +fi + +### +# Restart consul agent after everything else. +require="$restart_requires" __service consul --action restart diff --git a/cdist/conf/type/__consul_agent/parameter/boolean b/cdist/conf/type/__consul_agent/parameter/boolean index 91f7f17e..c86853c3 100644 --- a/cdist/conf/type/__consul_agent/parameter/boolean +++ b/cdist/conf/type/__consul_agent/parameter/boolean @@ -6,3 +6,4 @@ server enable-syslog verify-incoming verify-outgoing +use-distribution-package