This is an automated email from the ASF dual-hosted git repository.
ash pushed a commit to branch autoscaling-lambda
in repository https://gitbox.apache.org/repos/asf/airflow-ci-infra.git
The following commit(s) were added to refs/heads/autoscaling-lambda by this
push:
new 408a9b9 fixup! Lambda function to scale ASG based on Github webhooks
408a9b9 is described below
commit 408a9b916714af6738309fcd23c877efcfff434b
Author: Ash Berlin-Taylor <[email protected]>
AuthorDate: Wed Feb 17 14:48:57 2021 +0000
fixup! Lambda function to scale ASG based on Github webhooks
---
requirements-test.txt | 2 +
requirements.txt | 1 +
requirements.txt => tests/conftest.py | 4 --
.../webhooks/scale_out_runner/conftest.py | 21 ++++++--
tests/webhooks/scale_out_runner/test_app.py | 61 ++++++++++++++++++++++
.../scale_out_runner/.chalice/deployed/prod.json | 28 ++++++++++
webhooks/scale_out_runner/app.py | 8 +--
7 files changed, 115 insertions(+), 10 deletions(-)
diff --git a/requirements-test.txt b/requirements-test.txt
new file mode 100644
index 0000000..4e2748b
--- /dev/null
+++ b/requirements-test.txt
@@ -0,0 +1,2 @@
+pytest~=6.0
+moto
diff --git a/requirements.txt b/requirements.txt
index 432240d..95528c3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -18,3 +18,4 @@
boto3
click~=7.1
requests
+pytest~=6.0
diff --git a/requirements.txt b/tests/conftest.py
similarity index 96%
copy from requirements.txt
copy to tests/conftest.py
index 432240d..13a8339 100644
--- a/requirements.txt
+++ b/tests/conftest.py
@@ -14,7 +14,3 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-
-boto3
-click~=7.1
-requests
diff --git a/requirements.txt b/tests/webhooks/scale_out_runner/conftest.py
similarity index 70%
copy from requirements.txt
copy to tests/webhooks/scale_out_runner/conftest.py
index 432240d..378e130 100644
--- a/requirements.txt
+++ b/tests/webhooks/scale_out_runner/conftest.py
@@ -15,6 +15,21 @@
# specific language governing permissions and limitations
# under the License.
-boto3
-click~=7.1
-requests
+import os
+import sys
+
+import pytest
+from chalice.test import Client
+
+path = os.path.dirname(__file__)
+idx = path.rfind('/tests/')
+path = path[:idx] + path[idx + 6 :]
+sys.path.append(path)
+
+
[email protected]
+def client(request):
+ app = getattr(request.module, "app")
+
+ with Client(app) as client:
+ yield client
diff --git a/tests/webhooks/scale_out_runner/test_app.py
b/tests/webhooks/scale_out_runner/test_app.py
new file mode 100644
index 0000000..52f8e99
--- /dev/null
+++ b/tests/webhooks/scale_out_runner/test_app.py
@@ -0,0 +1,61 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import json
+
+import pytest
+from app import app # noqa
+
+
[email protected](autouse=True)
+def no_requests(monkeypatch):
+ monkeypatch.setenv("GH_WEBHOOK_TOKEN", "abc")
+
+
+def test_no_auth(client):
+ response = client.http.post('/', body=json.dumps({'hello': 'world'}))
+ assert response.status_code == 400
+
+
[email protected](
+ "sig",
+ [
+ "md5=",
+ # Valid, but not prefixed
+ "160156e060356c9444613b224fc5613a0a25315b7898fd5d8c7656bd8a6654af",
+ ],
+)
+def test_bad_auth(sig, client):
+ response = client.http.post(
+ '/',
+ headers={
+ 'X-Hub-Signature-256': sig,
+ },
+ body=json.dumps({'hello': 'world'}),
+ )
+ assert response.status_code == 400
+
+
+def test_auth(client):
+ response = client.http.post(
+ '/',
+ headers={
+ 'X-Hub-Signature-256':
'sha256=160156e060356c9444613b224fc5613a0a25315b7898fd5d8c7656bd8a6654af'
+ },
+ body=json.dumps({'hello': 'world'}),
+ )
+ assert response.status_code == 200
diff --git a/webhooks/scale_out_runner/.chalice/deployed/prod.json
b/webhooks/scale_out_runner/.chalice/deployed/prod.json
new file mode 100644
index 0000000..7f1a411
--- /dev/null
+++ b/webhooks/scale_out_runner/.chalice/deployed/prod.json
@@ -0,0 +1,28 @@
+{
+ "resources": [
+ {
+ "name": "managed-layer",
+ "resource_type": "lambda_layer",
+ "layer_version_arn":
"arn:aws:lambda:eu-central-1:827901512104:layer:scale_out_runner-prod-managed-layer:35"
+ },
+ {
+ "name": "api_handler_role",
+ "resource_type": "iam_role",
+ "role_arn":
"arn:aws:iam::827901512104:role/scale_out_runner-prod-api_handler",
+ "role_name": "scale_out_runner-prod-api_handler"
+ },
+ {
+ "name": "api_handler",
+ "resource_type": "lambda_function",
+ "lambda_arn":
"arn:aws:lambda:eu-central-1:827901512104:function:scale_out_runner-prod"
+ },
+ {
+ "name": "rest_api",
+ "resource_type": "rest_api",
+ "rest_api_id": "2onm92olq7",
+ "rest_api_url":
"https://2onm92olq7.execute-api.eu-central-1.amazonaws.com/api/"
+ }
+ ],
+ "schema_version": "2.0",
+ "backend": "api"
+}
diff --git a/webhooks/scale_out_runner/app.py b/webhooks/scale_out_runner/app.py
index 9fab64f..2f40fb1 100644
--- a/webhooks/scale_out_runner/app.py
+++ b/webhooks/scale_out_runner/app.py
@@ -34,13 +34,15 @@ TABLE_NAME = os.getenv('COUNTER_TABLE', 'GithubRunnerQueue')
_commiters = set()
GH_WEBHOOK_TOKEN = None
-if 'REPOS' in os.environ:
- REPO_CONFIGURATION = json.loads(os.getenv('REPOS'))
+REPOS = os.getenv('REPOS')
+if REPOS:
+ REPO_CONFIGURATION = json.loads(REPOS)
else:
REPO_CONFIGURATION = {
# <repo>: [list-of-branches-to-use-self-hosted-on]
'apache/airflow': {'main', 'master'},
}
+del REPOS
@app.route('/', methods=['POST'])
@@ -127,7 +129,7 @@ def commiters(ssm_repo_name: str =
os.getenv('SSM_REPO_NAME', 'apache/airflow'))
def validate_gh_sig(request: Request):
sig = request.headers.get('X-Hub-Signature-256', None)
- if not sig.startswith('sha256='):
+ if not sig or not sig.startswith('sha256='):
raise BadRequestError('X-Hub-Signature-256 not of expected format')
sig = sig[len('sha256=') :]