summaryrefslogtreecommitdiffstats
path: root/salt-keydiff.sh
blob: 324d0ad2d0047206f601ab636f5654423bb3c434 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#!/bin/sh
# Copyright 2023, Georg Pfuetzenreuter
#
# Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence").
# You may not use this work except in compliance with the Licence.
# An English copy of the Licence is shipped in a file called LICENSE along with this applications source code.
# You may obtain copies of the Licence in any of the official languages at https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12.
#
# ---
#
# This program helps with accepting Salt minion keys by asking for a key to compare with first. Intended to be run on a Salt master.

set -Ceu

config='/etc/salt-scriptconfig'
partner='null'
minion="${1:-null}"
key_user="${2:-null}"
NOCOLOR="$(tput sgr0)"
exco=0

if ! command -v jq >/dev/null || ! command -v salt-key >/dev/null
then
	printf 'Please ensure jq and salt-key are available.\n'
	exit 1
fi

if [ -f "$config" ]
then
	# shellcheck source=/dev/null
	. "$config"
	if [ ! "$partner" = 'null' ]
	then
		ssh_key="${ssh_key:?Configuration option 'partner' requires 'ssh_key'}"
	fi
fi

if [ "$minion" = 'null' ]
then
	printf 'Please specify the minion to diff against.\n'
	exit 1
fi

key_salt="$(salt-key --out json -f "$minion" | jq --arg minion "$minion" -r '.minions_pre[$minion]')"

if [ "$key_salt" = 'null' ]
then
	printf 'No pending keys for %s.\n' "$minion"
	exit 2
fi

if [ ! "$partner" = 'null' ]
then
	key_salt_remote="$(ssh -qi "$ssh_key" "$partner" salt-key --out json -f "$minion" | jq --arg minion "$minion" -r '.minions_pre[$minion]')"
	
	if [ ! "$key_salt" = "$key_salt_remote" ]
	then
		printf 'Local and remote keys do not match, bailing out.\n'
		exit 2
	fi
fi

if [ "$key_user" = 'null' ]
then
	# shellcheck disable=SC2016
	printf 'Enter fingerprint to diff against (run `salt-call --local key.finger` on the minion)\n'
	read -r key_user
fi

if [ "$key_salt" = "$key_user" ]
then
	GREEN="$(tput setaf 2)"
	printf '%sMatches%s\n' "$GREEN" "$NOCOLOR"
	printf 'Accept? (y/n)\n'
	read -r answer
	if [ "$answer" = 'y' ]
	then
		if salt-key --out=quiet -yqa "$minion" >/dev/null
		then
			printf 'Accepted on local master\n'
		else
			printf 'Failed to accept key on local master\n'
			exco=1
		fi

		if [ ! "$partner" = 'null' ]
		then
			if ssh -qi "$ssh_key" "$partner" salt-key --out=quiet -yqa "$minion" >/dev/null
			then
				printf 'Accepted on remote master\n'
			else
				printf 'Failed to accept key on remote master\n'
				exco=1
			fi
		fi
	else
		printf 'Bye\n'
		exco=2
	fi
elif [ ! "$key_salt" = "$key_user" ]
then
	RED="$(tput setaf 1)"
	printf '%sMismatch%s\n' "$RED" "$NOCOLOR"
	exco=2
fi

exit "$exco"