From 8897bbe4eb0653695c5951a3dc1ec096d6ef8771 Mon Sep 17 00:00:00 2001 From: Peter Kurfer Date: Tue, 21 Jan 2025 16:33:58 +0100 Subject: [PATCH] feat: migrate blob proxy --- .forgejo/workflows/functions.yml | 35 ++++++++------ blob-proxy/.gitignore | 2 + blob-proxy/go.mod | 10 ++++ blob-proxy/go.sum | 6 +++ blob-proxy/main.go | 80 ++++++++++++++++++++++++++++++++ blob-proxy/spin.toml | 24 ++++++++++ deploy/apps/blob-proxy.yaml | 11 +++++ deploy/kustomization.yaml | 21 +++++---- deploy/resources/routes.yaml | 17 +++++++ 9 files changed, 184 insertions(+), 22 deletions(-) create mode 100644 blob-proxy/.gitignore create mode 100644 blob-proxy/go.mod create mode 100644 blob-proxy/go.sum create mode 100644 blob-proxy/main.go create mode 100644 blob-proxy/spin.toml create mode 100644 deploy/apps/blob-proxy.yaml diff --git a/.forgejo/workflows/functions.yml b/.forgejo/workflows/functions.yml index 7002e36..fbf9ee9 100644 --- a/.forgejo/workflows/functions.yml +++ b/.forgejo/workflows/functions.yml @@ -5,26 +5,22 @@ on: jobs: build: + strategy: + fail-fast: true + matrix: + function: + - comics + - blob-proxy runs-on: ubuntu-latest steps: - name: Setup Git config run: | git config --global user.email "ci@icb4dc0.de" git config --global user.name "Forgejo Actions" + - name: Setup `spin` uses: fermyon/actions/spin/setup@v1 - - name: Setup argocd CLI - run: | - curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-arm64 - chmod +x /usr/local/bin/argocd - argocd version --client - - - name: Setup kustomize - run: | - unset GITHUB_TOKEN - curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash -s -- /usr/local/bin - - name: Setup Go 1.23.x uses: actions/setup-go@v5 with: @@ -48,20 +44,31 @@ jobs: - name: Build run: | - spin registry push --build code.icb4dc0.de/infrastructure/functions/comics:${{ github.sha }} + spin registry push --build code.icb4dc0.de/infrastructure/functions/${{ matrix.function }}:${{ github.sha }} working-directory: comics - name: Update image reference run: | - kustomize edit set image comics=code.icb4dc0.de/infrastructure/functions/comics:${{ github.sha }} + kustomize edit set image ${{ matrix.function }}=code.icb4dc0.de/infrastructure/functions/${{ matrix.function }}:${{ github.sha }} git add kustomization.yaml - git commit -m "chore(deploy): update comics image reference" + git commit -m "chore(deploy): update ${{ matrix.function }} image reference" git push working-directory: deploy + deploy: + runs-on: ubuntu-latest + needs: + - build + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.ref_name }} + - name: Upsert Argo App run: | argocd app create functions -f deploy/argo-app.yaml --upsert --server argo-cd-argocd-server.argo-system.svc --auth-token ${{ secrets.ARGOCD_TOKEN }} --plaintext + - name: Deploy KubeSpin apps run: | argocd app sync functions --server argo-cd-argocd-server.argo-system.svc --auth-token ${{ secrets.ARGOCD_TOKEN }} --plaintext --assumeYes diff --git a/blob-proxy/.gitignore b/blob-proxy/.gitignore new file mode 100644 index 0000000..b565010 --- /dev/null +++ b/blob-proxy/.gitignore @@ -0,0 +1,2 @@ +main.wasm +.spin/ diff --git a/blob-proxy/go.mod b/blob-proxy/go.mod new file mode 100644 index 0000000..2d62073 --- /dev/null +++ b/blob-proxy/go.mod @@ -0,0 +1,10 @@ +module github.com/blob_proxy + +go 1.23 + +require ( + github.com/fermyon/spin-go-sdk v0.0.0-20250115171427-1ec2bbb84009 + github.com/fermyon/spin/sdk/go/v2 v2.2.0 +) + +require github.com/julienschmidt/httprouter v1.3.0 // indirect diff --git a/blob-proxy/go.sum b/blob-proxy/go.sum new file mode 100644 index 0000000..737c5b6 --- /dev/null +++ b/blob-proxy/go.sum @@ -0,0 +1,6 @@ +github.com/fermyon/spin-go-sdk v0.0.0-20250115171427-1ec2bbb84009 h1:dP4VrX/4zdnjQ2dx3HBmPxbkbcnVL0Y/0NWUN7XyCyY= +github.com/fermyon/spin-go-sdk v0.0.0-20250115171427-1ec2bbb84009/go.mod h1:9GoW1+MR0gN1OEinITtjPOzmu0dur3U6ty3pIH/gN24= +github.com/fermyon/spin/sdk/go/v2 v2.2.0 h1:zHZdIqjbUwyxiwdygHItnM+vUUNSZ3CX43jbIUemBI4= +github.com/fermyon/spin/sdk/go/v2 v2.2.0/go.mod h1:kfJ+gdf/xIaKrsC6JHCUDYMv2Bzib1ohFIYUzvP+SCw= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= diff --git a/blob-proxy/main.go b/blob-proxy/main.go new file mode 100644 index 0000000..8e3fce8 --- /dev/null +++ b/blob-proxy/main.go @@ -0,0 +1,80 @@ +package main + +import ( + "encoding/json" + "io" + "log/slog" + "net/http" + "os" + "path" + + "github.com/fermyon/spin-go-sdk/variables" + spinhttp "github.com/fermyon/spin/sdk/go/v2/http" +) + +var ( + client = spinhttp.NewClient() + logLevel slog.LevelVar +) + +func init() { + // call the Handle function + spinhttp.Handle(func(w http.ResponseWriter, r *http.Request) { + if levelValue, err := variables.Get("log_level"); err == nil { + _ = logLevel.UnmarshalText([]byte(levelValue)) + } + + logger := slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{ + Level: &logLevel, + })) + + logger.Info("Incoming request", slog.String("url", r.URL.String())) + mappingValue, err := variables.Get("domain_mapping") + if err != nil { + panic(err) + } + + mapping := make(map[string]string) + + if err := json.Unmarshal([]byte(mappingValue), &mapping); err != nil { + panic(err) + } + + mappedHost, ok := mapping[r.URL.Host] + if !ok { + w.WriteHeader(http.StatusNotFound) + return + } + + if path.Ext(r.URL.Path) == "" { + r.URL.Path = path.Join(r.URL.Path, "index.html") + } + + r.URL.Host = mappedHost + r.URL.Scheme = "https" + + req, err := http.NewRequestWithContext(r.Context(), r.Method, r.URL.String(), nil) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + logger.Info("Forwarding request", slog.String("url", req.URL.String())) + resp, err := client.Do(req) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + defer resp.Body.Close() + + logger.Info("Got response", slog.Int("status_code", resp.StatusCode)) + + for k, v := range resp.Header { + w.Header().Add(k, v[0]) + } + + w.WriteHeader(resp.StatusCode) + _, _ = io.Copy(w, resp.Body) + }) +} diff --git a/blob-proxy/spin.toml b/blob-proxy/spin.toml new file mode 100644 index 0000000..ea0aa80 --- /dev/null +++ b/blob-proxy/spin.toml @@ -0,0 +1,24 @@ +spin_manifest_version = 2 + +[application] +name = "blob-proxy" +version = "0.1.0" +authors = ["Peter Kurfer "] +description = "" + +[variables] +domain_mapping = { default = '{"docs.git-age.icb4dc0.de":"1661580-git-age.fsn1.your-objectstorage.com","localhost:3000":"1661580-git-age.fsn1.your-objectstorage.com","docs.supabase-operator.icb4dc0.de":"1661580-supabase-operator-docs.hel1.your-objectstorage.com"}'} + +[[trigger.http]] +route = "/..." +component = "blob-proxy" + +[component.blob-proxy] +source = "main.wasm" +allowed_outbound_hosts = [ + "https://1661580-blog.fsn1.your-objectstorage.com", + "https://1661580-supabase-operator-docs.hel1.your-objectstorage.com" +] +[component.blob-proxy.build] +command = "tinygo build -target=wasip1 -gc=leaking -no-debug -scheduler=none -buildmode=c-shared -o main.wasm main.go" +watch = ["**/*.go", "go.mod"] diff --git a/deploy/apps/blob-proxy.yaml b/deploy/apps/blob-proxy.yaml new file mode 100644 index 0000000..89a2dd9 --- /dev/null +++ b/deploy/apps/blob-proxy.yaml @@ -0,0 +1,11 @@ +apiVersion: core.spinkube.dev/v1alpha1 +kind: SpinApp +metadata: + name: blob-proxy +spec: + image: blob-proxy + executor: containerd-shim-spin + replicas: 2 + variables: + - name: domain_mapping + value: '{"www.icb4dc0.de":"1661580-blog.fsn1.your-objectstorage.com","docs.supabase-operator.icb4dc0.de":"1661580-supabase-operator-docs.hel1.your-objectstorage.com"}' diff --git a/deploy/kustomization.yaml b/deploy/kustomization.yaml index 6e91e32..f5d32b9 100644 --- a/deploy/kustomization.yaml +++ b/deploy/kustomization.yaml @@ -4,15 +4,20 @@ kind: Kustomization namespace: functions images: -- name: comics - newName: code.icb4dc0.de/infrastructure/functions/comics - newTag: 96cf231814d27f6dc9451e4eef0b7faaa63fc3c5 + - name: comics + newName: code.icb4dc0.de/infrastructure/functions/comics + newTag: 96cf231814d27f6dc9451e4eef0b7faaa63fc3c5 + + - name: blob-proxy + newName: code.icb4dc0.de/infrastructure/functions/blob-proxy + newTag: latest resources: -- resources/namespace.yaml -- resources/executor.yaml -- resources/routes.yaml -- apps/comics.yaml + - resources/namespace.yaml + - resources/executor.yaml + - resources/routes.yaml + - apps/comics.yaml + - apps/blob-proxy.yaml configurations: -- kustomizeconfig/spinapp.yaml + - kustomizeconfig/spinapp.yaml diff --git a/deploy/resources/routes.yaml b/deploy/resources/routes.yaml index ce8c1ce..e1a36be 100644 --- a/deploy/resources/routes.yaml +++ b/deploy/resources/routes.yaml @@ -1,3 +1,4 @@ +--- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: @@ -16,3 +17,19 @@ spec: backendRefs: - name: comics port: 80 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: blog-https +spec: + parentRefs: + - name: contour + sectionName: https + namespace: projectcontour + hostnames: + - "www.icb4dc0.de" + rules: + - backendRefs: + - name: blob-proxy + port: 80