-
Notifications
You must be signed in to change notification settings - Fork 0
131 lines (117 loc) · 4.44 KB
/
tls-certificicate-check.yaml
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
# This file serves as the template to generate GitHub Workflow.
name: "Check TLS Certificate"
on:
push:
branches:
- main
- master
schedule:
# Run every day at 0:00am
- cron: '0 0 * * *'
workflow_dispatch:
jobs:
check-certificate:
runs-on: ubuntu-latest
steps:
# checkout is required here because:
# - Needs the script to load.
# - Make commits
- uses: actions/checkout@v3
- name: Check the TLS certificate
id: tls_certificate_check
uses: actions/github-script@v6
env:
FORCE_NOTIFICATION: "${{ vars.FORCE_NOTIFICATION }}"
with:
script: |-
const cert = require("./src/fetch-cert.js").use({exec});;
const { daysFromNow, range } = require("./src/tools.js");
const alertingRangesOfDaysLeft = [range(0, 5), range(9, 10), range(19, 20), range(29, 30)];
const forceNotification = process.env.FORCE_NOTIFICATION === "true";
const { sites } = require("./sites.json");
const checkSite = async (site) => {
const { domain, port } = site;
const notAfter = await cert.fetchNotAfter(domain, port);
console.log(`[info] - [${domain}:${port}]: Field notAfter read from TLS certificate: ${notAfter}`);
const daysLeft = daysFromNow(notAfter);
console.log(`[info] - [${domain}:${port}]: Day left: ${daysLeft}`);
const shouldAlert = forceNotification || alertingRangesOfDaysLeft.some(r => r.contains(daysLeft));
return ({
domain,
port,
notAfter,
daysLeft,
shouldAlert
});
};
const result = await Promise.all(sites.map(checkSite));
console.log("[debug] - " + JSON.stringify(result));
return result;
- name: Track execution as a Git commit
id: add-git-commit
run: |-
touch executions.jsonl
cat <<'__PAYLOAD__' >>executions.jsonl
${{ steps.tls_certificate_check.outputs.result }}
__PAYLOAD__
readonly now="$(date -u "+%Y-%m-%dT%H:%M:%S%Z")"
git config user.name "tls-watchbot"
git config user.email "[email protected]"
git add executions.jsonl
git commit -m "Run at $now"
git push
- name: Slack notifications
id: notify_slack
uses: actions/github-script@v6
env:
CHECKED_SITES: "${{ steps.tls_certificate_check.outputs.result }}"
SLACK_WEBHOOK_URL: "${{ secrets.SLACK_WEBHOOK_URL }}"
with:
script: |-
const checkedSites = JSON.parse(process.env.CHECKED_SITES);
const slackWebhookUrl = process.env.SLACK_WEBHOOK_URL;
const toSlackPayload = (site) => {
const { domain, notAfter, daysLeft } = site;
return ({
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": `*:warning: TLS Certificate for \`${domain}\` is about to expire.*`
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": `*Site:* \`${domain}\`\n*Expiration Date:* ${notAfter}\n*Days Left*: ${daysLeft}`
}
}
]
});
};
const sendSlack = (slackWebhookUrl) => {
return (async (payload) => {
const response = await fetch(slackWebhookUrl,
{
method: 'post',
body: JSON.stringify(payload),
headers: {
"content-type": "application/json"
}
}
);
if (response.ok) {
return response;
} else {
const body = await response.text();
throw `Failed: ${response.status} - ${body}`;
}
});
};
await Promise.all(checkedSites
.filter(site => site.shouldAlert)
.map(toSlackPayload)
.map(sendSlack(slackWebhookUrl))
);