Skip to content

Commit

Permalink
🎨 some code cleanup (#10)
Browse files Browse the repository at this point in the history
* ♻️ refactor time_since function and add tests

* 🐛 fix timezone awareness

* ♻️ refactor our filter, conversion, and label checks

* ♻️ refactor objects into functions for creation

* ♻️ major refactor of naming and exception handling

* 🐛 only fetch logs once

* ♻️ refactor namespace view

* ❇️ type hinting

* 🔥 unused import

* 🎨 formatting
  • Loading branch information
mshade authored Sep 11, 2023
1 parent ca05150 commit f758950
Show file tree
Hide file tree
Showing 5 changed files with 485 additions and 242 deletions.
145 changes: 65 additions & 80 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,86 +4,76 @@
import yaml

from kron import (
getCronJobs,
getNamespaces,
getJobs,
getJobsAndPods,
getCronJob,
getPods,
getPodLogs,
toggleCronJob,
triggerCronJob,
updateCronJob,
deleteCronJob,
deleteJob,
get_cronjobs,
get_jobs,
get_jobs_and_pods,
get_cronjob,
get_pods,
get_pod_logs,
toggle_cronjob_suspend,
trigger_cronjob,
update_cronjob,
delete_cronjob,
delete_job,
)

app = Flask(__name__, static_url_path="", static_folder="static")


def _strip_immutable_fields(spec):
try:
del spec["status"]
except KeyError:
pass

try:
del spec["metadata"]["uid"]
except KeyError:
pass
spec.pop("status", None)
metadata = spec.get("metadata", {})
metadata.pop("uid", None)
metadata.pop("resourceVersion", None)
return spec

try:
del spec["metadata"]["resourceVersion"]
except KeyError:
pass

return spec
@app.route("/healthz")
def healthz():
return {"status": "ok"}


@app.route("/")
def index():
cronjobs = getCronJobs()
cronjobs = get_cronjobs()
namespaces = {}
# Count cronjobs per namespace
for cronjob in cronjobs:
namespaces[cronjob["namespace"]] = namespaces.get(cronjob["namespace"], 0) + 1

return render_template("index.html", namespaces=namespaces)

@app.route("/healthz")
def healthz():
return {"status": "ok"}

@app.route("/namespaces/<name>")
def namespaceView(name):
cronjob_names = getCronJobs(name)
cronjobs = [
getCronJob(namespace=name, cronjob_name=cronjob["name"])
for cronjob in cronjob_names
]
for cron in cronjobs:
jobs = getJobs(namespace=name, cronjob_name=cron["metadata"]["name"])
cron["jobs"] = jobs
for job in cron["jobs"]:
job["pods"] = getPods(
cron["metadata"]["namespace"], job["metadata"]["name"]
)
@app.route("/namespaces/<namespace>")
def view_namespace(namespace):
cronjobs = get_cronjobs(namespace)
cronjobs_with_details = []

return render_template("namespace.html", cronjobs=cronjobs, namespace=name)
for cronjob in cronjobs:
cronjob_detail = get_cronjob(namespace, cronjob["name"])
jobs = get_jobs(namespace=namespace, cronjob_name=cronjob["name"])
for job in jobs:
job["pods"] = get_pods(namespace, job["metadata"]["name"])
cronjob_detail["jobs"] = jobs
cronjobs_with_details.append(cronjob_detail)

return render_template(
"namespace.html", cronjobs=cronjobs_with_details, namespace=namespace
)


@app.route("/namespaces/<namespace>/cronjobs/<cronjob_name>", methods=["GET", "POST"])
def cronjobView(namespace, cronjob_name):
def view_cronjob(namespace, cronjob_name):
if request.method == "POST":
edited_cronjob = yaml.safe_load(request.form["yaml"])
cronjob = updateCronJob(namespace, edited_cronjob)
cronjob = update_cronjob(namespace, edited_cronjob)
if cronjob["metadata"]["name"] != cronjob_name:
return redirect(
f"/namespaces/{namespace}/cronjobs/{cronjob['metadata']['name']}",
code=302,
)
else:
cronjob = getCronJob(namespace, cronjob_name)
cronjob = get_cronjob(namespace, cronjob_name)

if cronjob:
cronjob = _strip_immutable_fields(cronjob)
Expand All @@ -100,80 +90,75 @@ def cronjobView(namespace, cronjob_name):


@app.route("/api/")
def apiAllCronJobs():
jobs = getCronJobs()
def api_index():
# Return all cronjobs
jobs = get_cronjobs()
return jobs


@app.route("/api/namespaces/")
def apiNamespaces():
namespaces = getNamespaces()
return namespaces


@app.route("/api/namespaces/<namespace>/cronjobs")
@app.route("/api/namespaces/<namespace>")
def apiNamespaceCronjobs(namespace):
cronjobs = getCronJobs(namespace)
def api_namespace(namespace):
cronjobs = get_cronjobs(namespace)
return cronjobs


@app.route("/api/namespaces/<namespace>/cronjobs/<cronjob_name>")
def apiGetCronJob(namespace, cronjob_name):
cronjob = getCronJob(namespace, cronjob_name)
def api_get_cronjob(namespace, cronjob_name):
cronjob = get_cronjob(namespace, cronjob_name)
return cronjob


@app.route(
"/api/namespaces/<namespace>/cronjobs/<cronjob_name>/clone", methods=["POST"]
)
def apiCloneCronJob(namespace, cronjob_name):
cronjob_spec = getCronJob(namespace, cronjob_name)
def api_clone_cronjob(namespace, cronjob_name):
cronjob_spec = get_cronjob(namespace, cronjob_name)
new_name = request.json["name"]
cronjob_spec["metadata"]["name"] = new_name
cronjob_spec["spec"]["jobTemplate"]["metadata"]["name"] = new_name
cronjob_spec = _strip_immutable_fields(cronjob_spec)
print(cronjob_spec)
cronjob = updateCronJob(namespace, cronjob_spec)
cronjob = update_cronjob(namespace, cronjob_spec)
return cronjob


@app.route("/api/namespaces/<namespace>/cronjobs/create", methods=["POST"])
def apiCreateCronJob(namespace):
def api_create_cronjob(namespace):
cronjob_spec = request.json["data"]
cronjob = updateCronJob(namespace, cronjob_spec)
cronjob = update_cronjob(namespace, cronjob_spec)
return cronjob


@app.route(
"/api/namespaces/<namespace>/cronjobs/<cronjob_name>/delete", methods=["POST"]
)
def apiDeleteCronJob(namespace, cronjob_name):
deleted = deleteCronJob(namespace, cronjob_name)
def api_delete_cronjob(namespace, cronjob_name):
deleted = delete_cronjob(namespace, cronjob_name)
return deleted


@app.route(
"/api/namespaces/<namespace>/cronjobs/<cronjob_name>/suspend",
methods=["GET", "POST"],
)
def apiToggleSuspended(namespace, cronjob_name):
def api_toggle_cronjob_suspend(namespace, cronjob_name):
if request.method == "GET":
"""Return the suspended status of the <cronjob_name>"""
cronjob = getCronJob(namespace, cronjob_name)
cronjob = get_cronjob(namespace, cronjob_name)
return cronjob
if request.method == "POST":
"""Toggle the suspended status of <cronjob_name>"""
cronjob = toggleCronJob(namespace, cronjob_name)
cronjob = toggle_cronjob_suspend(namespace, cronjob_name)
return cronjob


@app.route(
"/api/namespaces/<namespace>/cronjobs/<cronjob_name>/trigger", methods=["POST"]
)
def apiTriggerJob(namespace, cronjob_name):
def api_trigger_cronjob(namespace, cronjob_name):
"""Manually trigger a job from <cronjob_name>"""
cronjob = triggerCronJob(namespace, cronjob_name)
cronjob = trigger_cronjob(namespace, cronjob_name)
status = 200
if "error" in cronjob:
status = cronjob["error"]
Expand All @@ -182,24 +167,24 @@ def apiTriggerJob(namespace, cronjob_name):


@app.route("/api/namespaces/<namespace>/cronjobs/<cronjob_name>/getJobs")
def apiGetJobs(namespace, cronjob_name):
jobs = getJobsAndPods(namespace, cronjob_name)
def api_get_jobs(namespace, cronjob_name):
jobs = get_jobs_and_pods(namespace, cronjob_name)
return jobs


@app.route("/api/namespaces/<namespace>/pods")
def apiGetPods(namespace):
pods = getPods(namespace)
def api_get_pods(namespace):
pods = get_pods(namespace)
return pods


@app.route("/api/namespaces/<namespace>/pods/<pod_name>/logs")
def apiGetPodLogs(namespace, pod_name):
logs = getPodLogs(namespace, pod_name)
def api_get_pod_logs(namespace, pod_name):
logs = get_pod_logs(namespace, pod_name)
return logs


@app.route("/api/namespaces/<namespace>/jobs/<job_name>/delete", methods=["POST"])
def apiDeleteJob(namespace, job_name):
deleted = deleteJob(namespace, job_name)
def api_delete_job(namespace, job_name):
deleted = delete_job(namespace, job_name)
return deleted
Loading

0 comments on commit f758950

Please sign in to comment.