Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit f18d41d

Browse files
committed
Add API Gateway frontend and client to kick off the lambda
1 parent 2315efa commit f18d41d

File tree

6 files changed

+154
-15
lines changed

6 files changed

+154
-15
lines changed

Makefile

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
SHELL := /bin/bash
2+
13
.PHONY: all
24
all: lambda
35

@@ -6,9 +8,6 @@ requirements: requirements-to-freeze.txt
68
@python3 -c 'print("Updating requirements.txt...")'
79
@docker run --rm -v $$(pwd):/usr/src/app/ python:3.8 /bin/bash -c "python -m pip install --upgrade pip && pip install -r /usr/src/app/requirements-to-freeze.txt && pip freeze > /usr/src/app/requirements.txt"
810

9-
.PHONY: clean
10-
clean: clean-python
11-
1211
.PHONY: clean-python
1312
clean-python:
1413
@# Prepending each recipe with - to continue regardless of errors per
@@ -18,7 +17,13 @@ clean-python:
1817
@-find . -type d -name '.pytest_cache' -exec rm -rf {} +
1918
@-find . -type f -name '*.pyc' -delete
2019

20+
.PHONY: clean
21+
clean: clean-python
22+
2123
.PHONY: lambda
2224
lambda: clean
2325
@docker run --rm -v $$(pwd):/usr/src/app/ python:3.8 /bin/bash -c "cd /usr/src/app/ && apt-get update && apt-get -y --no-install-recommends install zip && python -m pip install --upgrade pip && zip function.zip lambda_function.py && pip install --target ./package -r requirements.txt && cd package && zip -r9 ../function.zip ."
24-
@echo "docker run --rm -it --env-file <(env | grep AWS_) -v $$(pwd):/usr/src/app/ -v ${HOME}/.aws:/root/.aws easy_infra aws lambda update-function-code --function-name release_monitor --zip-file fileb:///usr/src/app/function.zip"
26+
27+
.PHONY: deploy
28+
deploy: lambda
29+
@docker run --rm --env-file <(env | grep AWS_) -v $$(pwd):/usr/src/app/ -v $${HOME}/.aws:/root/.aws seiso/easy_infra:latest aws lambda update-function-code --function-name release_monitor --zip-file fileb:///usr/src/app/function.zip

README.md

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,31 @@
11
# Release Monitor
22

