Added build action and kubernetes manifests

This commit is contained in:
Dreaded_X 2025-04-14 18:40:59 +02:00
parent eaadf02220
commit 5f0a0ade8c
Signed by: Dreaded_X
GPG Key ID: FA5F485356B0D2D4
16 changed files with 333 additions and 4 deletions

View File

@ -0,0 +1,93 @@
name: Build and deploy
on:
push:
branches:
- master
- feature/**
tags:
- v*.*.*
env:
OCI_REPO: git.huizinga.dev/dreaded_x/${{ gitea.event.repository.name}}
jobs:
build:
name: Build container and manifests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Get Git commit timestamps
run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
- name: Login to registry
uses: docker/login-action@v3
with:
registry: git.huizinga.dev
username: ${{ gitea.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Install kustomize
run: |
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
- name: Setup Flux CLI
uses: https://github.com/fluxcd/flux2/action@main
with:
version: v2.5.0
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.OCI_REPO }}
tags: |
type=edge
type=ref,event=branch
type=semver,pattern=v{{version}}
type=semver,pattern=v{{major}}.{{minor}}
type=semver,pattern=v{{major}}
- name: Build and export to docker
id: build
uses: docker/build-push-action@v6
with:
context: .
load: true
annotations: ${{ steps.meta.outputs.annotations }}
cache-from: type=gha
cache-to: type=gha,mode=max
env:
SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }}
- name: Push container
uses: docker/build-push-action@v6
id: push
with:
context: .
push: true
sbom: true
provenance: mode=max
tags: ${{ steps.meta.outputs.tags }}
annotations: ${{ steps.meta.outputs.annotations }}
env:
SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }}
- name: Kustomize manifests
run: |
./kustomize build ./manifests | sed "s/\${DIGEST}/${{ steps.push.outputs.digest }}/" > ./manifests.yaml
- name: Push manifests
run: |
flux push artifact oci://$OCI_REPO/manifests:latest \
--path="./manifests.yaml" \
--source="$(git config --get remote.origin.url)" \
--revision="$(git rev-parse HEAD)" \
$(echo "${{ steps.meta.outputs.labels }}" | sed -e 's/^/-a /')
flux tag artifact oci://$OCI_REPO/manifests:latest \
$(echo "${{ steps.meta.outputs.tags }}" | sed -e 's/^.*:/--tag /')

View File

@ -45,6 +45,7 @@ repos:
name: audit
description: Audit packages
entry: cargo audit
args: ["--deny", "warnings"]
language: system
pass_filenames: false
verbose: true

7
.sops.yaml Normal file
View File

@ -0,0 +1,7 @@
creation_rules:
- path_regex: .*.yaml
encrypted_regex: ^(data|stringData)$
key_groups:
- pgp:
- 1E0CF38FF7C9ADAED58B436ABA4A3D3607E5BA8E
- 49F10679C425233EFB4B1B6F9D641BEFA42DEC28

4
Cargo.lock generated
View File

@ -3091,9 +3091,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.44.1"
version = "1.44.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a"
checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48"
dependencies = [
"backtrace",
"bytes",

View File

@ -21,7 +21,7 @@ ratatui = { version = "0.29.0", features = ["unstable-backend-writer"] }
reqwest = { version = "0.12.15", features = ["rustls-tls"] }
russh = "0.51.1"
thiserror = "2.0.12"
tokio = { version = "1.44.1", features = ["full"] }
tokio = { version = "1.44.2", features = ["full"] }
tracing = "0.1.41"
tracing-subscriber = { version = "0.3.19", features = ["json", "env-filter"] }
unicode-width = "0.2.0"

22
Dockerfile Normal file
View File

@ -0,0 +1,22 @@
FROM rust:1.85 AS base
ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
RUN cargo install cargo-chef --locked --version 0.1.71 && \
cargo install cargo-auditable --locked --version 0.6.6
WORKDIR /app
FROM base AS planner
COPY . .
RUN cargo chef prepare --recipe-path recipe.json
FROM base AS builder
COPY --from=planner /app/recipe.json recipe.json
ENV RUSTC_BOOTSTRAP=1
RUN cargo chef cook --release --recipe-path recipe.json
COPY . .
ENV RUSTC_BOOTSTRAP=1
RUN cargo auditable build --release
FROM gcr.io/distroless/cc-debian12:nonroot AS runtime
COPY --from=builder /app/target/release/tunnel_rs /tunnel_rs
CMD ["/tunnel_rs"]

View File

@ -0,0 +1,13 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: tunnel
spec:
secretName: tunnel-tls
issuerRef:
name: letsencrypt
kind: ClusterIssuer
commonName: "*.tunnel.${domain}"
dnsNames:
- "tunnel.${domain}"
- "*.tunnel.${domain}"

View File

@ -0,0 +1,10 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: authelia-acl
annotations:
config.huizinga.dev/fragment: authelia-acl
data:
rules: |
- domain: "*.tunnel.${domain}"
policy: one_factor

65
manifests/deployment.yaml Normal file
View File

@ -0,0 +1,65 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: tunnel
labels:
app: tunnel
app.kubernetes.io/name: tunnel
spec:
replicas: 1
selector:
matchLabels:
app: tunnel
template:
metadata:
labels:
app: tunnel
annotations:
kubectl.kubernetes.io/default-container: tunnel
spec:
containers:
- name: tunnel
image: git.huizinga.dev/dreaded_x/tunnel_rs@${DIGEST}
imagePullPolicy: IfNotPresent
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 50m
memory: 100Mi
ports:
- containerPort: 3000
- containerPort: 2222
volumeMounts:
- name: credentials
readOnly: true
mountPath: "/secrets/credentials"
- name: key
readOnly: true
mountPath: "/secrets/key"
env:
- name: RUST_LOG
value: info,tunnel_rs=debug
- name: TUNNEL_DOMAIN
value: tunnel.${domain}
- name: AUTHZ_ENDPOINT
value: http://authelia.authelia.svc.cluster.local:80/api/authz/forward-auth
- name: LDAP_ADDRESS
value: ldap://lldap.lldap.svc.cluster.local:3890
- name: LDAP_BASE
value: ou=people,dc=huizinga,dc=dev
- name: LDAP_BIND_DN
value: uid=tunnel.tunnel,ou=people,dc=huizinga,dc=dev
- name: LDAP_PASSWORD_FILE
value: /secrets/credentials/password
- name: PRIVATE_KEY_FILE
value: /secrets/key/private.pem
volumes:
- name: credentials
secret:
secretName: tunnel-lldap-credentials
- name: key
secret:
secretName: tunnel-key

View File

@ -0,0 +1,15 @@
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: tunnel
spec:
entryPoints:
- websecure
routes:
- match: HostRegexp(`^.+\.tunnel\.${domain//./\\.}$`)
kind: Rule
services:
- name: tunnel
port: 3000
tls:
secretName: tunnel-tls

View File

@ -0,0 +1,12 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: tunnel
resources:
- ./namespace.yaml
- ./service-user.yaml
- ./secret-tunnel-key.yaml
- ./deployment.yaml
- ./service.yaml
- ./certificate.yaml
- ./ingress-route.yaml
- ./config-map-authelia-acl.yaml

4
manifests/namespace.yaml Normal file
View File

@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: tunnel

View File

@ -0,0 +1,59 @@
apiVersion: v1
kind: Secret
metadata:
name: tunnel-key
type: Opaque
stringData:
private.pem: ENC[AES256_GCM,data:9chbnKvGVtGEHTytURAK03ewcy+2LO3JLN6uCD6EtovQqAHZvBJFmUWDwSKXXLAoH8ErQ7VjldzaGPNhCqJaF/+69N9ruoOELR/NdqBbeXxQLdzNO95qlFGNbvBQaJheuQmT0BIqMxu8GHEjoswdHiE0wQebbJubPu3x85tLu24T86sUpeBuRcFsdouBPCO3q3h5Prdxscl/McTcdB+DE21Mpk0dw9GvxmyeTWg1LAbmtYv5vhdJRCSQW1EtQQNn/o/K3/7ALoGsekomjAoFmVG7OKIwaUbfJkVxyYN8UQ7Q4YQ3C16NCysoNx4aB9AlcvIeME/eNJ+nAQMWFA5q2ewhza+idw1H9GmBJaoIFCGsXXdPTyEglFFf5xGZR/lHGxxD1UP0Zd/b25dIKkAYBnYVPojN1HLom+3dG+Ci1oGQmDkT91w1Zj72b9uIdT+xNTBG7b8bkBlLprUJ8VYm2sGZiFmzYkJd6slwVJ+j0Y26iEEpvPb63stkhkeSIeg1fKSL,iv:lz3hiOS/+xYJ4/ooITqxXNlpZsiA+UXQH+4UTofj2p0=,tag:Pwz3pCqJkSUFx5JflKJJEw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2025-04-14T22:32:45Z"
mac: ENC[AES256_GCM,data:KGxVfxRVzyzkJTfGzVsWzLMDPBhElcpbgeHalctly14MhzsubEVPwr6Qlj4dh2714Vs0NUo3xERbIeLYRZqbqIQkVkXM31bzA0Tsud+Wapv92B9Z2yr249YX1EhxwnFzSR+180vkIB+Vc8n2hfgSXftUg5L5QEouUuilUiXWQKo=,iv:pal8Fypc6HnTnHulaFvo8A5FH6wjdDQQJGUb0G+w6Do=,tag:D4swtLKJctkyDTfMQpdGtg==,type:str]
pgp:
- created_at: "2025-04-14T16:11:54Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA7pKPTYH5bqOAQ/+NeM4vp2r4YXdBgjucZTXcD04WtLEq8rcBlK5naAoiMlN
4tKfKDDB6UO46An+hJDfIYcMp1PnXw6TxUSxrpyXQadXb6qu9lTow8QuMSMs5tO9
WmapcoFO9VnXkehC1ObqaZuWgNL/ksA/AF605Pl9ZsdKSgc9CHL7uPpLp6EiC8h7
/fAjwEnQsw8NbcAsyfJW9GJvrQpisFk1HPxv7d7v1zBO/Jm9otbSSejw1hEFdZcd
AB47XeYzmUJMWC4EVydk6pJhyEEKi3Dv5SrLq7tDSKqxF3wFEQcS2vbORKExzpeh
7mobTyavdWnT8oVWrnaNXtaCHyEQu58vAlpuL+WlzuPFCooMhlcI9FDceJ/k//MA
rIPt0xjWYqkHMhYLC41F61os1MFPdAJWa37kdJnL/jNjPB1CNKfTSvBZ3uJduOjP
VPQTKr5kne+W9CuE2zildbk3sq2RGNYgRKTNN2cLRPAtQYi75MgCyCACZKJ9kbR1
6tFhzWWoyOsiP+ykdWzpSnHTlJqFcV2GUhyCrNk3yRS2eN7e3akM/A5G7cHPiu+C
1Wt2ZK/df+5Hsj81DHllh2Iir73ezNIqhNisQFciQ2NuCs/42InuM4/CipDoZyBN
0FZz2E6fq6pupJE6nSklrEam9gg7x4pjF6Mhf2XLEpcWDzFIp956AHKMLIIXnpLU
ZgEJAhBdSWPQYaen46bkYKothIoL9ptVwZLRS4uEDNotJPKZbyfLGdCOIz1pbgQS
xj5nWZSgfDs5yj6NqwsJU7tjaxnGP+qS38fY7ez8tfUk7vZlqY2xRRAthfkhbn4T
lpuph/Pj0Q==
=Jee/
-----END PGP MESSAGE-----
fp: 1E0CF38FF7C9ADAED58B436ABA4A3D3607E5BA8E
- created_at: "2025-04-14T16:11:54Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA51kG++kLewoAQ/+KZeOjQHSNPw0DI0EPi6juGISmCk24z93THbDVn1KSdm0
jtLhAIXTKMqTRFuj9m1GFqIXgsmYjQoR5fmDyhzW9ecjyBxMP08qFp4Z7HOO97rM
3DEe8REiZOyrFyvCr51RzQtmtmULlquzvbzmEwy8CaUaIMpQdOmh2mXyHgX/lYL4
xqjkkSb64K4fOHKNo08cPBFN9eZtK0Slk09shGx6tS8I2fzpnKEPmgIBpKbuZhtJ
9MZ5zafiz+339yTQ/y83ZI9o8mNC0fiK8SZhSiIaFVYBzec6FspmkTUSq9wl+7n8
ZnT01A4UxyaDxmam4g1BK5y9eE8U8MB7op9xv6RjDlQdjOFwehnKUJ5wITjRvj9y
yPvmDYXzOlg15IRGPQdeCTt0GCEF/cdIM+vOLojE6hVDmy5pbOfjoegb/ue9VV3W
KRgj+tlQYKfa0vVCHC3bd1NsXr9eQJtIaQeAcuf5b+TKJn7x1ZwJ/CUQ5NJdTbsF
lRzFwemVijswOdZGGjYiBMA8/7Ql29xeQIzVZiEjU18APDvY9p37kozXRUzvf+3+
vjASmJICfZSptYYwA6uucpJIhyss9MXhY1/eX8brl4IsKOupX8XeCGnF5JAlYpD8
JsGFHuZPeKsqyFg5wVjnag3KUx++dqT7a/cgOQ+F2gstnfLJRwa3tMSoY8gVm7DS
XAHMCjfirTv5fO/7txioKFL/INxDXK8Heu+SLdyo2XA2zx3JwYmzVs4UbtkbXo2u
5NzCQMOVjI+Nq8niqdeV6YCAy/RwrG2ziZP3nNlP3iB3+g5KFmxTot4hFOec
=ckBd
-----END PGP MESSAGE-----
fp: 49F10679C425233EFB4B1B6F9D641BEFA42DEC28
encrypted_regex: ^(data|stringData)$
version: 3.9.4

View File

@ -0,0 +1,5 @@
apiVersion: lldap.huizinga.dev/v1
kind: ServiceUser
metadata:
name: tunnel
spec: {}

24
manifests/service.yaml Normal file
View File

@ -0,0 +1,24 @@
apiVersion: v1
kind: Service
metadata:
name: tunnel
spec:
ports:
- name: "3000"
port: 3000
targetPort: 3000
selector:
app: tunnel
---
apiVersion: v1
kind: Service
metadata:
name: tunnel-ssh
spec:
type: LoadBalancer
ports:
- name: "2222"
port: 2222
targetPort: 2222
selector:
app: tunnel

View File

@ -1,4 +1,3 @@
#![feature(impl_trait_in_fn_trait_return)]
#![feature(let_chains)]
mod animals;
mod auth;