aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXe Iaso <me@xeiaso.net>2024-11-09 10:50:59 -0500
committerGitHub <noreply@github.com>2024-11-09 10:50:59 -0500
commit20d07c7005665f8e2001b4cbd24e15ec589d9882 (patch)
tree8b98d1446c6d9e42bc2621e633543e0420f43541
parent2b349f56cb20420dd153f40f22b3654b5079100f (diff)
downloadxesite-20d07c7005665f8e2001b4cbd24e15ec589d9882.tar.xz
xesite-20d07c7005665f8e2001b4cbd24e15ec589d9882.zip
Move to Kubernetes (#853)
* start to lift-and-shift to k8s Signed-off-by: Xe Iaso <me@xeiaso.net> * manifest/xesite: properly configure pod disruption budget, hostmount for xesite as a hack Signed-off-by: Xe Iaso <me@xeiaso.net> * properly slonk readiness Signed-off-by: Xe Iaso <me@xeiaso.net> * manifest: move to aeacus Signed-off-by: Xe Iaso <me@xeiaso.net> * internal: add OnionLocation middleware Signed-off-by: Xe Iaso <me@xeiaso.net> * internal/lume: jettison serving from the zipfile Signed-off-by: Xe Iaso <me@xeiaso.net> * yolo deploy to prod Signed-off-by: Xe Iaso <me@xeiaso.net> * okay use a machineproxy here Signed-off-by: Xe Iaso <me@xeiaso.net> * test CI/CD Signed-off-by: Xe Iaso <me@xeiaso.net> * try civo route Signed-off-by: Xe Iaso <me@xeiaso.net> * lol Signed-off-by: Xe Iaso <me@xeiaso.net> * plan c? Signed-off-by: Xe Iaso <me@xeiaso.net> * specify the region Signed-off-by: Xe Iaso <me@xeiaso.net> * lol Signed-off-by: Xe Iaso <me@xeiaso.net> * blog: hello again kubernetes! Signed-off-by: Xe Iaso <me@xeiaso.net> --------- Signed-off-by: Xe Iaso <me@xeiaso.net>
-rw-r--r--.dockerignore3
-rw-r--r--.github/workflows/earthly.yml52
-rw-r--r--Earthfile2
-rw-r--r--cmd/hydrate/main.go125
-rw-r--r--cmd/hydrate/templates/blog.tmpl10
-rw-r--r--cmd/hydrate/templates/linkpost.tmpl5
-rw-r--r--cmd/hydrate/templates/note.tmpl5
-rw-r--r--cmd/hydrate/templates/talk.tmpl0
-rw-r--r--cmd/hydrate/templates/xecast.tmpl0
-rw-r--r--cmd/patreon-saasproxy/main.go47
-rw-r--r--cmd/xesite/internalapi.go4
-rw-r--r--cmd/xesite/main.go1
-rw-r--r--go.mod30
-rw-r--r--go.sum86
-rw-r--r--internal/cached_token_source.go3
-rw-r--r--internal/domain_redirect.go11
-rw-r--r--internal/k8s/k8s.go133
-rw-r--r--internal/lume/lume.go10
-rw-r--r--internal/onion_location.go36
-rw-r--r--lume/deno.lock4130
-rw-r--r--lume/src/blog/2024/hello-again-k8s.mdx206
-rw-r--r--manifest/kustomization.yaml5
-rw-r--r--manifest/patreon-saasproxy/1password.yaml6
-rw-r--r--manifest/patreon-saasproxy/deployment.yaml45
-rw-r--r--manifest/patreon-saasproxy/kustomization.yaml10
-rw-r--r--manifest/patreon-saasproxy/rbac.yaml30
-rw-r--r--manifest/patreon-saasproxy/service.yaml14
-rw-r--r--manifest/xesite/1password.yaml6
-rw-r--r--manifest/xesite/cache-pvc.yaml13
-rw-r--r--manifest/xesite/deployment.yaml70
-rw-r--r--manifest/xesite/ingress.yaml35
-rw-r--r--manifest/xesite/kustomization.yaml9
-rw-r--r--manifest/xesite/machineproxy.yaml9
-rw-r--r--manifest/xesite/onionservice.yaml17
-rw-r--r--manifest/xesite/pod-disruption-budget.yaml9
-rw-r--r--manifest/xesite/service.yaml18
36 files changed, 2988 insertions, 2207 deletions
diff --git a/.dockerignore b/.dockerignore
index 6e6e0e0..5b1079c 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,4 +1,5 @@
backend
frontend
.env
-.git \ No newline at end of file
+.git
+manifest \ No newline at end of file
diff --git a/.github/workflows/earthly.yml b/.github/workflows/earthly.yml
index acde1a5..72a076b 100644
--- a/.github/workflows/earthly.yml
+++ b/.github/workflows/earthly.yml
@@ -46,34 +46,8 @@ jobs:
id: build
run: |
earthly --org me-2625 --sat alpha --ci +all
-
- deploy-patreon:
- name: "Deploy patreon-saasproxy"
- needs: build
- runs-on: ubuntu-latest
- permissions:
- contents: read
- if: github.ref == 'refs/heads/main'
-
- steps:
- - uses: actions/checkout@v4
- - uses: superfly/flyctl-actions/setup-flyctl@master
- - uses: dorny/paths-filter@v3
- id: changes
- with:
- filters: |
- src:
- - 'cmd/patreon-saasproxy/*.go'
- - 'internal/**/*.go'
- - 'go.mod'
- - 'go.sum'
- - 'Earthfile'
- - if: steps.changes.outputs.src == 'true'
- run: flyctl deploy --remote-only -c ./fly/patreon-saasproxy/fly.toml
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
- deploy-xesite:
+ deploy:
name: "Deploy xesite"
needs: build
runs-on: ubuntu-latest
@@ -83,18 +57,30 @@ jobs:
steps:
- uses: actions/checkout@v4
- - uses: superfly/flyctl-actions/setup-flyctl@master
+ - uses: azure/setup-kubectl@v4
+ - name: Save Civo kubeconfig
+ run: |
+ curl -sL https://civo.com/get | sh
+ civo apikey add default $CIVO_TOKEN
+ civo apikey current default
+ civo kubernetes config --region phx1 aeacus --save --switch
+ env:
+ CIVO_TOKEN: ${{ secrets.CIVO_TOKEN }}
- uses: dorny/paths-filter@v3
id: changes
with:
filters: |
src:
- - 'cmd/xesite/*.go'
+ - 'cmd/**/*.go'
- 'internal/**/*.go'
+ - 'pb/*'
+ - 'pb/**/*'
- 'go.mod'
- 'go.sum'
- 'Earthfile'
- - if: steps.changes.outputs.src == 'true'
- run: flyctl deploy --remote-only -c ./fly/xesite/fly.toml
- env:
- FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
+ - 'manifest/**/*.yaml'
+ - name: "Deploy"
+ if: steps.changes.outputs.src == 'true'
+ run: |
+ kubectl apply -k manifest
+ kubectl rollout restart -n default deploy/xesite
diff --git a/Earthfile b/Earthfile
index 84a9a4b..68cc0fd 100644
--- a/Earthfile
+++ b/Earthfile
@@ -74,7 +74,7 @@ xesite:
LABEL org.opencontainers.image.source="https://github.com/Xe/site"
- SAVE IMAGE --push ghcr.io/xe/site/bin:earthly
+ SAVE IMAGE --push ghcr.io/xe/site/bin:latest
all:
BUILD --platform=linux/amd64 +xesite
diff --git a/cmd/hydrate/main.go b/cmd/hydrate/main.go
new file mode 100644
index 0000000..ced069c
--- /dev/null
+++ b/cmd/hydrate/main.go
@@ -0,0 +1,125 @@
+package main
+
+import (
+ "embed"
+ "flag"
+ "fmt"
+ "log"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "text/template"
+ "time"
+)
+
+var (
+ //go:embed templates/*.tmpl
+ templates embed.FS
+
+ date = flag.String("date", time.Now().Format(time.DateOnly), "Publication date of the post")
+
+ routing = map[string]string{
+ "blog": "lume/src/blog",
+ "linkpost": "lume/src/blog",
+ "note": "lume/src/notes",
+ "talk": "lume/src/talks",
+ "xecast": "lume/src/xecast",
+ }
+)
+
+// go run ./cmd/hydrate <kind> <slug>
+
+func init() {
+ flag.Usage = func() {
+ fmt.Fprintf(os.Stderr, "Usage: %s [flags] <kind> <slug>\n\n", filepath.Base(os.Args[0]))
+ fmt.Fprintln(os.Stderr, "Available kinds:")
+
+ templs, err := templates.ReadDir("templates")
+ if err != nil {
+ log.Panicf("can't read templates: %v", err)
+ }
+
+ for _, tmpl := range templs {
+ kind, ok := strings.CutSuffix(tmpl.Name(), filepath.Ext(tmpl.Name()))
+ if !ok {
+ log.Panicf("can't cut extension from %q", tmpl.Name())
+ }
+ fmt.Fprintln(os.Stderr, " *", kind)
+ }
+
+ fmt.Fprintln(os.Stderr)
+ fmt.Fprintln(os.Stderr, "Flags:")
+
+ flag.PrintDefaults()
+
+ os.Exit(2)
+ }
+}
+
+func main() {
+ tmpl, err := template.ParseFS(templates, "templates/*.tmpl")
+ if err != nil {
+ log.Fatalf("can't parse templates: %v", err)
+ }
+
+ flag.Parse()
+
+ if flag.NArg() != 2 {
+ flag.Usage()
+ }
+
+ kind := flag.Arg(0)
+ slug := flag.Arg(1)
+
+ year, err := yearOf(*date)
+ if err != nil {
+ log.Fatalf("can't parse year in %s: %v", *date, year)
+ }
+
+ foutName := filepath.Join(routing[kind], year, slug+".mdx")
+
+ if _, err := os.Stat(foutName); !os.IsNotExist(err) {
+ log.Printf("Potential error when trying to verify %s doesn't exist: %v", foutName, err)
+ log.Println("Does the file already exist?")
+ os.Exit(1)
+ }
+
+ fout, err := os.Create(foutName)
+ if err != nil {
+ log.Fatalf("can't create %s: %v", foutName, err)
+ }
+
+ if err := tmpl.ExecuteTemplate(fout, kind+".tmpl", struct {
+ Date string
+ }{
+ Date: *date,
+ }); err != nil {
+ log.Fatalf("error writing template: %v", err)
+ }
+
+ if err := fout.Close(); err != nil {
+ log.Fatalf("error closing output file: %v", err)
+ }
+
+ codePath, err := exec.LookPath("code")
+ if err != nil {
+ log.Println("hint: control shift p -> install code command")
+ log.Fatalf("can't find code command in $PATH: %v", err)
+ }
+
+ if err := exec.Command(codePath, foutName).Run(); err != nil {
+ log.Fatalf("can't open %s in VS Code: %v", foutName, err)
+ }
+
+}
+
+func yearOf(date string) (string, error) {
+ t, err := time.Parse(time.DateOnly, date)
+ if err != nil {
+ return "", err
+ }
+
+ return strconv.Itoa(t.Year()), nil
+}
diff --git a/cmd/hydrate/templates/blog.tmpl b/cmd/hydrate/templates/blog.tmpl
new file mode 100644
index 0000000..6d9edde
--- /dev/null
+++ b/cmd/hydrate/templates/blog.tmpl
@@ -0,0 +1,10 @@
+---
+title: ""
+desc: ""
+date: {{.Date}}
+hero:
+ ai: ""
+ file: ""
+ prompt: ""
+ social: false
+--- \ No newline at end of file
diff --git a/cmd/hydrate/templates/linkpost.tmpl b/cmd/hydrate/templates/linkpost.tmpl
new file mode 100644
index 0000000..9afcc71
--- /dev/null
+++ b/cmd/hydrate/templates/linkpost.tmpl
@@ -0,0 +1,5 @@
+---
+title: ""
+date: {{.Date}}
+redirect_to: ""
+--- \ No newline at end of file
diff --git a/cmd/hydrate/templates/note.tmpl b/cmd/hydrate/templates/note.tmpl
new file mode 100644
index 0000000..2e510a5
--- /dev/null
+++ b/cmd/hydrate/templates/note.tmpl
@@ -0,0 +1,5 @@
+---
+title: ""
+desc: ""
+date: {{.Date}}
+--- \ No newline at end of file
diff --git a/cmd/hydrate/templates/talk.tmpl b/cmd/hydrate/templates/talk.tmpl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmd/hydrate/templates/talk.tmpl
diff --git a/cmd/hydrate/templates/xecast.tmpl b/cmd/hydrate/templates/xecast.tmpl
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmd/hydrate/templates/xecast.tmpl
diff --git a/cmd/patreon-saasproxy/main.go b/cmd/patreon-saasproxy/main.go
index 6901ee3..363fa80 100644
--- a/cmd/patreon-saasproxy/main.go
+++ b/cmd/patreon-saasproxy/main.go
@@ -2,14 +2,13 @@ package main
import (
"context"
- "encoding/base64"
"flag"
+ "fmt"
"log"
"log/slog"
"net"
"net/http"
"os"
- "path/filepath"
"github.com/facebookgo/flagenv"
_ "github.com/joho/godotenv/autoload"
@@ -20,13 +19,16 @@ import (
"gopkg.in/mxpv/patreon-go.v1"
"xeiaso.net/v4/internal"
"xeiaso.net/v4/internal/adminpb"
+ "xeiaso.net/v4/internal/k8s"
)
var (
- bind = flag.String("bind", ":80", "HTTP bind addr")
- clientID = flag.String("client-id", "", "Patreon client ID")
- clientSecret = flag.String("client-secret", "", "Patreon client secret")
- dataDir = flag.String("data-dir", "./var", "Directory to store data in")
+ bind = flag.String("bind", ":80", "HTTP bind addr")
+ clientID = flag.String("client-id", "", "Patreon client ID")
+ clientSecret = flag.String("client-secret", "", "Patreon client secret")
+ dataDir = flag.String("data-dir", "./var", "Directory to store data in")
+ k8sNamespace = flag.String("kubernetes-namespace", "default", "Kubernetes namespace this app is running in")
+ k8sSecretName = flag.String("kubernetes-secret-name", "xesite-patreon-saasproxy-state", "Kubernetes secret to store state data in")
)
func main() {
@@ -46,36 +48,11 @@ func main() {
Scopes: []string{"users", "pledges-to-me", "my-campaign"},
}
- if !internal.FileExists(filepath.Join(*dataDir, "patreon-token.json")) {
- val, ok := os.LookupEnv("PATREON_TOKEN_JSON_B64")
- if !ok {
- log.Fatal("PATREON_TOKEN_JSON_B64 not set")
- }
-
- fout, err := os.Create(filepath.Join(*dataDir, "patreon-token.json"))
- if err != nil {
- log.Fatal(err)
- }
- defer fout.Close()
-
- decoded, err := base64.StdEncoding.DecodeString(val)
- if err != nil {
- slog.Error("can't decode token", "err", err, "val", val)
- log.Fatal(err)
- }
-
- if _, err := fout.Write(decoded); err != nil {
- log.Fatal(err)
- }
- }
-
- token, err := internal.ReadToken(filepath.Join(*dataDir, "patreon-token.json"))
+ cts, err := k8s.TokenSource(*k8sNamespace, *k8sSecretName, &config)
if err != nil {
- log.Fatalf("error reading token: %v", err)
+ log.Fatalf("error making token source: %v", err)
}
- cts := internal.CachingTokenSource(filepath.Join(*dataDir, "patreon-token.json"), &config, token)
-
s := &Server{
cts: cts,
}
@@ -83,6 +60,10 @@ func main() {
ph := adminpb.NewPatreonServer(s)
http.Handle(adminpb.PatreonPathPrefix, ph)
+ http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
+ fmt.Fprintln(w, "OK")
+ })
+
ln, err := net.Listen("tcp", *bind)
if err != nil {
log.Fatalf("can't listen over TCP: %v", err)
diff --git a/cmd/xesite/internalapi.go b/cmd/xesite/internalapi.go
index c0dfa9c..615af72 100644
--- a/cmd/xesite/internalapi.go
+++ b/cmd/xesite/internalapi.go
@@ -3,6 +3,7 @@ package main
import (
"context"
"expvar"
+ "fmt"
"log"
"net"
"net/http"
@@ -23,6 +24,9 @@ func internalAPI(fs *lume.FS) {
mux := http.NewServeMux()
mux.Handle("/debug/vars", expvar.Handler())
+ mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
+ fmt.Fprintln(w, "OK")
+ })
mux.HandleFunc("/rebuild", func(w http.ResponseWriter, r *http.Request) {
go fs.Update(context.Background())
diff --git a/cmd/xesite/main.go b/cmd/xesite/main.go
index 0062086..bef58e7 100644
--- a/cmd/xesite/main.go
+++ b/cmd/xesite/main.go
@@ -126,6 +126,7 @@ func main() {
h = internal.AcceptEncodingMiddleware(h)
h = internal.RefererMiddleware(h)
h = internal.DomainRedirect(h, *devel)
+ h = internal.OnionLocation(h)
slog.Info("starting server", "bind", *bind)
log.Fatal(http.Serve(ln, h))
diff --git a/go.mod b/go.mod
index 15b79d9..bdcd3ae 100644
--- a/go.mod
+++ b/go.mod
@@ -20,6 +20,8 @@ require (
google.golang.org/protobuf v1.34.2
gopkg.in/fsnotify.v1 v1.4.7
gopkg.in/mxpv/patreon-go.v1 v1.0.0-20171031001022-1d2f253ac700
+ k8s.io/apimachinery v0.31.2
+ k8s.io/client-go v0.31.2
tailscale.com v1.70.0
within.website/x v1.10.0
)
@@ -47,24 +49,41 @@ require (
github.com/cloudflare/circl v1.3.7 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
+ github.com/emicklei/go-restful/v3 v3.11.2 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c // indirect
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 // indirect
+ github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
+ github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
+ github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
+ github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
+ github.com/golang/protobuf v1.5.4 // indirect
+ github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
+ github.com/google/go-cmp v0.6.0 // indirect
+ github.com/google/gofuzz v1.2.0 // indirect
+ github.com/google/uuid v1.6.0 // indirect
+ github.com/imdario/mergo v0.3.16 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/josharian/intern v1.0.0 // indirect
+ github.com/json-iterator/go v1.1.12 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+ github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
+ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/skeema/knownhosts v1.2.2 // indirect
+ github.com/spf13/pflag v1.0.5 // indirect
+ github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
go4.org/mem v0.0.0-20220726221520-4f986261bf13 // indirect
golang.org/x/crypto v0.24.0 // indirect
@@ -72,8 +91,19 @@ require (
golang.org/x/net v0.26.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.21.0 // indirect
+ golang.org/x/term v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
+ golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.22.0 // indirect
+ gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
+ gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
+ k8s.io/api v0.31.2 // indirect
+ k8s.io/klog/v2 v2.130.1 // indirect
+ k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
+ k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
+ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
+ sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
+ sigs.k8s.io/yaml v1.4.0 // indirect
)
diff --git a/go.sum b/go.sum
index 99601b6..e600c50 100644
--- a/go.sum
+++ b/go.sum
@@ -61,6 +61,8 @@ github.com/donatj/hmacsig v1.1.0 h1:DbBIW1ZTMfJoJhDGPVpkatYyxhrR2xVoHAokPTrlw50=
github.com/donatj/hmacsig v1.1.0/go.mod h1:rh/7q72Fo5oYc7bcKgvGHWsfHcs8jKhJdFgCZcvZ/G0=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
+github.com/emicklei/go-restful/v3 v3.11.2 h1:1onLa9DcsMYO9P+CXaL0dStDqQ2EHHXLiz+BtnqkLAU=
+github.com/emicklei/go-restful/v3 v3.11.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emicklei/proto v1.13.2 h1:z/etSFO3uyXeuEsVPzfl56WNgzcvIr42aQazXaQmFZY=
github.com/emicklei/proto v1.13.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
@@ -75,6 +77,8 @@ github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpm
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
+github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
+github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/getkin/kin-openapi v0.120.0 h1:MqJcNJFrMDFNc07iwE8iFC5eT2k/NPUFDIpNeiZv8Jg=
github.com/getkin/kin-openapi v0.120.0/go.mod h1:PCWw/lfBrJY4HcdqE3jj+QFkaFK8ABoqo7PvqVhXXqw=
github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
@@ -91,16 +95,38 @@ github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZt
github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY=
github.com/go-json-experiment/json v0.0.0-20231102232822-2e55bd4e08b0 h1:ymLjT4f35nQbASLnvxEde4XOBL+Sn7rFuV+FOJqkljg=
github.com/go-json-experiment/json v0.0.0-20231102232822-2e55bd4e08b0/go.mod h1:6daplAwHHGbUGib4990V3Il26O0OC4aRyvewaaAihaA=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
+github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU=
+github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
+github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
+github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU=
+github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49/go.mod h1:BkkQ4L1KS1xMt2aWSPStnn55ChGC0DPOn2FQYj+f25M=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
+github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM=
+github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
+github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso=
github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
@@ -109,8 +135,12 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
@@ -120,8 +150,17 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
+github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
+github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
@@ -140,8 +179,11 @@ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A=
github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
@@ -149,23 +191,34 @@ github.com/twitchtv/twirp v8.1.3+incompatible h1:+F4TdErPgSUbMZMwp13Q/KgDVuI7HJX
github.com/twitchtv/twirp v8.1.3+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
+github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
+github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go4.org/mem v0.0.0-20220726221520-4f986261bf13 h1:CbZeCBZ0aZj8EfVgnqQcYZgf0lpZ3H9rmp5nkDTAst8=
go4.org/mem v0.0.0-20220726221520-4f986261bf13/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod