snapshot
This commit is contained in:
@@ -0,0 +1,336 @@
|
||||
import itertools
|
||||
import json
|
||||
import logging
|
||||
import pprint
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from urllib.parse import quote_plus
|
||||
|
||||
import boto3
|
||||
import httpx
|
||||
|
||||
import urllib.parse
|
||||
import subprocess
|
||||
import typing
|
||||
|
||||
|
||||
def list_repo_tags(*, repository_name: str, region: str, username: str, password: str) -> typing.List[dict]:
|
||||
"""
|
||||
Fetches the list of tags in a Codecommit repo using git ls-remote command
|
||||
|
||||
:returns: List of {tag, commit} items
|
||||
"""
|
||||
url = "https://{username}:{password}@git-codecommit.{region}.amazonaws.com/v1/repos/{repository_name}".format(
|
||||
username=quote_plus(username),
|
||||
password=quote_plus(password), # passwords are base64-encoded and might contain "/"
|
||||
region=region,
|
||||
repository_name=repository_name,
|
||||
)
|
||||
result = subprocess.run(["git", "ls-remote", "--refs", "--tags", url], text=True, stdout=subprocess.PIPE)
|
||||
|
||||
tags = []
|
||||
for line in result.stdout.splitlines(keepends=False):
|
||||
# lines are formatted as:
|
||||
# 070161940636bab5d934af2702f4248e5a13eb29 refs/tags/ui_sandbox_acc104
|
||||
# and columns are delimited with "\t"
|
||||
if "refs/tags/" in line:
|
||||
commit_hash, tag_ref = line.split("\t", maxsplit=1)
|
||||
tag = tag_ref.replace("refs/tags/", "")
|
||||
tags.append({"commit": commit_hash, "tag": tag})
|
||||
|
||||
# natural-sort by tag name
|
||||
# flora_prod_1 < ... < flora_prod_9 > flora_prod_10
|
||||
# vs lexical sort would give:
|
||||
# flora_prod_1 < flora_prod_10 < ... < flora_prod_9
|
||||
tags = sorted(tags, key=lambda t: [int(it) if it.isdigit() else it for it in re.split(r"(\d+)", t["tag"])])
|
||||
|
||||
return tags
|
||||
|
||||
|
||||
def chunk(it, size):
|
||||
it = iter(it)
|
||||
sentinel = ()
|
||||
return iter(lambda: tuple(itertools.islice(it, size)), sentinel)
|
||||
|
||||
|
||||
def summarize_tags(tags: list[dict], take: int = 10) -> list[dict]:
|
||||
re_prefix = re.compile(r"^(\D*)")
|
||||
re_digits = re.compile(r"(\d+)")
|
||||
grouped = defaultdict(list)
|
||||
for t in tags:
|
||||
tag_name = t["tag"]
|
||||
if m := re_prefix.search(tag_name):
|
||||
prefix = m.group(1)
|
||||
grouped[prefix].append(t)
|
||||
else:
|
||||
print("no match", m)
|
||||
flattened = [*grouped.pop("", [])]
|
||||
for g, items in grouped.items():
|
||||
sorted_items = sorted(
|
||||
items, key=lambda t: [int(it) if it.isdigit() else it for it in re_digits.split(t["tag"])], reverse=True
|
||||
)
|
||||
flattened.extend(sorted_items[:take])
|
||||
|
||||
return flattened
|
||||
|
||||
|
||||
abdus_creds = {
|
||||
"username": "coder+1-at-400344683105",
|
||||
"password": "4xdnGOtghKiT0M5CjulWf5raWwBSqT0Df2YkIY9Ws68=",
|
||||
}
|
||||
|
||||
|
||||
def get_commit_content():
|
||||
client = boto3.client("codecommit")
|
||||
|
||||
res = client.get_file(
|
||||
repositoryName="testing",
|
||||
filePath="content.txt1",
|
||||
commitSpecifier="vnext",
|
||||
)
|
||||
print(res)
|
||||
|
||||
|
||||
def main():
|
||||
import logging
|
||||
from botocore.endpoint import Endpoint
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
raw_make_request = Endpoint.make_request
|
||||
|
||||
def intercepted_make_request(*args, **kwargs):
|
||||
aws_response, parsed_response = raw_make_request(*args, **kwargs)
|
||||
logging.info('AWS response: %s', parsed_response)
|
||||
return aws_response, parsed_response
|
||||
|
||||
Endpoint.make_request = intercepted_make_request
|
||||
|
||||
session = boto3.Session(
|
||||
aws_access_key_id="AKIAQKZTNEVLBHDG5Q3X",
|
||||
aws_secret_access_key="Q7K9r45M9kh8bGqU8gIslAWIA1eaNo2M7w3xOZ6j",
|
||||
region_name="eu-central-1",
|
||||
)
|
||||
cc = session.client("rds")
|
||||
_ = cc.describe_db_clusters()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
exit()
|
||||
# get_commit_content()
|
||||
# flora b1cd47a221b84b2884b3d24198085a9f-f0dc2e747ff241649715c20d48232d8e
|
||||
# oms 36363cc2f43b4cf5b1965af9f8925a4d-6deff091ce2d4c2483d8834c532a6f36
|
||||
# omnitron 36363cc2f43b4cf5b1965af9f8925a4d-97400227a37940539c55489e1354ffc2
|
||||
all_tags = list_repo_tags(
|
||||
repository_name="b1cd47a221b84b2884b3d24198085a9f-f0dc2e747ff241649715c20d48232d8e",
|
||||
username="sandbox-acc-api-user-at-023193265494",
|
||||
password="sYPWKdhSx4JliXNI4ffRb4qWYBHLxA54nczSJ6CmYCY=",
|
||||
region="eu-central-1",
|
||||
)
|
||||
print(all_tags)
|
||||
exit(0)
|
||||
all_tags.append({"tag": "1asd", "commit": "asdf"})
|
||||
summarized = summarize_tags(all_tags, take=5)
|
||||
commits = {t["commit"] for t in summarized}
|
||||
session = boto3.Session(
|
||||
aws_access_key_id="AKIAQKZTNEVLBHDG5Q3X",
|
||||
aws_secret_access_key="Q7K9r45M9kh8bGqU8gIslAWIA1eaNo2M7w3xOZ6j",
|
||||
region_name="eu-central-1",
|
||||
)
|
||||
client = session.client("codecommit")
|
||||
|
||||
def get_commit_infos(commits: list[str]):
|
||||
res = client.batch_get_commits(
|
||||
repositoryName="36363cc2f43b4cf5b1965af9f8925a4d-97400227a37940539c55489e1354ffc2",
|
||||
commitIds=commits,
|
||||
)
|
||||
return res["commits"]
|
||||
|
||||
with ThreadPoolExecutor() as pool:
|
||||
results = list(pool.map(get_commit_infos, chunk(commits, 100)))
|
||||
|
||||
clone_ssh_url = repo["repositoryMetadata"]["cloneUrlSsh"]
|
||||
print(repo)
|
||||
exit(0)
|
||||
# exit()
|
||||
from botocore.awsrequest import AWSRequest
|
||||
from botocore.signers import RequestSigner
|
||||
|
||||
# AWS Version 4 signing example
|
||||
|
||||
# DynamoDB API (CreateTable)
|
||||
|
||||
# See: http://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html
|
||||
# This version makes a POST request and passes request parameters
|
||||
# in the body (payload) of the request. Auth information is passed in
|
||||
# an Authorization header.
|
||||
import sys, os, base64, datetime, hashlib, hmac
|
||||
import requests # pip install requests
|
||||
|
||||
# ************* REQUEST VALUES *************
|
||||
method = "POST"
|
||||
service = "codecommit"
|
||||
host = "codecommit.eu-central-1.amazonaws.com"
|
||||
region = "eu-central-1"
|
||||
endpoint = "https://codecommit.eu-central-1.amazonaws.com/"
|
||||
# POST requests use a content type header. For DynamoDB,
|
||||
# the content is JSON.
|
||||
content_type = "application/x-amz-json-1.1"
|
||||
# DynamoDB requires an x-amz-target header that has this format:
|
||||
# DynamoDB_<API version>.<operationName>
|
||||
amz_target = "CodeCommit_20150413.GetReferences"
|
||||
|
||||
# Request parameters for CreateTable--passed in a JSON block.
|
||||
request_body = {"repositoryName": "36363cc2f43b4cf5b1965af9f8925a4d-6deff091ce2d4c2483d8834c532a6f36"}
|
||||
request_parameters = json.dumps(request_body)
|
||||
|
||||
|
||||
# Key derivation functions. See:
|
||||
# http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-python
|
||||
def sign(key, msg):
|
||||
return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()
|
||||
|
||||
|
||||
def getSignatureKey(key, date_stamp, regionName, serviceName):
|
||||
kDate = sign(("AWS4" + key).encode("utf-8"), date_stamp)
|
||||
kRegion = sign(kDate, regionName)
|
||||
kService = sign(kRegion, serviceName)
|
||||
kSigning = sign(kService, "aws4_request")
|
||||
return kSigning
|
||||
|
||||
|
||||
# Read AWS access key from env. variables or configuration file. Best practice is NOT
|
||||
# to embed credentials in code.
|
||||
access_key = os.environ.get("AWS_ACCESS_KEY_ID", "AKIAQKZTNEVLBHDG5Q3X")
|
||||
secret_key = os.environ.get("AWS_SECRET_ACCESS_KEY", "Q7K9r45M9kh8bGqU8gIslAWIA1eaNo2M7w3xOZ6j")
|
||||
if access_key is None or secret_key is None:
|
||||
print("No access key is available.")
|
||||
sys.exit()
|
||||
|
||||
# Create a date for headers and the credential string
|
||||
t = datetime.datetime.utcnow()
|
||||
amz_date = t.strftime("%Y%m%dT%H%M%SZ")
|
||||
date_stamp = t.strftime("%Y%m%d") # Date w/o time, used in credential scope
|
||||
|
||||
# ************* TASK 1: CREATE A CANONICAL REQUEST *************
|
||||
# http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
|
||||
|
||||
# Step 1 is to define the verb (GET, POST, etc.)--already done.
|
||||
|
||||
# Step 2: Create canonical URI--the part of the URI from domain to query
|
||||
# string (use '/' if no path)
|
||||
canonical_uri = "/"
|
||||
|
||||
## Step 3: Create the canonical query string. In this example, request
|
||||
# parameters are passed in the body of the request and the query string
|
||||
# is blank.
|
||||
canonical_querystring = ""
|
||||
|
||||
# Step 4: Create the canonical headers. Header names must be trimmed
|
||||
# and lowercase, and sorted in code point order from low to high.
|
||||
# Note that there is a trailing \n.
|
||||
canonical_headers = (
|
||||
"content-type:"
|
||||
+ content_type
|
||||
+ "\n"
|
||||
+ "host:"
|
||||
+ host
|
||||
+ "\n"
|
||||
+ "x-amz-date:"
|
||||
+ amz_date
|
||||
+ "\n"
|
||||
+ "x-amz-target:"
|
||||
+ amz_target
|
||||
+ "\n"
|
||||
)
|
||||
|
||||
# Step 5: Create the list of signed headers. This lists the headers
|
||||
# in the canonical_headers list, delimited with ";" and in alpha order.
|
||||
# Note: The request can include any headers; canonical_headers and
|
||||
# signed_headers include those that you want to be included in the
|
||||
# hash of the request. "Host" and "x-amz-date" are always required.
|
||||
# For DynamoDB, content-type and x-amz-target are also required.
|
||||
signed_headers = "content-type;host;x-amz-date;x-amz-target"
|
||||
|
||||
# Step 6: Create payload hash. In this example, the payload (body of
|
||||
# the request) contains the request parameters.
|
||||
payload_hash = hashlib.sha256(request_parameters.encode("utf-8")).hexdigest()
|
||||
|
||||
# Step 7: Combine elements to create canonical request
|
||||
canonical_request = (
|
||||
method
|
||||
+ "\n"
|
||||
+ canonical_uri
|
||||
+ "\n"
|
||||
+ canonical_querystring
|
||||
+ "\n"
|
||||
+ canonical_headers
|
||||
+ "\n"
|
||||
+ signed_headers
|
||||
+ "\n"
|
||||
+ payload_hash
|
||||
)
|
||||
|
||||
# ************* TASK 2: CREATE THE STRING TO SIGN*************
|
||||
# Match the algorithm to the hashing algorithm you use, either SHA-1 or
|
||||
# SHA-256 (recommended)
|
||||
algorithm = "AWS4-HMAC-SHA256"
|
||||
credential_scope = date_stamp + "/" + region + "/" + service + "/" + "aws4_request"
|
||||
string_to_sign = (
|
||||
algorithm
|
||||
+ "\n"
|
||||
+ amz_date
|
||||
+ "\n"
|
||||
+ credential_scope
|
||||
+ "\n"
|
||||
+ hashlib.sha256(canonical_request.encode("utf-8")).hexdigest()
|
||||
)
|
||||
|
||||
# ************* TASK 3: CALCULATE THE SIGNATURE *************
|
||||
# Create the signing key using the function defined above.
|
||||
signing_key = getSignatureKey(secret_key, date_stamp, region, service)
|
||||
|
||||
# Sign the string_to_sign using the signing_key
|
||||
signature = hmac.new(signing_key, (string_to_sign).encode("utf-8"), hashlib.sha256).hexdigest()
|
||||
|
||||
# ************* TASK 4: ADD SIGNING INFORMATION TO THE REQUEST *************
|
||||
# Put the signature information in a header named Authorization.
|
||||
authorization_header = (
|
||||
algorithm
|
||||
+ " "
|
||||
+ "Credential="
|
||||
+ access_key
|
||||
+ "/"
|
||||
+ credential_scope
|
||||
+ ", "
|
||||
+ "SignedHeaders="
|
||||
+ signed_headers
|
||||
+ ", "
|
||||
+ "Signature="
|
||||
+ signature
|
||||
)
|
||||
|
||||
# For DynamoDB, the request can include any headers, but MUST include "host", "x-amz-date",
|
||||
# "x-amz-target", "content-type", and "Authorization". Except for the authorization
|
||||
# header, the headers must be included in the canonical_headers and signed_headers values, as
|
||||
# noted earlier. Order here is not significant.
|
||||
# # Python note: The 'host' header is added automatically by the Python 'requests' library.
|
||||
headers = {
|
||||
"User-Agent": "aws-sdk-js/2.627.0 promise",
|
||||
"Content-Type": content_type,
|
||||
"X-Amz-Date": amz_date,
|
||||
"X-Amz-Target": amz_target,
|
||||
"Authorization": authorization_header,
|
||||
}
|
||||
|
||||
# ************* SEND THE REQUEST *************
|
||||
print("\nBEGIN REQUEST++++++++++++++++++++++++++++++++++++")
|
||||
print("Request URL = " + endpoint)
|
||||
|
||||
r = httpx.post(endpoint, json=request_body, headers=headers)
|
||||
|
||||
print("\nRESPONSE++++++++++++++++++++++++++++++++++++")
|
||||
print("Response code: %d\n" % r.status_code)
|
||||
print(r.text)
|
||||
Reference in New Issue
Block a user