2021-09-28 11:52:51 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import requests
|
|
|
|
import argparse
|
|
|
|
import jwt
|
|
|
|
import sys
|
|
|
|
import json
|
|
|
|
import time
|
|
|
|
|
2022-03-22 16:39:58 +00:00
|
|
|
|
2021-09-28 11:52:51 +00:00
|
|
|
def get_installation_id(jwt_token):
|
|
|
|
headers = {
|
|
|
|
"Authorization": f"Bearer {jwt_token}",
|
|
|
|
"Accept": "application/vnd.github.v3+json",
|
|
|
|
}
|
|
|
|
response = requests.get("https://api.github.com/app/installations", headers=headers)
|
|
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
2022-03-22 16:39:58 +00:00
|
|
|
return data[0]["id"]
|
|
|
|
|
2021-09-28 11:52:51 +00:00
|
|
|
|
|
|
|
def get_access_token(jwt_token, installation_id):
|
|
|
|
headers = {
|
|
|
|
"Authorization": f"Bearer {jwt_token}",
|
|
|
|
"Accept": "application/vnd.github.v3+json",
|
|
|
|
}
|
2022-03-22 16:39:58 +00:00
|
|
|
response = requests.post(
|
|
|
|
f"https://api.github.com/app/installations/{installation_id}/access_tokens",
|
|
|
|
headers=headers,
|
|
|
|
)
|
2021-09-28 11:52:51 +00:00
|
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
2022-03-22 16:39:58 +00:00
|
|
|
return data["token"]
|
|
|
|
|
2021-09-28 11:52:51 +00:00
|
|
|
|
|
|
|
def get_runner_registration_token(access_token):
|
|
|
|
headers = {
|
|
|
|
"Authorization": f"token {access_token}",
|
|
|
|
"Accept": "application/vnd.github.v3+json",
|
|
|
|
}
|
2022-03-22 16:39:58 +00:00
|
|
|
response = requests.post(
|
|
|
|
"https://api.github.com/orgs/ClickHouse/actions/runners/registration-token",
|
|
|
|
headers=headers,
|
|
|
|
)
|
2021-09-28 11:52:51 +00:00
|
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
2022-03-22 16:39:58 +00:00
|
|
|
return data["token"]
|
|
|
|
|
2021-09-28 11:52:51 +00:00
|
|
|
|
|
|
|
def get_key_and_app_from_aws():
|
|
|
|
import boto3
|
2022-03-22 16:39:58 +00:00
|
|
|
|
2021-10-19 19:39:55 +00:00
|
|
|
secret_name = "clickhouse_github_secret_key"
|
2021-09-28 11:52:51 +00:00
|
|
|
session = boto3.session.Session()
|
|
|
|
client = session.client(
|
2022-03-22 16:39:58 +00:00
|
|
|
service_name="secretsmanager",
|
2021-09-28 11:52:51 +00:00
|
|
|
)
|
2022-03-22 16:39:58 +00:00
|
|
|
get_secret_value_response = client.get_secret_value(SecretId=secret_name)
|
|
|
|
data = json.loads(get_secret_value_response["SecretString"])
|
|
|
|
return data["clickhouse-app-key"], int(data["clickhouse-app-id"])
|
2021-09-28 11:52:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
def main(github_secret_key, github_app_id, push_to_ssm, ssm_parameter_name):
|
|
|
|
payload = {
|
|
|
|
"iat": int(time.time()) - 60,
|
|
|
|
"exp": int(time.time()) + (10 * 60),
|
|
|
|
"iss": github_app_id,
|
|
|
|
}
|
|
|
|
|
|
|
|
encoded_jwt = jwt.encode(payload, github_secret_key, algorithm="RS256")
|
|
|
|
installation_id = get_installation_id(encoded_jwt)
|
|
|
|
access_token = get_access_token(encoded_jwt, installation_id)
|
|
|
|
runner_registration_token = get_runner_registration_token(access_token)
|
|
|
|
|
|
|
|
if push_to_ssm:
|
|
|
|
import boto3
|
|
|
|
|
|
|
|
print("Trying to put params into ssm manager")
|
2022-03-22 16:39:58 +00:00
|
|
|
client = boto3.client("ssm")
|
2021-09-28 11:52:51 +00:00
|
|
|
client.put_parameter(
|
|
|
|
Name=ssm_parameter_name,
|
|
|
|
Value=runner_registration_token,
|
2022-03-22 16:39:58 +00:00
|
|
|
Type="SecureString",
|
|
|
|
Overwrite=True,
|
|
|
|
)
|
2021-09-28 11:52:51 +00:00
|
|
|
else:
|
2022-03-22 16:39:58 +00:00
|
|
|
print(
|
|
|
|
"Not push token to AWS Parameter Store, just print:",
|
|
|
|
runner_registration_token,
|
|
|
|
)
|
2021-09-28 11:52:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
def handler(event, context):
|
|
|
|
private_key, app_id = get_key_and_app_from_aws()
|
2022-03-22 16:39:58 +00:00
|
|
|
main(private_key, app_id, True, "github_runner_registration_token")
|
|
|
|
|
2021-09-28 11:52:51 +00:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2022-03-22 16:39:58 +00:00
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
description="Get new token from github to add runners"
|
|
|
|
)
|
|
|
|
parser.add_argument(
|
|
|
|
"-p", "--private-key-path", help="Path to file with private key"
|
|
|
|
)
|
|
|
|
parser.add_argument("-k", "--private-key", help="Private key")
|
|
|
|
parser.add_argument(
|
|
|
|
"-a", "--app-id", type=int, help="GitHub application ID", required=True
|
|
|
|
)
|
|
|
|
parser.add_argument(
|
|
|
|
"--push-to-ssm",
|
|
|
|
action="store_true",
|
|
|
|
help="Store received token in parameter store",
|
|
|
|
)
|
|
|
|
parser.add_argument(
|
|
|
|
"--ssm-parameter-name",
|
|
|
|
default="github_runner_registration_token",
|
|
|
|
help="AWS paramater store parameter name",
|
|
|
|
)
|
2021-09-28 11:52:51 +00:00
|
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
if not args.private_key_path and not args.private_key:
|
2022-03-22 16:39:58 +00:00
|
|
|
print(
|
|
|
|
"Either --private-key-path or --private-key must be specified",
|
|
|
|
file=sys.stderr,
|
|
|
|
)
|
2021-09-28 11:52:51 +00:00
|
|
|
|
|
|
|
if args.private_key_path and args.private_key:
|
2022-03-22 16:39:58 +00:00
|
|
|
print(
|
|
|
|
"Either --private-key-path or --private-key must be specified",
|
|
|
|
file=sys.stderr,
|
|
|
|
)
|
2021-09-28 11:52:51 +00:00
|
|
|
|
|
|
|
if args.private_key:
|
|
|
|
private_key = args.private_key
|
|
|
|
else:
|
2022-03-22 16:39:58 +00:00
|
|
|
with open(args.private_key_path, "r") as key_file:
|
2021-09-28 11:52:51 +00:00
|
|
|
private_key = key_file.read()
|
|
|
|
|
|
|
|
main(private_key, args.app_id, args.push_to_ssm, args.ssm_parameter_name)
|