From 04385257f7a1247ee6d36d2b9cd030ca8d0073ac Mon Sep 17 00:00:00 2001 From: Masaki Yatsu Date: Thu, 14 Aug 2025 16:11:30 +0900 Subject: [PATCH] feat(longhorn): add longhorn --- justfile | 1 + longhorn/.gitignore | 2 + longhorn/delete-setting.yaml | 5 ++ longhorn/ingressroute.gomplate.yaml | 32 +++++++ longhorn/justfile | 128 ++++++++++++++++++++++++++++ longhorn/longhorn-values.yaml | 6 ++ 6 files changed, 174 insertions(+) create mode 100644 longhorn/.gitignore create mode 100644 longhorn/delete-setting.yaml create mode 100644 longhorn/ingressroute.gomplate.yaml create mode 100644 longhorn/justfile create mode 100644 longhorn/longhorn-values.yaml diff --git a/justfile b/justfile index c82e108..4f72140 100644 --- a/justfile +++ b/justfile @@ -6,5 +6,6 @@ default: mod env mod k8s +mod longhorn import? "custom.just" diff --git a/longhorn/.gitignore b/longhorn/.gitignore new file mode 100644 index 0000000..ed70c66 --- /dev/null +++ b/longhorn/.gitignore @@ -0,0 +1,2 @@ +tls.crt +tls.key diff --git a/longhorn/delete-setting.yaml b/longhorn/delete-setting.yaml new file mode 100644 index 0000000..aaf4022 --- /dev/null +++ b/longhorn/delete-setting.yaml @@ -0,0 +1,5 @@ +apiVersion: longhorn.io/v1beta2 +kind: Setting +metadata: + name: deleting-confirmation-flag +value: "true" diff --git a/longhorn/ingressroute.gomplate.yaml b/longhorn/ingressroute.gomplate.yaml new file mode 100644 index 0000000..a813f9e --- /dev/null +++ b/longhorn/ingressroute.gomplate.yaml @@ -0,0 +1,32 @@ +# ForwardAuth with static upstreams configuration +# https://oauth2-proxy.github.io/oauth2-proxy/configuration/integration/#forwardauth-with-static-upstreams-configuration + +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: oauth-auth +spec: + forwardAuth: + address: "http://oauth2-proxy.{{ .Env.LONGHORN_NAMESPACE }}" # w/ redirect + # address: "http://oauth2-proxy.{{ .Env.LONGHORN_NAMESPACE }}/oauth2/auth" # w/o redirect + trustForwardHeader: true + authResponseHeaders: + - X-Auth-Request-Access-Token + - Authorization + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: longhorn +spec: + entryPoints: + - websecure + routes: + - match: "Host(`{{ .Env.LONGHORN_HOST }}`)" + kind: Rule + services: + - name: longhorn-frontend + port: 80 + middlewares: + - name: oauth-auth diff --git a/longhorn/justfile b/longhorn/justfile new file mode 100644 index 0000000..4824d0c --- /dev/null +++ b/longhorn/justfile @@ -0,0 +1,128 @@ +set fallback := true + +export LONGHORN_NAMESPACE := env("LONGHORN_NAMESPACE", "longhorn") +export LONGHORN_VERSION := env("LONGHORN_VERSION", "1.9.1") +export LONGHORN_OIDC_CLIENT_ID := env("LONGHORN_OIDC_CLIENT_ID", "longhorn") +export KEYCLOAK_REALM := env("KEYCLOAK_REALM", "") + +[private] +default: + @just --list --unsorted --list-submodules + +# Add Helm repository +add-helm-repo: + helm repo add longhorn https://charts.longhorn.io + helm repo update + +# Remove Helm repository +remove-helm-repo: + helm repo remove longhorn + +# Create namespace +create-namespace: + #!/bin/bash + set -euo pipefail + if ! kubectl get namespace ${LONGHORN_NAMESPACE} &>/dev/null; then + kubectl create namespace ${LONGHORN_NAMESPACE} + else + echo "Namespace ${LONGHORN_NAMESPACE} already exists." + fi + +# Delete namespace +delete-namespace: + #!/bin/bash + set -euo pipefail + if kubectl get namespace ${LONGHORN_NAMESPACE} &>/dev/null; then + kubectl delete namespace ${LONGHORN_NAMESPACE} --ignore-not-found + else + echo "Namespace ${LONGHORN_NAMESPACE} does not exist." + fi + +# Install Longhorn +install: + #!/bin/bash + set -euo pipefail + # https://longhorn.io/docs/1.9.1/deploy/install/install-with-helm/ + just add-helm-repo + helm upgrade --cleanup-on-fail --install longhorn longhorn/longhorn \ + --version ${LONGHORN_VERSION} -n ${LONGHORN_NAMESPACE} --create-namespace --wait \ + -f longhorn-values.yaml + just set-replicas 1 + +# Uninstall Longhorn +uninstall: + #!/bin/bash + set -euxo pipefail + if ! kubectl get -n ${LONGHORN_NAMESPACE} settings.longhorn.io \ + deleting-confirmation-flag &>/dev/null; then + kubectl apply -n ${LONGHORN_NAMESPACE} -f delete-setting.yaml + fi + helm uninstall longhorn -n ${LONGHORN_NAMESPACE} --ignore-not-found --wait + just delete-namespace + +# Install oauth2-proxy for Longhorn +oauth2-proxy-install: + #!/bin/bash + set -euo pipefail + export KEYCLOAK_CLIENT_SECRET=$(just random-password) + just keycloak::delete-client ${KEYCLOAK_REALM} ${LONGHORN_OIDC_CLIENT_ID} + just keycloak::create-client ${KEYCLOAK_REALM} ${LONGHORN_OIDC_CLIENT_ID} \ + "https://${LONGHORN_HOST}/oauth2/callback" + just keycloak::add-audience-mapper ${LONGHORN_OIDC_CLIENT_ID} + just create-namespace + KEYCLOAK_CLIENT_ID=${LONGHORN_OIDC_CLIENT_ID} \ + KEYCLOAK_REALM=${KEYCLOAK_REALM} \ + OAUTH2_PROXY_HOST=${LONGHORN_HOST} \ + COOKIE_SECRET=$(just random-password) \ + gomplate -f ../oauth2-proxy/configmap.gomplate.yaml | \ + kubectl apply -n ${LONGHORN_NAMESPACE} -f - + kubectl apply -n ${LONGHORN_NAMESPACE} -f ../oauth2-proxy/deployment.yaml + kubectl apply -n ${LONGHORN_NAMESPACE} -f ../oauth2-proxy/service.yaml + OAUTH2_PROXY_HOST=${LONGHORN_HOST} \ + gomplate -f ../oauth2-proxy/ingressroute.gomplate.yaml | \ + kubectl apply -n ${LONGHORN_NAMESPACE} -f - + +# Uninstall oauth2-proxy for Longhorn +oauth2-proxy-uninstall: + just keycloak::delete-client ${KEYCLOAK_REALM} ${LONGHORN_OIDC_CLIENT_ID} + OAUTH2_PROXY_HOST=${LONGHORN_HOST} \ + gomplate -f ../oauth2-proxy/ingressroute.gomplate.yaml | \ + kubectl delete -n ${LONGHORN_NAMESPACE} --ignore-not-found -f - + kubectl delete -n ${LONGHORN_NAMESPACE} --ignore-not-found service oauth2-proxy + kubectl delete -n ${LONGHORN_NAMESPACE} --ignore-not-found deployment oauth2-proxy + kubectl delete -n ${LONGHORN_NAMESPACE} --ignore-not-found configmap oauth2-proxy-config + +# Set Longhorn number of replicas +set-replicas num='1': + #!/bin/bash + set -euo pipefail + if ! command -v jq &>/dev/null; then + echo "jq is not installed. Install jq." >&2 + exit 1 + fi + yaml=$(kubectl get -n ${LONGHORN_NAMESPACE} configmap longhorn-storageclass \ + -o jsonpath='{.data.storageclass\.yaml}') + modified_yaml=$(echo "${yaml}" | sed 's/numberOfReplicas: "3"/numberOfReplicas: "{{ num }}"/') + kubectl patch -n ${LONGHORN_NAMESPACE} configmap longhorn-storageclass \ + --type merge -p "$(cat <