begin work on autodeployer
This commit is contained in:
parent
69dcc3e1af
commit
ff115f79aa
7 changed files with 231 additions and 0 deletions
22
.forgejo/workflows/build-deployer.yaml
Normal file
22
.forgejo/workflows/build-deployer.yaml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- containers/deployer/**
|
||||||
|
- .forgejo/workflows/build-deployer.yaml
|
||||||
|
jobs:
|
||||||
|
build-deployer:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: library/docker:dind
|
||||||
|
steps:
|
||||||
|
- run: apk add --no-cache nodejs git
|
||||||
|
- name: login to container registry
|
||||||
|
run: echo "${{ secrets.DEPLOY_SECRET }}" | docker login --username ${{ secrets.DEPLOY_USER }} --password-stdin git.janky.solutions
|
||||||
|
- name: build container image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
file: Containerfile
|
||||||
|
context: "{{defaultContext}}:containers/deployer"
|
||||||
|
tags: git.janky.solutions/jankysolutions/infra/deployer:latest
|
||||||
|
platforms: linux/amd64
|
||||||
|
push: true
|
37
.forgejo/workflows/k8s-diff-and-deploy.yaml
Normal file
37
.forgejo/workflows/k8s-diff-and-deploy.yaml
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- k8s/**
|
||||||
|
- .forgejo/workflows/k8s-diff-and-deploy.yaml
|
||||||
|
jobs:
|
||||||
|
diff-and-deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: git.devhack.net/devhack/containers/deployer:latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: kubectl diff and deploy
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
echo "${{ secrets.KUBERNETES_CLIENT_CONFIG }}" > ~/.kube/config
|
||||||
|
|
||||||
|
for component in k8s/*; do
|
||||||
|
if [ ! -d "${component}" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
touch "${component}/secrets.yaml"
|
||||||
|
|
||||||
|
echo "👀 $ kubectl diff -k ${component}"
|
||||||
|
kubectl diff -k "${component}" || echo
|
||||||
|
|
||||||
|
# if [[ "${GITHUB_REF_NAME}" == "main" ]]; then
|
||||||
|
# echo "🚀 $ kubectl apply -k ${component}"
|
||||||
|
# if [[ "${component}" == "k8s/operators" ]]; then
|
||||||
|
# kubectl apply -k "${component}" --server-side
|
||||||
|
# else
|
||||||
|
# kubectl apply -k "${component}"
|
||||||
|
# fi
|
||||||
|
# echo
|
||||||
|
# fi
|
||||||
|
done
|
3
containers/deployer/Containerfile
Normal file
3
containers/deployer/Containerfile
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
FROM library/alpine:3.20
|
||||||
|
RUN apk add --no-cache nodejs git bash helm kubectl
|
||||||
|
RUN mkdir -p ~/.kube
|
62
k8s/forgejo/forgejo-secret-sync.yaml
Normal file
62
k8s/forgejo/forgejo-secret-sync.yaml
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: CronJob
|
||||||
|
metadata:
|
||||||
|
name: forgejo-secret-sync
|
||||||
|
spec:
|
||||||
|
schedule: "0 0 * * *"
|
||||||
|
jobTemplate:
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: secret-sync
|
||||||
|
image: library/python:3
|
||||||
|
command:
|
||||||
|
- bash
|
||||||
|
- -c
|
||||||
|
- pip install requests && python /code/forgejo-secret-sync.py
|
||||||
|
env:
|
||||||
|
- name: REPO_MAPPINGS
|
||||||
|
value: |
|
||||||
|
[
|
||||||
|
{"k8s_name": "infra-deployer", "owner": "JankySolutions", "repo": "infra"}
|
||||||
|
]
|
||||||
|
envFrom:
|
||||||
|
- secretRef:
|
||||||
|
name: forgejo-secret-sync
|
||||||
|
volumeMounts:
|
||||||
|
- name: code
|
||||||
|
mountPath: /code
|
||||||
|
- name: host-tls
|
||||||
|
mountPath: /var/lib/rancher/k3s/server/tls
|
||||||
|
restartPolicy: OnFailure
|
||||||
|
affinity:
|
||||||
|
nodeAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
nodeSelectorTerms:
|
||||||
|
- matchExpressions:
|
||||||
|
- key: node-role.kubernetes.io/control-plane
|
||||||
|
operator: In
|
||||||
|
values: ["true"]
|
||||||
|
volumes:
|
||||||
|
- name: code
|
||||||
|
configMap:
|
||||||
|
name: forgejo-secret-sync
|
||||||
|
- name: host-tls
|
||||||
|
hostPath:
|
||||||
|
path: /var/lib/rancher/k3s/server/tls
|
||||||
|
---
|
||||||
|
apiVersion: external-secrets.io/v1beta1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: forgejo-secret-sync
|
||||||
|
spec:
|
||||||
|
secretStoreRef:
|
||||||
|
kind: SecretStore
|
||||||
|
name: openbao
|
||||||
|
target:
|
||||||
|
name: forgejo-secret-sync
|
||||||
|
creationPolicy: Owner
|
||||||
|
dataFrom:
|
||||||
|
- extract:
|
||||||
|
key: forgejo/default/secret-sync
|
86
k8s/forgejo/forgejo-secret-sync/forgejo-secret-sync.py
Normal file
86
k8s/forgejo/forgejo-secret-sync/forgejo-secret-sync.py
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import subprocess
|
||||||
|
import logging
|
||||||
|
import base64
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
|
with open("/var/lib/rancher/k3s/server/tls/server-ca.crt") as f:
|
||||||
|
ca = base64.b64encode(f.read().encode()).decode()
|
||||||
|
|
||||||
|
forgejo_token = os.getenv("FORGEJO_TOKEN")
|
||||||
|
|
||||||
|
|
||||||
|
def run(cmd: list[str], stdin=None) -> str:
|
||||||
|
logging.debug("executing %s", cmd)
|
||||||
|
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
|
||||||
|
out = p.communicate(stdin)
|
||||||
|
if p.returncode != 0:
|
||||||
|
logging.critical("{} exited with code {}", cmd, p.returncode)
|
||||||
|
os.exit(1)
|
||||||
|
return out[0]
|
||||||
|
|
||||||
|
|
||||||
|
def update_cert(k8s_name: str, owner: str, repo: str):
|
||||||
|
key = run(["openssl", "genrsa", "4096"])
|
||||||
|
req = run(
|
||||||
|
["openssl", "req", "-key", "/dev/stdin", "-new", "-nodes", "-subj", f"/CN={k8s_name}"], stdin=key
|
||||||
|
)
|
||||||
|
cert = run(
|
||||||
|
[
|
||||||
|
"openssl",
|
||||||
|
"x509",
|
||||||
|
"-req",
|
||||||
|
"-CA",
|
||||||
|
"/var/lib/rancher/k3s/server/tls/client-ca.nochain.crt",
|
||||||
|
"-CAkey",
|
||||||
|
"/var/lib/rancher/k3s/server/tls/client-ca.key",
|
||||||
|
"-CAcreateserial",
|
||||||
|
"-days",
|
||||||
|
"2",
|
||||||
|
],
|
||||||
|
stdin=req,
|
||||||
|
)
|
||||||
|
|
||||||
|
keyb64 = base64.b64encode(key).decode()
|
||||||
|
certb64 = base64.b64encode(cert).decode()
|
||||||
|
|
||||||
|
kubeconfig = f"""
|
||||||
|
apiVersion: v1
|
||||||
|
clusters:
|
||||||
|
- cluster:
|
||||||
|
certificate-authority-data: {ca}
|
||||||
|
server: https://k8s-node-1:6443
|
||||||
|
name: default
|
||||||
|
contexts:
|
||||||
|
- context:
|
||||||
|
cluster: default
|
||||||
|
user: default
|
||||||
|
name: default
|
||||||
|
current-context: default
|
||||||
|
kind: Config
|
||||||
|
preferences: {"{}"}
|
||||||
|
users:
|
||||||
|
- name: default
|
||||||
|
user:
|
||||||
|
client-certificate-data: {certb64}
|
||||||
|
client-key-data: {keyb64}
|
||||||
|
"""
|
||||||
|
logging.info(f"updating secret for {owner}/{repo}")
|
||||||
|
requests.put(
|
||||||
|
f"https://git.janky.solutions/api/v1/repos/{owner}/{repo}/actions/secrets/KUBERNETES_CLIENT_CONFIG",
|
||||||
|
data=json.dumps(
|
||||||
|
{"data": kubeconfig},
|
||||||
|
),
|
||||||
|
headers={
|
||||||
|
"Authorization": f"token {forgejo_token}",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
).raise_for_status()
|
||||||
|
|
||||||
|
|
||||||
|
for entry in json.loads(os.getenv("REPO_MAPPINGS")):
|
||||||
|
update_cert(**entry)
|
|
@ -5,8 +5,10 @@ resources:
|
||||||
- namespace.yaml
|
- namespace.yaml
|
||||||
- config.yaml
|
- config.yaml
|
||||||
- ingress.yaml
|
- ingress.yaml
|
||||||
|
- forgejo-secret-sync.yaml
|
||||||
- services.yaml
|
- services.yaml
|
||||||
- statefulset.yaml
|
- statefulset.yaml
|
||||||
|
- secret-store.yaml
|
||||||
- secrets.yaml
|
- secrets.yaml
|
||||||
- renovatebot.yaml
|
- renovatebot.yaml
|
||||||
configMapGenerator:
|
configMapGenerator:
|
||||||
|
@ -16,3 +18,6 @@ configMapGenerator:
|
||||||
- name: renovate-config
|
- name: renovate-config
|
||||||
files:
|
files:
|
||||||
- renovate/config.js
|
- renovate/config.js
|
||||||
|
- name: forgejo-secret-sync
|
||||||
|
files:
|
||||||
|
- forgejo-secret-sync/forgejo-secret-sync.py
|
||||||
|
|
16
k8s/forgejo/secret-store.yaml
Normal file
16
k8s/forgejo/secret-store.yaml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
apiVersion: external-secrets.io/v1beta1
|
||||||
|
kind: SecretStore
|
||||||
|
metadata:
|
||||||
|
name: openbao
|
||||||
|
spec:
|
||||||
|
provider:
|
||||||
|
vault:
|
||||||
|
server: http://openbao.openbao:8200
|
||||||
|
path: static-secrets
|
||||||
|
version: v2
|
||||||
|
auth:
|
||||||
|
kubernetes:
|
||||||
|
mountPath: kubernetes
|
||||||
|
role: kubernetes-default
|
||||||
|
serviceAccountRef:
|
||||||
|
name: default
|
Loading…
Reference in a new issue