majuna/app/tfstate.py

58 lines
2 KiB
Python
Raw Normal View History

import json
from flask import Blueprint, Response, request
2022-08-30 14:15:06 +01:00
from flask.typing import ResponseReturnValue
from app.extensions import db
from app.models.tfstate import TerraformState
tfstate = Blueprint("tfstate", __name__)
2024-12-06 18:15:47 +00:00
@tfstate.route("/<key>", methods=["GET"])
2022-08-30 14:15:06 +01:00
def handle_get(key: str) -> ResponseReturnValue:
state = TerraformState.query.filter(TerraformState.key == key).first()
if state is None or state.state is None:
return "Not Found", 404
return Response(state.state, content_type="application/json")
2024-12-06 18:15:47 +00:00
@tfstate.route("/<key>", methods=["POST", "DELETE", "UNLOCK"])
2022-08-30 14:15:06 +01:00
def handle_update(key: str) -> ResponseReturnValue:
state = TerraformState.query.filter(TerraformState.key == key).first()
if not state:
if request.method in ["DELETE", "UNLOCK"]:
return "OK", 200
state = TerraformState(key=key)
2024-12-06 18:15:47 +00:00
if state.lock and not (
request.method == "UNLOCK" and request.args.get("ID") is None
):
# force-unlock seems to not give an ID to verify so accept no ID being present
2024-12-06 18:15:47 +00:00
if json.loads(state.lock)["ID"] != request.args.get("ID"):
return Response(state.lock, status=409, content_type="application/json")
if request.method == "POST":
state.state = json.dumps(request.json)
elif request.method == "DELETE":
db.session.delete(state)
elif request.method == "UNLOCK":
state.lock = None
db.session.commit()
return "OK", 200
2024-12-06 18:15:47 +00:00
@tfstate.route("/<key>", methods=["LOCK"])
2022-08-30 14:15:06 +01:00
def handle_lock(key: str) -> ResponseReturnValue:
2024-12-06 18:15:47 +00:00
state = (
TerraformState.query.filter(TerraformState.key == key).with_for_update().first()
)
if state is None:
state = TerraformState(key=key, state="")
db.session.add(state)
if state.lock is not None:
lock = state.lock
db.session.rollback()
return Response(lock, status=423, content_type="application/json")
state.lock = json.dumps(request.json)
db.session.commit()
return "OK", 200