-
-
Notifications
You must be signed in to change notification settings - Fork 133
/
Copy pathaws-route53-rrs.sh
executable file
·166 lines (148 loc) · 4.06 KB
/
aws-route53-rrs.sh
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/bin/bash
#
# Create, list and update AWS Route53 DNS resource record sets.
#
# VERSION :0.2.2
# DOCS :http://jmespath.org/examples.html
# DEPENDS :pip3 install awscli
# LOCATION :/usr/local/bin/aws-route53-rrs.sh
# AWS CLI v1 installation
# python-add-opt-package.sh awscli aws
#
# AWS CLI v2 installation
# pip3 install --no-cache-dir --ignore-installed --no-warn-script-location --prefix /opt/awscliv2 \
# https://github.com/boto/botocore/archive/v2.zip https://github.com/aws/aws-cli/archive/v2.zip
#
# Configure
# aws configure
#
# List all zones
# aws-route53-rrs.sh . .
#
# List all rrs of a zone
# aws-route53-rrs.sh . ANY
#
# Add HOSTED_ZONE_ID=ZONE-ID to your ~/.profile
# aws-route53-rrs.sh . TXT
# aws-route53-rrs.sh non-existent-to-create.example.com. AAAA
# aws-route53-rrs.sh example.com. A
# aws-route53-rrs.sh example.com. IN TXT
#
# Delete a record by appending DELETE! in the Value field
HOSTED_ZONE="$HOSTED_ZONE_ID"
Route53_list_rrs()
{
aws route53 list-resource-record-sets --hosted-zone-id "$HOSTED_ZONE" "$@"
}
Route53_change_rrs()
{
local TEMP_JSON="$1"
aws route53 change-resource-record-sets --hosted-zone-id "$HOSTED_ZONE" \
--change-batch "file://${TEMP_JSON}"
}
Validate_request()
{
test -s "$TEMP_JSON"
python <<EOF
import sys, json
j = open('${TEMP_JSON}').read()
try:
json.loads(j)
except ValueError:
sys.exit(20)
EOF
}
Usage()
{
cat <<EOF
Usage: $0 name. TYPE
Update RRs by editing JSON data.
EOF
exit 0
}
set -e
# Credentials
if [ ! -r "${HOME}/.aws/credentials" ]; then
echo "Unconfigured ~/.aws/credentials" 1>&2
exit 125
fi
NAME="$1"
# Support bind format
if [ "$2" == IN ]; then
shift
fi
TYPE="$2"
# List all zones
if [ "$NAME" == . ] && [ "$TYPE" == . ]; then
aws route53 list-hosted-zones | jq -r '.HostedZones[] | .Name + " " + .Id'
exit 0
fi
# Get name. and TYPE
if [ "$#" != 2 ] || [ "${NAME:(-1)}" != . ] || [ -n "${TYPE//[A-Z]/}" ]; then
Usage
fi
# Check HOSTED_ZONE_ID
if [ -z "$HOSTED_ZONE" ]; then
echo "Unset HOSTED_ZONE_ID" 1>&2
exit 125
fi
# List names and values of RRs
if [ "$NAME" == . ]; then
if [ "$TYPE" == ANY ]; then
Route53_list_rrs
else
Route53_list_rrs --output text \
--query "ResourceRecordSets[?Type == '${TYPE}'].[Name, ResourceRecords[0].Value]"
fi
exit 0
fi
# Temporary file to edit JSON data
TEMP_JSON="$(mktemp)"
trap 'rm -f "$TEMP_JSON"' EXIT HUP INT QUIT PIPE TERM
# Get RRs
Route53_list_rrs \
--query "ResourceRecordSets[?Name == '${NAME}'] | [?Type == '${TYPE}'] | [0]" \
>"$TEMP_JSON"
MX_PRIO=""
# Operate based on RRs
if [ "$(cat "$TEMP_JSON")" == null ]; then
# New RRs
if [ "$TYPE" == MX ]; then
printf -v MX_PRIO '10 '
fi
printf '{\n "Name": "%s",\n "Type": "%s",\n "ResourceRecords": [\n { "Value": "%s" }\n ],\n "TTL": 86400\n}\n' \
"$NAME" "$TYPE" "$MX_PRIO" \
>"$TEMP_JSON"
editor "$TEMP_JSON"
Validate_request
# Build the request
# @FIXME The same file is input and output at the same time
printf '{ "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": %s } ] }' \
"$(cat "$TEMP_JSON")" \
>"$TEMP_JSON"
# Create RRs
RESPONSE="$(Route53_change_rrs "$TEMP_JSON")"
else
# Change RRs
editor "$TEMP_JSON"
Validate_request
if jq '.ResourceRecords[0].Value' <"$TEMP_JSON" | grep -q 'DELETE!'; then
# Build the request
printf '{ "Changes": [ { "Action": "DELETE", "ResourceRecordSet": %s } ] }' \
"$(sed -e '/"Value":/s#DELETE!##' "$TEMP_JSON")" \
>"$TEMP_JSON"
# Delete RRs
RESPONSE="$(Route53_change_rrs "$TEMP_JSON")"
else
# Build the request
printf '{ "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": %s } ] }' \
"$(cat "$TEMP_JSON")" \
>"$TEMP_JSON"
# Update RRs
RESPONSE="$(Route53_change_rrs "$TEMP_JSON")"
fi
fi
# Check response
grep -q '"ChangeInfo": {' <<<"$RESPONSE"
grep -q '"Status": "PENDING"' <<<"$RESPONSE"
echo "OK."