#!/bin/sh -e # # 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. # # cdist is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # cdist is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with cdist. If not, see . # os=$(cat "$__global/explorer/os") ### # 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" ### # Sane deployment, based on distribution package when available. 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 # Override previously defined environment to match debian packaging. conf_dir='/etc/consul.d' user='consul' group='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 # Install consul package. __package consul --state "$state" export config_deployment_requires="__package/consul" } ### # LEGACY manual deployment, kept for compatibility reasons. init_sysvinit() { __file /etc/init.d/consul \ --owner root --group root --mode 0755 \ --state "$state" \ --source "$__type/files/consul.sysv-$1" require="__file/etc/init.d/consul" __start_on_boot consul } init_systemd() { __file /lib/systemd/system/consul.service \ --owner root --group root --mode 0644 \ --state "$state" \ --source "$__type/files/consul.systemd" require="__file/lib/systemd/system/consul.service" __start_on_boot consul } init_upstart() { __file /etc/init/consul-prepare.conf \ --owner root --group root --mode 0644 \ --state "$state" \ --source "$__type/files/consul-prepare.upstart" require="__file/etc/init/consul-prepare.conf" \ __file /etc/init/consul.conf \ --owner root --group root --mode 0644 \ --state "$state" \ --source "$__type/files/consul.upstart" require="__file/etc/init/consul.conf" __start_on_boot consul } 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 # 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 # Create data directory. require="__user/consul" __directory "$data_dir" \ --owner "$user" --group "$group" --mode 770 --state "$state" # 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 ### # Install TLS certificates. if [ -f "$__object/parameter/ca-file-source" ] || \ [ -f "$__object/parameter/cert-file-source" ] || \ [ -f "$__object/parameter/key-file-source" ]; then requires="$config_deployment_requires" __directory $tls_dir \ --owner root --group "$group" --mode 750 --state "$state" # Append to service restart requirements. restart_requires="$restart_requires __directory/$conf_dir/tls" 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="$tls_dir/${source##*/}" require="__directory/$tls_dir" \ __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 "}" ) 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" ### # Restart consul agent after everything else. require="$restart_requires" __service consul --action restart