Skip to content

Commit f58d688

Browse files
committed
Added check to events-to-s3 for label canary
Signed-off-by: Brandon Shien <bshien@amazon.com>
1 parent 3b1ecd9 commit f58d688

File tree

5 files changed

+179
-3
lines changed

5 files changed

+179
-3
lines changed

configs/operations/github-events-to-s3.yml

+4
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,9 @@ events:
55
- all
66

77
tasks:
8+
- name: Github Label Canary Monitor
9+
call: github-label-canary-monitor@default
10+
args:
11+
metricName: AutomationApp_EventDataLake
812
- name: Github Events To S3 Operation
913
call: github-events-to-s3@default

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "opensearch-automation-app",
3-
"version": "0.3.5",
3+
"version": "0.3.6",
44
"description": "An Automation App that handles all your GitHub Repository Activities",
55
"author": "Peter Zhu",
66
"homepage": "https://github.com/opensearch-project/automation-app",
+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* The OpenSearch Contributors require contributions made to
6+
* this file be licensed under the Apache-2.0 license or a
7+
* compatible open source license.
8+
*/
9+
10+
// Name : githubLabelCanaryMonitor
11+
// Description : Handle canary event by sending CloudWatch Metrics for monitoring purposes
12+
// Arguments :
13+
// - metricName: (string) The name of the CloudWatch Metric you want to send data to.
14+
15+
import { Probot } from 'probot';
16+
import { CloudWatchClient, PutMetricDataCommand } from '@aws-sdk/client-cloudwatch';
17+
18+
export default async function githubLabelCanaryMonitor(app: Probot, context: any, metricName: string): Promise<void> {
19+
// Removed validateResourceConfig to let this function listen on all repos, and filter for only the repos that are public.
20+
// This is done so when a new repo is made public, this app can automatically start processing its events.
21+
//
22+
// This is only for the s3 data lake specific case, everything else should still specify repos required to be listened in resource config.
23+
//
24+
// if (!(await validateResourceConfig(app, context, resource))) return;
25+
//
26+
const repoName = context.payload.repository?.name;
27+
if (context.payload.repository?.private === false) {
28+
// Handle canary event for monitoring purposes
29+
if (repoName === 'opensearch-metrics' && context.name === 'label' && context.payload.label?.name === 's3-data-lake-app-canary-label') {
30+
// Ignore if label was created
31+
if (context.payload.action === 'deleted') {
32+
try {
33+
const cloudWatchClient = new CloudWatchClient({ region: String(process.env.REGION) });
34+
const putMetricDataCommand = new PutMetricDataCommand({
35+
Namespace: 'GitHubLabelCanary',
36+
MetricData: [
37+
{
38+
MetricName: metricName,
39+
Value: 1,
40+
Unit: 'Count',
41+
},
42+
],
43+
});
44+
await cloudWatchClient.send(putMetricDataCommand);
45+
app.log.info('CloudWatch metric for monitoring published.');
46+
} catch (error) {
47+
app.log.error(`Error Publishing CloudWatch metric for monitoring : ${error}`);
48+
}
49+
}
50+
return; // In the future, add `exit` right here to prevent subsequent tasks from running
51+
}
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* The OpenSearch Contributors require contributions made to
6+
* this file be licensed under the Apache-2.0 license or a
7+
* compatible open source license.
8+
*/
9+
10+
import { Logger, Probot } from 'probot';
11+
import githubLabelCanaryMonitor from '../../src/call/github-label-canary-monitor';
12+
import { CloudWatchClient, PutMetricDataCommand } from '@aws-sdk/client-cloudwatch';
13+
14+
jest.mock('@aws-sdk/client-cloudwatch');
15+
16+
describe('githubEventsToS3', () => {
17+
let app: Probot;
18+
let context: any;
19+
let mockCloudWatchClient: any;
20+
21+
beforeEach(() => {
22+
app = new Probot({ appId: 1, secret: 'test', privateKey: 'test' });
23+
app.log = {
24+
info: jest.fn(),
25+
error: jest.fn(),
26+
} as unknown as Logger;
27+
28+
context = {
29+
name: 'name',
30+
id: 'id',
31+
payload: {
32+
repository: {
33+
name: 'repo',
34+
owner: { login: 'org' },
35+
private: false,
36+
},
37+
},
38+
};
39+
40+
mockCloudWatchClient = {
41+
send: jest.fn(),
42+
};
43+
(CloudWatchClient as jest.Mock).mockImplementation(() => mockCloudWatchClient);
44+
});
45+
46+
afterEach(() => {
47+
jest.clearAllMocks();
48+
});
49+
50+
it('should publish CloudWatch metric if event is label canary', async () => {
51+
context = {
52+
name: 'label',
53+
id: 'id',
54+
payload: {
55+
action: 'deleted',
56+
label: {
57+
name: 's3-data-lake-app-canary-label',
58+
},
59+
repository: {
60+
name: 'opensearch-metrics',
61+
private: false,
62+
},
63+
},
64+
};
65+
66+
mockCloudWatchClient.send.mockResolvedValue({});
67+
68+
await githubLabelCanaryMonitor(app, context, 'testMetric');
69+
70+
expect(mockCloudWatchClient.send).toHaveBeenCalledWith(expect.any(PutMetricDataCommand));
71+
expect(app.log.info).toHaveBeenCalledWith('CloudWatch metric for monitoring published.');
72+
});
73+
74+
it('should not publish CloudWatch metric if event is not label canary', async () => {
75+
context = {
76+
name: 'label',
77+
id: 'id',
78+
payload: {
79+
label: {
80+
name: 'normal-label',
81+
},
82+
repository: {
83+
name: 'opensearch-metrics',
84+
private: false,
85+
},
86+
},
87+
};
88+
89+
mockCloudWatchClient.send.mockResolvedValue({});
90+
91+
await githubLabelCanaryMonitor(app, context, 'testMetric');
92+
93+
expect(mockCloudWatchClient.send).not.toHaveBeenCalledWith(expect.any(PutMetricDataCommand));
94+
expect(app.log.info).not.toHaveBeenCalledWith('CloudWatch metric for monitoring published.');
95+
});
96+
97+
it('should log an error if CloudWatch metric publishing fails', async () => {
98+
context = {
99+
name: 'label',
100+
id: 'id',
101+
payload: {
102+
action: 'deleted',
103+
label: {
104+
name: 's3-data-lake-app-canary-label',
105+
},
106+
repository: {
107+
name: 'opensearch-metrics',
108+
private: false,
109+
},
110+
},
111+
};
112+
113+
mockCloudWatchClient.send.mockRejectedValue(new Error('CloudWatch error'));
114+
115+
await githubLabelCanaryMonitor(app, context, 'testMetric');
116+
117+
expect(app.log.error).toHaveBeenCalledWith('Error Publishing CloudWatch metric for monitoring : Error: CloudWatch error');
118+
});
119+
});

0 commit comments

Comments
 (0)