@cloudsnorkel/cdk-github-runners 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +272 -25
- package/API.md +215 -0
- package/assets/lambdas/setup.lambda/index.js +10 -6
- package/assets/lambdas/status.lambda/index.js +22 -10
- package/assets/lambdas/webhook-handler.lambda/index.js +15 -7
- package/lib/access.d.ts +65 -0
- package/lib/access.js +160 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +2 -1
- package/lib/lambdas/setup.lambda.js +11 -7
- package/lib/lambdas/status.lambda.js +24 -11
- package/lib/lambdas/webhook-handler.lambda.js +19 -10
- package/lib/providers/codebuild.js +2 -2
- package/lib/providers/common.js +3 -3
- package/lib/providers/ec2.js +2 -2
- package/lib/providers/fargate.js +2 -2
- package/lib/providers/image-builders/api.js +1 -1
- package/lib/providers/image-builders/aws-image-builder/builder.js +1 -1
- package/lib/providers/image-builders/aws-image-builder/deprecated/ami.js +1 -1
- package/lib/providers/image-builders/aws-image-builder/deprecated/container.js +1 -1
- package/lib/providers/image-builders/aws-image-builder/deprecated/linux-components.js +1 -1
- package/lib/providers/image-builders/aws-image-builder/deprecated/windows-components.js +1 -1
- package/lib/providers/image-builders/codebuild-deprecated.js +1 -1
- package/lib/providers/image-builders/components.js +1 -1
- package/lib/providers/image-builders/static.js +1 -1
- package/lib/providers/lambda.js +2 -2
- package/lib/runner.d.ts +23 -0
- package/lib/runner.js +13 -4
- package/lib/secrets.js +1 -1
- package/lib/webhook.d.ts +5 -0
- package/lib/webhook.js +5 -4
- package/package.json +1 -1
package/API.md
CHANGED
|
@@ -4550,6 +4550,68 @@ VPC where builder instances will be launched.
|
|
|
4550
4550
|
|
|
4551
4551
|
---
|
|
4552
4552
|
|
|
4553
|
+
### ApiGatewayAccessProps <a name="ApiGatewayAccessProps" id="@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps"></a>
|
|
4554
|
+
|
|
4555
|
+
#### Initializer <a name="Initializer" id="@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps.Initializer"></a>
|
|
4556
|
+
|
|
4557
|
+
```typescript
|
|
4558
|
+
import { ApiGatewayAccessProps } from '@cloudsnorkel/cdk-github-runners'
|
|
4559
|
+
|
|
4560
|
+
const apiGatewayAccessProps: ApiGatewayAccessProps = { ... }
|
|
4561
|
+
```
|
|
4562
|
+
|
|
4563
|
+
#### Properties <a name="Properties" id="Properties"></a>
|
|
4564
|
+
|
|
4565
|
+
| **Name** | **Type** | **Description** |
|
|
4566
|
+
| --- | --- | --- |
|
|
4567
|
+
| <code><a href="#@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps.property.allowedIps">allowedIps</a></code> | <code>string[]</code> | List of IP addresses in CIDR notation that are allowed to access the API Gateway. |
|
|
4568
|
+
| <code><a href="#@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps.property.allowedSecurityGroups">allowedSecurityGroups</a></code> | <code>aws-cdk-lib.aws_ec2.ISecurityGroup[]</code> | List of security groups that are allowed to access the API Gateway. |
|
|
4569
|
+
| <code><a href="#@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps.property.allowedVpc">allowedVpc</a></code> | <code>aws-cdk-lib.aws_ec2.IVpc</code> | Creates a private API Gateway and allows access from the specified VPC. |
|
|
4570
|
+
|
|
4571
|
+
---
|
|
4572
|
+
|
|
4573
|
+
##### `allowedIps`<sup>Optional</sup> <a name="allowedIps" id="@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps.property.allowedIps"></a>
|
|
4574
|
+
|
|
4575
|
+
```typescript
|
|
4576
|
+
public readonly allowedIps: string[];
|
|
4577
|
+
```
|
|
4578
|
+
|
|
4579
|
+
- *Type:* string[]
|
|
4580
|
+
|
|
4581
|
+
List of IP addresses in CIDR notation that are allowed to access the API Gateway.
|
|
4582
|
+
|
|
4583
|
+
If not specified on public API Gateway, all IP addresses are allowed.
|
|
4584
|
+
|
|
4585
|
+
If not specified on private API Gateway, no IP addresses are allowed (but specified security groups are).
|
|
4586
|
+
|
|
4587
|
+
---
|
|
4588
|
+
|
|
4589
|
+
##### `allowedSecurityGroups`<sup>Optional</sup> <a name="allowedSecurityGroups" id="@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps.property.allowedSecurityGroups"></a>
|
|
4590
|
+
|
|
4591
|
+
```typescript
|
|
4592
|
+
public readonly allowedSecurityGroups: ISecurityGroup[];
|
|
4593
|
+
```
|
|
4594
|
+
|
|
4595
|
+
- *Type:* aws-cdk-lib.aws_ec2.ISecurityGroup[]
|
|
4596
|
+
|
|
4597
|
+
List of security groups that are allowed to access the API Gateway.
|
|
4598
|
+
|
|
4599
|
+
Only works for private API Gateways with {@link allowedVpc}.
|
|
4600
|
+
|
|
4601
|
+
---
|
|
4602
|
+
|
|
4603
|
+
##### `allowedVpc`<sup>Optional</sup> <a name="allowedVpc" id="@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps.property.allowedVpc"></a>
|
|
4604
|
+
|
|
4605
|
+
```typescript
|
|
4606
|
+
public readonly allowedVpc: IVpc;
|
|
4607
|
+
```
|
|
4608
|
+
|
|
4609
|
+
- *Type:* aws-cdk-lib.aws_ec2.IVpc
|
|
4610
|
+
|
|
4611
|
+
Creates a private API Gateway and allows access from the specified VPC.
|
|
4612
|
+
|
|
4613
|
+
---
|
|
4614
|
+
|
|
4553
4615
|
### AwsImageBuilderRunnerImageBuilderProps <a name="AwsImageBuilderRunnerImageBuilderProps" id="@cloudsnorkel/cdk-github-runners.AwsImageBuilderRunnerImageBuilderProps"></a>
|
|
4554
4616
|
|
|
4555
4617
|
#### Initializer <a name="Initializer" id="@cloudsnorkel/cdk-github-runners.AwsImageBuilderRunnerImageBuilderProps.Initializer"></a>
|
|
@@ -5819,8 +5881,11 @@ const gitHubRunnersProps: GitHubRunnersProps = { ... }
|
|
|
5819
5881
|
| <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.logOptions">logOptions</a></code> | <code><a href="#@cloudsnorkel/cdk-github-runners.LogOptions">LogOptions</a></code> | Logging options for the state machine that manages the runners. |
|
|
5820
5882
|
| <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.providers">providers</a></code> | <code><a href="#@cloudsnorkel/cdk-github-runners.IRunnerProvider">IRunnerProvider</a>[]</code> | List of runner providers to use. |
|
|
5821
5883
|
| <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.securityGroup">securityGroup</a></code> | <code>aws-cdk-lib.aws_ec2.ISecurityGroup</code> | Security group attached to all management functions. |
|
|
5884
|
+
| <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.setupAccess">setupAccess</a></code> | <code><a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess">LambdaAccess</a></code> | Access configuration for the setup function. |
|
|
5885
|
+
| <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.statusAccess">statusAccess</a></code> | <code><a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess">LambdaAccess</a></code> | Access configuration for the status function. |
|
|
5822
5886
|
| <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.vpc">vpc</a></code> | <code>aws-cdk-lib.aws_ec2.IVpc</code> | VPC used for all management functions. |
|
|
5823
5887
|
| <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.vpcSubnets">vpcSubnets</a></code> | <code>aws-cdk-lib.aws_ec2.SubnetSelection</code> | VPC subnets used for all management functions. |
|
|
5888
|
+
| <code><a href="#@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.webhookAccess">webhookAccess</a></code> | <code><a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess">LambdaAccess</a></code> | Access configuration for the webhook function. |
|
|
5824
5889
|
|
|
5825
5890
|
---
|
|
5826
5891
|
|
|
@@ -5928,6 +5993,36 @@ Use this with to provide access to GitHub Enterprise Server hosted inside a VPC.
|
|
|
5928
5993
|
|
|
5929
5994
|
---
|
|
5930
5995
|
|
|
5996
|
+
##### `setupAccess`<sup>Optional</sup> <a name="setupAccess" id="@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.setupAccess"></a>
|
|
5997
|
+
|
|
5998
|
+
```typescript
|
|
5999
|
+
public readonly setupAccess: LambdaAccess;
|
|
6000
|
+
```
|
|
6001
|
+
|
|
6002
|
+
- *Type:* <a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess">LambdaAccess</a>
|
|
6003
|
+
- *Default:* LambdaAccess.lambdaUrl()
|
|
6004
|
+
|
|
6005
|
+
Access configuration for the setup function.
|
|
6006
|
+
|
|
6007
|
+
Once you finish the setup process, you can set this to `LambdaAccess.noAccess()` to remove access to the setup function. You can also use `LambdaAccess.apiGateway({ allowedIps: ['my-ip/0']})` to limit access to your IP only.
|
|
6008
|
+
|
|
6009
|
+
---
|
|
6010
|
+
|
|
6011
|
+
##### `statusAccess`<sup>Optional</sup> <a name="statusAccess" id="@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.statusAccess"></a>
|
|
6012
|
+
|
|
6013
|
+
```typescript
|
|
6014
|
+
public readonly statusAccess: LambdaAccess;
|
|
6015
|
+
```
|
|
6016
|
+
|
|
6017
|
+
- *Type:* <a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess">LambdaAccess</a>
|
|
6018
|
+
- *Default:* LambdaAccess.noAccess()
|
|
6019
|
+
|
|
6020
|
+
Access configuration for the status function.
|
|
6021
|
+
|
|
6022
|
+
This function returns a lot of sensitive information about the runner, so you should only allow access to it from trusted IPs, if at all.
|
|
6023
|
+
|
|
6024
|
+
---
|
|
6025
|
+
|
|
5931
6026
|
##### `vpc`<sup>Optional</sup> <a name="vpc" id="@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.vpc"></a>
|
|
5932
6027
|
|
|
5933
6028
|
```typescript
|
|
@@ -5956,6 +6051,25 @@ Use this with GitHub Enterprise Server hosted that's inaccessible from outside t
|
|
|
5956
6051
|
|
|
5957
6052
|
---
|
|
5958
6053
|
|
|
6054
|
+
##### `webhookAccess`<sup>Optional</sup> <a name="webhookAccess" id="@cloudsnorkel/cdk-github-runners.GitHubRunnersProps.property.webhookAccess"></a>
|
|
6055
|
+
|
|
6056
|
+
```typescript
|
|
6057
|
+
public readonly webhookAccess: LambdaAccess;
|
|
6058
|
+
```
|
|
6059
|
+
|
|
6060
|
+
- *Type:* <a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess">LambdaAccess</a>
|
|
6061
|
+
- *Default:* LambdaAccess.lambdaUrl()
|
|
6062
|
+
|
|
6063
|
+
Access configuration for the webhook function.
|
|
6064
|
+
|
|
6065
|
+
This function is called by GitHub when a new workflow job is scheduled. For an extra layer of security, you can set this to `LambdaAccess.apiGateway({ allowedIps: LambdaAccess.githubWebhookIps() })`.
|
|
6066
|
+
|
|
6067
|
+
You can also set this to `LambdaAccess.privateApiGateway()` if your GitHub Enterprise Server is hosted in a VPC. This will create an API Gateway endpoint that's only accessible from within the VPC.
|
|
6068
|
+
|
|
6069
|
+
*WARNING*: changing access type may change the URL. When the URL changes, you must update GitHub as well.
|
|
6070
|
+
|
|
6071
|
+
---
|
|
6072
|
+
|
|
5959
6073
|
### ImageBuilderAsset <a name="ImageBuilderAsset" id="@cloudsnorkel/cdk-github-runners.ImageBuilderAsset"></a>
|
|
5960
6074
|
|
|
5961
6075
|
An asset including file or directory to place inside the built image.
|
|
@@ -7262,6 +7376,107 @@ X86_64.
|
|
|
7262
7376
|
|
|
7263
7377
|
---
|
|
7264
7378
|
|
|
7379
|
+
### LambdaAccess <a name="LambdaAccess" id="@cloudsnorkel/cdk-github-runners.LambdaAccess"></a>
|
|
7380
|
+
|
|
7381
|
+
Access configuration options for Lambda functions like setup and webhook function.
|
|
7382
|
+
|
|
7383
|
+
Use this to limit access to these functions.
|
|
7384
|
+
|
|
7385
|
+
#### Initializers <a name="Initializers" id="@cloudsnorkel/cdk-github-runners.LambdaAccess.Initializer"></a>
|
|
7386
|
+
|
|
7387
|
+
```typescript
|
|
7388
|
+
import { LambdaAccess } from '@cloudsnorkel/cdk-github-runners'
|
|
7389
|
+
|
|
7390
|
+
new LambdaAccess()
|
|
7391
|
+
```
|
|
7392
|
+
|
|
7393
|
+
| **Name** | **Type** | **Description** |
|
|
7394
|
+
| --- | --- | --- |
|
|
7395
|
+
|
|
7396
|
+
---
|
|
7397
|
+
|
|
7398
|
+
|
|
7399
|
+
#### Static Functions <a name="Static Functions" id="Static Functions"></a>
|
|
7400
|
+
|
|
7401
|
+
| **Name** | **Description** |
|
|
7402
|
+
| --- | --- |
|
|
7403
|
+
| <code><a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess.apiGateway">apiGateway</a></code> | Provide access using API Gateway. |
|
|
7404
|
+
| <code><a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess.githubWebhookIps">githubWebhookIps</a></code> | Downloads the list of IP addresses used by GitHub.com for webhooks. |
|
|
7405
|
+
| <code><a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess.lambdaUrl">lambdaUrl</a></code> | Provide access using Lambda URL. |
|
|
7406
|
+
| <code><a href="#@cloudsnorkel/cdk-github-runners.LambdaAccess.noAccess">noAccess</a></code> | Disables access to the configured Lambda function. |
|
|
7407
|
+
|
|
7408
|
+
---
|
|
7409
|
+
|
|
7410
|
+
##### `apiGateway` <a name="apiGateway" id="@cloudsnorkel/cdk-github-runners.LambdaAccess.apiGateway"></a>
|
|
7411
|
+
|
|
7412
|
+
```typescript
|
|
7413
|
+
import { LambdaAccess } from '@cloudsnorkel/cdk-github-runners'
|
|
7414
|
+
|
|
7415
|
+
LambdaAccess.apiGateway(props?: ApiGatewayAccessProps)
|
|
7416
|
+
```
|
|
7417
|
+
|
|
7418
|
+
Provide access using API Gateway.
|
|
7419
|
+
|
|
7420
|
+
This is the most secure option, but requires additional configuration. It allows you to limit access to specific IP addresses and even to a specific VPC.
|
|
7421
|
+
|
|
7422
|
+
To limit access to GitHub.com use:
|
|
7423
|
+
|
|
7424
|
+
```
|
|
7425
|
+
LambdaAccess.apiGateway({
|
|
7426
|
+
allowedIps: LambdaAccess.githubWebhookIps(),
|
|
7427
|
+
});
|
|
7428
|
+
```
|
|
7429
|
+
|
|
7430
|
+
Alternatively, get and manually update the list manually with:
|
|
7431
|
+
|
|
7432
|
+
```
|
|
7433
|
+
curl https://api.github.com/meta | jq .hooks
|
|
7434
|
+
```
|
|
7435
|
+
|
|
7436
|
+
###### `props`<sup>Optional</sup> <a name="props" id="@cloudsnorkel/cdk-github-runners.LambdaAccess.apiGateway.parameter.props"></a>
|
|
7437
|
+
|
|
7438
|
+
- *Type:* <a href="#@cloudsnorkel/cdk-github-runners.ApiGatewayAccessProps">ApiGatewayAccessProps</a>
|
|
7439
|
+
|
|
7440
|
+
---
|
|
7441
|
+
|
|
7442
|
+
##### `githubWebhookIps` <a name="githubWebhookIps" id="@cloudsnorkel/cdk-github-runners.LambdaAccess.githubWebhookIps"></a>
|
|
7443
|
+
|
|
7444
|
+
```typescript
|
|
7445
|
+
import { LambdaAccess } from '@cloudsnorkel/cdk-github-runners'
|
|
7446
|
+
|
|
7447
|
+
LambdaAccess.githubWebhookIps()
|
|
7448
|
+
```
|
|
7449
|
+
|
|
7450
|
+
Downloads the list of IP addresses used by GitHub.com for webhooks.
|
|
7451
|
+
|
|
7452
|
+
Note that downloading dynamic data during deployment is not recommended in CDK. This is a workaround for the lack of a better solution.
|
|
7453
|
+
|
|
7454
|
+
##### `lambdaUrl` <a name="lambdaUrl" id="@cloudsnorkel/cdk-github-runners.LambdaAccess.lambdaUrl"></a>
|
|
7455
|
+
|
|
7456
|
+
```typescript
|
|
7457
|
+
import { LambdaAccess } from '@cloudsnorkel/cdk-github-runners'
|
|
7458
|
+
|
|
7459
|
+
LambdaAccess.lambdaUrl()
|
|
7460
|
+
```
|
|
7461
|
+
|
|
7462
|
+
Provide access using Lambda URL.
|
|
7463
|
+
|
|
7464
|
+
This is the default and simplest option. It puts no limits on the requester, but the Lambda functions themselves authenticate every request.
|
|
7465
|
+
|
|
7466
|
+
##### `noAccess` <a name="noAccess" id="@cloudsnorkel/cdk-github-runners.LambdaAccess.noAccess"></a>
|
|
7467
|
+
|
|
7468
|
+
```typescript
|
|
7469
|
+
import { LambdaAccess } from '@cloudsnorkel/cdk-github-runners'
|
|
7470
|
+
|
|
7471
|
+
LambdaAccess.noAccess()
|
|
7472
|
+
```
|
|
7473
|
+
|
|
7474
|
+
Disables access to the configured Lambda function.
|
|
7475
|
+
|
|
7476
|
+
This is useful for the setup function after setup is done.
|
|
7477
|
+
|
|
7478
|
+
|
|
7479
|
+
|
|
7265
7480
|
### LinuxUbuntuComponents <a name="LinuxUbuntuComponents" id="@cloudsnorkel/cdk-github-runners.LinuxUbuntuComponents"></a>
|
|
7266
7481
|
|
|
7267
7482
|
Components for Ubuntu Linux that can be used with AWS Image Builder based builders.
|
|
@@ -9164,7 +9164,8 @@ function response(code, body) {
|
|
|
9164
9164
|
};
|
|
9165
9165
|
}
|
|
9166
9166
|
async function handleRoot(event, setupToken) {
|
|
9167
|
-
const
|
|
9167
|
+
const stage = event.requestContext.stage == "$default" ? "" : `/${event.requestContext.stage}`;
|
|
9168
|
+
const setupBaseUrl = `https://${event.requestContext.domainName}${stage}`;
|
|
9168
9169
|
const githubSecrets = await getSecretJsonValue(process.env.GITHUB_SECRET_ARN);
|
|
9169
9170
|
return response(200, getHtml(setupBaseUrl, setupToken, githubSecrets.domain));
|
|
9170
9171
|
}
|
|
@@ -9254,20 +9255,23 @@ exports.handler = async function(event) {
|
|
|
9254
9255
|
return response(403, "Wrong setup token.");
|
|
9255
9256
|
}
|
|
9256
9257
|
try {
|
|
9257
|
-
|
|
9258
|
+
const path = event.path ?? event.rawPath;
|
|
9259
|
+
const method = event.httpMethod ?? event.requestContext.http.method;
|
|
9260
|
+
if (path == "/") {
|
|
9258
9261
|
return await handleRoot(event, setupToken);
|
|
9259
|
-
} else if (
|
|
9262
|
+
} else if (path == "/domain" && method == "POST") {
|
|
9260
9263
|
return await handleDomain(event);
|
|
9261
|
-
} else if (
|
|
9264
|
+
} else if (path == "/pat" && method == "POST") {
|
|
9262
9265
|
return await handlePat(event);
|
|
9263
|
-
} else if (
|
|
9266
|
+
} else if (path == "/complete-new-app" && method == "GET") {
|
|
9264
9267
|
return await handleNewApp(event);
|
|
9265
|
-
} else if (
|
|
9268
|
+
} else if (path == "/app" && method == "POST") {
|
|
9266
9269
|
return await handleExistingApp(event);
|
|
9267
9270
|
} else {
|
|
9268
9271
|
return response(404, "Not found");
|
|
9269
9272
|
}
|
|
9270
9273
|
} catch (e) {
|
|
9274
|
+
console.error(e);
|
|
9271
9275
|
return response(500, `<b>Error:</b> ${e}`);
|
|
9272
9276
|
}
|
|
9273
9277
|
};
|
|
@@ -21184,7 +21184,19 @@ async function generateProvidersStatus(stack, logicalId) {
|
|
|
21184
21184
|
return p;
|
|
21185
21185
|
}));
|
|
21186
21186
|
}
|
|
21187
|
-
|
|
21187
|
+
function safeReturnValue(event, status) {
|
|
21188
|
+
if (event.path) {
|
|
21189
|
+
return {
|
|
21190
|
+
statusCode: 200,
|
|
21191
|
+
headers: {
|
|
21192
|
+
"Content-Type": "application/json"
|
|
21193
|
+
},
|
|
21194
|
+
body: JSON.stringify(status)
|
|
21195
|
+
};
|
|
21196
|
+
}
|
|
21197
|
+
return status;
|
|
21198
|
+
}
|
|
21199
|
+
exports.handler = async function(event) {
|
|
21188
21200
|
if (!process.env.WEBHOOK_SECRET_ARN || !process.env.GITHUB_SECRET_ARN || !process.env.GITHUB_PRIVATE_KEY_SECRET_ARN || !process.env.LOGICAL_ID || !process.env.WEBHOOK_HANDLER_ARN || !process.env.STEP_FUNCTION_ARN || !process.env.SETUP_SECRET_ARN || !process.env.SETUP_FUNCTION_URL || !process.env.STACK_NAME) {
|
|
21189
21201
|
throw new Error("Missing environment variables");
|
|
21190
21202
|
}
|
|
@@ -21261,14 +21273,14 @@ exports.handler = async function() {
|
|
|
21261
21273
|
githubSecrets = await getSecretJsonValue(process.env.GITHUB_SECRET_ARN);
|
|
21262
21274
|
} catch (e) {
|
|
21263
21275
|
status.github.auth.status = `Unable to read secret: ${e}`;
|
|
21264
|
-
return status;
|
|
21276
|
+
return safeReturnValue(event, status);
|
|
21265
21277
|
}
|
|
21266
21278
|
let privateKey;
|
|
21267
21279
|
try {
|
|
21268
21280
|
privateKey = await getSecretValue(process.env.GITHUB_PRIVATE_KEY_SECRET_ARN);
|
|
21269
21281
|
} catch (e) {
|
|
21270
21282
|
status.github.auth.status = `Unable to read private key secret: ${e}`;
|
|
21271
|
-
return status;
|
|
21283
|
+
return safeReturnValue(event, status);
|
|
21272
21284
|
}
|
|
21273
21285
|
let baseUrl = baseUrlFromDomain(githubSecrets.domain);
|
|
21274
21286
|
status.github.domain = githubSecrets.domain;
|
|
@@ -21280,14 +21292,14 @@ exports.handler = async function() {
|
|
|
21280
21292
|
octokit = new import_core.Octokit({ baseUrl, auth: githubSecrets.personalAuthToken });
|
|
21281
21293
|
} catch (e) {
|
|
21282
21294
|
status.github.auth.status = `Unable to authenticate using personal auth token: ${e}`;
|
|
21283
|
-
return status;
|
|
21295
|
+
return safeReturnValue(event, status);
|
|
21284
21296
|
}
|
|
21285
21297
|
try {
|
|
21286
21298
|
const user = await octokit.request("GET /user");
|
|
21287
21299
|
status.github.auth.personalAuthToken = `username: ${user.data.login}`;
|
|
21288
21300
|
} catch (e) {
|
|
21289
21301
|
status.github.auth.status = `Unable to call /user with personal auth token: ${e}`;
|
|
21290
|
-
return status;
|
|
21302
|
+
return safeReturnValue(event, status);
|
|
21291
21303
|
}
|
|
21292
21304
|
status.github.auth.status = "OK";
|
|
21293
21305
|
status.github.webhook.status = "Unable to verify automatically";
|
|
@@ -21306,14 +21318,14 @@ exports.handler = async function() {
|
|
|
21306
21318
|
});
|
|
21307
21319
|
} catch (e) {
|
|
21308
21320
|
status.github.auth.status = `Unable to authenticate app: ${e}`;
|
|
21309
|
-
return status;
|
|
21321
|
+
return safeReturnValue(event, status);
|
|
21310
21322
|
}
|
|
21311
21323
|
try {
|
|
21312
21324
|
const app = (await appOctokit.request("GET /app")).data;
|
|
21313
21325
|
status.github.auth.app.url = app.html_url;
|
|
21314
21326
|
} catch (e) {
|
|
21315
21327
|
status.github.auth.status = `Unable to get app details: ${e}`;
|
|
21316
|
-
return status;
|
|
21328
|
+
return safeReturnValue(event, status);
|
|
21317
21329
|
}
|
|
21318
21330
|
try {
|
|
21319
21331
|
const installations = (await appOctokit.request("GET /app/installations")).data;
|
|
@@ -21355,7 +21367,7 @@ exports.handler = async function() {
|
|
|
21355
21367
|
}
|
|
21356
21368
|
} catch (e) {
|
|
21357
21369
|
status.github.auth.status = "Unable to list app installations";
|
|
21358
|
-
return status;
|
|
21370
|
+
return safeReturnValue(event, status);
|
|
21359
21371
|
}
|
|
21360
21372
|
status.github.auth.status = "OK";
|
|
21361
21373
|
try {
|
|
@@ -21367,10 +21379,10 @@ exports.handler = async function() {
|
|
|
21367
21379
|
}
|
|
21368
21380
|
} catch (e) {
|
|
21369
21381
|
status.github.webhook.status = `Unable to check app configuration: ${e}`;
|
|
21370
|
-
return status;
|
|
21382
|
+
return safeReturnValue(event, status);
|
|
21371
21383
|
}
|
|
21372
21384
|
}
|
|
21373
|
-
return status;
|
|
21385
|
+
return safeReturnValue(event, status);
|
|
21374
21386
|
};
|
|
21375
21387
|
/*! Bundled license information:
|
|
21376
21388
|
|
|
@@ -45,8 +45,16 @@ async function getSecretJsonValue(arn) {
|
|
|
45
45
|
|
|
46
46
|
// src/lambdas/webhook-handler.lambda.ts
|
|
47
47
|
var sf = new AWS2.StepFunctions();
|
|
48
|
+
function getHeader(event, header) {
|
|
49
|
+
for (const headerName of Object.keys(event.headers)) {
|
|
50
|
+
if (headerName.toLowerCase() === header.toLowerCase()) {
|
|
51
|
+
return event.headers[headerName];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return void 0;
|
|
55
|
+
}
|
|
48
56
|
function verifyBody(event, secret) {
|
|
49
|
-
const sig = Buffer.from(event
|
|
57
|
+
const sig = Buffer.from(getHeader(event, "x-hub-signature-256") || "", "utf8");
|
|
50
58
|
if (!event.body) {
|
|
51
59
|
throw new Error("No body");
|
|
52
60
|
}
|
|
@@ -81,21 +89,21 @@ exports.handler = async function(event) {
|
|
|
81
89
|
body: "Bad signature"
|
|
82
90
|
};
|
|
83
91
|
}
|
|
84
|
-
if (event
|
|
85
|
-
console.error(`This webhook only accepts JSON payloads, got ${event
|
|
92
|
+
if (getHeader(event, "content-type") !== "application/json") {
|
|
93
|
+
console.error(`This webhook only accepts JSON payloads, got ${getHeader(event, "content-type")}`);
|
|
86
94
|
return {
|
|
87
95
|
statusCode: 400,
|
|
88
96
|
body: "Expecting JSON payload"
|
|
89
97
|
};
|
|
90
98
|
}
|
|
91
|
-
if (event
|
|
99
|
+
if (getHeader(event, "x-github-event") === "ping") {
|
|
92
100
|
return {
|
|
93
101
|
statusCode: 200,
|
|
94
102
|
body: "Pong"
|
|
95
103
|
};
|
|
96
104
|
}
|
|
97
|
-
if (event
|
|
98
|
-
console.error(`This webhook only accepts workflow_job, got ${event
|
|
105
|
+
if (getHeader(event, "x-github-event") !== "workflow_job") {
|
|
106
|
+
console.error(`This webhook only accepts workflow_job, got ${getHeader(event, "x-github-event")}`);
|
|
99
107
|
return {
|
|
100
108
|
statusCode: 400,
|
|
101
109
|
body: "Expecting workflow_job"
|
|
@@ -118,7 +126,7 @@ exports.handler = async function(event) {
|
|
|
118
126
|
}
|
|
119
127
|
let labels = {};
|
|
120
128
|
payload.workflow_job.labels.forEach((l) => labels[l.toLowerCase()] = true);
|
|
121
|
-
let executionName = `${payload.repository.full_name.replace("/", "-")}-${event
|
|
129
|
+
let executionName = `${payload.repository.full_name.replace("/", "-")}-${getHeader(event, "x-github-delivery")}`.slice(0, 64);
|
|
122
130
|
const execution = await sf.startExecution({
|
|
123
131
|
stateMachineArn: process.env.STEP_FUNCTION_ARN,
|
|
124
132
|
input: JSON.stringify({
|
package/lib/access.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { aws_ec2 as ec2, aws_lambda as lambda } from 'aws-cdk-lib';
|
|
2
|
+
import { Construct } from 'constructs';
|
|
3
|
+
export interface ApiGatewayAccessProps {
|
|
4
|
+
/**
|
|
5
|
+
* List of IP addresses in CIDR notation that are allowed to access the API Gateway.
|
|
6
|
+
*
|
|
7
|
+
* If not specified on public API Gateway, all IP addresses are allowed.
|
|
8
|
+
*
|
|
9
|
+
* If not specified on private API Gateway, no IP addresses are allowed (but specified security groups are).
|
|
10
|
+
*/
|
|
11
|
+
readonly allowedIps?: string[];
|
|
12
|
+
/**
|
|
13
|
+
* Creates a private API Gateway and allows access from the specified VPC.
|
|
14
|
+
*/
|
|
15
|
+
readonly allowedVpc?: ec2.IVpc;
|
|
16
|
+
/**
|
|
17
|
+
* List of security groups that are allowed to access the API Gateway.
|
|
18
|
+
*
|
|
19
|
+
* Only works for private API Gateways with {@link allowedVpc}.
|
|
20
|
+
*/
|
|
21
|
+
readonly allowedSecurityGroups?: ec2.ISecurityGroup[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Access configuration options for Lambda functions like setup and webhook function. Use this to limit access to these functions.
|
|
25
|
+
*/
|
|
26
|
+
export declare abstract class LambdaAccess {
|
|
27
|
+
/**
|
|
28
|
+
* Disables access to the configured Lambda function. This is useful for the setup function after setup is done.
|
|
29
|
+
*/
|
|
30
|
+
static noAccess(): LambdaAccess;
|
|
31
|
+
/**
|
|
32
|
+
* Provide access using Lambda URL. This is the default and simplest option. It puts no limits on the requester, but the Lambda functions themselves authenticate every request.
|
|
33
|
+
*/
|
|
34
|
+
static lambdaUrl(): LambdaAccess;
|
|
35
|
+
/**
|
|
36
|
+
* Provide access using API Gateway. This is the most secure option, but requires additional configuration. It allows you to limit access to specific IP addresses and even to a specific VPC.
|
|
37
|
+
*
|
|
38
|
+
* To limit access to GitHub.com use:
|
|
39
|
+
*
|
|
40
|
+
* ```
|
|
41
|
+
* LambdaAccess.apiGateway({
|
|
42
|
+
* allowedIps: LambdaAccess.githubWebhookIps(),
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* Alternatively, get and manually update the list manually with:
|
|
47
|
+
*
|
|
48
|
+
* ```
|
|
49
|
+
* curl https://api.github.com/meta | jq .hooks
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
static apiGateway(props?: ApiGatewayAccessProps): LambdaAccess;
|
|
53
|
+
/**
|
|
54
|
+
* Downloads the list of IP addresses used by GitHub.com for webhooks.
|
|
55
|
+
*
|
|
56
|
+
* Note that downloading dynamic data during deployment is not recommended in CDK. This is a workaround for the lack of a better solution.
|
|
57
|
+
*/
|
|
58
|
+
static githubWebhookIps(): string[];
|
|
59
|
+
/**
|
|
60
|
+
* Creates all required resources and returns access URL or empty string if disabled.
|
|
61
|
+
*
|
|
62
|
+
* @internal
|
|
63
|
+
*/
|
|
64
|
+
abstract _bind(construct: Construct, id: string, lambdaFunction: lambda.Function): string;
|
|
65
|
+
}
|