-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
110 lines (94 loc) · 3.93 KB
/
index.js
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
const {
Route53
} = require("@aws-sdk/client-route-53");
const route53 = new Route53({ region: 'eu-east-1' });
const core = require('@actions/core');
async function upsertRecords(domainName, geoCodes, loadBalancerDns, loadBalancerHostedZoneId, route53HostedZoneId) {
console.log(`Upserting records for ${domainName}`);
const records = await getRecordsByDomainName(domainName, route53HostedZoneId);
console.log(`Fetched ${records.length} records for ${domainName}`);
console.log(records);
const recordsToDelete = records.filter(record => {
const isDefaultRecord = record.Type === 'A' && record.Name === domainName && record.GeoLocation.CountryCode == '*';
const isGeoRecord = record.Type === 'A' && record.AliasTarget && record.AliasTarget.DNSName === loadBalancerDns && !geoCodes.includes(record.GeoLocation.ContinentCode || record.GeoLocation.CountryCode);
return isGeoRecord && !isDefaultRecord;
});
console.log(recordsToDelete);
console.log(`Deleting ${recordsToDelete.length} records for ${domainName}`);
// This code will first check if the record is the default record (the one with the domain name) and ignore it. For other records, it will check if they are geolocation records and include them only if they are not the default record.
await Promise.all(recordsToDelete.map(record => deleteRecord(route53HostedZoneId, record)));
console.log(`Upserting ${geoCodes.length} records for ${domainName}`);
geoCodes.map(async code => {
const GeoLocation = code.length === 2 ? { CountryCode: code } : { ContinentCode: code };
const upsertParams = {
HostedZoneId: route53HostedZoneId,
ChangeBatch: {
Changes: [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": domainName,
"Type": "A",
GeoLocation,
"SetIdentifier": code,
"AliasTarget": {
"DNSName": loadBalancerDns,
"EvaluateTargetHealth": false,
"HostedZoneId": loadBalancerHostedZoneId
}
}
}
]
},
};
await route53.changeResourceRecordSets(upsertParams);
});
}
async function deleteRecord(route53HostedZoneId, record) {
const deleteParams = {
HostedZoneId: route53HostedZoneId,
ChangeBatch: {
Changes: [
{
Action: 'DELETE',
ResourceRecordSet: record,
},
],
},
};
await route53.changeResourceRecordSets(deleteParams);
}
async function getRecordsByDomainName(domainName, route53HostedZoneId) {
const listParams = {
HostedZoneId: route53HostedZoneId,
StartRecordName: domainName,
StartRecordType: 'A',
};
let records = [];
do {
const res = await new Promise((resolve, reject) => {
route53.listResourceRecordSets(listParams, (err, data) => {
if (err) reject(err);
else resolve(data);
});
});
records = records.concat(res.ResourceRecordSets);
listParams.NextRecordName = res.NextRecordName;
listParams.NextRecordType = res.NextRecordType;
} while (listParams.NextRecordName && listParams.NextRecordType);
// filter records to only include the ones with the specific domain name
records = records.filter(record => record.Name === domainName);
return records;
}
async function run() {
const route53HostedZoneId = core.getInput("route53-hosted-zone-id", { required: true });
const loadBalancerHostedZoneId = core.getInput("load-balancer-hosted-zone-id", { required: true });
const domainName = core.getInput("domain-name", { required: true }).toLowerCase();
const geoCodes = core.getInput("geo-codes", { required: true }).split(",").map((code) => code.trim());
const loadBalancerDns = core.getInput("load-balancer-dns", { required: true }).toLowerCase();
await upsertRecords(domainName, geoCodes, loadBalancerDns, loadBalancerHostedZoneId, route53HostedZoneId);
}
run().catch(error => {
console.error(error);
process.exit(1);
});