Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Publish flask #42

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Publish to GHCR
name: Publish tmp to GHCR

env:
RELEASE: edge
Expand All @@ -8,10 +8,7 @@ concurrency:
cancel-in-progress: true

on:
push:
branches:
- 6-22.04
workflow_dispatch:
pull_request:

jobs:
build:
Expand Down Expand Up @@ -63,12 +60,13 @@ jobs:

# push major version to edge
major_tag_version="${version%%.*}-${{ env.RELEASE }}"

sudo skopeo \
--insecure-policy \
copy \
oci-archive:charmed-mongodb_${full_version}_amd64.rock \
docker-daemon:ghcr.io/canonical/charmed-mongodb:${major_tag_version}
docker push ghcr.io/canonical/charmed-mongodb:${major_tag_version}
docker-daemon:ghcr.io/miaaltieri/charmed-mongodb:${major_tag_version}
docker push ghcr.io/miaaltieri/charmed-mongodb:${major_tag_version}

### push full version to edge
tag_version="${version}-${base}_${{ env.RELEASE }}"
Expand All @@ -77,5 +75,5 @@ jobs:
--insecure-policy \
copy \
oci-archive:charmed-mongodb_${full_version}_amd64.rock \
docker-daemon:ghcr.io/canonical/charmed-mongodb:${tag_version}
docker push ghcr.io/canonical/charmed-mongodb:${tag_version}
docker-daemon:ghcr.io/miaaltieri/charmed-mongodb:${tag_version}
docker push ghcr.io/miaaltieri/charmed-mongodb:${tag_version}
119 changes: 119 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Copyright 2024 Canonical Ltd.
# See LICENSE file for licensing details.
from typing import Any
from flask import Flask, request, jsonify
import logging
import base64
from pydantic import BaseModel, TypeAdapter
import os

# Default to 1 year
YEAR = 31_556_952
GRACE_PERIOD: int = int(os.getenv("GRACE_PERIOD_SECONDS", YEAR))


class Patch(BaseModel):
op: str
path: str = "/spec/template/spec/terminationGracePeriodSeconds"
value: int


app = Flask(__name__)

webhook = logging.getLogger(__name__)
webhook.setLevel(logging.INFO)
logging.basicConfig(format="[%(asctime)s] %(levelname)s: %(message)s")

ADAPTER = TypeAdapter(list[Patch])


def patch_termination(existing_value: bool) -> str:
op = "replace" if existing_value else "add"
webhook.info(f"Updating terminationGracePeriodSeconds, replacing it ({op = })")
patch_operations = [
Patch(
op=op,
value=GRACE_PERIOD,
)
]
return base64.b64encode(ADAPTER.dump_json(patch_operations)).decode()


def admission_review(uid: str, message: str, existing_value: bool) -> dict:
print("admission_review - existing_value", existing_value)
if existing_value:
return {
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"response": {
"uid": uid,
"allowed": True,
"patchType": "JSONPatch",
"status": {"message": message},
"patch": patch_termination(existing_value),
},
}
return {
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"response": {
"uid": uid,
"allowed": True,
"status": {"message": "No value provided, continue."},
},
}


def admission_validation(uid: str, current_value: int | None):
if not current_value or current_value > 30:
print("current value", current_value)
return {
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"response": {
"uid": uid,
"allowed": True,
"status": {"message": f"Valid value has been provided ({current_value})"},
},
}
return {
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"response": {
"uid": uid,
"allowed": False,
"status": {
"code": 403,
"message": f"Termination period lower than 30s is not allowed (given {current_value})",
},
},
}


@app.route("/mutate", methods=["POST"])
def mutate_request():
req = request.get_json()
uid = req["request"]["uid"]
selector = req["request"]["object"]["spec"]["template"]["spec"]

return jsonify(
admission_review(
uid,
"Successfully updated terminationGracePeriodSeconds.",
True if "terminationGracePeriodSeconds" in selector else False,
)
)


@app.route("/validate", methods=["POST"])
def validate_request():
req = request.get_json()
uid = req["request"]["uid"]
selector = req["request"]["object"]["spec"]["template"]["spec"]
period_value = selector.get("terminationGracePeriodSeconds")

return jsonify(admission_validation(uid, period_value))


if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
5 changes: 5 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright 2024 Canonical Ltd.
# See LICENSE file for licensing details.
pydantic>=2.0,<3.0
uvicorn
flask
Loading