-
Notifications
You must be signed in to change notification settings - Fork 9
/
change.py
131 lines (116 loc) · 3.88 KB
/
change.py
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
import os
import sys
import json
import boto3
from distutils import util
class AWSRoute53RecordSet:
"""
Primary class for the handling of AWS Route 53 Record Sets.
"""
def __init__(self):
"""
The default constructor.
"""
self.client = None
self.waiter = None
self.rr_skeleton = dict()
def _get_env(self, variable, exit=True):
"""
Try to fetch a variable from the environment.
Per default the method will raise an exception if the variable isn't present.
This behaviour can be switched off via the exit flag.
"""
value = os.environ.get(variable)
if not value and exit:
raise NameError("Cannot find environment variable: " + str(variable))
return value
def _connect(self):
"""
Creates a new client object which wraps the connection to AWS.
"""
if not self.client:
self.client = boto3.client(
"route53",
aws_access_key_id=self._get_env("INPUT_AWS_ACCESS_KEY_ID"),
aws_secret_access_key=self._get_env("INPUT_AWS_SECRET_ACCESS_KEY")
)
self.waiter = self.client.get_waiter("resource_record_sets_changed")
def _set_comment(self):
"""
Appends an additional comment field to the record set.
"""
comment = self._get_env("INPUT_AWS_ROUTE53_RR_COMMENT", False)
if comment:
self.rr_skeleton["Comment"] = comment
def _set_base_changes(self):
"""
Creates the base skeleton required for creating a new record set.
"""
self.rr_skeleton["Changes"] = [{
"Action": self._get_env("INPUT_AWS_ROUTE53_RR_ACTION"),
"ResourceRecordSet": {
"Name": self._get_env("INPUT_AWS_ROUTE53_RR_NAME"),
"Type": self._get_env("INPUT_AWS_ROUTE53_RR_TYPE"),
"TTL": int(self._get_env("INPUT_AWS_ROUTE53_RR_TTL")),
"ResourceRecords": [{
"Value": self._get_env("INPUT_AWS_ROUTE53_RR_VALUE")
}]
}
}]
def _build_record_set(self):
"""
Builds up the skeleton used for modulating the record set.
"""
self._set_comment()
self._set_base_changes()
return self.rr_skeleton
def _change_record_set(self, record_set):
"""
Requests the required change at AWS.
"""
return self.client.change_resource_record_sets(
HostedZoneId=self._get_env("INPUT_AWS_ROUTE53_HOSTED_ZONE_ID"),
ChangeBatch=record_set
)
def _wait(self, request_id):
"""
Waits until the requested operations is finished.
"""
wait = self._get_env("INPUT_AWS_ROUTE53_WAIT", False)
if wait and util.strtobool(wait):
self.waiter.wait(
Id=request_id,
WaiterConfig={
"Delay": 10,
"MaxAttempts": 50
}
)
def _obtain_request_id(self, result):
"""
Grabs and returns the id of the given request.
"""
return result["ChangeInfo"]["Id"]
def _obtain_marshalled_result(self, result):
"""
Grabs and returns the HTTP response of the given request.
"""
return json.dumps(result["ResponseMetadata"], indent=4)
def change(self):
"""
Entrypoint for the management of a record set.
"""
self._connect()
record_set = self._build_record_set()
result = self._change_record_set(record_set)
self._wait(
self._obtain_request_id(result)
)
sys.stdout.write(
self._obtain_marshalled_result(result) + "\n"
)
try:
o = AWSRoute53RecordSet()
o.change()
except Exception as e:
sys.stderr.write(str(e) + "\n")
sys.exit(1)