Skip to content

Commit 8d7ce03

Browse files
authored
chore: move code from internal repo (#11)
Moving code as-is from the current internal repo. The repo was updated few minutes ago, so it should be the latest code version. The code was not edited, but there was some re-formatting happening, probably due to a different prettier settings. I have copied prettier params from our package as well, but it does not seem working...
1 parent d694d8a commit 8d7ce03

File tree

268 files changed

+116726
-18
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

268 files changed

+116726
-18
lines changed

API.md

Lines changed: 41445 additions & 8 deletions
Large diffs are not rendered by default.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Ignoring some checks since the function is in pure JS
2+
3+
/* eslint-disable */
4+
const aws = require('aws-sdk');
5+
6+
const DOCS = `
7+
## Display a CloudWatch bitmap graph
8+
Displays CloudWatch metrics as a bitmap, for faster display of metrics.
9+
10+
### Widget parameters
11+
Param | Description
12+
---|---
13+
**graph** | The graph definition. Use the parameters from the **Source** tab in CloudWatch Console's **Metrics** page.
14+
**useMonitorPortal** (default = true) | Flag indicating whether we want to use MonitorPortal to render the graph. False will switch to CloudWatch API.
15+
16+
### Example parameters
17+
\`\`\` yaml
18+
useMonitorPortal: boolean
19+
graph:
20+
view: timeSeries
21+
metrics:
22+
- [ AWS/Lambda, Invocations ]
23+
region: ${process.env.AWS_REGION}
24+
\`\`\`
25+
`;
26+
27+
exports.handler = async (event: any) => {
28+
async function renderUsingCloudWatch(graph: any, width: number, height: number) {
29+
const params = {MetricWidget: JSON.stringify(graph)};
30+
const region = graph.region;
31+
const customBackoff = (retryCount: number) => {
32+
// Keep retrying with a random delay, long enough to overcome throttling from CW
33+
const delay = 300 + Math.floor(Math.random() * 500);
34+
console.log(`retry number ${retryCount} with a delay of ${delay} ms`);
35+
return delay;
36+
}
37+
const clientOptions = {
38+
region,
39+
// Keep retrying until the Lambda times out
40+
maxRetries: 99,
41+
retryDelayOptions: {customBackoff},
42+
httpOptions: {
43+
connectTimeout: 3 * 1000,
44+
timeout: 3 * 1000,
45+
},
46+
};
47+
const cloudwatch = new aws.CloudWatch(clientOptions);
48+
const image = await cloudwatch.getMetricWidgetImage(params).promise();
49+
const base64Image = Buffer.from(image.MetricWidgetImage).toString('base64');
50+
return `<img width="${width}" height="${height}" loading="lazy" src="data:image/png;base64,${base64Image}"/>`;
51+
}
52+
53+
if (event.describe) {
54+
return DOCS;
55+
}
56+
57+
const widgetContext = event.widgetContext;
58+
const timeRange = widgetContext.timeRange.zoom || widgetContext.timeRange;
59+
const start = new Date(timeRange.start).toISOString();
60+
const end = new Date(timeRange.end).toISOString();
61+
const width = widgetContext.width;
62+
const height = widgetContext.height;
63+
const graph = Object.assign(event.graph, {start, end, width, height});
64+
65+
return renderUsingCloudWatch(graph, width, height);
66+
};
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import aws = require("aws-sdk");
2+
3+
const region = process.env.AWS_REGION;
4+
const millisPerDay = 1000 * 60 * 60 * 24;
5+
6+
const clientOptions = {
7+
region,
8+
maxRetries: 5,
9+
httpOptions: {
10+
connectTimeout: 3 * 1000,
11+
timeout: 3 * 1000,
12+
},
13+
};
14+
15+
const cloudwatch = new aws.CloudWatch(clientOptions);
16+
const sm = new aws.SecretsManager(clientOptions);
17+
18+
function daysSince(date: any, now = Date.now()) {
19+
const millis = now - date.getTime();
20+
const days = millis / millisPerDay;
21+
return Math.floor(days);
22+
}
23+
24+
exports.handler = async (event: any, context: any) => {
25+
console.debug("event:", JSON.stringify(event));
26+
console.debug("context:", JSON.stringify(context));
27+
28+
console.info(`retrieving secret: ${event.secretId}`);
29+
const secret = await sm
30+
.describeSecret({
31+
SecretId: event.secretId,
32+
})
33+
.promise();
34+
35+
console.debug("found secret: ", JSON.stringify(secret));
36+
if (!secret.Name || !secret.CreatedDate) {
37+
throw new Error("invalid secret response");
38+
}
39+
40+
// use retrieved secret name in case secretId was an arn
41+
const secretName = secret.Name;
42+
const lastChangedDate = secret.LastChangedDate ?? secret.CreatedDate;
43+
const lastRotatedDate = secret.LastRotatedDate ?? secret.CreatedDate;
44+
const now = Date.now();
45+
46+
const metricData = [
47+
{
48+
MetricName: "DaysSinceLastChange",
49+
Dimensions: [
50+
{
51+
Name: "SecretName",
52+
Value: secretName,
53+
},
54+
],
55+
Unit: "Count",
56+
Value: daysSince(lastChangedDate, now),
57+
},
58+
{
59+
MetricName: "DaysSinceLastRotation",
60+
Dimensions: [
61+
{
62+
Name: "SecretName",
63+
Value: secretName,
64+
},
65+
],
66+
Unit: "Count",
67+
Value: daysSince(lastRotatedDate, now),
68+
},
69+
];
70+
71+
const params = {
72+
Namespace: "SecretsManager",
73+
MetricData: metricData,
74+
};
75+
76+
console.debug("putMetricData params: ", JSON.stringify(params));
77+
78+
console.info(`publishing metrics for secret: ${event.secretId}`);
79+
await cloudwatch.putMetricData(params).promise();
80+
81+
return Promise.resolve();
82+
};

0 commit comments

Comments
 (0)