Skip to content

Commit d0d5eae

Browse files
committed
Integrate github app workflow with lambda.
A new github app "iocost-issue-creater" is created and installed with iocost-benchmark organization which has a permission to file issue on iocost-benachmarks repository. When a user uploads the benchmark result with lambda url, lambda saves the benchmark result in aws s3 bucket and create a issue in iocost-benchmarks projects. Signed-off-by: Santosh Mahto <santosh.mahto@collabora.com>
1 parent 022e11a commit d0d5eae

File tree

4 files changed

+73
-3
lines changed

4 files changed

+73
-3
lines changed

Cargo.lock

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

resctl-bench/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ aws-sdk-s3 = { version = "0.28.0", optional = true, features = ["rustls", "rt-to
2424
aws-sdk-ssm = { version = "0.28.0", optional = true, features = ["rustls", "rt-tokio"], default-features = false }
2525
aws_lambda_events = "0.10.0"
2626

27+
jsonwebtoken = "8.3.0"
2728
lambda_runtime = { version = "0.8.1", optional = true }
2829
md5 = { version = "0.7", optional = true }
2930
octocrab = { version = "0.28.0", optional = true, features = ["rustls"], default-features = false }

resctl-bench/doc/lambda.md

+26
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,32 @@ We still need to configure our S3 bucket to allow public read only access, so th
8787
}
8888
```
8989

90+
91+
We also store the credential parameters required to file a github issue in AWS Systems Manager -> parameter store.
92+
We use github app `iocost-issue-creater` to file a github issue, thus it's credentials information `App Id` and
93+
`Private Key` are stored in parameter store.
94+
```
95+
{
96+
/iocost-bot/appid : "xxxx"
97+
/iocost-bot/privatekey : "PEM format key"
98+
}
99+
```
100+
101+
AWS lambda flow
102+
===============
103+
1. User generates the benchmark result on their device.
104+
`$ resctl-bench -r "$RESULT_JSON" --logfile=$LOG_FILE run iocost-tun`
105+
2. User uploads the result to aws lambda function url as:
106+
`resctl-bench -r <RESULT_JSON> upload --upload-url <AWS lambda function URL>`
107+
e.g
108+
`$resctl-bench --result resctl-bench-result_2022_07_01-00_26_40.json.gz upload --upload-url https://ygvr6jnjckwamfao5xztg6idiu0ukjeb.lambda-url.eu-west-1.on.aws`
109+
110+
3. Lamda is tiggered automatically in AWS.
111+
- It saves the benchmark result to S3 bucket.
112+
- Then create a issue in iocost-benchmark/iocost-benchmarks project using `iocost-issue-creater` github app.
113+
- Issue contain a link to benchmark result stored in s3 bucket.
114+
115+
90116
Deploying
91117
=========
92118

resctl-bench/src/lambda.rs

+45-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ use aws_lambda_events::event::lambda_function_urls::LambdaFunctionUrlRequest;
55
use aws_sdk_s3::error::SdkError;
66
use lambda_runtime::{service_fn, LambdaEvent};
77
use log::error;
8+
use octocrab::models::InstallationToken;
9+
use octocrab::params::apps::CreateInstallationAccessToken;
10+
use octocrab::Octocrab;
811
use std::io::{Cursor, Read, Write};
912
use std::os::unix::process::CommandExt;
1013
use std::path::Path;
@@ -145,10 +148,10 @@ impl LambdaHelper {
145148
}
146149

147150
pub async fn create_github_issue(&self, title: &str, body: &str) -> Result<String> {
148-
let token = self
151+
let app_id = self
149152
.ssm
150153
.get_parameter()
151-
.set_name(Some("/iocost-bot/token".to_string()))
154+
.set_name(Some("/iocost-bot/appid".to_string()))
152155
.send()
153156
.await
154157
.expect("Failed to query parameter")
@@ -157,8 +160,47 @@ impl LambdaHelper {
157160
.value
158161
.expect("Parameter value is None");
159162

163+
let pem = self
164+
.ssm
165+
.get_parameter()
166+
.set_name(Some("/iocost-bot/privatekey".to_string()))
167+
.send()
168+
.await
169+
.expect("Failed to query parameter")
170+
.parameter
171+
.expect("Could not find parameter")
172+
.value
173+
.expect("Parameter value is None");
174+
175+
let token = octocrab::auth::create_jwt(
176+
app_id.parse::<u64>().unwrap().into(),
177+
&jsonwebtoken::EncodingKey::from_rsa_pem(pem.as_bytes()).unwrap(),
178+
)
179+
.unwrap();
180+
181+
let octocrab = Octocrab::builder().personal_token(token).build()?;
182+
183+
let installations = octocrab
184+
.apps()
185+
.installations()
186+
.send()
187+
.await
188+
.unwrap()
189+
.take_items();
190+
191+
let mut create_access_token = CreateInstallationAccessToken::default();
192+
create_access_token.repositories = vec!["iocost-benchmarks".to_string()];
193+
194+
let access: InstallationToken = octocrab
195+
.post(
196+
installations[0].access_tokens_url.as_ref().unwrap(),
197+
Some(&create_access_token),
198+
)
199+
.await
200+
.unwrap();
201+
160202
let issue = octocrab::OctocrabBuilder::new()
161-
.personal_token(token)
203+
.personal_token(access.token)
162204
.build()?
163205
.issues("iocost-benchmark", "iocost-benchmarks")
164206
.create(title)

0 commit comments

Comments
 (0)