3-
This project uses the unauthenticated GitHub APIs to monitor a provided account/repo for a release containing a provided commit. It is meant to be run as an AWS lambda on a cron, and send an email notification when a release with the provided commit is detected.
3+
This project uses the unauthenticated GitHub APIs to identify if the provided commit is in a stable release for the provided account/repo. It is meant to be run periodically, and send an email notification when a release with the provided commit is detected.
4+
5+
## Prereqs
6+
1. A lambda named "release_monitor", with a "lambda_function.lambda_handler" Handler, and Python 3.8 runtime.
7+
1. An API Gateway attached to the lambda with AWS_IAM authorization required, named "release_monitor", and "Invoke with caller credentials" enabled.
8+
1. Successful authentication to AWS with credentials that have access to lambda and API Gateway. For simplicity, we recommend using [environment variables](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html). If your environment uses roles, you may want to consider an approach such as [this](https://github.com/JonZeolla/Configs/blob/a524d572a5426b8cfffad3e5e70d300bfd9b8c90/apple/productivity/.zshrc#L159-L186).
49

510
## Quickstart
6-
1. Create a lambda in your AWS account.
7-
1. Auth to AWS via environment variables.
8-
1. Run the following:
11+
1. Make a reusable alias
12+
```bash
13+
alias awsdocker="docker run --rm -it --env-file <(env | grep AWS_) -v \$(pwd):/usr/src/app/ -v \${HOME}/.aws:/root/.aws seiso/easy_infra:latest"
14+
```
15+
1. Build and deploy the lambda.
16+
```bash
17+
make deploy
18+
```
19+
1. Get your REST api ID
20+
```bash
21+
awsdocker "aws apigateway get-rest-apis | jq -r '.[][][\"id\"]'
22+
```
23+
1. Query the lambda via API Gateway.
924
```bash
10-
make
11-
docker run --rm -it --env-file <(env | grep AWS_) -v $(pwd):/usr/src/app/ -v ${HOME}/.aws:/root/.aws seiso/easy_infra aws lambda update-function-code --function-name release_monitor --zip-file fileb:///usr/src/app/function.zip
25+
ACCOUNT=jonzeolla
26+
REPOSITORY=release_monitor
27+
COMMIT=2315efa04cd4a415916c654f26570a17b9195279
28+
API_ID=example
29+
./client.py --account $ACCOUNT --repository $REPOSITORY --commit $COMMIT --rest-api-id $API_ID
1230
```
1331

client.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Client for interacting with the release monitor's API gateway trigger
4+
"""
5+
# pylint: disable=line-too-long
6+
7+
import os
8+
from typing import Dict
9+
from argparse import ArgumentParser
10+
from urllib.parse import urlencode
11+
import requests
12+
from aws_requests_auth.boto_utils import BotoAWSRequestsAuth
13+
14+
15+
def main():
16+
"""Do the thing"""
17+
config = get_args_config()
18+
19+
account = config["account"]
20+
commit = config["commit"]
21+
repository = config["repository"]
22+
method = config["method"]
23+
rest_api_id = config["rest_api_id"]
24+
25+
uri = "/default/release_monitor"
26+
querystring = {
27+
"account": account, # pylint: disable=undefined-variable
28+
"commit": commit, # pylint: disable=undefined-variable
29+
"repository": repository, # pylint: disable=undefined-variable
30+
}
31+
querystring_encoded = urlencode(sorted(querystring.items()))
32+
33+
region = "us-east-1"
34+
host = rest_api_id + ".execute-api." + region + ".amazonaws.com"
35+
url = "https://" + host + uri + "?" + querystring_encoded
36+
service = "execute-api"
37+
38+
# Uses boto logic for auth
39+
auth = BotoAWSRequestsAuth(
40+
aws_host=rest_api_id + ".execute-api." + region + ".amazonaws.com",
41+
aws_region=region,
42+
aws_service=service,
43+
)
44+
45+
response = getattr(requests, method.lower())(url, auth=auth)
46+
print("Request sent. Hope it worked :shrug:")
47+
48+
49+
def get_args_config() -> Dict:
50+
"""
51+
Get the configs passed as arguments
52+
"""
53+
parser = create_arg_parser()
54+
config = vars(parser.parse_args())
55+
return config
56+
57+
58+
def create_arg_parser() -> ArgumentParser:
59+
"""Parse the arguments"""
60+
parser = ArgumentParser()
61+
parser.add_argument(
62+
"--account", type=str, required=True, help="github account",
63+
)
64+
parser.add_argument(
65+
"--repository", type=str, required=True, help="github repository",
66+
)
67+
parser.add_argument(
68+
"--commit", type=str, required=True, help="commitish to monitor for",
69+
)
70+
parser.add_argument(
71+
"--rest-api-id", type=str, required=True, help="The AWS API Gateway REST API ID"
72+
)
73+
parser.add_argument(
74+
"--method", type=str.upper, default="GET", help="HTTP method to use",
75+
)
76+
return parser
77+
78+
79+
if __name__ == "__main__":
80+
main()

lambda_function.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,17 @@
88
from argparse import ArgumentParser
99
import requests
1010

11+
1112
def lambda_handler(event, context):
1213
"""
1314
AWS Lambda handler
1415
"""
15-
check_for_commit(account=event["account"], repository=event["repository"], commitish=event["commit"])
16+
print(event)
17+
check_for_commit(
18+
account=event["queryStringParameters"]["account"],
19+
repository=event["queryStringParameters"]["repository"],
20+
commitish=event["queryStringParameters"]["commit"],
21+
)
1622

1723

1824
def main():
@@ -21,25 +27,46 @@ def main():
2127
"""
2228
config = get_args_config()
2329

24-
check_for_commit(account=config["account"], repository=config["repository"], commitish=config["commit"])
30+
check_for_commit(
31+
account=config["account"],
32+
repository=config["repository"],
33+
commitish=config["commit"],
34+
)
2535

2636

2737
def check_for_commit(*, account: str, repository: str, commitish: str) -> bool:
2838
"""
2939
Check a provided account/repo for a commitish
3040
"""
31-
url = "https://api.github.com/repos/" + account + "/" + repository + "/releases/latest"
41+
url = (
42+
"https://api.github.com/repos/"
43+
+ account
44+
+ "/"
45+
+ repository
46+
+ "/releases/latest"
47+
)
3248
headers = {"Accept": "application/vnd.github.v3+json"}
3349

3450
response = requests.get(url, headers=headers)
3551
latest_release_json = response.json()
3652
try:
3753
latest_release_sha = latest_release_json["target_commitish"]
3854
except KeyError:
39-
print("Unable to identify the latest release commitish, are you being rate limited?")
55+
print(
56+
"Unable to identify the latest release commitish, are you being rate limited?"
57+
)
4058
sys.exit(1)
4159

42-
url = "https://api.github.com/repos/" + account + "/" + repository + "/compare/" + commitish + "..." + latest_release_sha
60+
url = (
61+
"https://api.github.com/repos/"
62+
+ account
63+
+ "/"
64+
+ repository
65+
+ "/compare/"
66+
+ commitish
67+
+ "..."
68+
+ latest_release_sha
69+
)
4370

4471
response = requests.get(url, headers=headers)
4572
github_status_json = response.json()
@@ -79,5 +106,6 @@ def create_arg_parser() -> ArgumentParser:
79106
)
80107
return parser
81108

109+
82110
if __name__ == "__main__":
83111
main()

requirements-to-freeze.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
requests
2+
aws-requests-auth
3+
botocore

requirements.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
aws-requests-auth==0.4.3
2+
botocore==1.17.46
13
certifi==2020.6.20
24
chardet==3.0.4
5+
docutils==0.15.2
36
idna==2.10
7+
jmespath==0.10.0
8+
python-dateutil==2.8.1
49
requests==2.24.0
10+
six==1.15.0
511
urllib3==1.25.10

0 commit comments

Comments
 (0)