Skip to content

Commit

Permalink
add some behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
sblack4 committed Jun 8, 2022
1 parent 68a2014 commit dbcb8c4
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 7 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ In case the setup does not work as intended follow the trace of events:
| <a name="input_runner_ec2_tags"></a> [runner\_ec2\_tags](#input\_runner\_ec2\_tags) | Map of tags that will be added to the launch template instance tag specificatons. | `map(string)` | `{}` | no |
| <a name="input_runner_egress_rules"></a> [runner\_egress\_rules](#input\_runner\_egress\_rules) | List of egress rules for the GitHub runner instances. | <pre>list(object({<br> cidr_blocks = list(string)<br> ipv6_cidr_blocks = list(string)<br> prefix_list_ids = list(string)<br> from_port = number<br> protocol = string<br> security_groups = list(string)<br> self = bool<br> to_port = number<br> description = string<br> }))</pre> | <pre>[<br> {<br> "cidr_blocks": [<br> "0.0.0.0/0"<br> ],<br> "description": null,<br> "from_port": 0,<br> "ipv6_cidr_blocks": [<br> "::/0"<br> ],<br> "prefix_list_ids": null,<br> "protocol": "-1",<br> "security_groups": null,<br> "self": null,<br> "to_port": 0<br> }<br>]</pre> | no |
| <a name="input_runner_enable_workflow_job_labels_check"></a> [runner\_enable\_workflow\_job\_labels\_check](#input\_runner\_enable\_workflow\_job\_labels\_check) | If set to true all labels in the workflow job even are matched agaist the custom labels and GitHub labels (os, architecture and `self-hosted`). When the labels are not matching the event is dropped at the webhook. | `bool` | `false` | no |
| <a name="input_runner_enable_workflow_job_labels_check_all"></a> [runner\_enable\_workflow\_job\_labels\_check\_all](#input\_runner\_enable\_workflow\_job\_labels\_check\_all) | If set to true all labels in the workflow job must match the GitHub labels (os, architecture and `self-hosted`). When false if __any__ label matches it will trigger the webhook. `runner_enable_workflow_job_labels_check` must be true for this to take effect. | `bool` | `true` | no |
| <a name="input_runner_extra_labels"></a> [runner\_extra\_labels](#input\_runner\_extra\_labels) | Extra (custom) labels for the runners (GitHub). Separate each label by a comma. Labels checks on the webhook can be enforced by setting `enable_workflow_job_labels_check`. GitHub read-only labels should not be provided. | `string` | `""` | no |
| <a name="input_runner_group_name"></a> [runner\_group\_name](#input\_runner\_group\_name) | Name of the runner group. | `string` | `"Default"` | no |
| <a name="input_runner_iam_role_managed_policy_arns"></a> [runner\_iam\_role\_managed\_policy\_arns](#input\_runner\_iam\_role\_managed\_policy\_arns) | Attach AWS or customer-managed IAM policies (by ARN) to the runner IAM role | `list(string)` | `[]` | no |
Expand Down
1 change: 1 addition & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ module "webhook" {

# labels
enable_workflow_job_labels_check = var.runner_enable_workflow_job_labels_check
workflow_job_labels_check_all = var.runner_enable_workflow_job_labels_check_all
runner_labels = "self-hosted,${var.runner_os},${var.runner_architecture},${var.runner_extra_labels}"

role_path = var.role_path
Expand Down
3 changes: 2 additions & 1 deletion modules/setup-iam-permissions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ No modules.
|------|-------------|------|---------|:--------:|
| <a name="input_account_id"></a> [account\_id](#input\_account\_id) | The module allows to switch to the created role from the provided account id. | `string` | n/a | yes |
| <a name="input_aws_partition"></a> [aws\_partition](#input\_aws\_partition) | (optional) partition in the arn namespace if not aws | `string` | `"aws"` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | A name that identifies the environment, used as prefix and for tagging. | `string` | n/a | yes |
| <a name="input_environment"></a> [environment](#input\_environment) | A name that identifies the environment, used as prefix and for tagging. | `string` | `null` | no |
| <a name="input_namespaces"></a> [namespaces](#input\_namespaces) | The role will be only allowed to create roles, policies and instance profiles in the given namespace / path. All policies in the boundaries namespace cannot be modified by this role. | <pre>object({<br> boundary_namespace = string<br> role_namespace = string<br> policy_namespace = string<br> instance_profile_namespace = string<br> })</pre> | n/a | yes |
| <a name="input_prefix"></a> [prefix](#input\_prefix) | The prefix used for naming resources | `string` | `"github-actions"` | no |

## Outputs

Expand Down
1 change: 1 addition & 0 deletions modules/webhook/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ No modules.
| <a name="input_tags"></a> [tags](#input\_tags) | Map of tags that will be added to created resources. By default resources will be tagged with name and environment. | `map(string)` | `{}` | no |
| <a name="input_webhook_lambda_s3_key"></a> [webhook\_lambda\_s3\_key](#input\_webhook\_lambda\_s3\_key) | S3 key for webhook lambda function. Required if using S3 bucket to specify lambdas. | `any` | `null` | no |
| <a name="input_webhook_lambda_s3_object_version"></a> [webhook\_lambda\_s3\_object\_version](#input\_webhook\_lambda\_s3\_object\_version) | S3 object version for webhook lambda function. Useful if S3 versioning is enabled on source bucket. | `any` | `null` | no |
| <a name="input_workflow_job_labels_check_all"></a> [workflow\_job\_labels\_check\_all](#input\_workflow\_job\_labels\_check\_all) | If set to true all labels in the workflow job must match the GitHub labels (os, architecture and `self-hosted`). When false if __any__ label matches it will trigger the webhook. `enable_workflow_job_labels_check` must be true for this to take effect. | `bool` | `true` | no |

## Outputs

Expand Down
23 changes: 17 additions & 6 deletions modules/webhook/lambdas/webhook/src/webhook/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const supportedEvents = ['check_run', 'workflow_job'];
const logger = rootLogger.getChildLogger();

export async function handle(headers: IncomingHttpHeaders, body: string): Promise<Response> {
const { environment, repositoryWhiteList, enableWorkflowLabelCheck, runnerLabels } = readEnvironmentVariables();
const { environment, repositoryWhiteList, enableWorkflowLabelCheck, workflowLabelCheckAll, runnerLabels } = readEnvironmentVariables();

// ensure header keys lower case since github headers can contain capitals.
for (const key in headers) {
Expand Down Expand Up @@ -66,6 +66,7 @@ export async function handle(headers: IncomingHttpHeaders, body: string): Promis
payload as WorkflowJobEvent,
githubEvent,
enableWorkflowLabelCheck,
workflowLabelCheckAll,
runnerLabels,
);
} else if (githubEvent == 'check_run') {
Expand All @@ -79,11 +80,13 @@ function readEnvironmentVariables() {
const environment = process.env.ENVIRONMENT;
const enableWorkflowLabelCheckEnv = process.env.ENABLE_WORKFLOW_JOB_LABELS_CHECK || 'false';
const enableWorkflowLabelCheck = JSON.parse(enableWorkflowLabelCheckEnv) as boolean;
const workflowLabelCheckAllEnv = process.env.WORKFLOW_JOB_LABELS_CHECK_ALL || 'false';
const workflowLabelCheckAll = JSON.parse(workflowLabelCheckAllEnv) as boolean;
const repositoryWhiteListEnv = process.env.REPOSITORY_WHITE_LIST || '[]';
const repositoryWhiteList = JSON.parse(repositoryWhiteListEnv) as Array<string>;
const runnerLabelsEnv = process.env.RUNNER_LABELS || '[]';
const runnerLabels = JSON.parse(runnerLabelsEnv) as Array<string>;
return { environment, repositoryWhiteList, enableWorkflowLabelCheck, runnerLabels };
return { environment, repositoryWhiteList, enableWorkflowLabelCheck, workflowLabelCheckAll, runnerLabels };
}

async function verifySignature(
Expand Down Expand Up @@ -117,9 +120,10 @@ async function handleWorkflowJob(
body: WorkflowJobEvent,
githubEvent: string,
enableWorkflowLabelCheck: boolean,
workflowLabelCheckAll: boolean,
runnerLabels: string[],
): Promise<Response> {
if (enableWorkflowLabelCheck && !canRunJob(body, runnerLabels)) {
if (enableWorkflowLabelCheck && !canRunJob(body, runnerLabels, workflowLabelCheckAll)) {
logger.warn(
`Received event contains runner labels '${body.workflow_job.labels}' that are not accepted.`,
LogFields.print(),
Expand Down Expand Up @@ -171,10 +175,17 @@ function isRepoNotAllowed(repoFullName: string, repositoryWhiteList: string[]):
return repositoryWhiteList.length > 0 && !repositoryWhiteList.includes(repoFullName);
}

function canRunJob(job: WorkflowJobEvent, runnerLabels: string[]): boolean {
function canRunJob(job: WorkflowJobEvent, runnerLabels: string[], workflowLabelCheckAll: boolean): boolean {
const workflowJobLabels = job.workflow_job.labels;
const runnerMatch = runnerLabels.every((l) => workflowJobLabels.includes(l));
const jobMatch = workflowJobLabels.every((l) => runnerLabels.includes(l));
let runnerMatch;
let jobMatch
if(workflowLabelCheckAll) {
runnerMatch = runnerLabels.every((l) => workflowJobLabels.includes(l));
jobMatch = workflowJobLabels.every((l) => runnerLabels.includes(l));
} else {
runnerMatch = runnerLabels.some((l) => workflowJobLabels.includes(l));
jobMatch = workflowJobLabels.some((l) => runnerLabels.includes(l));
}
const match = jobMatch && runnerMatch;

logger.debug(
Expand Down
6 changes: 6 additions & 0 deletions modules/webhook/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ variable "enable_workflow_job_labels_check" {
default = false
}

variable "workflow_job_labels_check_all" {
description = "If set to true all labels in the workflow job must match the GitHub labels (os, architecture and `self-hosted`). When false if __any__ label matches it will trigger the webhook. `enable_workflow_job_labels_check` must be true for this to take effect."
type = bool
default = true
}

variable "log_type" {
description = "Logging format for lambda logging. Valid values are 'json', 'pretty', 'hidden'. "
type = string
Expand Down
1 change: 1 addition & 0 deletions modules/webhook/webhook.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ resource "aws_lambda_function" "webhook" {
environment {
variables = {
ENABLE_WORKFLOW_JOB_LABELS_CHECK = var.enable_workflow_job_labels_check
WORKFLOW_JOB_LABELS_CHECK_ALL = var.workflow_job_labels_check_all
ENVIRONMENT = var.prefix
LOG_LEVEL = var.log_level
LOG_TYPE = var.log_type
Expand Down
6 changes: 6 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,12 @@ variable "runner_enable_workflow_job_labels_check" {
default = false
}

variable "runner_enable_workflow_job_labels_check_all" {
description = "If set to true all labels in the workflow job must match the GitHub labels (os, architecture and `self-hosted`). When false if __any__ label matches it will trigger the webhook. `runner_enable_workflow_job_labels_check` must be true for this to take effect."
type = bool
default = true
}

variable "runner_ec2_tags" {
description = "Map of tags that will be added to the launch template instance tag specificatons."
type = map(string)
Expand Down

0 comments on commit dbcb8c4

Please sign in to comment.