FastAPI开发运维模板

发布时间 2023-03-28 15:58:30作者: 小维江湖

main.py

from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
import os


app = FastAPI()


class K8sData(BaseModel):
    operation: Optional[str] = "clean_pvc"
    namespaces: Optional[str] = "test"
    storage: Optional[str] = "nfs-client"
    re: Optional[str] = "test"
    size: Optional[int] = 100

class Aliyun(BaseModel):
    operation: Optional[str] = "poweroff"


@app.get("/healthz")
def read_root():
    return {"ok"}


@app.post("/api/v1/k8s")
def read_item(data:  K8sData):
    if data.operation == "clean_pvc":
        return {"namespaces": data.namespaces, "operation": data.operation, "status": "OK", "result": clean_pvc(data.namespaces, data.storage, data.re, data.size)}


def clean_pvc(namespaces, storage, re, size):
    # shell = os.path.abspath(os.path.join(os.getcwd(), "clean_pvc.sh"))
    shell = "clean_pvc.sh"
    cmd = "bash {shell} {namespaces} {storage} {re} {size}".format(
        shell=shell, namespaces=namespaces, storage=storage, re=re, size=size)
    return os.popen(cmd).read()


@app.post("/api/v1/aliyun")
def read_item(data:  Aliyun):
    if data.operation == "poweroff":
        return {"operation": data.operation, "status": "OK", "result": ""}


def aliyun():
    pass

requirements.txt

anyio==3.6.1
asgiref==3.5.2
click==8.1.3
fastapi==0.78.0
h11==0.13.0
httptools==0.4.0
idna==3.3
pydantic==1.9.1
python-dotenv==0.20.0
PyYAML==6.0
sniffio==1.2.0
starlette==0.19.1
typing_extensions==4.2.0
uvicorn==0.17.6
uvloop==0.16.0
watchgod==0.8.2
websockets==10.3

Dockerfile

FROM python:3.10.5-slim-buster


WORKDIR /home/app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt -i https://mirrors.cloud.tencent.com/pypi/simple && \
    useradd -s /bin/bash -m app && \
    rm -f requirements.txt

USER app

COPY --chown=app:app bin/* /usr/local/bin/
COPY main.py .

ENTRYPOINT ["entrypoint.sh"]

CMD ["start"]

bin/entrypoint.sh

#!/bin/bash

set -e

if [ ! -v PORT ]; then
    PORT="8000"
fi

if [ ! -v HOST ]; then
    HOST='0.0.0.0'
fi

ARGS=()

function check_config() {
    param="$1"
    value="$2"
    ARGS+=("--${param}")
    ARGS+=("${value}")
}

check_config "host" "$HOST"
check_config "port" "$PORT"

case "$1" in
start)
    exec uvicorn main:app "${ARGS[@]}" --reload
    ;;
-*)
    exec uvicorn main:app "$@" "${ARGS[@]}" --reload
    ;;
*)
    exec "$@"
    ;;
esac

exit 1

bin/clean_pvc.sh

#!/bin/bash

set -e

export KUBECONFIG=/app/config

namespaces="$1"
storage="$2"
#storage="nfs-client"
re="$3"
#re="node"
size=$4
#sizr=100

kubectl get ns "${namespaces}" && arr=($(kubectl get deploy -n "${namespaces}" --no-headers | grep -P "${re}" | cut -d' ' -f1))

for element in ${arr[@]}; do
  replicas=$(kubectl get deployments.apps -n "${namespaces}" "${element}" --no-headers -o custom-columns=replicas:.status.replicas)
  kubectl scale deployment -n "${namespaces}" "${element}" --replicas=0
  claimName=$(kubectl get deploy -n "${namespaces}" --no-headers ${element} -o custom-columns=claimName:.spec.template.spec.volumes[*].persistentVolumeClaim.claimName)
  kubectl delete pvc -n "${namespaces}" "${claimName}"

  echo "apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: "${claimName}"
  namespace: "${namespaces}"
spec:
  storageClassName: "${storage}"
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: ${size}Gi" | kubectl create -f -

  kubectl scale deployment -n "${namespaces}" "${element}" --replicas=${replicas}
done

bin/kubectl 根据实际的k8s版本下载对应的文件即可