diff --git a/dev/Tiltfile b/dev/Tiltfile index 4441513156..9c6d7f70f5 100644 --- a/dev/Tiltfile +++ b/dev/Tiltfile @@ -180,23 +180,6 @@ docker_build_with_restart( live_update=[sync('./bin/unkey', '/unkey')] ) -# Agent service -docker_build( - 'unkey/agent:latest', - '../web/apps/agent', - dockerfile='../web/apps/agent/Dockerfile', - ) -k8s_yaml('k8s/manifests/agent.yaml') -k8s_resource( - 'agent', - port_forwards='8082:8080', - resource_deps=['s3', 'clickhouse'], - labels=['unkey'], - auto_init=True, - trigger_mode=TRIGGER_MODE_AUTO -) - - # Vault service k8s_yaml('k8s/manifests/vault.yaml') k8s_resource( @@ -322,7 +305,7 @@ local_resource( cd ../web && pnpm --filter=@unkey/dashboard dev ''', deps=[], - resource_deps=['planetscale', 'clickhouse', 'agent', 'ctrl-api'], + resource_deps=['planetscale', 'clickhouse', 'ctrl-api'], labels=['unkey'], auto_init=True, readiness_probe=probe(http_get=http_get_action(port=3000, path='/'), period_secs=5, failure_threshold=30), diff --git a/dev/docker-compose.yaml b/dev/docker-compose.yaml index c081795483..40e6a1860a 100644 --- a/dev/docker-compose.yaml +++ b/dev/docker-compose.yaml @@ -150,30 +150,6 @@ services: start_period: 30s interval: 10s - agent: - networks: - - default - container_name: agent - command: ["/usr/local/bin/unkey", "agent", "--config", "config.docker.json"] - build: - context: ../web/apps/agent - dockerfile: ./Dockerfile - ports: - - 8080:8080 - depends_on: - - s3 - - clickhouse - environment: - PORT: 8080 - RPC_PORT: 9095 - AUTH_TOKEN: "agent-auth-secret" - VAULT_S3_URL: "http://s3:3902" - VAULT_S3_BUCKET: "vault" - VAULT_S3_ACCESS_KEY_ID: "minio_root_user" - VAULT_S3_ACCESS_KEY_SECRET: "minio_root_password" - VAULT_MASTER_KEYS: "Ch9rZWtfMmdqMFBJdVhac1NSa0ZhNE5mOWlLSnBHenFPENTt7an5MRogENt9Si6wms4pQ2XIvqNSIgNpaBenJmXgcInhu6Nfv2U=" - CLICKHOUSE_URL: "clickhouse://default:password@clickhouse:9000" - clickhouse: networks: - default @@ -445,9 +421,6 @@ services: planetscale: condition: service_started required: true - agent: - condition: service_started - required: true env_file: - ../web/apps/dashboard/.env environment: @@ -455,9 +428,6 @@ services: DATABASE_HOST: "planetscale:3900" # Auth configuration # Reading from env file, no override necessary - # Agent configuration - AGENT_URL: "http://agent:8080" - AGENT_TOKEN: "agent-auth-secret" # Clickhouse configuration CLICKHOUSE_URL: "http://default:password@clickhouse:8123" # Environment diff --git a/dev/k8s/manifests/agent.yaml b/dev/k8s/manifests/agent.yaml deleted file mode 100644 index baebb6ebfc..0000000000 --- a/dev/k8s/manifests/agent.yaml +++ /dev/null @@ -1,76 +0,0 @@ ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: agent - namespace: unkey - labels: - app: agent -spec: - replicas: 1 - selector: - matchLabels: - app: agent - template: - metadata: - labels: - app: agent - spec: - containers: - - name: agent - image: unkey/agent:latest - imagePullPolicy: Never - ports: - - containerPort: 8080 - - containerPort: 9095 - env: - - name: PORT - value: "8080" - - name: RPC_PORT - value: "9095" - - name: AUTH_TOKEN - value: "agent-auth-secret" - - name: VAULT_S3_URL - value: "http://s3:3902" - - name: VAULT_S3_BUCKET - value: "vault" - - name: VAULT_S3_ACCESS_KEY_ID - value: "minio_root_user" - - name: VAULT_S3_ACCESS_KEY_SECRET - value: "minio_root_password" - - name: VAULT_MASTER_KEYS - value: "Ch9rZWtfMmdqMFBJdVhac1NSa0ZhNE5mOWlLSnBHenFPENTt7an5MRogENt9Si6wms4pQ2XIvqNSIgNpaBenJmXgcInhu6Nfv2U=" - - name: CLICKHOUSE_URL - value: "clickhouse://default:password@clickhouse:9000" - command: ["/usr/local/bin/unkey", "agent", "--config", "config.docker.json"] - initContainers: - - name: wait-for-dependencies - image: busybox:1.36 - command: - [ - "sh", - "-c", - "until nc -z s3 3902 && nc -z clickhouse 9000; do echo waiting for dependencies; sleep 2; done;", - ] - ---- -apiVersion: v1 -kind: Service -metadata: - name: agent - namespace: unkey - labels: - app: agent -spec: - selector: - app: agent - ports: - - name: http - port: 8080 - targetPort: 8080 - protocol: TCP - - name: rpc - port: 9095 - targetPort: 9095 - protocol: TCP - type: ClusterIP diff --git a/web/apps/agent/.golangci.yaml b/web/apps/agent/.golangci.yaml deleted file mode 100644 index fe8555302a..0000000000 --- a/web/apps/agent/.golangci.yaml +++ /dev/null @@ -1,346 +0,0 @@ -# This code is licensed under the terms of the MIT license https://opensource.org/license/mit -# Copyright (c) 2021 Marat Reymers - -## Golden config for golangci-lint v1.59.1 -# -# This is the best config for golangci-lint based on my experience and opinion. -# It is very strict, but not extremely strict. -# Feel free to adapt and change it for your needs. - -run: - # Timeout for analysis, e.g. 30s, 5m. - # Default: 1m - timeout: 3m - -# This file contains only configs which differ from defaults. -# All possible options can be found here https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml -linters-settings: - cyclop: - # The maximal code complexity to report. - # Default: 10 - max-complexity: 30 - # The maximal average package complexity. - # If it's higher than 0.0 (float) the check is enabled - # Default: 0.0 - package-average: 10.0 - - errcheck: - # Report about not checking of errors in type assertions: `a := b.(MyStruct)`. - # Such cases aren't reported by default. - # Default: false - check-type-assertions: true - - exhaustive: - # Program elements to check for exhaustiveness. - # Default: [ switch ] - check: - - switch - - map - - exhaustruct: - # List of regular expressions to exclude struct packages and their names from checks. - # Regular expressions must match complete canonical struct package/name/structname. - # Default: [] - exclude: - # std libs - - "^net/http.Client$" - - "^net/http.Cookie$" - - "^net/http.Request$" - - "^net/http.Response$" - - "^net/http.Server$" - - "^net/http.Transport$" - - "^net/url.URL$" - - "^os/exec.Cmd$" - - "^reflect.StructField$" - # public libs - - "^github.com/Shopify/sarama.Config$" - - "^github.com/Shopify/sarama.ProducerMessage$" - - "^github.com/mitchellh/mapstructure.DecoderConfig$" - - "^github.com/prometheus/client_golang/.+Opts$" - - "^github.com/spf13/cobra.Command$" - - "^github.com/spf13/cobra.CompletionOptions$" - - "^github.com/stretchr/testify/mock.Mock$" - - "^github.com/testcontainers/testcontainers-go.+Request$" - - "^github.com/testcontainers/testcontainers-go.FromDockerfile$" - - "^golang.org/x/tools/go/analysis.Analyzer$" - - "^google.golang.org/protobuf/.+Options$" - - "^gopkg.in/yaml.v3.Node$" - - funlen: - # Checks the number of lines in a function. - # If lower than 0, disable the check. - # Default: 60 - lines: 100 - # Checks the number of statements in a function. - # If lower than 0, disable the check. - # Default: 40 - statements: 50 - # Ignore comments when counting lines. - # Default false - ignore-comments: true - - gocognit: - # Minimal code complexity to report. - # Default: 30 (but we recommend 10-20) - min-complexity: 20 - - gocritic: - # Settings passed to gocritic. - # The settings key is the name of a supported gocritic checker. - # The list of supported checkers can be find in https://go-critic.github.io/overview. - settings: - captLocal: - # Whether to restrict checker to params only. - # Default: true - paramsOnly: false - underef: - # Whether to skip (*x).method() calls where x is a pointer receiver. - # Default: true - skipRecvDeref: false - - gomodguard: - blocked: - # List of blocked modules. - # Default: [] - modules: - - github.com/golang/protobuf: - recommendations: - - google.golang.org/protobuf - reason: "see https://developers.google.com/protocol-buffers/docs/reference/go/faq#modules" - - github.com/satori/go.uuid: - recommendations: - - github.com/google/uuid - reason: "satori's package is not maintained" - - github.com/gofrs/uuid: - recommendations: - - github.com/gofrs/uuid/v5 - reason: "gofrs' package was not go module before v5" - - govet: - # Enable all analyzers. - # Default: false - enable-all: true - # Disable analyzers by name. - # Run `go tool vet help` to see all analyzers. - # Default: [] - disable: - - fieldalignment # too strict - # Settings per analyzer. - settings: - shadow: - # Whether to be strict about shadowing; can be noisy. - # Default: false - strict: false - - inamedparam: - # Skips check for interface methods with only a single parameter. - # Default: false - skip-single-param: true - - mnd: - # List of function patterns to exclude from analysis. - # Values always ignored: `time.Date`, - # `strconv.FormatInt`, `strconv.FormatUint`, `strconv.FormatFloat`, - # `strconv.ParseInt`, `strconv.ParseUint`, `strconv.ParseFloat`. - # Default: [] - ignored-functions: - - args.Error - - flag.Arg - - flag.Duration.* - - flag.Float.* - - flag.Int.* - - flag.Uint.* - - os.Chmod - - os.Mkdir.* - - os.OpenFile - - os.WriteFile - - prometheus.ExponentialBuckets.* - - prometheus.LinearBuckets - - nakedret: - # Make an issue if func has more lines of code than this setting, and it has naked returns. - # Default: 30 - max-func-lines: 0 - - nolintlint: - # Exclude following linters from requiring an explanation. - # Default: [] - allow-no-explanation: [funlen, gocognit, lll] - # Enable to require an explanation of nonzero length after each nolint directive. - # Default: false - require-explanation: true - # Enable to require nolint directives to mention the specific linter being suppressed. - # Default: false - require-specific: true - - perfsprint: - # Optimizes into strings concatenation. - # Default: true - strconcat: false - - rowserrcheck: - # database/sql is always checked - # Default: [] - packages: - - github.com/jmoiron/sqlx - - sloglint: - # Enforce not using global loggers. - # Values: - # - "": disabled - # - "all": report all global loggers - # - "default": report only the default slog logger - # https://github.com/go-simpler/sloglint?tab=readme-ov-file#no-global - # Default: "" - no-global: "all" - # Enforce using methods that accept a context. - # Values: - # - "": disabled - # - "all": report all contextless calls - # - "scope": report only if a context exists in the scope of the outermost function - # https://github.com/go-simpler/sloglint?tab=readme-ov-file#context-only - # Default: "" - context: "scope" - - tenv: - # The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures. - # Otherwise, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked. - # Default: false - all: true - -linters: - disable-all: true - enable: - - errcheck # checking for unchecked errors, these unchecked errors can be critical bugs in some cases - - gosimple # specializes in simplifying a code - - govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string -# - ineffassign # detects when assignments to existing variables are not used -# - staticcheck # is a go vet on steroids, applying a ton of static analysis checks -# - typecheck # like the front-end of a Go compiler, parses and type-checks Go code -# - unused # checks for unused constants, variables, functions and types -# - bodyclose # checks whether HTTP response body is closed successfully -# -# - asasalint # checks for pass []any as any in variadic func(...any) -# - asciicheck # checks that your code does not contain non-ASCII identifiers -# - bidichk # checks for dangerous unicode character sequences -# - canonicalheader # checks whether net/http.Header uses canonical header -# - copyloopvar # detects places where loop variables are copied -# - cyclop # checks function and package cyclomatic complexity -# - dupl # tool for code clone detection -# - durationcheck # checks for two durations multiplied together -# - errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error -# - errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13 -# - exhaustive # checks exhaustiveness of enum switch statements -# - exportloopref # checks for pointers to enclosing loop variables -# - fatcontext # detects nested contexts in loops -# # - forbidigo # forbids identifiers -# - funlen # tool for detection of long functions -# - gocheckcompilerdirectives # validates go compiler directive comments (//go:) -# - gochecknoglobals # checks that no global variables exist -# # - gochecknoinits # checks that no init functions are present in Go code -# - gochecksumtype # checks exhaustiveness on Go "sum types" -# - gocognit # computes and checks the cognitive complexity of functions -# - goconst # finds repeated strings that could be replaced by a constant -# - gocritic # provides diagnostics that check for bugs, performance and style issues -# - gocyclo # computes and checks the cyclomatic complexity of functions -# - godot # checks if comments end in a period -# - goimports # in addition to fixing imports, goimports also formats your code in the same style as gofmt -# - gomoddirectives # manages the use of 'replace', 'retract', and 'excludes' directives in go.mod -# - gomodguard # allow and block lists linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations -# - goprintffuncname # checks that printf-like functions are named with f at the end -# - gosec # inspects source code for security problems -# - intrange # finds places where for loops could make use of an integer range -# - lll # reports long lines -# - loggercheck # checks key value pairs for common logger libraries (kitlog,klog,logr,zap) -# - makezero # finds slice declarations with non-zero initial length -# - mirror # reports wrong mirror patterns of bytes/strings usage -# - mnd # detects magic numbers -# - musttag # enforces field tags in (un)marshaled structs -# - nakedret # finds naked returns in functions greater than a specified function length -# - nestif # reports deeply nested if statements -# - nilerr # finds the code that returns nil even if it checks that the error is not nil -# - nilnil # checks that there is no simultaneous return of nil error and an invalid value -# - noctx # finds sending http request without context.Context -# - nolintlint # reports ill-formed or insufficient nolint directives -# - nosprintfhostport # checks for misuse of Sprintf to construct a host with port in a URL -# - perfsprint # checks that fmt.Sprintf can be replaced with a faster alternative -# - predeclared # finds code that shadows one of Go's predeclared identifiers -# - promlinter # checks Prometheus metrics naming via promlint -# - protogetter # reports direct reads from proto message fields when getters should be used -# - reassign # checks that package variables are not reassigned -# - revive # fast, configurable, extensible, flexible, and beautiful linter for Go, drop-in replacement of golint -# - rowserrcheck # checks whether Err of rows is checked successfully -# - sloglint # ensure consistent code style when using log/slog -# - spancheck # checks for mistakes with OpenTelemetry/Census spans -# - sqlclosecheck # checks that sql.Rows and sql.Stmt are closed -# - stylecheck # is a replacement for golint -# - tenv # detects using os.Setenv instead of t.Setenv since Go1.17 -# - testableexamples # checks if examples are testable (have an expected output) -# - testifylint # checks usage of github.com/stretchr/testify -# - tparallel # detects inappropriate usage of t.Parallel() method in your Go test codes -# - unconvert # removes unnecessary type conversions -# - unparam # reports unused function parameters -# - usestdlibvars # detects the possibility to use variables/constants from the Go standard library -# - wastedassign # finds wasted assignment statements -# - whitespace # detects leading and trailing whitespace - -## you may want to enable -#- decorder # checks declaration order and count of types, constants, variables and functions -#- exhaustruct # [highly recommend to enable] checks if all structure fields are initialized -#- gci # controls golang package import order and makes it always deterministic -#- ginkgolinter # [if you use ginkgo/gomega] enforces standards of using ginkgo and gomega -#- godox # detects FIXME, TODO and other comment keywords -#- goheader # checks is file header matches to pattern -#- inamedparam # [great idea, but too strict, need to ignore a lot of cases by default] reports interfaces with unnamed method parameters -#- interfacebloat # checks the number of methods inside an interface -#- ireturn # accept interfaces, return concrete types -#- prealloc # [premature optimization, but can be used in some cases] finds slice declarations that could potentially be preallocated -#- tagalign # checks that struct tags are well aligned -#- varnamelen # [great idea, but too many false positives] checks that the length of a variable's name matches its scope -#- wrapcheck # checks that errors returned from external packages are wrapped -#- zerologlint # detects the wrong usage of zerolog that a user forgets to dispatch zerolog.Event - -## disabled -#- containedctx # detects struct contained context.Context field -#- contextcheck # [too many false positives] checks the function whether use a non-inherited context -#- depguard # [replaced by gomodguard] checks if package imports are in a list of acceptable packages -#- dogsled # checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) -#- dupword # [useless without config] checks for duplicate words in the source code -#- err113 # [too strict] checks the errors handling expressions -#- errchkjson # [don't see profit + I'm against of omitting errors like in the first example https://github.com/breml/errchkjson] checks types passed to the json encoding functions. Reports unsupported types and optionally reports occasions, where the check for the returned error can be omitted -#- execinquery # [deprecated] checks query string in Query function which reads your Go src files and warning it finds -#- forcetypeassert # [replaced by errcheck] finds forced type assertions -#- gofmt # [replaced by goimports] checks whether code was gofmt-ed -#- gofumpt # [replaced by goimports, gofumports is not available yet] checks whether code was gofumpt-ed -#- gosmopolitan # reports certain i18n/l10n anti-patterns in your Go codebase -#- grouper # analyzes expression groups -#- importas # enforces consistent import aliases -#- maintidx # measures the maintainability index of each function -#- misspell # [useless] finds commonly misspelled English words in comments -#- nlreturn # [too strict and mostly code is not more readable] checks for a new line before return and branch statements to increase code clarity -#- paralleltest # [too many false positives] detects missing usage of t.Parallel() method in your Go test -#- tagliatelle # checks the struct tags -#- thelper # detects golang test helpers without t.Helper() call and checks the consistency of test helpers -#- wsl # [too strict and mostly code is not more readable] whitespace linter forces you to use empty lines - -issues: - # Maximum count of issues with the same text. - # Set to 0 to disable. - # Default: 3 - max-same-issues: 50 - - exclude-rules: - - source: "(noinspection|TODO)" - linters: [godot] - - source: "//noinspection" - linters: [gocritic] - - path: "_test\\.go" - linters: - - bodyclose - - dupl - - funlen - - goconst - - gosec - - noctx - - wrapcheck - - errcheck diff --git a/web/apps/agent/.goreleaser.yaml b/web/apps/agent/.goreleaser.yaml deleted file mode 100644 index a5dc64be79..0000000000 --- a/web/apps/agent/.goreleaser.yaml +++ /dev/null @@ -1,82 +0,0 @@ -# yaml-language-server: $schema=https://goreleaser.com/static/schema.json -project_name: agent - -before: - hooks: - - go mod tidy - -builds: - - id: agent - main: ./cmd/main.go - binary: unkey - - ldflags: - - -X 'github.com/unkeyed/unkey/svc/agent/pkg/version.Version=${VERSION}' - - # Custom build tags templates. - # For more info refer to: https://pkg.go.dev/cmd/go#hdr-Build_constraints - tags: - - osusergo - - netgo - - static_build - - feature - - env: - - CGO_ENABLED=0 - - # GOOS list to build for. - # For more info refer to: https://pkg.go.dev/cmd/go#hdr-Environment_variables - # - # Default: [ 'darwin', 'linux', 'windows' ]. - goos: - - darwin - - freebsd - - windows - - # GOARCH to build for. - # For more info refer to: https://pkg.go.dev/cmd/go#hdr-Environment_variables - # - # Default: [ '386', 'amd64', 'arm64' ]. - goarch: - - amd64 - - arm - - arm64 -dockers: - - image_templates: - - "ghcr.io/unkeyed/agent:{{ .Version }}" - - "ghcr.io/unkeyed/agent:latest" - dockerfile: Dockerfile.goreleaser - build_flag_templates: - - "--label=org.opencontainers.image.created={{.Date}}" - - "--label=org.opencontainers.image.title={{.ProjectName}}" - - "--label=org.opencontainers.image.revision={{.FullCommit}}" - - "--label=org.opencontainers.image.version={{.Version}}" - - "--platform=linux/amd64" - use: docker - -archives: - - format: tar.gz - name_template: >- - {{ .ProjectName }}_ - {{- title .Os }}_ - {{- if eq .Arch "amd64" }}x86_64 - {{- else if eq .Arch "386" }}i386 - {{- else }}{{ .Arch }}{{ end }} - files: - - README.md - - LICENSE* - - config.*.json - -checksum: - name_template: "checksums.txt" - -snapshot: - name_template: "{{ incpatch .Version }}-next" - -changelog: - sort: asc - filters: - exclude: - - "^docs:" - - "^test:" - - "^chore:" diff --git a/web/apps/agent/Dockerfile b/web/apps/agent/Dockerfile deleted file mode 100644 index 1da59ab42f..0000000000 --- a/web/apps/agent/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM golang:1.24-alpine AS builder - - - -WORKDIR /go/src/github.com/unkeyed/unkey/web/apps/agent -COPY go.sum go.mod ./ -RUN go mod download - -COPY . . -ARG VERSION -RUN go build -o bin/unkey -ldflags "-X 'github.com/unkeyed/unkey/web/apps/agent/pkg/version.Version=${VERSION}'" ./cmd/main.go - -FROM golang:1.24-alpine -WORKDIR /usr/local/bin -COPY --from=builder /go/src/github.com/unkeyed/unkey/web/apps/agent/bin/unkey . -COPY --from=builder /go/src/github.com/unkeyed/unkey/web/apps/agent/config.production.json . -COPY --from=builder /go/src/github.com/unkeyed/unkey/web/apps/agent/config.staging.json . -COPY --from=builder /go/src/github.com/unkeyed/unkey/web/apps/agent/config.docker.json . -COPY --from=builder /go/src/github.com/unkeyed/unkey/web/apps/agent/config.apprunner.production.json . -COPY --from=builder /go/src/github.com/unkeyed/unkey/web/apps/agent/config.apprunner.staging.json . -COPY --from=builder /go/src/github.com/unkeyed/unkey/web/apps/agent/pkg/openapi/openapi.json ./pkg/openapi/openapi.json - -CMD [ "/usr/local/bin/unkey", "agent"] diff --git a/web/apps/agent/Makefile b/web/apps/agent/Makefile deleted file mode 100644 index 6d8b4db349..0000000000 --- a/web/apps/agent/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -.PHONY: install fmt test build race lint generate - -# Detect OS and set GOMAXPROCS accordingly -UNAME_S := $(shell uname -s) -ifeq ($(UNAME_S),Linux) - DETECTED_PROCS := $(shell nproc) -else ifeq ($(UNAME_S),Darwin) - DETECTED_PROCS := $(shell sysctl -n hw.ncpu) -else - DETECTED_PROCS := 4 -endif - -GOMAXPROCS_VAL := $(or $(GOMAXPROCS),$(DETECTED_PROCS)) -PARALLEL_PROCS := $(shell if [ $(GOMAXPROCS_VAL) -gt 1 ]; then expr $(GOMAXPROCS_VAL) / 2; else echo 1; fi) - -install: - @go mod tidy - -fmt: lint - @go fmt ./... - -test: - TESTCONTAINERS_RYUK_DISABLED=true go test -json -count=1 -parallel=$(PARALLEL_PROCS) -failfast ./pkg/... ./services/... | go run github.com/mfridman/tparse@ba2512e7be150bfcbd6f6220d517d3741f8f2f75 -all -smallscreen - -build: - go build -o unkey ./cmd/main.go - -race: - go install github.com/amit-davidson/Chronos/cmd/chronos - ~/go/bin/chronos --file=./cmd/main.go --mod=$$(pwd) - - -generate: - go get github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen - mkdir -p ./pkg/openapi - go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=./pkg/openapi/config.yaml ./pkg/openapi/openapi.json - buf generate diff --git a/web/apps/agent/README.md b/web/apps/agent/README.md deleted file mode 100644 index c334263464..0000000000 --- a/web/apps/agent/README.md +++ /dev/null @@ -1,15 +0,0 @@ -
-

Vault

-
Secure storage and encryption for per-tenant data encryption keys
-
- -
- unkey.com -
-
- - - -## Documentation - -The documentation lives [here](https://www.unkey.com/docs/contributing/services/agent/configuration). diff --git a/web/apps/agent/bruno/Eventrouter/Events.bru b/web/apps/agent/bruno/Eventrouter/Events.bru deleted file mode 100644 index 24623207d7..0000000000 --- a/web/apps/agent/bruno/Eventrouter/Events.bru +++ /dev/null @@ -1,47 +0,0 @@ -meta { - name: Events - type: http - seq: 1 -} - -post { - url: http://localhost:8080/v0/events?name=datasource - body: text - auth: bearer -} - -params:query { - name: datasource -} - -headers { - Content-Type: application/json -} - -auth:bearer { - token: agent-auth-secret -} - -body:json { - { - "identifier": "chronark", - "limit": 10, - "duration": 10000 - } - { - "x": 1 - } -} - -body:text { - { - "identifier": "chronark", - "limit": 10, - "duration": 10000 - } - { - "identifier": "chronark", - "limit": 10, - "duration": 10000 - } -} diff --git a/web/apps/agent/bruno/Liveness.bru b/web/apps/agent/bruno/Liveness.bru deleted file mode 100644 index e780613e65..0000000000 --- a/web/apps/agent/bruno/Liveness.bru +++ /dev/null @@ -1,19 +0,0 @@ -meta { - name: Liveness - type: http - seq: 1 -} - -post { - url: http://localhost:8080/ratelimit.v1.RatelimitService/Liveness - body: json - auth: none -} - -headers { - Content-Type: application/json -} - -body:json { - {} -} diff --git a/web/apps/agent/bruno/Ratelimit/Ratelimit.bru b/web/apps/agent/bruno/Ratelimit/Ratelimit.bru deleted file mode 100644 index 67c1056153..0000000000 --- a/web/apps/agent/bruno/Ratelimit/Ratelimit.bru +++ /dev/null @@ -1,27 +0,0 @@ -meta { - name: Ratelimit - type: http - seq: 1 -} - -post { - url: http://localhost:8081/ratelimit.v1.RatelimitService/Ratelimit - body: json - auth: bearer -} - -headers { - Content-Type: application/json -} - -auth:bearer { - token: agent-auth-secret -} - -body:json { - { - "identifier": "chronark", - "limit": 10, - "duration": 10000 - } -} diff --git a/web/apps/agent/bruno/bruno.json b/web/apps/agent/bruno/bruno.json deleted file mode 100644 index c2dd110370..0000000000 --- a/web/apps/agent/bruno/bruno.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": "1", - "name": "Agent", - "type": "collection", - "ignore": ["node_modules", ".git"] -} diff --git a/web/apps/agent/buf.gen.yaml b/web/apps/agent/buf.gen.yaml deleted file mode 100644 index 467f51ef5d..0000000000 --- a/web/apps/agent/buf.gen.yaml +++ /dev/null @@ -1,8 +0,0 @@ -version: v2 -plugins: - - remote: buf.build/protocolbuffers/go - out: gen - opt: paths=source_relative - - remote: buf.build/connectrpc/go:v1.16.2 - out: gen - opt: paths=source_relative diff --git a/web/apps/agent/buf.yaml b/web/apps/agent/buf.yaml deleted file mode 100644 index 47d83f9510..0000000000 --- a/web/apps/agent/buf.yaml +++ /dev/null @@ -1,10 +0,0 @@ -version: v1 -breaking: - use: - - FILE - - PACKAGE - - WIRE - - WIRE_JSON -lint: - use: - - DEFAULT diff --git a/web/apps/agent/cmd/agent/agent.go b/web/apps/agent/cmd/agent/agent.go deleted file mode 100644 index 4ec0d844d5..0000000000 --- a/web/apps/agent/cmd/agent/agent.go +++ /dev/null @@ -1,225 +0,0 @@ -package agent - -import ( - "context" - "fmt" - "os" - "os/signal" - "runtime/debug" - "strings" - "syscall" - - "github.com/unkeyed/unkey/svc/agent/pkg/api" - "github.com/unkeyed/unkey/svc/agent/pkg/clickhouse" - "github.com/unkeyed/unkey/svc/agent/pkg/config" - "github.com/unkeyed/unkey/svc/agent/pkg/connect" - "github.com/unkeyed/unkey/svc/agent/pkg/metrics" - "github.com/unkeyed/unkey/svc/agent/pkg/profiling" - "github.com/unkeyed/unkey/svc/agent/pkg/prometheus" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "github.com/unkeyed/unkey/svc/agent/pkg/uid" - "github.com/unkeyed/unkey/svc/agent/pkg/version" - "github.com/unkeyed/unkey/svc/agent/services/vault" - "github.com/unkeyed/unkey/svc/agent/services/vault/storage" - storageMiddleware "github.com/unkeyed/unkey/svc/agent/services/vault/storage/middleware" - "github.com/urfave/cli/v2" -) - -var Cmd = &cli.Command{ - Name: "agent", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "config", - Aliases: []string{"c"}, - Usage: "Load configuration file", - Value: "unkey.json", - DefaultText: "unkey.json", - EnvVars: []string{"AGENT_CONFIG_FILE"}, - }, - }, - Action: run, -} - -func run(c *cli.Context) error { - configFile := c.String("config") - - cfg := config.Agent{} - err := config.LoadFile(&cfg, configFile) - if err != nil { - return err - } - - if cfg.NodeId == "" { - cfg.NodeId = uid.Node() - - } - if cfg.Region == "" { - cfg.Region = "unknown" - } - logger, err := setupLogging(cfg) - if err != nil { - return err - } - logger = logger.With().Str("nodeId", cfg.NodeId).Str("platform", cfg.Platform).Str("region", cfg.Region).Str("version", version.Version).Logger() - - // Catch any panics now after we have a logger but before we start the server - defer func() { - if r := recover(); r != nil { - logger.Panic().Interface("panic", r).Bytes("stack", debug.Stack()).Msg("panic") - } - }() - - logger.Info().Str("file", configFile).Msg("configuration loaded") - - err = profiling.Start(cfg, logger) - if err != nil { - return err - } - - { - if cfg.Tracing != nil && cfg.Tracing.Axiom != nil { - var closeTracer tracing.Closer - closeTracer, err = tracing.Init(context.Background(), tracing.Config{ - Dataset: cfg.Tracing.Axiom.Dataset, - Application: "agent", - Version: "1.0.0", - AxiomToken: cfg.Tracing.Axiom.Token, - }) - if err != nil { - return err - } - defer func() { - err = closeTracer() - if err != nil { - logger.Error().Err(err).Msg("failed to close tracer") - } - }() - logger.Info().Msg("tracing to axiom") - } - } - - m := metrics.NewNoop() - if cfg.Metrics != nil && cfg.Metrics.Axiom != nil { - m, err = metrics.New(metrics.Config{ - Token: cfg.Metrics.Axiom.Token, - Dataset: cfg.Metrics.Axiom.Dataset, - Logger: logger.With().Str("pkg", "metrics").Logger(), - NodeId: cfg.NodeId, - Region: cfg.Region, - }) - if err != nil { - logger.Fatal().Err(err).Msg("unable to start metrics") - } - - } - defer m.Close() - - if cfg.Heartbeat != nil { - setupHeartbeat(cfg, logger) - } - - var ch clickhouse.Bufferer = clickhouse.NewNoop() - if cfg.Clickhouse != nil { - ch, err = clickhouse.New(clickhouse.Config{ - URL: cfg.Clickhouse.Url, - Logger: logger.With().Str("pkg", "clickhouse").Logger(), - }) - if err != nil { - return err - } - } - - s3, err := storage.NewS3(storage.S3Config{ - S3URL: cfg.Services.Vault.S3Url, - S3Bucket: cfg.Services.Vault.S3Bucket, - S3AccessKeyId: cfg.Services.Vault.S3AccessKeyId, - S3AccessKeySecret: cfg.Services.Vault.S3AccessKeySecret, - Logger: logger, - }) - if err != nil { - return fmt.Errorf("failed to create s3 storage: %w", err) - } - s3 = storageMiddleware.WithTracing("s3", s3) - v, err := vault.New(vault.Config{ - Logger: logger, - Metrics: m, - Storage: s3, - MasterKeys: strings.Split(cfg.Services.Vault.MasterKeys, ","), - }) - if err != nil { - return fmt.Errorf("failed to create vault: %w", err) - } - - if err != nil { - return fmt.Errorf("failed to create vault service: %w", err) - } - - srv, err := api.New(api.Config{ - NodeId: cfg.NodeId, - Logger: logger, - Ratelimit: nil, - Metrics: m, - Clickhouse: ch, - AuthToken: cfg.AuthToken, - Vault: v, - }) - if err != nil { - return err - } - - connectSrv, err := connect.New(connect.Config{Logger: logger, Image: cfg.Image, Metrics: m}) - if err != nil { - return err - } - - go func() { - err = connectSrv.Listen(fmt.Sprintf(":%s", cfg.RpcPort)) - if err != nil { - logger.Fatal().Err(err).Msg("failed to start connect service") - } - }() - - go func() { - logger.Info().Msgf("listening on port %s", cfg.Port) - err = srv.Listen(fmt.Sprintf(":%s", cfg.Port)) - if err != nil { - logger.Fatal().Err(err).Msg("failed to start service") - } - }() - - if cfg.Prometheus != nil { - go func() { - err = prometheus.Listen(cfg.Prometheus.Path, cfg.Prometheus.Port) - if err != nil { - logger.Fatal().Err(err).Msg("failed to start prometheus") - } - }() - } - - cShutdown := make(chan os.Signal, 1) - signal.Notify(cShutdown, os.Interrupt, syscall.SIGTERM) - - <-cShutdown - logger.Info().Msg("shutting down") - - err = connectSrv.Shutdown() - if err != nil { - return fmt.Errorf("failed to shutdown connect service: %w", err) - } - err = srv.Shutdown() - if err != nil { - return fmt.Errorf("failed to shutdown service: %w", err) - } - - return nil -} - -// TODO: generating this every time is a bit stupid, we should make this its own command -// -// and then run it as part of the build process -func init() { - _, err := config.GenerateJsonSchema(config.Agent{}, "schema.json") - if err != nil { - panic(err) - } -} diff --git a/web/apps/agent/cmd/agent/setup.go b/web/apps/agent/cmd/agent/setup.go deleted file mode 100644 index 87b306cfc6..0000000000 --- a/web/apps/agent/cmd/agent/setup.go +++ /dev/null @@ -1,46 +0,0 @@ -package agent - -import ( - "io" - "time" - - "github.com/unkeyed/unkey/svc/agent/pkg/config" - "github.com/unkeyed/unkey/svc/agent/pkg/heartbeat" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/uid" -) - -func setupLogging(cfg config.Agent) (logging.Logger, error) { - - logger := logging.New(nil) - - // runId is unique per start of the agent, this is useful for differnetiating logs between - // deployments - // If the agent is restarted, the runId will change - logger = logger.With().Str("runId", uid.New("run")).Logger() - - if cfg.Logging != nil && cfg.Logging.Axiom != nil { - ax, err := logging.NewAxiomWriter(logging.AxiomWriterConfig{ - Token: cfg.Logging.Axiom.Token, - Dataset: cfg.Logging.Axiom.Dataset, - }) - if err != nil { - return logger, err - } - logger = logging.New(&logging.Config{ - Writer: []io.Writer{ax}, - }) - logger.Info().Msg("Logging to axiom") - } - return logger, nil -} - -func setupHeartbeat(cfg config.Agent, logger logging.Logger) { - h := heartbeat.New(heartbeat.Config{ - Logger: logger, - Url: cfg.Heartbeat.URL, - Interval: time.Second * time.Duration(cfg.Heartbeat.Interval), - }) - h.RunAsync() - -} diff --git a/web/apps/agent/cmd/main.go b/web/apps/agent/cmd/main.go deleted file mode 100644 index 65e8069b18..0000000000 --- a/web/apps/agent/cmd/main.go +++ /dev/null @@ -1,40 +0,0 @@ -package main - -import ( - "fmt" - "os" - - "github.com/Southclaws/fault" - "github.com/unkeyed/unkey/svc/agent/cmd/agent" - "github.com/urfave/cli/v2" -) - -func main() { - app := &cli.App{ - Name: "unkey", - Usage: "Run unkey agents", - - Commands: []*cli.Command{ - agent.Cmd, - }, - } - - err := app.Run(os.Args) - if err != nil { - chain := fault.Flatten(err) - - fmt.Println() - fmt.Println() - - for _, e := range chain { - fmt.Printf(" - ") - if e.Location != "" { - fmt.Printf("%s\n", e.Location) - fmt.Printf(" > ") - } - fmt.Printf("%s\n", e.Message) - } - fmt.Println() - os.Exit(1) - } -} diff --git a/web/apps/agent/cmd/vault/generate_kek.go b/web/apps/agent/cmd/vault/generate_kek.go deleted file mode 100644 index 31dcc0d2f5..0000000000 --- a/web/apps/agent/cmd/vault/generate_kek.go +++ /dev/null @@ -1,27 +0,0 @@ -package vault - -import ( - "fmt" - "time" - - "github.com/spf13/cobra" - "github.com/unkeyed/unkey/svc/agent/services/vault/keys" -) - -// AgentCmd represents the agent command -var GenerateKEK = &cobra.Command{ - Use: "generate-kek", - Short: "Generate and print a new master key", - - RunE: func(cmd *cobra.Command, args []string) error { - kek, key, err := keys.GenerateMasterKey() - if err != nil { - return fmt.Errorf("failed to generate master key: %w", err) - } - - fmt.Printf("Key ID : %s\n", kek.Id) - fmt.Printf("Created : %v\n", time.UnixMilli(kek.CreatedAt)) - fmt.Printf("Secret : %s\n", key) - return nil - }, -} diff --git a/web/apps/agent/config.apprunner.production.json b/web/apps/agent/config.apprunner.production.json deleted file mode 100644 index d4fee7ef9c..0000000000 --- a/web/apps/agent/config.apprunner.production.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "$schema": "schema.json", - "platform": "aws", - "image": "${DOCKER_IMAGE}", - "nodeId": "", - "port": "${PORT}", - "rpcPort": "${RPC_PORT}", - "region": "aws::${AWS_REGION}", - "authToken": "${AUTH_TOKEN}", - "logging": { - "color": false, - "axiom": { - "dataset": "agent", - "token": "${AXIOM_TOKEN}" - } - }, - "tracing": { - "axiom": { - "dataset": "tracing", - "token": "${AXIOM_TOKEN}" - } - }, - "metrics": { - "axiom": { - "dataset": "metrics", - "token": "${AXIOM_TOKEN}" - } - }, - "services": { - "vault": { - "s3Url": "${VAULT_S3_URL}", - "s3Bucket": "${VAULT_S3_BUCKET}", - "s3AccessKeyId": "${VAULT_S3_ACCESS_KEY_ID}", - "s3AccessKeySecret": "${VAULT_S3_ACCESS_KEY_SECRET}", - "masterKeys": "${VAULT_MASTER_KEYS}" - } - }, - "heartbeat": { - "interval": 60, - "url": "${HEARTBEAT_URL}" - } -} diff --git a/web/apps/agent/config.apprunner.staging.json b/web/apps/agent/config.apprunner.staging.json deleted file mode 100644 index c5a4329864..0000000000 --- a/web/apps/agent/config.apprunner.staging.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$schema": "schema.json", - "platform": "aws", - "image": "${DOCKER_IMAGE}", - "nodeId": "", - "port": "${PORT}", - "rpcPort": "${RPC_PORT}", - "region": "aws::${AWS_REGION}", - "authToken": "${AUTH_TOKEN}", - "logging": { - "color": false - }, - "services": { - "vault": { - "s3Url": "${VAULT_S3_URL}", - "s3Bucket": "${VAULT_S3_BUCKET}", - "s3AccessKeyId": "${VAULT_S3_ACCESS_KEY_ID}", - "s3AccessKeySecret": "${VAULT_S3_ACCESS_KEY_SECRET}", - "masterKeys": "${VAULT_MASTER_KEYS}" - } - } -} diff --git a/web/apps/agent/config.docker.json b/web/apps/agent/config.docker.json deleted file mode 100644 index 7a64d26d48..0000000000 --- a/web/apps/agent/config.docker.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "$schema": "schema.json", - "port": "${PORT}", - "rpcPort": "${RPC_PORT}", - "pprof": { - "username": "admin", - "password": "admin" - }, - "authToken": "${AUTH_TOKEN}", - "nodeId": "${NODE_ID}", - "logging": {}, - "services": { - "vault": { - "s3Url": "${VAULT_S3_URL}", - "s3Bucket": "${VAULT_S3_BUCKET}", - "s3AccessKeyId": "${VAULT_S3_ACCESS_KEY_ID}", - "s3AccessKeySecret": "${VAULT_S3_ACCESS_KEY_SECRET}", - "masterKeys": "${VAULT_MASTER_KEYS}" - } - }, - "prometheus": { - "path": "/metrics", - "port": 2112 - }, - "clickhouse": { - "url": "${CLICKHOUSE_URL}" - } -} diff --git a/web/apps/agent/config.production.json b/web/apps/agent/config.production.json deleted file mode 100644 index e183459186..0000000000 --- a/web/apps/agent/config.production.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "$schema": "schema.json", - "platform": "fly", - "pprof": { - "username": "${PPROF_USERNAME}", - "password": "${PPROF_PASSWORD}" - }, - "image": "${FLY_IMAGE_REF}", - "nodeId": "node_${FLY_MACHINE_ID}", - "port": "${PORT}", - "rpcPort": "${RPC_PORT}", - "region": "fly::${FLY_REGION}", - "authToken": "${AUTH_TOKEN}", - "logging": { - "axiom": { - "dataset": "agent", - "token": "${AXIOM_TOKEN}" - } - }, - "tracing": { - "axiom": { - "dataset": "tracing", - "token": "${AXIOM_TOKEN}" - } - }, - "metrics": { - "axiom": { - "dataset": "metrics", - "token": "${AXIOM_TOKEN}" - } - }, - "services": { - "vault": { - "s3Url": "${VAULT_S3_URL}", - "s3Bucket": "${VAULT_S3_BUCKET}", - "s3AccessKeyId": "${VAULT_S3_ACCESS_KEY_ID}", - "s3AccessKeySecret": "${VAULT_S3_ACCESS_KEY_SECRET}", - "masterKeys": "${VAULT_MASTER_KEYS}" - } - }, - "heartbeat": { - "interval": 60, - "url": "${HEARTBEAT_URL}" - }, - "prometheus": { - "path": "/metrics", - "port": 2112 - }, - "pyroscope": { - "url": "${PYROSCOPE_URL}", - "user": "${PYROSCOPE_USER}", - "password": "${PYROSCOPE_PASSWORD}" - } -} diff --git a/web/apps/agent/config.staging.json b/web/apps/agent/config.staging.json deleted file mode 100644 index 251cb7aee4..0000000000 --- a/web/apps/agent/config.staging.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "$schema": "schema.json", - "platform": "fly", - "pprof": { - "username": "${PPROF_USERNAME}", - "password": "${PPROF_PASSWORD}" - }, - "image": "${FLY_IMAGE_REF}", - "nodeId": "node_${FLY_MACHINE_ID}", - "port": "${PORT}", - "rpcPort": "${RPC_PORT}", - "region": "fly::${FLY_REGION}", - "authToken": "${AUTH_TOKEN}", - "services": { - "vault": { - "s3Url": "${VAULT_S3_URL}", - "s3Bucket": "${VAULT_S3_BUCKET}", - "s3AccessKeyId": "${VAULT_S3_ACCESS_KEY_ID}", - "s3AccessKeySecret": "${VAULT_S3_ACCESS_KEY_SECRET}", - "masterKeys": "${VAULT_MASTER_KEYS}" - } - }, - "prometheus": { - "path": "/metrics", - "port": 2112 - } -} diff --git a/web/apps/agent/fly.production.toml b/web/apps/agent/fly.production.toml deleted file mode 100644 index 7ee0c45207..0000000000 --- a/web/apps/agent/fly.production.toml +++ /dev/null @@ -1,74 +0,0 @@ -# fly.toml app configuration file generated for unkey-production-agent on 2025-06-09T13:58:09+02:00 -# -# See https://fly.io/docs/reference/configuration/ for information about how to use this file. -# - -app = 'unkey-production-agent' -primary_region = 'iad' - -[experimental] -cmd = ['/usr/local/bin/unkey', 'agent', '--config=./config.production.json'] - -[build] -dockerfile = 'Dockerfile' - -[deploy] -strategy = 'canary' -max_unavailable = 10.0 - -[env] -PORT = '8080' -RPC_PORT = '9095' -SERF_PORT = '7373' - -[http_service] -internal_port = 8080 -auto_stop_machines = 'stop' -auto_start_machines = true -min_machines_running = 0 -processes = ['app'] - -[http_service.concurrency] -type = 'requests' -hard_limit = 250 -soft_limit = 100 - -[http_service.http_options] -[http_service.http_options.response] -pristine = true - -[[http_service.checks]] -interval = '30s' -timeout = '5s' -grace_period = '10s' -method = 'GET' -path = '/v1/liveness' - -[[services]] -protocol = 'tcp' -internal_port = 7373 - -[[services.ports]] -port = 7373 -handlers = ['tls'] - -[[services]] -protocol = 'tcp' -internal_port = 9095 - -[[services.ports]] -port = 9095 -handlers = ['tls'] - -[[restart]] -policy = 'always' -retries = 10 - -[[vm]] -memory = '2gb' -cpu_kind = 'shared' -cpus = 2 - -[[metrics]] -port = 2112 -path = '/metrics' diff --git a/web/apps/agent/fly.staging.toml b/web/apps/agent/fly.staging.toml deleted file mode 100644 index 1ded578aef..0000000000 --- a/web/apps/agent/fly.staging.toml +++ /dev/null @@ -1,70 +0,0 @@ -# fly.toml app configuration file generated for unkey-agent-dev on 2025-06-09T13:29:12+02:00 -# -# See https://fly.io/docs/reference/configuration/ for information about how to use this file. -# - -app = 'unkey-agent-dev' -primary_region = 'iad' - -[experimental] - cmd = ['/usr/local/bin/unkey', 'agent', '--config=./config.staging.json'] - -[build] - dockerfile = 'Dockerfile' - -[deploy] - strategy = 'canary' - max_unavailable = 1.0 - -[env] - PORT = '8080' - RPC_PORT = '9095' - SERF_PORT = '7373' - -[http_service] - internal_port = 8080 - auto_stop_machines = 'stop' - auto_start_machines = true - min_machines_running = 0 - processes = ['app'] - - [http_service.concurrency] - type = 'requests' - hard_limit = 1000 - soft_limit = 500 - - [http_service.http_options] - [http_service.http_options.response] - pristine = true - - [[http_service.checks]] - interval = '30s' - timeout = '5s' - grace_period = '10s' - method = 'GET' - path = '/v1/liveness' - -[[services]] - protocol = 'tcp' - internal_port = 7373 - - [[services.ports]] - port = 7373 - handlers = ['tls'] - -[[services]] - protocol = 'tcp' - internal_port = 9095 - - [[services.ports]] - port = 9095 - handlers = ['tls'] - -[[vm]] - memory = '1gb' - cpu_kind = 'shared' - cpus = 1 - -[[metrics]] - port = 2112 - path = '/metrics' diff --git a/web/apps/agent/gen/proto/cluster/v1/clusterv1connect/service.connect.go b/web/apps/agent/gen/proto/cluster/v1/clusterv1connect/service.connect.go deleted file mode 100644 index bf5cc9517c..0000000000 --- a/web/apps/agent/gen/proto/cluster/v1/clusterv1connect/service.connect.go +++ /dev/null @@ -1,117 +0,0 @@ -// Code generated by protoc-gen-connect-go. DO NOT EDIT. -// -// Source: proto/cluster/v1/service.proto - -package clusterv1connect - -import ( - connect "connectrpc.com/connect" - context "context" - errors "errors" - v1 "github.com/unkeyed/unkey/svc/agent/gen/proto/cluster/v1" - http "net/http" - strings "strings" -) - -// This is a compile-time assertion to ensure that this generated file and the connect package are -// compatible. If you get a compiler error that this constant is not defined, this code was -// generated with a version of connect newer than the one compiled into your binary. You can fix the -// problem by either regenerating this code with an older version of connect or updating the connect -// version compiled into your binary. -const _ = connect.IsAtLeastVersion1_13_0 - -const ( - // ClusterServiceName is the fully-qualified name of the ClusterService service. - ClusterServiceName = "cluster.v1.ClusterService" -) - -// These constants are the fully-qualified names of the RPCs defined in this package. They're -// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. -// -// Note that these are different from the fully-qualified method names used by -// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to -// reflection-formatted method names, remove the leading slash and convert the remaining slash to a -// period. -const ( - // ClusterServiceAnnounceStateChangeProcedure is the fully-qualified name of the ClusterService's - // AnnounceStateChange RPC. - ClusterServiceAnnounceStateChangeProcedure = "/cluster.v1.ClusterService/AnnounceStateChange" -) - -// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. -var ( - clusterServiceServiceDescriptor = v1.File_proto_cluster_v1_service_proto.Services().ByName("ClusterService") - clusterServiceAnnounceStateChangeMethodDescriptor = clusterServiceServiceDescriptor.Methods().ByName("AnnounceStateChange") -) - -// ClusterServiceClient is a client for the cluster.v1.ClusterService service. -type ClusterServiceClient interface { - // Announce that a node is changing state - // When a node shuts down, it should announce that it is leaving the cluster, so other nodes can remove it from their view of the cluster as soon as possible. - AnnounceStateChange(context.Context, *connect.Request[v1.AnnounceStateChangeRequest]) (*connect.Response[v1.AnnounceStateChangeResponse], error) -} - -// NewClusterServiceClient constructs a client for the cluster.v1.ClusterService service. By -// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, -// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the -// connect.WithGRPC() or connect.WithGRPCWeb() options. -// -// The URL supplied here should be the base URL for the Connect or gRPC server (for example, -// http://api.acme.com or https://acme.com/grpc). -func NewClusterServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) ClusterServiceClient { - baseURL = strings.TrimRight(baseURL, "/") - return &clusterServiceClient{ - announceStateChange: connect.NewClient[v1.AnnounceStateChangeRequest, v1.AnnounceStateChangeResponse]( - httpClient, - baseURL+ClusterServiceAnnounceStateChangeProcedure, - connect.WithSchema(clusterServiceAnnounceStateChangeMethodDescriptor), - connect.WithClientOptions(opts...), - ), - } -} - -// clusterServiceClient implements ClusterServiceClient. -type clusterServiceClient struct { - announceStateChange *connect.Client[v1.AnnounceStateChangeRequest, v1.AnnounceStateChangeResponse] -} - -// AnnounceStateChange calls cluster.v1.ClusterService.AnnounceStateChange. -func (c *clusterServiceClient) AnnounceStateChange(ctx context.Context, req *connect.Request[v1.AnnounceStateChangeRequest]) (*connect.Response[v1.AnnounceStateChangeResponse], error) { - return c.announceStateChange.CallUnary(ctx, req) -} - -// ClusterServiceHandler is an implementation of the cluster.v1.ClusterService service. -type ClusterServiceHandler interface { - // Announce that a node is changing state - // When a node shuts down, it should announce that it is leaving the cluster, so other nodes can remove it from their view of the cluster as soon as possible. - AnnounceStateChange(context.Context, *connect.Request[v1.AnnounceStateChangeRequest]) (*connect.Response[v1.AnnounceStateChangeResponse], error) -} - -// NewClusterServiceHandler builds an HTTP handler from the service implementation. It returns the -// path on which to mount the handler and the handler itself. -// -// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf -// and JSON codecs. They also support gzip compression. -func NewClusterServiceHandler(svc ClusterServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { - clusterServiceAnnounceStateChangeHandler := connect.NewUnaryHandler( - ClusterServiceAnnounceStateChangeProcedure, - svc.AnnounceStateChange, - connect.WithSchema(clusterServiceAnnounceStateChangeMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - return "/cluster.v1.ClusterService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - switch r.URL.Path { - case ClusterServiceAnnounceStateChangeProcedure: - clusterServiceAnnounceStateChangeHandler.ServeHTTP(w, r) - default: - http.NotFound(w, r) - } - }) -} - -// UnimplementedClusterServiceHandler returns CodeUnimplemented from all methods. -type UnimplementedClusterServiceHandler struct{} - -func (UnimplementedClusterServiceHandler) AnnounceStateChange(context.Context, *connect.Request[v1.AnnounceStateChangeRequest]) (*connect.Response[v1.AnnounceStateChangeResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cluster.v1.ClusterService.AnnounceStateChange is not implemented")) -} diff --git a/web/apps/agent/gen/proto/cluster/v1/service.openapi.yaml b/web/apps/agent/gen/proto/cluster/v1/service.openapi.yaml deleted file mode 100644 index 46811a8e5a..0000000000 --- a/web/apps/agent/gen/proto/cluster/v1/service.openapi.yaml +++ /dev/null @@ -1,102 +0,0 @@ -openapi: 3.1.0 -info: - title: cluster.v1 -paths: - /cluster.v1.ClusterService/AnnounceStateChange: - post: - tags: - - cluster.v1.ClusterService - description: |- - Announce that a node is changing state - When a node shuts down, it should announce that it is leaving the cluster, so other nodes can remove it from their view of the cluster as soon as possible. - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/cluster.v1.AnnounceStateChangeRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/cluster.v1.AnnounceStateChangeResponse' -components: - schemas: - cluster.v1.NodeState: - type: string - title: NodeState - enum: - - NODE_STATE_UNSPECIFIED - - NODE_STATE_JOINING - - NODE_STATE_LEAVING - - NODE_STATE_ACTIVE - cluster.v1.AnnounceStateChangeRequest: - type: object - properties: - nodeId: - type: string - title: node_id - additionalProperties: false - state: - $ref: '#/components/schemas/cluster.v1.NodeState' - title: AnnounceStateChangeRequest - additionalProperties: false - cluster.v1.AnnounceStateChangeResponse: - type: object - title: AnnounceStateChangeResponse - additionalProperties: false - connect.error: - type: object - properties: - code: - type: string - examples: - - CodeNotFound - enum: - - CodeCanceled - - CodeUnknown - - CodeInvalidArgument - - CodeDeadlineExceeded - - CodeNotFound - - CodeAlreadyExists - - CodePermissionDenied - - CodeResourceExhausted - - CodeFailedPrecondition - - CodeAborted - - CodeOutOfRange - - CodeInternal - - CodeUnavailable - - CodeDataLoss - - CodeUnauthenticated - description: The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. - message: - type: string - description: A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. - detail: - $ref: '#/components/schemas/google.protobuf.Any' - title: Connect Error - additionalProperties: true - description: 'Error type returned by Connect: https://connectrpc.com/docs/go/errors/#http-representation' - google.protobuf.Any: - type: object - properties: - type: - type: string - value: - type: string - format: binary - debug: - type: object - additionalProperties: true - additionalProperties: true - description: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message. -security: [] -tags: - - name: cluster.v1.ClusterService -externalDocs: {} diff --git a/web/apps/agent/gen/proto/cluster/v1/service.pb.go b/web/apps/agent/gen/proto/cluster/v1/service.pb.go deleted file mode 100644 index e31a590577..0000000000 --- a/web/apps/agent/gen/proto/cluster/v1/service.pb.go +++ /dev/null @@ -1,284 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.34.2 -// protoc (unknown) -// source: proto/cluster/v1/service.proto - -package clusterv1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type NodeState int32 - -const ( - NodeState_NODE_STATE_UNSPECIFIED NodeState = 0 - NodeState_NODE_STATE_JOINING NodeState = 1 - NodeState_NODE_STATE_LEAVING NodeState = 2 - NodeState_NODE_STATE_ACTIVE NodeState = 3 -) - -// Enum value maps for NodeState. -var ( - NodeState_name = map[int32]string{ - 0: "NODE_STATE_UNSPECIFIED", - 1: "NODE_STATE_JOINING", - 2: "NODE_STATE_LEAVING", - 3: "NODE_STATE_ACTIVE", - } - NodeState_value = map[string]int32{ - "NODE_STATE_UNSPECIFIED": 0, - "NODE_STATE_JOINING": 1, - "NODE_STATE_LEAVING": 2, - "NODE_STATE_ACTIVE": 3, - } -) - -func (x NodeState) Enum() *NodeState { - p := new(NodeState) - *p = x - return p -} - -func (x NodeState) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (NodeState) Descriptor() protoreflect.EnumDescriptor { - return file_proto_cluster_v1_service_proto_enumTypes[0].Descriptor() -} - -func (NodeState) Type() protoreflect.EnumType { - return &file_proto_cluster_v1_service_proto_enumTypes[0] -} - -func (x NodeState) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use NodeState.Descriptor instead. -func (NodeState) EnumDescriptor() ([]byte, []int) { - return file_proto_cluster_v1_service_proto_rawDescGZIP(), []int{0} -} - -type AnnounceStateChangeRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` - State NodeState `protobuf:"varint,2,opt,name=state,proto3,enum=cluster.v1.NodeState" json:"state,omitempty"` -} - -func (x *AnnounceStateChangeRequest) Reset() { - *x = AnnounceStateChangeRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_cluster_v1_service_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AnnounceStateChangeRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AnnounceStateChangeRequest) ProtoMessage() {} - -func (x *AnnounceStateChangeRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_cluster_v1_service_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AnnounceStateChangeRequest.ProtoReflect.Descriptor instead. -func (*AnnounceStateChangeRequest) Descriptor() ([]byte, []int) { - return file_proto_cluster_v1_service_proto_rawDescGZIP(), []int{0} -} - -func (x *AnnounceStateChangeRequest) GetNodeId() string { - if x != nil { - return x.NodeId - } - return "" -} - -func (x *AnnounceStateChangeRequest) GetState() NodeState { - if x != nil { - return x.State - } - return NodeState_NODE_STATE_UNSPECIFIED -} - -type AnnounceStateChangeResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *AnnounceStateChangeResponse) Reset() { - *x = AnnounceStateChangeResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_cluster_v1_service_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AnnounceStateChangeResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AnnounceStateChangeResponse) ProtoMessage() {} - -func (x *AnnounceStateChangeResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_cluster_v1_service_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AnnounceStateChangeResponse.ProtoReflect.Descriptor instead. -func (*AnnounceStateChangeResponse) Descriptor() ([]byte, []int) { - return file_proto_cluster_v1_service_proto_rawDescGZIP(), []int{1} -} - -var File_proto_cluster_v1_service_proto protoreflect.FileDescriptor - -var file_proto_cluster_v1_service_proto_rawDesc = []byte{ - 0x0a, 0x1e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, - 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x0a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x22, 0x62, 0x0a, 0x1a, - 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, - 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, - 0x65, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x22, 0x1d, 0x0a, 0x1b, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, - 0x6e, 0x0a, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x16, - 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x4e, 0x4f, 0x44, 0x45, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x4a, 0x4f, 0x49, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, - 0x12, 0x16, 0x0a, 0x12, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x4c, - 0x45, 0x41, 0x56, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x4e, 0x4f, 0x44, 0x45, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x03, 0x32, - 0x7a, 0x0a, 0x0e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x68, 0x0a, 0x13, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x27, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, - 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x44, 0x5a, 0x42, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x6e, 0x6b, 0x65, 0x79, 0x65, - 0x64, 0x2f, 0x75, 0x6e, 0x6b, 0x65, 0x79, 0x2f, 0x61, 0x70, 0x70, 0x73, 0x2f, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x76, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_cluster_v1_service_proto_rawDescOnce sync.Once - file_proto_cluster_v1_service_proto_rawDescData = file_proto_cluster_v1_service_proto_rawDesc -) - -func file_proto_cluster_v1_service_proto_rawDescGZIP() []byte { - file_proto_cluster_v1_service_proto_rawDescOnce.Do(func() { - file_proto_cluster_v1_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_cluster_v1_service_proto_rawDescData) - }) - return file_proto_cluster_v1_service_proto_rawDescData -} - -var file_proto_cluster_v1_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_proto_cluster_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_proto_cluster_v1_service_proto_goTypes = []any{ - (NodeState)(0), // 0: cluster.v1.NodeState - (*AnnounceStateChangeRequest)(nil), // 1: cluster.v1.AnnounceStateChangeRequest - (*AnnounceStateChangeResponse)(nil), // 2: cluster.v1.AnnounceStateChangeResponse -} -var file_proto_cluster_v1_service_proto_depIdxs = []int32{ - 0, // 0: cluster.v1.AnnounceStateChangeRequest.state:type_name -> cluster.v1.NodeState - 1, // 1: cluster.v1.ClusterService.AnnounceStateChange:input_type -> cluster.v1.AnnounceStateChangeRequest - 2, // 2: cluster.v1.ClusterService.AnnounceStateChange:output_type -> cluster.v1.AnnounceStateChangeResponse - 2, // [2:3] is the sub-list for method output_type - 1, // [1:2] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_proto_cluster_v1_service_proto_init() } -func file_proto_cluster_v1_service_proto_init() { - if File_proto_cluster_v1_service_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_cluster_v1_service_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*AnnounceStateChangeRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_cluster_v1_service_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*AnnounceStateChangeResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_cluster_v1_service_proto_rawDesc, - NumEnums: 1, - NumMessages: 2, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_cluster_v1_service_proto_goTypes, - DependencyIndexes: file_proto_cluster_v1_service_proto_depIdxs, - EnumInfos: file_proto_cluster_v1_service_proto_enumTypes, - MessageInfos: file_proto_cluster_v1_service_proto_msgTypes, - }.Build() - File_proto_cluster_v1_service_proto = out.File - file_proto_cluster_v1_service_proto_rawDesc = nil - file_proto_cluster_v1_service_proto_goTypes = nil - file_proto_cluster_v1_service_proto_depIdxs = nil -} diff --git a/web/apps/agent/gen/proto/errors/v1/errors.openapi.yaml b/web/apps/agent/gen/proto/errors/v1/errors.openapi.yaml deleted file mode 100644 index c84f387af2..0000000000 --- a/web/apps/agent/gen/proto/errors/v1/errors.openapi.yaml +++ /dev/null @@ -1,204 +0,0 @@ -openapi: 3.1.0 -info: - title: errors.v1 -paths: {} -components: - schemas: - errors.v1.ErrorCode: - type: string - title: ErrorCode - enum: - - ErrorCodeUnspecified - - ErrorCodeInternal - errors.v1.Fault: - type: string - title: Fault - enum: - - FAULT_UNSPECIFIED - - FAULT_UNKNOWN - - FAULT_PLANETSCALE - - FAULT_GITHUB - errors.v1.Service: - type: string - title: Service - enum: - - ServiceUnknown - - ServiceAgent - - ServiceAuth - - ServiceCatalog - - ServiceConfig - - ServiceDNS - - ServiceSentinel - - ServiceGitHub - - ServiceKubernetes - - ServiceLog - - ServiceMetrics - - ServiceMonitor - - ServiceNetwork - - ServiceOperator - - ServiceRegistry - - ServiceSecret - - ServiceStorage - - ServiceSystem - - ServiceTelemetry - - ServiceToken - - ServiceUser - - ServiceVault - - ServiceWebhook - google.protobuf.NullValue: - type: string - title: NullValue - enum: - - NULL_VALUE - description: |- - `NullValue` is a singleton enumeration to represent the null value for the - `Value` type union. - - The JSON representation for `NullValue` is JSON `null`. - errors.v1.Action: - type: object - properties: - url: - type: string - title: url - additionalProperties: false - label: - type: string - title: label - additionalProperties: false - description: - type: string - title: description - additionalProperties: false - title: Action - additionalProperties: false - errors.v1.Error: - type: object - properties: - fault: - $ref: '#/components/schemas/errors.v1.Fault' - group: - type: string - title: group - additionalProperties: false - code: - $ref: '#/components/schemas/errors.v1.ErrorCode' - type: - type: string - title: type - additionalProperties: false - metadata: - $ref: '#/components/schemas/google.protobuf.Struct' - actions: - type: array - items: - $ref: '#/components/schemas/errors.v1.Action' - title: Error - additionalProperties: false - google.protobuf.ListValue: - type: object - properties: - values: - type: array - items: - $ref: '#/components/schemas/google.protobuf.Value' - title: ListValue - additionalProperties: false - description: |- - `ListValue` is a wrapper around a repeated field of values. - - The JSON representation for `ListValue` is JSON array. - google.protobuf.Struct: - type: object - properties: - fields: - type: object - title: fields - additionalProperties: - $ref: '#/components/schemas/google.protobuf.Value' - description: Unordered map of dynamically typed values. - title: Struct - additionalProperties: false - description: |- - `Struct` represents a structured data value, consisting of fields - which map to dynamically typed values. In some languages, `Struct` - might be supported by a native representation. For example, in - scripting languages like JS a struct is represented as an - object. The details of that representation are described together - with the proto support for the language. - - The JSON representation for `Struct` is JSON object. - google.protobuf.Struct.FieldsEntry: - type: object - properties: - key: - type: string - title: key - additionalProperties: false - value: - $ref: '#/components/schemas/google.protobuf.Value' - title: FieldsEntry - additionalProperties: false - google.protobuf.Value: - oneOf: - - type: "null" - - type: number - - type: string - - type: boolean - - type: array - - type: object - additionalProperties: true - description: |- - `Value` represents a dynamically typed value which can be either - null, a number, a string, a boolean, a recursive struct value, or a - list of values. A producer of value is expected to set one of these - variants. Absence of any variant indicates an error. - - The JSON representation for `Value` is JSON value. - connect.error: - type: object - properties: - code: - type: string - examples: - - CodeNotFound - enum: - - CodeCanceled - - CodeUnknown - - CodeInvalidArgument - - CodeDeadlineExceeded - - CodeNotFound - - CodeAlreadyExists - - CodePermissionDenied - - CodeResourceExhausted - - CodeFailedPrecondition - - CodeAborted - - CodeOutOfRange - - CodeInternal - - CodeUnavailable - - CodeDataLoss - - CodeUnauthenticated - description: The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. - message: - type: string - description: A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. - detail: - $ref: '#/components/schemas/google.protobuf.Any' - title: Connect Error - additionalProperties: true - description: 'Error type returned by Connect: https://connectrpc.com/docs/go/errors/#http-representation' - google.protobuf.Any: - type: object - properties: - type: - type: string - value: - type: string - format: binary - debug: - type: object - additionalProperties: true - additionalProperties: true - description: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message. -security: [] -externalDocs: {} diff --git a/web/apps/agent/gen/proto/errors/v1/errors.pb.go b/web/apps/agent/gen/proto/errors/v1/errors.pb.go deleted file mode 100644 index 46e19a2f99..0000000000 --- a/web/apps/agent/gen/proto/errors/v1/errors.pb.go +++ /dev/null @@ -1,545 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.34.1 -// protoc (unknown) -// source: proto/errors/v1/errors.proto - -package errorsv1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - structpb "google.golang.org/protobuf/types/known/structpb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Fault int32 - -const ( - Fault_FAULT_UNSPECIFIED Fault = 0 - Fault_FAULT_UNKNOWN Fault = 1 - Fault_FAULT_PLANETSCALE Fault = 2 - Fault_FAULT_GITHUB Fault = 3 -) - -// Enum value maps for Fault. -var ( - Fault_name = map[int32]string{ - 0: "FAULT_UNSPECIFIED", - 1: "FAULT_UNKNOWN", - 2: "FAULT_PLANETSCALE", - 3: "FAULT_GITHUB", - } - Fault_value = map[string]int32{ - "FAULT_UNSPECIFIED": 0, - "FAULT_UNKNOWN": 1, - "FAULT_PLANETSCALE": 2, - "FAULT_GITHUB": 3, - } -) - -func (x Fault) Enum() *Fault { - p := new(Fault) - *p = x - return p -} - -func (x Fault) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Fault) Descriptor() protoreflect.EnumDescriptor { - return file_proto_errors_v1_errors_proto_enumTypes[0].Descriptor() -} - -func (Fault) Type() protoreflect.EnumType { - return &file_proto_errors_v1_errors_proto_enumTypes[0] -} - -func (x Fault) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Fault.Descriptor instead. -func (Fault) EnumDescriptor() ([]byte, []int) { - return file_proto_errors_v1_errors_proto_rawDescGZIP(), []int{0} -} - -type Service int32 - -const ( - Service_ServiceUnknown Service = 0 - Service_ServiceAgent Service = 1 - Service_ServiceAuth Service = 2 - Service_ServiceCatalog Service = 3 - Service_ServiceConfig Service = 4 - Service_ServiceDNS Service = 5 - Service_ServiceSentinel Service = 6 - Service_ServiceGitHub Service = 7 - Service_ServiceKubernetes Service = 8 - Service_ServiceLog Service = 9 - Service_ServiceMetrics Service = 10 - Service_ServiceMonitor Service = 11 - Service_ServiceNetwork Service = 12 - Service_ServiceOperator Service = 13 - Service_ServiceRegistry Service = 14 - Service_ServiceSecret Service = 15 - Service_ServiceStorage Service = 16 - Service_ServiceSystem Service = 17 - Service_ServiceTelemetry Service = 18 - Service_ServiceToken Service = 19 - Service_ServiceUser Service = 20 - Service_ServiceVault Service = 21 - Service_ServiceWebhook Service = 22 -) - -// Enum value maps for Service. -var ( - Service_name = map[int32]string{ - 0: "ServiceUnknown", - 1: "ServiceAgent", - 2: "ServiceAuth", - 3: "ServiceCatalog", - 4: "ServiceConfig", - 5: "ServiceDNS", - 6: "ServiceSentinel", - 7: "ServiceGitHub", - 8: "ServiceKubernetes", - 9: "ServiceLog", - 10: "ServiceMetrics", - 11: "ServiceMonitor", - 12: "ServiceNetwork", - 13: "ServiceOperator", - 14: "ServiceRegistry", - 15: "ServiceSecret", - 16: "ServiceStorage", - 17: "ServiceSystem", - 18: "ServiceTelemetry", - 19: "ServiceToken", - 20: "ServiceUser", - 21: "ServiceVault", - 22: "ServiceWebhook", - } - Service_value = map[string]int32{ - "ServiceUnknown": 0, - "ServiceAgent": 1, - "ServiceAuth": 2, - "ServiceCatalog": 3, - "ServiceConfig": 4, - "ServiceDNS": 5, - "ServiceSentinel": 6, - "ServiceGitHub": 7, - "ServiceKubernetes": 8, - "ServiceLog": 9, - "ServiceMetrics": 10, - "ServiceMonitor": 11, - "ServiceNetwork": 12, - "ServiceOperator": 13, - "ServiceRegistry": 14, - "ServiceSecret": 15, - "ServiceStorage": 16, - "ServiceSystem": 17, - "ServiceTelemetry": 18, - "ServiceToken": 19, - "ServiceUser": 20, - "ServiceVault": 21, - "ServiceWebhook": 22, - } -) - -func (x Service) Enum() *Service { - p := new(Service) - *p = x - return p -} - -func (x Service) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Service) Descriptor() protoreflect.EnumDescriptor { - return file_proto_errors_v1_errors_proto_enumTypes[1].Descriptor() -} - -func (Service) Type() protoreflect.EnumType { - return &file_proto_errors_v1_errors_proto_enumTypes[1] -} - -func (x Service) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Service.Descriptor instead. -func (Service) EnumDescriptor() ([]byte, []int) { - return file_proto_errors_v1_errors_proto_rawDescGZIP(), []int{1} -} - -type ErrorCode int32 - -const ( - ErrorCode_ErrorCodeUnspecified ErrorCode = 0 - ErrorCode_ErrorCodeInternal ErrorCode = 1 -) - -// Enum value maps for ErrorCode. -var ( - ErrorCode_name = map[int32]string{ - 0: "ErrorCodeUnspecified", - 1: "ErrorCodeInternal", - } - ErrorCode_value = map[string]int32{ - "ErrorCodeUnspecified": 0, - "ErrorCodeInternal": 1, - } -) - -func (x ErrorCode) Enum() *ErrorCode { - p := new(ErrorCode) - *p = x - return p -} - -func (x ErrorCode) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (ErrorCode) Descriptor() protoreflect.EnumDescriptor { - return file_proto_errors_v1_errors_proto_enumTypes[2].Descriptor() -} - -func (ErrorCode) Type() protoreflect.EnumType { - return &file_proto_errors_v1_errors_proto_enumTypes[2] -} - -func (x ErrorCode) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use ErrorCode.Descriptor instead. -func (ErrorCode) EnumDescriptor() ([]byte, []int) { - return file_proto_errors_v1_errors_proto_rawDescGZIP(), []int{2} -} - -type Action struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Url *string `protobuf:"bytes,1,opt,name=url,proto3,oneof" json:"url,omitempty"` - Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` - Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` -} - -func (x *Action) Reset() { - *x = Action{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_errors_v1_errors_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Action) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Action) ProtoMessage() {} - -func (x *Action) ProtoReflect() protoreflect.Message { - mi := &file_proto_errors_v1_errors_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Action.ProtoReflect.Descriptor instead. -func (*Action) Descriptor() ([]byte, []int) { - return file_proto_errors_v1_errors_proto_rawDescGZIP(), []int{0} -} - -func (x *Action) GetUrl() string { - if x != nil && x.Url != nil { - return *x.Url - } - return "" -} - -func (x *Action) GetLabel() string { - if x != nil { - return x.Label - } - return "" -} - -func (x *Action) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -type Error struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Fault Fault `protobuf:"varint,1,opt,name=fault,proto3,enum=errors.v1.Fault" json:"fault,omitempty"` - Group string `protobuf:"bytes,2,opt,name=group,proto3" json:"group,omitempty"` - Code ErrorCode `protobuf:"varint,3,opt,name=code,proto3,enum=errors.v1.ErrorCode" json:"code,omitempty"` - Type string `protobuf:"bytes,4,opt,name=type,proto3" json:"type,omitempty"` - Metadata *structpb.Struct `protobuf:"bytes,5,opt,name=metadata,proto3" json:"metadata,omitempty"` - // Suggested actions the user should take to resolve this error. - // These actions are not guaranteed to resolve the error, but they are a good starting point. - // - // As a last resort, the user should contact support. - // - // The actions are ordered by importance, the first action should be presented first. - Actions []*Action `protobuf:"bytes,6,rep,name=actions,proto3" json:"actions,omitempty"` -} - -func (x *Error) Reset() { - *x = Error{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_errors_v1_errors_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Error) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Error) ProtoMessage() {} - -func (x *Error) ProtoReflect() protoreflect.Message { - mi := &file_proto_errors_v1_errors_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Error.ProtoReflect.Descriptor instead. -func (*Error) Descriptor() ([]byte, []int) { - return file_proto_errors_v1_errors_proto_rawDescGZIP(), []int{1} -} - -func (x *Error) GetFault() Fault { - if x != nil { - return x.Fault - } - return Fault_FAULT_UNSPECIFIED -} - -func (x *Error) GetGroup() string { - if x != nil { - return x.Group - } - return "" -} - -func (x *Error) GetCode() ErrorCode { - if x != nil { - return x.Code - } - return ErrorCode_ErrorCodeUnspecified -} - -func (x *Error) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *Error) GetMetadata() *structpb.Struct { - if x != nil { - return x.Metadata - } - return nil -} - -func (x *Error) GetActions() []*Action { - if x != nil { - return x.Actions - } - return nil -} - -var File_proto_errors_v1_errors_proto protoreflect.FileDescriptor - -var file_proto_errors_v1_errors_proto_rawDesc = []byte{ - 0x0a, 0x1c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2f, 0x76, - 0x31, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, - 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5f, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x15, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, - 0x52, 0x03, 0x75, 0x72, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, - 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x20, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x75, 0x72, 0x6c, 0x22, 0xe5, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x26, 0x0a, 0x05, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x10, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x61, - 0x75, 0x6c, 0x74, 0x52, 0x05, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x12, 0x28, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, - 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x33, - 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x2b, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x76, 0x31, - 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2a, 0x5a, 0x0a, 0x05, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x15, 0x0a, 0x11, 0x46, 0x41, 0x55, - 0x4c, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x11, 0x0a, 0x0d, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, - 0x4e, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x50, 0x4c, 0x41, - 0x4e, 0x45, 0x54, 0x53, 0x43, 0x41, 0x4c, 0x45, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x46, 0x41, - 0x55, 0x4c, 0x54, 0x5f, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42, 0x10, 0x03, 0x2a, 0xc4, 0x03, 0x0a, - 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x10, 0x01, 0x12, 0x0f, - 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x10, 0x02, 0x12, - 0x12, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, - 0x67, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x44, 0x4e, 0x53, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x10, 0x06, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x47, 0x69, 0x74, 0x48, 0x75, 0x62, 0x10, 0x07, 0x12, 0x15, 0x0a, - 0x11, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, - 0x65, 0x73, 0x10, 0x08, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4c, - 0x6f, 0x67, 0x10, 0x09, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x10, 0x0b, 0x12, 0x12, 0x0a, 0x0e, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x10, 0x0c, - 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x6f, 0x72, 0x10, 0x0d, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x10, 0x0e, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x10, 0x0f, 0x12, 0x12, 0x0a, - 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x10, - 0x10, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x10, 0x11, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, - 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x10, 0x12, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0x13, 0x12, 0x0f, 0x0a, 0x0b, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x55, 0x73, 0x65, 0x72, 0x10, 0x14, 0x12, 0x10, 0x0a, - 0x0c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x15, 0x12, - 0x12, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, - 0x6b, 0x10, 0x16, 0x2a, 0x3c, 0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, - 0x12, 0x18, 0x0a, 0x14, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x55, 0x6e, 0x73, - 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x10, - 0x01, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x75, 0x6e, 0x6b, 0x65, 0x79, 0x65, 0x64, 0x2f, 0x75, 0x6e, 0x6b, 0x65, 0x79, 0x2f, 0x61, 0x70, - 0x70, 0x73, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x73, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_errors_v1_errors_proto_rawDescOnce sync.Once - file_proto_errors_v1_errors_proto_rawDescData = file_proto_errors_v1_errors_proto_rawDesc -) - -func file_proto_errors_v1_errors_proto_rawDescGZIP() []byte { - file_proto_errors_v1_errors_proto_rawDescOnce.Do(func() { - file_proto_errors_v1_errors_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_errors_v1_errors_proto_rawDescData) - }) - return file_proto_errors_v1_errors_proto_rawDescData -} - -var file_proto_errors_v1_errors_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_proto_errors_v1_errors_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_proto_errors_v1_errors_proto_goTypes = []interface{}{ - (Fault)(0), // 0: errors.v1.Fault - (Service)(0), // 1: errors.v1.Service - (ErrorCode)(0), // 2: errors.v1.ErrorCode - (*Action)(nil), // 3: errors.v1.Action - (*Error)(nil), // 4: errors.v1.Error - (*structpb.Struct)(nil), // 5: google.protobuf.Struct -} -var file_proto_errors_v1_errors_proto_depIdxs = []int32{ - 0, // 0: errors.v1.Error.fault:type_name -> errors.v1.Fault - 2, // 1: errors.v1.Error.code:type_name -> errors.v1.ErrorCode - 5, // 2: errors.v1.Error.metadata:type_name -> google.protobuf.Struct - 3, // 3: errors.v1.Error.actions:type_name -> errors.v1.Action - 4, // [4:4] is the sub-list for method output_type - 4, // [4:4] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name -} - -func init() { file_proto_errors_v1_errors_proto_init() } -func file_proto_errors_v1_errors_proto_init() { - if File_proto_errors_v1_errors_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_errors_v1_errors_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Action); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_errors_v1_errors_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Error); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_proto_errors_v1_errors_proto_msgTypes[0].OneofWrappers = []interface{}{} - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_errors_v1_errors_proto_rawDesc, - NumEnums: 3, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_proto_errors_v1_errors_proto_goTypes, - DependencyIndexes: file_proto_errors_v1_errors_proto_depIdxs, - EnumInfos: file_proto_errors_v1_errors_proto_enumTypes, - MessageInfos: file_proto_errors_v1_errors_proto_msgTypes, - }.Build() - File_proto_errors_v1_errors_proto = out.File - file_proto_errors_v1_errors_proto_rawDesc = nil - file_proto_errors_v1_errors_proto_goTypes = nil - file_proto_errors_v1_errors_proto_depIdxs = nil -} diff --git a/web/apps/agent/gen/proto/gossip/v1/gossip.openapi.yaml b/web/apps/agent/gen/proto/gossip/v1/gossip.openapi.yaml deleted file mode 100644 index d651a45cbe..0000000000 --- a/web/apps/agent/gen/proto/gossip/v1/gossip.openapi.yaml +++ /dev/null @@ -1,217 +0,0 @@ -openapi: 3.1.0 -info: - title: gossip.v1 -paths: - /gossip.v1.GossipService/Ping: - post: - tags: - - gossip.v1.GossipService - description: |- - Ping asks for the state of a peer - If the peer is healthy, it should respond with its state - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/gossip.v1.PingRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/gossip.v1.PingResponse' - /gossip.v1.GossipService/IndirectPing: - post: - tags: - - gossip.v1.GossipService - description: |- - IndirectPing asks a peer to ping another node because we can not reach it outselves - the peer should respond with the state of the node - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/gossip.v1.IndirectPingRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/gossip.v1.IndirectPingResponse' - /gossip.v1.GossipService/SyncMembers: - post: - tags: - - gossip.v1.GossipService - description: "Periodially we do a full sync of the members\n Both nodes tell each other about every member they know and then reconcile by taking the union \n of the two sets.\n Afterwards, both nodes should have the same view of the cluster and regular gossip will get rid\n of any dead nodes\n \n If they disagree on the state of a node, the most favourable state should be chosen\n ie: if one node thinks a peer is dead and the other thinks it is alive, the node should be \n marked as alive to prevent a split brain or unnecessary false positives" - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/gossip.v1.SyncMembersRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/gossip.v1.SyncMembersResponse' -components: - schemas: - gossip.v1.State: - type: string - title: State - enum: - - State_UNSPECIFIED - - State_ALIVE - - State_DEAD - - State_LEFT - - State_SUSPECT - gossip.v1.GossipRequest: - type: object - title: GossipRequest - additionalProperties: false - description: repeated Rumor rumors = 1; - gossip.v1.GossipResponse: - type: object - title: GossipResponse - additionalProperties: false - description: repeated Rumor rumors = 1; - gossip.v1.IndirectPingRequest: - type: object - properties: - nodeId: - type: string - title: node_id - additionalProperties: false - rpcAddr: - type: string - title: rpc_addr - additionalProperties: false - title: IndirectPingRequest - additionalProperties: false - gossip.v1.IndirectPingResponse: - type: object - properties: - state: - $ref: '#/components/schemas/gossip.v1.State' - title: IndirectPingResponse - additionalProperties: false - gossip.v1.Member: - type: object - properties: - nodeId: - type: string - title: node_id - additionalProperties: false - rpcAddr: - type: string - title: rpc_addr - additionalProperties: false - title: Member - additionalProperties: false - gossip.v1.PingRequest: - type: object - title: PingRequest - additionalProperties: false - gossip.v1.PingResponse: - type: object - properties: - state: - $ref: '#/components/schemas/gossip.v1.State' - title: PingResponse - additionalProperties: false - gossip.v1.Rumor: - type: object - properties: - time: - oneOf: - - type: string - - type: number - title: time - additionalProperties: false - title: Rumor - additionalProperties: false - gossip.v1.SyncMembersRequest: - type: object - properties: - members: - type: array - items: - $ref: '#/components/schemas/gossip.v1.Member' - title: SyncMembersRequest - additionalProperties: false - gossip.v1.SyncMembersResponse: - type: object - properties: - members: - type: array - items: - $ref: '#/components/schemas/gossip.v1.Member' - title: SyncMembersResponse - additionalProperties: false - connect.error: - type: object - properties: - code: - type: string - examples: - - CodeNotFound - enum: - - CodeCanceled - - CodeUnknown - - CodeInvalidArgument - - CodeDeadlineExceeded - - CodeNotFound - - CodeAlreadyExists - - CodePermissionDenied - - CodeResourceExhausted - - CodeFailedPrecondition - - CodeAborted - - CodeOutOfRange - - CodeInternal - - CodeUnavailable - - CodeDataLoss - - CodeUnauthenticated - description: The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. - message: - type: string - description: A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. - detail: - $ref: '#/components/schemas/google.protobuf.Any' - title: Connect Error - additionalProperties: true - description: 'Error type returned by Connect: https://connectrpc.com/docs/go/errors/#http-representation' - google.protobuf.Any: - type: object - properties: - type: - type: string - value: - type: string - format: binary - debug: - type: object - additionalProperties: true - additionalProperties: true - description: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message. -security: [] -tags: - - name: gossip.v1.GossipService -externalDocs: {} diff --git a/web/apps/agent/gen/proto/gossip/v1/gossip.pb.go b/web/apps/agent/gen/proto/gossip/v1/gossip.pb.go deleted file mode 100644 index 29b42477d2..0000000000 --- a/web/apps/agent/gen/proto/gossip/v1/gossip.pb.go +++ /dev/null @@ -1,1062 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.34.2 -// protoc (unknown) -// source: proto/gossip/v1/gossip.proto - -package gossipv1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type State int32 - -const ( - State_State_UNSPECIFIED State = 0 - State_State_ALIVE State = 1 - State_State_DEAD State = 2 - State_State_LEFT State = 3 - State_State_SUSPECT State = 4 -) - -// Enum value maps for State. -var ( - State_name = map[int32]string{ - 0: "State_UNSPECIFIED", - 1: "State_ALIVE", - 2: "State_DEAD", - 3: "State_LEFT", - 4: "State_SUSPECT", - } - State_value = map[string]int32{ - "State_UNSPECIFIED": 0, - "State_ALIVE": 1, - "State_DEAD": 2, - "State_LEFT": 3, - "State_SUSPECT": 4, - } -) - -func (x State) Enum() *State { - p := new(State) - *p = x - return p -} - -func (x State) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (State) Descriptor() protoreflect.EnumDescriptor { - return file_proto_gossip_v1_gossip_proto_enumTypes[0].Descriptor() -} - -func (State) Type() protoreflect.EnumType { - return &file_proto_gossip_v1_gossip_proto_enumTypes[0] -} - -func (x State) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use State.Descriptor instead. -func (State) EnumDescriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{0} -} - -type Rumor struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Time int64 `protobuf:"varint,1,opt,name=time,proto3" json:"time,omitempty"` -} - -func (x *Rumor) Reset() { - *x = Rumor{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Rumor) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Rumor) ProtoMessage() {} - -func (x *Rumor) ProtoReflect() protoreflect.Message { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Rumor.ProtoReflect.Descriptor instead. -func (*Rumor) Descriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{0} -} - -func (x *Rumor) GetTime() int64 { - if x != nil { - return x.Time - } - return 0 -} - -type GossipRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *GossipRequest) Reset() { - *x = GossipRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GossipRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GossipRequest) ProtoMessage() {} - -func (x *GossipRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GossipRequest.ProtoReflect.Descriptor instead. -func (*GossipRequest) Descriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{1} -} - -type GossipResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *GossipResponse) Reset() { - *x = GossipResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GossipResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GossipResponse) ProtoMessage() {} - -func (x *GossipResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GossipResponse.ProtoReflect.Descriptor instead. -func (*GossipResponse) Descriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{2} -} - -type PingRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *PingRequest) Reset() { - *x = PingRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PingRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PingRequest) ProtoMessage() {} - -func (x *PingRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PingRequest.ProtoReflect.Descriptor instead. -func (*PingRequest) Descriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{3} -} - -type PingResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - State State `protobuf:"varint,1,opt,name=state,proto3,enum=gossip.v1.State" json:"state,omitempty"` -} - -func (x *PingResponse) Reset() { - *x = PingResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PingResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PingResponse) ProtoMessage() {} - -func (x *PingResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PingResponse.ProtoReflect.Descriptor instead. -func (*PingResponse) Descriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{4} -} - -func (x *PingResponse) GetState() State { - if x != nil { - return x.State - } - return State_State_UNSPECIFIED -} - -type IndirectPingRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` - RpcAddr string `protobuf:"bytes,2,opt,name=rpc_addr,json=rpcAddr,proto3" json:"rpc_addr,omitempty"` -} - -func (x *IndirectPingRequest) Reset() { - *x = IndirectPingRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *IndirectPingRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*IndirectPingRequest) ProtoMessage() {} - -func (x *IndirectPingRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use IndirectPingRequest.ProtoReflect.Descriptor instead. -func (*IndirectPingRequest) Descriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{5} -} - -func (x *IndirectPingRequest) GetNodeId() string { - if x != nil { - return x.NodeId - } - return "" -} - -func (x *IndirectPingRequest) GetRpcAddr() string { - if x != nil { - return x.RpcAddr - } - return "" -} - -type IndirectPingResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - State State `protobuf:"varint,1,opt,name=state,proto3,enum=gossip.v1.State" json:"state,omitempty"` -} - -func (x *IndirectPingResponse) Reset() { - *x = IndirectPingResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *IndirectPingResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*IndirectPingResponse) ProtoMessage() {} - -func (x *IndirectPingResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use IndirectPingResponse.ProtoReflect.Descriptor instead. -func (*IndirectPingResponse) Descriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{6} -} - -func (x *IndirectPingResponse) GetState() State { - if x != nil { - return x.State - } - return State_State_UNSPECIFIED -} - -type Member struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` - RpcAddr string `protobuf:"bytes,2,opt,name=rpc_addr,json=rpcAddr,proto3" json:"rpc_addr,omitempty"` - State State `protobuf:"varint,3,opt,name=state,proto3,enum=gossip.v1.State" json:"state,omitempty"` -} - -func (x *Member) Reset() { - *x = Member{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Member) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Member) ProtoMessage() {} - -func (x *Member) ProtoReflect() protoreflect.Message { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Member.ProtoReflect.Descriptor instead. -func (*Member) Descriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{7} -} - -func (x *Member) GetNodeId() string { - if x != nil { - return x.NodeId - } - return "" -} - -func (x *Member) GetRpcAddr() string { - if x != nil { - return x.RpcAddr - } - return "" -} - -func (x *Member) GetState() State { - if x != nil { - return x.State - } - return State_State_UNSPECIFIED -} - -type SyncMembersRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The members that the sender knows about - Members []*Member `protobuf:"bytes,1,rep,name=members,proto3" json:"members,omitempty"` -} - -func (x *SyncMembersRequest) Reset() { - *x = SyncMembersRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SyncMembersRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SyncMembersRequest) ProtoMessage() {} - -func (x *SyncMembersRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SyncMembersRequest.ProtoReflect.Descriptor instead. -func (*SyncMembersRequest) Descriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{8} -} - -func (x *SyncMembersRequest) GetMembers() []*Member { - if x != nil { - return x.Members - } - return nil -} - -type SyncMembersResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // The members that the receiver knows about - Members []*Member `protobuf:"bytes,1,rep,name=members,proto3" json:"members,omitempty"` -} - -func (x *SyncMembersResponse) Reset() { - *x = SyncMembersResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SyncMembersResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SyncMembersResponse) ProtoMessage() {} - -func (x *SyncMembersResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SyncMembersResponse.ProtoReflect.Descriptor instead. -func (*SyncMembersResponse) Descriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{9} -} - -func (x *SyncMembersResponse) GetMembers() []*Member { - if x != nil { - return x.Members - } - return nil -} - -type JoinRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Self *Member `protobuf:"bytes,1,opt,name=self,proto3" json:"self,omitempty"` -} - -func (x *JoinRequest) Reset() { - *x = JoinRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *JoinRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*JoinRequest) ProtoMessage() {} - -func (x *JoinRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use JoinRequest.ProtoReflect.Descriptor instead. -func (*JoinRequest) Descriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{10} -} - -func (x *JoinRequest) GetSelf() *Member { - if x != nil { - return x.Self - } - return nil -} - -type JoinResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Members []*Member `protobuf:"bytes,1,rep,name=members,proto3" json:"members,omitempty"` -} - -func (x *JoinResponse) Reset() { - *x = JoinResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *JoinResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*JoinResponse) ProtoMessage() {} - -func (x *JoinResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use JoinResponse.ProtoReflect.Descriptor instead. -func (*JoinResponse) Descriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{11} -} - -func (x *JoinResponse) GetMembers() []*Member { - if x != nil { - return x.Members - } - return nil -} - -type LeaveRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Self *Member `protobuf:"bytes,1,opt,name=self,proto3" json:"self,omitempty"` -} - -func (x *LeaveRequest) Reset() { - *x = LeaveRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LeaveRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LeaveRequest) ProtoMessage() {} - -func (x *LeaveRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LeaveRequest.ProtoReflect.Descriptor instead. -func (*LeaveRequest) Descriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{12} -} - -func (x *LeaveRequest) GetSelf() *Member { - if x != nil { - return x.Self - } - return nil -} - -type LeaveResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *LeaveResponse) Reset() { - *x = LeaveResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LeaveResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LeaveResponse) ProtoMessage() {} - -func (x *LeaveResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_gossip_v1_gossip_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LeaveResponse.ProtoReflect.Descriptor instead. -func (*LeaveResponse) Descriptor() ([]byte, []int) { - return file_proto_gossip_v1_gossip_proto_rawDescGZIP(), []int{13} -} - -var File_proto_gossip_v1_gossip_proto protoreflect.FileDescriptor - -var file_proto_gossip_v1_gossip_proto_rawDesc = []byte{ - 0x0a, 0x1c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2f, 0x76, - 0x31, 0x2f, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, - 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x22, 0x1b, 0x0a, 0x05, 0x52, 0x75, 0x6d, - 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x10, 0x0a, 0x0e, 0x47, 0x6f, 0x73, 0x73, 0x69, - 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x50, 0x69, 0x6e, - 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x36, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x22, 0x49, 0x0a, 0x13, 0x49, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, - 0x12, 0x19, 0x0a, 0x08, 0x72, 0x70, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x72, 0x70, 0x63, 0x41, 0x64, 0x64, 0x72, 0x22, 0x3e, 0x0a, 0x14, 0x49, - 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x64, 0x0a, 0x06, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x19, - 0x0a, 0x08, 0x72, 0x70, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x72, 0x70, 0x63, 0x41, 0x64, 0x64, 0x72, 0x12, 0x26, 0x0a, 0x05, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, - 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x22, 0x41, 0x0a, 0x12, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, - 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x22, 0x42, 0x0a, 0x13, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, - 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, - 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x34, 0x0a, 0x0b, 0x4a, 0x6f, 0x69, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x04, 0x73, 0x65, 0x6c, 0x66, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x04, 0x73, 0x65, 0x6c, 0x66, 0x22, 0x3b, - 0x0a, 0x0c, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, - 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x35, 0x0a, 0x0c, 0x4c, - 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x04, 0x73, - 0x65, 0x6c, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x67, 0x6f, 0x73, 0x73, - 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x04, 0x73, 0x65, - 0x6c, 0x66, 0x22, 0x0f, 0x0a, 0x0d, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2a, 0x62, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, 0x11, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x41, 0x4c, 0x49, - 0x56, 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x44, 0x45, - 0x41, 0x44, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x4c, 0x45, - 0x46, 0x54, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x53, 0x55, - 0x53, 0x50, 0x45, 0x43, 0x54, 0x10, 0x04, 0x32, 0xe6, 0x02, 0x0a, 0x0d, 0x47, 0x6f, 0x73, 0x73, - 0x69, 0x70, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x04, 0x50, 0x69, 0x6e, - 0x67, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, - 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x67, 0x6f, 0x73, 0x73, - 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, 0x0a, 0x0c, 0x49, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, - 0x2e, 0x49, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, - 0x2e, 0x49, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, 0x53, 0x79, 0x6e, 0x63, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x04, 0x4a, 0x6f, 0x69, 0x6e, 0x12, - 0x16, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, - 0x2e, 0x76, 0x31, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x05, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x12, 0x17, 0x2e, 0x67, 0x6f, - 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, - 0x6e, 0x6b, 0x65, 0x79, 0x65, 0x64, 0x2f, 0x75, 0x6e, 0x6b, 0x65, 0x79, 0x2f, 0x61, 0x70, 0x70, - 0x73, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x2f, 0x76, 0x31, 0x3b, 0x67, 0x6f, 0x73, 0x73, - 0x69, 0x70, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_gossip_v1_gossip_proto_rawDescOnce sync.Once - file_proto_gossip_v1_gossip_proto_rawDescData = file_proto_gossip_v1_gossip_proto_rawDesc -) - -func file_proto_gossip_v1_gossip_proto_rawDescGZIP() []byte { - file_proto_gossip_v1_gossip_proto_rawDescOnce.Do(func() { - file_proto_gossip_v1_gossip_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_gossip_v1_gossip_proto_rawDescData) - }) - return file_proto_gossip_v1_gossip_proto_rawDescData -} - -var file_proto_gossip_v1_gossip_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_proto_gossip_v1_gossip_proto_msgTypes = make([]protoimpl.MessageInfo, 14) -var file_proto_gossip_v1_gossip_proto_goTypes = []any{ - (State)(0), // 0: gossip.v1.State - (*Rumor)(nil), // 1: gossip.v1.Rumor - (*GossipRequest)(nil), // 2: gossip.v1.GossipRequest - (*GossipResponse)(nil), // 3: gossip.v1.GossipResponse - (*PingRequest)(nil), // 4: gossip.v1.PingRequest - (*PingResponse)(nil), // 5: gossip.v1.PingResponse - (*IndirectPingRequest)(nil), // 6: gossip.v1.IndirectPingRequest - (*IndirectPingResponse)(nil), // 7: gossip.v1.IndirectPingResponse - (*Member)(nil), // 8: gossip.v1.Member - (*SyncMembersRequest)(nil), // 9: gossip.v1.SyncMembersRequest - (*SyncMembersResponse)(nil), // 10: gossip.v1.SyncMembersResponse - (*JoinRequest)(nil), // 11: gossip.v1.JoinRequest - (*JoinResponse)(nil), // 12: gossip.v1.JoinResponse - (*LeaveRequest)(nil), // 13: gossip.v1.LeaveRequest - (*LeaveResponse)(nil), // 14: gossip.v1.LeaveResponse -} -var file_proto_gossip_v1_gossip_proto_depIdxs = []int32{ - 0, // 0: gossip.v1.PingResponse.state:type_name -> gossip.v1.State - 0, // 1: gossip.v1.IndirectPingResponse.state:type_name -> gossip.v1.State - 0, // 2: gossip.v1.Member.state:type_name -> gossip.v1.State - 8, // 3: gossip.v1.SyncMembersRequest.members:type_name -> gossip.v1.Member - 8, // 4: gossip.v1.SyncMembersResponse.members:type_name -> gossip.v1.Member - 8, // 5: gossip.v1.JoinRequest.self:type_name -> gossip.v1.Member - 8, // 6: gossip.v1.JoinResponse.members:type_name -> gossip.v1.Member - 8, // 7: gossip.v1.LeaveRequest.self:type_name -> gossip.v1.Member - 4, // 8: gossip.v1.GossipService.Ping:input_type -> gossip.v1.PingRequest - 6, // 9: gossip.v1.GossipService.IndirectPing:input_type -> gossip.v1.IndirectPingRequest - 9, // 10: gossip.v1.GossipService.SyncMembers:input_type -> gossip.v1.SyncMembersRequest - 11, // 11: gossip.v1.GossipService.Join:input_type -> gossip.v1.JoinRequest - 13, // 12: gossip.v1.GossipService.Leave:input_type -> gossip.v1.LeaveRequest - 5, // 13: gossip.v1.GossipService.Ping:output_type -> gossip.v1.PingResponse - 7, // 14: gossip.v1.GossipService.IndirectPing:output_type -> gossip.v1.IndirectPingResponse - 10, // 15: gossip.v1.GossipService.SyncMembers:output_type -> gossip.v1.SyncMembersResponse - 12, // 16: gossip.v1.GossipService.Join:output_type -> gossip.v1.JoinResponse - 14, // 17: gossip.v1.GossipService.Leave:output_type -> gossip.v1.LeaveResponse - 13, // [13:18] is the sub-list for method output_type - 8, // [8:13] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name -} - -func init() { file_proto_gossip_v1_gossip_proto_init() } -func file_proto_gossip_v1_gossip_proto_init() { - if File_proto_gossip_v1_gossip_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_gossip_v1_gossip_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*Rumor); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_gossip_v1_gossip_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*GossipRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_gossip_v1_gossip_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*GossipResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_gossip_v1_gossip_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*PingRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_gossip_v1_gossip_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*PingResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_gossip_v1_gossip_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*IndirectPingRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_gossip_v1_gossip_proto_msgTypes[6].Exporter = func(v any, i int) any { - switch v := v.(*IndirectPingResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_gossip_v1_gossip_proto_msgTypes[7].Exporter = func(v any, i int) any { - switch v := v.(*Member); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_gossip_v1_gossip_proto_msgTypes[8].Exporter = func(v any, i int) any { - switch v := v.(*SyncMembersRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_gossip_v1_gossip_proto_msgTypes[9].Exporter = func(v any, i int) any { - switch v := v.(*SyncMembersResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_gossip_v1_gossip_proto_msgTypes[10].Exporter = func(v any, i int) any { - switch v := v.(*JoinRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_gossip_v1_gossip_proto_msgTypes[11].Exporter = func(v any, i int) any { - switch v := v.(*JoinResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_gossip_v1_gossip_proto_msgTypes[12].Exporter = func(v any, i int) any { - switch v := v.(*LeaveRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_gossip_v1_gossip_proto_msgTypes[13].Exporter = func(v any, i int) any { - switch v := v.(*LeaveResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_gossip_v1_gossip_proto_rawDesc, - NumEnums: 1, - NumMessages: 14, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_gossip_v1_gossip_proto_goTypes, - DependencyIndexes: file_proto_gossip_v1_gossip_proto_depIdxs, - EnumInfos: file_proto_gossip_v1_gossip_proto_enumTypes, - MessageInfos: file_proto_gossip_v1_gossip_proto_msgTypes, - }.Build() - File_proto_gossip_v1_gossip_proto = out.File - file_proto_gossip_v1_gossip_proto_rawDesc = nil - file_proto_gossip_v1_gossip_proto_goTypes = nil - file_proto_gossip_v1_gossip_proto_depIdxs = nil -} diff --git a/web/apps/agent/gen/proto/gossip/v1/gossipv1connect/gossip.connect.go b/web/apps/agent/gen/proto/gossip/v1/gossipv1connect/gossip.connect.go deleted file mode 100644 index 23e2d00935..0000000000 --- a/web/apps/agent/gen/proto/gossip/v1/gossipv1connect/gossip.connect.go +++ /dev/null @@ -1,274 +0,0 @@ -// Code generated by protoc-gen-connect-go. DO NOT EDIT. -// -// Source: proto/gossip/v1/gossip.proto - -package gossipv1connect - -import ( - connect "connectrpc.com/connect" - context "context" - errors "errors" - v1 "github.com/unkeyed/unkey/svc/agent/gen/proto/gossip/v1" - http "net/http" - strings "strings" -) - -// This is a compile-time assertion to ensure that this generated file and the connect package are -// compatible. If you get a compiler error that this constant is not defined, this code was -// generated with a version of connect newer than the one compiled into your binary. You can fix the -// problem by either regenerating this code with an older version of connect or updating the connect -// version compiled into your binary. -const _ = connect.IsAtLeastVersion1_13_0 - -const ( - // GossipServiceName is the fully-qualified name of the GossipService service. - GossipServiceName = "gossip.v1.GossipService" -) - -// These constants are the fully-qualified names of the RPCs defined in this package. They're -// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. -// -// Note that these are different from the fully-qualified method names used by -// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to -// reflection-formatted method names, remove the leading slash and convert the remaining slash to a -// period. -const ( - // GossipServicePingProcedure is the fully-qualified name of the GossipService's Ping RPC. - GossipServicePingProcedure = "/gossip.v1.GossipService/Ping" - // GossipServiceIndirectPingProcedure is the fully-qualified name of the GossipService's - // IndirectPing RPC. - GossipServiceIndirectPingProcedure = "/gossip.v1.GossipService/IndirectPing" - // GossipServiceSyncMembersProcedure is the fully-qualified name of the GossipService's SyncMembers - // RPC. - GossipServiceSyncMembersProcedure = "/gossip.v1.GossipService/SyncMembers" - // GossipServiceJoinProcedure is the fully-qualified name of the GossipService's Join RPC. - GossipServiceJoinProcedure = "/gossip.v1.GossipService/Join" - // GossipServiceLeaveProcedure is the fully-qualified name of the GossipService's Leave RPC. - GossipServiceLeaveProcedure = "/gossip.v1.GossipService/Leave" -) - -// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. -var ( - gossipServiceServiceDescriptor = v1.File_proto_gossip_v1_gossip_proto.Services().ByName("GossipService") - gossipServicePingMethodDescriptor = gossipServiceServiceDescriptor.Methods().ByName("Ping") - gossipServiceIndirectPingMethodDescriptor = gossipServiceServiceDescriptor.Methods().ByName("IndirectPing") - gossipServiceSyncMembersMethodDescriptor = gossipServiceServiceDescriptor.Methods().ByName("SyncMembers") - gossipServiceJoinMethodDescriptor = gossipServiceServiceDescriptor.Methods().ByName("Join") - gossipServiceLeaveMethodDescriptor = gossipServiceServiceDescriptor.Methods().ByName("Leave") -) - -// GossipServiceClient is a client for the gossip.v1.GossipService service. -type GossipServiceClient interface { - // Ping asks for the state of a peer - // If the peer is healthy, it should respond with its state - Ping(context.Context, *connect.Request[v1.PingRequest]) (*connect.Response[v1.PingResponse], error) - // IndirectPing asks a peer to ping another node because we can not reach it outselves - // the peer should respond with the state of the node - IndirectPing(context.Context, *connect.Request[v1.IndirectPingRequest]) (*connect.Response[v1.IndirectPingResponse], error) - // Periodially we do a full sync of the members - // Both nodes tell each other about every member they know and then reconcile by taking the union - // of the two sets. - // Afterwards, both nodes should have the same view of the cluster and regular gossip will get rid - // of any dead nodes - // - // If they disagree on the state of a node, the most favourable state should be chosen - // ie: if one node thinks a peer is dead and the other thinks it is alive, the node should be - // marked as alive to prevent a split brain or unnecessary false positives - SyncMembers(context.Context, *connect.Request[v1.SyncMembersRequest]) (*connect.Response[v1.SyncMembersResponse], error) - // Join allows a node to advertise itself to the cluster - // The node sends their own information, so the cluster may add them to the list of known members - // The cluster responds with the list of known members to bootstrap the new node - // - // It's sufficient to call join on one node, the rest of the cluster will be updated through - // gossip, however it is recommended to call join on multiple nodes to ensure the information is - // propagated quickly and to minimize the chance of a single node failing before propagating the - // information. - Join(context.Context, *connect.Request[v1.JoinRequest]) (*connect.Response[v1.JoinResponse], error) - // Leave should be broadcasted to all nodes in the cluster when a node is leaving for any reason. - Leave(context.Context, *connect.Request[v1.LeaveRequest]) (*connect.Response[v1.LeaveResponse], error) -} - -// NewGossipServiceClient constructs a client for the gossip.v1.GossipService service. By default, -// it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and -// sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() -// or connect.WithGRPCWeb() options. -// -// The URL supplied here should be the base URL for the Connect or gRPC server (for example, -// http://api.acme.com or https://acme.com/grpc). -func NewGossipServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) GossipServiceClient { - baseURL = strings.TrimRight(baseURL, "/") - return &gossipServiceClient{ - ping: connect.NewClient[v1.PingRequest, v1.PingResponse]( - httpClient, - baseURL+GossipServicePingProcedure, - connect.WithSchema(gossipServicePingMethodDescriptor), - connect.WithClientOptions(opts...), - ), - indirectPing: connect.NewClient[v1.IndirectPingRequest, v1.IndirectPingResponse]( - httpClient, - baseURL+GossipServiceIndirectPingProcedure, - connect.WithSchema(gossipServiceIndirectPingMethodDescriptor), - connect.WithClientOptions(opts...), - ), - syncMembers: connect.NewClient[v1.SyncMembersRequest, v1.SyncMembersResponse]( - httpClient, - baseURL+GossipServiceSyncMembersProcedure, - connect.WithSchema(gossipServiceSyncMembersMethodDescriptor), - connect.WithClientOptions(opts...), - ), - join: connect.NewClient[v1.JoinRequest, v1.JoinResponse]( - httpClient, - baseURL+GossipServiceJoinProcedure, - connect.WithSchema(gossipServiceJoinMethodDescriptor), - connect.WithClientOptions(opts...), - ), - leave: connect.NewClient[v1.LeaveRequest, v1.LeaveResponse]( - httpClient, - baseURL+GossipServiceLeaveProcedure, - connect.WithSchema(gossipServiceLeaveMethodDescriptor), - connect.WithClientOptions(opts...), - ), - } -} - -// gossipServiceClient implements GossipServiceClient. -type gossipServiceClient struct { - ping *connect.Client[v1.PingRequest, v1.PingResponse] - indirectPing *connect.Client[v1.IndirectPingRequest, v1.IndirectPingResponse] - syncMembers *connect.Client[v1.SyncMembersRequest, v1.SyncMembersResponse] - join *connect.Client[v1.JoinRequest, v1.JoinResponse] - leave *connect.Client[v1.LeaveRequest, v1.LeaveResponse] -} - -// Ping calls gossip.v1.GossipService.Ping. -func (c *gossipServiceClient) Ping(ctx context.Context, req *connect.Request[v1.PingRequest]) (*connect.Response[v1.PingResponse], error) { - return c.ping.CallUnary(ctx, req) -} - -// IndirectPing calls gossip.v1.GossipService.IndirectPing. -func (c *gossipServiceClient) IndirectPing(ctx context.Context, req *connect.Request[v1.IndirectPingRequest]) (*connect.Response[v1.IndirectPingResponse], error) { - return c.indirectPing.CallUnary(ctx, req) -} - -// SyncMembers calls gossip.v1.GossipService.SyncMembers. -func (c *gossipServiceClient) SyncMembers(ctx context.Context, req *connect.Request[v1.SyncMembersRequest]) (*connect.Response[v1.SyncMembersResponse], error) { - return c.syncMembers.CallUnary(ctx, req) -} - -// Join calls gossip.v1.GossipService.Join. -func (c *gossipServiceClient) Join(ctx context.Context, req *connect.Request[v1.JoinRequest]) (*connect.Response[v1.JoinResponse], error) { - return c.join.CallUnary(ctx, req) -} - -// Leave calls gossip.v1.GossipService.Leave. -func (c *gossipServiceClient) Leave(ctx context.Context, req *connect.Request[v1.LeaveRequest]) (*connect.Response[v1.LeaveResponse], error) { - return c.leave.CallUnary(ctx, req) -} - -// GossipServiceHandler is an implementation of the gossip.v1.GossipService service. -type GossipServiceHandler interface { - // Ping asks for the state of a peer - // If the peer is healthy, it should respond with its state - Ping(context.Context, *connect.Request[v1.PingRequest]) (*connect.Response[v1.PingResponse], error) - // IndirectPing asks a peer to ping another node because we can not reach it outselves - // the peer should respond with the state of the node - IndirectPing(context.Context, *connect.Request[v1.IndirectPingRequest]) (*connect.Response[v1.IndirectPingResponse], error) - // Periodially we do a full sync of the members - // Both nodes tell each other about every member they know and then reconcile by taking the union - // of the two sets. - // Afterwards, both nodes should have the same view of the cluster and regular gossip will get rid - // of any dead nodes - // - // If they disagree on the state of a node, the most favourable state should be chosen - // ie: if one node thinks a peer is dead and the other thinks it is alive, the node should be - // marked as alive to prevent a split brain or unnecessary false positives - SyncMembers(context.Context, *connect.Request[v1.SyncMembersRequest]) (*connect.Response[v1.SyncMembersResponse], error) - // Join allows a node to advertise itself to the cluster - // The node sends their own information, so the cluster may add them to the list of known members - // The cluster responds with the list of known members to bootstrap the new node - // - // It's sufficient to call join on one node, the rest of the cluster will be updated through - // gossip, however it is recommended to call join on multiple nodes to ensure the information is - // propagated quickly and to minimize the chance of a single node failing before propagating the - // information. - Join(context.Context, *connect.Request[v1.JoinRequest]) (*connect.Response[v1.JoinResponse], error) - // Leave should be broadcasted to all nodes in the cluster when a node is leaving for any reason. - Leave(context.Context, *connect.Request[v1.LeaveRequest]) (*connect.Response[v1.LeaveResponse], error) -} - -// NewGossipServiceHandler builds an HTTP handler from the service implementation. It returns the -// path on which to mount the handler and the handler itself. -// -// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf -// and JSON codecs. They also support gzip compression. -func NewGossipServiceHandler(svc GossipServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { - gossipServicePingHandler := connect.NewUnaryHandler( - GossipServicePingProcedure, - svc.Ping, - connect.WithSchema(gossipServicePingMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - gossipServiceIndirectPingHandler := connect.NewUnaryHandler( - GossipServiceIndirectPingProcedure, - svc.IndirectPing, - connect.WithSchema(gossipServiceIndirectPingMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - gossipServiceSyncMembersHandler := connect.NewUnaryHandler( - GossipServiceSyncMembersProcedure, - svc.SyncMembers, - connect.WithSchema(gossipServiceSyncMembersMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - gossipServiceJoinHandler := connect.NewUnaryHandler( - GossipServiceJoinProcedure, - svc.Join, - connect.WithSchema(gossipServiceJoinMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - gossipServiceLeaveHandler := connect.NewUnaryHandler( - GossipServiceLeaveProcedure, - svc.Leave, - connect.WithSchema(gossipServiceLeaveMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - return "/gossip.v1.GossipService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - switch r.URL.Path { - case GossipServicePingProcedure: - gossipServicePingHandler.ServeHTTP(w, r) - case GossipServiceIndirectPingProcedure: - gossipServiceIndirectPingHandler.ServeHTTP(w, r) - case GossipServiceSyncMembersProcedure: - gossipServiceSyncMembersHandler.ServeHTTP(w, r) - case GossipServiceJoinProcedure: - gossipServiceJoinHandler.ServeHTTP(w, r) - case GossipServiceLeaveProcedure: - gossipServiceLeaveHandler.ServeHTTP(w, r) - default: - http.NotFound(w, r) - } - }) -} - -// UnimplementedGossipServiceHandler returns CodeUnimplemented from all methods. -type UnimplementedGossipServiceHandler struct{} - -func (UnimplementedGossipServiceHandler) Ping(context.Context, *connect.Request[v1.PingRequest]) (*connect.Response[v1.PingResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("gossip.v1.GossipService.Ping is not implemented")) -} - -func (UnimplementedGossipServiceHandler) IndirectPing(context.Context, *connect.Request[v1.IndirectPingRequest]) (*connect.Response[v1.IndirectPingResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("gossip.v1.GossipService.IndirectPing is not implemented")) -} - -func (UnimplementedGossipServiceHandler) SyncMembers(context.Context, *connect.Request[v1.SyncMembersRequest]) (*connect.Response[v1.SyncMembersResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("gossip.v1.GossipService.SyncMembers is not implemented")) -} - -func (UnimplementedGossipServiceHandler) Join(context.Context, *connect.Request[v1.JoinRequest]) (*connect.Response[v1.JoinResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("gossip.v1.GossipService.Join is not implemented")) -} - -func (UnimplementedGossipServiceHandler) Leave(context.Context, *connect.Request[v1.LeaveRequest]) (*connect.Response[v1.LeaveResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("gossip.v1.GossipService.Leave is not implemented")) -} diff --git a/web/apps/agent/gen/proto/ratelimit/v1/ratelimitv1connect/service.connect.go b/web/apps/agent/gen/proto/ratelimit/v1/ratelimitv1connect/service.connect.go deleted file mode 100644 index 6cdf9cda15..0000000000 --- a/web/apps/agent/gen/proto/ratelimit/v1/ratelimitv1connect/service.connect.go +++ /dev/null @@ -1,279 +0,0 @@ -// Code generated by protoc-gen-connect-go. DO NOT EDIT. -// -// Source: proto/ratelimit/v1/service.proto - -package ratelimitv1connect - -import ( - connect "connectrpc.com/connect" - context "context" - errors "errors" - v1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" - http "net/http" - strings "strings" -) - -// This is a compile-time assertion to ensure that this generated file and the connect package are -// compatible. If you get a compiler error that this constant is not defined, this code was -// generated with a version of connect newer than the one compiled into your binary. You can fix the -// problem by either regenerating this code with an older version of connect or updating the connect -// version compiled into your binary. -const _ = connect.IsAtLeastVersion1_13_0 - -const ( - // RatelimitServiceName is the fully-qualified name of the RatelimitService service. - RatelimitServiceName = "ratelimit.v1.RatelimitService" -) - -// These constants are the fully-qualified names of the RPCs defined in this package. They're -// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. -// -// Note that these are different from the fully-qualified method names used by -// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to -// reflection-formatted method names, remove the leading slash and convert the remaining slash to a -// period. -const ( - // RatelimitServiceLivenessProcedure is the fully-qualified name of the RatelimitService's Liveness - // RPC. - RatelimitServiceLivenessProcedure = "/ratelimit.v1.RatelimitService/Liveness" - // RatelimitServiceRatelimitProcedure is the fully-qualified name of the RatelimitService's - // Ratelimit RPC. - RatelimitServiceRatelimitProcedure = "/ratelimit.v1.RatelimitService/Ratelimit" - // RatelimitServiceMultiRatelimitProcedure is the fully-qualified name of the RatelimitService's - // MultiRatelimit RPC. - RatelimitServiceMultiRatelimitProcedure = "/ratelimit.v1.RatelimitService/MultiRatelimit" - // RatelimitServicePushPullProcedure is the fully-qualified name of the RatelimitService's PushPull - // RPC. - RatelimitServicePushPullProcedure = "/ratelimit.v1.RatelimitService/PushPull" - // RatelimitServiceCommitLeaseProcedure is the fully-qualified name of the RatelimitService's - // CommitLease RPC. - RatelimitServiceCommitLeaseProcedure = "/ratelimit.v1.RatelimitService/CommitLease" - // RatelimitServiceMitigateProcedure is the fully-qualified name of the RatelimitService's Mitigate - // RPC. - RatelimitServiceMitigateProcedure = "/ratelimit.v1.RatelimitService/Mitigate" -) - -// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. -var ( - ratelimitServiceServiceDescriptor = v1.File_proto_ratelimit_v1_service_proto.Services().ByName("RatelimitService") - ratelimitServiceLivenessMethodDescriptor = ratelimitServiceServiceDescriptor.Methods().ByName("Liveness") - ratelimitServiceRatelimitMethodDescriptor = ratelimitServiceServiceDescriptor.Methods().ByName("Ratelimit") - ratelimitServiceMultiRatelimitMethodDescriptor = ratelimitServiceServiceDescriptor.Methods().ByName("MultiRatelimit") - ratelimitServicePushPullMethodDescriptor = ratelimitServiceServiceDescriptor.Methods().ByName("PushPull") - ratelimitServiceCommitLeaseMethodDescriptor = ratelimitServiceServiceDescriptor.Methods().ByName("CommitLease") - ratelimitServiceMitigateMethodDescriptor = ratelimitServiceServiceDescriptor.Methods().ByName("Mitigate") -) - -// RatelimitServiceClient is a client for the ratelimit.v1.RatelimitService service. -type RatelimitServiceClient interface { - Liveness(context.Context, *connect.Request[v1.LivenessRequest]) (*connect.Response[v1.LivenessResponse], error) - Ratelimit(context.Context, *connect.Request[v1.RatelimitRequest]) (*connect.Response[v1.RatelimitResponse], error) - MultiRatelimit(context.Context, *connect.Request[v1.RatelimitMultiRequest]) (*connect.Response[v1.RatelimitMultiResponse], error) - // Internal - // - // PushPull syncs the ratelimit with the origin server - // For each identifier there is an origin server, agred upon by every node in the ring via - // consistent hashing - // - // PushPull notifies the origin of a ratelimit operation that happened and then pulls the latest - // ratelimit information from the origin server to update its own local state - PushPull(context.Context, *connect.Request[v1.PushPullRequest]) (*connect.Response[v1.PushPullResponse], error) - CommitLease(context.Context, *connect.Request[v1.CommitLeaseRequest]) (*connect.Response[v1.CommitLeaseResponse], error) - Mitigate(context.Context, *connect.Request[v1.MitigateRequest]) (*connect.Response[v1.MitigateResponse], error) -} - -// NewRatelimitServiceClient constructs a client for the ratelimit.v1.RatelimitService service. By -// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, -// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the -// connect.WithGRPC() or connect.WithGRPCWeb() options. -// -// The URL supplied here should be the base URL for the Connect or gRPC server (for example, -// http://api.acme.com or https://acme.com/grpc). -func NewRatelimitServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) RatelimitServiceClient { - baseURL = strings.TrimRight(baseURL, "/") - return &ratelimitServiceClient{ - liveness: connect.NewClient[v1.LivenessRequest, v1.LivenessResponse]( - httpClient, - baseURL+RatelimitServiceLivenessProcedure, - connect.WithSchema(ratelimitServiceLivenessMethodDescriptor), - connect.WithClientOptions(opts...), - ), - ratelimit: connect.NewClient[v1.RatelimitRequest, v1.RatelimitResponse]( - httpClient, - baseURL+RatelimitServiceRatelimitProcedure, - connect.WithSchema(ratelimitServiceRatelimitMethodDescriptor), - connect.WithClientOptions(opts...), - ), - multiRatelimit: connect.NewClient[v1.RatelimitMultiRequest, v1.RatelimitMultiResponse]( - httpClient, - baseURL+RatelimitServiceMultiRatelimitProcedure, - connect.WithSchema(ratelimitServiceMultiRatelimitMethodDescriptor), - connect.WithClientOptions(opts...), - ), - pushPull: connect.NewClient[v1.PushPullRequest, v1.PushPullResponse]( - httpClient, - baseURL+RatelimitServicePushPullProcedure, - connect.WithSchema(ratelimitServicePushPullMethodDescriptor), - connect.WithClientOptions(opts...), - ), - commitLease: connect.NewClient[v1.CommitLeaseRequest, v1.CommitLeaseResponse]( - httpClient, - baseURL+RatelimitServiceCommitLeaseProcedure, - connect.WithSchema(ratelimitServiceCommitLeaseMethodDescriptor), - connect.WithClientOptions(opts...), - ), - mitigate: connect.NewClient[v1.MitigateRequest, v1.MitigateResponse]( - httpClient, - baseURL+RatelimitServiceMitigateProcedure, - connect.WithSchema(ratelimitServiceMitigateMethodDescriptor), - connect.WithClientOptions(opts...), - ), - } -} - -// ratelimitServiceClient implements RatelimitServiceClient. -type ratelimitServiceClient struct { - liveness *connect.Client[v1.LivenessRequest, v1.LivenessResponse] - ratelimit *connect.Client[v1.RatelimitRequest, v1.RatelimitResponse] - multiRatelimit *connect.Client[v1.RatelimitMultiRequest, v1.RatelimitMultiResponse] - pushPull *connect.Client[v1.PushPullRequest, v1.PushPullResponse] - commitLease *connect.Client[v1.CommitLeaseRequest, v1.CommitLeaseResponse] - mitigate *connect.Client[v1.MitigateRequest, v1.MitigateResponse] -} - -// Liveness calls ratelimit.v1.RatelimitService.Liveness. -func (c *ratelimitServiceClient) Liveness(ctx context.Context, req *connect.Request[v1.LivenessRequest]) (*connect.Response[v1.LivenessResponse], error) { - return c.liveness.CallUnary(ctx, req) -} - -// Ratelimit calls ratelimit.v1.RatelimitService.Ratelimit. -func (c *ratelimitServiceClient) Ratelimit(ctx context.Context, req *connect.Request[v1.RatelimitRequest]) (*connect.Response[v1.RatelimitResponse], error) { - return c.ratelimit.CallUnary(ctx, req) -} - -// MultiRatelimit calls ratelimit.v1.RatelimitService.MultiRatelimit. -func (c *ratelimitServiceClient) MultiRatelimit(ctx context.Context, req *connect.Request[v1.RatelimitMultiRequest]) (*connect.Response[v1.RatelimitMultiResponse], error) { - return c.multiRatelimit.CallUnary(ctx, req) -} - -// PushPull calls ratelimit.v1.RatelimitService.PushPull. -func (c *ratelimitServiceClient) PushPull(ctx context.Context, req *connect.Request[v1.PushPullRequest]) (*connect.Response[v1.PushPullResponse], error) { - return c.pushPull.CallUnary(ctx, req) -} - -// CommitLease calls ratelimit.v1.RatelimitService.CommitLease. -func (c *ratelimitServiceClient) CommitLease(ctx context.Context, req *connect.Request[v1.CommitLeaseRequest]) (*connect.Response[v1.CommitLeaseResponse], error) { - return c.commitLease.CallUnary(ctx, req) -} - -// Mitigate calls ratelimit.v1.RatelimitService.Mitigate. -func (c *ratelimitServiceClient) Mitigate(ctx context.Context, req *connect.Request[v1.MitigateRequest]) (*connect.Response[v1.MitigateResponse], error) { - return c.mitigate.CallUnary(ctx, req) -} - -// RatelimitServiceHandler is an implementation of the ratelimit.v1.RatelimitService service. -type RatelimitServiceHandler interface { - Liveness(context.Context, *connect.Request[v1.LivenessRequest]) (*connect.Response[v1.LivenessResponse], error) - Ratelimit(context.Context, *connect.Request[v1.RatelimitRequest]) (*connect.Response[v1.RatelimitResponse], error) - MultiRatelimit(context.Context, *connect.Request[v1.RatelimitMultiRequest]) (*connect.Response[v1.RatelimitMultiResponse], error) - // Internal - // - // PushPull syncs the ratelimit with the origin server - // For each identifier there is an origin server, agred upon by every node in the ring via - // consistent hashing - // - // PushPull notifies the origin of a ratelimit operation that happened and then pulls the latest - // ratelimit information from the origin server to update its own local state - PushPull(context.Context, *connect.Request[v1.PushPullRequest]) (*connect.Response[v1.PushPullResponse], error) - CommitLease(context.Context, *connect.Request[v1.CommitLeaseRequest]) (*connect.Response[v1.CommitLeaseResponse], error) - Mitigate(context.Context, *connect.Request[v1.MitigateRequest]) (*connect.Response[v1.MitigateResponse], error) -} - -// NewRatelimitServiceHandler builds an HTTP handler from the service implementation. It returns the -// path on which to mount the handler and the handler itself. -// -// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf -// and JSON codecs. They also support gzip compression. -func NewRatelimitServiceHandler(svc RatelimitServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { - ratelimitServiceLivenessHandler := connect.NewUnaryHandler( - RatelimitServiceLivenessProcedure, - svc.Liveness, - connect.WithSchema(ratelimitServiceLivenessMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - ratelimitServiceRatelimitHandler := connect.NewUnaryHandler( - RatelimitServiceRatelimitProcedure, - svc.Ratelimit, - connect.WithSchema(ratelimitServiceRatelimitMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - ratelimitServiceMultiRatelimitHandler := connect.NewUnaryHandler( - RatelimitServiceMultiRatelimitProcedure, - svc.MultiRatelimit, - connect.WithSchema(ratelimitServiceMultiRatelimitMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - ratelimitServicePushPullHandler := connect.NewUnaryHandler( - RatelimitServicePushPullProcedure, - svc.PushPull, - connect.WithSchema(ratelimitServicePushPullMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - ratelimitServiceCommitLeaseHandler := connect.NewUnaryHandler( - RatelimitServiceCommitLeaseProcedure, - svc.CommitLease, - connect.WithSchema(ratelimitServiceCommitLeaseMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - ratelimitServiceMitigateHandler := connect.NewUnaryHandler( - RatelimitServiceMitigateProcedure, - svc.Mitigate, - connect.WithSchema(ratelimitServiceMitigateMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - return "/ratelimit.v1.RatelimitService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - switch r.URL.Path { - case RatelimitServiceLivenessProcedure: - ratelimitServiceLivenessHandler.ServeHTTP(w, r) - case RatelimitServiceRatelimitProcedure: - ratelimitServiceRatelimitHandler.ServeHTTP(w, r) - case RatelimitServiceMultiRatelimitProcedure: - ratelimitServiceMultiRatelimitHandler.ServeHTTP(w, r) - case RatelimitServicePushPullProcedure: - ratelimitServicePushPullHandler.ServeHTTP(w, r) - case RatelimitServiceCommitLeaseProcedure: - ratelimitServiceCommitLeaseHandler.ServeHTTP(w, r) - case RatelimitServiceMitigateProcedure: - ratelimitServiceMitigateHandler.ServeHTTP(w, r) - default: - http.NotFound(w, r) - } - }) -} - -// UnimplementedRatelimitServiceHandler returns CodeUnimplemented from all methods. -type UnimplementedRatelimitServiceHandler struct{} - -func (UnimplementedRatelimitServiceHandler) Liveness(context.Context, *connect.Request[v1.LivenessRequest]) (*connect.Response[v1.LivenessResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ratelimit.v1.RatelimitService.Liveness is not implemented")) -} - -func (UnimplementedRatelimitServiceHandler) Ratelimit(context.Context, *connect.Request[v1.RatelimitRequest]) (*connect.Response[v1.RatelimitResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ratelimit.v1.RatelimitService.Ratelimit is not implemented")) -} - -func (UnimplementedRatelimitServiceHandler) MultiRatelimit(context.Context, *connect.Request[v1.RatelimitMultiRequest]) (*connect.Response[v1.RatelimitMultiResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ratelimit.v1.RatelimitService.MultiRatelimit is not implemented")) -} - -func (UnimplementedRatelimitServiceHandler) PushPull(context.Context, *connect.Request[v1.PushPullRequest]) (*connect.Response[v1.PushPullResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ratelimit.v1.RatelimitService.PushPull is not implemented")) -} - -func (UnimplementedRatelimitServiceHandler) CommitLease(context.Context, *connect.Request[v1.CommitLeaseRequest]) (*connect.Response[v1.CommitLeaseResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ratelimit.v1.RatelimitService.CommitLease is not implemented")) -} - -func (UnimplementedRatelimitServiceHandler) Mitigate(context.Context, *connect.Request[v1.MitigateRequest]) (*connect.Response[v1.MitigateResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ratelimit.v1.RatelimitService.Mitigate is not implemented")) -} diff --git a/web/apps/agent/gen/proto/ratelimit/v1/service.openapi.yaml b/web/apps/agent/gen/proto/ratelimit/v1/service.openapi.yaml deleted file mode 100644 index c908affd79..0000000000 --- a/web/apps/agent/gen/proto/ratelimit/v1/service.openapi.yaml +++ /dev/null @@ -1,296 +0,0 @@ -openapi: 3.1.0 -info: - title: ratelimit.v1 -paths: - /ratelimit.v1.RatelimitService/Liveness: - post: - tags: - - ratelimit.v1.RatelimitService - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/ratelimit.v1.LivenessRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/ratelimit.v1.LivenessResponse' - /ratelimit.v1.RatelimitService/Ratelimit: - post: - tags: - - ratelimit.v1.RatelimitService - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/ratelimit.v1.RatelimitRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/ratelimit.v1.RatelimitResponse' - /ratelimit.v1.RatelimitService/MultiRatelimit: - post: - tags: - - ratelimit.v1.RatelimitService - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/ratelimit.v1.RatelimitMultiRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/ratelimit.v1.RatelimitMultiResponse' - /ratelimit.v1.RatelimitService/PushPull: - post: - tags: - - ratelimit.v1.RatelimitService - description: "Internal\n\n PushPull syncs the ratelimit with the origin server\n For each identifier there is an origin server, agred upon by every node in the ring via \n consistent hashing\n\n PushPull notifies the origin of a ratelimit operation that happened and then pulls the latest\n ratelimit information from the origin server to update its own local state" - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/ratelimit.v1.PushPullRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/ratelimit.v1.PushPullResponse' -components: - schemas: - ratelimit.v1.LivenessRequest: - type: object - title: LivenessRequest - additionalProperties: false - ratelimit.v1.LivenessResponse: - type: object - properties: - status: - type: string - title: status - additionalProperties: false - title: LivenessResponse - additionalProperties: false - ratelimit.v1.PushPullEvent: - type: object - properties: - identifier: - type: string - title: identifier - additionalProperties: false - limit: - oneOf: - - type: string - - type: number - title: limit - additionalProperties: false - duration: - oneOf: - - type: string - - type: number - title: duration - additionalProperties: false - cost: - oneOf: - - type: string - - type: number - title: cost - additionalProperties: false - title: PushPullEvent - additionalProperties: false - ratelimit.v1.PushPullRequest: - type: object - properties: - events: - type: array - items: - $ref: '#/components/schemas/ratelimit.v1.PushPullEvent' - title: PushPullRequest - additionalProperties: false - ratelimit.v1.PushPullResponse: - type: object - properties: - updates: - type: array - items: - $ref: '#/components/schemas/ratelimit.v1.PushPullUpdate' - title: PushPullResponse - additionalProperties: false - ratelimit.v1.PushPullUpdate: - type: object - properties: - identifier: - type: string - title: identifier - additionalProperties: false - current: - oneOf: - - type: string - - type: number - title: current - additionalProperties: false - title: PushPullUpdate - additionalProperties: false - ratelimit.v1.RatelimitMultiRequest: - type: object - properties: - ratelimits: - type: array - items: - $ref: '#/components/schemas/ratelimit.v1.RatelimitRequest' - title: RatelimitMultiRequest - additionalProperties: false - ratelimit.v1.RatelimitMultiResponse: - type: object - properties: - ratelimits: - type: array - items: - $ref: '#/components/schemas/ratelimit.v1.RatelimitResponse' - title: RatelimitMultiResponse - additionalProperties: false - ratelimit.v1.RatelimitRequest: - type: object - properties: - identifier: - type: string - title: identifier - additionalProperties: false - limit: - oneOf: - - type: string - - type: number - title: limit - additionalProperties: false - duration: - oneOf: - - type: string - - type: number - title: duration - additionalProperties: false - cost: - oneOf: - - type: string - - type: number - title: cost - additionalProperties: false - name: - type: string - title: name - additionalProperties: false - description: A name for the ratelimit, used for debugging - title: RatelimitRequest - additionalProperties: false - ratelimit.v1.RatelimitResponse: - type: object - properties: - limit: - oneOf: - - type: string - - type: number - title: limit - additionalProperties: false - remaining: - oneOf: - - type: string - - type: number - title: remaining - additionalProperties: false - reset: - oneOf: - - type: string - - type: number - title: reset - additionalProperties: false - success: - type: boolean - title: success - additionalProperties: false - current: - oneOf: - - type: string - - type: number - title: current - additionalProperties: false - title: RatelimitResponse - additionalProperties: false - connect.error: - type: object - properties: - code: - type: string - examples: - - CodeNotFound - enum: - - CodeCanceled - - CodeUnknown - - CodeInvalidArgument - - CodeDeadlineExceeded - - CodeNotFound - - CodeAlreadyExists - - CodePermissionDenied - - CodeResourceExhausted - - CodeFailedPrecondition - - CodeAborted - - CodeOutOfRange - - CodeInternal - - CodeUnavailable - - CodeDataLoss - - CodeUnauthenticated - description: The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. - message: - type: string - description: A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. - detail: - $ref: '#/components/schemas/google.protobuf.Any' - title: Connect Error - additionalProperties: true - description: 'Error type returned by Connect: https://connectrpc.com/docs/go/errors/#http-representation' - google.protobuf.Any: - type: object - properties: - type: - type: string - value: - type: string - format: binary - debug: - type: object - additionalProperties: true - additionalProperties: true - description: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message. -security: [] -tags: - - name: ratelimit.v1.RatelimitService -externalDocs: {} diff --git a/web/apps/agent/gen/proto/ratelimit/v1/service.pb.go b/web/apps/agent/gen/proto/ratelimit/v1/service.pb.go deleted file mode 100644 index d1ae5e9346..0000000000 --- a/web/apps/agent/gen/proto/ratelimit/v1/service.pb.go +++ /dev/null @@ -1,1353 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.34.2 -// protoc (unknown) -// source: proto/ratelimit/v1/service.proto - -package ratelimitv1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type LivenessRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *LivenessRequest) Reset() { - *x = LivenessRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LivenessRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LivenessRequest) ProtoMessage() {} - -func (x *LivenessRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LivenessRequest.ProtoReflect.Descriptor instead. -func (*LivenessRequest) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{0} -} - -type LivenessResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` -} - -func (x *LivenessResponse) Reset() { - *x = LivenessResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LivenessResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LivenessResponse) ProtoMessage() {} - -func (x *LivenessResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LivenessResponse.ProtoReflect.Descriptor instead. -func (*LivenessResponse) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{1} -} - -func (x *LivenessResponse) GetStatus() string { - if x != nil { - return x.Status - } - return "" -} - -type LeaseRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Cost int64 `protobuf:"varint,1,opt,name=cost,proto3" json:"cost,omitempty"` - // milliseconds - Timeout int64 `protobuf:"varint,2,opt,name=timeout,proto3" json:"timeout,omitempty"` -} - -func (x *LeaseRequest) Reset() { - *x = LeaseRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LeaseRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LeaseRequest) ProtoMessage() {} - -func (x *LeaseRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LeaseRequest.ProtoReflect.Descriptor instead. -func (*LeaseRequest) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{2} -} - -func (x *LeaseRequest) GetCost() int64 { - if x != nil { - return x.Cost - } - return 0 -} - -func (x *LeaseRequest) GetTimeout() int64 { - if x != nil { - return x.Timeout - } - return 0 -} - -type RatelimitRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Identifier string `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` - Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` - Duration int64 `protobuf:"varint,3,opt,name=duration,proto3" json:"duration,omitempty"` - Cost int64 `protobuf:"varint,4,opt,name=cost,proto3" json:"cost,omitempty"` - // A name for the ratelimit, used for debugging - Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"` - // Create a lease with this many tokens - Lease *LeaseRequest `protobuf:"bytes,6,opt,name=lease,proto3,oneof" json:"lease,omitempty"` - Time *int64 `protobuf:"varint,7,opt,name=time,proto3,oneof" json:"time,omitempty"` -} - -func (x *RatelimitRequest) Reset() { - *x = RatelimitRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RatelimitRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RatelimitRequest) ProtoMessage() {} - -func (x *RatelimitRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RatelimitRequest.ProtoReflect.Descriptor instead. -func (*RatelimitRequest) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{3} -} - -func (x *RatelimitRequest) GetIdentifier() string { - if x != nil { - return x.Identifier - } - return "" -} - -func (x *RatelimitRequest) GetLimit() int64 { - if x != nil { - return x.Limit - } - return 0 -} - -func (x *RatelimitRequest) GetDuration() int64 { - if x != nil { - return x.Duration - } - return 0 -} - -func (x *RatelimitRequest) GetCost() int64 { - if x != nil { - return x.Cost - } - return 0 -} - -func (x *RatelimitRequest) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *RatelimitRequest) GetLease() *LeaseRequest { - if x != nil { - return x.Lease - } - return nil -} - -func (x *RatelimitRequest) GetTime() int64 { - if x != nil && x.Time != nil { - return *x.Time - } - return 0 -} - -type RatelimitResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Limit int64 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"` - Remaining int64 `protobuf:"varint,2,opt,name=remaining,proto3" json:"remaining,omitempty"` - Reset_ int64 `protobuf:"varint,3,opt,name=reset,proto3" json:"reset,omitempty"` - Success bool `protobuf:"varint,4,opt,name=success,proto3" json:"success,omitempty"` - Current int64 `protobuf:"varint,5,opt,name=current,proto3" json:"current,omitempty"` - Lease *Lease `protobuf:"bytes,6,opt,name=lease,proto3,oneof" json:"lease,omitempty"` -} - -func (x *RatelimitResponse) Reset() { - *x = RatelimitResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RatelimitResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RatelimitResponse) ProtoMessage() {} - -func (x *RatelimitResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RatelimitResponse.ProtoReflect.Descriptor instead. -func (*RatelimitResponse) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{4} -} - -func (x *RatelimitResponse) GetLimit() int64 { - if x != nil { - return x.Limit - } - return 0 -} - -func (x *RatelimitResponse) GetRemaining() int64 { - if x != nil { - return x.Remaining - } - return 0 -} - -func (x *RatelimitResponse) GetReset_() int64 { - if x != nil { - return x.Reset_ - } - return 0 -} - -func (x *RatelimitResponse) GetSuccess() bool { - if x != nil { - return x.Success - } - return false -} - -func (x *RatelimitResponse) GetCurrent() int64 { - if x != nil { - return x.Current - } - return 0 -} - -func (x *RatelimitResponse) GetLease() *Lease { - if x != nil { - return x.Lease - } - return nil -} - -type RatelimitMultiRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Ratelimits []*RatelimitRequest `protobuf:"bytes,1,rep,name=ratelimits,proto3" json:"ratelimits,omitempty"` -} - -func (x *RatelimitMultiRequest) Reset() { - *x = RatelimitMultiRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RatelimitMultiRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RatelimitMultiRequest) ProtoMessage() {} - -func (x *RatelimitMultiRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RatelimitMultiRequest.ProtoReflect.Descriptor instead. -func (*RatelimitMultiRequest) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{5} -} - -func (x *RatelimitMultiRequest) GetRatelimits() []*RatelimitRequest { - if x != nil { - return x.Ratelimits - } - return nil -} - -type RatelimitMultiResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Ratelimits []*RatelimitResponse `protobuf:"bytes,1,rep,name=ratelimits,proto3" json:"ratelimits,omitempty"` -} - -func (x *RatelimitMultiResponse) Reset() { - *x = RatelimitMultiResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RatelimitMultiResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RatelimitMultiResponse) ProtoMessage() {} - -func (x *RatelimitMultiResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RatelimitMultiResponse.ProtoReflect.Descriptor instead. -func (*RatelimitMultiResponse) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{6} -} - -func (x *RatelimitMultiResponse) GetRatelimits() []*RatelimitResponse { - if x != nil { - return x.Ratelimits - } - return nil -} - -type Window struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Sequence int64 `protobuf:"varint,1,opt,name=sequence,proto3" json:"sequence,omitempty"` - Duration int64 `protobuf:"varint,2,opt,name=duration,proto3" json:"duration,omitempty"` - Counter int64 `protobuf:"varint,3,opt,name=counter,proto3" json:"counter,omitempty"` - // unix milli - Start int64 `protobuf:"varint,4,opt,name=start,proto3" json:"start,omitempty"` - // An origin node can broadcast a mitigation to all nodes in the ring - // Before the mitigation is broadcasted, the origin node must flip this to true - // to avoid duplicate broadcasts - MitigateBroadcasted bool `protobuf:"varint,5,opt,name=mitigate_broadcasted,json=mitigateBroadcasted,proto3" json:"mitigate_broadcasted,omitempty"` - // A map of leaseIDs to leases - Leases map[string]*Lease `protobuf:"bytes,6,rep,name=leases,proto3" json:"leases,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *Window) Reset() { - *x = Window{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Window) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Window) ProtoMessage() {} - -func (x *Window) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Window.ProtoReflect.Descriptor instead. -func (*Window) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{7} -} - -func (x *Window) GetSequence() int64 { - if x != nil { - return x.Sequence - } - return 0 -} - -func (x *Window) GetDuration() int64 { - if x != nil { - return x.Duration - } - return 0 -} - -func (x *Window) GetCounter() int64 { - if x != nil { - return x.Counter - } - return 0 -} - -func (x *Window) GetStart() int64 { - if x != nil { - return x.Start - } - return 0 -} - -func (x *Window) GetMitigateBroadcasted() bool { - if x != nil { - return x.MitigateBroadcasted - } - return false -} - -func (x *Window) GetLeases() map[string]*Lease { - if x != nil { - return x.Leases - } - return nil -} - -type PushPullRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Request *RatelimitRequest `protobuf:"bytes,1,opt,name=request,proto3" json:"request,omitempty"` - // Whether the edge note let the request pass - // If it did, we must increment the counter on the origin regardless of the result - Passed bool `protobuf:"varint,2,opt,name=passed,proto3" json:"passed,omitempty"` - // The time the event happened, so we can replay it on the origin and record latency - Time int64 `protobuf:"varint,3,opt,name=time,proto3" json:"time,omitempty"` -} - -func (x *PushPullRequest) Reset() { - *x = PushPullRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PushPullRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PushPullRequest) ProtoMessage() {} - -func (x *PushPullRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PushPullRequest.ProtoReflect.Descriptor instead. -func (*PushPullRequest) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{8} -} - -func (x *PushPullRequest) GetRequest() *RatelimitRequest { - if x != nil { - return x.Request - } - return nil -} - -func (x *PushPullRequest) GetPassed() bool { - if x != nil { - return x.Passed - } - return false -} - -func (x *PushPullRequest) GetTime() int64 { - if x != nil { - return x.Time - } - return 0 -} - -type PushPullResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Current *Window `protobuf:"bytes,1,opt,name=current,proto3" json:"current,omitempty"` - Previous *Window `protobuf:"bytes,2,opt,name=previous,proto3" json:"previous,omitempty"` - Response *RatelimitResponse `protobuf:"bytes,3,opt,name=response,proto3" json:"response,omitempty"` -} - -func (x *PushPullResponse) Reset() { - *x = PushPullResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PushPullResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PushPullResponse) ProtoMessage() {} - -func (x *PushPullResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PushPullResponse.ProtoReflect.Descriptor instead. -func (*PushPullResponse) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{9} -} - -func (x *PushPullResponse) GetCurrent() *Window { - if x != nil { - return x.Current - } - return nil -} - -func (x *PushPullResponse) GetPrevious() *Window { - if x != nil { - return x.Previous - } - return nil -} - -func (x *PushPullResponse) GetResponse() *RatelimitResponse { - if x != nil { - return x.Response - } - return nil -} - -// Lease contains everything from original ratelimit request that we need to find the origin server -type Lease struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Identifier string `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` - Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` - Duration int64 `protobuf:"varint,3,opt,name=duration,proto3" json:"duration,omitempty"` -} - -func (x *Lease) Reset() { - *x = Lease{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Lease) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Lease) ProtoMessage() {} - -func (x *Lease) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Lease.ProtoReflect.Descriptor instead. -func (*Lease) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{10} -} - -func (x *Lease) GetIdentifier() string { - if x != nil { - return x.Identifier - } - return "" -} - -func (x *Lease) GetLimit() int64 { - if x != nil { - return x.Limit - } - return 0 -} - -func (x *Lease) GetDuration() int64 { - if x != nil { - return x.Duration - } - return 0 -} - -type CommitLeaseRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Lease *Lease `protobuf:"bytes,1,opt,name=lease,proto3" json:"lease,omitempty"` - // The actual cost that should be commited - Cost int64 `protobuf:"varint,2,opt,name=cost,proto3" json:"cost,omitempty"` -} - -func (x *CommitLeaseRequest) Reset() { - *x = CommitLeaseRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CommitLeaseRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CommitLeaseRequest) ProtoMessage() {} - -func (x *CommitLeaseRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CommitLeaseRequest.ProtoReflect.Descriptor instead. -func (*CommitLeaseRequest) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{11} -} - -func (x *CommitLeaseRequest) GetLease() *Lease { - if x != nil { - return x.Lease - } - return nil -} - -func (x *CommitLeaseRequest) GetCost() int64 { - if x != nil { - return x.Cost - } - return 0 -} - -type CommitLeaseResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *CommitLeaseResponse) Reset() { - *x = CommitLeaseResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CommitLeaseResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CommitLeaseResponse) ProtoMessage() {} - -func (x *CommitLeaseResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CommitLeaseResponse.ProtoReflect.Descriptor instead. -func (*CommitLeaseResponse) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{12} -} - -type MitigateRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Identifier string `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` - Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` - Duration int64 `protobuf:"varint,3,opt,name=duration,proto3" json:"duration,omitempty"` - Window *Window `protobuf:"bytes,4,opt,name=window,proto3" json:"window,omitempty"` -} - -func (x *MitigateRequest) Reset() { - *x = MitigateRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MitigateRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MitigateRequest) ProtoMessage() {} - -func (x *MitigateRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MitigateRequest.ProtoReflect.Descriptor instead. -func (*MitigateRequest) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{13} -} - -func (x *MitigateRequest) GetIdentifier() string { - if x != nil { - return x.Identifier - } - return "" -} - -func (x *MitigateRequest) GetLimit() int64 { - if x != nil { - return x.Limit - } - return 0 -} - -func (x *MitigateRequest) GetDuration() int64 { - if x != nil { - return x.Duration - } - return 0 -} - -func (x *MitigateRequest) GetWindow() *Window { - if x != nil { - return x.Window - } - return nil -} - -type MitigateResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *MitigateResponse) Reset() { - *x = MitigateResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MitigateResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MitigateResponse) ProtoMessage() {} - -func (x *MitigateResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_ratelimit_v1_service_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MitigateResponse.ProtoReflect.Descriptor instead. -func (*MitigateResponse) Descriptor() ([]byte, []int) { - return file_proto_ratelimit_v1_service_proto_rawDescGZIP(), []int{14} -} - -var File_proto_ratelimit_v1_service_proto protoreflect.FileDescriptor - -var file_proto_ratelimit_v1_service_proto_rawDesc = []byte{ - 0x0a, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, - 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x0c, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, - 0x22, 0x11, 0x0a, 0x0f, 0x4c, 0x69, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x2a, 0x0a, 0x10, 0x4c, 0x69, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, - 0x3c, 0x0a, 0x0c, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x63, - 0x6f, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xef, 0x01, - 0x0a, 0x10, 0x52, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x04, 0x63, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x05, - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x61, - 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x65, 0x61, 0x73, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x05, 0x6c, 0x65, 0x61, 0x73, 0x65, - 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x03, 0x48, 0x01, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, - 0x5f, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x22, - 0xcb, 0x01, 0x0a, 0x11, 0x52, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x72, - 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, - 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x73, - 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x72, 0x65, 0x73, 0x65, 0x74, 0x12, - 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x75, 0x72, - 0x72, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x63, 0x75, 0x72, 0x72, - 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x48, 0x00, 0x52, 0x05, 0x6c, 0x65, 0x61, 0x73, 0x65, - 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x22, 0x57, 0x0a, - 0x15, 0x52, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x0a, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x61, 0x74, - 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x72, 0x61, 0x74, 0x65, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x22, 0x59, 0x0a, 0x16, 0x52, 0x61, 0x74, 0x65, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x3f, 0x0a, 0x0a, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, - 0x73, 0x22, 0xad, 0x02, 0x0a, 0x06, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x12, 0x1a, 0x0a, 0x08, - 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, - 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x14, - 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x12, 0x31, 0x0a, 0x14, 0x6d, 0x69, 0x74, 0x69, 0x67, 0x61, 0x74, 0x65, - 0x5f, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x13, 0x6d, 0x69, 0x74, 0x69, 0x67, 0x61, 0x74, 0x65, 0x42, 0x72, 0x6f, 0x61, - 0x64, 0x63, 0x61, 0x73, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x06, 0x6c, 0x65, 0x61, 0x73, 0x65, - 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x4c, 0x65, - 0x61, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x65, 0x61, 0x73, 0x65, - 0x73, 0x1a, 0x4e, 0x0a, 0x0b, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x77, 0x0a, 0x0f, 0x50, 0x75, 0x73, 0x68, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, - 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0xb1, 0x01, 0x0a, 0x10, 0x50, - 0x75, 0x73, 0x68, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x2e, 0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, - 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x52, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, - 0x30, 0x0a, 0x08, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x52, 0x08, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, - 0x73, 0x12, 0x3b, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x59, - 0x0a, 0x05, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x53, 0x0a, 0x12, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x29, 0x0a, 0x05, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x65, - 0x61, 0x73, 0x65, 0x52, 0x05, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, - 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x63, 0x6f, 0x73, 0x74, 0x22, 0x15, - 0x0a, 0x13, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x91, 0x01, 0x0a, 0x0f, 0x4d, 0x69, 0x74, 0x69, 0x67, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, - 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, - 0x1a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x06, 0x77, - 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x61, - 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x6e, 0x64, 0x6f, - 0x77, 0x52, 0x06, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x22, 0x12, 0x0a, 0x10, 0x4d, 0x69, 0x74, - 0x69, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xfe, 0x03, - 0x0a, 0x10, 0x52, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x12, 0x4b, 0x0a, 0x08, 0x4c, 0x69, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x12, 0x1d, - 0x2e, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, - 0x76, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, - 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x76, - 0x65, 0x6e, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x4e, 0x0a, 0x09, 0x52, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1e, 0x2e, 0x72, - 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x61, 0x74, 0x65, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x72, - 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x61, 0x74, 0x65, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x5d, 0x0a, 0x0e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, - 0x74, 0x12, 0x23, 0x2e, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, - 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x4d, - 0x75, 0x6c, 0x74, 0x69, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4b, - 0x0a, 0x08, 0x50, 0x75, 0x73, 0x68, 0x50, 0x75, 0x6c, 0x6c, 0x12, 0x1d, 0x2e, 0x72, 0x61, 0x74, - 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x50, 0x75, - 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x72, 0x61, 0x74, 0x65, - 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x50, 0x75, 0x6c, - 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0b, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x20, 0x2e, 0x72, 0x61, 0x74, - 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x4c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, - 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x4c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x00, 0x12, 0x4b, 0x0a, 0x08, 0x4d, 0x69, 0x74, 0x69, 0x67, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x2e, - 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x74, - 0x69, 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x72, - 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x74, 0x69, - 0x67, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x48, - 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x6e, 0x6b, - 0x65, 0x79, 0x65, 0x64, 0x2f, 0x75, 0x6e, 0x6b, 0x65, 0x79, 0x2f, 0x61, 0x70, 0x70, 0x73, 0x2f, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x72, 0x61, 0x74, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x61, 0x74, - 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_ratelimit_v1_service_proto_rawDescOnce sync.Once - file_proto_ratelimit_v1_service_proto_rawDescData = file_proto_ratelimit_v1_service_proto_rawDesc -) - -func file_proto_ratelimit_v1_service_proto_rawDescGZIP() []byte { - file_proto_ratelimit_v1_service_proto_rawDescOnce.Do(func() { - file_proto_ratelimit_v1_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_ratelimit_v1_service_proto_rawDescData) - }) - return file_proto_ratelimit_v1_service_proto_rawDescData -} - -var file_proto_ratelimit_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 16) -var file_proto_ratelimit_v1_service_proto_goTypes = []any{ - (*LivenessRequest)(nil), // 0: ratelimit.v1.LivenessRequest - (*LivenessResponse)(nil), // 1: ratelimit.v1.LivenessResponse - (*LeaseRequest)(nil), // 2: ratelimit.v1.LeaseRequest - (*RatelimitRequest)(nil), // 3: ratelimit.v1.RatelimitRequest - (*RatelimitResponse)(nil), // 4: ratelimit.v1.RatelimitResponse - (*RatelimitMultiRequest)(nil), // 5: ratelimit.v1.RatelimitMultiRequest - (*RatelimitMultiResponse)(nil), // 6: ratelimit.v1.RatelimitMultiResponse - (*Window)(nil), // 7: ratelimit.v1.Window - (*PushPullRequest)(nil), // 8: ratelimit.v1.PushPullRequest - (*PushPullResponse)(nil), // 9: ratelimit.v1.PushPullResponse - (*Lease)(nil), // 10: ratelimit.v1.Lease - (*CommitLeaseRequest)(nil), // 11: ratelimit.v1.CommitLeaseRequest - (*CommitLeaseResponse)(nil), // 12: ratelimit.v1.CommitLeaseResponse - (*MitigateRequest)(nil), // 13: ratelimit.v1.MitigateRequest - (*MitigateResponse)(nil), // 14: ratelimit.v1.MitigateResponse - nil, // 15: ratelimit.v1.Window.LeasesEntry -} -var file_proto_ratelimit_v1_service_proto_depIdxs = []int32{ - 2, // 0: ratelimit.v1.RatelimitRequest.lease:type_name -> ratelimit.v1.LeaseRequest - 10, // 1: ratelimit.v1.RatelimitResponse.lease:type_name -> ratelimit.v1.Lease - 3, // 2: ratelimit.v1.RatelimitMultiRequest.ratelimits:type_name -> ratelimit.v1.RatelimitRequest - 4, // 3: ratelimit.v1.RatelimitMultiResponse.ratelimits:type_name -> ratelimit.v1.RatelimitResponse - 15, // 4: ratelimit.v1.Window.leases:type_name -> ratelimit.v1.Window.LeasesEntry - 3, // 5: ratelimit.v1.PushPullRequest.request:type_name -> ratelimit.v1.RatelimitRequest - 7, // 6: ratelimit.v1.PushPullResponse.current:type_name -> ratelimit.v1.Window - 7, // 7: ratelimit.v1.PushPullResponse.previous:type_name -> ratelimit.v1.Window - 4, // 8: ratelimit.v1.PushPullResponse.response:type_name -> ratelimit.v1.RatelimitResponse - 10, // 9: ratelimit.v1.CommitLeaseRequest.lease:type_name -> ratelimit.v1.Lease - 7, // 10: ratelimit.v1.MitigateRequest.window:type_name -> ratelimit.v1.Window - 10, // 11: ratelimit.v1.Window.LeasesEntry.value:type_name -> ratelimit.v1.Lease - 0, // 12: ratelimit.v1.RatelimitService.Liveness:input_type -> ratelimit.v1.LivenessRequest - 3, // 13: ratelimit.v1.RatelimitService.Ratelimit:input_type -> ratelimit.v1.RatelimitRequest - 5, // 14: ratelimit.v1.RatelimitService.MultiRatelimit:input_type -> ratelimit.v1.RatelimitMultiRequest - 8, // 15: ratelimit.v1.RatelimitService.PushPull:input_type -> ratelimit.v1.PushPullRequest - 11, // 16: ratelimit.v1.RatelimitService.CommitLease:input_type -> ratelimit.v1.CommitLeaseRequest - 13, // 17: ratelimit.v1.RatelimitService.Mitigate:input_type -> ratelimit.v1.MitigateRequest - 1, // 18: ratelimit.v1.RatelimitService.Liveness:output_type -> ratelimit.v1.LivenessResponse - 4, // 19: ratelimit.v1.RatelimitService.Ratelimit:output_type -> ratelimit.v1.RatelimitResponse - 6, // 20: ratelimit.v1.RatelimitService.MultiRatelimit:output_type -> ratelimit.v1.RatelimitMultiResponse - 9, // 21: ratelimit.v1.RatelimitService.PushPull:output_type -> ratelimit.v1.PushPullResponse - 12, // 22: ratelimit.v1.RatelimitService.CommitLease:output_type -> ratelimit.v1.CommitLeaseResponse - 14, // 23: ratelimit.v1.RatelimitService.Mitigate:output_type -> ratelimit.v1.MitigateResponse - 18, // [18:24] is the sub-list for method output_type - 12, // [12:18] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name -} - -func init() { file_proto_ratelimit_v1_service_proto_init() } -func file_proto_ratelimit_v1_service_proto_init() { - if File_proto_ratelimit_v1_service_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_ratelimit_v1_service_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*LivenessRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*LivenessResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*LeaseRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*RatelimitRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*RatelimitResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*RatelimitMultiRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[6].Exporter = func(v any, i int) any { - switch v := v.(*RatelimitMultiResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[7].Exporter = func(v any, i int) any { - switch v := v.(*Window); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[8].Exporter = func(v any, i int) any { - switch v := v.(*PushPullRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[9].Exporter = func(v any, i int) any { - switch v := v.(*PushPullResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[10].Exporter = func(v any, i int) any { - switch v := v.(*Lease); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[11].Exporter = func(v any, i int) any { - switch v := v.(*CommitLeaseRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[12].Exporter = func(v any, i int) any { - switch v := v.(*CommitLeaseResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[13].Exporter = func(v any, i int) any { - switch v := v.(*MitigateRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[14].Exporter = func(v any, i int) any { - switch v := v.(*MitigateResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_proto_ratelimit_v1_service_proto_msgTypes[3].OneofWrappers = []any{} - file_proto_ratelimit_v1_service_proto_msgTypes[4].OneofWrappers = []any{} - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_ratelimit_v1_service_proto_rawDesc, - NumEnums: 0, - NumMessages: 16, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_ratelimit_v1_service_proto_goTypes, - DependencyIndexes: file_proto_ratelimit_v1_service_proto_depIdxs, - MessageInfos: file_proto_ratelimit_v1_service_proto_msgTypes, - }.Build() - File_proto_ratelimit_v1_service_proto = out.File - file_proto_ratelimit_v1_service_proto_rawDesc = nil - file_proto_ratelimit_v1_service_proto_goTypes = nil - file_proto_ratelimit_v1_service_proto_depIdxs = nil -} diff --git a/web/apps/agent/gen/proto/vault/v1/object.openapi.yaml b/web/apps/agent/gen/proto/vault/v1/object.openapi.yaml deleted file mode 100644 index b3f93b0137..0000000000 --- a/web/apps/agent/gen/proto/vault/v1/object.openapi.yaml +++ /dev/null @@ -1,151 +0,0 @@ -openapi: 3.1.0 -info: - title: vault.v1 -paths: {} -components: - schemas: - vault.v1.Algorithm: - type: string - title: Algorithm - enum: - - AES_256_GCM - vault.v1.DataEncryptionKey: - type: object - properties: - id: - type: string - title: id - additionalProperties: false - createdAt: - oneOf: - - type: string - - type: number - title: created_at - additionalProperties: false - description: Linux milliseconds since epoch - key: - type: string - title: key - format: byte - additionalProperties: false - title: DataEncryptionKey - additionalProperties: false - vault.v1.Encrypted: - type: object - properties: - algorithm: - $ref: '#/components/schemas/vault.v1.Algorithm' - nonce: - type: string - title: nonce - format: byte - additionalProperties: false - ciphertext: - type: string - title: ciphertext - format: byte - additionalProperties: false - encryptionKeyId: - type: string - title: encryption_key_id - additionalProperties: false - description: key id of the key that encrypted this data - time: - oneOf: - - type: string - - type: number - title: time - additionalProperties: false - description: |- - time of encryption - we can use this later to figure out if a piece of data should be re-encrypted - title: Encrypted - additionalProperties: false - description: Encrypted contains the output of the encryption and all of the metadata required to decrypt it - vault.v1.EncryptedDataEncryptionKey: - type: object - properties: - id: - type: string - title: id - additionalProperties: false - createdAt: - oneOf: - - type: string - - type: number - title: created_at - additionalProperties: false - description: Linux milliseconds since epoch - encrypted: - $ref: '#/components/schemas/vault.v1.Encrypted' - title: EncryptedDataEncryptionKey - additionalProperties: false - description: This is stored in the database in whatever format the database uses - vault.v1.KeyEncryptionKey: - type: object - properties: - id: - type: string - title: id - additionalProperties: false - createdAt: - oneOf: - - type: string - - type: number - title: created_at - additionalProperties: false - key: - type: string - title: key - format: byte - additionalProperties: false - title: KeyEncryptionKey - additionalProperties: false - description: KeyEncryptionKey is a key used to encrypt data encryption keys - connect.error: - type: object - properties: - code: - type: string - examples: - - CodeNotFound - enum: - - CodeCanceled - - CodeUnknown - - CodeInvalidArgument - - CodeDeadlineExceeded - - CodeNotFound - - CodeAlreadyExists - - CodePermissionDenied - - CodeResourceExhausted - - CodeFailedPrecondition - - CodeAborted - - CodeOutOfRange - - CodeInternal - - CodeUnavailable - - CodeDataLoss - - CodeUnauthenticated - description: The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. - message: - type: string - description: A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. - detail: - $ref: '#/components/schemas/google.protobuf.Any' - title: Connect Error - additionalProperties: true - description: 'Error type returned by Connect: https://connectrpc.com/docs/go/errors/#http-representation' - google.protobuf.Any: - type: object - properties: - type: - type: string - value: - type: string - format: binary - debug: - type: object - additionalProperties: true - additionalProperties: true - description: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message. -security: [] -externalDocs: {} diff --git a/web/apps/agent/gen/proto/vault/v1/object.pb.go b/web/apps/agent/gen/proto/vault/v1/object.pb.go deleted file mode 100644 index ff56495128..0000000000 --- a/web/apps/agent/gen/proto/vault/v1/object.pb.go +++ /dev/null @@ -1,492 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.34.2 -// protoc (unknown) -// source: proto/vault/v1/object.proto - -package vaultv1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Algorithm int32 - -const ( - Algorithm_AES_256_GCM Algorithm = 0 -) - -// Enum value maps for Algorithm. -var ( - Algorithm_name = map[int32]string{ - 0: "AES_256_GCM", - } - Algorithm_value = map[string]int32{ - "AES_256_GCM": 0, - } -) - -func (x Algorithm) Enum() *Algorithm { - p := new(Algorithm) - *p = x - return p -} - -func (x Algorithm) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Algorithm) Descriptor() protoreflect.EnumDescriptor { - return file_proto_vault_v1_object_proto_enumTypes[0].Descriptor() -} - -func (Algorithm) Type() protoreflect.EnumType { - return &file_proto_vault_v1_object_proto_enumTypes[0] -} - -func (x Algorithm) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Algorithm.Descriptor instead. -func (Algorithm) EnumDescriptor() ([]byte, []int) { - return file_proto_vault_v1_object_proto_rawDescGZIP(), []int{0} -} - -type DataEncryptionKey struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // Linux milliseconds since epoch - CreatedAt int64 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - Key []byte `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` -} - -func (x *DataEncryptionKey) Reset() { - *x = DataEncryptionKey{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_object_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DataEncryptionKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DataEncryptionKey) ProtoMessage() {} - -func (x *DataEncryptionKey) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_object_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DataEncryptionKey.ProtoReflect.Descriptor instead. -func (*DataEncryptionKey) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_object_proto_rawDescGZIP(), []int{0} -} - -func (x *DataEncryptionKey) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *DataEncryptionKey) GetCreatedAt() int64 { - if x != nil { - return x.CreatedAt - } - return 0 -} - -func (x *DataEncryptionKey) GetKey() []byte { - if x != nil { - return x.Key - } - return nil -} - -// This is stored in the database in whatever format the database uses -type EncryptedDataEncryptionKey struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // Linux milliseconds since epoch - CreatedAt int64 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - Encrypted *Encrypted `protobuf:"bytes,3,opt,name=encrypted,proto3" json:"encrypted,omitempty"` -} - -func (x *EncryptedDataEncryptionKey) Reset() { - *x = EncryptedDataEncryptionKey{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_object_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EncryptedDataEncryptionKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EncryptedDataEncryptionKey) ProtoMessage() {} - -func (x *EncryptedDataEncryptionKey) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_object_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EncryptedDataEncryptionKey.ProtoReflect.Descriptor instead. -func (*EncryptedDataEncryptionKey) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_object_proto_rawDescGZIP(), []int{1} -} - -func (x *EncryptedDataEncryptionKey) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *EncryptedDataEncryptionKey) GetCreatedAt() int64 { - if x != nil { - return x.CreatedAt - } - return 0 -} - -func (x *EncryptedDataEncryptionKey) GetEncrypted() *Encrypted { - if x != nil { - return x.Encrypted - } - return nil -} - -// KeyEncryptionKey is a key used to encrypt data encryption keys -type KeyEncryptionKey struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - CreatedAt int64 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - Key []byte `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` -} - -func (x *KeyEncryptionKey) Reset() { - *x = KeyEncryptionKey{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_object_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *KeyEncryptionKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*KeyEncryptionKey) ProtoMessage() {} - -func (x *KeyEncryptionKey) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_object_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use KeyEncryptionKey.ProtoReflect.Descriptor instead. -func (*KeyEncryptionKey) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_object_proto_rawDescGZIP(), []int{2} -} - -func (x *KeyEncryptionKey) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *KeyEncryptionKey) GetCreatedAt() int64 { - if x != nil { - return x.CreatedAt - } - return 0 -} - -func (x *KeyEncryptionKey) GetKey() []byte { - if x != nil { - return x.Key - } - return nil -} - -// Encrypted contains the output of the encryption and all of the metadata required to decrypt it -type Encrypted struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Algorithm Algorithm `protobuf:"varint,1,opt,name=algorithm,proto3,enum=vault.v1.Algorithm" json:"algorithm,omitempty"` - Nonce []byte `protobuf:"bytes,2,opt,name=nonce,proto3" json:"nonce,omitempty"` - Ciphertext []byte `protobuf:"bytes,3,opt,name=ciphertext,proto3" json:"ciphertext,omitempty"` - // key id of the key that encrypted this data - EncryptionKeyId string `protobuf:"bytes,4,opt,name=encryption_key_id,json=encryptionKeyId,proto3" json:"encryption_key_id,omitempty"` - // time of encryption - // we can use this later to figure out if a piece of data should be re-encrypted - Time int64 `protobuf:"varint,5,opt,name=time,proto3" json:"time,omitempty"` -} - -func (x *Encrypted) Reset() { - *x = Encrypted{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_object_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Encrypted) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Encrypted) ProtoMessage() {} - -func (x *Encrypted) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_object_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Encrypted.ProtoReflect.Descriptor instead. -func (*Encrypted) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_object_proto_rawDescGZIP(), []int{3} -} - -func (x *Encrypted) GetAlgorithm() Algorithm { - if x != nil { - return x.Algorithm - } - return Algorithm_AES_256_GCM -} - -func (x *Encrypted) GetNonce() []byte { - if x != nil { - return x.Nonce - } - return nil -} - -func (x *Encrypted) GetCiphertext() []byte { - if x != nil { - return x.Ciphertext - } - return nil -} - -func (x *Encrypted) GetEncryptionKeyId() string { - if x != nil { - return x.EncryptionKeyId - } - return "" -} - -func (x *Encrypted) GetTime() int64 { - if x != nil { - return x.Time - } - return 0 -} - -var File_proto_vault_v1_object_proto protoreflect.FileDescriptor - -var file_proto_vault_v1_object_proto_rawDesc = []byte{ - 0x0a, 0x1b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, - 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x76, - 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x22, 0x54, 0x0a, 0x11, 0x44, 0x61, 0x74, 0x61, 0x45, - 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x0e, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x7e, 0x0a, - 0x1a, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x31, 0x0a, 0x09, 0x65, 0x6e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, - 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, - 0x65, 0x64, 0x52, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x22, 0x53, 0x0a, - 0x10, 0x4b, 0x65, 0x79, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, - 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x22, 0xb4, 0x01, 0x0a, 0x09, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, - 0x12, 0x31, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, - 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, - 0x74, 0x68, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x69, 0x70, - 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x63, - 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x6e, 0x63, - 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x2a, 0x1c, 0x0a, 0x09, 0x41, 0x6c, 0x67, - 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x32, 0x35, - 0x36, 0x5f, 0x47, 0x43, 0x4d, 0x10, 0x00, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x6e, 0x6b, 0x65, 0x79, 0x65, 0x64, 0x2f, 0x75, 0x6e, - 0x6b, 0x65, 0x79, 0x2f, 0x61, 0x70, 0x70, 0x73, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x67, - 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, - 0x31, 0x3b, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} - -var ( - file_proto_vault_v1_object_proto_rawDescOnce sync.Once - file_proto_vault_v1_object_proto_rawDescData = file_proto_vault_v1_object_proto_rawDesc -) - -func file_proto_vault_v1_object_proto_rawDescGZIP() []byte { - file_proto_vault_v1_object_proto_rawDescOnce.Do(func() { - file_proto_vault_v1_object_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_vault_v1_object_proto_rawDescData) - }) - return file_proto_vault_v1_object_proto_rawDescData -} - -var file_proto_vault_v1_object_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_proto_vault_v1_object_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_proto_vault_v1_object_proto_goTypes = []any{ - (Algorithm)(0), // 0: vault.v1.Algorithm - (*DataEncryptionKey)(nil), // 1: vault.v1.DataEncryptionKey - (*EncryptedDataEncryptionKey)(nil), // 2: vault.v1.EncryptedDataEncryptionKey - (*KeyEncryptionKey)(nil), // 3: vault.v1.KeyEncryptionKey - (*Encrypted)(nil), // 4: vault.v1.Encrypted -} -var file_proto_vault_v1_object_proto_depIdxs = []int32{ - 4, // 0: vault.v1.EncryptedDataEncryptionKey.encrypted:type_name -> vault.v1.Encrypted - 0, // 1: vault.v1.Encrypted.algorithm:type_name -> vault.v1.Algorithm - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_proto_vault_v1_object_proto_init() } -func file_proto_vault_v1_object_proto_init() { - if File_proto_vault_v1_object_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_vault_v1_object_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*DataEncryptionKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_object_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*EncryptedDataEncryptionKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_object_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*KeyEncryptionKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_object_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*Encrypted); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_vault_v1_object_proto_rawDesc, - NumEnums: 1, - NumMessages: 4, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_proto_vault_v1_object_proto_goTypes, - DependencyIndexes: file_proto_vault_v1_object_proto_depIdxs, - EnumInfos: file_proto_vault_v1_object_proto_enumTypes, - MessageInfos: file_proto_vault_v1_object_proto_msgTypes, - }.Build() - File_proto_vault_v1_object_proto = out.File - file_proto_vault_v1_object_proto_rawDesc = nil - file_proto_vault_v1_object_proto_goTypes = nil - file_proto_vault_v1_object_proto_depIdxs = nil -} diff --git a/web/apps/agent/gen/proto/vault/v1/service.openapi.yaml b/web/apps/agent/gen/proto/vault/v1/service.openapi.yaml deleted file mode 100644 index 842d096ea4..0000000000 --- a/web/apps/agent/gen/proto/vault/v1/service.openapi.yaml +++ /dev/null @@ -1,345 +0,0 @@ -openapi: 3.1.0 -info: - title: vault.v1 -paths: - /vault.v1.VaultService/Liveness: - post: - tags: - - vault.v1.VaultService - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/vault.v1.LivenessRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/vault.v1.LivenessResponse' - /vault.v1.VaultService/CreateDEK: - post: - tags: - - vault.v1.VaultService - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/vault.v1.CreateDEKRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/vault.v1.CreateDEKResponse' - /vault.v1.VaultService/Encrypt: - post: - tags: - - vault.v1.VaultService - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/vault.v1.EncryptRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/vault.v1.EncryptResponse' - /vault.v1.VaultService/EncryptBulk: - post: - tags: - - vault.v1.VaultService - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/vault.v1.EncryptBulkRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/vault.v1.EncryptBulkResponse' - /vault.v1.VaultService/Decrypt: - post: - tags: - - vault.v1.VaultService - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/vault.v1.DecryptRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/vault.v1.DecryptResponse' - /vault.v1.VaultService/ReEncrypt: - post: - tags: - - vault.v1.VaultService - description: ReEncrypt rec - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/vault.v1.ReEncryptRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/vault.v1.ReEncryptResponse' - /vault.v1.VaultService/ReEncryptDEKs: - post: - tags: - - vault.v1.VaultService - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/vault.v1.ReEncryptDEKsRequest' - required: true - responses: - default: - content: - application/json: - schema: - $ref: '#/components/schemas/connect.error' - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/vault.v1.ReEncryptDEKsResponse' -components: - schemas: - vault.v1.CreateDEKRequest: - type: object - properties: - keyring: - type: string - title: keyring - additionalProperties: false - title: CreateDEKRequest - additionalProperties: false - vault.v1.CreateDEKResponse: - type: object - properties: - keyId: - type: string - title: key_id - additionalProperties: false - title: CreateDEKResponse - additionalProperties: false - vault.v1.DecryptRequest: - type: object - properties: - keyring: - type: string - title: keyring - additionalProperties: false - encrypted: - type: string - title: encrypted - additionalProperties: false - title: DecryptRequest - additionalProperties: false - vault.v1.DecryptResponse: - type: object - properties: - plaintext: - type: string - title: plaintext - additionalProperties: false - title: DecryptResponse - additionalProperties: false - vault.v1.EncryptBulkRequest: - type: object - properties: - keyring: - type: string - title: keyring - additionalProperties: false - data: - type: array - items: - type: string - title: data - additionalProperties: false - title: EncryptBulkRequest - additionalProperties: false - vault.v1.EncryptBulkResponse: - type: object - properties: - encrypted: - type: array - items: - $ref: '#/components/schemas/vault.v1.EncryptResponse' - title: EncryptBulkResponse - additionalProperties: false - vault.v1.EncryptRequest: - type: object - properties: - keyring: - type: string - title: keyring - additionalProperties: false - data: - type: string - title: data - additionalProperties: false - title: EncryptRequest - additionalProperties: false - vault.v1.EncryptResponse: - type: object - properties: - encrypted: - type: string - title: encrypted - additionalProperties: false - keyId: - type: string - title: key_id - additionalProperties: false - title: EncryptResponse - additionalProperties: false - vault.v1.LivenessRequest: - type: object - title: LivenessRequest - additionalProperties: false - vault.v1.LivenessResponse: - type: object - properties: - status: - type: string - title: status - additionalProperties: false - title: LivenessResponse - additionalProperties: false - vault.v1.ReEncryptDEKsRequest: - type: object - title: ReEncryptDEKsRequest - additionalProperties: false - vault.v1.ReEncryptDEKsResponse: - type: object - title: ReEncryptDEKsResponse - additionalProperties: false - vault.v1.ReEncryptRequest: - type: object - properties: - keyring: - type: string - title: keyring - additionalProperties: false - encrypted: - type: string - title: encrypted - additionalProperties: false - keyId: - type: string - title: key_id - additionalProperties: false - description: Specify the key_id to use for re-encryption. If not provided, the latest will be used - title: ReEncryptRequest - additionalProperties: false - vault.v1.ReEncryptResponse: - type: object - properties: - encrypted: - type: string - title: encrypted - additionalProperties: false - keyId: - type: string - title: key_id - additionalProperties: false - title: ReEncryptResponse - additionalProperties: false - connect.error: - type: object - properties: - code: - type: string - examples: - - CodeNotFound - enum: - - CodeCanceled - - CodeUnknown - - CodeInvalidArgument - - CodeDeadlineExceeded - - CodeNotFound - - CodeAlreadyExists - - CodePermissionDenied - - CodeResourceExhausted - - CodeFailedPrecondition - - CodeAborted - - CodeOutOfRange - - CodeInternal - - CodeUnavailable - - CodeDataLoss - - CodeUnauthenticated - description: The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. - message: - type: string - description: A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. - detail: - $ref: '#/components/schemas/google.protobuf.Any' - title: Connect Error - additionalProperties: true - description: 'Error type returned by Connect: https://connectrpc.com/docs/go/errors/#http-representation' - google.protobuf.Any: - type: object - properties: - type: - type: string - value: - type: string - format: binary - debug: - type: object - additionalProperties: true - additionalProperties: true - description: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message. -security: [] -tags: - - name: vault.v1.VaultService -externalDocs: {} diff --git a/web/apps/agent/gen/proto/vault/v1/service.pb.go b/web/apps/agent/gen/proto/vault/v1/service.pb.go deleted file mode 100644 index 7d0397ead0..0000000000 --- a/web/apps/agent/gen/proto/vault/v1/service.pb.go +++ /dev/null @@ -1,1052 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.34.2 -// protoc (unknown) -// source: proto/vault/v1/service.proto - -package vaultv1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type LivenessRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *LivenessRequest) Reset() { - *x = LivenessRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_service_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LivenessRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LivenessRequest) ProtoMessage() {} - -func (x *LivenessRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_service_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LivenessRequest.ProtoReflect.Descriptor instead. -func (*LivenessRequest) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_service_proto_rawDescGZIP(), []int{0} -} - -type LivenessResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` -} - -func (x *LivenessResponse) Reset() { - *x = LivenessResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_service_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *LivenessResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LivenessResponse) ProtoMessage() {} - -func (x *LivenessResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_service_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LivenessResponse.ProtoReflect.Descriptor instead. -func (*LivenessResponse) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_service_proto_rawDescGZIP(), []int{1} -} - -func (x *LivenessResponse) GetStatus() string { - if x != nil { - return x.Status - } - return "" -} - -type EncryptRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Keyring string `protobuf:"bytes,1,opt,name=keyring,proto3" json:"keyring,omitempty"` - Data string `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` -} - -func (x *EncryptRequest) Reset() { - *x = EncryptRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_service_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EncryptRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EncryptRequest) ProtoMessage() {} - -func (x *EncryptRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_service_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EncryptRequest.ProtoReflect.Descriptor instead. -func (*EncryptRequest) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_service_proto_rawDescGZIP(), []int{2} -} - -func (x *EncryptRequest) GetKeyring() string { - if x != nil { - return x.Keyring - } - return "" -} - -func (x *EncryptRequest) GetData() string { - if x != nil { - return x.Data - } - return "" -} - -type EncryptResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Encrypted string `protobuf:"bytes,1,opt,name=encrypted,proto3" json:"encrypted,omitempty"` - KeyId string `protobuf:"bytes,2,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` -} - -func (x *EncryptResponse) Reset() { - *x = EncryptResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_service_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EncryptResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EncryptResponse) ProtoMessage() {} - -func (x *EncryptResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_service_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EncryptResponse.ProtoReflect.Descriptor instead. -func (*EncryptResponse) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_service_proto_rawDescGZIP(), []int{3} -} - -func (x *EncryptResponse) GetEncrypted() string { - if x != nil { - return x.Encrypted - } - return "" -} - -func (x *EncryptResponse) GetKeyId() string { - if x != nil { - return x.KeyId - } - return "" -} - -type EncryptBulkRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Keyring string `protobuf:"bytes,1,opt,name=keyring,proto3" json:"keyring,omitempty"` - Data []string `protobuf:"bytes,2,rep,name=data,proto3" json:"data,omitempty"` -} - -func (x *EncryptBulkRequest) Reset() { - *x = EncryptBulkRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_service_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EncryptBulkRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EncryptBulkRequest) ProtoMessage() {} - -func (x *EncryptBulkRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_service_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EncryptBulkRequest.ProtoReflect.Descriptor instead. -func (*EncryptBulkRequest) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_service_proto_rawDescGZIP(), []int{4} -} - -func (x *EncryptBulkRequest) GetKeyring() string { - if x != nil { - return x.Keyring - } - return "" -} - -func (x *EncryptBulkRequest) GetData() []string { - if x != nil { - return x.Data - } - return nil -} - -type EncryptBulkResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Encrypted []*EncryptResponse `protobuf:"bytes,1,rep,name=encrypted,proto3" json:"encrypted,omitempty"` -} - -func (x *EncryptBulkResponse) Reset() { - *x = EncryptBulkResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_service_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *EncryptBulkResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EncryptBulkResponse) ProtoMessage() {} - -func (x *EncryptBulkResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_service_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EncryptBulkResponse.ProtoReflect.Descriptor instead. -func (*EncryptBulkResponse) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_service_proto_rawDescGZIP(), []int{5} -} - -func (x *EncryptBulkResponse) GetEncrypted() []*EncryptResponse { - if x != nil { - return x.Encrypted - } - return nil -} - -type DecryptRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Keyring string `protobuf:"bytes,1,opt,name=keyring,proto3" json:"keyring,omitempty"` - Encrypted string `protobuf:"bytes,2,opt,name=encrypted,proto3" json:"encrypted,omitempty"` -} - -func (x *DecryptRequest) Reset() { - *x = DecryptRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_service_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DecryptRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DecryptRequest) ProtoMessage() {} - -func (x *DecryptRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_service_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DecryptRequest.ProtoReflect.Descriptor instead. -func (*DecryptRequest) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_service_proto_rawDescGZIP(), []int{6} -} - -func (x *DecryptRequest) GetKeyring() string { - if x != nil { - return x.Keyring - } - return "" -} - -func (x *DecryptRequest) GetEncrypted() string { - if x != nil { - return x.Encrypted - } - return "" -} - -type DecryptResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Plaintext string `protobuf:"bytes,1,opt,name=plaintext,proto3" json:"plaintext,omitempty"` -} - -func (x *DecryptResponse) Reset() { - *x = DecryptResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_service_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DecryptResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DecryptResponse) ProtoMessage() {} - -func (x *DecryptResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_service_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DecryptResponse.ProtoReflect.Descriptor instead. -func (*DecryptResponse) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_service_proto_rawDescGZIP(), []int{7} -} - -func (x *DecryptResponse) GetPlaintext() string { - if x != nil { - return x.Plaintext - } - return "" -} - -type CreateDEKRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Keyring string `protobuf:"bytes,1,opt,name=keyring,proto3" json:"keyring,omitempty"` -} - -func (x *CreateDEKRequest) Reset() { - *x = CreateDEKRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_service_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateDEKRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateDEKRequest) ProtoMessage() {} - -func (x *CreateDEKRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_service_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateDEKRequest.ProtoReflect.Descriptor instead. -func (*CreateDEKRequest) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_service_proto_rawDescGZIP(), []int{8} -} - -func (x *CreateDEKRequest) GetKeyring() string { - if x != nil { - return x.Keyring - } - return "" -} - -type CreateDEKResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - KeyId string `protobuf:"bytes,1,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` -} - -func (x *CreateDEKResponse) Reset() { - *x = CreateDEKResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_service_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateDEKResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateDEKResponse) ProtoMessage() {} - -func (x *CreateDEKResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_service_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateDEKResponse.ProtoReflect.Descriptor instead. -func (*CreateDEKResponse) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_service_proto_rawDescGZIP(), []int{9} -} - -func (x *CreateDEKResponse) GetKeyId() string { - if x != nil { - return x.KeyId - } - return "" -} - -type ReEncryptRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Keyring string `protobuf:"bytes,1,opt,name=keyring,proto3" json:"keyring,omitempty"` - Encrypted string `protobuf:"bytes,2,opt,name=encrypted,proto3" json:"encrypted,omitempty"` - // Specify the key_id to use for re-encryption. If not provided, the latest will be used - KeyId *string `protobuf:"bytes,3,opt,name=key_id,json=keyId,proto3,oneof" json:"key_id,omitempty"` -} - -func (x *ReEncryptRequest) Reset() { - *x = ReEncryptRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_service_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReEncryptRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReEncryptRequest) ProtoMessage() {} - -func (x *ReEncryptRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_service_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReEncryptRequest.ProtoReflect.Descriptor instead. -func (*ReEncryptRequest) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_service_proto_rawDescGZIP(), []int{10} -} - -func (x *ReEncryptRequest) GetKeyring() string { - if x != nil { - return x.Keyring - } - return "" -} - -func (x *ReEncryptRequest) GetEncrypted() string { - if x != nil { - return x.Encrypted - } - return "" -} - -func (x *ReEncryptRequest) GetKeyId() string { - if x != nil && x.KeyId != nil { - return *x.KeyId - } - return "" -} - -type ReEncryptResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Encrypted string `protobuf:"bytes,1,opt,name=encrypted,proto3" json:"encrypted,omitempty"` - KeyId string `protobuf:"bytes,2,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty"` -} - -func (x *ReEncryptResponse) Reset() { - *x = ReEncryptResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_service_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReEncryptResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReEncryptResponse) ProtoMessage() {} - -func (x *ReEncryptResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_service_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReEncryptResponse.ProtoReflect.Descriptor instead. -func (*ReEncryptResponse) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_service_proto_rawDescGZIP(), []int{11} -} - -func (x *ReEncryptResponse) GetEncrypted() string { - if x != nil { - return x.Encrypted - } - return "" -} - -func (x *ReEncryptResponse) GetKeyId() string { - if x != nil { - return x.KeyId - } - return "" -} - -type ReEncryptDEKsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *ReEncryptDEKsRequest) Reset() { - *x = ReEncryptDEKsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_service_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReEncryptDEKsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReEncryptDEKsRequest) ProtoMessage() {} - -func (x *ReEncryptDEKsRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_service_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReEncryptDEKsRequest.ProtoReflect.Descriptor instead. -func (*ReEncryptDEKsRequest) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_service_proto_rawDescGZIP(), []int{12} -} - -type ReEncryptDEKsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *ReEncryptDEKsResponse) Reset() { - *x = ReEncryptDEKsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_vault_v1_service_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ReEncryptDEKsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ReEncryptDEKsResponse) ProtoMessage() {} - -func (x *ReEncryptDEKsResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_vault_v1_service_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ReEncryptDEKsResponse.ProtoReflect.Descriptor instead. -func (*ReEncryptDEKsResponse) Descriptor() ([]byte, []int) { - return file_proto_vault_v1_service_proto_rawDescGZIP(), []int{13} -} - -var File_proto_vault_v1_service_proto protoreflect.FileDescriptor - -var file_proto_vault_v1_service_proto_rawDesc = []byte{ - 0x0a, 0x1c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, - 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, - 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x22, 0x11, 0x0a, 0x0f, 0x4c, 0x69, 0x76, 0x65, - 0x6e, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2a, 0x0a, 0x10, 0x4c, - 0x69, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3e, 0x0a, 0x0e, 0x45, 0x6e, 0x63, 0x72, 0x79, - 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6b, 0x65, 0x79, - 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x72, - 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x46, 0x0a, 0x0f, 0x45, 0x6e, 0x63, 0x72, 0x79, - 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, - 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, - 0x42, 0x0a, 0x12, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x72, 0x69, 0x6e, 0x67, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x72, 0x69, 0x6e, 0x67, 0x12, - 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x22, 0x4e, 0x0a, 0x13, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x42, 0x75, - 0x6c, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x09, 0x65, 0x6e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, - 0x74, 0x65, 0x64, 0x22, 0x48, 0x0a, 0x0e, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x72, 0x69, 0x6e, 0x67, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x72, 0x69, 0x6e, 0x67, 0x12, - 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x22, 0x2f, 0x0a, - 0x0f, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x2c, - 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x45, 0x4b, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x2a, 0x0a, 0x11, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x45, 0x4b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x71, 0x0a, 0x10, 0x52, 0x65, 0x45, 0x6e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, - 0x6b, 0x65, 0x79, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, - 0x65, 0x79, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, - 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, - 0x70, 0x74, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x88, 0x01, 0x01, - 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x22, 0x48, 0x0a, 0x11, 0x52, - 0x65, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x12, 0x15, - 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x45, 0x6e, 0x63, 0x72, 0x79, - 0x70, 0x74, 0x44, 0x45, 0x4b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x17, 0x0a, - 0x15, 0x52, 0x65, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x44, 0x45, 0x4b, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x89, 0x04, 0x0a, 0x0c, 0x56, 0x61, 0x75, 0x6c, 0x74, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x08, 0x4c, 0x69, 0x76, 0x65, 0x6e, - 0x65, 0x73, 0x73, 0x12, 0x19, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x69, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, - 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x76, 0x65, 0x6e, 0x65, - 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x09, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x45, 0x4b, 0x12, 0x1a, 0x2e, 0x76, 0x61, 0x75, 0x6c, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x45, 0x4b, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x45, 0x4b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x07, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x12, - 0x18, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, - 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x76, 0x61, 0x75, 0x6c, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x0b, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, - 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x12, 0x1c, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, - 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x07, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x12, - 0x18, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x63, 0x72, 0x79, - 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x76, 0x61, 0x75, 0x6c, - 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x09, 0x52, 0x65, 0x45, 0x6e, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x12, 0x1a, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x65, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1b, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x45, 0x6e, 0x63, - 0x72, 0x79, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, - 0x0a, 0x0d, 0x52, 0x65, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x44, 0x45, 0x4b, 0x73, 0x12, - 0x1e, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x45, 0x6e, 0x63, - 0x72, 0x79, 0x70, 0x74, 0x44, 0x45, 0x4b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1f, 0x2e, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x45, 0x6e, 0x63, - 0x72, 0x79, 0x70, 0x74, 0x44, 0x45, 0x4b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x75, 0x6e, 0x6b, 0x65, 0x79, 0x65, 0x64, 0x2f, 0x75, 0x6e, 0x6b, 0x65, 0x79, 0x2f, 0x61, - 0x70, 0x70, 0x73, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x61, 0x75, - 0x6c, 0x74, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_vault_v1_service_proto_rawDescOnce sync.Once - file_proto_vault_v1_service_proto_rawDescData = file_proto_vault_v1_service_proto_rawDesc -) - -func file_proto_vault_v1_service_proto_rawDescGZIP() []byte { - file_proto_vault_v1_service_proto_rawDescOnce.Do(func() { - file_proto_vault_v1_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_vault_v1_service_proto_rawDescData) - }) - return file_proto_vault_v1_service_proto_rawDescData -} - -var file_proto_vault_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 14) -var file_proto_vault_v1_service_proto_goTypes = []any{ - (*LivenessRequest)(nil), // 0: vault.v1.LivenessRequest - (*LivenessResponse)(nil), // 1: vault.v1.LivenessResponse - (*EncryptRequest)(nil), // 2: vault.v1.EncryptRequest - (*EncryptResponse)(nil), // 3: vault.v1.EncryptResponse - (*EncryptBulkRequest)(nil), // 4: vault.v1.EncryptBulkRequest - (*EncryptBulkResponse)(nil), // 5: vault.v1.EncryptBulkResponse - (*DecryptRequest)(nil), // 6: vault.v1.DecryptRequest - (*DecryptResponse)(nil), // 7: vault.v1.DecryptResponse - (*CreateDEKRequest)(nil), // 8: vault.v1.CreateDEKRequest - (*CreateDEKResponse)(nil), // 9: vault.v1.CreateDEKResponse - (*ReEncryptRequest)(nil), // 10: vault.v1.ReEncryptRequest - (*ReEncryptResponse)(nil), // 11: vault.v1.ReEncryptResponse - (*ReEncryptDEKsRequest)(nil), // 12: vault.v1.ReEncryptDEKsRequest - (*ReEncryptDEKsResponse)(nil), // 13: vault.v1.ReEncryptDEKsResponse -} -var file_proto_vault_v1_service_proto_depIdxs = []int32{ - 3, // 0: vault.v1.EncryptBulkResponse.encrypted:type_name -> vault.v1.EncryptResponse - 0, // 1: vault.v1.VaultService.Liveness:input_type -> vault.v1.LivenessRequest - 8, // 2: vault.v1.VaultService.CreateDEK:input_type -> vault.v1.CreateDEKRequest - 2, // 3: vault.v1.VaultService.Encrypt:input_type -> vault.v1.EncryptRequest - 4, // 4: vault.v1.VaultService.EncryptBulk:input_type -> vault.v1.EncryptBulkRequest - 6, // 5: vault.v1.VaultService.Decrypt:input_type -> vault.v1.DecryptRequest - 10, // 6: vault.v1.VaultService.ReEncrypt:input_type -> vault.v1.ReEncryptRequest - 12, // 7: vault.v1.VaultService.ReEncryptDEKs:input_type -> vault.v1.ReEncryptDEKsRequest - 1, // 8: vault.v1.VaultService.Liveness:output_type -> vault.v1.LivenessResponse - 9, // 9: vault.v1.VaultService.CreateDEK:output_type -> vault.v1.CreateDEKResponse - 3, // 10: vault.v1.VaultService.Encrypt:output_type -> vault.v1.EncryptResponse - 5, // 11: vault.v1.VaultService.EncryptBulk:output_type -> vault.v1.EncryptBulkResponse - 7, // 12: vault.v1.VaultService.Decrypt:output_type -> vault.v1.DecryptResponse - 11, // 13: vault.v1.VaultService.ReEncrypt:output_type -> vault.v1.ReEncryptResponse - 13, // 14: vault.v1.VaultService.ReEncryptDEKs:output_type -> vault.v1.ReEncryptDEKsResponse - 8, // [8:15] is the sub-list for method output_type - 1, // [1:8] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_proto_vault_v1_service_proto_init() } -func file_proto_vault_v1_service_proto_init() { - if File_proto_vault_v1_service_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_vault_v1_service_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*LivenessRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_service_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*LivenessResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_service_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*EncryptRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_service_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*EncryptResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_service_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*EncryptBulkRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_service_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*EncryptBulkResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_service_proto_msgTypes[6].Exporter = func(v any, i int) any { - switch v := v.(*DecryptRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_service_proto_msgTypes[7].Exporter = func(v any, i int) any { - switch v := v.(*DecryptResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_service_proto_msgTypes[8].Exporter = func(v any, i int) any { - switch v := v.(*CreateDEKRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_service_proto_msgTypes[9].Exporter = func(v any, i int) any { - switch v := v.(*CreateDEKResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_service_proto_msgTypes[10].Exporter = func(v any, i int) any { - switch v := v.(*ReEncryptRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_service_proto_msgTypes[11].Exporter = func(v any, i int) any { - switch v := v.(*ReEncryptResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_service_proto_msgTypes[12].Exporter = func(v any, i int) any { - switch v := v.(*ReEncryptDEKsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_vault_v1_service_proto_msgTypes[13].Exporter = func(v any, i int) any { - switch v := v.(*ReEncryptDEKsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_proto_vault_v1_service_proto_msgTypes[10].OneofWrappers = []any{} - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_vault_v1_service_proto_rawDesc, - NumEnums: 0, - NumMessages: 14, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_vault_v1_service_proto_goTypes, - DependencyIndexes: file_proto_vault_v1_service_proto_depIdxs, - MessageInfos: file_proto_vault_v1_service_proto_msgTypes, - }.Build() - File_proto_vault_v1_service_proto = out.File - file_proto_vault_v1_service_proto_rawDesc = nil - file_proto_vault_v1_service_proto_goTypes = nil - file_proto_vault_v1_service_proto_depIdxs = nil -} diff --git a/web/apps/agent/gen/proto/vault/v1/vaultv1connect/service.connect.go b/web/apps/agent/gen/proto/vault/v1/vaultv1connect/service.connect.go deleted file mode 100644 index 633d9e5165..0000000000 --- a/web/apps/agent/gen/proto/vault/v1/vaultv1connect/service.connect.go +++ /dev/null @@ -1,290 +0,0 @@ -// Code generated by protoc-gen-connect-go. DO NOT EDIT. -// -// Source: proto/vault/v1/service.proto - -package vaultv1connect - -import ( - connect "connectrpc.com/connect" - context "context" - errors "errors" - v1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - http "net/http" - strings "strings" -) - -// This is a compile-time assertion to ensure that this generated file and the connect package are -// compatible. If you get a compiler error that this constant is not defined, this code was -// generated with a version of connect newer than the one compiled into your binary. You can fix the -// problem by either regenerating this code with an older version of connect or updating the connect -// version compiled into your binary. -const _ = connect.IsAtLeastVersion1_13_0 - -const ( - // VaultServiceName is the fully-qualified name of the VaultService service. - VaultServiceName = "vault.v1.VaultService" -) - -// These constants are the fully-qualified names of the RPCs defined in this package. They're -// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. -// -// Note that these are different from the fully-qualified method names used by -// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to -// reflection-formatted method names, remove the leading slash and convert the remaining slash to a -// period. -const ( - // VaultServiceLivenessProcedure is the fully-qualified name of the VaultService's Liveness RPC. - VaultServiceLivenessProcedure = "/vault.v1.VaultService/Liveness" - // VaultServiceCreateDEKProcedure is the fully-qualified name of the VaultService's CreateDEK RPC. - VaultServiceCreateDEKProcedure = "/vault.v1.VaultService/CreateDEK" - // VaultServiceEncryptProcedure is the fully-qualified name of the VaultService's Encrypt RPC. - VaultServiceEncryptProcedure = "/vault.v1.VaultService/Encrypt" - // VaultServiceEncryptBulkProcedure is the fully-qualified name of the VaultService's EncryptBulk - // RPC. - VaultServiceEncryptBulkProcedure = "/vault.v1.VaultService/EncryptBulk" - // VaultServiceDecryptProcedure is the fully-qualified name of the VaultService's Decrypt RPC. - VaultServiceDecryptProcedure = "/vault.v1.VaultService/Decrypt" - // VaultServiceReEncryptProcedure is the fully-qualified name of the VaultService's ReEncrypt RPC. - VaultServiceReEncryptProcedure = "/vault.v1.VaultService/ReEncrypt" - // VaultServiceReEncryptDEKsProcedure is the fully-qualified name of the VaultService's - // ReEncryptDEKs RPC. - VaultServiceReEncryptDEKsProcedure = "/vault.v1.VaultService/ReEncryptDEKs" -) - -// These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. -var ( - vaultServiceServiceDescriptor = v1.File_proto_vault_v1_service_proto.Services().ByName("VaultService") - vaultServiceLivenessMethodDescriptor = vaultServiceServiceDescriptor.Methods().ByName("Liveness") - vaultServiceCreateDEKMethodDescriptor = vaultServiceServiceDescriptor.Methods().ByName("CreateDEK") - vaultServiceEncryptMethodDescriptor = vaultServiceServiceDescriptor.Methods().ByName("Encrypt") - vaultServiceEncryptBulkMethodDescriptor = vaultServiceServiceDescriptor.Methods().ByName("EncryptBulk") - vaultServiceDecryptMethodDescriptor = vaultServiceServiceDescriptor.Methods().ByName("Decrypt") - vaultServiceReEncryptMethodDescriptor = vaultServiceServiceDescriptor.Methods().ByName("ReEncrypt") - vaultServiceReEncryptDEKsMethodDescriptor = vaultServiceServiceDescriptor.Methods().ByName("ReEncryptDEKs") -) - -// VaultServiceClient is a client for the vault.v1.VaultService service. -type VaultServiceClient interface { - Liveness(context.Context, *connect.Request[v1.LivenessRequest]) (*connect.Response[v1.LivenessResponse], error) - CreateDEK(context.Context, *connect.Request[v1.CreateDEKRequest]) (*connect.Response[v1.CreateDEKResponse], error) - Encrypt(context.Context, *connect.Request[v1.EncryptRequest]) (*connect.Response[v1.EncryptResponse], error) - EncryptBulk(context.Context, *connect.Request[v1.EncryptBulkRequest]) (*connect.Response[v1.EncryptBulkResponse], error) - Decrypt(context.Context, *connect.Request[v1.DecryptRequest]) (*connect.Response[v1.DecryptResponse], error) - // ReEncrypt rec - ReEncrypt(context.Context, *connect.Request[v1.ReEncryptRequest]) (*connect.Response[v1.ReEncryptResponse], error) - ReEncryptDEKs(context.Context, *connect.Request[v1.ReEncryptDEKsRequest]) (*connect.Response[v1.ReEncryptDEKsResponse], error) -} - -// NewVaultServiceClient constructs a client for the vault.v1.VaultService service. By default, it -// uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends -// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or -// connect.WithGRPCWeb() options. -// -// The URL supplied here should be the base URL for the Connect or gRPC server (for example, -// http://api.acme.com or https://acme.com/grpc). -func NewVaultServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) VaultServiceClient { - baseURL = strings.TrimRight(baseURL, "/") - return &vaultServiceClient{ - liveness: connect.NewClient[v1.LivenessRequest, v1.LivenessResponse]( - httpClient, - baseURL+VaultServiceLivenessProcedure, - connect.WithSchema(vaultServiceLivenessMethodDescriptor), - connect.WithClientOptions(opts...), - ), - createDEK: connect.NewClient[v1.CreateDEKRequest, v1.CreateDEKResponse]( - httpClient, - baseURL+VaultServiceCreateDEKProcedure, - connect.WithSchema(vaultServiceCreateDEKMethodDescriptor), - connect.WithClientOptions(opts...), - ), - encrypt: connect.NewClient[v1.EncryptRequest, v1.EncryptResponse]( - httpClient, - baseURL+VaultServiceEncryptProcedure, - connect.WithSchema(vaultServiceEncryptMethodDescriptor), - connect.WithClientOptions(opts...), - ), - encryptBulk: connect.NewClient[v1.EncryptBulkRequest, v1.EncryptBulkResponse]( - httpClient, - baseURL+VaultServiceEncryptBulkProcedure, - connect.WithSchema(vaultServiceEncryptBulkMethodDescriptor), - connect.WithClientOptions(opts...), - ), - decrypt: connect.NewClient[v1.DecryptRequest, v1.DecryptResponse]( - httpClient, - baseURL+VaultServiceDecryptProcedure, - connect.WithSchema(vaultServiceDecryptMethodDescriptor), - connect.WithClientOptions(opts...), - ), - reEncrypt: connect.NewClient[v1.ReEncryptRequest, v1.ReEncryptResponse]( - httpClient, - baseURL+VaultServiceReEncryptProcedure, - connect.WithSchema(vaultServiceReEncryptMethodDescriptor), - connect.WithClientOptions(opts...), - ), - reEncryptDEKs: connect.NewClient[v1.ReEncryptDEKsRequest, v1.ReEncryptDEKsResponse]( - httpClient, - baseURL+VaultServiceReEncryptDEKsProcedure, - connect.WithSchema(vaultServiceReEncryptDEKsMethodDescriptor), - connect.WithClientOptions(opts...), - ), - } -} - -// vaultServiceClient implements VaultServiceClient. -type vaultServiceClient struct { - liveness *connect.Client[v1.LivenessRequest, v1.LivenessResponse] - createDEK *connect.Client[v1.CreateDEKRequest, v1.CreateDEKResponse] - encrypt *connect.Client[v1.EncryptRequest, v1.EncryptResponse] - encryptBulk *connect.Client[v1.EncryptBulkRequest, v1.EncryptBulkResponse] - decrypt *connect.Client[v1.DecryptRequest, v1.DecryptResponse] - reEncrypt *connect.Client[v1.ReEncryptRequest, v1.ReEncryptResponse] - reEncryptDEKs *connect.Client[v1.ReEncryptDEKsRequest, v1.ReEncryptDEKsResponse] -} - -// Liveness calls vault.v1.VaultService.Liveness. -func (c *vaultServiceClient) Liveness(ctx context.Context, req *connect.Request[v1.LivenessRequest]) (*connect.Response[v1.LivenessResponse], error) { - return c.liveness.CallUnary(ctx, req) -} - -// CreateDEK calls vault.v1.VaultService.CreateDEK. -func (c *vaultServiceClient) CreateDEK(ctx context.Context, req *connect.Request[v1.CreateDEKRequest]) (*connect.Response[v1.CreateDEKResponse], error) { - return c.createDEK.CallUnary(ctx, req) -} - -// Encrypt calls vault.v1.VaultService.Encrypt. -func (c *vaultServiceClient) Encrypt(ctx context.Context, req *connect.Request[v1.EncryptRequest]) (*connect.Response[v1.EncryptResponse], error) { - return c.encrypt.CallUnary(ctx, req) -} - -// EncryptBulk calls vault.v1.VaultService.EncryptBulk. -func (c *vaultServiceClient) EncryptBulk(ctx context.Context, req *connect.Request[v1.EncryptBulkRequest]) (*connect.Response[v1.EncryptBulkResponse], error) { - return c.encryptBulk.CallUnary(ctx, req) -} - -// Decrypt calls vault.v1.VaultService.Decrypt. -func (c *vaultServiceClient) Decrypt(ctx context.Context, req *connect.Request[v1.DecryptRequest]) (*connect.Response[v1.DecryptResponse], error) { - return c.decrypt.CallUnary(ctx, req) -} - -// ReEncrypt calls vault.v1.VaultService.ReEncrypt. -func (c *vaultServiceClient) ReEncrypt(ctx context.Context, req *connect.Request[v1.ReEncryptRequest]) (*connect.Response[v1.ReEncryptResponse], error) { - return c.reEncrypt.CallUnary(ctx, req) -} - -// ReEncryptDEKs calls vault.v1.VaultService.ReEncryptDEKs. -func (c *vaultServiceClient) ReEncryptDEKs(ctx context.Context, req *connect.Request[v1.ReEncryptDEKsRequest]) (*connect.Response[v1.ReEncryptDEKsResponse], error) { - return c.reEncryptDEKs.CallUnary(ctx, req) -} - -// VaultServiceHandler is an implementation of the vault.v1.VaultService service. -type VaultServiceHandler interface { - Liveness(context.Context, *connect.Request[v1.LivenessRequest]) (*connect.Response[v1.LivenessResponse], error) - CreateDEK(context.Context, *connect.Request[v1.CreateDEKRequest]) (*connect.Response[v1.CreateDEKResponse], error) - Encrypt(context.Context, *connect.Request[v1.EncryptRequest]) (*connect.Response[v1.EncryptResponse], error) - EncryptBulk(context.Context, *connect.Request[v1.EncryptBulkRequest]) (*connect.Response[v1.EncryptBulkResponse], error) - Decrypt(context.Context, *connect.Request[v1.DecryptRequest]) (*connect.Response[v1.DecryptResponse], error) - // ReEncrypt rec - ReEncrypt(context.Context, *connect.Request[v1.ReEncryptRequest]) (*connect.Response[v1.ReEncryptResponse], error) - ReEncryptDEKs(context.Context, *connect.Request[v1.ReEncryptDEKsRequest]) (*connect.Response[v1.ReEncryptDEKsResponse], error) -} - -// NewVaultServiceHandler builds an HTTP handler from the service implementation. It returns the -// path on which to mount the handler and the handler itself. -// -// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf -// and JSON codecs. They also support gzip compression. -func NewVaultServiceHandler(svc VaultServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { - vaultServiceLivenessHandler := connect.NewUnaryHandler( - VaultServiceLivenessProcedure, - svc.Liveness, - connect.WithSchema(vaultServiceLivenessMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - vaultServiceCreateDEKHandler := connect.NewUnaryHandler( - VaultServiceCreateDEKProcedure, - svc.CreateDEK, - connect.WithSchema(vaultServiceCreateDEKMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - vaultServiceEncryptHandler := connect.NewUnaryHandler( - VaultServiceEncryptProcedure, - svc.Encrypt, - connect.WithSchema(vaultServiceEncryptMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - vaultServiceEncryptBulkHandler := connect.NewUnaryHandler( - VaultServiceEncryptBulkProcedure, - svc.EncryptBulk, - connect.WithSchema(vaultServiceEncryptBulkMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - vaultServiceDecryptHandler := connect.NewUnaryHandler( - VaultServiceDecryptProcedure, - svc.Decrypt, - connect.WithSchema(vaultServiceDecryptMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - vaultServiceReEncryptHandler := connect.NewUnaryHandler( - VaultServiceReEncryptProcedure, - svc.ReEncrypt, - connect.WithSchema(vaultServiceReEncryptMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - vaultServiceReEncryptDEKsHandler := connect.NewUnaryHandler( - VaultServiceReEncryptDEKsProcedure, - svc.ReEncryptDEKs, - connect.WithSchema(vaultServiceReEncryptDEKsMethodDescriptor), - connect.WithHandlerOptions(opts...), - ) - return "/vault.v1.VaultService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - switch r.URL.Path { - case VaultServiceLivenessProcedure: - vaultServiceLivenessHandler.ServeHTTP(w, r) - case VaultServiceCreateDEKProcedure: - vaultServiceCreateDEKHandler.ServeHTTP(w, r) - case VaultServiceEncryptProcedure: - vaultServiceEncryptHandler.ServeHTTP(w, r) - case VaultServiceEncryptBulkProcedure: - vaultServiceEncryptBulkHandler.ServeHTTP(w, r) - case VaultServiceDecryptProcedure: - vaultServiceDecryptHandler.ServeHTTP(w, r) - case VaultServiceReEncryptProcedure: - vaultServiceReEncryptHandler.ServeHTTP(w, r) - case VaultServiceReEncryptDEKsProcedure: - vaultServiceReEncryptDEKsHandler.ServeHTTP(w, r) - default: - http.NotFound(w, r) - } - }) -} - -// UnimplementedVaultServiceHandler returns CodeUnimplemented from all methods. -type UnimplementedVaultServiceHandler struct{} - -func (UnimplementedVaultServiceHandler) Liveness(context.Context, *connect.Request[v1.LivenessRequest]) (*connect.Response[v1.LivenessResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("vault.v1.VaultService.Liveness is not implemented")) -} - -func (UnimplementedVaultServiceHandler) CreateDEK(context.Context, *connect.Request[v1.CreateDEKRequest]) (*connect.Response[v1.CreateDEKResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("vault.v1.VaultService.CreateDEK is not implemented")) -} - -func (UnimplementedVaultServiceHandler) Encrypt(context.Context, *connect.Request[v1.EncryptRequest]) (*connect.Response[v1.EncryptResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("vault.v1.VaultService.Encrypt is not implemented")) -} - -func (UnimplementedVaultServiceHandler) EncryptBulk(context.Context, *connect.Request[v1.EncryptBulkRequest]) (*connect.Response[v1.EncryptBulkResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("vault.v1.VaultService.EncryptBulk is not implemented")) -} - -func (UnimplementedVaultServiceHandler) Decrypt(context.Context, *connect.Request[v1.DecryptRequest]) (*connect.Response[v1.DecryptResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("vault.v1.VaultService.Decrypt is not implemented")) -} - -func (UnimplementedVaultServiceHandler) ReEncrypt(context.Context, *connect.Request[v1.ReEncryptRequest]) (*connect.Response[v1.ReEncryptResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("vault.v1.VaultService.ReEncrypt is not implemented")) -} - -func (UnimplementedVaultServiceHandler) ReEncryptDEKs(context.Context, *connect.Request[v1.ReEncryptDEKsRequest]) (*connect.Response[v1.ReEncryptDEKsResponse], error) { - return nil, connect.NewError(connect.CodeUnimplemented, errors.New("vault.v1.VaultService.ReEncryptDEKs is not implemented")) -} diff --git a/web/apps/agent/go.mod b/web/apps/agent/go.mod deleted file mode 100644 index d945006018..0000000000 --- a/web/apps/agent/go.mod +++ /dev/null @@ -1,276 +0,0 @@ -module github.com/unkeyed/unkey/svc/agent - -go 1.23.0 - -toolchain go1.23.6 - -require ( - connectrpc.com/connect v1.18.1 - connectrpc.com/otelconnect v0.7.1 - github.com/ClickHouse/clickhouse-go/v2 v2.32.0 - github.com/Southclaws/fault v0.8.1 - github.com/aws/aws-sdk-go-v2 v1.36.1 - github.com/aws/aws-sdk-go-v2/config v1.29.6 - github.com/aws/aws-sdk-go-v2/credentials v1.17.59 - github.com/aws/aws-sdk-go-v2/service/s3 v1.76.1 - github.com/axiomhq/axiom-go v0.22.0 - github.com/btcsuite/btcutil v1.0.2 - github.com/danielgtaylor/huma v1.14.3 - github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b - github.com/google/uuid v1.6.0 - github.com/grafana/pyroscope-go v1.2.0 - github.com/hashicorp/serf v0.10.2 - github.com/maypok86/otter v1.2.4 - github.com/pb33f/libopenapi v0.21.2 - github.com/pb33f/libopenapi-validator v0.3.0 - github.com/prometheus/client_golang v1.20.5 - github.com/redis/go-redis/v9 v9.6.3 - github.com/rs/zerolog v1.33.0 - github.com/segmentio/ksuid v1.0.4 - github.com/spf13/cobra v1.8.1 - github.com/stretchr/testify v1.10.0 - github.com/testcontainers/testcontainers-go v0.33.0 - github.com/testcontainers/testcontainers-go/modules/compose v0.33.0 - github.com/tsenart/vegeta/v12 v12.12.0 - github.com/unkeyed/unkey-go v0.8.8 - github.com/urfave/cli/v2 v2.27.5 - github.com/xeipuuv/gojsonschema v1.2.0 - go.opentelemetry.io/otel v1.34.0 - go.opentelemetry.io/otel/trace v1.34.0 - golang.org/x/net v0.38.0 - google.golang.org/protobuf v1.36.5 -) - -require ( - dario.cat/mergo v1.0.1 // indirect - github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect - github.com/AlecAivazis/survey/v2 v2.3.7 // indirect - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/ClickHouse/ch-go v0.65.0 // indirect - github.com/Masterminds/semver/v3 v3.3.0 // indirect - github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/Microsoft/hcsshim v0.12.6 // indirect - github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect - github.com/andybalholm/brotli v1.1.1 // indirect - github.com/armon/go-metrics v0.4.1 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.8 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.28 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.32 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.32 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.32 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.6.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.13 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.13 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.24.15 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.14 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.14 // indirect - github.com/aws/smithy-go v1.22.2 // indirect - github.com/bahlo/generic-list-go v0.2.0 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/buger/goterm v1.0.4 // indirect - github.com/buger/jsonparser v1.1.1 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/compose-spec/compose-go/v2 v2.1.6 // indirect - github.com/containerd/console v1.0.4 // indirect - github.com/containerd/containerd v1.7.21 // indirect - github.com/containerd/containerd/api v1.7.19 // indirect - github.com/containerd/continuity v0.4.3 // indirect - github.com/containerd/errdefs v0.1.0 // indirect - github.com/containerd/log v0.1.0 // indirect - github.com/containerd/platforms v0.2.1 // indirect - github.com/containerd/ttrpc v1.2.5 // indirect - github.com/containerd/typeurl/v2 v2.2.0 // indirect - github.com/cpuguy83/dockercfg v0.3.1 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/distribution/reference v0.6.0 // indirect - github.com/docker/buildx v0.16.2 // indirect - github.com/docker/cli v27.2.0+incompatible // indirect - github.com/docker/cli-docs-tool v0.8.0 // indirect - github.com/docker/compose/v2 v2.29.2 // indirect - github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker v27.5.1+incompatible // indirect - github.com/docker/docker-credential-helpers v0.8.2 // indirect - github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect - github.com/docker/go-connections v0.5.0 // indirect - github.com/docker/go-metrics v0.0.1 // indirect - github.com/docker/go-units v0.5.0 // indirect - github.com/dolthub/maphash v0.1.0 // indirect - github.com/dprotaso/go-yit v0.0.0-20240618133044-5a0af90af097 // indirect - github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203 // indirect - github.com/emicklei/go-restful/v3 v3.12.1 // indirect - github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsevents v0.2.0 // indirect - github.com/fvbommel/sortorder v1.1.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/gammazero/deque v1.0.0 // indirect - github.com/go-faster/city v1.0.1 // indirect - github.com/go-faster/errors v0.7.1 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/go-sql-driver/mysql v1.4.0 // indirect - github.com/go-viper/mapstructure/v2 v2.3.0 // indirect - github.com/gofrs/flock v0.12.1 // indirect - github.com/gogo/googleapis v1.4.1 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac // indirect - github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82 // indirect - github.com/gonum/integrate v0.0.0-20181209220457-a422b5c0fdf2 // indirect - github.com/gonum/internal v0.0.0-20181124074243-f884aa714029 // indirect - github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9 // indirect - github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9 // indirect - github.com/google/btree v1.1.3 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/google/go-querystring v1.1.0 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/websocket v1.5.3 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-metrics v0.5.4 // indirect - github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-sockaddr v1.0.7 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect - github.com/hashicorp/golang-lru v1.0.2 // indirect - github.com/hashicorp/memberlist v0.5.3 // indirect - github.com/imdario/mergo v0.3.16 // indirect - github.com/in-toto/in-toto-golang v0.9.0 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/influxdata/tdigest v0.0.1 // indirect - github.com/jonboulle/clockwork v0.4.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/klauspost/compress v1.17.11 // indirect - github.com/lufia/plan9stats v0.0.0-20240819163618-b1d8f4d146e7 // indirect - github.com/magiconair/properties v1.8.7 // indirect - github.com/mailru/easyjson v0.9.0 // indirect - github.com/mattn/go-colorable v0.1.14 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect - github.com/mattn/go-shellwords v1.0.12 // indirect - github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect - github.com/miekg/dns v1.1.63 // indirect - github.com/miekg/pkcs11 v1.1.1 // indirect - github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moby/buildkit v0.15.2 // indirect - github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/locker v1.0.1 // indirect - github.com/moby/patternmatcher v0.6.0 // indirect - github.com/moby/spdystream v0.5.0 // indirect - github.com/moby/sys/mountinfo v0.7.2 // indirect - github.com/moby/sys/sequential v0.6.0 // indirect - github.com/moby/sys/signal v0.7.1 // indirect - github.com/moby/sys/symlink v0.3.0 // indirect - github.com/moby/sys/user v0.3.0 // indirect - github.com/moby/sys/userns v0.1.0 // indirect - github.com/moby/term v0.5.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/morikuni/aec v1.0.0 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0 // indirect - github.com/paulmach/orb v0.11.1 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pierrec/lz4/v4 v4.1.22 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.62.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect - github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc // indirect - github.com/rivo/uniseg v0.4.7 // indirect - github.com/rs/dnscache v0.0.0-20230804202142-fc85eb664529 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 // indirect - github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect - github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect - github.com/segmentio/asm v1.2.0 // indirect - github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b // indirect - github.com/shibumi/go-pathspec v1.3.0 // indirect - github.com/shirou/gopsutil/v3 v3.24.5 // indirect - github.com/shoenig/go-m1cpu v0.1.6 // indirect - github.com/shopspring/decimal v1.4.0 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect - github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect - github.com/speakeasy-api/jsonpath v0.6.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/spyzhov/ajson v0.8.0 // indirect - github.com/theupdateframework/notary v0.7.0 // indirect - github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375 // indirect - github.com/tklauser/go-sysconf v0.3.14 // indirect - github.com/tklauser/numcpus v0.8.0 // indirect - github.com/tonistiigi/fsutil v0.0.0-20240820162337-c117dd14469d // indirect - github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0 // indirect - github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect - github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab // indirect - github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect - github.com/wk8/go-ordered-map/v2 v2.1.9-0.20240815153524-6ea36470d1bd // indirect - github.com/x448/float16 v0.8.4 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect - github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.54.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.29.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect - go.opentelemetry.io/otel/metric v1.34.0 // indirect - go.opentelemetry.io/otel/sdk v1.34.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.32.0 // indirect - go.opentelemetry.io/proto/otlp v1.5.0 // indirect - go.uber.org/mock v0.4.0 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac // indirect - golang.org/x/mod v0.23.0 // indirect - golang.org/x/oauth2 v0.26.0 // indirect - golang.org/x/sync v0.12.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/term v0.30.0 // indirect - golang.org/x/text v0.23.0 // indirect - golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.30.0 // indirect - google.golang.org/genproto v0.0.0-20240827150818-7e3bb234dfed // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250207221924-e9438ea467c6 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 // indirect - google.golang.org/grpc v1.70.0 // indirect - gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.31.0 // indirect - k8s.io/apimachinery v0.31.0 // indirect - k8s.io/client-go v0.31.0 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 // indirect - k8s.io/utils v0.0.0-20240821151609-f90d01438635 // 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 - tags.cncf.io/container-device-interface v0.8.0 // indirect -) diff --git a/web/apps/agent/go.sum b/web/apps/agent/go.sum deleted file mode 100644 index cf5f3ec189..0000000000 --- a/web/apps/agent/go.sum +++ /dev/null @@ -1,1625 +0,0 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -connectrpc.com/connect v1.18.1 h1:PAg7CjSAGvscaf6YZKUefjoih5Z/qYkyaTrBW8xvYPw= -connectrpc.com/connect v1.18.1/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8= -connectrpc.com/otelconnect v0.7.1 h1:scO5pOb0i4yUE66CnNrHeK1x51yq0bE0ehPg6WvzXJY= -connectrpc.com/otelconnect v0.7.1/go.mod h1:dh3bFgHBTb2bkqGCeVVOtHJreSns7uu9wwL2Tbz17ms= -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= -github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 h1:59MxjQVfjXsBpLy+dbd2/ELV5ofnUkUZBvWSC85sheA= -github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU= -github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= -github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ClickHouse/ch-go v0.65.0 h1:vZAXfTQliuNNefqkPDewX3kgRxN6Q4vUENnnY+ynTRY= -github.com/ClickHouse/ch-go v0.65.0/go.mod h1:tCM0XEH5oWngoi9Iu/8+tjPBo04I/FxNIffpdjtwx3k= -github.com/ClickHouse/clickhouse-go/v2 v2.32.0 h1:zVWJUmUGdtCApM/vRfQhruGXIm1M643bk68B3IYbR1I= -github.com/ClickHouse/clickhouse-go/v2 v2.32.0/go.mod h1:rGFIgeNbJVggBp2C+0FXOdfjsMlpsKx7FUYnHHyy2KE= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/Jeffail/gabs/v2 v2.6.1/go.mod h1:xCn81vdHKxFUuWWAaD5jCTQDNPBMh5pPs9IJ+NcziBI= -github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= -github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/hcsshim v0.12.6 h1:qEnZjoHXv+4/s0LmKZWE0/AiZmMWEIkFfWBSf1a0wlU= -github.com/Microsoft/hcsshim v0.12.6/go.mod h1:ZABCLVcvLMjIkzr9rUGcQ1QA0p0P3Ps+d3N1g2DsFfk= -github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= -github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= -github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= -github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= -github.com/Southclaws/fault v0.8.1 h1:mgqqdC6kUBQ6ExMALZ0nNaDfNJD5h2+wq3se5mAyX+8= -github.com/Southclaws/fault v0.8.1/go.mod h1:VUVkAWutC59SL16s6FTqf3I6I2z77RmnaW5XRz4bLOE= -github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= -github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= -github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc= -github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA= -github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= -github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= -github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aws/aws-sdk-go-v2 v1.36.1 h1:iTDl5U6oAhkNPba0e1t1hrwAo02ZMqbrGq4k5JBWM5E= -github.com/aws/aws-sdk-go-v2 v1.36.1/go.mod h1:5PMILGVKiW32oDzjj6RU52yrNrDPUHcbZQYr1sM7qmM= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.8 h1:zAxi9p3wsZMIaVCdoiQp2uZ9k1LsZvmAnoTBeZPXom0= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.8/go.mod h1:3XkePX5dSaxveLAYY7nsbsZZrKxCyEuE5pM4ziFxyGg= -github.com/aws/aws-sdk-go-v2/config v1.29.6 h1:fqgqEKK5HaZVWLQoLiC9Q+xDlSp+1LYidp6ybGE2OGg= -github.com/aws/aws-sdk-go-v2/config v1.29.6/go.mod h1:Ft+WLODzDQmCTHDvqAH1JfC2xxbZ0MxpZAcJqmE1LTQ= -github.com/aws/aws-sdk-go-v2/credentials v1.17.59 h1:9btwmrt//Q6JcSdgJOLI98sdr5p7tssS9yAsGe8aKP4= -github.com/aws/aws-sdk-go-v2/credentials v1.17.59/go.mod h1:NM8fM6ovI3zak23UISdWidyZuI1ghNe2xjzUZAyT+08= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.28 h1:KwsodFKVQTlI5EyhRSugALzsV6mG/SGrdjlMXSZSdso= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.28/go.mod h1:EY3APf9MzygVhKuPXAc5H+MkGb8k/DOSQjWS0LgkKqI= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.32 h1:BjUcr3X3K0wZPGFg2bxOWW3VPN8rkE3/61zhP+IHviA= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.32/go.mod h1:80+OGC/bgzzFFTUmcuwD0lb4YutwQeKLFpmt6hoWapU= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.32 h1:m1GeXHVMJsRsUAqG6HjZWx9dj7F5TR+cF1bjyfYyBd4= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.32/go.mod h1:IitoQxGfaKdVLNg0hD8/DXmAqNy0H4K2H2Sf91ti8sI= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 h1:Pg9URiobXy85kgFev3og2CuOZ8JZUBENF+dcgWBaYNk= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.32 h1:OIHj/nAhVzIXGzbAE+4XmZ8FPvro3THr6NlqErJc3wY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.32/go.mod h1:LiBEsDo34OJXqdDlRGsilhlIiXR7DL+6Cx2f4p1EgzI= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 h1:D4oz8/CzT9bAEYtVhSBmFj2dNOtaHOtMKc2vHBwYizA= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2/go.mod h1:Za3IHqTQ+yNcRHxu1OFucBh0ACZT4j4VQFF0BqpZcLY= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.6.0 h1:kT2WeWcFySdYpPgyqJMSUE7781Qucjtn6wBvrgm9P+M= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.6.0/go.mod h1:WYH1ABybY7JK9TITPnk6ZlP7gQB8psI4c9qDmMsnLSA= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.13 h1:SYVGSFQHlchIcy6e7x12bsrxClCXSP5et8cqVhL8cuw= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.13/go.mod h1:kizuDaLX37bG5WZaoxGPQR/LNFXpxp0vsUnqfkWXfNE= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.13 h1:OBsrtam3rk8NfBEq7OLOMm5HtQ9Yyw32X4UQMya/wjw= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.13/go.mod h1:3U4gFA5pmoCOja7aq4nSaIAGbaOHv2Yl2ug018cmC+Q= -github.com/aws/aws-sdk-go-v2/service/s3 v1.76.1 h1:d4ZG8mELlLeUWFBMCqPtRfEP3J6aQgg/KTC9jLSlkMs= -github.com/aws/aws-sdk-go-v2/service/s3 v1.76.1/go.mod h1:uZoEIR6PzGOZEjgAZE4hfYfsqK2zOHhq68JLKEvvXj4= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.15 h1:/eE3DogBjYlvlbhd2ssWyeuovWunHLxfgw3s/OJa4GQ= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.15/go.mod h1:2PCJYpi7EKeA5SkStAmZlF6fi0uUABuhtF8ILHjGc3Y= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.14 h1:M/zwXiL2iXUrHputuXgmO94TVNmcenPHxgLXLutodKE= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.14/go.mod h1:RVwIw3y/IqxC2YEXSIkAzRDdEU1iRabDPaYjpGCbCGQ= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.14 h1:TzeR06UCMUq+KA3bDkujxK1GVGy+G8qQN/QVYzGLkQE= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.14/go.mod h1:dspXf/oYWGWo6DEvj98wpaTeqt5+DMidZD0A9BYTizc= -github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ= -github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= -github.com/axiomhq/axiom-go v0.22.0 h1:QFC09ugLrwc8DNaq8QgF4Q2R/B2V5xYTjZzvUfe72s8= -github.com/axiomhq/axiom-go v0.22.0/go.mod h1:ybDThTO73XgRNQjTRxXqUiZh3QM7Wf5/exaFbp9VgLY= -github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= -github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw= -github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/bmizerany/perks v0.0.0-20230307044200-03f9df79da1e h1:mWOqoK5jV13ChKf/aF3plwQ96laasTJgZi4f1aSOu+M= -github.com/bmizerany/perks v0.0.0-20230307044200-03f9df79da1e/go.mod h1:ac9efd0D1fsDb3EJvhqgXRbFx7bs2wqZ10HQPeU8U/Q= -github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= -github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= -github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= -github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts= -github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= -github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/buger/goterm v1.0.4 h1:Z9YvGmOih81P0FbVtEYTFF6YsSgxSUKEhf/f9bTMXbY= -github.com/buger/goterm v1.0.4/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE= -github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= -github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/bugsnag/bugsnag-go v1.0.5-0.20150529004307-13fd6b8acda0 h1:s7+5BfS4WFJoVF9pnB8kBk03S7pZXRdKamnV0FOl5Sc= -github.com/bugsnag/bugsnag-go v1.0.5-0.20150529004307-13fd6b8acda0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= -github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ= -github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= -github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= -github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e85keuznYcH5rqI438v41pKcBl4ZxQ= -github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE= -github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= -github.com/compose-spec/compose-go/v2 v2.1.6 h1:d0Cs0DffmOwmSzs0YPHwKCskknGq2jfGg4uGowlEpps= -github.com/compose-spec/compose-go/v2 v2.1.6/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc= -github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= -github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0= -github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= -github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro= -github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= -github.com/containerd/containerd v1.7.21 h1:USGXRK1eOC/SX0L195YgxTHb0a00anxajOzgfN0qrCA= -github.com/containerd/containerd v1.7.21/go.mod h1:e3Jz1rYRUZ2Lt51YrH9Rz0zPyJBOlSvB3ghr2jbVD8g= -github.com/containerd/containerd/api v1.7.19 h1:VWbJL+8Ap4Ju2mx9c9qS1uFSB1OVYr5JJrW2yT5vFoA= -github.com/containerd/containerd/api v1.7.19/go.mod h1:fwGavl3LNwAV5ilJ0sbrABL44AQxmNjDRcwheXDb6Ig= -github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= -github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= -github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= -github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= -github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY= -github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/containerd/nydus-snapshotter v0.13.7 h1:x7DHvGnzJOu1ZPwPYkeOPk5MjZZYbdddygEjaSDoFTk= -github.com/containerd/nydus-snapshotter v0.13.7/go.mod h1:VPVKQ3jmHFIcUIV2yiQ1kImZuBFS3GXDohKs9mRABVE= -github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= -github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= -github.com/containerd/stargz-snapshotter v0.15.1 h1:fpsP4kf/Z4n2EYnU0WT8ZCE3eiKDwikDhL6VwxIlgeA= -github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU= -github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= -github.com/containerd/ttrpc v1.2.5 h1:IFckT1EFQoFBMG4c3sMdT8EP3/aKfumK1msY+Ze4oLU= -github.com/containerd/ttrpc v1.2.5/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= -github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso= -github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= -github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0= -github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= -github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/danielgtaylor/casing v0.0.0-20210126043903-4e55e6373ac3/go.mod h1:eFdYmNxcuLDrRNW0efVoxSaApmvGXfHZ9k2CT/RSUF0= -github.com/danielgtaylor/huma v1.14.3 h1:CqmODzN6xA1zxzHMND3cFuyaVWNPAPc3bI8mvgyC9qM= -github.com/danielgtaylor/huma v1.14.3/go.mod h1:I/19C1eNQd7ojMIQvynPe3lbuD5KfQEinH+ivIqjqmg= -github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/dgryski/go-gk v0.0.0-20200319235926-a69029f61654 h1:XOPLOMn/zT4jIgxfxSsoXPxkrzz0FaCHwp33x5POJ+Q= -github.com/dgryski/go-gk v0.0.0-20200319235926-a69029f61654/go.mod h1:qm+vckxRlDt0aOla0RYJJVeqHZlWfOm2UIxHaqPB46E= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= -github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= -github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/docker/buildx v0.16.2 h1:SPcyEiiCZEntJQ+V0lJI8ZudUrki2v1qUqmC/NqxDDs= -github.com/docker/buildx v0.16.2/go.mod h1:by+CuE4Q+2NvECkIhNcWe89jjbHADCrDlzS9MRgbv2k= -github.com/docker/cli v27.2.0+incompatible h1:yHD1QEB1/0vr5eBNpu8tncu8gWxg8EydFPOSKHzXSMM= -github.com/docker/cli v27.2.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli-docs-tool v0.8.0 h1:YcDWl7rQJC3lJ7WVZRwSs3bc9nka97QLWfyJQli8yJU= -github.com/docker/cli-docs-tool v0.8.0/go.mod h1:8TQQ3E7mOXoYUs811LiPdUnAhXrcVsBIrW21a5pUbdk= -github.com/docker/compose/v2 v2.29.2 h1:gRlR2ApZ0IGcwmSUb/wlEVCk18Az8b7zl03hJArldOg= -github.com/docker/compose/v2 v2.29.2/go.mod h1:U+yqqZqYPhILehkmmir+Yh7ZhCfkKqAvaZdrM47JBRs= -github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= -github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.5.1+incompatible h1:4PYU5dnBYqRQi0294d1FBECqT9ECWeQAIfE8q4YnPY8= -github.com/docker/docker v27.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= -github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= -github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= -github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= -github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= -github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= -github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= -github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= -github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= -github.com/dolthub/maphash v0.1.0 h1:bsQ7JsF4FkkWyrP3oCnFJgrCUAFbFf3kOl4L/QxPDyQ= -github.com/dolthub/maphash v0.1.0/go.mod h1:gkg4Ch4CdCDu5h6PMriVLawB7koZ+5ijb9puGMV50a4= -github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= -github.com/dprotaso/go-yit v0.0.0-20240618133044-5a0af90af097 h1:f5nA5Ys8RXqFXtKc0XofVRiuwNTuJzPIwTmbjLz9vj8= -github.com/dprotaso/go-yit v0.0.0-20240618133044-5a0af90af097/go.mod h1:FTAVyH6t+SlS97rv6EXRVuBDLkQqcIe/xQw9f4IFUI4= -github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= -github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203 h1:XBBHcIb256gUJtLmY22n99HaZTz+r2Z51xUPi01m3wg= -github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203/go.mod h1:E1jcSv8FaEny+OP/5k9UxZVw9YFWGj7eI4KR/iOBqCg= -github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= -github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= -github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05 h1:S92OBrGuLLZsyM5ybUzgc/mPjIYk2AZqufieooe98uw= -github.com/ericlagergren/decimal v0.0.0-20221120152707-495c53812d05/go.mod h1:M9R1FoZ3y//hwwnJtO51ypFGwm8ZfpxPT/ZLtO1mcgQ= -github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= -github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fsnotify/fsevents v0.2.0 h1:BRlvlqjvNTfogHfeBOFvSC9N0Ddy+wzQCQukyoD7o/c= -github.com/fsnotify/fsevents v0.2.0/go.mod h1:B3eEk39i4hz8y1zaWS/wPrAP4O6wkIl7HQwKBr1qH/w= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -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/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= -github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= -github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gammazero/deque v1.0.0 h1:LTmimT8H7bXkkCy6gZX7zNLtkbz4NdS2z8LZuor3j34= -github.com/gammazero/deque v1.0.0/go.mod h1:iflpYvtGfM3U8S8j+sZEKIak3SAKYpA5/SQewgfXDKo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= -github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= -github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw= -github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg= -github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -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-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= -github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -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.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= -github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= -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-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -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-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk= -github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/goccy/go-yaml v1.9.5/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= -github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= -github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= -github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -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/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac h1:Q0Jsdxl5jbxouNs1TQYt0gxesYMU4VXRbsTlgDloZ50= -github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac/go.mod h1:P32wAyui1PQ58Oce/KYkOqQv8cVw1zAapXOl+dRFGbc= -github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82 h1:EvokxLQsaaQjcWVWSV38221VAK7qc2zhaO17bKys/18= -github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg= -github.com/gonum/integrate v0.0.0-20181209220457-a422b5c0fdf2 h1:GUSkTcIe1SlregbHNUKbYDhBsS8lNgYfIp4S4cToUyU= -github.com/gonum/integrate v0.0.0-20181209220457-a422b5c0fdf2/go.mod h1:pDgmNM6seYpwvPos3q+zxlXMsbve6mOIPucUnUOrI7Y= -github.com/gonum/internal v0.0.0-20181124074243-f884aa714029 h1:8jtTdc+Nfj9AR+0soOeia9UZSvYBvETVHZrugUowJ7M= -github.com/gonum/internal v0.0.0-20181124074243-f884aa714029/go.mod h1:Pu4dmpkhSyOzRwuXkOgAvijx4o+4YMUJJo9OvPYMkks= -github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9 h1:7qnwS9+oeSiOIsiUMajT+0R7HR6hw5NegnKPmn/94oI= -github.com/gonum/lapack v0.0.0-20181123203213-e4cdc5a0bff9/go.mod h1:XA3DeT6rxh2EAE789SSiSJNqxPaC0aE9J8NTOI0Jo/A= -github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9 h1:V2IgdyerlBa/MxaEFRbV5juy/C3MGdj4ePi+g6ePIp4= -github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9/go.mod h1:0EXg4mc1CNP0HCqCz+K4ts155PXIlUywf0wqN+GfPZw= -github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b h1:fbskpz/cPqWH8VqkQ7LJghFkl2KPAiIFUHrTJ2O3RGk= -github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b/go.mod h1:Z4GIJBJO3Wa4gD4vbwQxXXZ+WHmW6E9ixmNrwvs0iZs= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= -github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93 h1:jc2UWq7CbdszqeH6qu1ougXMIUBfSy8Pbh/anURYbGI= -github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -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/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -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/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -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/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= -github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grafana/pyroscope-go v1.2.0 h1:aILLKjTj8CS8f/24OPMGPewQSYlhmdQMBmol1d3KGj8= -github.com/grafana/pyroscope-go v1.2.0/go.mod h1:2GHr28Nr05bg2pElS+dDsc98f3JTUh2f6Fz1hWXrqwk= -github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= -github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= -github.com/graphql-go/graphql v0.7.9/go.mod h1:k6yrAYQaSP59DC5UVxbgxESlmVyojThKdORUqGDGmrI= -github.com/graphql-go/graphql v0.8.0/go.mod h1:nKiHzRM0qopJEwCITUuIsxk9PlVlwIiiI8pnJEhordQ= -github.com/graphql-go/handler v0.2.3/go.mod h1:leLF6RpV5uZMN1CdImAxuiayrYYhOk33bZciaUGaXeU= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M= -github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= -github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= -github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-metrics v0.5.4 h1:8mmPiIJkTPPEbAiV97IxdAGNdRdaWwVap1BU6elejKY= -github.com/hashicorp/go-metrics v0.5.4/go.mod h1:CG5yz4NZ/AI/aQt9Ucm/vdBnbh7fvmv4lxZ350i+QQI= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0= -github.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw= -github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= -github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/memberlist v0.5.3 h1:tQ1jOCypD0WvMemw/ZhhtH+PWpzcftQvgCorLu0hndk= -github.com/hashicorp/memberlist v0.5.3/go.mod h1:h60o12SZn/ua/j0B6iKAZezA4eDaGsIuPO70eOaJ6WE= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hashicorp/serf v0.10.2 h1:m5IORhuNSjaxeljg5DeQVDlQyVkhRIjJDimbkCa8aAc= -github.com/hashicorp/serf v0.10.2/go.mod h1:T1CmSGfSeGfnfNy/w0odXQUR1rfECGd2Qdsp84DjOiY= -github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= -github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -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/in-toto/in-toto-golang v0.9.0 h1:tHny7ac4KgtsfrG6ybU8gVOZux2H8jN05AXJ9EBM1XU= -github.com/in-toto/in-toto-golang v0.9.0/go.mod h1:xsBVrVsHNsB61++S6Dy2vWosKhuA3lUTQd+eF9HdeMo= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/influxdata/tdigest v0.0.1 h1:XpFptwYmnEKUqmkcDjrzffswZ3nvNeevbUSLPP/ZzIY= -github.com/influxdata/tdigest v0.0.1/go.mod h1:Z0kXnxzbTC2qrx4NaIzYkE1k66+6oEDQTvL95hQFh5Y= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8 h1:CZkYfurY6KGhVtlalI4QwQ6T0Cu6iuY3e0x5RLu96WE= -github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo= -github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d h1:jRQLvyVGL+iVtDElaEIDdKwpPqUIZJfzkNLV34htpEc= -github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= -github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= -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/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -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/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= -github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron-go/gqlcost v0.2.2/go.mod h1:8ZAmWla8nXCH0lBTxMZ+gbvgHhCCvTX3V4pEkC3obQA= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lufia/plan9stats v0.0.0-20240819163618-b1d8f4d146e7 h1:5RK988zAqB3/AN3opGfRpoQgAVqr6/A5+qRTi67VUZY= -github.com/lufia/plan9stats v0.0.0-20240819163618-b1d8f4d146e7/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= -github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= -github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= -github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= -github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= -github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/maypok86/otter v1.2.4 h1:HhW1Pq6VdJkmWwcZZq19BlEQkHtI8xgsQzBVXJU0nfc= -github.com/maypok86/otter v1.2.4/go.mod h1:mKLfoI7v1HOmQMwFgX4QkRk23mX6ge3RDvjdHOWG4R4= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= -github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY= -github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs= -github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= -github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= -github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= -github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/buildkit v0.15.2 h1:DnONr0AoceTWyv+plsQ7IhkSaj+6o0WyoaxYPyTFIxs= -github.com/moby/buildkit v0.15.2/go.mod h1:Yis8ZMUJTHX9XhH9zVyK2igqSHV3sxi3UN0uztZocZk= -github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= -github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= -github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= -github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= -github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= -github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= -github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= -github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= -github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= -github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= -github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= -github.com/moby/sys/signal v0.7.1 h1:PrQxdvxcGijdo6UXXo/lU/TvHUWyPhj7UOpSo8tuvk0= -github.com/moby/sys/signal v0.7.1/go.mod h1:Se1VGehYokAkrSQwL4tDzHvETwUZlnY7S5XtQ50mQp8= -github.com/moby/sys/symlink v0.3.0 h1:GZX89mEZ9u53f97npBy4Rc3vJKj7JBDj/PN2I22GrNU= -github.com/moby/sys/symlink v0.3.0/go.mod h1:3eNdhduHmYPcgsJtZXW1W4XUJdZGBIkttZ8xKqPUJq0= -github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= -github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= -github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= -github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= -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 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -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/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -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.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= -github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= -github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= -github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= -github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU= -github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU= -github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= -github.com/pb33f/libopenapi v0.21.2 h1:L99NhyXtcRIawo8aVmWPIfA6k8v+8t6zJrTZkv7ggMI= -github.com/pb33f/libopenapi v0.21.2/go.mod h1:Gc8oQkjr2InxwumK0zOBtKN9gIlv9L2VmSVIUk2YxcU= -github.com/pb33f/libopenapi-validator v0.3.0 h1:xiIdPDETIPYICJn5RxD6SeGNdOBpe0ADHHW5NfNvypU= -github.com/pb33f/libopenapi-validator v0.3.0/go.mod h1:NmCV/GZcDrL5slbCMbqWz/9KU3Q/qST001hiRctOXDs= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= -github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= -github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= -github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= -github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= -github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= -github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= -github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc h1:zAsgcP8MhzAbhMnB1QQ2O7ZhWYVGYSR2iVcjzQuPV+o= -github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc/go.mod h1:S8xSOnV3CgpNrWd0GQ/OoQfMtlg2uPRSuTzcSGrzwK8= -github.com/redis/go-redis/v9 v9.6.3 h1:8Dr5ygF1QFXRxIH/m3Xg9MMG1rS8YCtAgosrsewT6i0= -github.com/redis/go-redis/v9 v9.6.3/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= -github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/rs/dnscache v0.0.0-20230804202142-fc85eb664529 h1:18kd+8ZUlt/ARXhljq+14TwAoKa61q6dX8jtwOf6DH8= -github.com/rs/dnscache v0.0.0-20230804202142-fc85eb664529/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= -github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM= -github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 h1:PKK9DyHxif4LZo+uQSgXNqs0jj5+xZwwfKHgph2lxBw= -github.com/santhosh-tekuri/jsonschema/v6 v6.0.1/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbmfHkLguCE9laoZCUzEEpIZXA= -github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU= -github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= -github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= -github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= -github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b h1:h+3JX2VoWTFuyQEo87pStk/a99dzIO1mM9KxIyLPGTU= -github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc= -github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI= -github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE= -github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= -github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk= -github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= -github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= -github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= -github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= -github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= -github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= -github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spdx/tools-golang v0.5.3 h1:ialnHeEYUC4+hkm5vJm4qz2x+oEJbS0mAMFrNXdQraY= -github.com/spdx/tools-golang v0.5.3/go.mod h1:/ETOahiAo96Ob0/RAIBmFZw6XN0yTnyr/uFZm2NTMhI= -github.com/speakeasy-api/jsonpath v0.6.1 h1:FWbuCEPGaJTVB60NZg2orcYHGZlelbNJAcIk/JGnZvo= -github.com/speakeasy-api/jsonpath v0.6.1/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= -github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -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/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= -github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU= -github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= -github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/spyzhov/ajson v0.8.0 h1:sFXyMbi4Y/BKjrsfkUZHSjA2JM1184enheSjjoT/zCc= -github.com/spyzhov/ajson v0.8.0/go.mod h1:63V+CGM6f1Bu/p4nLIN8885ojBdt88TbLoSFzyqMuVA= -github.com/streadway/quantile v0.0.0-20220407130108-4246515d968d h1:X4+kt6zM/OVO6gbJdAfJR60MGPsqCzbtXNnjoGqdfAs= -github.com/streadway/quantile v0.0.0-20220407130108-4246515d968d/go.mod h1:lbP8tGiBjZ5YWIc2fzuRpTaz0b/53vT6PEs3QuAWzuU= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= -github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/tent/http-link-go v0.0.0-20130702225549-ac974c61c2f9/go.mod h1:RHkNRtSLfOK7qBTHaeSX1D6BNpI3qw7NTxsmNr4RvN8= -github.com/testcontainers/testcontainers-go v0.33.0 h1:zJS9PfXYT5O0ZFXM2xxXfk4J5UMw/kRiISng037Gxdw= -github.com/testcontainers/testcontainers-go v0.33.0/go.mod h1:W80YpTa8D5C3Yy16icheD01UTDu+LmXIA2Keo+jWtT8= -github.com/testcontainers/testcontainers-go/modules/compose v0.33.0 h1:PyrUOF+zG+xrS3p+FesyVxMI+9U+7pwhZhyFozH3jKY= -github.com/testcontainers/testcontainers-go/modules/compose v0.33.0/go.mod h1:oqZaUnFEskdZriO51YBquku/jhgzoXHPot6xe1DqKV4= -github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c= -github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw= -github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= -github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= -github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375 h1:QB54BJwA6x8QU9nHY3xJSZR2kX9bgpZekRKGkLTmEXA= -github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375/go.mod h1:xRroudyp5iVtxKqZCrA6n2TLFRBf8bmnjr1UD4x+z7g= -github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= -github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= -github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= -github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= -github.com/tonistiigi/fsutil v0.0.0-20240820162337-c117dd14469d h1:Vje1mokfrtmg7piOEB/mn9DBgm56xTel7SPK2Hs+KuY= -github.com/tonistiigi/fsutil v0.0.0-20240820162337-c117dd14469d/go.mod h1:vbbYqJlnswsbJqWUcJN8fKtBhnEgldDrcagTgnBVKKM= -github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0 h1:2f304B10LaZdB8kkVEaoXvAMVan2tl9AiK4G0odjQtE= -github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0/go.mod h1:278M4p8WsNh3n4a1eqiFcV2FGk7wE5fwUpUom9mK9lE= -github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0= -github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk= -github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab h1:H6aJ0yKQ0gF49Qb2z5hI1UHxSQt4JMyxebFR15KnApw= -github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab/go.mod h1:ulncasL3N9uLrVann0m+CDlJKWsIAP34MPcOJF6VRvc= -github.com/tsenart/vegeta/v12 v12.12.0 h1:FKMMNomd3auAElO/TtbXzRFXAKGee6N/GKCGweFVm2U= -github.com/tsenart/vegeta/v12 v12.12.0/go.mod h1:gpdfR++WHV9/RZh4oux0f6lNPhsOH8pCjIGUlcPQe1M= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/unkeyed/unkey-go v0.8.8 h1:NtWI5Ix9nuERVVwP+1Bs4GAr7aHDcDR+/ArD84PgCn8= -github.com/unkeyed/unkey-go v0.8.8/go.mod h1:X8PHynf0QviDvYFWXePSFIGZydm3bRCqOIk7k1nNHuk= -github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= -github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= -github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts= -github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk= -github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= -github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/wk8/go-ordered-map/v2 v2.1.9-0.20240815153524-6ea36470d1bd h1:dLuIF2kX9c+KknGJUdJi1Il1SDiTSK158/BB9kdgAew= -github.com/wk8/go-ordered-map/v2 v2.1.9-0.20240815153524-6ea36470d1bd/go.mod h1:DbzwytT4g/odXquuOCqroKvtxxldI4nb3nuesHF/Exo= -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/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= -github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= -github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= -github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= -github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= -go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.54.0 h1:U9ge/19g8pkNXL+0eqeWgiJAd8nSmmvbvwehqyxU/Lc= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.54.0/go.mod h1:dmNhUi0Tl5v/3e0QNp7/3KLMvAPoHh4lMbZU319UkM0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I= -go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= -go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0 h1:k6fQVDQexDE+3jG2SfCQjnHS7OamcP73YMoxEVq5B6k= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.29.0/go.mod h1:t4BrYLHU450Zo9fnydWlIuswB1bm7rM8havDpWOJeDo= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.29.0 h1:xvhQxJ/C9+RTnAj5DpTg7LSM1vbbMTiXt7e9hsfqHNw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.29.0/go.mod h1:Fcvs2Bz1jkDM+Wf5/ozBGmi3tQ/c9zPKLnsipnfhGAo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0/go.mod h1:hKn/e/Nmd19/x1gvIHwtOwVWM+VhuITSWip3JUDghj0= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= -go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= -go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= -go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= -go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= -go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= -go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= -go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= -go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= -go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/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.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= -golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac h1:l5+whBCLH3iH2ZNHYLbAe58bo7yrN4mVcnkHDYz5vvs= -golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac/go.mod h1:hH+7mtFmImwwcMvScyxUhjuVHR3HGaDPMn9rMSUUbxo= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -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.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= -golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= -golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= -golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca h1:PupagGYwj8+I4ubCxcmcBRk3VlUWtTg5huQpZR9flmE= -gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20240827150818-7e3bb234dfed h1:4C4dbrVFtfIp3GXJdMX1Sj25mahfn5DywOo65/2ISQ8= -google.golang.org/genproto v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:ICjniACoWvcDz8c8bOsHVKuuSGDJy1z5M4G0DM3HzTc= -google.golang.org/genproto/googleapis/api v0.0.0-20250207221924-e9438ea467c6 h1:L9JNMl/plZH9wmzQUHleO/ZZDSN+9Gh41wPczNy+5Fk= -google.golang.org/genproto/googleapis/api v0.0.0-20250207221924-e9438ea467c6/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 h1:2duwAxN2+k0xLNpjnHTXoMUgnv6VPSp5fiqTuwSxjmI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= -google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= -google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y= -gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI= -gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII= -gopkg.in/cenkalti/backoff.v2 v2.2.1/go.mod h1:S0QdOvT2AlerfSBkp0O+dk+bbIMaNbEmVk876gPCthU= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1 h1:d4KQkxAaAiRY2h5Zqis161Pv91A37uZyJOx73duwUwM= -gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1/go.mod h1:WbjuEoo1oadwzQ4apSDU+JTvmllEHtsNHS6y7vFc7iw= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo= -k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE= -k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc= -k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8= -k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU= -k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= -k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 h1:GKE9U8BH16uynoxQii0auTjmmmuZ3O0LFMN6S0lPPhI= -k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2/go.mod h1:coRQXBK9NxO98XUv3ZD6AK3xzHCxV6+b7lrquKwaKzA= -k8s.io/utils v0.0.0-20240821151609-f90d01438635 h1:2wThSvJoW/Ncn9TmQEYXRnevZXi2duqHWf5OX9S3zjI= -k8s.io/utils v0.0.0-20240821151609-f90d01438635/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= -pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= -pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= -tags.cncf.io/container-device-interface v0.8.0 h1:8bCFo/g9WODjWx3m6EYl3GfUG31eKJbaggyBDxEldRc= -tags.cncf.io/container-device-interface v0.8.0/go.mod h1:Apb7N4VdILW0EVdEMRYXIDVRZfNJZ+kmEUss2kRRQ6Y= diff --git a/web/apps/agent/pkg/api/agent_auth.go b/web/apps/agent/pkg/api/agent_auth.go deleted file mode 100644 index 6a7f79127e..0000000000 --- a/web/apps/agent/pkg/api/agent_auth.go +++ /dev/null @@ -1,51 +0,0 @@ -package api - -import ( - "crypto/subtle" - "net/http" - "strings" - - "github.com/unkeyed/unkey/svc/agent/pkg/api/routes" -) - -func newBearerAuthMiddleware(secret string) routes.Middeware { - secretB := []byte(secret) - - return func(next http.HandlerFunc) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - - authorizationHeader := r.Header.Get("Authorization") - if authorizationHeader == "" { - w.WriteHeader(401) - _, err := w.Write([]byte("Authorization header is required")) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } - return - } - - token := strings.TrimPrefix(authorizationHeader, "Bearer ") - if token == "" { - w.WriteHeader(401) - _, err := w.Write([]byte("Bearer token is required")) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } - return - - } - - if subtle.ConstantTimeCompare([]byte(token), secretB) != 1 { - w.WriteHeader(401) - _, err := w.Write([]byte("Bearer token is invalid")) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } - return - } - - next(w, r) - } - } - -} diff --git a/web/apps/agent/pkg/api/ctxutil/context.go b/web/apps/agent/pkg/api/ctxutil/context.go deleted file mode 100644 index 2ce32a3b0f..0000000000 --- a/web/apps/agent/pkg/api/ctxutil/context.go +++ /dev/null @@ -1,27 +0,0 @@ -package ctxutil - -import "context" - -type contextKey string - -const ( - request_id contextKey = "request_id" -) - -// getValue returns the value for the given key from the context or its zero value if it doesn't exist. -func getValue[T any](ctx context.Context, key contextKey) T { - val, ok := ctx.Value(key).(T) - if !ok { - var t T - return t - } - return val -} - -func GetRequestID(ctx context.Context) string { - return getValue[string](ctx, request_id) -} - -func SetRequestID(ctx context.Context, requestID string) context.Context { - return context.WithValue(ctx, request_id, requestID) -} diff --git a/web/apps/agent/pkg/api/errors/internal_server_error.go b/web/apps/agent/pkg/api/errors/internal_server_error.go deleted file mode 100644 index 9e32d4ebe2..0000000000 --- a/web/apps/agent/pkg/api/errors/internal_server_error.go +++ /dev/null @@ -1,24 +0,0 @@ -package errors - -import ( - "context" - "net/http" - - "github.com/Southclaws/fault/fmsg" - "github.com/unkeyed/unkey/svc/agent/pkg/api/ctxutil" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" -) - -// HandleError takes in any unforseen error and returns a BaseError to be sent to the client -func HandleError(ctx context.Context, err error) openapi.BaseError { - - return openapi.BaseError{ - Title: "Internal Server Error", - Detail: fmsg.GetIssue(err), - Instance: "https://errors.unkey.com/todo", - Status: http.StatusInternalServerError, - RequestId: ctxutil.GetRequestID(ctx), - Type: "TODO docs link", - } - -} diff --git a/web/apps/agent/pkg/api/errors/validation_error.go b/web/apps/agent/pkg/api/errors/validation_error.go deleted file mode 100644 index df2a31dcb7..0000000000 --- a/web/apps/agent/pkg/api/errors/validation_error.go +++ /dev/null @@ -1,32 +0,0 @@ -package errors - -import ( - "context" - "net/http" - - "github.com/Southclaws/fault/fmsg" - "github.com/unkeyed/unkey/svc/agent/pkg/api/ctxutil" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" -) - -func HandleValidationError(ctx context.Context, err error) openapi.ValidationError { - - issues := fmsg.GetIssues(err) - details := make([]openapi.ValidationErrorDetail, len(issues)) - for i, issue := range issues { - details[i] = openapi.ValidationErrorDetail{ - Message: issue, - } - } - - return openapi.ValidationError{ - Title: "Internal Server Error", - Detail: "An internal server error occurred", - Errors: details, - Instance: "https://errors.unkey.com/todo", - Status: http.StatusBadRequest, - RequestId: ctxutil.GetRequestID(ctx), - Type: "TODO docs link", - } - -} diff --git a/web/apps/agent/pkg/api/interface.go b/web/apps/agent/pkg/api/interface.go deleted file mode 100644 index f7542fc259..0000000000 --- a/web/apps/agent/pkg/api/interface.go +++ /dev/null @@ -1,7 +0,0 @@ -package api - -import "github.com/unkeyed/unkey/svc/agent/pkg/clickhouse/schema" - -type EventBuffer interface { - BufferApiRequest(schema.ApiRequestV1) -} diff --git a/web/apps/agent/pkg/api/mw_logging.go b/web/apps/agent/pkg/api/mw_logging.go deleted file mode 100644 index 6c8e0e3d50..0000000000 --- a/web/apps/agent/pkg/api/mw_logging.go +++ /dev/null @@ -1,93 +0,0 @@ -package api - -import ( - "bytes" - "fmt" - "io" - "net/http" - "strings" - "time" - - "github.com/unkeyed/unkey/svc/agent/pkg/api/ctxutil" - "github.com/unkeyed/unkey/svc/agent/pkg/clickhouse" - "github.com/unkeyed/unkey/svc/agent/pkg/clickhouse/schema" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" -) - -type responseWriterInterceptor struct { - w http.ResponseWriter - body *bytes.Buffer - statusCode int -} - -// Pass through -func (w *responseWriterInterceptor) Header() http.Header { - return w.w.Header() -} - -// Capture and pass through -func (w *responseWriterInterceptor) Write(b []byte) (int, error) { - w.body.Write(b) - return w.w.Write(b) -} - -// Capture and pass through -func (w *responseWriterInterceptor) WriteHeader(statusCode int) { - w.statusCode = statusCode - w.w.WriteHeader(statusCode) -} -func withLogging(next http.Handler, ch clickhouse.Bufferer, logger logging.Logger) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - start := time.Now() - ctx := r.Context() - wi := &responseWriterInterceptor{w: w, body: &bytes.Buffer{}} - - errorMessage := "" - // r2 is a clone of r, so we can read the body twice - r2 := r.Clone(ctx) - defer r2.Body.Close() - requestBody, err := io.ReadAll(r2.Body) - if err != nil { - logger.Error().Err(err).Msg("error reading r2 body") - errorMessage = err.Error() - requestBody = []byte("unable to read request body") - } - - next.ServeHTTP(wi, r) - serviceLatency := time.Since(start) - - logger.Info(). - Str("method", r.Method). - Str("path", r.URL.Path). - Int("status", wi.statusCode). - Str("latency", serviceLatency.String()). - Msg("request") - - requestHeaders := []string{} - for k, vv := range r.Header { - if strings.ToLower(k) == "authorization" { - vv = []string{""} - } - requestHeaders = append(requestHeaders, fmt.Sprintf("%s: %s", k, strings.Join(vv, ","))) - } - - responseHeaders := []string{} - for k, vv := range wi.Header() { - responseHeaders = append(responseHeaders, fmt.Sprintf("%s: %s", k, strings.Join(vv, ","))) - } - - ch.BufferApiRequest(schema.ApiRequestV1{ - RequestID: ctxutil.GetRequestID(ctx), - Time: start.UnixMilli(), - Host: r.Host, - Method: r.Method, - Path: r.URL.Path, - RequestHeaders: requestHeaders, - RequestBody: string(requestBody), - ResponseStatus: wi.statusCode, - ResponseHeaders: responseHeaders, - ResponseBody: wi.body.String(), - Error: errorMessage, - }) - }) -} diff --git a/web/apps/agent/pkg/api/mw_metrics.go b/web/apps/agent/pkg/api/mw_metrics.go deleted file mode 100644 index 6eef990c84..0000000000 --- a/web/apps/agent/pkg/api/mw_metrics.go +++ /dev/null @@ -1,48 +0,0 @@ -package api - -import ( - "fmt" - "net/http" - "time" - - "github.com/unkeyed/unkey/svc/agent/pkg/prometheus" -) - -type responseWriterStatusInterceptor struct { - w http.ResponseWriter - statusCode int -} - -// Pass through -func (w *responseWriterStatusInterceptor) Header() http.Header { - return w.w.Header() -} - -// Pass through -func (w *responseWriterStatusInterceptor) Write(b []byte) (int, error) { - return w.w.Write(b) -} - -// Capture and pass through -func (w *responseWriterStatusInterceptor) WriteHeader(statusCode int) { - w.statusCode = statusCode - w.w.WriteHeader(statusCode) -} - -func withMetrics(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - wi := &responseWriterStatusInterceptor{w: w} - - start := time.Now() - next.ServeHTTP(wi, r) - serviceLatency := time.Since(start) - - prometheus.HTTPRequests.With(map[string]string{ - "method": r.Method, - "path": r.URL.Path, - "status": fmt.Sprintf("%d", wi.statusCode), - }).Inc() - - prometheus.ServiceLatency.WithLabelValues(r.URL.Path).Observe(serviceLatency.Seconds()) - }) -} diff --git a/web/apps/agent/pkg/api/mw_request_id.go b/web/apps/agent/pkg/api/mw_request_id.go deleted file mode 100644 index 5e1aff5f2f..0000000000 --- a/web/apps/agent/pkg/api/mw_request_id.go +++ /dev/null @@ -1,16 +0,0 @@ -package api - -import ( - "net/http" - - "github.com/unkeyed/unkey/svc/agent/pkg/api/ctxutil" - "github.com/unkeyed/unkey/svc/agent/pkg/uid" -) - -func withRequestId(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - ctx = ctxutil.SetRequestID(ctx, uid.New(uid.Request())) - next.ServeHTTP(w, r.WithContext(ctx)) - }) -} diff --git a/web/apps/agent/pkg/api/mw_tracing.go b/web/apps/agent/pkg/api/mw_tracing.go deleted file mode 100644 index f30231eae6..0000000000 --- a/web/apps/agent/pkg/api/mw_tracing.go +++ /dev/null @@ -1,18 +0,0 @@ -package api - -import ( - "net/http" - - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" -) - -func withTracing(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - ctx, span := tracing.Start(ctx, tracing.NewSpanName("api", r.URL.Path)) - defer span.End() - r = r.WithContext(ctx) - - next.ServeHTTP(w, r) - }) -} diff --git a/web/apps/agent/pkg/api/register_routes.go b/web/apps/agent/pkg/api/register_routes.go deleted file mode 100644 index 4c0eefff79..0000000000 --- a/web/apps/agent/pkg/api/register_routes.go +++ /dev/null @@ -1,58 +0,0 @@ -package api - -import ( - "github.com/unkeyed/unkey/svc/agent/pkg/api/routes" - notFound "github.com/unkeyed/unkey/svc/agent/pkg/api/routes/not_found" - openapi "github.com/unkeyed/unkey/svc/agent/pkg/api/routes/openapi" - v1Liveness "github.com/unkeyed/unkey/svc/agent/pkg/api/routes/v1_liveness" - v1RatelimitCommitLease "github.com/unkeyed/unkey/svc/agent/pkg/api/routes/v1_ratelimit_commitLease" - v1RatelimitMultiRatelimit "github.com/unkeyed/unkey/svc/agent/pkg/api/routes/v1_ratelimit_multiRatelimit" - v1RatelimitRatelimit "github.com/unkeyed/unkey/svc/agent/pkg/api/routes/v1_ratelimit_ratelimit" - v1VaultDecrypt "github.com/unkeyed/unkey/svc/agent/pkg/api/routes/v1_vault_decrypt" - v1VaultEncrypt "github.com/unkeyed/unkey/svc/agent/pkg/api/routes/v1_vault_encrypt" - v1VaultEncryptBulk "github.com/unkeyed/unkey/svc/agent/pkg/api/routes/v1_vault_encrypt_bulk" -) - -func (s *Server) RegisterRoutes() { - svc := routes.Services{ - Logger: s.logger, - Metrics: s.metrics, - Vault: s.vault, - Ratelimit: s.ratelimit, - OpenApiValidator: s.validator, - Sender: routes.NewJsonSender(s.logger), - } - - s.logger.Info().Interface("svc", svc).Msg("Registering routes") - - staticBearerAuth := newBearerAuthMiddleware(s.authToken) - - v1Liveness.New(svc).Register(s.mux) - openapi.New(svc).Register(s.mux) - - v1RatelimitCommitLease.New(svc). - WithMiddleware(staticBearerAuth). - Register(s.mux) - - v1RatelimitMultiRatelimit.New(svc). - WithMiddleware(staticBearerAuth). - Register(s.mux) - - v1RatelimitRatelimit.New(svc). - WithMiddleware(staticBearerAuth). - Register(s.mux) - - v1VaultDecrypt.New(svc). - WithMiddleware(staticBearerAuth). - Register(s.mux) - - v1VaultEncrypt.New(svc). - WithMiddleware(staticBearerAuth). - Register(s.mux) - - v1VaultEncryptBulk.New(svc). - WithMiddleware(staticBearerAuth). - Register(s.mux) - - notFound.New(svc).Register(s.mux) -} diff --git a/web/apps/agent/pkg/api/routes/not_found/handler.go b/web/apps/agent/pkg/api/routes/not_found/handler.go deleted file mode 100644 index 13306534e1..0000000000 --- a/web/apps/agent/pkg/api/routes/not_found/handler.go +++ /dev/null @@ -1,26 +0,0 @@ -package notFound - -import ( - "net/http" - - "github.com/unkeyed/unkey/svc/agent/pkg/api/ctxutil" - "github.com/unkeyed/unkey/svc/agent/pkg/api/routes" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" -) - -// This is a hack, because / matches everything, so we need to make sure this is the last route -func New(svc routes.Services) *routes.Route { - return routes.NewRoute("", "/", - func(w http.ResponseWriter, r *http.Request) { - - svc.Sender.Send(r.Context(), w, 200, openapi.BaseError{ - Title: "Not Found", - Detail: "This route does not exist", - Instance: "https://errors.unkey.com/todo", - Status: http.StatusNotFound, - RequestId: ctxutil.GetRequestID(r.Context()), - Type: "TODO docs link", - }) - }, - ) -} diff --git a/web/apps/agent/pkg/api/routes/openapi/handler.go b/web/apps/agent/pkg/api/routes/openapi/handler.go deleted file mode 100644 index a0ebb173bb..0000000000 --- a/web/apps/agent/pkg/api/routes/openapi/handler.go +++ /dev/null @@ -1,22 +0,0 @@ -package openapi - -import ( - "net/http" - - "github.com/unkeyed/unkey/svc/agent/pkg/api/routes" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" -) - -func New(svc routes.Services) *routes.Route { - return routes.NewRoute("GET", "/openapi.json", - func(w http.ResponseWriter, r *http.Request) { - - w.WriteHeader(200) - w.Header().Set("Content-Type", "application/json") - _, err := w.Write(openapi.Spec) - if err != nil { - http.Error(w, "failed to write response", http.StatusInternalServerError) - } - }, - ) -} diff --git a/web/apps/agent/pkg/api/routes/route.go b/web/apps/agent/pkg/api/routes/route.go deleted file mode 100644 index 968f234364..0000000000 --- a/web/apps/agent/pkg/api/routes/route.go +++ /dev/null @@ -1,41 +0,0 @@ -package routes - -import ( - "fmt" - "net/http" -) - -type Route struct { - method string - path string - handler http.HandlerFunc -} - -func NewRoute(method string, path string, handler http.HandlerFunc) *Route { - return &Route{ - method: method, - path: path, - handler: handler, - } -} - -type Middeware func(http.HandlerFunc) http.HandlerFunc - -func (r *Route) WithMiddleware(mws ...Middeware) *Route { - for _, mw := range mws { - r.handler = mw(r.handler) - } - return r -} - -func (r *Route) Register(mux *http.ServeMux) { - mux.HandleFunc(fmt.Sprintf("%s %s", r.method, r.path), r.handler) -} - -func (r *Route) Method() string { - return r.method -} - -func (r *Route) Path() string { - return r.path -} diff --git a/web/apps/agent/pkg/api/routes/sender.go b/web/apps/agent/pkg/api/routes/sender.go deleted file mode 100644 index 2624e34502..0000000000 --- a/web/apps/agent/pkg/api/routes/sender.go +++ /dev/null @@ -1,70 +0,0 @@ -package routes - -import ( - "context" - "encoding/json" - "net/http" - - "github.com/unkeyed/unkey/svc/agent/pkg/api/ctxutil" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" -) - -type Sender interface { - - // Send marshals the body and sends it as a response with the given status code. - // If marshalling fails, it will return a 500 response with the error message. - Send(ctx context.Context, w http.ResponseWriter, status int, body any) -} - -type JsonSender struct { - logger logging.Logger -} - -func NewJsonSender(logger logging.Logger) Sender { - return &JsonSender{logger: logger} -} - -// Send returns a JSON response with the given status code and body. -// If marshalling fails, it will return a 500 response with the error message. -func (r *JsonSender) Send(ctx context.Context, w http.ResponseWriter, status int, body any) { - if body == nil { - return - } - - b, err := json.Marshal(body) - if err != nil { - r.logger.Error().Err(err).Interface("body", body).Msg("failed to marshal response body") - w.WriteHeader(http.StatusInternalServerError) - - error := openapi.BaseError{ - Title: "Internal Server Error", - Detail: "failed to marshal response body", - Instance: "https://errors.unkey.com/todo", - Status: http.StatusInternalServerError, - RequestId: ctxutil.GetRequestID(ctx), - Type: "TODO docs link", - } - - b, err = json.Marshal(error) - if err != nil { - _, err = w.Write([]byte("failed to marshal response body")) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } - return - } - _, err = w.Write(b) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } - return - } - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(status) - _, err = w.Write(b) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } -} diff --git a/web/apps/agent/pkg/api/routes/services.go b/web/apps/agent/pkg/api/routes/services.go deleted file mode 100644 index 149c6ae685..0000000000 --- a/web/apps/agent/pkg/api/routes/services.go +++ /dev/null @@ -1,18 +0,0 @@ -package routes - -import ( - "github.com/unkeyed/unkey/svc/agent/pkg/api/validation" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/metrics" - "github.com/unkeyed/unkey/svc/agent/services/ratelimit" - "github.com/unkeyed/unkey/svc/agent/services/vault" -) - -type Services struct { - Logger logging.Logger - Metrics metrics.Metrics - Vault *vault.Service - Ratelimit ratelimit.Service - OpenApiValidator validation.OpenAPIValidator - Sender Sender -} diff --git a/web/apps/agent/pkg/api/routes/v1_liveness/handler.go b/web/apps/agent/pkg/api/routes/v1_liveness/handler.go deleted file mode 100644 index c5d6f44973..0000000000 --- a/web/apps/agent/pkg/api/routes/v1_liveness/handler.go +++ /dev/null @@ -1,21 +0,0 @@ -package v1Liveness - -import ( - "net/http" - - "github.com/unkeyed/unkey/svc/agent/pkg/api/routes" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" -) - -func New(svc routes.Services) *routes.Route { - return routes.NewRoute("GET", "/v1/liveness", - func(w http.ResponseWriter, r *http.Request) { - - svc.Logger.Debug().Msg("incoming liveness check") - - svc.Sender.Send(r.Context(), w, 200, openapi.V1LivenessResponseBody{ - Message: "OK", - }) - }, - ) -} diff --git a/web/apps/agent/pkg/api/routes/v1_liveness/handler_test.go b/web/apps/agent/pkg/api/routes/v1_liveness/handler_test.go deleted file mode 100644 index 045e321cef..0000000000 --- a/web/apps/agent/pkg/api/routes/v1_liveness/handler_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package v1Liveness_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - v1Liveness "github.com/unkeyed/unkey/svc/agent/pkg/api/routes/v1_liveness" - "github.com/unkeyed/unkey/svc/agent/pkg/api/testutil" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" -) - -func TestLiveness(t *testing.T) { - - h := testutil.NewHarness(t) - route := h.SetupRoute(v1Liveness.New) - res := testutil.CallRoute[any, openapi.V1LivenessResponseBody](t, route, nil, nil) - - require.Equal(t, 200, res.Status) -} diff --git a/web/apps/agent/pkg/api/routes/v1_ratelimit_commitLease/handler.go b/web/apps/agent/pkg/api/routes/v1_ratelimit_commitLease/handler.go deleted file mode 100644 index 1802a4c88b..0000000000 --- a/web/apps/agent/pkg/api/routes/v1_ratelimit_commitLease/handler.go +++ /dev/null @@ -1,48 +0,0 @@ -package v1RatelimitCommitLease - -import ( - "net/http" - - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" - "github.com/btcsuite/btcutil/base58" - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/api/errors" - "github.com/unkeyed/unkey/svc/agent/pkg/api/routes" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" - "google.golang.org/protobuf/proto" -) - -func New(svc routes.Services) *routes.Route { - return routes.NewRoute("POST", "/ratelimit.v1.RatelimitService/CommitLease", - func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - req := &openapi.V1RatelimitCommitLeaseRequestBody{} - errorResponse, valid := svc.OpenApiValidator.Body(r, req) - if !valid { - svc.Sender.Send(ctx, w, 400, errorResponse) - return - } - - b := base58.Decode(req.Lease) - lease := &ratelimitv1.Lease{} - err := proto.Unmarshal(b, lease) - if err != nil { - errors.HandleValidationError(ctx, fault.Wrap(err, fmsg.WithDesc("invalid_lease", "The lease is not valid."))) - return - } - - _, err = svc.Ratelimit.CommitLease(ctx, &ratelimitv1.CommitLeaseRequest{ - Lease: lease, - Cost: req.Cost, - }) - if err != nil { - errors.HandleError(ctx, fault.Wrap(err, fmsg.With("failed to commit lease"))) - return - - } - - svc.Sender.Send(ctx, w, 204, nil) - }) -} diff --git a/web/apps/agent/pkg/api/routes/v1_ratelimit_commitLease/handler_test.go b/web/apps/agent/pkg/api/routes/v1_ratelimit_commitLease/handler_test.go deleted file mode 100644 index 8756d482c0..0000000000 --- a/web/apps/agent/pkg/api/routes/v1_ratelimit_commitLease/handler_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package v1RatelimitCommitLease_test - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - v1RatelimitCommitLease "github.com/unkeyed/unkey/svc/agent/pkg/api/routes/v1_ratelimit_commitLease" - v1RatelimitRatelimit "github.com/unkeyed/unkey/svc/agent/pkg/api/routes/v1_ratelimit_ratelimit" - "github.com/unkeyed/unkey/svc/agent/pkg/api/testutil" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" - "github.com/unkeyed/unkey/svc/agent/pkg/uid" - "github.com/unkeyed/unkey/svc/agent/pkg/util" -) - -func TestCommitLease(t *testing.T) { - t.Skip() - h := testutil.NewHarness(t) - ratelimitRoute := h.SetupRoute(v1RatelimitRatelimit.New) - commitLeaseRoute := h.SetupRoute(v1RatelimitCommitLease.New) - - req := openapi.V1RatelimitRatelimitRequestBody{ - - Identifier: uid.New("test"), - Limit: 100, - Duration: time.Minute.Milliseconds(), - Cost: util.Pointer[int64](0), - Lease: &openapi.Lease{ - Cost: 10, - Timeout: 10 * time.Second.Milliseconds(), - }, - } - - res := testutil.CallRoute[openapi.V1RatelimitRatelimitRequestBody, openapi.V1RatelimitRatelimitResponseBody](t, ratelimitRoute, nil, req) - - require.Equal(t, 200, res.Status) - require.Equal(t, int64(100), res.Body.Limit) - require.Equal(t, int64(90), res.Body.Remaining) - require.Equal(t, true, res.Body.Success) - require.Equal(t, int64(10), res.Body.Current) - require.NotNil(t, res.Body.Lease) - - commitReq := openapi.V1RatelimitCommitLeaseRequestBody{ - Cost: 5, - Lease: res.Body.Lease, - } - - commitRes := testutil.CallRoute[openapi.V1RatelimitCommitLeaseRequestBody, any](t, commitLeaseRoute, nil, commitReq) - - require.Equal(t, 204, commitRes.Status) - -} diff --git a/web/apps/agent/pkg/api/routes/v1_ratelimit_multiRatelimit/handler.go b/web/apps/agent/pkg/api/routes/v1_ratelimit_multiRatelimit/handler.go deleted file mode 100644 index 291c1b5b9b..0000000000 --- a/web/apps/agent/pkg/api/routes/v1_ratelimit_multiRatelimit/handler.go +++ /dev/null @@ -1,55 +0,0 @@ -package v1RatelimitMultiRatelimit - -import ( - "net/http" - - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/api/errors" - "github.com/unkeyed/unkey/svc/agent/pkg/api/routes" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" -) - -func New(svc routes.Services) *routes.Route { - return routes.NewRoute("POST", "/ratelimit.v1.RatelimitService/MultiRatelimit", func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - req := &openapi.V1RatelimitMultiRatelimitRequestBody{} - res := &openapi.V1RatelimitMultiRatelimitResponseBody{} - - errorResponse, valid := svc.OpenApiValidator.Body(r, req) - if !valid { - svc.Sender.Send(ctx, w, 400, errorResponse) - return - } - ratelimits := make([]*ratelimitv1.RatelimitRequest, len(req.Ratelimits)) - for i, r := range req.Ratelimits { - cost := int64(1) - if r.Cost != nil { - cost = *r.Cost - } - ratelimits[i] = &ratelimitv1.RatelimitRequest{ - Identifier: r.Identifier, - Limit: r.Limit, - Duration: r.Duration, - Cost: cost, - } - } - svcRes, err := svc.Ratelimit.MultiRatelimit(ctx, &ratelimitv1.RatelimitMultiRequest{}) - if err != nil { - errors.HandleError(ctx, err) - return - - } - res.Ratelimits = make([]openapi.SingleRatelimitResponse, len(res.Ratelimits)) - for i, r := range svcRes.Ratelimits { - res.Ratelimits[i] = openapi.SingleRatelimitResponse{ - Current: r.Current, - Limit: r.Limit, - Remaining: r.Remaining, - Reset: r.Reset_, - Success: r.Success, - } - } - - svc.Sender.Send(ctx, w, 200, res) - }) -} diff --git a/web/apps/agent/pkg/api/routes/v1_ratelimit_ratelimit/handler.go b/web/apps/agent/pkg/api/routes/v1_ratelimit_ratelimit/handler.go deleted file mode 100644 index c2ac9d63f6..0000000000 --- a/web/apps/agent/pkg/api/routes/v1_ratelimit_ratelimit/handler.go +++ /dev/null @@ -1,69 +0,0 @@ -package v1RatelimitRatelimit - -import ( - "net/http" - - "github.com/btcsuite/btcutil/base58" - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/api/errors" - "github.com/unkeyed/unkey/svc/agent/pkg/api/routes" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" - "github.com/unkeyed/unkey/svc/agent/pkg/util" - "google.golang.org/protobuf/proto" -) - -func New(svc routes.Services) *routes.Route { - return routes.NewRoute("POST", "/ratelimit.v1.RatelimitService/Ratelimit", func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - req := &openapi.V1RatelimitRatelimitRequestBody{} - errorResponse, valid := svc.OpenApiValidator.Body(r, req) - if !valid { - svc.Sender.Send(ctx, w, 400, errorResponse) - return - } - - if req.Cost == nil { - req.Cost = util.Pointer[int64](1) - } - - var lease *ratelimitv1.LeaseRequest = nil - if req.Lease != nil { - lease = &ratelimitv1.LeaseRequest{ - Cost: req.Lease.Cost, - Timeout: req.Lease.Timeout, - } - } - - res, err := svc.Ratelimit.Ratelimit(ctx, &ratelimitv1.RatelimitRequest{ - Identifier: req.Identifier, - Limit: req.Limit, - Duration: req.Duration, - Cost: *req.Cost, - Lease: lease, - }) - if err != nil { - errors.HandleError(ctx, err) - return - } - - response := openapi.V1RatelimitRatelimitResponseBody{ - Limit: res.Limit, - Remaining: res.Remaining, - Reset: res.Reset_, - Success: res.Success, - Current: res.Current, - } - - if res.Lease != nil { - b, err := proto.Marshal(res.Lease) - if err != nil { - errors.HandleError(ctx, err) - return - } - response.Lease = base58.Encode(b) - } - - svc.Sender.Send(ctx, w, 200, response) - }) -} diff --git a/web/apps/agent/pkg/api/routes/v1_ratelimit_ratelimit/handler_test.go b/web/apps/agent/pkg/api/routes/v1_ratelimit_ratelimit/handler_test.go deleted file mode 100644 index 897701370b..0000000000 --- a/web/apps/agent/pkg/api/routes/v1_ratelimit_ratelimit/handler_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package v1RatelimitRatelimit_test - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - v1RatelimitRatelimit "github.com/unkeyed/unkey/svc/agent/pkg/api/routes/v1_ratelimit_ratelimit" - "github.com/unkeyed/unkey/svc/agent/pkg/api/testutil" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" - "github.com/unkeyed/unkey/svc/agent/pkg/uid" -) - -func TestRatelimit(t *testing.T) { - h := testutil.NewHarness(t) - route := h.SetupRoute(v1RatelimitRatelimit.New) - - req := openapi.V1RatelimitRatelimitRequestBody{ - Identifier: uid.New("test"), - Limit: 10, - Duration: 1000, - } - - resp := testutil.CallRoute[openapi.V1RatelimitRatelimitRequestBody, openapi.V1RatelimitRatelimitResponseBody](t, route, nil, req) - - require.Equal(t, 200, resp.Status) - require.Equal(t, int64(10), resp.Body.Limit) - require.Equal(t, int64(9), resp.Body.Remaining) - require.Equal(t, true, resp.Body.Success) - require.Equal(t, int64(1), resp.Body.Current) -} - -func TestRatelimitWithLease(t *testing.T) { - t.Skip() - h := testutil.NewHarness(t) - route := h.SetupRoute(v1RatelimitRatelimit.New) - - req := openapi.V1RatelimitRatelimitRequestBody{ - - Identifier: uid.New("test"), - Limit: 100, - Duration: time.Minute.Milliseconds(), - Lease: &openapi.Lease{ - Cost: 10, - Timeout: 10 * time.Second.Milliseconds(), - }, - } - resp := testutil.CallRoute[openapi.V1RatelimitRatelimitRequestBody, openapi.V1RatelimitRatelimitResponseBody](t, route, nil, req) - - require.Equal(t, 200, resp.Status) - require.Equal(t, int64(100), resp.Body.Limit) - require.Equal(t, int64(90), resp.Body.Remaining) - require.Equal(t, true, resp.Body.Success) - require.Equal(t, int64(10), resp.Body.Current) - require.NotNil(t, resp.Body.Lease) -} diff --git a/web/apps/agent/pkg/api/routes/v1_vault_decrypt/handler.go b/web/apps/agent/pkg/api/routes/v1_vault_decrypt/handler.go deleted file mode 100644 index 49bb55283e..0000000000 --- a/web/apps/agent/pkg/api/routes/v1_vault_decrypt/handler.go +++ /dev/null @@ -1,35 +0,0 @@ -package v1VaultDecrypt - -import ( - "net/http" - - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/api/errors" - "github.com/unkeyed/unkey/svc/agent/pkg/api/routes" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" -) - -func New(svc routes.Services) *routes.Route { - return routes.NewRoute("POST", "/vault.v1.VaultService/Decrypt", func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - req := &openapi.V1DecryptRequestBody{} - errorResponse, valid := svc.OpenApiValidator.Body(r, req) - if !valid { - svc.Sender.Send(ctx, w, 400, errorResponse) - return - } - res, err := svc.Vault.Decrypt(ctx, &vaultv1.DecryptRequest{ - Keyring: req.Keyring, - Encrypted: req.Encrypted, - }) - if err != nil { - errors.HandleError(ctx, fault.Wrap(err, fmsg.With("failed to decrypt"))) - } - - svc.Sender.Send(ctx, w, 200, openapi.V1DecryptResponseBody{ - Plaintext: res.Plaintext, - }) - }) -} diff --git a/web/apps/agent/pkg/api/routes/v1_vault_encrypt/handler.go b/web/apps/agent/pkg/api/routes/v1_vault_encrypt/handler.go deleted file mode 100644 index 8912e28d02..0000000000 --- a/web/apps/agent/pkg/api/routes/v1_vault_encrypt/handler.go +++ /dev/null @@ -1,36 +0,0 @@ -package v1VaultEncrypt - -import ( - "net/http" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/api/errors" - "github.com/unkeyed/unkey/svc/agent/pkg/api/routes" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" -) - -func New(svc routes.Services) *routes.Route { - return routes.NewRoute("POST", "/vault.v1.VaultService/Encrypt", - func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - req := &openapi.V1EncryptRequestBody{} - errorResponse, valid := svc.OpenApiValidator.Body(r, req) - if !valid { - svc.Sender.Send(ctx, w, 400, errorResponse) - return - } - res, err := svc.Vault.Encrypt(ctx, &vaultv1.EncryptRequest{ - Keyring: req.Keyring, - Data: req.Data, - }) - if err != nil { - errors.HandleError(ctx, err) - return - } - - svc.Sender.Send(ctx, w, 200, openapi.V1EncryptResponseBody{ - Encrypted: res.Encrypted, - KeyId: res.KeyId, - }) - }) -} diff --git a/web/apps/agent/pkg/api/routes/v1_vault_encrypt_bulk/handler.go b/web/apps/agent/pkg/api/routes/v1_vault_encrypt_bulk/handler.go deleted file mode 100644 index 58abf0559e..0000000000 --- a/web/apps/agent/pkg/api/routes/v1_vault_encrypt_bulk/handler.go +++ /dev/null @@ -1,45 +0,0 @@ -package v1VaultEncryptBulk - -import ( - "net/http" - - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/api/errors" - "github.com/unkeyed/unkey/svc/agent/pkg/api/routes" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" -) - -type Request = openapi.V1EncryptBulkRequestBody -type Response = openapi.V1EncryptBulkResponseBody - -func New(svc routes.Services) *routes.Route { - return routes.NewRoute("POST", "/vault.v1.VaultService/EncryptBulk", func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - req := Request{} - errorResponse, valid := svc.OpenApiValidator.Body(r, &req) - if !valid { - svc.Sender.Send(ctx, w, 400, errorResponse) - return - } - res, err := svc.Vault.EncryptBulk(ctx, &vaultv1.EncryptBulkRequest{ - Keyring: req.Keyring, - Data: req.Data, - }) - if err != nil { - errors.HandleError(ctx, fault.Wrap(err, fmsg.With("failed to encrypt"))) - return - } - - encrypted := make([]openapi.Encrypted, len(res.Encrypted)) - for i, e := range res.Encrypted { - encrypted[i] = openapi.Encrypted{ - Encrypted: e.Encrypted, - KeyId: e.KeyId, - } - } - - svc.Sender.Send(ctx, w, 200, Response{Encrypted: encrypted}) - }) -} diff --git a/web/apps/agent/pkg/api/server.go b/web/apps/agent/pkg/api/server.go deleted file mode 100644 index 96aad81797..0000000000 --- a/web/apps/agent/pkg/api/server.go +++ /dev/null @@ -1,119 +0,0 @@ -package api - -import ( - "net/http" - "sync" - "time" - - "github.com/unkeyed/unkey/svc/agent/pkg/api/validation" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/metrics" - "github.com/unkeyed/unkey/svc/agent/services/ratelimit" - "github.com/unkeyed/unkey/svc/agent/services/vault" -) - -type Server struct { - sync.Mutex - logger logging.Logger - metrics metrics.Metrics - isListening bool - mux *http.ServeMux - srv *http.Server - - // The bearer token required for inter service communication - authToken string - vault *vault.Service - ratelimit ratelimit.Service - - clickhouse EventBuffer - validator validation.OpenAPIValidator -} - -type Config struct { - NodeId string - Logger logging.Logger - Metrics metrics.Metrics - Ratelimit ratelimit.Service - Clickhouse EventBuffer - Vault *vault.Service - AuthToken string -} - -func New(config Config) (*Server, error) { - - mux := http.NewServeMux() - srv := &http.Server{ - Handler: mux, - // See https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/ - // - // > # http.ListenAndServe is doing it wrong - // > Incidentally, this means that the package-level convenience functions that bypass http.Server - // > like http.ListenAndServe, http.ListenAndServeTLS and http.Serve are unfit for public Internet - // > Servers. - // > - // > Those functions leave the Timeouts to their default off value, with no way of enabling them, - // > so if you use them you'll soon be leaking connections and run out of file descriptors. I've - // > made this mistake at least half a dozen times. - // > - // > Instead, create a http.Server instance with ReadTimeout and WriteTimeout and use its - // > corresponding methods, like in the example a few paragraphs above. - ReadTimeout: 10 * time.Second, - WriteTimeout: 20 * time.Second, - } - - s := &Server{ - logger: config.Logger, - metrics: config.Metrics, - ratelimit: config.Ratelimit, - vault: config.Vault, - isListening: false, - mux: mux, - srv: srv, - clickhouse: config.Clickhouse, - authToken: config.AuthToken, - } - // validationMiddleware, err := s.createOpenApiValidationMiddleware("./pkg/openapi/openapi.json") - // if err != nil { - // return nil, fault.Wrap(err, fmsg.With("openapi spec encountered an error")) - // } - // s.app.Use( - // createLoggerMiddleware(s.logger), - // createMetricsMiddleware(), - // // validationMiddleware, - // ) - // s.app.Use(tracingMiddleware) - v, err := validation.New() - if err != nil { - return nil, err - } - s.validator = v - - s.srv.Handler = withMetrics(withTracing(withRequestId(s.mux))) - - return s, nil -} - -// Calling this function multiple times will have no effect. -func (s *Server) Listen(addr string) error { - s.Lock() - if s.isListening { - s.logger.Warn().Msg("already listening") - s.Unlock() - return nil - } - s.isListening = true - s.Unlock() - s.RegisterRoutes() - - s.srv.Addr = addr - - s.logger.Info().Str("addr", addr).Msg("listening") - return s.srv.ListenAndServe() -} - -func (s *Server) Shutdown() error { - s.Lock() - defer s.Unlock() - return s.srv.Close() - -} diff --git a/web/apps/agent/pkg/api/testutil/harness.go b/web/apps/agent/pkg/api/testutil/harness.go deleted file mode 100644 index 4e7c43e864..0000000000 --- a/web/apps/agent/pkg/api/testutil/harness.go +++ /dev/null @@ -1,145 +0,0 @@ -package testutil - -import ( - "bytes" - "encoding/json" - "fmt" - "net/http" - "net/http/httptest" - "testing" - - "github.com/stretchr/testify/require" - "github.com/unkeyed/unkey/svc/agent/pkg/api/routes" - "github.com/unkeyed/unkey/svc/agent/pkg/api/validation" - "github.com/unkeyed/unkey/svc/agent/pkg/cluster" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/membership" - "github.com/unkeyed/unkey/svc/agent/pkg/metrics" - "github.com/unkeyed/unkey/svc/agent/pkg/port" - "github.com/unkeyed/unkey/svc/agent/pkg/uid" - "github.com/unkeyed/unkey/svc/agent/services/ratelimit" -) - -type Harness struct { - t *testing.T - - logger logging.Logger - metrics metrics.Metrics - - ratelimit ratelimit.Service - - mux *http.ServeMux -} - -func NewHarness(t *testing.T) *Harness { - mux := http.NewServeMux() - - p := port.New() - nodeId := uid.New("test") - authToken := uid.New("test") - serfAddr := fmt.Sprintf("localhost:%d", p.Get()) - rpcAddr := fmt.Sprintf("localhost:%d", p.Get()) - - h := Harness{ - t: t, - logger: logging.NewNoopLogger(), - metrics: metrics.NewNoop(), - mux: mux, - } - - memb, err := membership.New(membership.Config{ - NodeId: nodeId, - SerfAddr: serfAddr, - }) - require.NoError(t, err) - - c, err := cluster.New(cluster.Config{ - NodeId: nodeId, - Membership: memb, - Logger: h.logger, - Metrics: h.metrics, - AuthToken: authToken, - RpcAddr: rpcAddr, - }) - require.NoError(t, err) - rl, err := ratelimit.New(ratelimit.Config{ - Logger: h.logger, - Metrics: h.metrics, - Cluster: c, - }) - require.NoError(t, err) - h.ratelimit = rl - - return &h -} - -func (h *Harness) Register(route *routes.Route) { - - route.Register(h.mux) - -} - -func (h *Harness) SetupRoute(constructor func(svc routes.Services) *routes.Route) *routes.Route { - - validator, err := validation.New() - require.NoError(h.t, err) - route := constructor(routes.Services{ - Logger: h.logger, - Metrics: h.metrics, - Ratelimit: h.ratelimit, - Vault: nil, - OpenApiValidator: validator, - Sender: routes.NewJsonSender(h.logger), - }) - h.Register(route) - return route -} - -// Post is a helper function to make a POST request to the API. -// It will hanndle serializing the request and response objects to and from JSON. -func UnmarshalBody[Body any](t *testing.T, r *httptest.ResponseRecorder, body *Body) { - - err := json.Unmarshal(r.Body.Bytes(), &body) - require.NoError(t, err) - -} - -type TestResponse[TBody any] struct { - Status int - Headers http.Header - Body TBody -} - -func CallRoute[Req any, Res any](t *testing.T, route *routes.Route, headers http.Header, req Req) TestResponse[Res] { - t.Helper() - mux := http.NewServeMux() - route.Register(mux) - - rr := httptest.NewRecorder() - - body := new(bytes.Buffer) - err := json.NewEncoder(body).Encode(req) - require.NoError(t, err) - - httpReq := httptest.NewRequest(route.Method(), route.Path(), body) - httpReq.Header = headers - if httpReq.Header == nil { - httpReq.Header = http.Header{} - } - if route.Method() == http.MethodPost { - httpReq.Header.Set("Content-Type", "application/json") - } - - mux.ServeHTTP(rr, httpReq) - require.NoError(t, err) - - var res Res - err = json.NewDecoder(rr.Body).Decode(&res) - require.NoError(t, err) - - return TestResponse[Res]{ - Status: rr.Code, - Headers: rr.Header(), - Body: res, - } -} diff --git a/web/apps/agent/pkg/api/validation/validator.go b/web/apps/agent/pkg/api/validation/validator.go deleted file mode 100644 index cc7b6638e6..0000000000 --- a/web/apps/agent/pkg/api/validation/validator.go +++ /dev/null @@ -1,113 +0,0 @@ -package validation - -import ( - "bytes" - "encoding/json" - "io" - "net/http" - - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" - "github.com/pb33f/libopenapi" - validator "github.com/pb33f/libopenapi-validator" - "github.com/unkeyed/unkey/svc/agent/pkg/api/ctxutil" - "github.com/unkeyed/unkey/svc/agent/pkg/openapi" - "github.com/unkeyed/unkey/svc/agent/pkg/util" -) - -type OpenAPIValidator interface { - Body(r *http.Request, dest any) (openapi.ValidationError, bool) -} - -type Validator struct { - validator validator.Validator -} - -func New() (*Validator, error) { - - document, err := libopenapi.NewDocument(openapi.Spec) - if err != nil { - return nil, fault.Wrap(err, fmsg.With("failed to create OpenAPI document")) - } - - v, errors := validator.NewValidator(document) - if len(errors) > 0 { - messages := make([]fault.Wrapper, len(errors)) - for i, e := range errors { - messages[i] = fmsg.With(e.Error()) - } - return nil, fault.New("failed to create validator", messages...) - } - return &Validator{ - validator: v, - }, nil -} - -// Body reads the request body and validates it against the OpenAPI spec -// The body is closed after reading. -// Returns a ValidationError if the body is invalid that should be marshalled and returned to the client. -// The second return value is a boolean that is true if the body is valid. -func (v *Validator) Body(r *http.Request, dest any) (openapi.ValidationError, bool) { - - bodyBytes, err := io.ReadAll(r.Body) - r.Body.Close() - if err != nil { - return openapi.ValidationError{ - Title: "Bad Request", - Detail: "Failed to read request body", - Errors: []openapi.ValidationErrorDetail{{ - Location: "body", - Message: err.Error(), - }}, - Instance: "https://errors.unkey.com/todo", - Status: http.StatusBadRequest, - RequestId: ctxutil.GetRequestID(r.Context()), - }, false - } - r.Body = io.NopCloser(bytes.NewReader(bodyBytes)) - - valid, errors := v.validator.ValidateHttpRequest(r) - - if !valid { - valErr := openapi.ValidationError{ - Title: "Bad Request", - Detail: "One or more fields failed validation", - Instance: "https://errors.unkey.com/todo", - Status: http.StatusBadRequest, - RequestId: ctxutil.GetRequestID(r.Context()), - Type: "TODO docs link", - Errors: []openapi.ValidationErrorDetail{}, - } - for _, e := range errors { - - for _, schemaValidationError := range e.SchemaValidationErrors { - valErr.Errors = append(valErr.Errors, openapi.ValidationErrorDetail{ - Location: schemaValidationError.Location, - Message: schemaValidationError.Reason, - }) - } - } - return valErr, false - } - - err = json.Unmarshal(bodyBytes, dest) - - if err != nil { - return openapi.ValidationError{ - Title: "Bad Request", - Detail: "Failed to parse request body as JSON", - Errors: []openapi.ValidationErrorDetail{{ - Location: "body", - Message: err.Error(), - Fix: util.Pointer("Ensure the request body is valid JSON"), - }}, - Instance: "https://errors.unkey.com/todo", - Status: http.StatusBadRequest, - RequestId: ctxutil.GetRequestID(r.Context()), - Type: "TODO docs link", - }, false - } - - return openapi.ValidationError{}, true - -} diff --git a/web/apps/agent/pkg/auth/authorization.go b/web/apps/agent/pkg/auth/authorization.go deleted file mode 100644 index a0d0d9a551..0000000000 --- a/web/apps/agent/pkg/auth/authorization.go +++ /dev/null @@ -1,27 +0,0 @@ -package auth - -import ( - "context" - "crypto/subtle" - "errors" - "strings" -) - -var ( - ErrMissingBearerToken = errors.New("missing bearer token") - ErrUnauthorized = errors.New("unauthorized") -) - -func Authorize(ctx context.Context, authToken, authorizationHeader string) error { - - if authorizationHeader == "" { - return ErrMissingBearerToken - } - - for _, token := range strings.Split(authToken, ",") { - if subtle.ConstantTimeCompare([]byte(strings.TrimPrefix(authorizationHeader, "Bearer ")), []byte(token)) == 1 { - return nil - } - } - return ErrUnauthorized -} diff --git a/web/apps/agent/pkg/batch/consume.go b/web/apps/agent/pkg/batch/consume.go deleted file mode 100644 index 4971479642..0000000000 --- a/web/apps/agent/pkg/batch/consume.go +++ /dev/null @@ -1,49 +0,0 @@ -package batch - -import ( - "context" - "time" -) - -// Process batches items and flushes them in a new goroutine. -// flush is called when the batch is full or the interval has elapsed and needs to be implemented by the caller. -// it must handle all errors itself and must not panic. -// -// Process returns a channel that can be used to send items to be batched. -func Process[T any](flush func(ctx context.Context, batch []T), size int, interval time.Duration) chan<- T { - - c := make(chan T) - - batch := make([]T, 0, size) - ticker := time.NewTicker(interval) - - flushAndReset := func() { - if len(batch) > 0 { - flush(context.Background(), batch) - batch = batch[:0] - } - ticker.Reset(interval) - } - - go func() { - for { - select { - case e, ok := <-c: - if !ok { - // channel closed - flush(context.Background(), batch) - break - } - batch = append(batch, e) - if len(batch) >= size { - flushAndReset() - - } - case <-ticker.C: - flushAndReset() - } - } - }() - - return c -} diff --git a/web/apps/agent/pkg/batch/metrics.go b/web/apps/agent/pkg/batch/metrics.go deleted file mode 100644 index 7c2342622c..0000000000 --- a/web/apps/agent/pkg/batch/metrics.go +++ /dev/null @@ -1,17 +0,0 @@ -package batch - -import ( - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" -) - -var ( - // droppedMessages tracks the number of messages dropped due to a full buffer - // for each BatchProcessor instance. The "name" label identifies the specific - // BatchProcessor. - droppedMessages = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: "agent", - Subsystem: "batch", - Name: "dropped_messages", - }, []string{"name"}) -) diff --git a/web/apps/agent/pkg/batch/process.go b/web/apps/agent/pkg/batch/process.go deleted file mode 100644 index 6c1a633084..0000000000 --- a/web/apps/agent/pkg/batch/process.go +++ /dev/null @@ -1,102 +0,0 @@ -package batch - -import ( - "context" - "time" -) - -type BatchProcessor[T any] struct { - name string - drop bool - buffer chan T - batch []T - config Config[T] - flush func(ctx context.Context, batch []T) -} - -type Config[T any] struct { - // drop events if the buffer is full - Drop bool - Name string - BatchSize int - BufferSize int - FlushInterval time.Duration - Flush func(ctx context.Context, batch []T) - // How many goroutine workers should be processing the channel - // defaults to 1 - Consumers int -} - -func New[T any](config Config[T]) *BatchProcessor[T] { - if config.Consumers <= 0 { - config.Consumers = 1 - } - - bp := &BatchProcessor[T]{ - name: config.Name, - drop: config.Drop, - buffer: make(chan T, config.BufferSize), - batch: make([]T, 0, config.BatchSize), - flush: config.Flush, - config: config, - } - - for _ = range bp.config.Consumers { - go bp.process() - } - - return bp -} - -func (bp *BatchProcessor[T]) process() { - t := time.NewTimer(bp.config.FlushInterval) - flushAndReset := func() { - if len(bp.batch) > 0 { - bp.flush(context.Background(), bp.batch) - bp.batch = bp.batch[:0] - } - t.Reset(bp.config.FlushInterval) - } - for { - select { - case e, ok := <-bp.buffer: - if !ok { - // channel closed - if len(bp.batch) > 0 { - bp.flush(context.Background(), bp.batch) - bp.batch = bp.batch[:0] - } - t.Stop() - return - } - bp.batch = append(bp.batch, e) - if len(bp.batch) >= int(bp.config.BatchSize) { - flushAndReset() - - } - case <-t.C: - flushAndReset() - } - } -} - -func (bp *BatchProcessor[T]) Size() int { - return len(bp.buffer) -} - -func (bp *BatchProcessor[T]) Buffer(t T) { - if bp.drop { - - select { - case bp.buffer <- t: - default: - droppedMessages.WithLabelValues(bp.name).Inc() - } - } else { - bp.buffer <- t - } -} - -func (bp *BatchProcessor[T]) Close() { - close(bp.buffer) -} diff --git a/web/apps/agent/pkg/cache/cache.go b/web/apps/agent/pkg/cache/cache.go deleted file mode 100644 index 819009aa87..0000000000 --- a/web/apps/agent/pkg/cache/cache.go +++ /dev/null @@ -1,201 +0,0 @@ -package cache - -import ( - "context" - "encoding/json" - "fmt" - "time" - - "github.com/maypok86/otter" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/metrics" - "github.com/unkeyed/unkey/svc/agent/pkg/prometheus" - "github.com/unkeyed/unkey/svc/agent/pkg/repeat" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "go.opentelemetry.io/otel/attribute" - - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" -) - -type cache[T any] struct { - otter otter.Cache[string, swrEntry[T]] - fresh time.Duration - stale time.Duration - refreshFromOrigin func(ctx context.Context, identifier string) (data T, ok bool) - // If a key is stale, its identifier will be put into this channel and a goroutine refreshes it in the background - refreshC chan string - metrics metrics.Metrics - logger logging.Logger - resource string -} - -type Config[T any] struct { - // How long the data is considered fresh - // Subsequent requests in this time will try to use the cache - Fresh time.Duration - - // Subsequent requests that are not fresh but within the stale time will return cached data but also trigger - // fetching from the origin server - Stale time.Duration - - // A handler that will be called to refetch data from the origin when necessary - RefreshFromOrigin func(ctx context.Context, identifier string) (data T, ok bool) - - Logger logging.Logger - Metrics metrics.Metrics - - // Start evicting the least recently used entry when the cache grows to MaxSize - MaxSize int - - Resource string -} - -func New[T any](config Config[T]) (*cache[T], error) { - - builder, err := otter.NewBuilder[string, swrEntry[T]](config.MaxSize) - if err != nil { - return nil, fault.Wrap(err, fmsg.With("failed to create otter builder")) - } - - otter, err := builder.CollectStats().Cost(func(key string, value swrEntry[T]) uint32 { - return 1 - }).WithTTL(time.Hour).Build() - if err != nil { - return nil, fault.Wrap(err, fmsg.With("failed to create otter cache")) - } - - c := &cache[T]{ - otter: otter, - fresh: config.Fresh, - stale: config.Stale, - refreshFromOrigin: config.RefreshFromOrigin, - refreshC: make(chan string, 1000), - logger: config.Logger, - metrics: config.Metrics, - resource: config.Resource, - } - - go c.runRefreshing() - repeat.Every(5*time.Second, func() { - prometheus.CacheEntries.WithLabelValues(c.resource).Set(float64(c.otter.Size())) - prometheus.CacheRejected.WithLabelValues(c.resource).Set(float64(c.otter.Stats().EvictedCount())) - }) - - return c, nil - -} - -func (c cache[T]) Get(ctx context.Context, key string) (value T, hit CacheHit) { - - e, ok := c.otter.Get(key) - if !ok { - // This hack is necessary because you can not return nil as T - var t T - return t, Miss - } - - now := time.Now() - - if now.Before(e.Fresh) { - - return e.Value, e.Hit - - } - if now.Before(e.Stale) { - c.refreshC <- key - - return e.Value, e.Hit - } - - c.otter.Delete(key) - - var t T - return t, Miss - -} - -func (c cache[T]) SetNull(ctx context.Context, key string) { - c.set(ctx, key) -} - -func (c cache[T]) Set(ctx context.Context, key string, value T) { - c.set(ctx, key, value) -} -func (c cache[T]) set(ctx context.Context, key string, value ...T) { - now := time.Now() - - e := swrEntry[T]{ - Value: value[0], - Fresh: now.Add(c.fresh), - Stale: now.Add(c.stale), - } - if len(value) > 0 { - e.Value = value[0] - e.Hit = Hit - } else { - e.Hit = Miss - } - c.otter.Set(key, e) - -} - -func (c cache[T]) Remove(ctx context.Context, key string) { - - c.otter.Delete(key) - -} - -func (c cache[T]) Dump(ctx context.Context) ([]byte, error) { - data := make(map[string]swrEntry[T]) - - c.otter.Range(func(key string, entry swrEntry[T]) bool { - data[key] = entry - return true - }) - - return json.Marshal(data) - -} - -func (c cache[T]) Restore(ctx context.Context, b []byte) error { - - data := make(map[string]swrEntry[T]) - err := json.Unmarshal(b, &data) - if err != nil { - return fmt.Errorf("failed to unmarshal cache data: %w", err) - } - now := time.Now() - for key, entry := range data { - if now.Before(entry.Fresh) { - c.Set(ctx, key, entry.Value) - } else if now.Before(entry.Stale) { - c.refreshC <- key - } - // If the entry is older than, we don't restore it - } - return nil -} - -func (c cache[T]) Clear(ctx context.Context) { - c.otter.Clear() -} - -func (c cache[T]) runRefreshing() { - for { - identifier := <-c.refreshC - - ctx, span := tracing.Start(context.Background(), tracing.NewSpanName(fmt.Sprintf("cache.%s", c.resource), "refresh")) - span.SetAttributes(attribute.String("identifier", identifier)) - t, ok := c.refreshFromOrigin(ctx, identifier) - if !ok { - span.AddEvent("identifier not found in origin") - c.logger.Warn().Str("identifier", identifier).Msg("origin couldn't find") - span.End() - continue - } - c.Set(ctx, identifier, t) - span.End() - } - -} diff --git a/web/apps/agent/pkg/cache/cache_test.go b/web/apps/agent/pkg/cache/cache_test.go deleted file mode 100644 index 0788273835..0000000000 --- a/web/apps/agent/pkg/cache/cache_test.go +++ /dev/null @@ -1,106 +0,0 @@ -package cache_test - -import ( - "context" - "sync/atomic" - "testing" - "time" - - "github.com/stretchr/testify/require" - - "github.com/unkeyed/unkey/svc/agent/pkg/cache" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/metrics" -) - -func TestWriteRead(t *testing.T) { - - c, err := cache.New[string](cache.Config[string]{ - MaxSize: 10_000, - - Fresh: time.Minute, - Stale: time.Minute * 5, - RefreshFromOrigin: func(ctx context.Context, id string) (string, bool) { - return "hello", true - }, - Logger: logging.NewNoopLogger(), - Metrics: metrics.NewNoop(), - }) - require.NoError(t, err) - c.Set(context.Background(), "key", "value") - value, hit := c.Get(context.Background(), "key") - require.Equal(t, cache.Hit, hit) - require.Equal(t, "value", value) -} - -func TestEviction(t *testing.T) { - - c, err := cache.New[string](cache.Config[string]{ - MaxSize: 10_000, - - Fresh: time.Second, - Stale: time.Second, - RefreshFromOrigin: func(ctx context.Context, id string) (string, bool) { - return "hello", true - }, - Logger: logging.NewNoopLogger(), - Metrics: metrics.NewNoop(), - }) - require.NoError(t, err) - - c.Set(context.Background(), "key", "value") - time.Sleep(time.Second * 2) - _, hit := c.Get(context.Background(), "key") - require.Equal(t, cache.Miss, hit) -} - -func TestRefresh(t *testing.T) { - - // count how many times we refreshed from origin - refreshedFromOrigin := atomic.Int32{} - - c, err := cache.New[string](cache.Config[string]{ - MaxSize: 10_000, - - Fresh: time.Second * 2, - Stale: time.Minute * 5, - RefreshFromOrigin: func(ctx context.Context, id string) (string, bool) { - refreshedFromOrigin.Add(1) - return "hello", true - }, - Logger: logging.NewNoopLogger(), - Metrics: metrics.NewNoop(), - }) - require.NoError(t, err) - - c.Set(context.Background(), "key", "value") - time.Sleep(time.Second * 1) - for i := 0; i < 10; i++ { - _, hit := c.Get(context.Background(), "key") - require.Equal(t, cache.Hit, hit) - time.Sleep(time.Second) - } - - time.Sleep(5 * time.Second) - - require.Equal(t, int32(5), refreshedFromOrigin.Load()) - -} - -func TestNull(t *testing.T) { - t.Skip() - - c, err := cache.New[string](cache.Config[string]{ - MaxSize: 10_000, - Fresh: time.Second * 1, - Stale: time.Minute * 5, - Logger: logging.NewNoopLogger(), - }) - require.NoError(t, err) - - c.SetNull(context.Background(), "key") - - _, hit := c.Get(context.Background(), "key") - require.Equal(t, cache.Null, hit) - -} diff --git a/web/apps/agent/pkg/cache/entry.go b/web/apps/agent/pkg/cache/entry.go deleted file mode 100644 index 74270ecc42..0000000000 --- a/web/apps/agent/pkg/cache/entry.go +++ /dev/null @@ -1,18 +0,0 @@ -package cache - -import ( - "container/list" - "time" -) - -type swrEntry[T any] struct { - Value T `json:"value"` - - Hit CacheHit `json:"hit"` - // Before this time the entry is considered fresh and vaid - Fresh time.Time `json:"fresh"` - // Before this time, the entry should be revalidated - // After this time, the entry must be discarded - Stale time.Time `json:"stale"` - LruElement *list.Element `json:"-"` -} diff --git a/web/apps/agent/pkg/cache/interface.go b/web/apps/agent/pkg/cache/interface.go deleted file mode 100644 index 3bdfc2b287..0000000000 --- a/web/apps/agent/pkg/cache/interface.go +++ /dev/null @@ -1,41 +0,0 @@ -package cache - -import ( - "context" -) - -type Cache[T any] interface { - // Get returns the value for the given key. - // If the key is not found, found will be false. - Get(ctx context.Context, key string) (value T, hit CacheHit) - - // Sets the value for the given key. - Set(ctx context.Context, key string, value T) - - // Sets the given key to null, indicating that the value does not exist in the origin. - SetNull(ctx context.Context, key string) - - // Removes the key from the cache. - Remove(ctx context.Context, key string) - - // Dump returns a serialized representation of the cache. - Dump(ctx context.Context) ([]byte, error) - - // Restore restores the cache from a serialized representation. - Restore(ctx context.Context, data []byte) error - - // Clear removes all entries from the cache. - Clear(ctx context.Context) -} - -type CacheHit int - -const ( - Null CacheHit = iota - // The entry was in the cache and can be used - Hit - // The entry was not in the cache - Miss - // The entry did not exist in the origin - -) diff --git a/web/apps/agent/pkg/cache/middleware.go b/web/apps/agent/pkg/cache/middleware.go deleted file mode 100644 index 971d7b1c1d..0000000000 --- a/web/apps/agent/pkg/cache/middleware.go +++ /dev/null @@ -1,3 +0,0 @@ -package cache - -type Middleware[T any] func(Cache[T]) Cache[T] diff --git a/web/apps/agent/pkg/cache/middleware/metrics.go b/web/apps/agent/pkg/cache/middleware/metrics.go deleted file mode 100644 index ff79d5d217..0000000000 --- a/web/apps/agent/pkg/cache/middleware/metrics.go +++ /dev/null @@ -1,66 +0,0 @@ -package middleware - -import ( - "context" - "time" - - "github.com/unkeyed/unkey/svc/agent/pkg/cache" - "github.com/unkeyed/unkey/svc/agent/pkg/metrics" - "github.com/unkeyed/unkey/svc/agent/pkg/prometheus" -) - -type metricsMiddleware[T any] struct { - next cache.Cache[T] - metrics metrics.Metrics - resource string - tier string -} - -func WithMetrics[T any](c cache.Cache[T], m metrics.Metrics, resource string, tier string) cache.Cache[T] { - return &metricsMiddleware[T]{next: c, metrics: m, resource: resource, tier: tier} -} - -func (mw *metricsMiddleware[T]) Get(ctx context.Context, key string) (T, cache.CacheHit) { - start := time.Now() - value, hit := mw.next.Get(ctx, key) - - labels := map[string]string{ - "key": key, - "resource": mw.resource, - "tier": mw.tier, - } - - if hit == cache.Miss { - prometheus.CacheMisses.With(labels).Inc() - } else { - prometheus.CacheHits.With(labels).Inc() - } - prometheus.CacheLatency.With(labels).Observe(time.Since(start).Seconds()) - - return value, hit -} -func (mw *metricsMiddleware[T]) Set(ctx context.Context, key string, value T) { - mw.next.Set(ctx, key, value) - -} -func (mw *metricsMiddleware[T]) SetNull(ctx context.Context, key string) { - mw.next.SetNull(ctx, key) - -} -func (mw *metricsMiddleware[T]) Remove(ctx context.Context, key string) { - - mw.next.Remove(ctx, key) - -} - -func (mw *metricsMiddleware[T]) Dump(ctx context.Context) ([]byte, error) { - return mw.next.Dump(ctx) -} - -func (mw *metricsMiddleware[T]) Restore(ctx context.Context, data []byte) error { - return mw.next.Restore(ctx, data) -} - -func (mw *metricsMiddleware[T]) Clear(ctx context.Context) { - mw.next.Clear(ctx) -} diff --git a/web/apps/agent/pkg/cache/middleware/tracing.go b/web/apps/agent/pkg/cache/middleware/tracing.go deleted file mode 100644 index 83b3337384..0000000000 --- a/web/apps/agent/pkg/cache/middleware/tracing.go +++ /dev/null @@ -1,74 +0,0 @@ -package middleware - -import ( - "context" - - "github.com/unkeyed/unkey/svc/agent/pkg/cache" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "go.opentelemetry.io/otel/attribute" -) - -type tracingMiddleware[T any] struct { - next cache.Cache[T] -} - -func WithTracing[T any](c cache.Cache[T]) cache.Cache[T] { - return &tracingMiddleware[T]{next: c} -} - -func (mw *tracingMiddleware[T]) Get(ctx context.Context, key string) (T, cache.CacheHit) { - ctx, span := tracing.Start(ctx, "cache.Get") - defer span.End() - span.SetAttributes(attribute.String("key", key)) - - value, hit := mw.next.Get(ctx, key) - span.SetAttributes( - attribute.Bool("hit", hit != cache.Miss), - ) - return value, hit -} -func (mw *tracingMiddleware[T]) Set(ctx context.Context, key string, value T) { - ctx, span := tracing.Start(ctx, "cache.Set") - defer span.End() - span.SetAttributes(attribute.String("key", key)) - - mw.next.Set(ctx, key, value) - -} -func (mw *tracingMiddleware[T]) SetNull(ctx context.Context, key string) { - ctx, span := tracing.Start(ctx, "cache.SetNull") - defer span.End() - - span.SetAttributes(attribute.String("key", key)) - mw.next.SetNull(ctx, key) - -} -func (mw *tracingMiddleware[T]) Remove(ctx context.Context, key string) { - ctx, span := tracing.Start(ctx, "cache.Remove") - defer span.End() - span.SetAttributes(attribute.String("key", key)) - - mw.next.Remove(ctx, key) - -} - -func (mw *tracingMiddleware[T]) Dump(ctx context.Context) ([]byte, error) { - ctx, span := tracing.Start(ctx, "cache.Dump") - defer span.End() - - return mw.next.Dump(ctx) -} - -func (mw *tracingMiddleware[T]) Restore(ctx context.Context, data []byte) error { - ctx, span := tracing.Start(ctx, "cache.Restore") - defer span.End() - - return mw.next.Restore(ctx, data) -} - -func (mw *tracingMiddleware[T]) Clear(ctx context.Context) { - ctx, span := tracing.Start(ctx, "cache.Clear") - defer span.End() - - mw.next.Clear(ctx) -} diff --git a/web/apps/agent/pkg/cache/noop.go b/web/apps/agent/pkg/cache/noop.go deleted file mode 100644 index 8e3e94c1bd..0000000000 --- a/web/apps/agent/pkg/cache/noop.go +++ /dev/null @@ -1,28 +0,0 @@ -package cache - -import ( - "context" -) - -type noopCache[T any] struct{} - -func (c *noopCache[T]) Get(ctx context.Context, key string) (value T, hit CacheHit) { - var t T - return t, Miss -} -func (c *noopCache[T]) Set(ctx context.Context, key string, value T) {} -func (c *noopCache[T]) SetNull(ctx context.Context, key string) {} - -func (c *noopCache[T]) Remove(ctx context.Context, key string) {} - -func (c *noopCache[T]) Dump(ctx context.Context) ([]byte, error) { - return []byte{}, nil -} -func (c *noopCache[T]) Restore(ctx context.Context, data []byte) error { - return nil -} -func (c *noopCache[T]) Clear(ctx context.Context) {} - -func NewNoopCache[T any]() Cache[T] { - return &noopCache[T]{} -} diff --git a/web/apps/agent/pkg/cache/util.go b/web/apps/agent/pkg/cache/util.go deleted file mode 100644 index 3f703d6755..0000000000 --- a/web/apps/agent/pkg/cache/util.go +++ /dev/null @@ -1,33 +0,0 @@ -package cache - -import ( - "context" -) - -// withCache builds a pullthrough cache function to wrap a database call. -// Example: -// api, found, err := withCache(s.apiCache, s.db.FindApiByKeyAuthId)(ctx, key.KeyAuthId) -func WithCache[T any](c Cache[T], loadFromDatabase func(ctx context.Context, identifier string) (T, bool, error)) func(ctx context.Context, identifier string) (T, bool, error) { - return func(ctx context.Context, identifier string) (T, bool, error) { - value, hit := c.Get(ctx, identifier) - - if hit == Hit { - return value, true, nil - } - if hit == Null { - return value, false, nil - } - - value, found, err := loadFromDatabase(ctx, identifier) - if err != nil { - return value, false, err - } - if found { - c.Set(ctx, identifier, value) - return value, true, nil - } else { - c.SetNull(ctx, identifier) - return value, false, nil - } - } -} diff --git a/web/apps/agent/pkg/circuitbreaker/interface.go b/web/apps/agent/pkg/circuitbreaker/interface.go deleted file mode 100644 index bc1332ae59..0000000000 --- a/web/apps/agent/pkg/circuitbreaker/interface.go +++ /dev/null @@ -1,29 +0,0 @@ -package circuitbreaker - -import ( - "context" - "errors" -) - -type State string - -var ( - // Open state means the circuit breaker is open and requests are not allowed - // to pass through - Open State = "open" - // HalfOpen state means the circuit breaker is in a state of testing the - // upstream service to see if it has recovered - HalfOpen State = "halfopen" - // Closed state means the circuit breaker is allowing requests to pass - // through to the upstream service - Closed State = "closed" -) - -var ( - ErrTripped = errors.New("circuit breaker is open") - ErrTooManyRequests = errors.New("too many requests during half open state") -) - -type CircuitBreaker[Res any] interface { - Do(ctx context.Context, fn func(context.Context) (Res, error)) (Res, error) -} diff --git a/web/apps/agent/pkg/circuitbreaker/lib.go b/web/apps/agent/pkg/circuitbreaker/lib.go deleted file mode 100644 index 28f9d2126c..0000000000 --- a/web/apps/agent/pkg/circuitbreaker/lib.go +++ /dev/null @@ -1,227 +0,0 @@ -package circuitbreaker - -import ( - "context" - "fmt" - "sync" - "time" - - "github.com/unkeyed/unkey/svc/agent/pkg/clock" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" -) - -type CB[Res any] struct { - sync.Mutex - // This is a pointer to the configuration of the circuit breaker because we - // need to modify the clock for testing - config *config - - logger logging.Logger - - // State of the circuit - state State - - // reset the counters every cyclic period - resetCountersAt time.Time - - // reset the state every recoveryTimeout - resetStateAt time.Time - - // counters are protected by the mutex and are reset every cyclic period - requests int - successes int - failures int - consecutiveSuccesses int - consecutiveFailures int -} - -type config struct { - name string - // Max requests that may pass through the circuit breaker in its half-open state - // If all requests are successful, the circuit will close - // If any request fails, the circuit will remaing half open until the next cycle - maxRequests int - - // Interval to clear counts while the circuit is closed - cyclicPeriod time.Duration - - // How long the circuit will stay open before transitioning to half-open - timeout time.Duration - - // Determine whether the error is a downstream error or not - // If the error is a downstream error, the circuit will count it - // If the error is not a downstream error, the circuit will not count it - isDownstreamError func(error) bool - - // How many downstream errors within a cyclic period are allowed before the - // circuit trips and opens - tripThreshold int - - // Clock to use for timing, defaults to the system clock but can be overridden for testing - clock clock.Clock - - logger logging.Logger -} - -func WithMaxRequests(maxRequests int) applyConfig { - return func(c *config) { - c.maxRequests = maxRequests - } -} - -func WithCyclicPeriod(cyclicPeriod time.Duration) applyConfig { - return func(c *config) { - c.cyclicPeriod = cyclicPeriod - } -} -func WithIsDownstreamError(isDownstreamError func(error) bool) applyConfig { - return func(c *config) { - c.isDownstreamError = isDownstreamError - } -} -func WithTripThreshold(tripThreshold int) applyConfig { - return func(c *config) { - c.tripThreshold = tripThreshold - } -} - -func WithTimeout(timeout time.Duration) applyConfig { - return func(c *config) { - c.timeout = timeout - } -} - -// for testing -func WithClock(clock clock.Clock) applyConfig { - return func(c *config) { - c.clock = clock - } -} - -func WithLogger(logger logging.Logger) applyConfig { - return func(c *config) { - c.logger = logger - } -} - -// applyConfig applies a config setting to the circuit breaker -type applyConfig func(*config) - -func New[Res any](name string, applyConfigs ...applyConfig) *CB[Res] { - - cfg := &config{ - name: name, - maxRequests: 10, - cyclicPeriod: 5 * time.Second, - timeout: time.Minute, - isDownstreamError: func(err error) bool { - return err != nil - }, - tripThreshold: 5, - clock: clock.New(), - logger: logging.New(nil), - } - - for _, apply := range applyConfigs { - apply(cfg) - } - - cb := &CB[Res]{ - config: cfg, - logger: cfg.logger, - state: Closed, - resetCountersAt: cfg.clock.Now().Add(cfg.cyclicPeriod), - resetStateAt: cfg.clock.Now().Add(cfg.timeout), - } - - return cb -} - -var _ CircuitBreaker[any] = &CB[any]{} - -func (cb *CB[Res]) Do(ctx context.Context, fn func(context.Context) (Res, error)) (res Res, err error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName(fmt.Sprintf("circuitbreaker.%s", cb.config.name), "Do")) - defer span.End() - - err = cb.preflight(ctx) - if err != nil { - return res, err - } - - ctx, fnSpan := tracing.Start(ctx, tracing.NewSpanName(fmt.Sprintf("circuitbreaker.%s", cb.config.name), "fn")) - res, err = fn(ctx) - fnSpan.End() - - cb.postflight(ctx, err) - - return res, err - -} - -// preflight checks if the circuit is ready to accept a request -func (cb *CB[Res]) preflight(ctx context.Context) error { - ctx, span := tracing.Start(ctx, tracing.NewSpanName(fmt.Sprintf("circuitbreaker.%s", cb.config.name), "preflight")) - defer span.End() - cb.Lock() - defer cb.Unlock() - - now := cb.config.clock.Now() - - if now.After(cb.resetCountersAt) { - cb.requests = 0 - cb.successes = 0 - cb.failures = 0 - cb.consecutiveSuccesses = 0 - cb.consecutiveFailures = 0 - cb.resetCountersAt = now.Add(cb.config.cyclicPeriod) - } - if cb.state == Open && now.After(cb.resetStateAt) { - cb.state = HalfOpen - cb.resetStateAt = now.Add(cb.config.timeout) - } - - requests.WithLabelValues(cb.config.name, string(cb.state)).Inc() - - if cb.state == Open { - return ErrTripped - } - - cb.logger.Debug().Str("state", string(cb.state)).Int("requests", cb.requests).Int("maxRequests", cb.config.maxRequests).Msg("circuit breaker state") - if cb.state == HalfOpen && cb.requests >= cb.config.maxRequests { - return ErrTooManyRequests - } - return nil -} - -// postflight updates the circuit breaker state based on the result of the request -func (cb *CB[Res]) postflight(ctx context.Context, err error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName(fmt.Sprintf("circuitbreaker.%s", cb.config.name), "postflight")) - defer span.End() - cb.Lock() - defer cb.Unlock() - cb.requests++ - if cb.config.isDownstreamError(err) { - cb.failures++ - cb.consecutiveFailures++ - cb.consecutiveSuccesses = 0 - } else { - cb.successes++ - cb.consecutiveSuccesses++ - cb.consecutiveFailures = 0 - } - - switch cb.state { - - case Closed: - if cb.failures >= cb.config.tripThreshold { - cb.state = Open - } - - case HalfOpen: - if cb.consecutiveSuccesses >= cb.config.maxRequests { - cb.state = Closed - } - } - -} diff --git a/web/apps/agent/pkg/circuitbreaker/lib_test.go b/web/apps/agent/pkg/circuitbreaker/lib_test.go deleted file mode 100644 index 4aa62dd808..0000000000 --- a/web/apps/agent/pkg/circuitbreaker/lib_test.go +++ /dev/null @@ -1,93 +0,0 @@ -package circuitbreaker - -import ( - "context" - "errors" - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/unkeyed/unkey/svc/agent/pkg/clock" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" -) - -var errTestDownstream = errors.New("downstream test error") - -func TestCircuitBreakerStates(t *testing.T) { - - c := clock.NewTestClock() - cb := New[int]("test", WithCyclicPeriod(5*time.Second), WithClock(c), WithTripThreshold(3), WithLogger(logging.New(nil))) - - // Test Closed State - for i := 0; i < 3; i++ { - _, err := cb.Do(context.Background(), func(ctx context.Context) (int, error) { - return 0, errTestDownstream - }) - require.ErrorIs(t, err, errTestDownstream) - } - require.Equal(t, Open, cb.state) - - // Test Open State - _, err := cb.Do(context.Background(), func(ctx context.Context) (int, error) { - return 0, errTestDownstream - }) - require.ErrorIs(t, err, ErrTripped) - require.Equal(t, Open, cb.state) - - // Test Half-Open State - c.Tick(2 * time.Minute) // Advance time to reset - _, err = cb.Do(context.Background(), func(ctx context.Context) (int, error) { - return 42, nil - }) - require.NoError(t, err) - require.Equal(t, HalfOpen, cb.state) -} - -func TestCircuitBreakerReset(t *testing.T) { - - c := clock.NewTestClock() - cb := New[int]("test", WithCyclicPeriod(5*time.Second), WithClock(c), WithTripThreshold(3), WithTimeout(20*time.Second)) - - // Trigger circuit breaker to open - for i := 0; i < 3; i++ { - _, err := cb.Do(context.Background(), func(ctx context.Context) (int, error) { - return 0, errTestDownstream - }) - require.ErrorIs(t, err, errTestDownstream) - } - - require.Equal(t, Open, cb.state) - - // Advance time to reset - c.Tick(30 * time.Second) - - // Next request should be allowed (Half-Open state) - _, err := cb.Do(context.Background(), func(ctx context.Context) (int, error) { - return 42, nil - }) - - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - require.Equal(t, HalfOpen, cb.state) - -} - -func TestCircuitBreakerRecovers(t *testing.T) { - - cb := New[int]("test", WithMaxRequests(2)) - - // Reset to Half-Open state - cb.state = HalfOpen - - // Two requests should succeed - for i := 0; i < 2; i++ { - _, err := cb.Do(context.Background(), func(ctx context.Context) (int, error) { - return 42, nil - }) - require.NoError(t, err) - } - - // Circuit should close - require.Equal(t, Closed, cb.state) -} diff --git a/web/apps/agent/pkg/circuitbreaker/metrics.go b/web/apps/agent/pkg/circuitbreaker/metrics.go deleted file mode 100644 index ccc0167340..0000000000 --- a/web/apps/agent/pkg/circuitbreaker/metrics.go +++ /dev/null @@ -1,14 +0,0 @@ -package circuitbreaker - -import ( - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" -) - -var ( - requests = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: "agent", - Subsystem: "circuitbreaker", - Name: "requests", - }, []string{"name", "state"}) -) diff --git a/web/apps/agent/pkg/clickhouse/client.go b/web/apps/agent/pkg/clickhouse/client.go deleted file mode 100644 index 357c557ca1..0000000000 --- a/web/apps/agent/pkg/clickhouse/client.go +++ /dev/null @@ -1,104 +0,0 @@ -package clickhouse - -import ( - "context" - "time" - - ch "github.com/ClickHouse/clickhouse-go/v2" - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" - "github.com/unkeyed/unkey/svc/agent/pkg/batch" - "github.com/unkeyed/unkey/svc/agent/pkg/clickhouse/schema" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/util" -) - -type Clickhouse struct { - conn ch.Conn - logger logging.Logger - - requests *batch.BatchProcessor[schema.ApiRequestV1] - keyVerifications *batch.BatchProcessor[schema.KeyVerificationRequestV1] -} - -type Config struct { - URL string - Logger logging.Logger -} - -func New(config Config) (*Clickhouse, error) { - - opts, err := ch.ParseDSN(config.URL) - if err != nil { - return nil, fault.Wrap(err, fmsg.With("parsing clickhouse DSN failed")) - } - - // opts.TLS = &tls.Config{} - opts.Debug = true - opts.Debugf = func(format string, v ...any) { - config.Logger.Debug().Msgf(format, v...) - } - conn, err := ch.Open(opts) - if err != nil { - return nil, fault.Wrap(err, fmsg.With("opening clickhouse failed")) - } - - err = util.Retry(func() error { - return conn.Ping(context.Background()) - }, 10, func(n int) time.Duration { - return time.Duration(n) * time.Second - }) - if err != nil { - return nil, fault.Wrap(err, fmsg.With("pinging clickhouse failed")) - } - c := &Clickhouse{ - conn: conn, - logger: config.Logger, - - requests: batch.New[schema.ApiRequestV1](batch.Config[schema.ApiRequestV1]{ - BatchSize: 1000, - BufferSize: 100000, - FlushInterval: time.Second, - Consumers: 4, - Flush: func(ctx context.Context, rows []schema.ApiRequestV1) { - table := "raw_api_requests_v1" - err := flush(ctx, conn, table, rows) - if err != nil { - config.Logger.Error().Err(err).Str("table", table).Msg("failed to flush batch") - } - }, - }), - keyVerifications: batch.New[schema.KeyVerificationRequestV1](batch.Config[schema.KeyVerificationRequestV1]{ - BatchSize: 1000, - BufferSize: 100000, - FlushInterval: time.Second, - Consumers: 4, - Flush: func(ctx context.Context, rows []schema.KeyVerificationRequestV1) { - table := "raw_key_verifications_v1" - err := flush(ctx, conn, table, rows) - if err != nil { - config.Logger.Error().Err(err).Str("table", table).Msg("failed to flush batch") - } - }, - }), - } - - // err = c.conn.Ping(context.Background()) - // if err != nil { - // return nil, fault.Wrap(err, fmsg.With("pinging clickhouse failed")) - // } - return c, nil -} - -func (c *Clickhouse) Shutdown(ctx context.Context) error { - c.requests.Close() - return c.conn.Close() -} - -func (c *Clickhouse) BufferApiRequest(req schema.ApiRequestV1) { - c.requests.Buffer(req) -} - -func (c *Clickhouse) BufferKeyVerification(req schema.KeyVerificationRequestV1) { - c.keyVerifications.Buffer(req) -} diff --git a/web/apps/agent/pkg/clickhouse/flush.go b/web/apps/agent/pkg/clickhouse/flush.go deleted file mode 100644 index 12778c1417..0000000000 --- a/web/apps/agent/pkg/clickhouse/flush.go +++ /dev/null @@ -1,28 +0,0 @@ -package clickhouse - -import ( - "context" - "fmt" - - ch "github.com/ClickHouse/clickhouse-go/v2" - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" -) - -func flush[T any](ctx context.Context, conn ch.Conn, table string, rows []T) error { - batch, err := conn.PrepareBatch(ctx, fmt.Sprintf("INSERT INTO %s", table)) - if err != nil { - return fault.Wrap(err, fmsg.With("preparing batch failed")) - } - for _, row := range rows { - err = batch.AppendStruct(&row) - if err != nil { - return fault.Wrap(err, fmsg.With("appending struct to batch failed")) - } - } - err = batch.Send() - if err != nil { - return fault.Wrap(err, fmsg.With("committing batch failed")) - } - return nil -} diff --git a/web/apps/agent/pkg/clickhouse/interface.go b/web/apps/agent/pkg/clickhouse/interface.go deleted file mode 100644 index daf9abce47..0000000000 --- a/web/apps/agent/pkg/clickhouse/interface.go +++ /dev/null @@ -1,10 +0,0 @@ -package clickhouse - -import ( - "github.com/unkeyed/unkey/svc/agent/pkg/clickhouse/schema" -) - -type Bufferer interface { - BufferApiRequest(schema.ApiRequestV1) - BufferKeyVerification(schema.KeyVerificationRequestV1) -} diff --git a/web/apps/agent/pkg/clickhouse/noop.go b/web/apps/agent/pkg/clickhouse/noop.go deleted file mode 100644 index a646e106bc..0000000000 --- a/web/apps/agent/pkg/clickhouse/noop.go +++ /dev/null @@ -1,20 +0,0 @@ -package clickhouse - -import ( - "github.com/unkeyed/unkey/svc/agent/pkg/clickhouse/schema" -) - -type noop struct{} - -var _ Bufferer = &noop{} - -func (n *noop) BufferApiRequest(schema.ApiRequestV1) { - -} -func (n *noop) BufferKeyVerification(schema.KeyVerificationRequestV1) { - -} - -func NewNoop() *noop { - return &noop{} -} diff --git a/web/apps/agent/pkg/clickhouse/schema/requests.go b/web/apps/agent/pkg/clickhouse/schema/requests.go deleted file mode 100644 index 9df975648e..0000000000 --- a/web/apps/agent/pkg/clickhouse/schema/requests.go +++ /dev/null @@ -1,26 +0,0 @@ -package schema - -type ApiRequestV1 struct { - RequestID string `ch:"request_id"` - Time int64 `ch:"time"` - Host string `ch:"host"` - Method string `ch:"method"` - Path string `ch:"path"` - RequestHeaders []string `ch:"request_headers"` - RequestBody string `ch:"request_body"` - ResponseStatus int `ch:"response_status"` - ResponseHeaders []string `ch:"response_headers"` - ResponseBody string `ch:"response_body"` - Error string `ch:"error"` -} - -type KeyVerificationRequestV1 struct { - RequestID string `ch:"request_id"` - Time int64 `ch:"time"` - WorkspaceID string `ch:"workspace_id"` - KeySpaceID string `ch:"key_space_id"` - KeyID string `ch:"key_id"` - Region string `ch:"region"` - Outcome string `ch:"outcome"` - IdentityID string `ch:"identity_id"` -} diff --git a/web/apps/agent/pkg/clock/interface.go b/web/apps/agent/pkg/clock/interface.go deleted file mode 100644 index 787c5db069..0000000000 --- a/web/apps/agent/pkg/clock/interface.go +++ /dev/null @@ -1,10 +0,0 @@ -package clock - -import "time" - -// Clock is an interface for getting the current time. -// We're mainly using this for testing purposes, where waiting in real time -// would be impractical. -type Clock interface { - Now() time.Time -} diff --git a/web/apps/agent/pkg/clock/real_clock.go b/web/apps/agent/pkg/clock/real_clock.go deleted file mode 100644 index 580be114e0..0000000000 --- a/web/apps/agent/pkg/clock/real_clock.go +++ /dev/null @@ -1,16 +0,0 @@ -package clock - -import "time" - -type RealClock struct { -} - -func New() *RealClock { - return &RealClock{} -} - -var _ Clock = &RealClock{} - -func (c *RealClock) Now() time.Time { - return time.Now() -} diff --git a/web/apps/agent/pkg/clock/test_clock.go b/web/apps/agent/pkg/clock/test_clock.go deleted file mode 100644 index 50e33a6a17..0000000000 --- a/web/apps/agent/pkg/clock/test_clock.go +++ /dev/null @@ -1,32 +0,0 @@ -package clock - -import "time" - -type TestClock struct { - now time.Time -} - -func NewTestClock(now ...time.Time) *TestClock { - if len(now) == 0 { - now = append(now, time.Now()) - } - return &TestClock{now: now[0]} -} - -var _ Clock = &TestClock{} - -func (c *TestClock) Now() time.Time { - return c.now -} - -// Tick advances the clock by the given duration and returns the new time. -func (c *TestClock) Tick(d time.Duration) time.Time { - c.now = c.now.Add(d) - return c.now -} - -// Set sets the clock to the given time and returns the new time. -func (c *TestClock) Set(t time.Time) time.Time { - c.now = t - return c.now -} diff --git a/web/apps/agent/pkg/cluster/cluster.go b/web/apps/agent/pkg/cluster/cluster.go deleted file mode 100644 index 14e17ec6b0..0000000000 --- a/web/apps/agent/pkg/cluster/cluster.go +++ /dev/null @@ -1,209 +0,0 @@ -package cluster - -import ( - "fmt" - "time" - - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/membership" - "github.com/unkeyed/unkey/svc/agent/pkg/metrics" - "github.com/unkeyed/unkey/svc/agent/pkg/prometheus" - "github.com/unkeyed/unkey/svc/agent/pkg/repeat" - "github.com/unkeyed/unkey/svc/agent/pkg/ring" -) - -const defaultTokensPerNode = 256 - -type cluster struct { - id string - membership membership.Membership - logger logging.Logger - metrics metrics.Metrics - - // The hash ring is used to determine which node is responsible for a given key. - ring *ring.Ring[Node] - - // bearer token used to authenticate with other nodes - authToken string -} - -type Config struct { - NodeId string - Membership membership.Membership - Logger logging.Logger - Metrics metrics.Metrics - Debug bool - RpcAddr string - AuthToken string -} - -func New(config Config) (*cluster, error) { - - r, err := ring.New[Node](ring.Config{ - TokensPerNode: defaultTokensPerNode, - Logger: config.Logger, - }) - if err != nil { - return nil, err - } - - c := &cluster{ - id: config.NodeId, - membership: config.Membership, - logger: config.Logger, - metrics: config.Metrics, - ring: r, - authToken: config.AuthToken, - } - - go func() { - joins := c.membership.SubscribeJoinEvents() - leaves := c.membership.SubscribeLeaveEvents() - for { - select { - case join := <-joins: - err = r.AddNode(ring.Node[Node]{ - Id: join.NodeId, - Tags: Node{Id: join.NodeId, RpcAddr: join.RpcAddr}, - }) - if err != nil { - c.logger.Error().Err(err).Str("nodeId", join.NodeId).Msg("unable to add node to ring") - } - case leave := <-leaves: - err := r.RemoveNode(leave.NodeId) - if err != nil { - c.logger.Error().Err(err).Str("nodeId", leave.NodeId).Msg("unable to remove node from ring") - } - } - } - }() - - repeat.Every(10*time.Second, func() { - members, err := c.membership.Members() - if err != nil { - c.logger.Error().Err(err).Msg("failed to get members") - return - } - - prometheus.ClusterSize.Set(float64(len(members))) - - }) - - // Do a forced sync every minute - // I have observed that the channels can sometimes not be enough to keep the ring in sync - repeat.Every(10*time.Second, func() { - members, err := c.membership.Members() - if err != nil { - c.logger.Error().Err(err).Msg("failed to get members") - return - } - existingMembers := c.ring.Members() - c.logger.Debug().Int("want", len(members)).Int("have", len(existingMembers)).Msg("force syncing ring members") - - for _, existing := range existingMembers { - found := false - for _, m := range members { - if m.NodeId == existing.Id { - found = true - break - } - } - if !found { - err := c.ring.RemoveNode(existing.Id) - if err != nil { - c.logger.Error().Err(err).Str("nodeId", existing.Id).Msg("unable to remove node from ring") - } - } - } - for _, m := range members { - found := false - for _, existing := range c.ring.Members() { - if m.NodeId == existing.Id { - found = true - break - } - } - if !found { - err := c.ring.AddNode(ring.Node[Node]{ - Id: m.NodeId, - Tags: Node{Id: m.NodeId, RpcAddr: m.RpcAddr}, - }) - if err != nil { - c.logger.Error().Err(err).Str("nodeId", m.NodeId).Msg("unable to add node to ring") - } - } - } - }) - - return c, nil - -} - -func (c *cluster) NodeId() string { - return c.id -} -func (c *cluster) Peers() []Node { - members := c.ring.Members() - nodes := []Node{} - for _, m := range members { - if m.Id == c.id { - continue - } - nodes = append(nodes, m.Tags) - } - return nodes -} - -func (c *cluster) Size() int { - return len(c.ring.Members()) -} - -func (c *cluster) AuthToken() string { - return c.authToken -} - -func (c *cluster) FindNode(key string) (Node, error) { - found, err := c.ring.FindNode(key) - if err != nil { - return Node{}, fmt.Errorf("failed to find node: %w", err) - } - - return found.Tags, nil -} - -func (c *cluster) Shutdown() error { - c.logger.Info().Msg("shutting down cluster") - - // members, err := c.membership.Members() - // if err != nil { - // return fmt.Errorf("failed to get members: %w", err) - - // } - - err := c.membership.Leave() - if err != nil { - return fmt.Errorf("failed to leave membership: %w", err) - } - - // ctx := context.Background() - // wg := sync.WaitGroup{} - // for _, m := range members { - // wg.Add(1) - // go func() { - // defer wg.Done() - - // req := connect.NewRequest(&clusterv1.AnnounceStateChangeRequest{ - // NodeId: c.id, - // State: clusterv1.NodeState_NODE_STATE_LEAVING, - // }) - // req.Header().Set("Authorization", c.authToken) - - // _, err := clusterv1connect.NewClusterServiceClient(http.DefaultClient, m.RpcAddr).AnnounceStateChange(ctx, req) - // if err != nil { - // c.logger.Error().Err(err).Str("peerId", m.NodeId).Msg("failed to announce state change") - // } - // }() - // } - // wg.Wait() - return nil -} diff --git a/web/apps/agent/pkg/cluster/interface.go b/web/apps/agent/pkg/cluster/interface.go deleted file mode 100644 index aead2e63c7..0000000000 --- a/web/apps/agent/pkg/cluster/interface.go +++ /dev/null @@ -1,14 +0,0 @@ -package cluster - -type Cluster interface { - Shutdown() error - FindNode(key string) (Node, error) - Peers() []Node - AuthToken() string - - // Returns its own node ID - NodeId() string - - // Returns the number of nodes in the cluster - Size() int -} diff --git a/web/apps/agent/pkg/cluster/node.go b/web/apps/agent/pkg/cluster/node.go deleted file mode 100644 index 56bac4cb88..0000000000 --- a/web/apps/agent/pkg/cluster/node.go +++ /dev/null @@ -1,6 +0,0 @@ -package cluster - -type Node struct { - Id string - RpcAddr string -} diff --git a/web/apps/agent/pkg/config/agent.go b/web/apps/agent/pkg/config/agent.go deleted file mode 100644 index 32fc5a2e5a..0000000000 --- a/web/apps/agent/pkg/config/agent.go +++ /dev/null @@ -1,76 +0,0 @@ -package config - -type Agent struct { - Platform string `json:"platform,omitempty" description:"The platform this agent is running on"` - NodeId string `json:"nodeId,omitempty" description:"A unique node id"` - Image string `json:"image,omitempty" description:"The image this agent is running"` - AuthToken string `json:"authToken" minLength:"1" description:"The token to use for http authentication"` - Logging *struct { - Color bool `json:"color,omitempty"` - Axiom *struct { - Dataset string `json:"dataset" minLength:"1" description:"The dataset to send logs to"` - Token string `json:"token" minLength:"1" description:"The token to use for authentication"` - } `json:"axiom,omitempty" description:"Send logs to axiom"` - } `json:"logging,omitempty"` - - Tracing *struct { - Axiom *struct { - Dataset string `json:"dataset" minLength:"1" description:"The dataset to send traces to"` - Token string `json:"token" minLength:"1" description:"The token to use for authentication"` - } `json:"axiom,omitempty" description:"Send traces to axiom"` - } `json:"tracing,omitempty"` - - Metrics *struct { - Axiom *struct { - Dataset string `json:"dataset" minLength:"1" description:"The dataset to send metrics to"` - Token string `json:"token" minLength:"1" description:"The token to use for authentication"` - } `json:"axiom,omitempty" description:"Send metrics to axiom"` - } `json:"metrics,omitempty"` - - Schema string `json:"$schema,omitempty" description:"Make jsonschema happy"` - Region string `json:"region,omitempty" description:"The region this agent is running in"` - Port string `json:"port,omitempty" default:"8080" description:"Port to listen on"` - RpcPort string `json:"rpcPort,omitempty" default:"9090" description:"Port to listen on for RPC requests"` - Heartbeat *struct { - URL string `json:"url" minLength:"1" description:"URL to send heartbeat to"` - Interval int `json:"interval" min:"1" description:"Interval in seconds to send heartbeat"` - } `json:"heartbeat,omitempty" description:"Send heartbeat to a URL"` - - Services struct { - Vault struct { - S3Bucket string `json:"s3Bucket" minLength:"1" description:"The bucket to store secrets in"` - S3Url string `json:"s3Url" minLength:"1" description:"The url to store secrets in"` - S3AccessKeyId string `json:"s3AccessKeyId" minLength:"1" description:"The access key id to use for s3"` - S3AccessKeySecret string `json:"s3AccessKeySecret" minLength:"1" description:"The access key secret to use for s3"` - MasterKeys string `json:"masterKeys" minLength:"1" description:"The master keys to use for encryption, comma separated"` - } `json:"vault" description:"Store secrets"` - } `json:"services"` - - Cluster *struct { - AuthToken string `json:"authToken" minLength:"1" description:"The token to use for http authentication"` - SerfAddr string `json:"serfAddr" minLength:"1" description:"The host and port for serf to listen on"` - RpcAddr string `json:"rpcAddr" minLength:"1" description:"This node's internal address, including protocol and port"` - - Join *struct { - Env *struct { - Addrs []string `json:"addrs" description:"Addresses to join, comma separated"` - } `json:"env,omitempty"` - Dns *struct { - AAAA string `json:"aaaa" description:"The AAAA record that returns a comma separated list, containing the ipv6 addresses of all nodes"` - } `json:"dns,omitempty"` - } `json:"join,omitempty" description:"The strategy to use to join the cluster"` - } `json:"cluster,omitempty"` - - Prometheus *struct { - Path string `json:"path" default:"/metrics" description:"The path where prometheus scrapes metrics"` - Port int `json:"port" default:"2112" description:"The port where prometheus scrapes metrics"` - } `json:"prometheus,omitempty"` - Pyroscope *struct { - Url string `json:"url" minLength:"1"` - User string `json:"user" minLength:"1"` - Password string `json:"password" minLength:"1"` - } `json:"pyroscope,omitempty"` - Clickhouse *struct { - Url string `json:"url" minLength:"1"` - } `json:"clickhouse,omitempty"` -} diff --git a/web/apps/agent/pkg/config/json.go b/web/apps/agent/pkg/config/json.go deleted file mode 100644 index 2598cb54b7..0000000000 --- a/web/apps/agent/pkg/config/json.go +++ /dev/null @@ -1,81 +0,0 @@ -package config - -import ( - "encoding/json" - "fmt" - "reflect" - "strings" - - "os" - - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" - "github.com/danielgtaylor/huma/schema" - "github.com/xeipuuv/gojsonschema" -) - -func LoadFile[C any](config *C, path string) (err error) { - content, err := os.ReadFile(path) - if err != nil { - return fmt.Errorf("Failed to read configuration file: %s", err) - } - - expanded := os.ExpandEnv(string(content)) - - schema, err := GenerateJsonSchema(config) - if err != nil { - return fmt.Errorf("Failed to generate json schema: %s", err) - } - - v, err := gojsonschema.Validate( - gojsonschema.NewStringLoader(schema), - gojsonschema.NewStringLoader(expanded)) - if err != nil { - return fmt.Errorf("Failed to validate configuration: %s", err) - } - - if !v.Valid() { - lines := []string{"Configuration is invalid", fmt.Sprintf("read file: %s", path), ""} - - for _, e := range v.Errors() { - lines = append(lines, fmt.Sprintf(" - %s: %s", e.Field(), e.Description())) - } - lines = append(lines, "") - lines = append(lines, "") - lines = append(lines, "Configuration received:") - lines = append(lines, expanded) - return fault.New(strings.Join(lines, "\n")) - } - - err = json.Unmarshal([]byte(expanded), config) - if err != nil { - return fault.Wrap(err, fmsg.WithDesc("bad_config", "Failed to unmarshal configuration")) - - } - return nil - -} - -// GenerateJsonSchema generates a JSON schema for the given configuration struct. -// If `file` is provided, it will be written to that file. -func GenerateJsonSchema(cfg any, file ...string) (string, error) { - s, err := schema.Generate(reflect.TypeOf(cfg)) - if err != nil { - return "", err - } - s.AdditionalProperties = true - b, err := json.MarshalIndent(s, "", " ") - if err != nil { - return "", err - } - - if len(file) > 0 { - err = os.WriteFile(file[0], b, 0644) - if err != nil { - return "", err - } - } - - return string(b), nil - -} diff --git a/web/apps/agent/pkg/config/json_test.go b/web/apps/agent/pkg/config/json_test.go deleted file mode 100644 index 6c82246742..0000000000 --- a/web/apps/agent/pkg/config/json_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package config_test - -import ( - "os" - "path/filepath" - "testing" - - "github.com/stretchr/testify/require" - "github.com/unkeyed/unkey/svc/agent/pkg/config" -) - -func TestLoadFile_WithMissingRequired(t *testing.T) { - - cfg := struct { - Hello string `json:"hello" required:"true"` - }{} - - dir := t.TempDir() - path := filepath.Join(dir, "config.json") - - err := os.WriteFile(path, []byte(`{"somethingElse": "world"}`), 0644) - require.NoError(t, err) - - err = config.LoadFile(&cfg, path) - require.Error(t, err) - require.Contains(t, err.Error(), "hello is required") - -} - -func TestLoadFile_WritesValuesToPointer(t *testing.T) { - - cfg := struct { - Hello string `json:"hello" required:"true"` - }{} - - dir := t.TempDir() - path := filepath.Join(dir, "config.json") - - err := os.WriteFile(path, []byte(`{"hello": "world"}`), 0644) - require.NoError(t, err) - - err = config.LoadFile(&cfg, path) - require.NoError(t, err) - require.Equal(t, "world", cfg.Hello) - -} - -func TestLoadFile_ExpandsEnv(t *testing.T) { - - cfg := struct { - Hello string `json:"hello" required:"true"` - }{} - - dir := t.TempDir() - path := filepath.Join(dir, "config.json") - - err := os.WriteFile(path, []byte(`{"hello": "${TEST_HELLO}"}`), 0644) - require.NoError(t, err) - - t.Setenv("TEST_HELLO", "world") - err = config.LoadFile(&cfg, path) - require.NoError(t, err) - require.Equal(t, "world", cfg.Hello) - -} diff --git a/web/apps/agent/pkg/connect/cluster.go b/web/apps/agent/pkg/connect/cluster.go deleted file mode 100644 index ac46408cd5..0000000000 --- a/web/apps/agent/pkg/connect/cluster.go +++ /dev/null @@ -1,53 +0,0 @@ -package connect - -import ( - "context" - "net/http" - - "connectrpc.com/connect" - "connectrpc.com/otelconnect" - clusterv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/cluster/v1" - "github.com/unkeyed/unkey/svc/agent/gen/proto/cluster/v1/clusterv1connect" - "github.com/unkeyed/unkey/svc/agent/pkg/auth" - "github.com/unkeyed/unkey/svc/agent/pkg/cluster" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" -) - -type clusterServer struct { - svc cluster.Cluster - logger logging.Logger - clusterv1connect.UnimplementedClusterServiceHandler -} - -func NewClusterServer(svc cluster.Cluster, logger logging.Logger) *clusterServer { - - return &clusterServer{ - svc: svc, - logger: logger, - } -} - -func (s *clusterServer) CreateHandler() (string, http.Handler, error) { - otelInterceptor, err := otelconnect.NewInterceptor() - if err != nil { - return "", nil, err - } - - path, handler := clusterv1connect.NewClusterServiceHandler(s, connect.WithInterceptors(otelInterceptor)) - return path, handler, nil - -} - -func (s *clusterServer) AnnounceStateChange( - ctx context.Context, - req *connect.Request[clusterv1.AnnounceStateChangeRequest], -) (*connect.Response[clusterv1.AnnounceStateChangeResponse], error) { - authorization := req.Header().Get("Authorization") - err := auth.Authorize(ctx, "TODO:", authorization) - if err != nil { - s.logger.Warn().Err(err).Msg("failed to authorize request") - return nil, err - } - - return connect.NewResponse(&clusterv1.AnnounceStateChangeResponse{}), nil -} diff --git a/web/apps/agent/pkg/connect/middleware_headers.go b/web/apps/agent/pkg/connect/middleware_headers.go deleted file mode 100644 index 3389657740..0000000000 --- a/web/apps/agent/pkg/connect/middleware_headers.go +++ /dev/null @@ -1,23 +0,0 @@ -package connect - -import ( - "fmt" - "net/http" - "time" -) - -type headerMiddleware struct { - handler http.Handler -} - -func newHeaderMiddleware(handler http.Handler) http.Handler { - return &headerMiddleware{handler} -} - -func (h *headerMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) { - start := time.Now() - h.handler.ServeHTTP(w, r) - serviceLatency := time.Since(start).Milliseconds() - w.Header().Add("Unkey-Latency", fmt.Sprintf("service=%d", serviceLatency)) - -} diff --git a/web/apps/agent/pkg/connect/ratelimit.go b/web/apps/agent/pkg/connect/ratelimit.go deleted file mode 100644 index 3ac0388180..0000000000 --- a/web/apps/agent/pkg/connect/ratelimit.go +++ /dev/null @@ -1,148 +0,0 @@ -package connect - -import ( - "context" - "fmt" - "net/http" - - "connectrpc.com/connect" - "connectrpc.com/otelconnect" - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" - "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1/ratelimitv1connect" - "github.com/unkeyed/unkey/svc/agent/pkg/auth" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" -) - -var _ ratelimitv1connect.RatelimitServiceHandler = (*ratelimitServer)(nil) - -type RatelimitService interface { - Ratelimit(context.Context, *ratelimitv1.RatelimitRequest) (*ratelimitv1.RatelimitResponse, error) - MultiRatelimit(context.Context, *ratelimitv1.RatelimitMultiRequest) (*ratelimitv1.RatelimitMultiResponse, error) - PushPull(context.Context, *ratelimitv1.PushPullRequest) (*ratelimitv1.PushPullResponse, error) - CommitLease(context.Context, *ratelimitv1.CommitLeaseRequest) (*ratelimitv1.CommitLeaseResponse, error) - Mitigate(context.Context, *ratelimitv1.MitigateRequest) (*ratelimitv1.MitigateResponse, error) -} -type ratelimitServer struct { - svc RatelimitService - logger logging.Logger - authToken string - ratelimitv1connect.UnimplementedRatelimitServiceHandler -} - -func NewRatelimitServer(svc RatelimitService, logger logging.Logger, authToken string) *ratelimitServer { - - return &ratelimitServer{ - svc: svc, - logger: logger, - authToken: authToken, - } - -} - -func (s *ratelimitServer) CreateHandler() (string, http.Handler, error) { - otelInterceptor, err := otelconnect.NewInterceptor() - if err != nil { - return "", nil, err - } - - path, handler := ratelimitv1connect.NewRatelimitServiceHandler(s, connect.WithInterceptors(otelInterceptor)) - return path, handler, nil - -} -func (s *ratelimitServer) Ratelimit( - ctx context.Context, - req *connect.Request[ratelimitv1.RatelimitRequest], -) (*connect.Response[ratelimitv1.RatelimitResponse], error) { - - ctx, span := tracing.Start(ctx, tracing.NewSpanName("connect.ratelimit", "Ratelimit")) - defer span.End() - err := auth.Authorize(ctx, s.authToken, req.Header().Get("Authorization")) - if err != nil { - s.logger.Warn().Err(err).Msg("failed to authorize request") - return nil, err - } - - res, err := s.svc.Ratelimit(ctx, req.Msg) - if err != nil { - return nil, fmt.Errorf("failed to ratelimit: %w", err) - } - return connect.NewResponse(res), nil - -} - -func (s *ratelimitServer) MultiRatelimit( - ctx context.Context, - req *connect.Request[ratelimitv1.RatelimitMultiRequest], -) (*connect.Response[ratelimitv1.RatelimitMultiResponse], error) { - - ctx, span := tracing.Start(ctx, tracing.NewSpanName("connect.ratelimit", "MultiRatelimit")) - defer span.End() - err := auth.Authorize(ctx, s.authToken, req.Header().Get("Authorization")) - if err != nil { - s.logger.Warn().Err(err).Msg("failed to authorize request") - return nil, err - } - - res, err := s.svc.MultiRatelimit(ctx, req.Msg) - if err != nil { - return nil, fmt.Errorf("failed to ratelimit: %w", err) - } - return connect.NewResponse(res), nil - -} - -func (s *ratelimitServer) Liveness( - ctx context.Context, - req *connect.Request[ratelimitv1.LivenessRequest], -) (*connect.Response[ratelimitv1.LivenessResponse], error) { - - return connect.NewResponse(&ratelimitv1.LivenessResponse{ - Status: "ok", - }), nil - -} - -func (s *ratelimitServer) PushPull( - ctx context.Context, - req *connect.Request[ratelimitv1.PushPullRequest], -) (*connect.Response[ratelimitv1.PushPullResponse], error) { - - ctx, span := tracing.Start(ctx, tracing.NewSpanName("connect.ratelimit", "PushPull")) - defer span.End() - err := auth.Authorize(ctx, s.authToken, req.Header().Get("Authorization")) - if err != nil { - - s.logger.Warn().Err(err).Msg("failed to authorize request") - return nil, err - } - - res, err := s.svc.PushPull(ctx, req.Msg) - if err != nil { - return nil, fmt.Errorf("failed to pushpull: %w", err) - } - return connect.NewResponse(res), nil - -} - -func (s *ratelimitServer) Mitigate( - ctx context.Context, - req *connect.Request[ratelimitv1.MitigateRequest], -) (*connect.Response[ratelimitv1.MitigateResponse], error) { - - ctx, span := tracing.Start(ctx, tracing.NewSpanName("connect.ratelimit", "Mitigate")) - defer span.End() - err := auth.Authorize(ctx, s.authToken, req.Header().Get("Authorization")) - if err != nil { - - s.logger.Warn().Err(err).Msg("failed to authorize request") - return nil, err - } - - res, err := s.svc.Mitigate(ctx, req.Msg) - if err != nil { - return nil, fmt.Errorf("failed to pushpull: %w", err) - } - return connect.NewResponse(res), nil - -} diff --git a/web/apps/agent/pkg/connect/service.go b/web/apps/agent/pkg/connect/service.go deleted file mode 100644 index 3b26d94d24..0000000000 --- a/web/apps/agent/pkg/connect/service.go +++ /dev/null @@ -1,157 +0,0 @@ -package connect - -import ( - "context" - "crypto/subtle" - "encoding/json" - "fmt" - "sync" - "time" - - "net/http" - "net/http/pprof" - - "connectrpc.com/connect" - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/metrics" - "golang.org/x/net/http2" - "golang.org/x/net/http2/h2c" -) - -type Service interface { - CreateHandler() (pattern string, handler http.Handler, err error) -} - -type Server struct { - sync.Mutex - logger logging.Logger - metrics metrics.Metrics - mux *http.ServeMux - isListening bool - image string - srv *http.Server -} - -type Config struct { - Logger logging.Logger - Metrics metrics.Metrics - Image string -} - -func New(cfg Config) (*Server, error) { - - return &Server{ - logger: cfg.Logger, - metrics: cfg.Metrics, - isListening: false, - mux: http.NewServeMux(), - image: cfg.Image, - }, nil -} - -func (s *Server) AddService(svc Service) error { - pattern, handler, err := svc.CreateHandler() - if err != nil { - return fmt.Errorf("failed to create handler: %w", err) - } - s.logger.Info().Str("pattern", pattern).Msg("adding service") - - h := newHeaderMiddleware(handler) - s.mux.Handle(pattern, h) - return nil -} - -func (s *Server) EnablePprof(expectedUsername string, expectedPassword string) { - - var withBasicAuth = func(handler http.HandlerFunc) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - user, pass, ok := r.BasicAuth() - if !ok { - w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } - - usernameMatch := subtle.ConstantTimeCompare([]byte(user), []byte(expectedUsername)) == 1 - passwordMatch := subtle.ConstantTimeCompare([]byte(pass), []byte(expectedPassword)) == 1 - - if !usernameMatch || !passwordMatch { - w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) - http.Error(w, "Forbidden", http.StatusForbidden) - return - } - handler(w, r) - } - } - - s.mux.HandleFunc("/debug/pprof/", withBasicAuth(pprof.Index)) - s.mux.HandleFunc("/debug/pprof/cmdline", withBasicAuth(pprof.Cmdline)) - s.mux.HandleFunc("/debug/pprof/profile", withBasicAuth(pprof.Profile)) - s.mux.HandleFunc("/debug/pprof/symbol", withBasicAuth(pprof.Symbol)) - s.mux.HandleFunc("/debug/pprof/trace", withBasicAuth(pprof.Trace)) - s.logger.Info().Msg("pprof enabled") - -} - -func (s *Server) Liveness(ctx context.Context, req *connect.Request[ratelimitv1.LivenessRequest]) (*connect.Response[ratelimitv1.LivenessResponse], error) { - return connect.NewResponse(&ratelimitv1.LivenessResponse{ - Status: "serving", - }), nil -} - -func (s *Server) Listen(addr string) error { - s.Lock() - if s.isListening { - s.logger.Info().Msg("already listening") - s.Unlock() - return nil - } - s.isListening = true - s.Unlock() - - s.mux.HandleFunc("/v1/liveness", func(w http.ResponseWriter, r *http.Request) { - b, err := json.Marshal(map[string]string{"status": "serving", "image": s.image}) - if err != nil { - s.logger.Error().Err(err).Msg("failed to marshal response") - return - } - - w.WriteHeader(http.StatusOK) - _, err = w.Write(b) - if err != nil { - s.logger.Error().Err(err).Msg("failed to write response") - } - }) - - s.srv = &http.Server{Addr: addr, Handler: h2c.NewHandler(s.mux, &http2.Server{})} - - // See https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/ - // - // > # http.ListenAndServe is doing it wrong - // > Incidentally, this means that the package-level convenience functions that bypass http.Server - // > like http.ListenAndServe, http.ListenAndServeTLS and http.Serve are unfit for public Internet - // > servers. - // > - // > Those functions leave the Timeouts to their default off value, with no way of enabling them, - // > so if you use them you'll soon be leaking connections and run out of file descriptors. I've - // > made this mistake at least half a dozen times. - // > - // > Instead, create a http.Server instance with ReadTimeout and WriteTimeout and use its - // > corresponding methods, like in the example a few paragraphs above. - s.srv.ReadTimeout = 10 * time.Second - s.srv.WriteTimeout = 20 * time.Second - - s.logger.Info().Str("addr", addr).Msg("listening") - return s.srv.ListenAndServe() - -} - -func (s *Server) Shutdown() error { - s.Lock() - defer s.Unlock() - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - return s.srv.Shutdown(ctx) - -} diff --git a/web/apps/agent/pkg/encryption/aes.go b/web/apps/agent/pkg/encryption/aes.go deleted file mode 100644 index 240c080b62..0000000000 --- a/web/apps/agent/pkg/encryption/aes.go +++ /dev/null @@ -1,52 +0,0 @@ -package encryption - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/rand" - "fmt" -) - -func Encrypt(key []byte, plaintext []byte) (nonce []byte, ciphertext []byte, err error) { - block, err := aes.NewCipher(key) - if err != nil { - return nil, nil, fmt.Errorf("failed to create cipher: %w", err) - } - nonce = make([]byte, 12) - n, err := rand.Read(nonce) - if err != nil { - return nil, nil, fmt.Errorf("failed to create nonce: %w", err) - } - if n != 12 { - return nil, nil, fmt.Errorf("failed to read 12 bytes of random data: %w", err) - } - - aes, err := cipher.NewGCM(block) - - if err != nil { - return nil, nil, fmt.Errorf("failed to create gcm: %w", err) - } - ciphertext = aes.Seal(nil, nonce, plaintext, nil) - - return nonce, ciphertext, nil - -} - -func Decrypt(key []byte, nonce []byte, ciphertext []byte) ([]byte, error) { - block, err := aes.NewCipher(key) - if err != nil { - return nil, fmt.Errorf("failed to create cipher: %w", err) - } - - aes, err := cipher.NewGCM(block) - if err != nil { - return nil, fmt.Errorf("failed to create gcm: %w", err) - } - - plaintext, err := aes.Open(nil, nonce, ciphertext, nil) - if err != nil { - return nil, fmt.Errorf("failed to decrypt data: %w", err) - } - - return plaintext, nil -} diff --git a/web/apps/agent/pkg/encryption/aes_test.go b/web/apps/agent/pkg/encryption/aes_test.go deleted file mode 100644 index 3019836a7c..0000000000 --- a/web/apps/agent/pkg/encryption/aes_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package encryption_test - -import ( - "crypto/rand" - "testing" - - "github.com/stretchr/testify/require" - "github.com/unkeyed/unkey/svc/agent/pkg/encryption" -) - -func TestEncryptDecrypt(t *testing.T) { - - data := make([]byte, 1024) - _, err := rand.Read(data) - require.NoError(t, err) - - key := make([]byte, 32) - _, err = rand.Read(key) - require.NoError(t, err) - - nonce, ciphertext, err := encryption.Encrypt(key, data) - require.NoError(t, err) - - plaintext, err := encryption.Decrypt(key, nonce, ciphertext) - require.NoError(t, err) - require.Equal(t, data, plaintext) - -} diff --git a/web/apps/agent/pkg/env/env.go b/web/apps/agent/pkg/env/env.go deleted file mode 100644 index 4c411f9ed4..0000000000 --- a/web/apps/agent/pkg/env/env.go +++ /dev/null @@ -1,109 +0,0 @@ -package env - -import ( - "fmt" - "os" - "strconv" - "strings" - "time" -) - -type Env struct { - ErrorHandler func(error) -} - -func (e *Env) String(name string, fallback ...string) string { - value := os.Getenv(name) - if value != "" { - return value - } - if len(fallback) > 0 { - return fallback[0] - } - e.ErrorHandler(fmt.Errorf("%s is not set and no fallback provided", name)) - return "" -} - -// Strings parses a comma-separated list of strings. -func (e *Env) Strings(name string, fallback ...[]string) []string { - value := os.Getenv(name) - if value != "" { - return strings.Split(value, ",") - } - if len(fallback) > 0 { - return fallback[0] - } - e.ErrorHandler(fmt.Errorf("%s is not set and no fallback provided", name)) - return []string{} - -} - -// Strings parses a comma-separated list of strings and appends it to the default values -func (e *Env) StringsAppend(name string, defaultValues ...[]string) []string { - all := []string{} - if len(defaultValues) > 0 { - all = defaultValues[0] - } - - value := os.Getenv(name) - if value != "" { - all = append(all, strings.Split(value, ",")...) - } - if len(all) == 0 { - e.ErrorHandler(fmt.Errorf("%s is not set and no fallback provided", name)) - return []string{} - } - return all - -} - -func (e *Env) Int(name string, fallback ...int) int { - value := os.Getenv(name) - if value != "" { - i, err := strconv.Atoi(value) - if err != nil { - e.ErrorHandler(err) - return 0 - } - return i - } - if len(fallback) > 0 { - return fallback[0] - } - e.ErrorHandler(fmt.Errorf("%s is not set and no fallback provided", name)) - return 0 -} - -func (e *Env) Bool(name string, fallback ...bool) bool { - value := os.Getenv(name) - if value != "" { - b, err := strconv.ParseBool(value) - if err != nil { - e.ErrorHandler(err) - return false - } - return b - } - if len(fallback) > 0 { - return fallback[0] - } - e.ErrorHandler(fmt.Errorf("%s is not set and no fallback provided", name)) - return false -} - -func (e *Env) Duration(name string, fallback ...time.Duration) time.Duration { - value := os.Getenv(name) - if value != "" { - d, err := time.ParseDuration(value) - if err != nil { - e.ErrorHandler(err) - return 0 - } - return d - } - if len(fallback) > 0 { - return fallback[0] - } - e.ErrorHandler(fmt.Errorf("%s is not set and no fallback provided", name)) - return 0 -} diff --git a/web/apps/agent/pkg/env/env_test.go b/web/apps/agent/pkg/env/env_test.go deleted file mode 100644 index 0c4de32edf..0000000000 --- a/web/apps/agent/pkg/env/env_test.go +++ /dev/null @@ -1,182 +0,0 @@ -package env_test - -import ( - "fmt" - "math/rand" - "strings" - "testing" - "time" - - "github.com/google/uuid" - "github.com/stretchr/testify/require" - "github.com/unkeyed/unkey/svc/agent/pkg/env" -) - -func TestString_WhenSet(t *testing.T) { - e := env.Env{ - ErrorHandler: func(err error) { require.NoError(t, err) }, - } - - key := uuid.NewString() - value := uuid.NewString() - - t.Setenv(key, value) - - got := e.String(key) - require.Equal(t, got, value) -} - -func TestString_WhenNotSet(t *testing.T) { - e := env.Env{ - ErrorHandler: func(err error) { require.Error(t, err) }, - } - - key := uuid.NewString() - - got := e.String(key) - require.Equal(t, "", got) -} - -func TestString_WhenNotSetFallback(t *testing.T) { - e := env.Env{ - ErrorHandler: func(err error) { require.NoError(t, err) }, - } - - key := uuid.NewString() - fallback := uuid.NewString() - - got := e.String(key, fallback) - require.Equal(t, fallback, got) -} - -func TestStringsAppend_WhenSet(t *testing.T) { - e := env.Env{ - ErrorHandler: func(err error) { require.NoError(t, err) }, - } - - key := uuid.NewString() - values := []string{uuid.NewString(), uuid.NewString()} - - t.Setenv(key, strings.Join(values, ",")) - - got := e.StringsAppend(key) - require.Equal(t, got, values) -} - -func TestStringsAppend_WhenSetWithDefaults(t *testing.T) { - e := env.Env{ - ErrorHandler: func(err error) { require.NoError(t, err) }, - } - - key := uuid.NewString() - values := []string{uuid.NewString(), uuid.NewString()} - defaults := []string{uuid.NewString(), uuid.NewString()} - - t.Setenv(key, strings.Join(values, ",")) - - got := e.StringsAppend(key, defaults) - require.Equal(t, 4, len(got)) - require.Contains(t, got, values[0]) - require.Contains(t, got, values[1]) - require.Contains(t, got, defaults[0]) - require.Contains(t, got, defaults[1]) -} - -func TestStringsAppend_WhenNotSet(t *testing.T) { - e := env.Env{ - ErrorHandler: func(err error) { require.Error(t, err) }, - } - - key := uuid.NewString() - - got := e.StringsAppend(key) - require.Equal(t, []string{}, got) -} - -func TestStringsAppend_WhenNotSetFallback(t *testing.T) { - e := env.Env{ - ErrorHandler: func(err error) { require.NoError(t, err) }, - } - - key := uuid.NewString() - fallback := []string{uuid.NewString()} - - got := e.StringsAppend(key, fallback) - require.Equal(t, fallback, got) -} - -func TestInt_WhenSet(t *testing.T) { - - e := env.Env{ - ErrorHandler: func(err error) { require.NoError(t, err) }, - } - - key := uuid.NewString() - value := int(rand.NewSource(time.Now().UnixNano()).Int63()) - - t.Setenv(key, fmt.Sprintf("%d", value)) - - got := e.Int(key) - require.Equal(t, got, value) -} - -func TestInt_WhenNotSet(t *testing.T) { - e := env.Env{ - ErrorHandler: func(err error) { require.Error(t, err) }, - } - - key := uuid.NewString() - - got := e.Int(key) - require.Equal(t, 0, got) -} - -func TestInt_WhenNotSetFallback(t *testing.T) { - e := env.Env{ - ErrorHandler: func(err error) { require.NoError(t, err) }, - } - - key := uuid.NewString() - fallback := int(rand.NewSource(time.Now().UnixNano()).Int63()) - - got := e.Int(key, fallback) - require.Equal(t, fallback, got) -} - -func TestBool_WhenSet(t *testing.T) { - - e := env.Env{ - ErrorHandler: func(err error) { require.NoError(t, err) }, - } - - key := uuid.NewString() - value := true - - t.Setenv(key, fmt.Sprintf("%t", value)) - - got := e.Bool(key) - require.Equal(t, got, value) -} - -func TestBool_WhenNotSet(t *testing.T) { - e := env.Env{ - ErrorHandler: func(err error) { require.Error(t, err) }, - } - - key := uuid.NewString() - - got := e.Bool(key) - require.Equal(t, false, got) -} - -func TestBool_WhenNotSetFallback(t *testing.T) { - e := env.Env{ - ErrorHandler: func(err error) { require.NoError(t, err) }, - } - - key := uuid.NewString() - fallback := true - - got := e.Bool(key, fallback) - require.Equal(t, fallback, got) -} diff --git a/web/apps/agent/pkg/events/topic.go b/web/apps/agent/pkg/events/topic.go deleted file mode 100644 index fa5b16ade7..0000000000 --- a/web/apps/agent/pkg/events/topic.go +++ /dev/null @@ -1,73 +0,0 @@ -package events - -import ( - "context" - "fmt" - "sync" - - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" -) - -type EventEmitter[E any] interface { - Emit(ctx context.Context, event E) -} - -type EventSubscriber[E any] interface { - Subscribe(id string) <-chan E -} - -type Topic[E any] interface { - EventEmitter[E] - EventSubscriber[E] -} - -type listener[E any] struct { - id string - ch chan E -} - -type topic[E any] struct { - sync.RWMutex - bufferSize int - listeners []listener[E] -} - -// NewTopic creates a new topic with an optional buffer size -// Omiting the buffer size will create an unbuffered topic -func NewTopic[E any](bufferSize ...int) Topic[E] { - n := 0 - if len(bufferSize) > 0 { - n = bufferSize[0] - } - return &topic[E]{ - bufferSize: n, - listeners: []listener[E]{}, - } -} - -func (t *topic[E]) Emit(ctx context.Context, event E) { - - t.Lock() - defer t.Unlock() - for _, l := range t.listeners { - var span trace.Span - ctx, span = tracing.Start(ctx, fmt.Sprintf("topic.Emit:%s", l.id)) - span.SetAttributes(attribute.Int("channelSize", len(l.ch))) - l.ch <- event - span.End() - } - -} - -// Subscribe returns a channel that will receive events from the topic -// The channel will be closed when the topic is closed -// The id is used for debugging and tracing, not for uniqueness -func (t *topic[E]) Subscribe(id string) <-chan E { - t.Lock() - defer t.Unlock() - ch := make(chan E, t.bufferSize) - t.listeners = append(t.listeners, listener[E]{id: id, ch: ch}) - return ch -} diff --git a/web/apps/agent/pkg/gossip/cluster.go b/web/apps/agent/pkg/gossip/cluster.go deleted file mode 100644 index 15b9ecbc83..0000000000 --- a/web/apps/agent/pkg/gossip/cluster.go +++ /dev/null @@ -1,422 +0,0 @@ -package gossip - -import ( - "context" - "net/http" - "sync" - "time" - - "math/rand" - - "connectrpc.com/connect" - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" - gossipv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/gossip/v1" - "github.com/unkeyed/unkey/svc/agent/gen/proto/gossip/v1/gossipv1connect" - "github.com/unkeyed/unkey/svc/agent/pkg/events" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/util" -) - -// ensure cluster implements Cluster -var _ Cluster = &cluster{} - -type cluster struct { - sync.RWMutex - logger logging.Logger - - self *gossipv1.Member - - // all members of the cluster, including self - members map[string]*gossipv1.Member - - config Config - - memberJoinTopic events.Topic[Member] - memberUpdateTopic events.Topic[Member] - memberLeaveTopic events.Topic[Member] - - shutdown events.Topic[bool] -} - -type Config struct { - Logger logging.Logger - - NodeId string - RpcAddr string - - // How frequently to gossip with other members - GossipInterval time.Duration - - // Timeout for gossip requests, if a member doesn't respond within this time, it is considered a - // suspect - GossipTimeout time.Duration - - // Each interval, a member will gossip to this many other members - GossipFactor int -} - -func (c Config) withDefaults() Config { - if c.GossipInterval == 0 { - c.GossipInterval = time.Second - } - if c.GossipTimeout == 0 { - c.GossipTimeout = time.Second - } - if c.GossipFactor == 0 { - c.GossipFactor = 3 - } - - return c - -} - -func New(config Config) (*cluster, error) { - - self := &gossipv1.Member{ - NodeId: config.NodeId, - RpcAddr: config.RpcAddr, - State: gossipv1.State_State_ALIVE, - } - - c := &cluster{ - logger: config.Logger, - self: self, - members: map[string]*gossipv1.Member{}, - config: config.withDefaults(), - shutdown: events.NewTopic[bool](), - memberJoinTopic: events.NewTopic[Member](), - memberUpdateTopic: events.NewTopic[Member](), - memberLeaveTopic: events.NewTopic[Member](), - } - - c.members[self.NodeId] = self - - return c, nil -} - -// Run starts the cluster's gossip loop and other background tasks -// -// Stops automatic when a message from the shutdown topic is received -func (c *cluster) run() { - stop := c.shutdown.Subscribe("cluster shutdown") - t := time.NewTicker(c.config.GossipInterval) - - for { - select { - case <-stop: - t.Stop() - return - case <-t.C: - err := c.gossip(context.Background()) - if err != nil { - c.logger.Warn().Err(err).Msg("failed to gossip") - } - - } - } -} - -func (c *cluster) RpcAddr() string { - return c.self.RpcAddr -} - -func (c *cluster) Members() map[string]Member { - c.RLock() - defer c.RUnlock() - - members := map[string]Member{} - for k, v := range c.members { - members[k] = Member{ - NodeId: v.NodeId, - RpcAddr: v.RpcAddr, - } - } - - return members -} - -func (c *cluster) Join(ctx context.Context, rpcAddrs ...string) error { - c.logger.Info().Strs("rpcAddrs", rpcAddrs).Msg("attempting to join cluster") - - c.Lock() - defer c.Unlock() - - successfullyExchanged := 0 - errors := []error{} - - for _, rpcAddr := range rpcAddrs { - if rpcAddr == c.self.RpcAddr { - // Skip talking to ourselves - continue - } - - client := gossipv1connect.NewGossipServiceClient(http.DefaultClient, rpcAddr) - - var resp *connect.Response[gossipv1.JoinResponse] - err := util.Retry(func() error { - var joinErr error - resp, joinErr = client.Join(ctx, connect.NewRequest(&gossipv1.JoinRequest{ - Self: &gossipv1.Member{ - NodeId: c.self.NodeId, - RpcAddr: c.self.RpcAddr, - State: gossipv1.State_State_ALIVE, - }, - })) - if joinErr != nil { - c.logger.Warn().Err(joinErr).Str("rpcAddr", rpcAddr).Msg("error joining cluster") - - return joinErr - } - return nil - }, 5, func(n int) time.Duration { - return time.Duration(n) * time.Second - }) - - if err != nil { - errors = append(errors, err) - continue - } - - for _, m := range resp.Msg.Members { - c.members[m.NodeId] = m - c.memberJoinTopic.Emit(ctx, Member{ - NodeId: m.NodeId, - RpcAddr: m.RpcAddr, - }) - } - - successfullyExchanged++ - } - if (float64(successfullyExchanged) / float64(len(rpcAddrs))) >= 0.5 { - // If more than half of the members successfully exchanged, consider the join successful - return nil - } - - if len(errors) > 0 { - return fault.Wrap(errors[0], fmsg.With("failed to join cluster")) - } - - // After joining the cluster, start the gossip loop - go c.run() - return nil -} - -func (c *cluster) Shutdown(ctx context.Context) error { - - c.shutdown.Emit(ctx, true) - - c.Lock() - defer c.Unlock() - - errors := []error{} - - for _, member := range c.members { - if member.NodeId == c.self.NodeId { - // Skip talking to ourselves - continue - } - - client := gossipv1connect.NewGossipServiceClient(http.DefaultClient, member.RpcAddr) - - err := util.Retry(func() error { - _, leaveError := client.Leave(ctx, connect.NewRequest(&gossipv1.LeaveRequest{ - Self: &gossipv1.Member{ - NodeId: c.self.NodeId, - RpcAddr: c.self.RpcAddr, - State: gossipv1.State_State_LEFT, - }, - })) - if leaveError != nil { - c.logger.Warn().Err(leaveError).Str("rpcAddr", member.RpcAddr).Msg("error leaving cluster") - - return leaveError - } - return nil - }, 5, func(n int) time.Duration { - return time.Duration(n) * time.Second - }) - - if err != nil { - errors = append(errors, err) - continue - } - - } - if len(errors) > 0 { - return fault.Wrap(errors[0], fmsg.With("failed to leave cluster")) - - } - - return nil -} - -func (c *cluster) SubscribeJoinEvents(callerName string) <-chan Member { - return c.memberJoinTopic.Subscribe(callerName) -} - -func (c *cluster) SubscribeUpdateEvents(callerName string) <-chan Member { - return c.memberUpdateTopic.Subscribe(callerName) -} - -func (c *cluster) SubscribeLeaveEvents(callerName string) <-chan Member { - return c.memberLeaveTopic.Subscribe(callerName) -} - -func (c *cluster) randomPeers(n int, withoutNodeIds ...string) ([]*gossipv1.Member, error) { - c.RLock() - defer c.RUnlock() - - peerIds := make([]string, 0, len(c.members)) - for id := range c.members { - if id == c.self.NodeId { - continue - } - peerIds = append(peerIds, id) - } - - peers := []*gossipv1.Member{} - for len(peers) < n { - peer := c.members[peerIds[rand.Intn(len(peerIds))]] - if len(withoutNodeIds) > 0 { - for _, withoutNodeId := range withoutNodeIds { - if peer.NodeId == withoutNodeId { - continue - } - } - - } - - peers = append(peers, peer) - } - - return peers, nil -} - -func (c *cluster) addMemberToState(ctx context.Context, member *gossipv1.Member) { - c.Lock() - defer c.Unlock() - - _, ok := c.members[member.NodeId] - - c.members[member.NodeId] = member - - if !ok { - c.memberJoinTopic.Emit(ctx, Member{ - NodeId: member.NodeId, - RpcAddr: member.RpcAddr, - }) - } -} - -func (c *cluster) removeMemberFromState(ctx context.Context, nodeId string) { - c.Lock() - defer c.Unlock() - - member, ok := c.members[nodeId] - if !ok { - return - } - - delete(c.members, member.NodeId) - c.memberLeaveTopic.Emit(ctx, Member{ - NodeId: member.NodeId, - RpcAddr: member.RpcAddr, - }) -} - -func (c *cluster) gossip(ctx context.Context) error { - - peers, err := c.randomPeers(c.config.GossipFactor) - if err != nil { - return fault.Wrap(err, fmsg.With("failed to find peers to gossip with")) - } - - for _, peer := range peers { - c.logger.Debug().Str("peerId", peer.NodeId).Msg("gossiping about membership with peer") - client := gossipv1connect.NewGossipServiceClient(http.DefaultClient, peer.RpcAddr) - ctxWithTimeout, cancel := context.WithTimeout(ctx, c.config.GossipTimeout) - defer cancel() - res, err := client.Ping(ctxWithTimeout, connect.NewRequest(&gossipv1.PingRequest{})) - - if err == nil { - switch res.Msg.State { - case gossipv1.State_State_ALIVE: - c.logger.Debug().Str("peerId", peer.NodeId).Msg("peer is alive") - continue - case gossipv1.State_State_LEFT: - c.logger.Debug().Str("peerId", peer.NodeId).Msg("peer has left") - c.removeMemberFromState(ctx, peer.NodeId) - continue - default: - c.logger.Debug().Str("peerId", peer.NodeId).Msg("peer is not alive") - } - } - - // Peer was not alive, let's check via indirect gossip - - indirectPeers, err := c.randomPeers(c.config.GossipFactor, peer.NodeId) - if err != nil { - return fault.Wrap(err, fmsg.With("failed to find indirect peers to gossip with")) - } - - for _, indirectPeer := range indirectPeers { - c.logger.Debug().Str("peerId", indirectPeer.NodeId).Msg("gossiping about membership with indirect peer") - client := gossipv1connect.NewGossipServiceClient(http.DefaultClient, indirectPeer.RpcAddr) - ctxWithTimeout, cancel := context.WithTimeout(ctx, c.config.GossipTimeout) - defer cancel() - res, err := client.IndirectPing(ctxWithTimeout, connect.NewRequest(&gossipv1.IndirectPingRequest{ - NodeId: peer.NodeId, - RpcAddr: peer.RpcAddr, - })) - if err != nil { - return fault.Wrap(err, fmsg.With("failed to gossip with indirect peer")) - } - switch res.Msg.State { - case gossipv1.State_State_ALIVE: - c.logger.Debug().Str("peerId", indirectPeer.NodeId).Msg("indirect peer is alive") - default: - c.logger.Debug().Str("peerId", indirectPeer.NodeId).Msg("indirect peer is not alive") - c.removeMemberFromState(ctx, peer.NodeId) - } - - } - } - - // // sync with one random node - - // peers, err = c.randomPeers(1) - // if err != nil { - // return fault.Wrap(err, fmsg.With("failed to find peers to sync with")) - // } - // client := gossipv1connect.NewGossipServiceClient(http.DefaultClient, peers[0].RpcAddr) - // ctxWithTimeout, cancel := context.WithTimeout(ctx, c.config.GossipTimeout) - // defer cancel() - - // arr := []*gossipv1.Member{} - // c.RLock() - // for _, m := range c.members { - // arr = append(arr, m) - // } - // c.RUnlock() - // res, err := client.SyncMembers(ctxWithTimeout, connect.NewRequest(&gossipv1.SyncMembersRequest{ - // Members: arr, - // })) - // if err != nil { - // return fault.Wrap(err, fmsg.With("failed to sync with peer")) - // } - - // c.Lock() - // defer c.Unlock() - // for _, m := range res.Msg.Members { - // _, ok := c.members[m.NodeId] - // if !ok { - // c.members[m.NodeId] = m - // } else if m.State == gossipv1.State_State_ALIVE { - // c.members[m.NodeId] = m - // } - // } - - return nil - -} diff --git a/web/apps/agent/pkg/gossip/connect.go b/web/apps/agent/pkg/gossip/connect.go deleted file mode 100644 index 2c09024da4..0000000000 --- a/web/apps/agent/pkg/gossip/connect.go +++ /dev/null @@ -1,120 +0,0 @@ -package gossip - -import ( - "context" - "net/http" - "net/url" - - "connectrpc.com/connect" - "connectrpc.com/otelconnect" - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" - gossipv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/gossip/v1" - "github.com/unkeyed/unkey/svc/agent/gen/proto/gossip/v1/gossipv1connect" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "golang.org/x/net/http2" - "golang.org/x/net/http2/h2c" -) - -type clusterServer struct { - svc *cluster - logger logging.Logger - close chan struct{} - gossipv1connect.UnimplementedGossipServiceHandler -} - -func NewClusterServer(svc *cluster, logger logging.Logger) *clusterServer { - - return &clusterServer{ - svc: svc, - logger: logger, - close: make(chan struct{}), - } -} - -func (s *clusterServer) CreateHandler() (string, http.Handler, error) { - otelInterceptor, err := otelconnect.NewInterceptor() - if err != nil { - return "", nil, err - } - - path, handler := gossipv1connect.NewGossipServiceHandler(s, connect.WithInterceptors(otelInterceptor)) - return path, handler, nil -} - -func (c *clusterServer) Serve() error { - - mux := http.NewServeMux() - - path, handler, err := c.CreateHandler() - if err != nil { - return fault.Wrap(err, fmsg.With("failed to create handler")) - } - mux.Handle(path, handler) - - u, err := url.Parse(c.svc.self.RpcAddr) - if err != nil { - return fault.Wrap(err, fmsg.With("failed to parse self rpc addr")) - } - - srv := &http.Server{Addr: u.Host, Handler: h2c.NewHandler(mux, &http2.Server{})} - - c.logger.Info().Str("addr", u.Host).Msg("listening") - - go func() { - <-c.close - _ = srv.Close() - }() - - return srv.ListenAndServe() -} - -func (s *clusterServer) Join( - ctx context.Context, - req *connect.Request[gossipv1.JoinRequest], -) (*connect.Response[gossipv1.JoinResponse], error) { - - res, err := s.svc.join(ctx, req.Msg) - - return connect.NewResponse(res), err -} - -func (s *clusterServer) Leave( - ctx context.Context, - req *connect.Request[gossipv1.LeaveRequest], -) (*connect.Response[gossipv1.LeaveResponse], error) { - - res, err := s.svc.leave(ctx, req.Msg) - - return connect.NewResponse(res), err -} - -func (s *clusterServer) Ping( - ctx context.Context, - req *connect.Request[gossipv1.PingRequest], -) (*connect.Response[gossipv1.PingResponse], error) { - - res, err := s.svc.ping(ctx, req.Msg) - - return connect.NewResponse(res), err -} - -func (s *clusterServer) IndirectPing( - ctx context.Context, - req *connect.Request[gossipv1.IndirectPingRequest], -) (*connect.Response[gossipv1.IndirectPingResponse], error) { - - res, err := s.svc.indirectPing(ctx, req.Msg) - - return connect.NewResponse(res), err -} - -func (s *clusterServer) SyncMembers( - ctx context.Context, - req *connect.Request[gossipv1.SyncMembersRequest], -) (*connect.Response[gossipv1.SyncMembersResponse], error) { - - res, err := s.svc.syncMembers(ctx, req.Msg) - - return connect.NewResponse(res), err -} diff --git a/web/apps/agent/pkg/gossip/interface.go b/web/apps/agent/pkg/gossip/interface.go deleted file mode 100644 index e938e517a7..0000000000 --- a/web/apps/agent/pkg/gossip/interface.go +++ /dev/null @@ -1,26 +0,0 @@ -package gossip - -import ( - "context" - "crypto/sha256" -) - -type Member struct { - NodeId string - RpcAddr string -} - -// Hash returns a hash of the member to detect duplicates or changes. -func (m Member) Hash() []byte { - h := sha256.New() - h.Write([]byte(m.NodeId)) - h.Write([]byte(m.RpcAddr)) - return h.Sum(nil) -} - -type Cluster interface { - SubscribeJoinEvents(callerName string) <-chan Member - SubscribeLeaveEvents(callerName string) <-chan Member - Join(ctx context.Context, addrs ...string) error - Shutdown(ctx context.Context) error -} diff --git a/web/apps/agent/pkg/gossip/rpc.go b/web/apps/agent/pkg/gossip/rpc.go deleted file mode 100644 index d8b983d0da..0000000000 --- a/web/apps/agent/pkg/gossip/rpc.go +++ /dev/null @@ -1,136 +0,0 @@ -package gossip - -import ( - "bytes" - "context" - "net/http" - - "connectrpc.com/connect" - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" - gossipv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/gossip/v1" - "github.com/unkeyed/unkey/svc/agent/gen/proto/gossip/v1/gossipv1connect" - "google.golang.org/protobuf/proto" -) - -func (c *cluster) join(ctx context.Context, req *gossipv1.JoinRequest) (*gossipv1.JoinResponse, error) { - c.logger.Info().Str("peerId", req.Self.NodeId).Msg("peer is asking to join") - - newMember := Member{ - NodeId: req.Self.NodeId, - RpcAddr: req.Self.RpcAddr, - } - - c.Lock() - defer c.Unlock() - - existing, ok := c.members[req.Self.NodeId] - if !ok { - c.memberJoinTopic.Emit(ctx, newMember) - c.members[req.Self.NodeId] = req.Self - } else { - e, err := proto.Marshal(existing) - if err != nil { - return nil, fault.Wrap(err, fmsg.With("failed to marshal existing member")) - } - j, err := proto.Marshal(req.Self) - if err != nil { - return nil, fault.Wrap(err, fmsg.With("failed to marshal new member")) - } - if !bytes.Equal(e, j) { - c.memberUpdateTopic.Emit(ctx, newMember) - c.members[req.Self.NodeId] = req.Self - } - - } - - members := []*gossipv1.Member{} - for _, m := range c.members { - members = append(members, m) - } - - return &gossipv1.JoinResponse{ - Members: members, - }, nil -} - -func (c *cluster) leave(ctx context.Context, req *gossipv1.LeaveRequest) (*gossipv1.LeaveResponse, error) { - c.Lock() - delete(c.members, req.Self.NodeId) - c.Unlock() - c.memberLeaveTopic.Emit(ctx, Member{ - NodeId: req.Self.NodeId, - RpcAddr: req.Self.RpcAddr, - }) - - return &gossipv1.LeaveResponse{}, nil -} - -func (c *cluster) ping( - ctx context.Context, - req *gossipv1.PingRequest, -) (*gossipv1.PingResponse, error) { - - return &gossipv1.PingResponse{ - State: gossipv1.State_State_ALIVE, - }, nil -} - -func (c *cluster) indirectPing( - ctx context.Context, - req *gossipv1.IndirectPingRequest, -) (*gossipv1.IndirectPingResponse, error) { - peer := gossipv1connect.NewGossipServiceClient(http.DefaultClient, req.RpcAddr) - - pong, err := peer.Ping(ctx, connect.NewRequest(&gossipv1.PingRequest{})) - - switch pong.Msg.State { - case gossipv1.State_State_ALIVE: - - default: - c.removeMemberFromState(ctx, req.NodeId) - } - - if err != nil { - return nil, fault.Wrap(err, fmsg.With("unable to ping peer")) - } - - return &gossipv1.IndirectPingResponse{ - State: pong.Msg.State, - }, nil -} - -func (c *cluster) syncMembers( - ctx context.Context, - req *gossipv1.SyncMembersRequest, -) (*gossipv1.SyncMembersResponse, error) { - c.Lock() - defer c.Unlock() - - union := map[string]*gossipv1.Member{} - // Add all existing members to the union - for _, m := range c.members { - union[m.NodeId] = m - } - - // Add all new members to the union - for _, m := range req.Members { - _, ok := union[m.NodeId] - if !ok { - union[m.NodeId] = m - } else if m.State == gossipv1.State_State_ALIVE { - union[m.NodeId] = m - } - } - - arr := []*gossipv1.Member{} - for _, m := range union { - arr = append(arr, m) - } - c.members = union - - return &gossipv1.SyncMembersResponse{ - Members: arr, - }, nil - -} diff --git a/web/apps/agent/pkg/gossip/server_test.goxx b/web/apps/agent/pkg/gossip/server_test.goxx deleted file mode 100644 index d7f5aa1049..0000000000 --- a/web/apps/agent/pkg/gossip/server_test.goxx +++ /dev/null @@ -1,160 +0,0 @@ -package gossip - -import ( - "fmt" - "math/rand" - "testing" - "time" - - "github.com/rs/zerolog" - "github.com/stretchr/testify/require" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/port" -) - -var CLUSTER_SIZES = []int{3, 9, 27} - -func TestMembershipChangesArePropagatedToHashRing(t *testing.T) { - - for _, clusterSize := range CLUSTER_SIZES { - - t.Run(fmt.Sprintf("cluster size %d", clusterSize), func(t *testing.T) { - - clusters := []*cluster{} - - // Starting clusters - for i := 1; i <= clusterSize; i++ { - c := createCluster(t, fmt.Sprintf("node_%d", i)) - clusters = append(clusters, c) - addrs := []string{} - for _, c := range clusters { - addrs = append(addrs, c.membership.SerfAddr()) - } - _, err := c.membership.Join(addrs...) - require.NoError(t, err) - - // Check if the hash rings are updated - for _, peer := range clusters { - - require.Eventually(t, func() bool { - - t.Logf("%s, clusters: %d, peer.ring.Members(): %d", peer.id, len(clusters), len(peer.ring.Members())) - - return len(peer.ring.Members()) == len(clusters) - }, time.Minute, 100*time.Millisecond) - } - } - - // Stopping clusters - - for len(clusters) > 0 { - - i := rand.Intn(len(clusters)) - - c := clusters[i] - - err := c.membership.Leave() - require.NoError(t, err) - clusters = append(clusters[:i], clusters[i+1:]...) - - // Check if the hash rings are updated - for _, peer := range clusters { - - require.Eventually(t, func() bool { - t.Logf("%s, clusters: %d, peer.ring.Members(): %d", peer.id, len(clusters), len(peer.ring.Members())) - - return len(peer.ring.Members()) == len(clusters) - }, 5*time.Minute, 100*time.Millisecond) - } - - } - - }) - } - -} - -func createCluster(t *testing.T, nodeId string) *cluster { - t.Helper() - - logger := logging.New(nil).With().Str("nodeId", nodeId).Logger().Level(zerolog.ErrorLevel) - rpcAddr := fmt.Sprintf("http://localhost:%d", port.Get()) - - m, err := membership.New(membership.Config{ - NodeId: nodeId, - Logger: logger, - SerfAddr: fmt.Sprintf("localhost:%d", port.Get()), - RpcAddr: rpcAddr, - }) - require.NoError(t, err) - - c, err := New(Config{ - NodeId: nodeId, - Membership: m, - Logger: logger, - Debug: true, - RpcAddr: rpcAddr, - AuthToken: "test-auth-token", - }) - require.NoError(t, err) - - return c - -} - -func TestFindNodeIsConsistent(t *testing.T) { - - for _, clusterSize := range CLUSTER_SIZES { - - t.Run(fmt.Sprintf("cluster size %d", clusterSize), func(t *testing.T) { - - clusters := []*cluster{} - - // Starting clusters - for i := 1; i <= clusterSize; i++ { - c := createCluster(t, fmt.Sprintf("node_%d", i)) - clusters = append(clusters, c) - addrs := []string{} - for _, c := range clusters { - addrs = append(addrs, c.membership.SerfAddr()) - } - _, err := c.membership.Join(addrs...) - require.NoError(t, err) - } - - // key -> nodeId -> count - counters := make(map[string]map[string]int) - - keys := make([]string, 10000) - for i := range keys { - keys[i] = fmt.Sprintf("key-%d", i) - } - - // Run the simulation - for i := 0; i < 1_000_000; i++ { - key := keys[rand.Intn(len(keys))] - node := clusters[rand.Intn(len(clusters))] - found, err := node.FindNode(key) - require.NoError(t, err) - counter, ok := counters[key] - if !ok { - counter = make(map[string]int) - counters[key] = counter - } - _, ok = counter[found.Id] - if !ok { - counter[found.Id] = 0 - } - counter[found.Id]++ - - } - // t.Logf("counters: %+v", counters) - - for _, foundNodes := range counters { - require.Len(t, foundNodes, 1) - } - - }) - } - -} diff --git a/web/apps/agent/pkg/gossip/test_utils_server.go b/web/apps/agent/pkg/gossip/test_utils_server.go deleted file mode 100644 index fdedf9ac21..0000000000 --- a/web/apps/agent/pkg/gossip/test_utils_server.go +++ /dev/null @@ -1,8 +0,0 @@ -package gossip - -// _testSimulateFailure is a test helper function that simulates a failure in the cluster -// by shutting down the connect server, so other members can no longer ping it. -func (s *clusterServer) _testSimulateFailure() { - close(s.close) - -} diff --git a/web/apps/agent/pkg/heartbeat/heartbeat.go b/web/apps/agent/pkg/heartbeat/heartbeat.go deleted file mode 100644 index e7c6ec47e2..0000000000 --- a/web/apps/agent/pkg/heartbeat/heartbeat.go +++ /dev/null @@ -1,59 +0,0 @@ -package heartbeat - -import ( - "net/http" - "time" - - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/repeat" -) - -type Heartbeat struct { - logger logging.Logger - url string - interval time.Duration -} - -type Config struct { - Logger logging.Logger - Url string - Interval time.Duration -} - -func New(config Config) *Heartbeat { - - h := &Heartbeat{ - url: config.Url, - logger: config.Logger, - interval: config.Interval, - } - if h.interval == 0 { - h.interval = time.Minute - } - return h -} - -// Starts a timer that sends a POST request to the URL every interval -// This function is running in a goroutine and will not block the caller. -func (h *Heartbeat) RunAsync() { - // Tracks how many errors in a row have occurred when sending the heartbeat - // If a heartbeat succeeds it is reset to 0 - errorsInARow := 0 - - repeat.Every(h.interval, func() { - h.logger.Debug().Msg("sending heartbeat") - res, err := http.Post(h.url, "", nil) - if err != nil { - errorsInARow++ - if errorsInARow >= 3 { - h.logger.Err(err).Int("errorsInARow", errorsInARow).Msg("error sending heartbeat") - } - return - } - errorsInARow = 0 - err = res.Body.Close() - if err != nil { - h.logger.Err(err).Msg("error closing response body") - } - }) -} diff --git a/web/apps/agent/pkg/logging/axiom.go b/web/apps/agent/pkg/logging/axiom.go deleted file mode 100644 index 8e09b0311c..0000000000 --- a/web/apps/agent/pkg/logging/axiom.go +++ /dev/null @@ -1,66 +0,0 @@ -package logging - -import ( - "context" - "encoding/json" - - "log" - "time" - - "github.com/Southclaws/fault" - ax "github.com/axiomhq/axiom-go/axiom" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" -) - -type AxiomWriter struct { - eventsC chan ax.Event -} - -type AxiomWriterConfig struct { - Dataset string - Token string -} - -func NewAxiomWriter(config AxiomWriterConfig) (*AxiomWriter, error) { - - client, err := ax.NewClient( - ax.SetToken(config.Token), - ) - if err != nil { - return nil, fault.New("unable to create axiom client") - } - a := &AxiomWriter{ - eventsC: make(chan ax.Event, 10_000), - } - - go func() { - _, err := client.IngestChannel(context.Background(), config.Dataset, a.eventsC) - if err != nil { - log.Print("unable to ingest to axiom") - } - }() - - return a, nil -} - -func (aw *AxiomWriter) Close() { - close(aw.eventsC) -} - -func (aw *AxiomWriter) Write(p []byte) (int, error) { - ctx, span := tracing.Start(context.Background(), "axiom.Write") - defer span.End() - - e := make(map[string]any) - - err := json.Unmarshal(p, &e) - if err != nil { - return 0, err - } - e["_time"] = time.Now().UnixMilli() - - _, span2 := tracing.Start(ctx, "ingest channel") - aw.eventsC <- e - span2.End() - return len(p), nil -} diff --git a/web/apps/agent/pkg/logging/logger.go b/web/apps/agent/pkg/logging/logger.go deleted file mode 100644 index c96f56e77b..0000000000 --- a/web/apps/agent/pkg/logging/logger.go +++ /dev/null @@ -1,57 +0,0 @@ -package logging - -import ( - "fmt" - "io" - "os" - "strconv" - "strings" - - "github.com/rs/zerolog" -) - -type Logger = zerolog.Logger - -const timeFormat = "2006-01-02T15:04:05.000MST" - -type Config struct { - Debug bool - Writer []io.Writer - Color bool -} - -func init() { - zerolog.CallerMarshalFunc = func(pc uintptr, file string, line int) string { - return fmt.Sprintf("%s:%s", - strings.TrimPrefix(file, "/go/src/github.com/unkeyed/unkey/svc/agent/"), - strconv.Itoa(line)) - } -} - -func New(config *Config) Logger { - if config == nil { - config = &Config{} - } - - consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: timeFormat, NoColor: !config.Color} - - writers := []io.Writer{consoleWriter} - if len(config.Writer) > 0 { - writers = append(writers, config.Writer...) - } - - multi := zerolog.MultiLevelWriter(writers...) - - logger := zerolog.New(multi).With().Timestamp().Caller().Logger() - if config.Debug { - logger = logger.Level(zerolog.DebugLevel) - } else { - logger = logger.Level(zerolog.InfoLevel) - } - - return logger -} - -func NewNoopLogger() Logger { - return zerolog.Nop() -} diff --git a/web/apps/agent/pkg/membership/interface.go b/web/apps/agent/pkg/membership/interface.go deleted file mode 100644 index c756b80ed8..0000000000 --- a/web/apps/agent/pkg/membership/interface.go +++ /dev/null @@ -1,13 +0,0 @@ -package membership - -type Membership interface { - Join(addrs ...string) (int, error) - Leave() error - Members() ([]Member, error) - SerfAddr() string - SubscribeJoinEvents() <-chan Member - - SubscribeLeaveEvents() <-chan Member - - NodeId() string -} diff --git a/web/apps/agent/pkg/membership/member.go b/web/apps/agent/pkg/membership/member.go deleted file mode 100644 index d2be4e945e..0000000000 --- a/web/apps/agent/pkg/membership/member.go +++ /dev/null @@ -1,72 +0,0 @@ -package membership - -import ( - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" -) - -// utility to convert a map of tags to a Member struct -func memberFromTags(tags map[string]string) (Member, error) { - m := Member{} - err := m.Unmarshal(tags) - if err != nil { - return m, fault.Wrap(err, fmsg.With("failed to unmarshal tags")) - } - return m, nil -} - -type Member struct { - // Global unique identifier for the node - NodeId string `json:"nodeId"` - RpcAddr string `json:"addr"` - SerfAddr string `json:"serfAddr"` - State string `json:"state"` -} - -func (m *Member) Marshal() (map[string]string, error) { - out := make(map[string]string) - if m.NodeId == "" { - return nil, fault.New("NodeId is empty") - } - out["node_id"] = m.NodeId - - if m.SerfAddr == "" { - return nil, fault.New("SerfAddr is empty") - } - out["serf_addr"] = m.SerfAddr - - if m.RpcAddr == "" { - return nil, fault.New("RpcAddr is empty") - } - out["rpc_addr"] = m.RpcAddr - - if m.State == "" { - return nil, fault.New("State is empty") - } - out["state"] = m.State - - return out, nil -} - -func (t *Member) Unmarshal(m map[string]string) error { - var ok bool - t.NodeId, ok = m["node_id"] - if !ok { - return fault.New("NodeId is missing") - } - t.RpcAddr, ok = m["rpc_addr"] - if !ok { - return fault.New("RpcAddr is missing") - - } - t.SerfAddr, ok = m["serf_addr"] - if !ok { - return fault.New("SerfAddr is missing") - } - t.State, ok = m["state"] - if !ok { - return fault.New("State is missing") - } - - return nil -} diff --git a/web/apps/agent/pkg/membership/serf.go b/web/apps/agent/pkg/membership/serf.go deleted file mode 100644 index cace42ba0d..0000000000 --- a/web/apps/agent/pkg/membership/serf.go +++ /dev/null @@ -1,200 +0,0 @@ -package membership - -import ( - "context" - "fmt" - "net" - "sync" - "time" - - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" - "github.com/hashicorp/serf/serf" - "github.com/unkeyed/unkey/svc/agent/pkg/events" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/util" -) - -type Config struct { - NodeId string - SerfAddr string - Logger logging.Logger - RpcAddr string -} - -type gossipEvent struct { - event string - payload []byte -} - -type membership struct { - sync.Mutex - serfAddr string - - self Member - joinEvents events.Topic[Member] - leaveEvents events.Topic[Member] - gossipEvents events.Topic[gossipEvent] - serf *serf.Serf - events chan serf.Event - logger logging.Logger - started bool -} - -func New(config Config) (Membership, error) { - m := &membership{ - serfAddr: config.SerfAddr, - self: Member{ - NodeId: config.NodeId, - SerfAddr: config.SerfAddr, - RpcAddr: config.RpcAddr, - State: "alive", - }, - logger: config.Logger.With().Str("node", config.NodeId).Str("SerfAddr", config.SerfAddr).Logger(), - joinEvents: events.NewTopic[Member](), - leaveEvents: events.NewTopic[Member](), - gossipEvents: events.NewTopic[gossipEvent](), - } - - return m, nil -} -func (m *membership) NodeId() string { - return m.self.NodeId -} - -func (m *membership) SerfAddr() string { - return m.serfAddr -} -func (m *membership) SubscribeJoinEvents() <-chan Member { - return m.joinEvents.Subscribe("serfJoinEvents") -} - -func (m *membership) SubscribeLeaveEvents() <-chan Member { - return m.leaveEvents.Subscribe("serfLeaveEvents") -} - -func (m *membership) SubscribeGossipEvents() <-chan gossipEvent { - return m.gossipEvents.Subscribe("serfGossipEvents") -} - -func (m *membership) Shutdown() error { - err := m.serf.Leave() - if err != nil { - return fmt.Errorf("Failed to leave serf: %w", err) - } - return m.serf.Shutdown() -} -func (m *membership) Join(joinAddrs ...string) (int, error) { - m.Lock() - defer m.Unlock() - if m.started { - return 0, fault.New("Membership already started") - } - m.started = true - m.logger.Info().Msg("Initilizing serf") - - addr, err := net.ResolveTCPAddr("tcp", m.serfAddr) - if err != nil { - return 0, fault.Wrap(err, fmsg.With("Failed to resolve serf address")) - } - config := serf.DefaultConfig() - config.MemberlistConfig.BindAddr = addr.IP.String() - config.MemberlistConfig.BindPort = addr.Port - - m.events = make(chan serf.Event) - config.EventCh = m.events - config.Tags, err = m.self.Marshal() - if err != nil { - return 0, fault.Wrap(err, fmsg.With("Failed to convert tags to map")) - } - config.NodeName = m.self.NodeId - - m.serf, err = serf.Create(config) - if err != nil { - return 0, fault.Wrap(err, fmsg.With("Failed to create serf")) - } - - m.logger.Info().Msg("Config is initialized") - - go m.eventHandler() - if len(joinAddrs) > 0 { - m.logger.Info().Strs("addrs", joinAddrs).Msg("Joining serf cluster") - err = util.Retry( - func() error { - successfullyContacted, joinErr := m.serf.Join(joinAddrs, true) - if joinErr != nil { - m.logger.Warn().Err(joinErr).Int("successfullyContacted", successfullyContacted).Strs("addrs", joinAddrs).Msg("Failed to join") - } - return joinErr - }, - 10, - func(n int) time.Duration { return time.Duration(n) * time.Second }, - ) - if err != nil { - return 0, fault.Wrap(err, fmsg.With("Failed to join")) - } - - } - - return m.serf.Memberlist().NumMembers(), nil -} - -func (m *membership) Broadcast(eventType string, payload []byte) error { - return m.serf.UserEvent(eventType, payload, true) -} -func (m *membership) eventHandler() { - - for e := range m.events { - ctx := context.Background() - - m.logger.Info().Str("type", e.EventType().String()).Msg("Event") - switch e.EventType() { - case serf.EventMemberJoin: - for _, serfMember := range e.(serf.MemberEvent).Members { - - member, err := memberFromTags(serfMember.Tags) - if err != nil { - m.logger.Error().Err(err).Msg("Failed to unmarshal tags") - continue - } - m.joinEvents.Emit(ctx, member) - } - case serf.EventMemberLeave, serf.EventMemberFailed: - for _, serfMember := range e.(serf.MemberEvent).Members { - member, err := memberFromTags(serfMember.Tags) - if err != nil { - m.logger.Error().Err(err).Msg("Failed to unmarshal tags") - continue - } - m.leaveEvents.Emit(ctx, member) - } - case serf.EventUser: - m.gossipEvents.Emit(ctx, gossipEvent{ - event: e.(serf.UserEvent).Name, - payload: e.(serf.UserEvent).Payload, - }) - } - - } -} - -func (m *membership) isLocal(member serf.Member) bool { - return member.Name == m.self.NodeId -} - -func (m *membership) Members() ([]Member, error) { - members := make([]Member, 0) - for _, serfMember := range m.serf.Members() { - if serfMember.Status == serf.StatusAlive { - member, err := memberFromTags(serfMember.Tags) - if err != nil { - return nil, fault.Wrap(err, fmsg.With("Failed to unmarshal tags")) - } - members = append(members, member) - } - } - return members, nil -} -func (m *membership) Leave() error { - return m.serf.Leave() -} diff --git a/web/apps/agent/pkg/metrics/axiom.go b/web/apps/agent/pkg/metrics/axiom.go deleted file mode 100644 index 06795dd702..0000000000 --- a/web/apps/agent/pkg/metrics/axiom.go +++ /dev/null @@ -1,104 +0,0 @@ -package metrics - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "time" - - "github.com/unkeyed/unkey/svc/agent/pkg/batch" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/util" -) - -type axiom struct { - region string - nodeId string - batcher *batch.BatchProcessor[map[string]any] -} - -type Config struct { - Token string - NodeId string - Region string - Logger logging.Logger - Dataset string -} - -func New(config Config) (*axiom, error) { - - client := http.DefaultClient - - batcher := batch.New(batch.Config[map[string]any]{ - BatchSize: 1000, - FlushInterval: time.Second, - BufferSize: 10000, - Flush: func(ctx context.Context, batch []map[string]any) { - buf, err := json.Marshal(batch) - if err != nil { - config.Logger.Err(err).Msg("failed to marshal events") - return - } - - req, err := http.NewRequest( - http.MethodPost, - fmt.Sprintf("https://api.axiom.co/v1/datasets/%s/ingest", config.Dataset), - bytes.NewBuffer(buf), - ) - if err != nil { - config.Logger.Err(err).Msg("failed to create request") - return - } - req.Header.Set("Content-Type", "application/json") - req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", config.Token)) - - resp, err := client.Do(req) - if err != nil { - config.Logger.Err(err).Msg("failed to send request") - return - } - defer resp.Body.Close() - if resp.StatusCode != 200 { - body, err := io.ReadAll(resp.Body) - if err != nil { - config.Logger.Err(err).Msg("failed to read response body") - return - } - config.Logger.Error().Str("body", string(body)).Int("status", resp.StatusCode).Msg("failed to ingest events") - return - } - - }, - }) - a := &axiom{ - region: config.Region, - nodeId: config.NodeId, - batcher: batcher, - } - - return a, nil -} - -func (a *axiom) Close() { - a.batcher.Close() -} - -func (a *axiom) merge(m Metric, now time.Time) map[string]any { - - data := util.StructToMap(m) - data["metric"] = m.Name() - data["_time"] = now.UnixMilli() - data["nodeId"] = a.nodeId - data["region"] = a.region - data["application"] = "agent" - - return data -} - -func (a *axiom) Record(m Metric) { - - a.batcher.Buffer(a.merge(m, time.Now())) -} diff --git a/web/apps/agent/pkg/metrics/axiom_test.go b/web/apps/agent/pkg/metrics/axiom_test.go deleted file mode 100644 index e6846be7aa..0000000000 --- a/web/apps/agent/pkg/metrics/axiom_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package metrics - -import ( - "encoding/json" - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/uid" -) - -type fakeMetric struct { - Value string `json:"value"` - Another bool `json:"another"` -} - -func (fm fakeMetric) Name() string { - return "metric.fake" -} - -func TestMerge(t *testing.T) { - - nodeId := uid.New("") - region := "test" - now := time.Now() - - ax, err := New(Config{ - Token: "", - NodeId: nodeId, - Region: region, - Logger: logging.NewNoopLogger(), - Dataset: "", - }) - - require.NoError(t, err) - - fm := fakeMetric{ - Value: uid.New(""), - Another: true, - } - - merged := ax.merge(fm, now) - b, err := json.Marshal(merged) - require.NoError(t, err) - - expected := map[string]any{ - "value": fm.Value, - "another": fm.Another, - "_time": now.UnixMilli(), - "metric": "metric.fake", - "nodeId": nodeId, - "region": "test", - "application": "agent", - } - - e, err := json.Marshal(expected) - require.NoError(t, err) - - require.JSONEq(t, string(e), string(b)) - -} diff --git a/web/apps/agent/pkg/metrics/interface.go b/web/apps/agent/pkg/metrics/interface.go deleted file mode 100644 index 82aa293808..0000000000 --- a/web/apps/agent/pkg/metrics/interface.go +++ /dev/null @@ -1,18 +0,0 @@ -package metrics - -type Metrics interface { - Record(metric Metric) - Close() -} - -// Metric is the interface that all metrics must implement to be recorded by -// the metrics package -// -// A metric must have a name that is unique within the system -// The remaining public fields are up to the caller and will be serialized to -// JSON when recorded. -type Metric interface { - // The name of the metric - // e.g. "metric.cache.hit" - Name() string -} diff --git a/web/apps/agent/pkg/metrics/metrics.go b/web/apps/agent/pkg/metrics/metrics.go deleted file mode 100644 index 0d641d0347..0000000000 --- a/web/apps/agent/pkg/metrics/metrics.go +++ /dev/null @@ -1,11 +0,0 @@ -package metrics - -type RingState struct { - Nodes int `json:"nodes"` - Tokens int `json:"tokens"` - State string `json:"state"` -} - -func (m RingState) Name() string { - return "metric.ring.state" -} diff --git a/web/apps/agent/pkg/metrics/noop.go b/web/apps/agent/pkg/metrics/noop.go deleted file mode 100644 index 4cde852eca..0000000000 --- a/web/apps/agent/pkg/metrics/noop.go +++ /dev/null @@ -1,13 +0,0 @@ -package metrics - -type noop struct { -} - -func NewNoop() Metrics { - return &noop{} - -} - -func (n *noop) Close() {} - -func (n *noop) Record(metric Metric) {} diff --git a/web/apps/agent/pkg/mutex/traced.go b/web/apps/agent/pkg/mutex/traced.go deleted file mode 100644 index 5eac9ba23b..0000000000 --- a/web/apps/agent/pkg/mutex/traced.go +++ /dev/null @@ -1,43 +0,0 @@ -package mutex - -import ( - "context" - "sync" - - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" -) - -// Lock is a wrapper around sync.RWMutex that traces lock and unlock operations. -type TraceLock struct { - mu sync.RWMutex -} - -func New() *TraceLock { - return &TraceLock{ - mu: sync.RWMutex{}, - } -} - -func (l *TraceLock) Lock(ctx context.Context) { - _, span := tracing.Start(ctx, "Lock") - defer span.End() - l.mu.Lock() -} - -func (l *TraceLock) RLock(ctx context.Context) { - _, span := tracing.Start(ctx, "RLock") - defer span.End() - l.mu.RLock() -} - -func (l *TraceLock) Unlock(ctx context.Context) { - _, span := tracing.Start(ctx, "RUnlock") - defer span.End() - l.mu.Unlock() -} - -func (l *TraceLock) RUnlock(ctx context.Context) { - _, span := tracing.Start(ctx, "RUnlock") - defer span.End() - l.mu.RUnlock() -} diff --git a/web/apps/agent/pkg/openapi/config.yaml b/web/apps/agent/pkg/openapi/config.yaml deleted file mode 100644 index c2959e8d1e..0000000000 --- a/web/apps/agent/pkg/openapi/config.yaml +++ /dev/null @@ -1,6 +0,0 @@ -package: openapi -output: ./pkg/openapi/gen.go -generate: - models: true -output-options: - nullable-type: true diff --git a/web/apps/agent/pkg/openapi/gen.go b/web/apps/agent/pkg/openapi/gen.go deleted file mode 100644 index 61ba7ada85..0000000000 --- a/web/apps/agent/pkg/openapi/gen.go +++ /dev/null @@ -1,284 +0,0 @@ -// Package openapi provides primitives to interact with the openapi HTTP API. -// -// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.3.0 DO NOT EDIT. -package openapi - -// BaseError defines model for BaseError. -type BaseError struct { - // Detail A human-readable explanation specific to this occurrence of the problem. - Detail string `json:"detail"` - - // Instance A URI reference that identifies the specific occurrence of the problem. - Instance string `json:"instance"` - - // RequestId A unique id for this request. Please always provide this to support. - RequestId string `json:"requestId"` - - // Status HTTP status code - Status int `json:"status"` - - // Title A short, human-readable summary of the problem type. This value should not change between occurrences of the error. - Title string `json:"title"` - - // Type A URI reference to human-readable documentation for the error. - Type string `json:"type"` -} - -// Encrypted defines model for Encrypted. -type Encrypted struct { - Encrypted string `json:"encrypted"` - KeyId string `json:"keyId"` -} - -// Item defines model for Item. -type Item struct { - // Cost The cost of the request. - Cost *int64 `json:"cost,omitempty"` - - // Duration The duration in milliseconds for the rate limit window. - Duration int64 `json:"duration"` - - // Identifier The identifier for the rate limit. - Identifier string `json:"identifier"` - - // Limit The maximum number of requests allowed. - Limit int64 `json:"limit"` -} - -// Lease defines model for Lease. -type Lease struct { - // Cost How much to lease. - Cost int64 `json:"cost"` - - // Timeout The time in milliseconds when the lease will expire. If you do not commit the lease by this time, it will be commited as is. - Timeout int64 `json:"timeout"` -} - -// SingleRatelimitResponse defines model for SingleRatelimitResponse. -type SingleRatelimitResponse struct { - // Current The current number of requests made in the current window. - Current int64 `json:"current"` - - // Limit The maximum number of requests allowed. - Limit int64 `json:"limit"` - - // Remaining The number of requests remaining in the current window. - Remaining int64 `json:"remaining"` - - // Reset The time in milliseconds when the rate limit will reset. - Reset int64 `json:"reset"` - - // Success Whether the request passed the ratelimit. If false, the request must be blocked. - Success bool `json:"success"` -} - -// V0EventsRequestBody NDJSON payload of events -type V0EventsRequestBody = string - -// V0EventsResponseBody defines model for V0EventsResponseBody. -type V0EventsResponseBody struct { - // Schema A URL to the JSON Schema for this object. - Schema *string `json:"$schema,omitempty"` - - // QuarantinedRows The number of rows that were quarantined - QuarantinedRows int `json:"quarantined_rows"` - - // SuccessfulRows The number of rows that were successfully processed - SuccessfulRows int `json:"successful_rows"` -} - -// V1DecryptRequestBody defines model for V1DecryptRequestBody. -type V1DecryptRequestBody struct { - // Schema A URL to the JSON Schema for this object. - Schema *string `json:"$schema,omitempty"` - - // Encrypted The encrypted base64 string. - Encrypted string `json:"encrypted"` - - // Keyring The keyring to use for encryption. - Keyring string `json:"keyring"` -} - -// V1DecryptResponseBody defines model for V1DecryptResponseBody. -type V1DecryptResponseBody struct { - // Schema A URL to the JSON Schema for this object. - Schema *string `json:"$schema,omitempty"` - - // Plaintext The plaintext value. - Plaintext string `json:"plaintext"` -} - -// V1EncryptBulkRequestBody defines model for V1EncryptBulkRequestBody. -type V1EncryptBulkRequestBody struct { - // Schema A URL to the JSON Schema for this object. - Schema *string `json:"$schema,omitempty"` - Data []string `json:"data"` - Keyring string `json:"keyring"` -} - -// V1EncryptBulkResponseBody defines model for V1EncryptBulkResponseBody. -type V1EncryptBulkResponseBody struct { - // Schema A URL to the JSON Schema for this object. - Schema *string `json:"$schema,omitempty"` - Encrypted []Encrypted `json:"encrypted"` -} - -// V1EncryptRequestBody defines model for V1EncryptRequestBody. -type V1EncryptRequestBody struct { - // Schema A URL to the JSON Schema for this object. - Schema *string `json:"$schema,omitempty"` - - // Data The data to encrypt. - Data string `json:"data"` - - // Keyring The keyring to use for encryption. - Keyring string `json:"keyring"` -} - -// V1EncryptResponseBody defines model for V1EncryptResponseBody. -type V1EncryptResponseBody struct { - // Schema A URL to the JSON Schema for this object. - Schema *string `json:"$schema,omitempty"` - - // Encrypted The encrypted data as base64 encoded string. - Encrypted string `json:"encrypted"` - - // KeyId The ID of the key used for encryption. - KeyId string `json:"keyId"` -} - -// V1LivenessResponseBody defines model for V1LivenessResponseBody. -type V1LivenessResponseBody struct { - // Schema A URL to the JSON Schema for this object. - Schema *string `json:"$schema,omitempty"` - - // Message Whether we're alive or not - Message string `json:"message"` -} - -// V1RatelimitCommitLeaseRequestBody defines model for V1RatelimitCommitLeaseRequestBody. -type V1RatelimitCommitLeaseRequestBody struct { - // Schema A URL to the JSON Schema for this object. - Schema *string `json:"$schema,omitempty"` - - // Cost The actual cost of the request. - Cost int64 `json:"cost"` - - // Lease The lease you received from the ratelimit response. - Lease string `json:"lease"` -} - -// V1RatelimitMultiRatelimitRequestBody defines model for V1RatelimitMultiRatelimitRequestBody. -type V1RatelimitMultiRatelimitRequestBody struct { - // Schema A URL to the JSON Schema for this object. - Schema *string `json:"$schema,omitempty"` - - // Ratelimits The rate limits to check. - Ratelimits []Item `json:"ratelimits"` -} - -// V1RatelimitMultiRatelimitResponseBody defines model for V1RatelimitMultiRatelimitResponseBody. -type V1RatelimitMultiRatelimitResponseBody struct { - // Schema A URL to the JSON Schema for this object. - Schema *string `json:"$schema,omitempty"` - - // Ratelimits The rate limits that were checked. - Ratelimits []SingleRatelimitResponse `json:"ratelimits"` -} - -// V1RatelimitRatelimitRequestBody defines model for V1RatelimitRatelimitRequestBody. -type V1RatelimitRatelimitRequestBody struct { - // Schema A URL to the JSON Schema for this object. - Schema *string `json:"$schema,omitempty"` - - // Cost The cost of the request. Defaults to 1 if not provided. - Cost *int64 `json:"cost,omitempty"` - - // Duration The duration in milliseconds for the rate limit window. - Duration int64 `json:"duration"` - - // Identifier The identifier for the rate limit. - Identifier string `json:"identifier"` - Lease *Lease `json:"lease,omitempty"` - - // Limit The maximum number of requests allowed. - Limit int64 `json:"limit"` -} - -// V1RatelimitRatelimitResponseBody defines model for V1RatelimitRatelimitResponseBody. -type V1RatelimitRatelimitResponseBody struct { - // Schema A URL to the JSON Schema for this object. - Schema *string `json:"$schema,omitempty"` - - // Current The current number of requests made in the current window. - Current int64 `json:"current"` - - // Lease The lease to use when committing the request. - Lease string `json:"lease"` - - // Limit The maximum number of requests allowed. - Limit int64 `json:"limit"` - - // Remaining The number of requests remaining in the current window. - Remaining int64 `json:"remaining"` - - // Reset The time in milliseconds when the rate limit will reset. - Reset int64 `json:"reset"` - - // Success Whether the request passed the ratelimit. If false, the request must be blocked. - Success bool `json:"success"` -} - -// ValidationError defines model for ValidationError. -type ValidationError struct { - // Detail A human-readable explanation specific to this occurrence of the problem. - Detail string `json:"detail"` - - // Errors Optional list of individual error details - Errors []ValidationErrorDetail `json:"errors"` - - // Instance A URI reference that identifies the specific occurrence of the problem. - Instance string `json:"instance"` - - // RequestId A unique id for this request. Please always provide this to support. - RequestId string `json:"requestId"` - - // Status HTTP status code - Status int `json:"status"` - - // Title A short, human-readable summary of the problem type. This value should not change between occurrences of the error. - Title string `json:"title"` - - // Type A URI reference to human-readable documentation for the error. - Type string `json:"type"` -} - -// ValidationErrorDetail defines model for ValidationErrorDetail. -type ValidationErrorDetail struct { - // Fix A human-readable message describing how to fix the error. - Fix *string `json:"fix,omitempty"` - - // Location Where the error occurred, e.g. 'body.items[3].tags' or 'path.thing-id' - Location string `json:"location"` - - // Message Error message text - Message string `json:"message"` -} - -// RatelimitV1MultiRatelimitJSONRequestBody defines body for RatelimitV1MultiRatelimit for application/json ContentType. -type RatelimitV1MultiRatelimitJSONRequestBody = V1RatelimitMultiRatelimitRequestBody - -// RatelimitV1RatelimitJSONRequestBody defines body for RatelimitV1Ratelimit for application/json ContentType. -type RatelimitV1RatelimitJSONRequestBody = V1RatelimitRatelimitRequestBody - -// V1RatelimitCommitLeaseJSONRequestBody defines body for V1RatelimitCommitLease for application/json ContentType. -type V1RatelimitCommitLeaseJSONRequestBody = V1RatelimitCommitLeaseRequestBody - -// VaultV1DecryptJSONRequestBody defines body for VaultV1Decrypt for application/json ContentType. -type VaultV1DecryptJSONRequestBody = V1DecryptRequestBody - -// VaultV1EncryptJSONRequestBody defines body for VaultV1Encrypt for application/json ContentType. -type VaultV1EncryptJSONRequestBody = V1EncryptRequestBody - -// VaultV1EncryptBulkJSONRequestBody defines body for VaultV1EncryptBulk for application/json ContentType. -type VaultV1EncryptBulkJSONRequestBody = V1EncryptBulkRequestBody diff --git a/web/apps/agent/pkg/openapi/openapi.json b/web/apps/agent/pkg/openapi/openapi.json deleted file mode 100644 index 05b01e58e4..0000000000 --- a/web/apps/agent/pkg/openapi/openapi.json +++ /dev/null @@ -1,898 +0,0 @@ -{ - "components": { - "schemas": { - "V0EventsRequestBody": { - "type": "string", - "description": "NDJSON payload of events" - }, - "V0EventsResponseBody": { - "type": "object", - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "example": "https://api.unkey.dev/schemas/V0EventsResponseBody.json", - "format": "uri", - "readOnly": true, - "type": "string" - }, - "successful_rows": { - "type": "integer", - "description": "The number of rows that were successfully processed" - }, - "quarantined_rows": { - "type": "integer", - "description": "The number of rows that were quarantined" - } - }, - "required": ["successful_rows", "quarantined_rows"] - }, - "Encrypted": { - "additionalProperties": false, - "properties": { - "encrypted": { - "type": "string" - }, - "keyId": { - "type": "string" - } - }, - "required": ["encrypted", "keyId"], - "type": "object" - }, - "ValidationErrorDetail": { - "additionalProperties": false, - "properties": { - "location": { - "description": "Where the error occurred, e.g. 'body.items[3].tags' or 'path.thing-id'", - "type": "string" - }, - "message": { - "description": "Error message text", - "type": "string" - }, - "fix": { - "description": "A human-readable message describing how to fix the error.", - "type": "string" - } - }, - "type": "object", - "required": ["message", "location"] - }, - "ValidationError": { - "additionalProperties": false, - "properties": { - "requestId": { - "description": "A unique id for this request. Please always provide this to support.", - "example": "req_123", - "type": "string" - }, - "detail": { - "description": "A human-readable explanation specific to this occurrence of the problem.", - "example": "Property foo is required but is missing.", - "type": "string" - }, - "errors": { - "description": "Optional list of individual error details", - "items": { - "$ref": "#/components/schemas/ValidationErrorDetail" - }, - "type": ["array"] - }, - "instance": { - "description": "A URI reference that identifies the specific occurrence of the problem.", - "example": "https://example.com/error-log/abc123", - "format": "uri", - "type": "string" - }, - "status": { - "description": "HTTP status code", - "example": 400, - "format": "int", - "type": "integer" - }, - "title": { - "description": "A short, human-readable summary of the problem type. This value should not change between occurrences of the error.", - "example": "Bad Request", - "type": "string" - }, - "type": { - "default": "about:blank", - "description": "A URI reference to human-readable documentation for the error.", - "example": "https://example.com/errors/example", - "format": "uri", - "type": "string" - } - }, - "type": "object", - "required": ["requestId", "detail", "instance", "status", "title", "type", "errors"] - }, - "BaseError": { - "additionalProperties": false, - "properties": { - "requestId": { - "description": "A unique id for this request. Please always provide this to support.", - "example": "req_123", - "type": "string" - }, - "detail": { - "description": "A human-readable explanation specific to this occurrence of the problem.", - "example": "Property foo is required but is missing.", - "type": "string" - }, - "instance": { - "description": "A URI reference that identifies the specific occurrence of the problem.", - "example": "https://example.com/error-log/abc123", - "format": "uri", - "type": "string" - }, - "status": { - "description": "HTTP status code", - "example": 400, - "format": "int", - "type": "integer" - }, - "title": { - "description": "A short, human-readable summary of the problem type. This value should not change between occurrences of the error.", - "example": "Bad Request", - "type": "string" - }, - "type": { - "default": "about:blank", - "description": "A URI reference to human-readable documentation for the error.", - "example": "https://example.com/errors/example", - "format": "uri", - "type": "string" - } - }, - "type": "object", - "required": ["requestId", "detail", "instance", "status", "title", "type", "errors"] - }, - "Item": { - "additionalProperties": false, - "properties": { - "cost": { - "default": 1, - "description": "The cost of the request.", - "format": "int64", - "type": "integer" - }, - "duration": { - "description": "The duration in milliseconds for the rate limit window.", - "format": "int64", - "type": "integer" - }, - "identifier": { - "description": "The identifier for the rate limit.", - "type": "string" - }, - "limit": { - "description": "The maximum number of requests allowed.", - "format": "int64", - "type": "integer" - } - }, - "required": ["identifier", "limit", "duration"], - "type": "object" - }, - "Lease": { - "additionalProperties": false, - "properties": { - "cost": { - "description": "How much to lease.", - "format": "int64", - "type": "integer" - }, - "timeout": { - "description": "The time in milliseconds when the lease will expire. If you do not commit the lease by this time, it will be commited as is.", - "format": "int64", - "type": "integer" - } - }, - "required": ["cost", "timeout"], - "type": "object" - }, - "SingleRatelimitResponse": { - "additionalProperties": false, - "properties": { - "current": { - "description": "The current number of requests made in the current window.", - "format": "int64", - "type": "integer" - }, - "limit": { - "description": "The maximum number of requests allowed.", - "format": "int64", - "type": "integer" - }, - "remaining": { - "description": "The number of requests remaining in the current window.", - "format": "int64", - "type": "integer" - }, - "reset": { - "description": "The time in milliseconds when the rate limit will reset.", - "format": "int64", - "type": "integer" - }, - "success": { - "description": "Whether the request passed the ratelimit. If false, the request must be blocked.", - "type": "boolean" - } - }, - "required": ["limit", "remaining", "reset", "success", "current"], - "type": "object" - }, - "V1DecryptRequestBody": { - "additionalProperties": false, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "example": "https://api.unkey.dev/schemas/V1DecryptRequestBody.json", - "format": "uri", - "readOnly": true, - "type": "string" - }, - "encrypted": { - "description": "The encrypted base64 string.", - "minLength": 1, - "type": "string" - }, - "keyring": { - "description": "The keyring to use for encryption.", - "type": "string" - } - }, - "required": ["keyring", "encrypted"], - "type": "object" - }, - "V1DecryptResponseBody": { - "additionalProperties": false, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "example": "https://api.unkey.dev/schemas/V1DecryptResponseBody.json", - "format": "uri", - "readOnly": true, - "type": "string" - }, - "plaintext": { - "description": "The plaintext value.", - "type": "string" - } - }, - "required": ["plaintext"], - "type": "object" - }, - "V1EncryptBulkRequestBody": { - "additionalProperties": false, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "example": "https://api.unkey.dev/schemas/V1EncryptBulkRequestBody.json", - "format": "uri", - "readOnly": true, - "type": "string" - }, - "data": { - "items": { - "type": "string" - }, - "maxItems": 1000, - "minItems": 1, - "type": ["array"] - }, - "keyring": { - "type": "string" - } - }, - "required": ["keyring", "data"], - "type": "object" - }, - "V1EncryptBulkResponseBody": { - "additionalProperties": false, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "example": "https://api.unkey.dev/schemas/V1EncryptBulkResponseBody.json", - "format": "uri", - "readOnly": true, - "type": "string" - }, - "encrypted": { - "items": { - "$ref": "#/components/schemas/Encrypted" - }, - "type": ["array"] - } - }, - "required": ["encrypted"], - "type": "object" - }, - "V1EncryptRequestBody": { - "additionalProperties": false, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "example": "https://api.unkey.dev/schemas/V1EncryptRequestBody.json", - "format": "uri", - "readOnly": true, - "type": "string" - }, - "data": { - "description": "The data to encrypt.", - "minLength": 1, - "type": "string" - }, - "keyring": { - "description": "The keyring to use for encryption.", - "type": "string" - } - }, - "required": ["keyring", "data"], - "type": "object" - }, - "V1EncryptResponseBody": { - "additionalProperties": false, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "example": "https://api.unkey.dev/schemas/V1EncryptResponseBody.json", - "format": "uri", - "readOnly": true, - "type": "string" - }, - "encrypted": { - "description": "The encrypted data as base64 encoded string.", - "type": "string" - }, - "keyId": { - "description": "The ID of the key used for encryption.", - "type": "string" - } - }, - "required": ["encrypted", "keyId"], - "type": "object" - }, - "V1LivenessResponseBody": { - "additionalProperties": false, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "example": "https://api.unkey.dev/schemas/V1LivenessResponseBody.json", - "format": "uri", - "readOnly": true, - "type": "string" - }, - "message": { - "description": "Whether we're alive or not", - "example": "OK", - "type": "string" - } - }, - "required": ["message"], - "type": "object" - }, - "V1RatelimitCommitLeaseRequestBody": { - "additionalProperties": false, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "example": "https://api.unkey.dev/schemas/V1RatelimitCommitLeaseRequestBody.json", - "format": "uri", - "readOnly": true, - "type": "string" - }, - "cost": { - "description": "The actual cost of the request.", - "format": "int64", - "type": "integer" - }, - "lease": { - "description": "The lease you received from the ratelimit response.", - "type": "string" - } - }, - "required": ["lease", "cost"], - "type": "object" - }, - "V1RatelimitMultiRatelimitRequestBody": { - "additionalProperties": false, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "example": "https://api.unkey.dev/schemas/V1RatelimitMultiRatelimitRequestBody.json", - "format": "uri", - "readOnly": true, - "type": "string" - }, - "ratelimits": { - "description": "The rate limits to check.", - "items": { - "$ref": "#/components/schemas/Item" - }, - "type": ["array"] - } - }, - "required": ["ratelimits"], - "type": "object" - }, - "V1RatelimitMultiRatelimitResponseBody": { - "additionalProperties": false, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "example": "https://api.unkey.dev/schemas/V1RatelimitMultiRatelimitResponseBody.json", - "format": "uri", - "readOnly": true, - "type": "string" - }, - "ratelimits": { - "description": "The rate limits that were checked.", - "items": { - "$ref": "#/components/schemas/SingleRatelimitResponse" - }, - "type": ["array"] - } - }, - "required": ["ratelimits"], - "type": "object" - }, - "V1RatelimitRatelimitRequestBody": { - "additionalProperties": false, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "example": "https://api.unkey.dev/schemas/V1RatelimitRatelimitRequestBody.json", - "format": "uri", - "readOnly": true, - "type": "string" - }, - "cost": { - "description": "The cost of the request. Defaults to 1 if not provided.", - "format": "int64", - "type": "integer", - "default": 1 - }, - "duration": { - "description": "The duration in milliseconds for the rate limit window.", - "format": "int64", - "type": "integer" - }, - "identifier": { - "description": "The identifier for the rate limit.", - "type": "string" - }, - "lease": { - "$ref": "#/components/schemas/Lease", - "description": "Reserve an amount of tokens with the option to commit and update later." - }, - "limit": { - "description": "The maximum number of requests allowed.", - "format": "int64", - "type": "integer" - } - }, - "required": ["identifier", "limit", "duration"], - "type": "object" - }, - "V1RatelimitRatelimitResponseBody": { - "additionalProperties": false, - "properties": { - "$schema": { - "description": "A URL to the JSON Schema for this object.", - "example": "https://api.unkey.dev/schemas/V1RatelimitRatelimitResponseBody.json", - "format": "uri", - "readOnly": true, - "type": "string" - }, - "current": { - "description": "The current number of requests made in the current window.", - "format": "int64", - "type": "integer" - }, - "lease": { - "description": "The lease to use when committing the request.", - "type": ["string"] - }, - "limit": { - "description": "The maximum number of requests allowed.", - "format": "int64", - "type": "integer" - }, - "remaining": { - "description": "The number of requests remaining in the current window.", - "format": "int64", - "type": "integer" - }, - "reset": { - "description": "The time in milliseconds when the rate limit will reset.", - "format": "int64", - "type": "integer" - }, - "success": { - "description": "Whether the request passed the ratelimit. If false, the request must be blocked.", - "type": "boolean" - } - }, - "required": ["limit", "remaining", "reset", "success", "current", "lease"], - "type": "object" - } - } - }, - "info": { - "title": "Unkey API", - "version": "1.0.0" - }, - "openapi": "3.0.0", - "paths": { - "/v0/events": { - "post": { - "operationId": "v0.events.create", - "summary": "Create events", - "description": "Accept NDJSON payload of events and process them", - "requestBody": { - "content": { - "application/x-ndjson": { - "schema": { - "$ref": "#/components/schemas/V0EventsRequestBody" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V0EventsResponseBody" - } - } - } - }, - "400": { - "description": "Bad request", - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ValidationError" - } - } - } - }, - "500": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/BaseError" - } - } - }, - "description": "Error" - } - }, - "tags": ["events"] - } - }, - "/ratelimit.v1.RatelimitService/MultiRatelimit": { - "post": { - "operationId": "ratelimit.v1.multiRatelimit", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V1RatelimitMultiRatelimitRequestBody" - } - } - }, - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V1RatelimitMultiRatelimitResponseBody" - } - } - }, - "description": "OK" - }, - "400": { - "description": "Bad request", - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ValidationError" - } - } - } - }, - "500": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/BaseError" - } - } - }, - "description": "Error" - } - }, - "tags": ["ratelimit"] - } - }, - "/ratelimit.v1.RatelimitService/Ratelimit": { - "post": { - "operationId": "ratelimit.v1.ratelimit", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V1RatelimitRatelimitRequestBody" - } - } - }, - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V1RatelimitRatelimitResponseBody" - } - } - }, - "description": "OK" - }, - "400": { - "description": "Bad request", - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ValidationError" - } - } - } - }, - "500": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/BaseError" - } - } - }, - "description": "Error" - } - }, - "tags": ["ratelimit"] - } - }, - "/v1/liveness": { - "get": { - "description": "This endpoint checks if the service is alive.", - "operationId": "liveness", - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V1LivenessResponseBody" - } - } - }, - "description": "OK" - }, - "500": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/BaseError" - } - } - }, - "description": "Internal Server Error" - } - }, - "summary": "Liveness check", - "tags": ["liveness"] - } - }, - "/v1/ratelimit.commitLease": { - "post": { - "operationId": "v1.ratelimit.commitLease", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V1RatelimitCommitLeaseRequestBody" - } - } - }, - "required": true - }, - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad request", - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ValidationError" - } - } - } - }, - "500": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/BaseError" - } - } - }, - "description": "Error" - } - }, - "tags": ["ratelimit"] - } - }, - "/vault.v1.VaultService/Decrypt": { - "post": { - "operationId": "vault.v1.decrypt", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V1DecryptRequestBody" - } - } - }, - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V1DecryptResponseBody" - } - } - }, - "description": "OK" - }, - "400": { - "description": "Bad request", - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ValidationError" - } - } - } - }, - "500": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/BaseError" - } - } - }, - "description": "Error" - } - }, - "tags": ["vault"] - } - }, - "/vault.v1.VaultService/Encrypt": { - "post": { - "operationId": "vault.v1.encrypt", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V1EncryptRequestBody" - } - } - }, - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V1EncryptResponseBody" - } - } - }, - "description": "OK" - }, - "400": { - "description": "Bad request", - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ValidationError" - } - } - } - }, - "500": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/BaseError" - } - } - }, - "description": "Error" - } - }, - "tags": ["vault"] - } - }, - "/vault.v1.VaultService/EncryptBulk": { - "post": { - "operationId": "vault.v1.encryptBulk", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V1EncryptBulkRequestBody" - } - } - }, - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/V1EncryptBulkResponseBody" - } - } - }, - "description": "OK" - }, - "400": { - "description": "Bad request", - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/ValidationError" - } - } - } - }, - "500": { - "content": { - "application/problem+json": { - "schema": { - "$ref": "#/components/schemas/BaseError" - } - } - }, - "description": "Error" - } - }, - "tags": ["vault"] - } - } - }, - "servers": [ - { - "url": "https://api.unkey.dev" - }, - { - "url": "http://localhost" - } - ] -} diff --git a/web/apps/agent/pkg/openapi/spec.go b/web/apps/agent/pkg/openapi/spec.go deleted file mode 100644 index 77cf03690e..0000000000 --- a/web/apps/agent/pkg/openapi/spec.go +++ /dev/null @@ -1,11 +0,0 @@ -package openapi - -import ( - _ "embed" -) - -// Spec is the OpenAPI specification for the service -// It's loaded from our openapi file and embedded into the binary -// -//go:embed openapi.json -var Spec []byte diff --git a/web/apps/agent/pkg/port/free.go b/web/apps/agent/pkg/port/free.go deleted file mode 100644 index beb8ee80a3..0000000000 --- a/web/apps/agent/pkg/port/free.go +++ /dev/null @@ -1,65 +0,0 @@ -package port - -import ( - "fmt" - "math/rand" - "net" - "sync" - "time" -) - -// FreePort is a utility to find a free port. -type FreePort struct { - sync.RWMutex - min int - max int - attempts int - - // The caller may request multiple ports without binding them immediately - // so we need to keep track of which ports are assigned. - assigned map[int]bool -} - -func New() *FreePort { - rand.New(rand.NewSource(time.Now().UnixNano())) - return &FreePort{ - min: 10000, - max: 65535, - attempts: 10, - assigned: map[int]bool{}, - } -} -func (f *FreePort) Get() int { - port, err := f.GetWithError() - if err != nil { - panic(err) - } - - return port -} - -// Get returns a free port. -func (f *FreePort) GetWithError() (int, error) { - f.Lock() - defer f.Unlock() - - for i := 0; i < f.attempts; i++ { - - port := rand.Intn(f.max-f.min) + f.min - if f.assigned[port] { - continue - } - - ln, err := net.ListenTCP("tcp", &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: port}) - if err != nil { - continue - } - err = ln.Close() - if err != nil { - return -1, err - } - f.assigned[port] = true - return port, nil - } - return -1, fmt.Errorf("could not find a free port, maybe increase attempts?") -} diff --git a/web/apps/agent/pkg/profiling/grafana.go b/web/apps/agent/pkg/profiling/grafana.go deleted file mode 100644 index b4df987a92..0000000000 --- a/web/apps/agent/pkg/profiling/grafana.go +++ /dev/null @@ -1,56 +0,0 @@ -package profiling - -import ( - "runtime" - "time" - - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" - "github.com/grafana/pyroscope-go" - "github.com/unkeyed/unkey/svc/agent/pkg/config" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" -) - -func Start(cfg config.Agent, logger logging.Logger) error { - if cfg.Pyroscope == nil { - logger.Info().Msg("profiling is disabled") - return nil - } - runtime.SetMutexProfileFraction(5) - runtime.SetBlockProfileRate(5) - - _, err := pyroscope.Start(pyroscope.Config{ - UploadRate: time.Minute, - ApplicationName: "api.unkey.cloud", - ServerAddress: cfg.Pyroscope.Url, - BasicAuthUser: cfg.Pyroscope.User, - BasicAuthPassword: cfg.Pyroscope.Password, - Tags: map[string]string{ - "nodeId": cfg.NodeId, - "image": cfg.Image, - "region": cfg.Region, - }, - // Logger: pyroscope.StandardLogger, - - ProfileTypes: []pyroscope.ProfileType{ - pyroscope.ProfileCPU, - pyroscope.ProfileAllocObjects, - pyroscope.ProfileAllocSpace, - pyroscope.ProfileInuseObjects, - pyroscope.ProfileInuseSpace, - - pyroscope.ProfileGoroutines, - pyroscope.ProfileMutexCount, - pyroscope.ProfileMutexDuration, - pyroscope.ProfileBlockCount, - pyroscope.ProfileBlockDuration, - }, - }) - - if err != nil { - return fault.Wrap(err, fmsg.With("unable to start profiling")) - } - - logger.Info().Msg("sending profiles to grafana") - return nil -} diff --git a/web/apps/agent/pkg/prometheus/metrics.go b/web/apps/agent/pkg/prometheus/metrics.go deleted file mode 100644 index 1f1f97dc30..0000000000 --- a/web/apps/agent/pkg/prometheus/metrics.go +++ /dev/null @@ -1,71 +0,0 @@ -package prometheus - -import ( - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" -) - -var ( - HTTPRequests = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: "agent", - Subsystem: "http", - Name: "requests_total", - }, []string{"method", "path", "status"}) - - ServiceLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ - Namespace: "agent", - Subsystem: "http", - Name: "service_latency", - Buckets: []float64{0.001, 0.005, 0.01, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10}, - }, []string{"path"}) - ClusterSize = promauto.NewGauge(prometheus.GaugeOpts{ - Namespace: "agent", - Subsystem: "cluster", - Name: "nodes", - Help: "How many nodes are in the cluster", - }) - - ChannelBuffer = promauto.NewGaugeVec(prometheus.GaugeOpts{ - Namespace: "agent", - Subsystem: "channel", - Name: "buffer", - Help: "Track buffered channel buffers to detect backpressure", - }, []string{"id"}) - CacheHits = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: "agent", - Subsystem: "cache", - Name: "hits", - }, []string{"key", "resource", "tier"}) - CacheMisses = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: "agent", - Subsystem: "cache", - Name: "misses", - }, []string{"key", "resource", "tier"}) - CacheLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ - Namespace: "agent", - Subsystem: "cache", - Name: "latency", - }, []string{"key", "resource", "tier"}) - - CacheEntries = promauto.NewGaugeVec(prometheus.GaugeOpts{ - Namespace: "agent", - Subsystem: "cache", - Name: "entries", - }, []string{"resource"}) - CacheRejected = promauto.NewGaugeVec(prometheus.GaugeOpts{ - Namespace: "agent", - Subsystem: "cache", - Name: "rejected", - }, []string{"resource"}) - RatelimitPushPullEvents = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: "agent", - Subsystem: "ratelimit", - Name: "push_pull_events", - }, []string{"nodeId", "peerId"}) - RatelimitPushPullLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{ - Namespace: "agent", - Subsystem: "ratelimit", - Name: "push_pull_latency", - Help: "Latency of push/pull events in seconds", - }, []string{"nodeId", "peerId"}) -) diff --git a/web/apps/agent/pkg/prometheus/server.go b/web/apps/agent/pkg/prometheus/server.go deleted file mode 100644 index 5b44c50f67..0000000000 --- a/web/apps/agent/pkg/prometheus/server.go +++ /dev/null @@ -1,14 +0,0 @@ -package prometheus - -import ( - "fmt" - "net/http" - - "github.com/prometheus/client_golang/prometheus/promhttp" -) - -func Listen(path string, port int) error { - mux := http.NewServeMux() - mux.Handle(path, promhttp.Handler()) - return http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", port), mux) -} diff --git a/web/apps/agent/pkg/repeat/every.go b/web/apps/agent/pkg/repeat/every.go deleted file mode 100644 index cea84cf277..0000000000 --- a/web/apps/agent/pkg/repeat/every.go +++ /dev/null @@ -1,16 +0,0 @@ -package repeat - -import "time" - -// Every runs the given function in a go routine every d duration until the returned function is called. -func Every(d time.Duration, fn func()) func() { - t := time.NewTicker(d) - go func() { - for range t.C { - fn() - } - }() - return func() { - t.Stop() - } -} diff --git a/web/apps/agent/pkg/ring/metrics.go b/web/apps/agent/pkg/ring/metrics.go deleted file mode 100644 index 2f8ee14117..0000000000 --- a/web/apps/agent/pkg/ring/metrics.go +++ /dev/null @@ -1,20 +0,0 @@ -package ring - -import ( - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" -) - -var ringTokens = promauto.NewGauge(prometheus.GaugeOpts{ - Namespace: "agent", - Subsystem: "cluster", - Name: "ring_tokens", - Help: "The number of virtual tokens in the ring", -}) - -var foundNode = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: "agent", - Subsystem: "cluster", - Name: "found_node", - Help: "Which nodes were found in the ring", -}, []string{"key", "peerId"}) diff --git a/web/apps/agent/pkg/ring/ring.go b/web/apps/agent/pkg/ring/ring.go deleted file mode 100644 index 08021bab00..0000000000 --- a/web/apps/agent/pkg/ring/ring.go +++ /dev/null @@ -1,179 +0,0 @@ -package ring - -import ( - "bytes" - "crypto/sha256" - "encoding/base64" - "fmt" - "sort" - "sync" - "time" - - "github.com/Southclaws/fault" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/repeat" -) - -// Node represents an individual entity in the ring, usually a container instance. -// Nodes are identified by their unique ID and can have arbitrary tags associated with them. -// Tags must be copyable, don't use pointers or channels. -type Node[T any] struct { - // The id must be unique across all nodes in the ring and ideally should be stable - // across restarts of the node to minimize data movement. - Id string - // Arbitrary tags associated with the node - // For example an ip address, availability zone, etc. - // Nodes may get copied or cached, so don't use pointers or channels in tags - Tags T -} -type Config struct { - // how many tokens each node should have - TokensPerNode int - - Logger logging.Logger -} - -type Token struct { - hash string - // index into the nodeIds array - NodeId string -} - -type Ring[T any] struct { - sync.RWMutex - - tokensPerNode int - // nodeIds - nodes map[string]Node[T] - tokens []Token - logger logging.Logger -} - -func New[T any](config Config) (*Ring[T], error) { - r := &Ring[T]{ - tokensPerNode: config.TokensPerNode, - logger: config.Logger, - nodes: make(map[string]Node[T]), - tokens: make([]Token, 0), - } - - repeat.Every(10*time.Second, func() { - r.Lock() - defer r.Unlock() - buf := bytes.NewBuffer(nil) - for _, token := range r.tokens { - _, err := buf.WriteString(fmt.Sprintf("%s,", token.hash)) - if err != nil { - r.logger.Error().Err(err).Msg("failed to write token to buffer") - } - continue - } - - ringTokens.Set(float64(len(r.tokens))) - - }) - - return r, nil -} - -func (r *Ring[T]) AddNode(node Node[T]) error { - r.Lock() - defer r.Unlock() - - for _, n := range r.nodes { - if n.Id == node.Id { - return fmt.Errorf("node already exists: %s", node.Id) - } - } - r.logger.Info().Str("newNodeId", node.Id).Msg("adding node to ring") - - for i := 0; i < r.tokensPerNode; i++ { - hash, err := r.hash(fmt.Sprintf("%s-%d", node.Id, i)) - if err != nil { - return err - } - r.tokens = append(r.tokens, Token{hash: hash, NodeId: node.Id}) - } - sort.Slice(r.tokens, func(i int, j int) bool { - return r.tokens[i].hash < r.tokens[j].hash - }) - - r.nodes[node.Id] = node - - r.logger.Info().Int("nodes", len(r.nodes)).Int("tokens", len(r.tokens)).Msg("tokens in ring") - - return nil -} - -func (r *Ring[T]) RemoveNode(nodeId string) error { - r.Lock() - defer r.Unlock() - r.logger.Info().Str("removedNodeId", nodeId).Msg("removing node from ring") - - delete(r.nodes, nodeId) - - tokens := make([]Token, 0) - for _, t := range r.tokens { - if t.NodeId != nodeId { - tokens = append(tokens, t) - } - } - r.tokens = tokens - - return nil -} - -func (r *Ring[T]) hash(key string) (string, error) { - - h := sha256.New() - _, err := h.Write([]byte(key)) - if err != nil { - return "", err - } - return base64.StdEncoding.EncodeToString(h.Sum(nil)), nil -} - -func (r *Ring[T]) Members() []Node[T] { - r.RLock() - defer r.RUnlock() - - nodes := make([]Node[T], len(r.nodes)) - i := 0 - for _, n := range r.nodes { - nodes[i] = n - i++ - } - return nodes -} - -func (r *Ring[T]) FindNode(key string) (Node[T], error) { - r.RLock() - defer r.RUnlock() - - if len(r.tokens) == 0 { - return Node[T]{}, fault.New("ring is empty") - - } - - hash, err := r.hash(key) - if err != nil { - return Node[T]{}, err - } - tokenIndex := sort.Search(len(r.tokens), func(i int) bool { - return r.tokens[i].hash >= hash - }) - if tokenIndex >= len(r.tokens) { - tokenIndex = 0 - } - - token := r.tokens[tokenIndex] - node, ok := r.nodes[token.NodeId] - if !ok { - return Node[T]{}, fmt.Errorf("node not found: %s", token.NodeId) - - } - - foundNode.WithLabelValues(key, node.Id).Inc() - - return node, nil -} diff --git a/web/apps/agent/pkg/testutil/attack.go b/web/apps/agent/pkg/testutil/attack.go deleted file mode 100644 index 5b872c5c04..0000000000 --- a/web/apps/agent/pkg/testutil/attack.go +++ /dev/null @@ -1,69 +0,0 @@ -package attack - -import ( - "fmt" - "sync" - "testing" - "time" -) - -type Rate struct { - Freq int - Per time.Duration -} - -func (r Rate) String() string { - return fmt.Sprintf("%d per %s", r.Freq, r.Per) -} - -// Attack executes the given function at the given rate for the given duration -// and returns a channel on which the results are sent. -// -// The caller must process the results as they arrive on the channel to avoid -// blocking the worker goroutines. -func Attack[Response any](t *testing.T, rate Rate, duration time.Duration, fn func() Response) <-chan Response { - t.Log("attacking") - wg := sync.WaitGroup{} - workers := 256 - - ticks := make(chan struct{}) - responses := make(chan Response) - - totalRequests := rate.Freq * int(duration/rate.Per) - dt := rate.Per / time.Duration(rate.Freq) - - wg.Add(totalRequests) - - go func() { - for i := 0; i < totalRequests; i++ { - ticks <- struct{}{} - time.Sleep(dt) - } - }() - - for i := 0; i < workers; i++ { - go func() { - for range ticks { - responses <- fn() - wg.Done() - - } - }() - } - - go func() { - wg.Wait() - t.Log("attack done, waiting for responses to be processed") - - close(ticks) - pending := len(responses) - for pending > 0 { - t.Logf("waiting for responses to be processed: %d", pending) - time.Sleep(100 * time.Millisecond) - } - close(responses) - - }() - - return responses -} diff --git a/web/apps/agent/pkg/testutils/containers/agent.go b/web/apps/agent/pkg/testutils/containers/agent.go deleted file mode 100644 index 8596a50d04..0000000000 --- a/web/apps/agent/pkg/testutils/containers/agent.go +++ /dev/null @@ -1,98 +0,0 @@ -package containers - -import ( - "context" - "fmt" - "os" - "path" - "testing" - - "github.com/stretchr/testify/require" - "github.com/testcontainers/testcontainers-go" - "github.com/testcontainers/testcontainers-go/network" - "github.com/testcontainers/testcontainers-go/wait" -) - -type Agent struct { - URL string -} - -// NewAgent runs an Agent container -// The caller is responsible for stopping the container when done. -func NewAgent(t *testing.T, clusterSize int) []Agent { - t.Helper() - - ctx := context.Background() - - net, err := network.New(ctx) - require.NoError(t, err) - - t.Cleanup(func() { - require.NoError(t, net.Remove(ctx)) - }) - - s3 := NewS3(t, net.Name) - t.Cleanup(s3.Stop) - - require.NoError(t, err) - dockerContext := path.Join(os.Getenv("OLDPWD"), "./apps/agent") - t.Logf("using docker context: %s", dockerContext) - - t.Log("s3 url: " + s3.InternalURL) - agents := []Agent{} - for i := 1; i <= clusterSize; i++ { - - agent, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ - ContainerRequest: testcontainers.ContainerRequest{ - Name: fmt.Sprintf("unkey-agent-%d", i), - SkipReaper: true, - Networks: []string{net.Name}, - FromDockerfile: testcontainers.FromDockerfile{ - Context: dockerContext, - Dockerfile: "Dockerfile", - }, - Cmd: []string{"/usr/local/bin/unkey", "agent", "--config", "config.docker.json"}, - ExposedPorts: []string{"8081/tcp"}, - - Env: map[string]string{ - "PORT": "8081", - "SERF_PORT": "9090", - "RPC_PORT": "9095", - "AUTH_TOKEN": "agent-auth-secret", - "VAULT_S3_URL": s3.InternalURL, - "VAULT_S3_BUCKET": "vault", - "VAULT_S3_ACCESS_KEY_ID": s3.AccessKeyId, - "VAULT_S3_ACCESS_KEY_SECRET": s3.AccessKeySecret, - "VAULT_MASTER_KEYS": "Ch9rZWtfMmdqMFBJdVhac1NSa0ZhNE5mOWlLSnBHenFPENTt7an5MRogENt9Si6wms4pQ2XIvqNSIgNpaBenJmXgcInhu6Nfv2U=", - }, - WaitingFor: wait.ForHTTP("/v1/liveness"), - }, - }) - - require.NoError(t, err) - - err = agent.Start(ctx) - require.NoError(t, err) - // t.Cleanup(func() { - // require.NoError(t, agent.Terminate(ctx)) - // }) - t.Log(agent.Networks(ctx)) - - host, err := agent.Host(ctx) - require.NoError(t, err) - - port, err := agent.MappedPort(ctx, "8081") - require.NoError(t, err) - - url := fmt.Sprintf("http://%s:%s", host, port.Port()) - - require.NotEmpty(t, url, "connection string is empty") - - agents = append(agents, Agent{ - URL: url, - }) - } - - return agents - -} diff --git a/web/apps/agent/pkg/testutils/containers/compose.go b/web/apps/agent/pkg/testutils/containers/compose.go deleted file mode 100644 index 3525998fcb..0000000000 --- a/web/apps/agent/pkg/testutils/containers/compose.go +++ /dev/null @@ -1,38 +0,0 @@ -package containers - -import ( - "context" - "os" - "path" - "strings" - "testing" - - "github.com/stretchr/testify/require" - "github.com/testcontainers/testcontainers-go/modules/compose" -) - -// ComposeUp starts a docker-compose stack and returns the stack object. -func ComposeUp(t *testing.T) compose.ComposeStack { - t.Helper() - os.Setenv("TESTCONTAINERS_RYUK_DISABLED", "true") - - ctx := context.Background() - - file := path.Join(os.Getenv("OLDPWD"), "dev/docker-compose.yaml") - t.Logf("using docker-compose file: %s", file) - - c, err := compose.NewDockerComposeWith( - - compose.WithStackFiles(file), - compose.StackIdentifier(strings.ToLower(t.Name())), - ) - require.NoError(t, err) - - t.Cleanup(func() { - require.NoError(t, c.Down(ctx, compose.RemoveOrphans(true))) - }) - - err = c.Up(ctx, compose.Wait(true)) - require.NoError(t, err) - return c -} diff --git a/web/apps/agent/pkg/testutils/containers/redis.go b/web/apps/agent/pkg/testutils/containers/redis.go deleted file mode 100644 index 09cc595285..0000000000 --- a/web/apps/agent/pkg/testutils/containers/redis.go +++ /dev/null @@ -1,67 +0,0 @@ -package containers - -import ( - "context" - "fmt" - "testing" - - goredis "github.com/redis/go-redis/v9" - "github.com/stretchr/testify/require" - "github.com/testcontainers/testcontainers-go" - "github.com/testcontainers/testcontainers-go/wait" -) - -type Redis struct { - URL string - Client *goredis.Client - Stop func() -} - -// NewRedis runs a Redis container and returns the URL and a client to interact with it. -// The caller is responsible for stopping the container when done. -func NewRedis(t *testing.T) Redis { - t.Helper() - - ctx := context.Background() - - req := testcontainers.ContainerRequest{ - SkipReaper: true, - Image: "redis:latest", - ExposedPorts: []string{"6379/tcp"}, - WaitingFor: wait.ForExposedPort(), - } - container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ - ContainerRequest: req, - Started: true, - }) - require.NoError(t, err) - - err = container.Start(ctx) - require.NoError(t, err) - - host, err := container.Host(ctx) - require.NoError(t, err) - - port, err := container.MappedPort(ctx, "6379") - require.NoError(t, err) - - url := fmt.Sprintf("redis://%s:%s", host, port.Port()) - - require.NotEmpty(t, url, "connection string is empty") - - opts, err := goredis.ParseURL(url) - require.NoError(t, err) - client := goredis.NewClient(opts) - - _, err = client.Ping(ctx).Result() - require.NoError(t, err) - - return Redis{ - URL: url, - Client: client, - Stop: func() { - require.NoError(t, client.Close()) - require.NoError(t, container.Terminate(ctx)) - }, - } -} diff --git a/web/apps/agent/pkg/testutils/containers/s3.go b/web/apps/agent/pkg/testutils/containers/s3.go deleted file mode 100644 index 0aa019e259..0000000000 --- a/web/apps/agent/pkg/testutils/containers/s3.go +++ /dev/null @@ -1,73 +0,0 @@ -package containers - -import ( - "context" - "fmt" - "strings" - "testing" - - "github.com/stretchr/testify/require" - "github.com/testcontainers/testcontainers-go" - "github.com/testcontainers/testcontainers-go/wait" -) - -type S3 struct { - URL string - // From another container - InternalURL string - AccessKeyId string - AccessKeySecret string - Stop func() -} - -// NewS3 runs a minion container and returns the URL -// The caller is responsible for stopping the container when done. -func NewS3(t *testing.T, networks ...string) S3 { - - ctx := context.Background() - - req := testcontainers.ContainerRequest{ - Name: "s3", - SkipReaper: true, - Networks: networks, - Image: "bitnamilegacy/minio:2025.7.23-debian-12-r5", - ExposedPorts: []string{"9000/tcp"}, - WaitingFor: wait.ForHTTP("/minio/health/live").WithPort("9000"), - Env: map[string]string{ - "MINIO_ROOT_USER": "minio_root_user", - "MINIO_ROOT_PASSWORD": "minio_root_password", - }, - Cmd: []string{"server", "/data"}, - } - - container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ - - ContainerRequest: req, - Started: true, - }) - require.NoError(t, err) - - host, err := container.Host(ctx) - require.NoError(t, err) - - port, err := container.MappedPort(ctx, "9000") - require.NoError(t, err) - ip, err := container.ContainerIP(ctx) - require.NoError(t, err) - - t.Log(container.Networks(ctx)) - name, err := container.Name(ctx) - require.NoError(t, err) - url := fmt.Sprintf("http://%s:%s", host, port.Port()) - t.Logf("S3 Name: %s", name) - t.Logf("S3 IP: %s", ip) - return S3{ - URL: url, - InternalURL: fmt.Sprintf("http://%s:%s", strings.TrimPrefix(name, "/"), "9000"), - AccessKeyId: "minio_root_user", - AccessKeySecret: "minio_root_password", - Stop: func() { - require.NoError(t, container.Terminate(ctx)) - }, - } -} diff --git a/web/apps/agent/pkg/tracing/axiom.go b/web/apps/agent/pkg/tracing/axiom.go deleted file mode 100644 index d47febff2e..0000000000 --- a/web/apps/agent/pkg/tracing/axiom.go +++ /dev/null @@ -1,30 +0,0 @@ -package tracing - -import ( - "context" - "fmt" - - axiom "github.com/axiomhq/axiom-go/axiom/otel" -) - -type Config struct { - Dataset string - Application string - Version string - AxiomToken string -} - -// Coser is a function that closes the global tracer. -type Closer func() error - -func Init(ctx context.Context, config Config) (Closer, error) { - tp, err := axiom.TracerProvider(ctx, config.Dataset, config.Application, config.Version, axiom.SetNoEnv(), axiom.SetToken(config.AxiomToken)) - if err != nil { - return nil, fmt.Errorf("unable to init tracing: %w", err) - } - globalTracer = tp - - return func() error { - return tp.Shutdown(context.Background()) - }, nil -} diff --git a/web/apps/agent/pkg/tracing/schema.go b/web/apps/agent/pkg/tracing/schema.go deleted file mode 100644 index 5d0674f53b..0000000000 --- a/web/apps/agent/pkg/tracing/schema.go +++ /dev/null @@ -1,7 +0,0 @@ -package tracing - -import "fmt" - -func NewSpanName(pkg string, method string) string { - return fmt.Sprintf("%s.%s", pkg, method) -} diff --git a/web/apps/agent/pkg/tracing/trace.go b/web/apps/agent/pkg/tracing/trace.go deleted file mode 100644 index 2af921a26c..0000000000 --- a/web/apps/agent/pkg/tracing/trace.go +++ /dev/null @@ -1,22 +0,0 @@ -package tracing - -import ( - "context" - - "go.opentelemetry.io/otel/trace" - "go.opentelemetry.io/otel/trace/noop" -) - -var globalTracer trace.TracerProvider - -func init() { - globalTracer = noop.NewTracerProvider() -} - -func Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) { - return globalTracer.Tracer("main").Start(ctx, name, opts...) -} - -func GetGlobalTraceProvider() trace.TracerProvider { - return globalTracer -} diff --git a/web/apps/agent/pkg/tracing/util.go b/web/apps/agent/pkg/tracing/util.go deleted file mode 100644 index 484e14c67e..0000000000 --- a/web/apps/agent/pkg/tracing/util.go +++ /dev/null @@ -1,14 +0,0 @@ -package tracing - -import ( - "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/trace" -) - -// RecordError sets the status of the span to error if the error is not nil. -func RecordError(span trace.Span, err error) { - if err == nil { - return - } - span.SetStatus(codes.Error, err.Error()) -} diff --git a/web/apps/agent/pkg/uid/hash.go b/web/apps/agent/pkg/uid/hash.go deleted file mode 100644 index 2238395a25..0000000000 --- a/web/apps/agent/pkg/uid/hash.go +++ /dev/null @@ -1,22 +0,0 @@ -package uid - -import ( - "crypto/sha256" - "strings" - - "github.com/btcsuite/btcutil/base58" -) - -func IdFromHash(s string, prefix ...string) string { - - hash := sha256.New() - _, _ = hash.Write([]byte(s)) - - id := base58.Encode(hash.Sum(nil)) - if len(prefix) > 0 && prefix[0] != "" { - return strings.Join([]string{prefix[0], id}, "_") - } else { - return id - } - -} diff --git a/web/apps/agent/pkg/uid/uid.go b/web/apps/agent/pkg/uid/uid.go deleted file mode 100644 index a79831fc80..0000000000 --- a/web/apps/agent/pkg/uid/uid.go +++ /dev/null @@ -1,32 +0,0 @@ -package uid - -import ( - "strings" - - "github.com/segmentio/ksuid" -) - -type Prefix string - -const ( - RequestPrefix Prefix = "req" - NodePrefix Prefix = "node" -) - -// New Returns a new random base58 encoded uuid. -func New(prefix string) string { - - id := ksuid.New().String() - if prefix != "" { - return strings.Join([]string{string(prefix), id}, "_") - } else { - return id - } -} -func Node() string { - return New(string(NodePrefix)) -} - -func Request() string { - return New(string(RequestPrefix)) -} diff --git a/web/apps/agent/pkg/uid/uid_test.go b/web/apps/agent/pkg/uid/uid_test.go deleted file mode 100644 index fcf4be6d87..0000000000 --- a/web/apps/agent/pkg/uid/uid_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package uid_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - "github.com/unkeyed/unkey/svc/agent/pkg/uid" -) - -func TestNew(t *testing.T) { - ids := map[string]bool{} - for range 1000 { - id := uid.New("") - require.Positive(t, len(id)) - _, ok := ids[id] - require.False(t, ok, "generated id must be unique") - ids[id] = true - } -} - -func TestNewWithPrefix(t *testing.T) { - prefixes := []uid.Prefix{ - uid.NodePrefix, - } - - ids := map[string]bool{} - for _, prefix := range prefixes { - for range 1000 { - id := uid.New(string(prefix)) - require.Positive(t, len(id)) - _, ok := ids[id] - require.False(t, ok, "generated id must be unique") - ids[id] = true - } - } -} diff --git a/web/apps/agent/pkg/util/compare.go b/web/apps/agent/pkg/util/compare.go deleted file mode 100644 index 6c737192b4..0000000000 --- a/web/apps/agent/pkg/util/compare.go +++ /dev/null @@ -1,33 +0,0 @@ -package util - -import ( - "cmp" -) - -func Max[T cmp.Ordered](s []T) T { - if len(s) == 0 { - var t T - return t - } - max := s[0] - for _, v := range s[1:] { - if v > max { - max = v - } - } - return max -} - -func Min[T cmp.Ordered](s []T) T { - if len(s) == 0 { - var t T - return t - } - min := s[0] - for _, v := range s[1:] { - if v < min { - min = v - } - } - return min -} diff --git a/web/apps/agent/pkg/util/convert.go b/web/apps/agent/pkg/util/convert.go deleted file mode 100644 index b661c108f2..0000000000 --- a/web/apps/agent/pkg/util/convert.go +++ /dev/null @@ -1,32 +0,0 @@ -package util - -import ( - "reflect" -) - -// StructToMap converts a struct to a map using its json tags -func StructToMap(s any) map[string]any { - obj := map[string]any{} - if s == nil { - return obj - } - v := reflect.TypeOf(s) - reflectValue := reflect.ValueOf(s) - reflectValue = reflect.Indirect(reflectValue) - - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - for i := 0; i < v.NumField(); i++ { - tag := v.Field(i).Tag.Get("json") - field := reflectValue.Field(i).Interface() - if tag != "" && tag != "-" { - if v.Field(i).Type.Kind() == reflect.Struct { - obj[tag] = StructToMap(field) - } else { - obj[tag] = field - } - } - } - return obj -} diff --git a/web/apps/agent/pkg/util/convert_test.go b/web/apps/agent/pkg/util/convert_test.go deleted file mode 100644 index 23970a2363..0000000000 --- a/web/apps/agent/pkg/util/convert_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package util_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - "github.com/unkeyed/unkey/svc/agent/pkg/util" -) - -type TestStruct1 struct { - Field1 string `json:"field1"` - Field2 int `json:"field2"` -} - -type TestStruct2 struct { - Field3 string `json:"field3"` - Field4 int `json:"field4"` -} - -type NestedStruct struct { - Inner TestStruct2 `json:"inner"` -} - -func TestStructToMap_NilInput(t *testing.T) { - result := util.StructToMap(nil) - require.Empty(t, result) -} - -func TestStructToMap_SimpleStruct(t *testing.T) { - input := TestStruct1{ - Field1: "value1", - Field2: 42, - } - expected := map[string]interface{}{ - "field1": "value1", - "field2": 42, - } - result := util.StructToMap(input) - require.Equal(t, expected, result) -} - -func TestStructToMap_NestedStruct(t *testing.T) { - input := NestedStruct{ - Inner: TestStruct2{ - Field3: "value3", - Field4: 99, - }, - } - expected := map[string]interface{}{ - "inner": map[string]interface{}{ - "field3": "value3", - "field4": 99, - }, - } - result := util.StructToMap(input) - require.Equal(t, expected, result) -} diff --git a/web/apps/agent/pkg/util/pointer.go b/web/apps/agent/pkg/util/pointer.go deleted file mode 100644 index 75a831bd9c..0000000000 --- a/web/apps/agent/pkg/util/pointer.go +++ /dev/null @@ -1,6 +0,0 @@ -package util - -func Pointer[T any](t T) *T { - return &t - -} diff --git a/web/apps/agent/pkg/util/random.go b/web/apps/agent/pkg/util/random.go deleted file mode 100644 index 18e8a48eb0..0000000000 --- a/web/apps/agent/pkg/util/random.go +++ /dev/null @@ -1,17 +0,0 @@ -package util - -import ( - "math/rand" -) - -// RandomElement returns a random element from the given slice. -// -// If the slice is empty, it returns the zero value of the element type. -func RandomElement[T any](s []T) T { - - if len(s) == 0 { - var t T - return t - } - return s[rand.Intn(len(s))] -} diff --git a/web/apps/agent/pkg/util/retry.go b/web/apps/agent/pkg/util/retry.go deleted file mode 100644 index 97cb032740..0000000000 --- a/web/apps/agent/pkg/util/retry.go +++ /dev/null @@ -1,24 +0,0 @@ -package util - -import ( - "fmt" - "time" -) - -// Retry retries the given function until it succeeds or all retries are exhausted -func Retry(fn func() error, attempts int, backoff func(n int) time.Duration) error { - if attempts < 1 { - return fmt.Errorf("attempts must be greater than 0") - } - - var err error - for i := 0; i < attempts; i++ { - err = fn() - if err == nil { - return nil - } - time.Sleep(backoff(i)) - } - return err - -} diff --git a/web/apps/agent/pkg/version/version.go b/web/apps/agent/pkg/version/version.go deleted file mode 100644 index 68f5712cd9..0000000000 --- a/web/apps/agent/pkg/version/version.go +++ /dev/null @@ -1,3 +0,0 @@ -package version - -var Version string = "development" diff --git a/web/apps/agent/proto/cluster/v1/service.proto b/web/apps/agent/proto/cluster/v1/service.proto deleted file mode 100644 index 2ec87a1698..0000000000 --- a/web/apps/agent/proto/cluster/v1/service.proto +++ /dev/null @@ -1,24 +0,0 @@ -syntax = "proto3"; - -package cluster.v1; - -option go_package = "github.com/unkeyed/unkey/svc/agent/gen/proto/cluster/v1;clusterv1"; - -enum NodeState { - NODE_STATE_UNSPECIFIED = 0; - NODE_STATE_JOINING = 1; - NODE_STATE_LEAVING = 2; - NODE_STATE_ACTIVE = 3; -} - -message AnnounceStateChangeRequest { - string node_id = 1; - NodeState state = 2; -} - -message AnnounceStateChangeResponse {} -service ClusterService { - // Announce that a node is changing state - // When a node shuts down, it should announce that it is leaving the cluster, so other nodes can remove it from their view of the cluster as soon as possible. - rpc AnnounceStateChange(AnnounceStateChangeRequest) returns (AnnounceStateChangeResponse) {} -} diff --git a/web/apps/agent/proto/errors/v1/errors.proto.disabled b/web/apps/agent/proto/errors/v1/errors.proto.disabled deleted file mode 100644 index ff07387217..0000000000 --- a/web/apps/agent/proto/errors/v1/errors.proto.disabled +++ /dev/null @@ -1,71 +0,0 @@ -syntax = "proto3"; -import "google/protobuf/struct.proto"; - -package errors.v1; -option go_package = "github.com/unkeyed/unkey/svc/agent/gen/proto/errors/v1;errorsv1"; - - - -enum Fault { - FAULT_UNSPECIFIED = 0; - FAULT_UNKNOWN = 1; - FAULT_PLANETSCALE = 2; - FAULT_GITHUB = 3; -} - -enum Service { - ServiceUnknown = 0; - ServiceAgent = 1; - ServiceAuth = 2; - ServiceCatalog = 3; - ServiceConfig = 4; - ServiceDNS = 5; - ServiceSentinel = 6; - ServiceGitHub = 7; - ServiceKubernetes = 8; - ServiceLog = 9; - ServiceMetrics = 10; - ServiceMonitor = 11; - ServiceNetwork = 12; - ServiceOperator = 13; - ServiceRegistry = 14; - ServiceSecret = 15; - ServiceStorage = 16; - ServiceSystem = 17; - ServiceTelemetry = 18; - ServiceToken = 19; - ServiceUser = 20; - ServiceVault = 21; - ServiceWebhook = 22; - - -} - - -enum ErrorCode { - ErrorCodeUnspecified = 0; - ErrorCodeInternal = 1; - -} - -message Action { - optional string url = 1; - string label = 2; - string description = 3; -} - -message Error { - Fault fault = 1; - string group = 2; - ErrorCode code = 3; - string type = 4; - .google.protobuf.Struct metadata = 5; - - // Suggested actions the user should take to resolve this error. - // These actions are not guaranteed to resolve the error, but they are a good starting point. - // - // As a last resort, the user should contact support. - // - // The actions are ordered by importance, the first action should be presented first. - repeated Action actions = 6; -} \ No newline at end of file diff --git a/web/apps/agent/proto/gossip/v1/gossip.proto b/web/apps/agent/proto/gossip/v1/gossip.proto deleted file mode 100644 index 13f7e79a14..0000000000 --- a/web/apps/agent/proto/gossip/v1/gossip.proto +++ /dev/null @@ -1,104 +0,0 @@ -syntax = "proto3"; - -package gossip.v1; - -option go_package = "github.com/unkeyed/unkey/svc/agent/gen/proto/gossip/v1;gossipv1"; - -enum State { - State_UNSPECIFIED = 0; - State_ALIVE = 1; - State_DEAD = 2; - State_LEFT = 3; - State_SUSPECT = 4; -} - -message Rumor { - int64 time = 1; -} - -message GossipRequest { - // repeated Rumor rumors = 1; -} - -message GossipResponse { - // repeated Rumor rumors = 1; -} - -message PingRequest {} - -message PingResponse { - State state = 1; -} - -message IndirectPingRequest { - string node_id = 1; - string rpc_addr = 2; -} - -message IndirectPingResponse { - State state = 1; -} - -message Member { - string node_id = 1; - string rpc_addr = 2; - State state = 3; -} - -message SyncMembersRequest { - // The members that the sender knows about - repeated Member members = 1; -} -message SyncMembersResponse { - // The members that the receiver knows about - repeated Member members = 1; -} - -message JoinRequest { - Member self = 1; -} -message JoinResponse { - repeated Member members = 1; -} - -message LeaveRequest { - Member self = 1; -} - -message LeaveResponse { - // simple ack, if there's no error, we're good -} - -service GossipService { - // Ping asks for the state of a peer - // If the peer is healthy, it should respond with its state - rpc Ping(PingRequest) returns (PingResponse) {} - - // IndirectPing asks a peer to ping another node because we can not reach it outselves - // the peer should respond with the state of the node - rpc IndirectPing(IndirectPingRequest) returns (IndirectPingResponse) {} - - // Periodially we do a full sync of the members - // Both nodes tell each other about every member they know and then reconcile by taking the union - // of the two sets. - // Afterwards, both nodes should have the same view of the cluster and regular gossip will get rid - // of any dead nodes - // - // If they disagree on the state of a node, the most favourable state should be chosen - // ie: if one node thinks a peer is dead and the other thinks it is alive, the node should be - // marked as alive to prevent a split brain or unnecessary false positives - rpc SyncMembers(SyncMembersRequest) returns (SyncMembersResponse) {} - - // Join allows a node to advertise itself to the cluster - // The node sends their own information, so the cluster may add them to the list of known members - // The cluster responds with the list of known members to bootstrap the new node - // - // It's sufficient to call join on one node, the rest of the cluster will be updated through - // gossip, however it is recommended to call join on multiple nodes to ensure the information is - // propagated quickly and to minimize the chance of a single node failing before propagating the - // information. - rpc Join(JoinRequest) returns (JoinResponse) {} - - // Leave should be broadcasted to all nodes in the cluster when a node is leaving for any reason. - rpc Leave(LeaveRequest) returns (LeaveResponse) {} -} diff --git a/web/apps/agent/proto/ratelimit/v1/service.proto b/web/apps/agent/proto/ratelimit/v1/service.proto deleted file mode 100644 index ca6f7cfee3..0000000000 --- a/web/apps/agent/proto/ratelimit/v1/service.proto +++ /dev/null @@ -1,124 +0,0 @@ -syntax = "proto3"; - -package ratelimit.v1; - -option go_package = "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1;ratelimitv1"; - -message LivenessRequest {} -message LivenessResponse { - string status = 1; -} - -message LeaseRequest { - int64 cost = 1; - // milliseconds - int64 timeout = 2; -} - -message RatelimitRequest { - string identifier = 1; - int64 limit = 2; - int64 duration = 3; - int64 cost = 4; - // A name for the ratelimit, used for debugging - string name = 5; - - // Create a lease with this many tokens - optional LeaseRequest lease = 6; - - optional int64 time = 7; -} -message RatelimitResponse { - int64 limit = 1; - int64 remaining = 2; - int64 reset = 3; - bool success = 4; - int64 current = 5; - - optional Lease lease = 6; -} - -message RatelimitMultiRequest { - repeated RatelimitRequest ratelimits = 1; -} -message RatelimitMultiResponse { - repeated RatelimitResponse ratelimits = 1; -} - -message Window { - int64 sequence = 1; - int64 duration = 2; - int64 counter = 3; - // unix milli - int64 start = 4; - - // An origin node can broadcast a mitigation to all nodes in the ring - // Before the mitigation is broadcasted, the origin node must flip this to true - // to avoid duplicate broadcasts - bool mitigate_broadcasted = 5; - - // A map of leaseIDs to leases - map leases = 6; -} - -message PushPullRequest { - RatelimitRequest request = 1; - - // Whether the edge note let the request pass - // If it did, we must increment the counter on the origin regardless of the result - bool passed = 2; - - // The time the event happened, so we can replay it on the origin and record latency - int64 time = 3; -} - -message PushPullResponse { - Window current = 1; - Window previous = 2; - - RatelimitResponse response = 3; -} - -// Lease contains everything from original ratelimit request that we need to find the origin server -message Lease { - string identifier = 1; - int64 limit = 2; - int64 duration = 3; -} -message CommitLeaseRequest { - Lease lease = 1; - // The actual cost that should be commited - int64 cost = 2; -} - -message CommitLeaseResponse {} - -message MitigateRequest { -string identifier = 1; -int64 limit = 2; -int64 duration = 3; - Window window = 4; - } - -message MitigateResponse {} - -service RatelimitService { - rpc Liveness(LivenessRequest) returns (LivenessResponse) {} - - rpc Ratelimit(RatelimitRequest) returns (RatelimitResponse) {} - rpc MultiRatelimit(RatelimitMultiRequest) returns (RatelimitMultiResponse) {} - - // Internal - // - // PushPull syncs the ratelimit with the origin server - // For each identifier there is an origin server, agred upon by every node in the ring via - // consistent hashing - // - // PushPull notifies the origin of a ratelimit operation that happened and then pulls the latest - // ratelimit information from the origin server to update its own local state - rpc PushPull(PushPullRequest) returns (PushPullResponse) {} - - rpc CommitLease(CommitLeaseRequest) returns (CommitLeaseResponse) {} - - rpc Mitigate(MitigateRequest) returns (MitigateResponse) {} -} diff --git a/web/apps/agent/proto/vault/v1/object.proto b/web/apps/agent/proto/vault/v1/object.proto deleted file mode 100644 index d526b0ec88..0000000000 --- a/web/apps/agent/proto/vault/v1/object.proto +++ /dev/null @@ -1,44 +0,0 @@ -syntax = "proto3"; - -package vault.v1; - -option go_package = "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1;vaultv1"; - -enum Algorithm { - AES_256_GCM = 0; -} - -message DataEncryptionKey { - string id = 1; - // Linux milliseconds since epoch - int64 created_at = 2; - bytes key = 3; -} - -// This is stored in the database in whatever format the database uses -message EncryptedDataEncryptionKey { - string id = 1; - // Linux milliseconds since epoch - int64 created_at = 2; - Encrypted encrypted = 3; -} - -// KeyEncryptionKey is a key used to encrypt data encryption keys -message KeyEncryptionKey { - string id = 1; - int64 created_at = 2; - bytes key = 3; -} - -// Encrypted contains the output of the encryption and all of the metadata required to decrypt it -message Encrypted { - Algorithm algorithm = 1; - bytes nonce = 2; - bytes ciphertext = 3; - // key id of the key that encrypted this data - string encryption_key_id = 4; - - // time of encryption - // we can use this later to figure out if a piece of data should be re-encrypted - int64 time = 5; -} diff --git a/web/apps/agent/proto/vault/v1/service.proto b/web/apps/agent/proto/vault/v1/service.proto deleted file mode 100644 index 47dfd10657..0000000000 --- a/web/apps/agent/proto/vault/v1/service.proto +++ /dev/null @@ -1,73 +0,0 @@ -syntax = "proto3"; - -package vault.v1; - -option go_package = "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1;vaultv1"; - -message LivenessRequest {} -message LivenessResponse { - string status = 1; -} - -message EncryptRequest { - string keyring = 1; - string data = 2; -} - -message EncryptResponse { - string encrypted = 1; - string key_id = 2; -} - -message EncryptBulkRequest { - string keyring = 1; - repeated string data = 2; -} - -message EncryptBulkResponse { - repeated EncryptResponse encrypted = 1; -} - -message DecryptRequest { - string keyring = 1; - string encrypted = 2; -} - -message DecryptResponse { - string plaintext = 1; -} - -message CreateDEKRequest { - string keyring = 1; -} - -message CreateDEKResponse { - string key_id = 1; -} - -message ReEncryptRequest { - string keyring = 1; - string encrypted = 2; - - // Specify the key_id to use for re-encryption. If not provided, the latest will be used - optional string key_id = 3; -} -message ReEncryptResponse { - string encrypted = 1; - string key_id = 2; -} - -message ReEncryptDEKsRequest {} -message ReEncryptDEKsResponse {} - -service VaultService { - rpc Liveness(LivenessRequest) returns (LivenessResponse) {} - rpc CreateDEK(CreateDEKRequest) returns (CreateDEKResponse) {} - rpc Encrypt(EncryptRequest) returns (EncryptResponse) {} - rpc EncryptBulk(EncryptBulkRequest) returns (EncryptBulkResponse) {} - rpc Decrypt(DecryptRequest) returns (DecryptResponse) {} - - // ReEncrypt rec - rpc ReEncrypt(ReEncryptRequest) returns (ReEncryptResponse) {} - rpc ReEncryptDEKs(ReEncryptDEKsRequest) returns (ReEncryptDEKsResponse) {} -} diff --git a/web/apps/agent/schema.json b/web/apps/agent/schema.json deleted file mode 100644 index ee3e30d4d0..0000000000 --- a/web/apps/agent/schema.json +++ /dev/null @@ -1,274 +0,0 @@ -{ - "type": "object", - "properties": { - "$schema": { - "type": "string", - "description": "Make jsonschema happy" - }, - "authToken": { - "type": "string", - "description": "The token to use for http authentication", - "minLength": 1 - }, - "clickhouse": { - "type": "object", - "properties": { - "url": { - "type": "string", - "minLength": 1 - } - }, - "additionalProperties": false, - "required": ["url"] - }, - "cluster": { - "type": "object", - "properties": { - "authToken": { - "type": "string", - "description": "The token to use for http authentication", - "minLength": 1 - }, - "join": { - "type": "object", - "description": "The strategy to use to join the cluster", - "properties": { - "dns": { - "type": "object", - "properties": { - "aaaa": { - "type": "string", - "description": "The AAAA record that returns a comma separated list, containing the ipv6 addresses of all nodes" - } - }, - "additionalProperties": false, - "required": ["aaaa"] - }, - "env": { - "type": "object", - "properties": { - "addrs": { - "type": "array", - "description": "Addresses to join, comma separated", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false, - "required": ["addrs"] - } - }, - "additionalProperties": false - }, - "rpcAddr": { - "type": "string", - "description": "This node's internal address, including protocol and port", - "minLength": 1 - }, - "serfAddr": { - "type": "string", - "description": "The host and port for serf to listen on", - "minLength": 1 - } - }, - "additionalProperties": false, - "required": ["authToken", "serfAddr", "rpcAddr"] - }, - "heartbeat": { - "type": "object", - "description": "Send heartbeat to a URL", - "properties": { - "interval": { - "type": "integer", - "description": "Interval in seconds to send heartbeat", - "format": "int32" - }, - "url": { - "type": "string", - "description": "URL to send heartbeat to", - "minLength": 1 - } - }, - "additionalProperties": false, - "required": ["url", "interval"] - }, - "image": { - "type": "string", - "description": "The image this agent is running" - }, - "logging": { - "type": "object", - "properties": { - "axiom": { - "type": "object", - "description": "Send logs to axiom", - "properties": { - "dataset": { - "type": "string", - "description": "The dataset to send logs to", - "minLength": 1 - }, - "token": { - "type": "string", - "description": "The token to use for authentication", - "minLength": 1 - } - }, - "additionalProperties": false, - "required": ["dataset", "token"] - } - }, - "additionalProperties": false - }, - "metrics": { - "type": "object", - "properties": { - "axiom": { - "type": "object", - "description": "Send metrics to axiom", - "properties": { - "dataset": { - "type": "string", - "description": "The dataset to send metrics to", - "minLength": 1 - }, - "token": { - "type": "string", - "description": "The token to use for authentication", - "minLength": 1 - } - }, - "additionalProperties": false, - "required": ["dataset", "token"] - } - }, - "additionalProperties": false - }, - "nodeId": { - "type": "string", - "description": "A unique node id" - }, - "platform": { - "type": "string", - "description": "The platform this agent is running on" - }, - "port": { - "type": "string", - "description": "Port to listen on", - "default": "8080" - }, - "prometheus": { - "type": "object", - "properties": { - "path": { - "type": "string", - "description": "The path where prometheus scrapes metrics", - "default": "/metrics" - }, - "port": { - "type": "integer", - "description": "The port where prometheus scrapes metrics", - "format": "int32", - "default": 2112 - } - }, - "additionalProperties": false, - "required": ["path", "port"] - }, - "pyroscope": { - "type": "object", - "properties": { - "password": { - "type": "string", - "minLength": 1 - }, - "url": { - "type": "string", - "minLength": 1 - }, - "user": { - "type": "string", - "minLength": 1 - } - }, - "additionalProperties": false, - "required": ["url", "user", "password"] - }, - "region": { - "type": "string", - "description": "The region this agent is running in" - }, - "rpcPort": { - "type": "string", - "description": "Port to listen on for RPC requests", - "default": "9090" - }, - "services": { - "type": "object", - "properties": { - "vault": { - "type": "object", - "description": "Store secrets", - "properties": { - "masterKeys": { - "type": "string", - "description": "The master keys to use for encryption, comma separated", - "minLength": 1 - }, - "s3AccessKeyId": { - "type": "string", - "description": "The access key id to use for s3", - "minLength": 1 - }, - "s3AccessKeySecret": { - "type": "string", - "description": "The access key secret to use for s3", - "minLength": 1 - }, - "s3Bucket": { - "type": "string", - "description": "The bucket to store secrets in", - "minLength": 1 - }, - "s3Url": { - "type": "string", - "description": "The url to store secrets in", - "minLength": 1 - } - }, - "additionalProperties": false, - "required": ["s3Bucket", "s3Url", "s3AccessKeyId", "s3AccessKeySecret", "masterKeys"] - } - }, - "additionalProperties": false, - "required": ["vault"] - }, - "tracing": { - "type": "object", - "properties": { - "axiom": { - "type": "object", - "description": "Send traces to axiom", - "properties": { - "dataset": { - "type": "string", - "description": "The dataset to send traces to", - "minLength": 1 - }, - "token": { - "type": "string", - "description": "The token to use for authentication", - "minLength": 1 - } - }, - "additionalProperties": false, - "required": ["dataset", "token"] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": true, - "required": ["authToken", "services"] -} diff --git a/web/apps/agent/scripts/deploy.bash b/web/apps/agent/scripts/deploy.bash deleted file mode 100644 index b49c8137f4..0000000000 --- a/web/apps/agent/scripts/deploy.bash +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - - -regionsResponse=$(fly platform regions --json) - -count=$(echo $regionsResponse | jq '. | length') - -# returns a comma delimited list of regions for fly cli: 'iad,ord,dfw,...' -commaDelimitedRegions=$(echo $regionsResponse | jq '.[].Code' | paste -sd "," - | sed 's/"//g') - - fly --config=fly.production.toml scale count $count --max-per-region=1 --region=$commaDelimitedRegions \ No newline at end of file diff --git a/web/apps/agent/scripts/heap.bash b/web/apps/agent/scripts/heap.bash deleted file mode 100644 index c9aa7d85f8..0000000000 --- a/web/apps/agent/scripts/heap.bash +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -set -e - - -# The following environment variables are required: -# PPROF_USERNAME -# PPROF_PASSWORD -# MACHINE_ID - -# Usage -# PPROF_USERNAME=xxx PPROF_PASSWORD=xxx MACHINE_ID=xxx bash ./scripts/heap.bash - -url="https://api.unkey.cloud" -seconds=60 -now=$(date +"%Y-%m-%d_%H-%M-%S") -filename="heap-$now.out" - - -echo "Checking machine status" -curl -s -o /dev/null -w "%{http_code}" $url/v1/liveness -H "Fly-Force-Instance-Id: $MACHINE_ID" - -echo "" -echo "" - -echo "Fetching heap profile from $url, this takes $seconds seconds..." -curl -u $PPROF_USERNAME:$PPROF_PASSWORD \ - $url/debug/pprof/heap?seconds=$seconds \ - -H "Fly-Force-Instance-Id: $MACHINE_ID" \ - > $filename -go tool pprof -http=:9000 $filename \ No newline at end of file diff --git a/web/apps/agent/scripts/profile.bash b/web/apps/agent/scripts/profile.bash deleted file mode 100644 index b06c1b95b9..0000000000 --- a/web/apps/agent/scripts/profile.bash +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -set -e - - -# The following environment variables are required: -# PPROF_USERNAME -# PPROF_PASSWORD -# MACHINE_ID - -# Usage -# PPROF_USERNAME=xxx PPROF_PASSWORD=xxx MACHINE_ID=xxx bash ./scripts/profile.bash - -url="https://api.unkey.cloud" -seconds=60 -now=$(date +"%Y-%m-%d_%H-%M-%S") - - -echo "Checking machine status" -curl -s -o /dev/null -w "%{http_code}" $url/v1/liveness -H "Fly-Force-Instance-Id: $MACHINE_ID" - -echo "" -echo "" - -for type in "profile" "heap" "mutex" "block" -do - echo "Fetching $type from $url, this takes $seconds seconds..." - curl -u $PPROF_USERNAME:$PPROF_PASSWORD \ - $url/debug/pprof/$type?seconds=$seconds \ - -H "Fly-Force-Instance-Id: $MACHINE_ID" \ - > $MACHINE_ID-$type-$now.out -done - -wait - - - - - -echo "run 'go tool pprof -http=:9000 ' to view the profile" \ No newline at end of file diff --git a/web/apps/agent/services/ratelimit/bucket.go b/web/apps/agent/services/ratelimit/bucket.go deleted file mode 100644 index 3ad71fa1af..0000000000 --- a/web/apps/agent/services/ratelimit/bucket.go +++ /dev/null @@ -1,85 +0,0 @@ -package ratelimit - -import ( - "fmt" - "sync" - "time" - - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" -) - -// Generally there is one bucket per identifier. -// However if the same identifier is used with different config, such as limit -// or duration, there will be multiple buckets for the same identifier. -// -// A bucket is always uniquely identified by this triplet: identifier, limit, duration. -// See `bucketKey` for more details. -// -// A bucket reaches its lifetime when the last window has expired at least 1 * duration ago. -// In other words, we can remove a bucket when it is no longer relevant for -// ratelimit decisions. -type bucket struct { - sync.RWMutex - limit int64 - duration time.Duration - // sequence -> window - windows map[int64]*ratelimitv1.Window -} - -// bucketKey returns a unique key for an identifier and duration config -// the duration is required to ensure a change in ratelimit config will not -// reuse the same bucket and mess up the sequence numbers -type bucketKey struct { - identifier string - limit int64 - duration time.Duration -} - -func (b bucketKey) toString() string { - return fmt.Sprintf("%s-%d-%d", b.identifier, b.limit, b.duration.Milliseconds()) -} - -// getBucket returns a bucket for the given key and will create one if it does not exist. -// It returns the bucket and a boolean indicating if the bucket existed before. -func (s *service) getBucket(key bucketKey) (*bucket, bool) { - s.bucketsMu.RLock() - b, ok := s.buckets[key.toString()] - s.bucketsMu.RUnlock() - if !ok { - b = &bucket{ - limit: key.limit, - duration: key.duration, - windows: make(map[int64]*ratelimitv1.Window), - } - s.bucketsMu.Lock() - s.buckets[key.toString()] = b - s.bucketsMu.Unlock() - } - return b, ok -} - -// must be called while holding a lock on the bucket -func (b *bucket) getCurrentWindow(now time.Time) *ratelimitv1.Window { - sequence := calculateSequence(now, b.duration) - - w, ok := b.windows[sequence] - if !ok { - w = newWindow(sequence, now.Truncate(b.duration), b.duration) - b.windows[sequence] = w - } - - return w -} - -// must be called while holding a lock on the bucket -func (b *bucket) getPreviousWindow(now time.Time) *ratelimitv1.Window { - sequence := calculateSequence(now, b.duration) - 1 - - w, ok := b.windows[sequence] - if !ok { - w = newWindow(sequence, now.Add(-b.duration).Truncate(b.duration), b.duration) - b.windows[sequence] = w - } - - return w -} diff --git a/web/apps/agent/services/ratelimit/commit_lease.go b/web/apps/agent/services/ratelimit/commit_lease.go deleted file mode 100644 index f1dd58650a..0000000000 --- a/web/apps/agent/services/ratelimit/commit_lease.go +++ /dev/null @@ -1,48 +0,0 @@ -package ratelimit - -import ( - "context" - "fmt" - - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" -) - -func (s *service) CommitLease(ctx context.Context, req *ratelimitv1.CommitLeaseRequest) (*ratelimitv1.CommitLeaseResponse, error) { - // ctx, span := tracing.Start(ctx, "svc.ratelimit.CommitLease") - // defer span.End() - - // key := bucketKey{req.Lease.Identifier, req.Lease.Limit, time.Duration(req.Lease.Duration) * time.Millisecond} - - // client, origin, err := s.getPeerClient(ctx, key.toString()) - // if err != nil { - // tracing.RecordError(span, err) - // s.logger.Warn().Err(err).Str("key", key.toString()).Msg("unable to find responsible nodes") - // return nil, nil - // } - - // // If we're the origin, we can commit the lease locally and return - // if origin.Id == s.cluster.NodeId() { - // s.commitLease(ctx, commitLeaseRequest{ - // Identifier: req.Lease.Identifier, - // LeaseId: "TODO", - // Tokens: req.Cost, - // }) - - // return &ratelimitv1.CommitLeaseResponse{}, nil - // } - - // // Else we need to forward the request to the responsible node - - // connectReq := connect.NewRequest(req) - - // connectReq.Header().Set("Authorization", fmt.Sprintf("Bearer %s", s.cluster.AuthToken())) - - // res, err := client.CommitLease(ctx, connectReq) - // if err != nil { - // tracing.RecordError(span, err) - // s.logger.Err(err).Msg("failed to commit lease") - // return nil, fault.Wrap(err) - // } - // return res.Msg, nil - return nil, fmt.Errorf("TODO: implement me") -} diff --git a/web/apps/agent/services/ratelimit/consistency.go b/web/apps/agent/services/ratelimit/consistency.go deleted file mode 100644 index c284dd1542..0000000000 --- a/web/apps/agent/services/ratelimit/consistency.go +++ /dev/null @@ -1,56 +0,0 @@ -package ratelimit - -import ( - "sync" - "time" - - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/repeat" -) - -type consistencyChecker struct { - sync.Mutex - // key -> peerId -> count - counters map[string]map[string]int - - logger logging.Logger -} - -func newConsistencyChecker(logger logging.Logger) *consistencyChecker { - m := &consistencyChecker{ - counters: make(map[string]map[string]int), - logger: logger, - } - - repeat.Every(time.Minute, func() { - m.Lock() - defer m.Unlock() - - for key, peers := range m.counters { - if len(peers) > 1 { - // Our hashring ensures that a single key is only ever sent to a single node for pushpull - // In theory at least.. - m.logger.Warn().Str("key", key).Interface("peers", peers).Msg("ratelimit used multiple origins") - } - - } - // Reset the counters - m.counters = make(map[string]map[string]int) - }) - - return m -} - -func (m *consistencyChecker) Record(key, peerId string) { - m.Lock() - defer m.Unlock() - - if _, ok := m.counters[key]; !ok { - m.counters[key] = make(map[string]int) - } - - if _, ok := m.counters[key][peerId]; !ok { - m.counters[key][peerId] = 0 - } - m.counters[key][peerId]++ -} diff --git a/web/apps/agent/services/ratelimit/interface.go b/web/apps/agent/services/ratelimit/interface.go deleted file mode 100644 index 01dc764d12..0000000000 --- a/web/apps/agent/services/ratelimit/interface.go +++ /dev/null @@ -1,17 +0,0 @@ -package ratelimit - -import ( - "context" - - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" -) - -type Service interface { - Ratelimit(context.Context, *ratelimitv1.RatelimitRequest) (*ratelimitv1.RatelimitResponse, error) - MultiRatelimit(context.Context, *ratelimitv1.RatelimitMultiRequest) (*ratelimitv1.RatelimitMultiResponse, error) - PushPull(context.Context, *ratelimitv1.PushPullRequest) (*ratelimitv1.PushPullResponse, error) - CommitLease(context.Context, *ratelimitv1.CommitLeaseRequest) (*ratelimitv1.CommitLeaseResponse, error) - Mitigate(context.Context, *ratelimitv1.MitigateRequest) (*ratelimitv1.MitigateResponse, error) -} - -type Middleware func(Service) Service diff --git a/web/apps/agent/services/ratelimit/metrics.go b/web/apps/agent/services/ratelimit/metrics.go deleted file mode 100644 index 595dc06855..0000000000 --- a/web/apps/agent/services/ratelimit/metrics.go +++ /dev/null @@ -1,34 +0,0 @@ -package ratelimit - -import ( - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" -) - -var ( - ratelimitAccuracy = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: "agent", - Subsystem: "ratelimit", - Name: "ratelimit_accuracy", - }, []string{"correct"}) - - activeRatelimits = promauto.NewGauge(prometheus.GaugeOpts{ - Namespace: "agent", - Subsystem: "ratelimit", - Name: "ratelimits_active", - }) - - ratelimitsCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: "agent", - Subsystem: "ratelimit", - Name: "ratelimits_total", - }, []string{"passed"}) - - // forceSync is a counter that increments every time the agent is forced to - // sync with the origin ratelimit service because it doesn't have enough data - forceSync = promauto.NewCounter(prometheus.CounterOpts{ - Namespace: "agent", - Subsystem: "ratelimit", - Name: "force_sync", - }) -) diff --git a/web/apps/agent/services/ratelimit/middleware.go b/web/apps/agent/services/ratelimit/middleware.go deleted file mode 100644 index 8ca0a1f9b3..0000000000 --- a/web/apps/agent/services/ratelimit/middleware.go +++ /dev/null @@ -1,74 +0,0 @@ -package ratelimit - -import ( - "context" - - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "go.opentelemetry.io/otel/attribute" -) - -func WithTracing(svc Service) Service { - return &tracingMiddleware{next: svc} -} - -type tracingMiddleware struct { - next Service -} - -func (mw *tracingMiddleware) Ratelimit(ctx context.Context, req *ratelimitv1.RatelimitRequest) (res *ratelimitv1.RatelimitResponse, err error) { - - ctx, span := tracing.Start(ctx, tracing.NewSpanName("svc.ratelimit", "Ratelimit")) - defer span.End() - span.SetAttributes(attribute.String("identifier", req.Identifier), attribute.String("name", req.Name)) - - res, err = mw.next.Ratelimit(ctx, req) - if err != nil { - tracing.RecordError(span, err) - } - return res, err -} - -func (mw *tracingMiddleware) MultiRatelimit(ctx context.Context, req *ratelimitv1.RatelimitMultiRequest) (res *ratelimitv1.RatelimitMultiResponse, err error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("svc.ratelimit", "MultiRatelimit")) - defer span.End() - - res, err = mw.next.MultiRatelimit(ctx, req) - if err != nil { - tracing.RecordError(span, err) - } - return res, err -} - -func (mw *tracingMiddleware) PushPull(ctx context.Context, req *ratelimitv1.PushPullRequest) (res *ratelimitv1.PushPullResponse, err error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("svc.ratelimit", "PushPull")) - defer span.End() - - res, err = mw.next.PushPull(ctx, req) - if err != nil { - tracing.RecordError(span, err) - } - return res, err -} - -func (mw *tracingMiddleware) CommitLease(ctx context.Context, req *ratelimitv1.CommitLeaseRequest) (res *ratelimitv1.CommitLeaseResponse, err error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("svc.ratelimit", "CommitLease")) - defer span.End() - - res, err = mw.next.CommitLease(ctx, req) - if err != nil { - tracing.RecordError(span, err) - } - return res, err -} - -func (mw *tracingMiddleware) Mitigate(ctx context.Context, req *ratelimitv1.MitigateRequest) (res *ratelimitv1.MitigateResponse, err error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("svc.ratelimit", "Mitigate")) - defer span.End() - - res, err = mw.next.Mitigate(ctx, req) - if err != nil { - tracing.RecordError(span, err) - } - return res, err -} diff --git a/web/apps/agent/services/ratelimit/mitigate.go b/web/apps/agent/services/ratelimit/mitigate.go deleted file mode 100644 index 3ba44c4a30..0000000000 --- a/web/apps/agent/services/ratelimit/mitigate.go +++ /dev/null @@ -1,69 +0,0 @@ -package ratelimit - -import ( - "context" - "time" - - "connectrpc.com/connect" - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" -) - -// Mitigate is an RPC handler receiving a mitigation broadcast from the origin node -// and applying the mitigation to the local sliding window -func (s *service) Mitigate(ctx context.Context, req *ratelimitv1.MitigateRequest) (*ratelimitv1.MitigateResponse, error) { - ctx, span := tracing.Start(ctx, "ratelimit.Mitigate") - defer span.End() - - s.logger.Info().Interface("req", req).Msg("mitigating") - - duration := time.Duration(req.Duration) * time.Millisecond - bucket, _ := s.getBucket(bucketKey{req.Identifier, req.Limit, duration}) - bucket.Lock() - defer bucket.Unlock() - bucket.windows[req.Window.GetSequence()] = req.Window - - return &ratelimitv1.MitigateResponse{}, nil -} - -type mitigateWindowRequest struct { - identifier string - limit int64 - duration time.Duration - window *ratelimitv1.Window -} - -func (s *service) broadcastMitigation(req mitigateWindowRequest) { - ctx := context.Background() - node, err := s.cluster.FindNode(bucketKey{req.identifier, req.limit, req.duration}.toString()) - if err != nil { - s.logger.Warn().Err(err).Msg("failed to find node") - return - } - if node.Id != s.cluster.NodeId() { - return - } - - peers, err := s.getAllPeers(ctx) - if err != nil { - s.logger.Err(err).Msg("failed to get peers") - return - } - for _, peer := range peers { - _, err := s.mitigateCircuitBreaker.Do(ctx, func(innerCtx context.Context) (*connect.Response[ratelimitv1.MitigateResponse], error) { - innerCtx, cancel := context.WithTimeout(innerCtx, 10*time.Second) - defer cancel() - return peer.client.Mitigate(innerCtx, connect.NewRequest(&ratelimitv1.MitigateRequest{ - Identifier: req.identifier, - Limit: req.limit, - Duration: req.duration.Milliseconds(), - Window: req.window, - })) - }) - if err != nil { - s.logger.Err(err).Msg("failed to call mitigate") - } else { - s.logger.Debug().Str("peerId", peer.id).Msg("broadcasted mitigation") - } - } -} diff --git a/web/apps/agent/services/ratelimit/peer.go b/web/apps/agent/services/ratelimit/peer.go deleted file mode 100644 index b23a6c149c..0000000000 --- a/web/apps/agent/services/ratelimit/peer.go +++ /dev/null @@ -1,112 +0,0 @@ -package ratelimit - -import ( - "context" - "fmt" - "net/http" - "strings" - - "connectrpc.com/connect" - "connectrpc.com/otelconnect" - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" - "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1/ratelimitv1connect" - "github.com/unkeyed/unkey/svc/agent/pkg/cluster" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" -) - -type authorizedRoundTripper struct { - rt http.RoundTripper - headers http.Header -} - -func (h *authorizedRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { - for k, vv := range h.headers { - for _, v := range vv { - - r.Header.Add(k, v) - } - } - return h.rt.RoundTrip(r) -} - -func (s *service) getPeerClient(ctx context.Context, key string) (ratelimitv1connect.RatelimitServiceClient, cluster.Node, error) { - ctx, span := tracing.Start(ctx, "ratelimit.getPeer") - defer span.End() - - peer, err := s.cluster.FindNode(key) - if err != nil { - tracing.RecordError(span, err) - return nil, peer, fault.Wrap(err, fmsg.With("unable to find responsible nodes")) - } - s.consistencyChecker.Record(key, peer.Id) - - url := peer.RpcAddr - if !strings.Contains(url, "://") { - url = "http://" + url - } - s.peersMu.RLock() - c, ok := s.peers[url] - s.peersMu.RUnlock() - if !ok { - interceptor, err := otelconnect.NewInterceptor(otelconnect.WithTracerProvider(tracing.GetGlobalTraceProvider())) - if err != nil { - tracing.RecordError(span, err) - s.logger.Err(err).Msg("failed to create interceptor") - return nil, peer, err - } - httpClient := &http.Client{ - Transport: &authorizedRoundTripper{ - rt: http.DefaultTransport, - headers: http.Header{"Authorization": []string{fmt.Sprintf("Bearer %s", s.cluster.AuthToken())}}, - }, - } - c = ratelimitv1connect.NewRatelimitServiceClient(httpClient, url, connect.WithInterceptors(interceptor)) - s.peersMu.Lock() - s.peers[url] = c - s.peersMu.Unlock() - } - - return c, peer, nil -} - -type peer struct { - id string - client ratelimitv1connect.RatelimitServiceClient -} - -// getAllPeers returns clients for all nodes in the cluster except ourselves -func (s *service) getAllPeers(context.Context) ([]peer, error) { - peers := []peer{} - for _, p := range s.cluster.Peers() { - if p.Id == s.cluster.NodeId() { - continue - } - url := p.RpcAddr - if !strings.Contains(url, "://") { - url = "http://" + url - } - s.peersMu.RLock() - c, ok := s.peers[url] - s.peersMu.RUnlock() - if !ok { - interceptor, err := otelconnect.NewInterceptor(otelconnect.WithTracerProvider(tracing.GetGlobalTraceProvider())) - if err != nil { - s.logger.Err(err).Msg("failed to create interceptor") - return nil, err - } - httpClient := &http.Client{ - Transport: &authorizedRoundTripper{ - rt: http.DefaultTransport, - headers: http.Header{"Authorization": []string{fmt.Sprintf("Bearer %s", s.cluster.AuthToken())}}, - }, - } - c = ratelimitv1connect.NewRatelimitServiceClient(httpClient, url, connect.WithInterceptors(interceptor)) - s.peersMu.Lock() - s.peers[url] = c - s.peersMu.Unlock() - } - peers = append(peers, peer{id: p.Id, client: c}) - } - return peers, nil -} diff --git a/web/apps/agent/services/ratelimit/pushpull.go b/web/apps/agent/services/ratelimit/pushpull.go deleted file mode 100644 index eaf2f6763d..0000000000 --- a/web/apps/agent/services/ratelimit/pushpull.go +++ /dev/null @@ -1,34 +0,0 @@ -package ratelimit - -import ( - "context" - "time" - - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" -) - -func (s *service) PushPull(ctx context.Context, req *ratelimitv1.PushPullRequest) (*ratelimitv1.PushPullResponse, error) { - - r := s.Take(ctx, ratelimitRequest{ - Time: time.UnixMilli(req.Time), - Name: req.Request.Name, - Identifier: req.Request.Identifier, - Limit: req.Request.Limit, - Duration: time.Duration(req.Request.Duration) * time.Millisecond, - Cost: req.Request.Cost, - }) - - return &ratelimitv1.PushPullResponse{ - Response: &ratelimitv1.RatelimitResponse{ - Current: int64(r.Current), - Limit: int64(r.Limit), - Remaining: int64(r.Remaining), - Reset_: r.Reset, - Success: r.Pass, - }, - - Current: r.currentWindow, - Previous: r.previousWindow, - }, nil - -} diff --git a/web/apps/agent/services/ratelimit/ratelimit.go b/web/apps/agent/services/ratelimit/ratelimit.go deleted file mode 100644 index 3a0ee7fcf7..0000000000 --- a/web/apps/agent/services/ratelimit/ratelimit.go +++ /dev/null @@ -1,185 +0,0 @@ -package ratelimit - -import ( - "context" - "time" - - "connectrpc.com/connect" - "github.com/Southclaws/fault" - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "github.com/unkeyed/unkey/svc/agent/pkg/util" - "go.opentelemetry.io/otel/attribute" -) - -func (s *service) Ratelimit(ctx context.Context, req *ratelimitv1.RatelimitRequest) (*ratelimitv1.RatelimitResponse, error) { - ctx, span := tracing.Start(ctx, "ratelimit.Ratelimit") - defer span.End() - - now := time.Now() - if req.Time != nil { - now = time.UnixMilli(req.GetTime()) - } else { - req.Time = util.Pointer(now.UnixMilli()) - } - - ratelimitReq := ratelimitRequest{ - Time: now, - Name: req.Name, - Identifier: req.Identifier, - Limit: req.Limit, - Duration: time.Duration(req.Duration) * time.Millisecond, - Cost: req.Cost, - } - if req.Lease != nil { - ratelimitReq.Lease = &lease{ - Cost: req.Lease.Cost, - ExpiresAt: now.Add(time.Duration(req.Lease.Timeout) * time.Millisecond), - } - } - - prevExists, currExists := s.CheckWindows(ctx, ratelimitReq) - // If neither window existed before, we should do an origin ratelimit check - // because we likely don't have enough data to make an accurate decision' - if !prevExists && !currExists { - - originRes, err := s.ratelimitOrigin(ctx, req) - // The control flow is a bit unusual here because we want to return early on - // success, rather than on error - if err == nil && originRes != nil { - return originRes, nil - } - if err != nil { - // We want to know about the error, but if there is one, we just fall back - // to local state, so we don't return early - s.logger.Warn().Err(err).Msg("failed to sync with origin, falling back to local state") - } - } - - taken := s.Take(ctx, ratelimitReq) - - // s.logger.Warn().Str("taken", fmt.Sprintf("%+v", taken)).Send() - - res := &ratelimitv1.RatelimitResponse{ - Current: int64(taken.Current), - Limit: int64(taken.Limit), - Remaining: int64(taken.Remaining), - Reset_: taken.Reset, - Success: taken.Pass, - } - - if s.syncBuffer != nil { - err := s.bufferSync(ctx, req, now, res.Success) - if err != nil { - s.logger.Err(err).Msg("failed to sync buffer") - } - } - - if req.Lease != nil { - res.Lease = &ratelimitv1.Lease{ - Identifier: req.Identifier, - Limit: req.Limit, - Duration: req.Duration, - } - } - - return res, nil - -} - -// ratelimitOrigin forwards the ratelimit request to the origin node and updates -// the local state to reflect the true state -func (s *service) ratelimitOrigin(ctx context.Context, req *ratelimitv1.RatelimitRequest) (*ratelimitv1.RatelimitResponse, error) { - ctx, span := tracing.Start(ctx, "ratelimit.RatelimitOrigin") - defer span.End() - - forceSync.Inc() - - now := time.Now() - if req.Time != nil { - now = time.UnixMilli(req.GetTime()) - } - - key := bucketKey{req.Identifier, req.Limit, time.Duration(req.Duration) * time.Millisecond} - - client, peer, err := s.getPeerClient(ctx, key.toString()) - if err != nil { - tracing.RecordError(span, err) - s.logger.Err(err).Msg("failed to get peer client") - return nil, err - } - if peer.Id == s.cluster.NodeId() { - return nil, nil - } - s.logger.Info().Str("identifier", req.Identifier).Msg("no local state found, syncing with origin") - - connectReq := connect.NewRequest(&ratelimitv1.PushPullRequest{ - Request: req, - Time: now.UnixMilli(), - }) - - res, err := s.syncCircuitBreaker.Do(ctx, func(innerCtx context.Context) (*connect.Response[ratelimitv1.PushPullResponse], error) { - innerCtx, cancel := context.WithTimeout(innerCtx, 10*time.Second) - defer cancel() - return client.PushPull(innerCtx, connectReq) - }) - if err != nil { - tracing.RecordError(span, err) - s.logger.Warn().Err(err).Msg("failed to call ratelimit") - return nil, err - } - - duration := time.Duration(req.Duration) * time.Millisecond - err = s.SetCounter(ctx, - setCounterRequest{ - Identifier: req.Identifier, - Limit: req.Limit, - Counter: res.Msg.Current.Counter, - Sequence: res.Msg.Current.Sequence, - Duration: duration, - Time: time.UnixMilli(req.GetTime()), - }, - setCounterRequest{ - Identifier: req.Identifier, - Limit: req.Limit, - Counter: res.Msg.Previous.Counter, - Sequence: res.Msg.Previous.Sequence, - Duration: duration, - Time: time.UnixMilli(req.GetTime()), - }, - ) - if err != nil { - tracing.RecordError(span, err) - s.logger.Err(err).Msg("failed to set counter") - return nil, err - } - return res.Msg.Response, nil -} - -func (s *service) bufferSync(ctx context.Context, req *ratelimitv1.RatelimitRequest, now time.Time, localPassed bool) error { - ctx, span := tracing.Start(ctx, "ratelimit.bufferSync") - defer span.End() - key := bucketKey{req.Identifier, req.Limit, time.Duration(req.Duration) * time.Millisecond}.toString() - - origin, err := s.cluster.FindNode(key) - if err != nil { - tracing.RecordError(span, err) - s.logger.Warn().Err(err).Str("key", key).Msg("unable to find responsible nodes") - return fault.Wrap(err) - } - span.SetAttributes(attribute.Int("channelSize", len(s.syncBuffer))) - s.logger.Debug().Str("origin", origin.Id).Int("size", len(s.syncBuffer)).Msg("syncing with origin") - if origin.Id == s.cluster.NodeId() { - // no need to sync with ourselves - return nil - } - s.syncBuffer <- syncWithOriginRequest{ - req: &ratelimitv1.PushPullRequest{ - Passed: localPassed, - Time: now.UnixMilli(), - Request: req, - }, - localPassed: localPassed, - } - return nil -} diff --git a/web/apps/agent/services/ratelimit/ratelimit_multi.go b/web/apps/agent/services/ratelimit/ratelimit_multi.go deleted file mode 100644 index a3e48bb630..0000000000 --- a/web/apps/agent/services/ratelimit/ratelimit_multi.go +++ /dev/null @@ -1,34 +0,0 @@ -package ratelimit - -import ( - "context" - "time" - - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" -) - -func (s *service) MultiRatelimit(ctx context.Context, req *ratelimitv1.RatelimitMultiRequest) (*ratelimitv1.RatelimitMultiResponse, error) { - - responses := make([]*ratelimitv1.RatelimitResponse, len(req.Ratelimits)) - for i, r := range req.Ratelimits { - res := s.Take(ctx, ratelimitRequest{ - Identifier: r.Identifier, - Limit: r.Limit, - Duration: time.Duration(r.Duration) * time.Millisecond, - Cost: r.Cost, - }) - - responses[i] = &ratelimitv1.RatelimitResponse{ - Limit: res.Limit, - Remaining: res.Remaining, - Reset_: res.Reset, - Success: res.Pass, - Current: res.Current, - } - - } - - return &ratelimitv1.RatelimitMultiResponse{ - Ratelimits: responses}, nil - -} diff --git a/web/apps/agent/services/ratelimit/service.go b/web/apps/agent/services/ratelimit/service.go deleted file mode 100644 index b06a415ccf..0000000000 --- a/web/apps/agent/services/ratelimit/service.go +++ /dev/null @@ -1,121 +0,0 @@ -package ratelimit - -import ( - "sync" - "time" - - "connectrpc.com/connect" - - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" - "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1/ratelimitv1connect" - "github.com/unkeyed/unkey/svc/agent/pkg/circuitbreaker" - "github.com/unkeyed/unkey/svc/agent/pkg/cluster" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/metrics" - "github.com/unkeyed/unkey/svc/agent/pkg/prometheus" - "github.com/unkeyed/unkey/svc/agent/pkg/repeat" -) - -type service struct { - logger logging.Logger - cluster cluster.Cluster - - mitigateBuffer chan mitigateWindowRequest - syncBuffer chan syncWithOriginRequest - metrics metrics.Metrics - consistencyChecker *consistencyChecker - - peersMu sync.RWMutex - // url -> client map - peers map[string]ratelimitv1connect.RatelimitServiceClient - - shutdownCh chan struct{} - - bucketsMu sync.RWMutex - // identifier+sequence -> bucket - buckets map[string]*bucket - leaseIdToKeyMapLock sync.RWMutex - // Store a reference leaseId -> window key - leaseIdToKeyMap map[string]string - - syncCircuitBreaker circuitbreaker.CircuitBreaker[*connect.Response[ratelimitv1.PushPullResponse]] - mitigateCircuitBreaker circuitbreaker.CircuitBreaker[*connect.Response[ratelimitv1.MitigateResponse]] -} - -type Config struct { - Logger logging.Logger - Metrics metrics.Metrics - Cluster cluster.Cluster -} - -func New(cfg Config) (*service, error) { - - s := &service{ - logger: cfg.Logger, - cluster: cfg.Cluster, - metrics: cfg.Metrics, - consistencyChecker: newConsistencyChecker(cfg.Logger), - peersMu: sync.RWMutex{}, - peers: map[string]ratelimitv1connect.RatelimitServiceClient{}, - // Only set if we have a cluster - syncBuffer: nil, - mitigateBuffer: nil, - shutdownCh: make(chan struct{}), - bucketsMu: sync.RWMutex{}, - buckets: make(map[string]*bucket), - leaseIdToKeyMapLock: sync.RWMutex{}, - leaseIdToKeyMap: make(map[string]string), - - mitigateCircuitBreaker: circuitbreaker.New[*connect.Response[ratelimitv1.MitigateResponse]]( - "ratelimit.broadcastMitigation", - circuitbreaker.WithLogger(cfg.Logger), - circuitbreaker.WithCyclicPeriod(10*time.Second), - circuitbreaker.WithTimeout(time.Minute), - circuitbreaker.WithMaxRequests(100), - circuitbreaker.WithTripThreshold(50), - ), - syncCircuitBreaker: circuitbreaker.New[*connect.Response[ratelimitv1.PushPullResponse]]( - "ratelimit.syncWithOrigin", - circuitbreaker.WithLogger(cfg.Logger), - circuitbreaker.WithCyclicPeriod(10*time.Second), - circuitbreaker.WithTimeout(time.Minute), - circuitbreaker.WithMaxRequests(100), - circuitbreaker.WithTripThreshold(50), - ), - } - - repeat.Every(time.Minute, s.removeExpiredIdentifiers) - - if cfg.Cluster != nil { - s.mitigateBuffer = make(chan mitigateWindowRequest, 100000) - s.syncBuffer = make(chan syncWithOriginRequest, 100000) - // Process the individual requests to the origin and update local state - // We're using 128 goroutines to parallelise the network requests' - s.logger.Info().Msg("starting background jobs") - for range 128 { - go func() { - for { - select { - case <-s.shutdownCh: - return - case req := <-s.syncBuffer: - s.syncWithOrigin(req) - case req := <-s.mitigateBuffer: - s.broadcastMitigation(req) - } - } - }() - } - - repeat.Every(time.Second, func() { - - prometheus.ChannelBuffer.With(map[string]string{ - "id": "pushpull.syncWithOrigin", - }).Set(float64(len(s.syncBuffer)) / float64(cap(s.syncBuffer))) - - }) - - } - - return s, nil -} diff --git a/web/apps/agent/services/ratelimit/sliding_window.go b/web/apps/agent/services/ratelimit/sliding_window.go deleted file mode 100644 index c7f8342829..0000000000 --- a/web/apps/agent/services/ratelimit/sliding_window.go +++ /dev/null @@ -1,290 +0,0 @@ -package ratelimit - -import ( - "context" - "time" - - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "go.opentelemetry.io/otel/attribute" -) - -type ( - leaseId string -) -type lease struct { - Cost int64 - ExpiresAt time.Time -} - -type ratelimitRequest struct { - - // Optionally set a time, to replay this request at a specific time on the origin node - // defaults to time.Now() if not set - Time time.Time - Name string - Identifier string - Limit int64 - Cost int64 - Duration time.Duration - Lease *lease -} - -type ratelimitResponse struct { - Pass bool - Limit int64 - Remaining int64 - Reset int64 - Current int64 - - currentWindow *ratelimitv1.Window - previousWindow *ratelimitv1.Window -} - -type setCounterRequest struct { - Identifier string - Limit int64 - Duration time.Duration - Sequence int64 - // any time within the window - Time time.Time - Counter int64 -} - -type commitLeaseRequest struct { - Identifier string - LeaseId string - Tokens int64 -} - -// removeExpiredIdentifiers removes buckets that are no longer relevant -// for ratelimit decisions -func (r *service) removeExpiredIdentifiers() { - r.bucketsMu.Lock() - defer r.bucketsMu.Unlock() - - activeRatelimits.Set(float64(len(r.buckets))) - now := time.Now() - for id, bucket := range r.buckets { - bucket.Lock() - for seq, w := range bucket.windows { - if now.UnixMilli() > (w.Start + 2*w.Duration) { - delete(bucket.windows, seq) - } - } - if len(bucket.windows) == 0 { - delete(r.buckets, id) - } - bucket.Unlock() - } -} - -func calculateSequence(t time.Time, duration time.Duration) int64 { - return t.UnixMilli() / duration.Milliseconds() -} - -// CheckWindows returns whether the previous and current windows exist for the given request -func (r *service) CheckWindows(ctx context.Context, req ratelimitRequest) (prev bool, curr bool) { - ctx, span := tracing.Start(ctx, "slidingWindow.CheckWindows") - defer span.End() - - if req.Time.IsZero() { - req.Time = time.Now() - } - - key := bucketKey{req.Identifier, req.Limit, req.Duration} - bucket, existedBefore := r.getBucket(key) - if !existedBefore { - return false, false - } - - currentWindowSequence := calculateSequence(req.Time, req.Duration) - previousWindowSequence := currentWindowSequence - 1 - - bucket.RLock() - _, curr = bucket.windows[currentWindowSequence] - _, prev = bucket.windows[previousWindowSequence] - bucket.RUnlock() - return prev, curr -} - -// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -// Experimentally, we are reverting this to fixed-window until we can get rid -// of the cloudflare cachelayer. -// -// Throughout this function there is commented out and annotated code that we -// need to reenable later. Such code is also marked with the comment "FIXED-WINDOW" -// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -func (r *service) Take(ctx context.Context, req ratelimitRequest) ratelimitResponse { - ctx, span := tracing.Start(ctx, "slidingWindow.Take") - defer span.End() - - if req.Time.IsZero() { - req.Time = time.Now() - } - - key := bucketKey{req.Identifier, req.Limit, req.Duration} - span.SetAttributes(attribute.String("key", string(key.toString()))) - - bucket, _ := r.getBucket(key) - - bucket.Lock() - defer bucket.Unlock() - - currentWindow := bucket.getCurrentWindow(req.Time) - previousWindow := bucket.getPreviousWindow(req.Time) - // FIXED-WINDOW - // uncomment - // currentWindowPercentage := float64(req.Time.UnixMilli()-currentWindow.Start) / float64(req.Duration.Milliseconds()) - // previousWindowPercentage := 1.0 - currentWindowPercentage - - // Calculate the current count including all leases - // FIXED-WINDOW - // uncomment - // fromPreviousWindow := float64(previousWindow.Counter) * previousWindowPercentage - // fromCurrentWindow := float64(currentWindow.Counter) - - // FIXED-WINDOW - // replace this with the following line - // current := int64(math.Ceil(fromCurrentWindow + fromPreviousWindow)) - current := currentWindow.Counter - - // r.logger.Info().Int64("fromCurrentWindow", fromCurrentWindow).Int64("fromPreviousWindow", fromPreviousWindow).Time("now", req.Time).Time("currentWindow.start", currentWindow.start).Int64("msSinceStart", msSinceStart).Float64("currentWindowPercentage", currentWindowPercentage).Float64("previousWindowPercentage", previousWindowPercentage).Bool("currentWindowExists", currentWindowExists).Bool("previousWindowExists", previousWindowExists).Int64("current", current).Interface("buckets", r.buckets).Send() - // currentWithLeases := id.current - // if req.Lease != nil { - // currentWithLeases += req.Lease.Cost - // } - // for _, lease := range id.leases { - // if lease.expiresAt.Before(time.Now()) { - // currentWithLeases += lease.cost - // } - // } - - // Evaluate if the request should pass or not - - if current+req.Cost > req.Limit { - - ratelimitsCount.WithLabelValues("false").Inc() - remaining := req.Limit - current - if remaining < 0 { - remaining = 0 - } - return ratelimitResponse{ - Pass: false, - Remaining: remaining, - Reset: currentWindow.Start + currentWindow.Duration, - Limit: req.Limit, - Current: current, - currentWindow: currentWindow, - previousWindow: previousWindow, - } - } - - // if req.Lease != nil { - // leaseId := uid.New("lease") - // id.leases[leaseId] = lease{ - // id: leaseId, - // cost: req.Lease.Cost, - // expiresAt: req.Lease.ExpiresAt, - // } - // r.leaseIdToKeyMapLock.Lock() - // r.leaseIdToKeyMap[leaseId] = key - // r.leaseIdToKeyMapLock.Unlock() - // } - currentWindow.Counter += req.Cost - if currentWindow.Counter >= req.Limit && !currentWindow.MitigateBroadcasted && r.mitigateBuffer != nil { - currentWindow.MitigateBroadcasted = true - r.mitigateBuffer <- mitigateWindowRequest{ - identifier: req.Identifier, - limit: req.Limit, - duration: req.Duration, - window: currentWindow, - } - } - - current += req.Cost - - remaining := req.Limit - current - if remaining < 0 { - remaining = 0 - } - // currentWithLeases += req.Cost - ratelimitsCount.WithLabelValues("true").Inc() - return ratelimitResponse{ - Pass: true, - Remaining: remaining, - Reset: currentWindow.Start + currentWindow.Duration, - Limit: req.Limit, - Current: current, - currentWindow: currentWindow, - previousWindow: previousWindow, - } -} - -func (r *service) SetCounter(ctx context.Context, requests ...setCounterRequest) error { - ctx, span := tracing.Start(ctx, "slidingWindow.SetCounter") - defer span.End() - for _, req := range requests { - key := bucketKey{req.Identifier, req.Limit, req.Duration} - bucket, _ := r.getBucket(key) - - // Only increment the current value if the new value is greater than the current value - // Due to varying network latency, we may receive out of order responses and could decrement the - // current value, which would result in inaccurate rate limiting - bucket.Lock() - window, ok := bucket.windows[req.Sequence] - if !ok { - window = newWindow(req.Sequence, req.Time, req.Duration) - bucket.windows[req.Sequence] = window - } - if req.Counter > window.Counter { - window.Counter = req.Counter - } - bucket.Unlock() - - } - return nil -} - -// func (r *service) commitLease(ctx context.Context, req commitLeaseRequest) error { -// ctx, span := tracing.Start(ctx, "slidingWindow.SetCounter") -// defer span.End() - -// r.leaseIdToKeyMapLock.RLock() -// key, ok := r.leaseIdToKeyMap[req.LeaseId] -// r.leaseIdToKeyMapLock.RUnlock() -// if !ok { -// r.logger.Warn().Str("leaseId", req.LeaseId).Msg("leaseId not found") -// return nil -// } - -// r.bucketsMu.Lock() -// defer r.bucketsMu.Unlock() -// window, ok := r.buckets[key] -// if !ok { -// r.logger.Warn().Str("key", key).Msg("key not found") -// return nil -// } - -// _, ok = window.leases[req.LeaseId] -// if !ok { -// r.logger.Warn().Str("leaseId", req.LeaseId).Msg("leaseId not found") -// return nil -// } - -// return fmt.Errorf("not implemented") - -// } - -func newWindow(sequence int64, t time.Time, duration time.Duration) *ratelimitv1.Window { - return &ratelimitv1.Window{ - Sequence: sequence, - MitigateBroadcasted: false, - Start: t.Truncate(duration).UnixMilli(), - Duration: duration.Milliseconds(), - Counter: 0, - Leases: make(map[string]*ratelimitv1.Lease), - } -} diff --git a/web/apps/agent/services/ratelimit/sliding_window_test.go b/web/apps/agent/services/ratelimit/sliding_window_test.go deleted file mode 100644 index 7aca98cda8..0000000000 --- a/web/apps/agent/services/ratelimit/sliding_window_test.go +++ /dev/null @@ -1,118 +0,0 @@ -package ratelimit - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/metrics" - "github.com/unkeyed/unkey/svc/agent/pkg/uid" -) - -func TestTakeCreatesWindows(t *testing.T) { - rl, err := New(Config{ - Logger: logging.NewNoopLogger(), - Metrics: metrics.NewNoop(), - }) - require.NoError(t, err) - - now := time.Now() - - identifier := "test" - limit := int64(10) - duration := time.Minute - - res := rl.Take(context.Background(), ratelimitRequest{ - Time: now, - Name: "test", - Identifier: identifier, - Limit: limit, - Duration: duration, - Cost: 1, - }) - - require.Equal(t, int64(10), res.Limit) - require.Equal(t, int64(9), res.Remaining) - require.Equal(t, int64(1), res.Current) - require.True(t, res.Pass) - require.Equal(t, int64(0), res.previousWindow.Counter) - require.Equal(t, int64(1), res.currentWindow.Counter) - - rl.bucketsMu.RLock() - bucket, ok := rl.buckets[bucketKey{identifier, limit, duration}.toString()] - rl.bucketsMu.RUnlock() - require.True(t, ok) - - bucket.Lock() - sequence := now.UnixMilli() / duration.Milliseconds() - currentWindow, ok := bucket.windows[sequence] - require.True(t, ok) - require.Equal(t, int64(1), currentWindow.Counter) - - previousWindow, ok := bucket.windows[sequence-1] - require.True(t, ok) - require.Equal(t, int64(0), previousWindow.Counter) - -} - -func TestSlidingWindowAccuracy(t *testing.T) { - rl, err := New(Config{ - Logger: logging.New(nil), - Metrics: metrics.NewNoop(), - }) - require.NoError(t, err) - - for _, limit := range []int64{ - 5, - 10, - 100, - 500, - } { - for _, duration := range []time.Duration{ - 1 * time.Second, - 10 * time.Second, - 1 * time.Minute, - 5 * time.Minute, - 1 * time.Hour, - } { - for _, windows := range []int64{1, 2, 5, 10, 50} { - requests := limit * windows * 1000 - t.Run(fmt.Sprintf("rate %d/%s %d requests across %d windows", - limit, - duration, - requests, - windows, - ), func(t *testing.T) { - - identifier := uid.New("test") - - passed := int64(0) - total := time.Duration(windows) * duration - dt := total / time.Duration(requests) - now := time.Now().Truncate(duration) - for i := int64(0); i < requests; i++ { - res := rl.Take(context.Background(), ratelimitRequest{ - Time: now.Add(time.Duration(i) * dt), - Identifier: identifier, - Limit: limit, - Duration: duration, - Cost: 1, - }) - if res.Pass { - passed++ - } - } - - require.GreaterOrEqual(t, passed, int64(float64(limit)*float64(windows)*0.8), "%d out of %d passed", passed, requests) - require.LessOrEqual(t, passed, limit*(windows+1), "%d out of %d passed", passed, requests) - - }) - } - - } - } - -} diff --git a/web/apps/agent/services/ratelimit/sync_with_origin.go b/web/apps/agent/services/ratelimit/sync_with_origin.go deleted file mode 100644 index 906ed055b5..0000000000 --- a/web/apps/agent/services/ratelimit/sync_with_origin.go +++ /dev/null @@ -1,92 +0,0 @@ -package ratelimit - -import ( - "context" - "time" - - "connectrpc.com/connect" - ratelimitv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/ratelimit/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/prometheus" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" -) - -type syncWithOriginRequest struct { - req *ratelimitv1.PushPullRequest - localPassed bool -} - -func (s *service) syncWithOrigin(req syncWithOriginRequest) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - ctx, span := tracing.Start(ctx, "ratelimit.syncWithOrigin") - defer span.End() - - t := time.UnixMilli(req.req.Time) - duration := time.Duration(req.req.Request.Duration) * time.Millisecond - - key := bucketKey{req.req.Request.Identifier, req.req.Request.Limit, duration}.toString() - client, peer, err := s.getPeerClient(ctx, key) - if err != nil { - tracing.RecordError(span, err) - s.logger.Warn().Err(err).Str("key", key).Msg("unable to create peer client") - return - } - if peer.Id == s.cluster.NodeId() { - return - } - - res, err := s.syncCircuitBreaker.Do(ctx, func(innerCtx context.Context) (*connect.Response[ratelimitv1.PushPullResponse], error) { - innerCtx, cancel = context.WithTimeout(innerCtx, 10*time.Second) - defer cancel() - return client.PushPull(innerCtx, connect.NewRequest(req.req)) - }) - if err != nil { - s.peersMu.Lock() - s.logger.Warn().Str("peerId", peer.Id).Err(err).Msg("resetting peer client due to error") - delete(s.peers, peer.Id) - s.peersMu.Unlock() - tracing.RecordError(span, err) - s.logger.Warn().Err(err).Str("peerId", peer.Id).Str("addr", peer.RpcAddr).Msg("failed to push pull") - return - } - - err = s.SetCounter(ctx, - setCounterRequest{ - Identifier: req.req.Request.Identifier, - Limit: req.req.Request.Limit, - Counter: res.Msg.Current.Counter, - Sequence: res.Msg.Current.Sequence, - Duration: duration, - Time: t, - }, - setCounterRequest{ - Identifier: req.req.Request.Identifier, - - Counter: res.Msg.Previous.Counter, - Sequence: res.Msg.Previous.Sequence, - Duration: duration, - Time: t, - }, - ) - - if req.localPassed == res.Msg.Response.Success { - ratelimitAccuracy.WithLabelValues("true").Inc() - } else { - ratelimitAccuracy.WithLabelValues("false").Inc() - } - - // req.events is guaranteed to have at least element - // and the first one should be the oldest event, so we can use it to get the max latency - latency := time.Since(t) - labels := map[string]string{ - "nodeId": s.cluster.NodeId(), - "peerId": peer.Id, - } - prometheus.RatelimitPushPullEvents.With(labels).Inc() - - prometheus.RatelimitPushPullLatency.With(labels).Observe(latency.Seconds()) - - // if we got this far, we pushpulled successfully with a peer and don't need to try the rest - -} diff --git a/web/apps/agent/services/vault/create_dek.go b/web/apps/agent/services/vault/create_dek.go deleted file mode 100644 index 3e860f17c4..0000000000 --- a/web/apps/agent/services/vault/create_dek.go +++ /dev/null @@ -1,21 +0,0 @@ -package vault - -import ( - "context" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" -) - -func (s *Service) CreateDEK(ctx context.Context, req *vaultv1.CreateDEKRequest) (*vaultv1.CreateDEKResponse, error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("service.vault", "CreateDEK")) - defer span.End() - - key, err := s.keyring.CreateKey(ctx, req.Keyring) - if err != nil { - return nil, err - } - return &vaultv1.CreateDEKResponse{ - KeyId: key.Id, - }, nil -} diff --git a/web/apps/agent/services/vault/decrypt.go b/web/apps/agent/services/vault/decrypt.go deleted file mode 100644 index a0a34f9cd6..0000000000 --- a/web/apps/agent/services/vault/decrypt.go +++ /dev/null @@ -1,52 +0,0 @@ -package vault - -import ( - "context" - "encoding/base64" - "fmt" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/cache" - "github.com/unkeyed/unkey/svc/agent/pkg/encryption" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "google.golang.org/protobuf/proto" -) - -func (s *Service) Decrypt( - ctx context.Context, - req *vaultv1.DecryptRequest, -) (*vaultv1.DecryptResponse, error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("service.vault", "Decrypt")) - defer span.End() - - b, err := base64.StdEncoding.DecodeString(req.Encrypted) - if err != nil { - return nil, fmt.Errorf("failed to decode encrypted data: %w", err) - } - encrypted := &vaultv1.Encrypted{} - err = proto.Unmarshal(b, encrypted) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal encrypted data: %w", err) - } - - cacheKey := fmt.Sprintf("%s-%s", req.Keyring, encrypted.EncryptionKeyId) - - dek, hit := s.keyCache.Get(ctx, cacheKey) - if hit == cache.Miss { - dek, err = s.keyring.GetKey(ctx, req.Keyring, encrypted.EncryptionKeyId) - if err != nil { - return nil, fmt.Errorf("failed to get dek in keyring %s: %w", req.Keyring, err) - } - s.keyCache.Set(ctx, cacheKey, dek) - } - - plaintext, err := encryption.Decrypt(dek.GetKey(), encrypted.GetNonce(), encrypted.GetCiphertext()) - if err != nil { - return nil, fmt.Errorf("failed to decrypt ciphertext: %w", err) - } - - return &vaultv1.DecryptResponse{ - Plaintext: string(plaintext), - }, nil - -} diff --git a/web/apps/agent/services/vault/encrypt.go b/web/apps/agent/services/vault/encrypt.go deleted file mode 100644 index 6b3031f7bc..0000000000 --- a/web/apps/agent/services/vault/encrypt.go +++ /dev/null @@ -1,59 +0,0 @@ -package vault - -import ( - "context" - "encoding/base64" - "fmt" - "time" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/cache" - "github.com/unkeyed/unkey/svc/agent/pkg/encryption" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "go.opentelemetry.io/otel/attribute" - "google.golang.org/protobuf/proto" -) - -func (s *Service) Encrypt( - ctx context.Context, - req *vaultv1.EncryptRequest, -) (*vaultv1.EncryptResponse, error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("service.vault", "Encrypt")) - defer span.End() - span.SetAttributes(attribute.String("keyring", req.Keyring)) - - cacheKey := fmt.Sprintf("%s-%s", req.Keyring, LATEST) - - dek, hit := s.keyCache.Get(ctx, cacheKey) - if hit != cache.Hit { - var err error - dek, err = s.keyring.GetOrCreateKey(ctx, req.Keyring, LATEST) - if err != nil { - return nil, fmt.Errorf("failed to get latest dek in keyring %s: %w", req.Keyring, err) - } - s.keyCache.Set(ctx, cacheKey, dek) - } - - nonce, ciphertext, err := encryption.Encrypt(dek.Key, []byte(req.GetData())) - if err != nil { - return nil, fmt.Errorf("failed to encrypt data: %w", err) - } - - encryptedData := &vaultv1.Encrypted{ - Algorithm: vaultv1.Algorithm_AES_256_GCM, - Nonce: nonce, - Ciphertext: ciphertext, - EncryptionKeyId: dek.GetId(), - Time: time.Now().UnixMilli(), - } - - b, err := proto.Marshal(encryptedData) - if err != nil { - return nil, fmt.Errorf("failed to marshal encrypted data: %w", err) - } - - return &vaultv1.EncryptResponse{ - Encrypted: base64.StdEncoding.EncodeToString(b), - KeyId: dek.GetId(), - }, nil -} diff --git a/web/apps/agent/services/vault/encrypt_bulk.go b/web/apps/agent/services/vault/encrypt_bulk.go deleted file mode 100644 index 62505150ae..0000000000 --- a/web/apps/agent/services/vault/encrypt_bulk.go +++ /dev/null @@ -1,34 +0,0 @@ -package vault - -import ( - "context" - "fmt" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" -) - -func (s *Service) EncryptBulk( - ctx context.Context, - req *vaultv1.EncryptBulkRequest, -) (*vaultv1.EncryptBulkResponse, error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("service.vault", "EncryptBulk")) - defer span.End() - - res := &vaultv1.EncryptBulkResponse{ - Encrypted: make([]*vaultv1.EncryptResponse, len(req.Data)), - } - - for i, data := range req.Data { - decryptResponse, err := s.Encrypt(ctx, &vaultv1.EncryptRequest{ - Keyring: req.Keyring, - Data: data, - }) - if err != nil { - return nil, fmt.Errorf("failed to encrypt request %d: %w", i, err) - } - res.Encrypted[i] = decryptResponse - } - - return res, nil -} diff --git a/web/apps/agent/services/vault/integration/coldstart_test.go b/web/apps/agent/services/vault/integration/coldstart_test.go deleted file mode 100644 index da023237ce..0000000000 --- a/web/apps/agent/services/vault/integration/coldstart_test.go +++ /dev/null @@ -1,94 +0,0 @@ -package integration_test - -import ( - "context" - "testing" - - "github.com/rs/zerolog" - "github.com/stretchr/testify/require" - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/testutils/containers" - "github.com/unkeyed/unkey/svc/agent/services/vault" - "github.com/unkeyed/unkey/svc/agent/services/vault/keys" - "github.com/unkeyed/unkey/svc/agent/services/vault/storage" -) - -// This scenario tests the cold start of the vault service. -// There are no keys in the storage and a few users are starting to use it - -func Test_ColdStart(t *testing.T) { - - logger := logging.New(nil).Level(zerolog.ErrorLevel) - - s3 := containers.NewS3(t) - defer s3.Stop() - - storage, err := storage.NewS3(storage.S3Config{ - S3URL: s3.URL, - S3Bucket: "vault", - S3AccessKeyId: s3.AccessKeyId, - S3AccessKeySecret: s3.AccessKeySecret, - Logger: logger, - }) - require.NoError(t, err) - - _, masterKey, err := keys.GenerateMasterKey() - require.NoError(t, err) - - v, err := vault.New(vault.Config{ - Storage: storage, - Logger: logger, - MasterKeys: []string{masterKey}, - }) - require.NoError(t, err) - - ctx := context.Background() - - // Alice encrypts a secret - aliceData := "alice secret" - aliceEncryptionRes, err := v.Encrypt(ctx, &vaultv1.EncryptRequest{ - Keyring: "alice", - Data: aliceData, - }) - require.NoError(t, err) - - // Bob encrypts a secret - bobData := "bob secret" - bobEncryptionRes, err := v.Encrypt(ctx, &vaultv1.EncryptRequest{ - Keyring: "bob", - Data: bobData, - }) - require.NoError(t, err) - - // Alice decrypts her secret - aliceDecryptionRes, err := v.Decrypt(ctx, &vaultv1.DecryptRequest{ - Keyring: "alice", - Encrypted: aliceEncryptionRes.Encrypted, - }) - require.NoError(t, err) - require.Equal(t, aliceData, aliceDecryptionRes.Plaintext) - - // Bob reencrypts his secret - - _, err = v.CreateDEK(ctx, &vaultv1.CreateDEKRequest{ - Keyring: "bob", - }) - require.NoError(t, err) - bobReencryptionRes, err := v.ReEncrypt(ctx, &vaultv1.ReEncryptRequest{ - Keyring: "bob", - Encrypted: bobEncryptionRes.Encrypted, - }) - require.NoError(t, err) - - // Bob decrypts his secret - bobDecryptionRes, err := v.Decrypt(ctx, &vaultv1.DecryptRequest{ - Keyring: "bob", - Encrypted: bobReencryptionRes.Encrypted, - }) - require.NoError(t, err) - require.Equal(t, bobData, bobDecryptionRes.Plaintext) - // expect the key to be different - require.NotEqual(t, bobEncryptionRes.KeyId, bobReencryptionRes.KeyId) - -} diff --git a/web/apps/agent/services/vault/integration/migrate_deks_test.go b/web/apps/agent/services/vault/integration/migrate_deks_test.go deleted file mode 100644 index bd251c068b..0000000000 --- a/web/apps/agent/services/vault/integration/migrate_deks_test.go +++ /dev/null @@ -1,110 +0,0 @@ -package integration_test - -import ( - "context" - "crypto/rand" - "testing" - - "github.com/rs/zerolog" - "github.com/stretchr/testify/require" - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/testutils/containers" - "github.com/unkeyed/unkey/svc/agent/services/vault" - "github.com/unkeyed/unkey/svc/agent/services/vault/keys" - "github.com/unkeyed/unkey/svc/agent/services/vault/storage" -) - -// This scenario tests the re-encryption of a secret. -func TestMigrateDeks(t *testing.T) { - - logger := logging.New(nil).Level(zerolog.ErrorLevel) - - data := make(map[string]string) - s3 := containers.NewS3(t) - defer s3.Stop() - - storage, err := storage.NewS3(storage.S3Config{ - S3URL: s3.URL, - S3Bucket: "vault", - S3AccessKeyId: s3.AccessKeyId, - S3AccessKeySecret: s3.AccessKeySecret, - Logger: logger, - }) - require.NoError(t, err) - - _, masterKeyOld, err := keys.GenerateMasterKey() - require.NoError(t, err) - - v, err := vault.New(vault.Config{ - Storage: storage, - Logger: logger, - MasterKeys: []string{masterKeyOld}, - }) - require.NoError(t, err) - - ctx := context.Background() - - // Seed some DEKs - for range 10 { - _, err = v.CreateDEK(ctx, &vaultv1.CreateDEKRequest{ - Keyring: "keyring", - }) - require.NoError(t, err) - - buf := make([]byte, 32) - _, err = rand.Read(buf) - d := string(buf) - require.NoError(t, err) - res, encryptErr := v.Encrypt(ctx, &vaultv1.EncryptRequest{ - Keyring: "keyring", - Data: string(d), - }) - require.NoError(t, encryptErr) - data[d] = res.Encrypted - } - - // Simulate Restart - - _, masterKeyNew, err := keys.GenerateMasterKey() - require.NoError(t, err) - - v, err = vault.New(vault.Config{ - Storage: storage, - Logger: logger, - MasterKeys: []string{masterKeyOld, masterKeyNew}, - }) - require.NoError(t, err) - - err = v.RollDeks(ctx) - require.NoError(t, err) - - // Check each piece of data can be decrypted - for d, e := range data { - res, decryptErr := v.Decrypt(ctx, &vaultv1.DecryptRequest{ - Keyring: "keyring", - Encrypted: e, - }) - require.NoError(t, decryptErr) - require.Equal(t, d, res.Plaintext) - } - // Simulate another restart, removing the old master key - - v, err = vault.New(vault.Config{ - Storage: storage, - Logger: logger, - MasterKeys: []string{masterKeyNew}, - }) - require.NoError(t, err) - - // Check each piece of data can be decrypted - for d, e := range data { - res, err := v.Decrypt(ctx, &vaultv1.DecryptRequest{ - Keyring: "keyring", - Encrypted: e, - }) - require.NoError(t, err) - require.Equal(t, d, res.Plaintext) - } - -} diff --git a/web/apps/agent/services/vault/integration/reencryption_test.go b/web/apps/agent/services/vault/integration/reencryption_test.go deleted file mode 100644 index 96adf02a33..0000000000 --- a/web/apps/agent/services/vault/integration/reencryption_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package integration_test - -import ( - "context" - "crypto/rand" - "fmt" - "math" - "testing" - - "github.com/rs/zerolog" - "github.com/stretchr/testify/require" - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/testutils/containers" - "github.com/unkeyed/unkey/svc/agent/services/vault" - "github.com/unkeyed/unkey/svc/agent/services/vault/keys" - "github.com/unkeyed/unkey/svc/agent/services/vault/storage" -) - -// This scenario tests the re-encryption of a secret. -func TestReEncrypt(t *testing.T) { - - logger := logging.New(nil).Level(zerolog.ErrorLevel) - s3 := containers.NewS3(t) - defer s3.Stop() - - storage, err := storage.NewS3(storage.S3Config{ - S3URL: s3.URL, - S3Bucket: "vault", - S3AccessKeyId: s3.AccessKeyId, - S3AccessKeySecret: s3.AccessKeySecret, - Logger: logger, - }) - require.NoError(t, err) - - _, masterKey, err := keys.GenerateMasterKey() - require.NoError(t, err) - - v, err := vault.New(vault.Config{ - Storage: storage, - Logger: logger, - MasterKeys: []string{masterKey}, - }) - require.NoError(t, err) - - ctx := context.Background() - - for i := 1; i < 9; i++ { - - dataSize := int(math.Pow(8, float64(i))) - t.Run(fmt.Sprintf("with %d bytes", dataSize), func(t *testing.T) { - - keyring := fmt.Sprintf("keyring-%d", i) - buf := make([]byte, dataSize) - _, err := rand.Read(buf) - require.NoError(t, err) - - data := string(buf) - - enc, err := v.Encrypt(ctx, &vaultv1.EncryptRequest{ - Keyring: keyring, - Data: data, - }) - require.NoError(t, err) - - deks := []string{} - for range 10 { - dek, createDekErr := v.CreateDEK(ctx, &vaultv1.CreateDEKRequest{ - Keyring: keyring, - }) - require.NoError(t, createDekErr) - require.NotContains(t, deks, dek.KeyId) - deks = append(deks, dek.KeyId) - _, err = v.ReEncrypt(ctx, &vaultv1.ReEncryptRequest{ - Keyring: keyring, - Encrypted: enc.Encrypted, - }) - require.NoError(t, err) - } - - dec, err := v.Decrypt(ctx, &vaultv1.DecryptRequest{ - Keyring: keyring, - Encrypted: enc.Encrypted, - }) - require.NoError(t, err) - require.Equal(t, data, dec.Plaintext) - }) - - } - -} diff --git a/web/apps/agent/services/vault/integration/reusing_deks_test.go b/web/apps/agent/services/vault/integration/reusing_deks_test.go deleted file mode 100644 index 7e7ccc6640..0000000000 --- a/web/apps/agent/services/vault/integration/reusing_deks_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package integration_test - -import ( - "context" - "testing" - - "github.com/google/uuid" - "github.com/rs/zerolog" - "github.com/stretchr/testify/require" - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/testutils/containers" - "github.com/unkeyed/unkey/svc/agent/services/vault" - "github.com/unkeyed/unkey/svc/agent/services/vault/keys" - "github.com/unkeyed/unkey/svc/agent/services/vault/storage" -) - -// When encrypting multiple secrets with the same keyring, the same DEK should be reused for all of them. -func TestReuseDEKsForSameKeyring(t *testing.T) { - - logger := logging.New(nil).Level(zerolog.ErrorLevel) - - s3 := containers.NewS3(t) - defer s3.Stop() - - storage, err := storage.NewS3(storage.S3Config{ - S3URL: s3.URL, - S3Bucket: "vault", - S3AccessKeyId: s3.AccessKeyId, - S3AccessKeySecret: s3.AccessKeySecret, - Logger: logger, - }) - require.NoError(t, err) - - _, masterKey, err := keys.GenerateMasterKey() - require.NoError(t, err) - - v, err := vault.New(vault.Config{ - Storage: storage, - Logger: logger, - MasterKeys: []string{masterKey}, - }) - require.NoError(t, err) - - ctx := context.Background() - - deks := map[string]bool{} - - for range 10 { - res, encryptErr := v.Encrypt(ctx, &vaultv1.EncryptRequest{ - Keyring: "keyring", - Data: uuid.NewString(), - }) - require.NoError(t, encryptErr) - deks[res.KeyId] = true - } - - require.Len(t, deks, 1) - -} - -// When encrypting multiple secrets with different keyrings, a different DEK should be used for each keyring. -func TestIndividualDEKsPerKeyring(t *testing.T) { - - logger := logging.New(nil).Level(zerolog.ErrorLevel) - - s3 := containers.NewS3(t) - defer s3.Stop() - - storage, err := storage.NewS3(storage.S3Config{ - S3URL: s3.URL, - S3Bucket: "vault", - S3AccessKeyId: s3.AccessKeyId, - S3AccessKeySecret: s3.AccessKeySecret, - Logger: logger, - }) - require.NoError(t, err) - - _, masterKey, err := keys.GenerateMasterKey() - require.NoError(t, err) - - v, err := vault.New(vault.Config{ - Storage: storage, - Logger: logger, - MasterKeys: []string{masterKey}, - }) - require.NoError(t, err) - - ctx := context.Background() - - deks := map[string]bool{} - - for range 10 { - res, encryptErr := v.Encrypt(ctx, &vaultv1.EncryptRequest{ - Keyring: uuid.NewString(), - Data: uuid.NewString(), - }) - require.NoError(t, encryptErr) - deks[res.KeyId] = true - } - - require.Len(t, deks, 10) - -} diff --git a/web/apps/agent/services/vault/keyring/create_key.go b/web/apps/agent/services/vault/keyring/create_key.go deleted file mode 100644 index 13cbcf2458..0000000000 --- a/web/apps/agent/services/vault/keyring/create_key.go +++ /dev/null @@ -1,42 +0,0 @@ -package keyring - -import ( - "context" - "fmt" - "time" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "github.com/unkeyed/unkey/svc/agent/services/vault/keys" -) - -func (k *Keyring) CreateKey(ctx context.Context, ringID string) (*vaultv1.DataEncryptionKey, error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("keyring", "CreateKey")) - defer span.End() - keyId, key, err := keys.GenerateKey("dek") - if err != nil { - return nil, fmt.Errorf("failed to generate key: %w", err) - } - - dek := &vaultv1.DataEncryptionKey{ - Id: keyId, - Key: key, - CreatedAt: time.Now().UnixMilli(), - } - - b, err := k.EncryptAndEncodeKey(ctx, dek) - if err != nil { - return nil, fmt.Errorf("failed to encrypt and encode dek: %w", err) - } - - err = k.store.PutObject(ctx, k.buildLookupKey(ringID, dek.Id), b) - if err != nil { - return nil, fmt.Errorf("failed to put encrypted dek: %w", err) - } - err = k.store.PutObject(ctx, k.buildLookupKey(ringID, "LATEST"), b) - if err != nil { - return nil, fmt.Errorf("failed to put encrypted dek: %w", err) - } - - return dek, nil -} diff --git a/web/apps/agent/services/vault/keyring/decode_and_decrypt_key.go b/web/apps/agent/services/vault/keyring/decode_and_decrypt_key.go deleted file mode 100644 index 4ae5591ca7..0000000000 --- a/web/apps/agent/services/vault/keyring/decode_and_decrypt_key.go +++ /dev/null @@ -1,44 +0,0 @@ -package keyring - -import ( - "context" - "fmt" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/encryption" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "google.golang.org/protobuf/proto" -) - -func (k *Keyring) DecodeAndDecryptKey(ctx context.Context, b []byte) (*vaultv1.DataEncryptionKey, string, error) { - _, span := tracing.Start(ctx, tracing.NewSpanName("keyring", "DecodeAndDecryptKey")) - defer span.End() - encrypted := &vaultv1.EncryptedDataEncryptionKey{} - err := proto.Unmarshal(b, encrypted) - if err != nil { - tracing.RecordError(span, err) - return nil, "", fmt.Errorf("failed to unmarshal encrypted dek: %w", err) - } - - kek, ok := k.decryptionKeys[encrypted.Encrypted.EncryptionKeyId] - if !ok { - err = fmt.Errorf("no kek found for key id: %s", encrypted.Encrypted.EncryptionKeyId) - tracing.RecordError(span, err) - return nil, "", err - } - - plaintext, err := encryption.Decrypt(kek.GetKey(), encrypted.GetEncrypted().GetNonce(), encrypted.GetEncrypted().GetCiphertext()) - if err != nil { - tracing.RecordError(span, err) - return nil, "", fmt.Errorf("failed to decrypt ciphertext: %w", err) - } - - dek := &vaultv1.DataEncryptionKey{} - err = proto.Unmarshal(plaintext, dek) - if err != nil { - tracing.RecordError(span, err) - return nil, "", fmt.Errorf("failed to unmarshal dek: %w", err) - } - return dek, encrypted.Encrypted.EncryptionKeyId, nil - -} diff --git a/web/apps/agent/services/vault/keyring/encrypt_and_encode_key.go b/web/apps/agent/services/vault/keyring/encrypt_and_encode_key.go deleted file mode 100644 index 9455d8f0b8..0000000000 --- a/web/apps/agent/services/vault/keyring/encrypt_and_encode_key.go +++ /dev/null @@ -1,44 +0,0 @@ -package keyring - -import ( - "context" - "fmt" - "time" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/encryption" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "google.golang.org/protobuf/proto" -) - -func (k *Keyring) EncryptAndEncodeKey(ctx context.Context, dek *vaultv1.DataEncryptionKey) ([]byte, error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("keyring", "EncryptAndEncodeKey")) - defer span.End() - b, err := proto.Marshal(dek) - if err != nil { - return nil, fmt.Errorf("failed to marshal dek: %w", err) - } - - nonce, ciphertext, err := encryption.Encrypt(k.encryptionKey.Key, b) - if err != nil { - return nil, fmt.Errorf("failed to encrypt dek: %w", err) - } - - encryptedDek := &vaultv1.EncryptedDataEncryptionKey{ - Id: dek.Id, - CreatedAt: dek.CreatedAt, - Encrypted: &vaultv1.Encrypted{ - Algorithm: vaultv1.Algorithm_AES_256_GCM, - Nonce: nonce, - Ciphertext: ciphertext, - EncryptionKeyId: k.encryptionKey.Id, - Time: time.Now().UnixMilli(), - }, - } - - b, err = proto.Marshal(encryptedDek) - if err != nil { - return nil, fmt.Errorf("failed to marshal encrypted dek: %w", err) - } - return b, nil -} diff --git a/web/apps/agent/services/vault/keyring/get_key.go b/web/apps/agent/services/vault/keyring/get_key.go deleted file mode 100644 index 4e49dc8b8f..0000000000 --- a/web/apps/agent/services/vault/keyring/get_key.go +++ /dev/null @@ -1,37 +0,0 @@ -package keyring - -import ( - "context" - "fmt" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "github.com/unkeyed/unkey/svc/agent/services/vault/storage" - "go.opentelemetry.io/otel/attribute" -) - -func (k *Keyring) GetKey(ctx context.Context, ringID, keyID string) (*vaultv1.DataEncryptionKey, error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("keyring", "GetKey")) - defer span.End() - - lookupKey := k.buildLookupKey(ringID, keyID) - span.SetAttributes(attribute.String("lookupKey", lookupKey)) - - b, found, err := k.store.GetObject(ctx, lookupKey) - span.SetAttributes(attribute.Bool("found", found)) - if err != nil { - tracing.RecordError(span, err) - return nil, fmt.Errorf("failed to get object: %w", err) - - } - if !found { - return nil, storage.ErrObjectNotFound - } - - dek, _, err := k.DecodeAndDecryptKey(ctx, b) - if err != nil { - tracing.RecordError(span, err) - return nil, fmt.Errorf("failed to decode and decrypt key: %w", err) - } - return dek, nil -} diff --git a/web/apps/agent/services/vault/keyring/get_latest_key.go b/web/apps/agent/services/vault/keyring/get_latest_key.go deleted file mode 100644 index 79cc35469d..0000000000 --- a/web/apps/agent/services/vault/keyring/get_latest_key.go +++ /dev/null @@ -1,28 +0,0 @@ -package keyring - -import ( - "context" - "fmt" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "github.com/unkeyed/unkey/svc/agent/services/vault/storage" -) - -// GetLatestKey returns the latest key from the keyring. If no key is found, it creates a new key. -func (k *Keyring) GetLatestKey(ctx context.Context, ringID string) (*vaultv1.DataEncryptionKey, error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("keyring", "GetLatestKey")) - defer span.End() - dek, err := k.GetKey(ctx, ringID, "LATEST") - - if err == nil { - return dek, nil - } - - if err != storage.ErrObjectNotFound { - tracing.RecordError(span, err) - return nil, fmt.Errorf("failed to get key: %w", err) - } - - return k.CreateKey(ctx, ringID) -} diff --git a/web/apps/agent/services/vault/keyring/get_or_create_key.go b/web/apps/agent/services/vault/keyring/get_or_create_key.go deleted file mode 100644 index 2e8077a0f6..0000000000 --- a/web/apps/agent/services/vault/keyring/get_or_create_key.go +++ /dev/null @@ -1,31 +0,0 @@ -package keyring - -import ( - "context" - "errors" - "fmt" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "github.com/unkeyed/unkey/svc/agent/services/vault/storage" - "go.opentelemetry.io/otel/attribute" -) - -func (k *Keyring) GetOrCreateKey(ctx context.Context, ringID, keyID string) (*vaultv1.DataEncryptionKey, error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("keyring", "GetOrCreateKey")) - defer span.End() - span.SetAttributes(attribute.String("ringID", ringID), attribute.String("keyID", keyID)) - dek, err := k.GetKey(ctx, ringID, keyID) - if err == nil { - return dek, nil - } - - if errors.Is(err, storage.ErrObjectNotFound) { - return k.CreateKey(ctx, ringID) - } - - tracing.RecordError(span, err) - - return nil, fmt.Errorf("failed to get key: %w", err) - -} diff --git a/web/apps/agent/services/vault/keyring/keyring.go b/web/apps/agent/services/vault/keyring/keyring.go deleted file mode 100644 index afe338be2b..0000000000 --- a/web/apps/agent/services/vault/keyring/keyring.go +++ /dev/null @@ -1,41 +0,0 @@ -package keyring - -import ( - "fmt" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/services/vault/storage" -) - -type Keyring struct { - store storage.Storage - logger logging.Logger - - // any of these can be used for decryption - decryptionKeys map[string]*vaultv1.KeyEncryptionKey - encryptionKey *vaultv1.KeyEncryptionKey -} - -type Config struct { - Store storage.Storage - Logger logging.Logger - - DecryptionKeys map[string]*vaultv1.KeyEncryptionKey - EncryptionKey *vaultv1.KeyEncryptionKey -} - -func New(config Config) (*Keyring, error) { - - return &Keyring{ - store: config.Store, - logger: config.Logger, - encryptionKey: config.EncryptionKey, - decryptionKeys: config.DecryptionKeys, - }, nil -} - -// The storage layer doesn't know about keyrings, so we need to prefix the key with the keyring id -func (k *Keyring) buildLookupKey(ringID, dekID string) string { - return fmt.Sprintf("keyring/%s/%s", ringID, dekID) -} diff --git a/web/apps/agent/services/vault/keyring/roll_keys.go b/web/apps/agent/services/vault/keyring/roll_keys.go deleted file mode 100644 index 6f00a9be96..0000000000 --- a/web/apps/agent/services/vault/keyring/roll_keys.go +++ /dev/null @@ -1,48 +0,0 @@ -package keyring - -import ( - "context" - "fmt" - - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "github.com/unkeyed/unkey/svc/agent/services/vault/storage" -) - -func (k *Keyring) RollKeys(ctx context.Context, ringID string) error { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("keyring", "RollKeys")) - defer span.End() - lookupKeys, err := k.store.ListObjectKeys(ctx, k.buildLookupKey(ringID, "dek_")) - if err != nil { - return fmt.Errorf("failed to list keys: %w", err) - } - - for _, objectKey := range lookupKeys { - b, found, err := k.store.GetObject(ctx, objectKey) - if err != nil { - return fmt.Errorf("failed to get object: %w", err) - } - if !found { - return storage.ErrObjectNotFound - } - - dek, encryptionKeyId, err := k.DecodeAndDecryptKey(ctx, b) - if err != nil { - return fmt.Errorf("failed to decode and decrypt key: %w", err) - } - if encryptionKeyId == k.encryptionKey.Id { - k.logger.Info().Str("keyId", dek.Id).Msg("key already encrypted with latest kek") - continue - } - reencrypted, err := k.EncryptAndEncodeKey(ctx, dek) - if err != nil { - return fmt.Errorf("failed to re-encrypt key: %w", err) - } - err = k.store.PutObject(ctx, objectKey, reencrypted) - if err != nil { - return fmt.Errorf("failed to put re-encrypted key: %w", err) - } - } - - return nil - -} diff --git a/web/apps/agent/services/vault/keys/key.go b/web/apps/agent/services/vault/keys/key.go deleted file mode 100644 index 0bbc82309b..0000000000 --- a/web/apps/agent/services/vault/keys/key.go +++ /dev/null @@ -1,19 +0,0 @@ -package keys - -import ( - "crypto/rand" - "fmt" - "github.com/segmentio/ksuid" -) - -func GenerateKey(prefix string) (id string, key []byte, err error) { - - key = make([]byte, 32) - _, err = rand.Read(key) - if err != nil { - return "", nil, fmt.Errorf("failed to generate random data: %w", err) - } - - return fmt.Sprintf("%s_%s", prefix, ksuid.New().String()), key, nil - -} diff --git a/web/apps/agent/services/vault/keys/master_key.go b/web/apps/agent/services/vault/keys/master_key.go deleted file mode 100644 index 554a00c882..0000000000 --- a/web/apps/agent/services/vault/keys/master_key.go +++ /dev/null @@ -1,31 +0,0 @@ -package keys - -import ( - "encoding/base64" - "fmt" - "time" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "google.golang.org/protobuf/proto" -) - -func GenerateMasterKey() (*vaultv1.KeyEncryptionKey, string, error) { - id, key, err := GenerateKey("kek") - if err != nil { - return nil, "", fmt.Errorf("failed to generate key: %w", err) - } - - kek := &vaultv1.KeyEncryptionKey{ - Id: id, - CreatedAt: time.Now().UnixMilli(), - Key: key, - } - - b, err := proto.Marshal(kek) - - if err != nil { - return nil, "", fmt.Errorf("failed to marshal key: %w", err) - } - - return kek, base64.StdEncoding.EncodeToString(b), nil -} diff --git a/web/apps/agent/services/vault/reencrypt.go b/web/apps/agent/services/vault/reencrypt.go deleted file mode 100644 index cb8dc49699..0000000000 --- a/web/apps/agent/services/vault/reencrypt.go +++ /dev/null @@ -1,39 +0,0 @@ -package vault - -import ( - "context" - "fmt" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" -) - -func (s *Service) ReEncrypt(ctx context.Context, req *vaultv1.ReEncryptRequest) (*vaultv1.ReEncryptResponse, error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("service.vault", "ReEncrypt")) - defer span.End() - s.logger.Info().Str("keyring", req.Keyring).Msg("reencrypting") - - decrypted, err := s.Decrypt(ctx, &vaultv1.DecryptRequest{ - Keyring: req.Keyring, - Encrypted: req.Encrypted, - }) - if err != nil { - return nil, fmt.Errorf("failed to decrypt: %w", err) - } - - // TODO: this is very inefficient, as it clears the entire cache for every key re-encryption - s.keyCache.Clear(ctx) - - encrypted, err := s.Encrypt(ctx, &vaultv1.EncryptRequest{ - Keyring: req.Keyring, - Data: decrypted.Plaintext, - }) - if err != nil { - return nil, fmt.Errorf("failed to encrypt: %w", err) - } - return &vaultv1.ReEncryptResponse{ - Encrypted: encrypted.Encrypted, - KeyId: encrypted.KeyId, - }, nil - -} diff --git a/web/apps/agent/services/vault/roll_deks.go b/web/apps/agent/services/vault/roll_deks.go deleted file mode 100644 index c3c187f750..0000000000 --- a/web/apps/agent/services/vault/roll_deks.go +++ /dev/null @@ -1,46 +0,0 @@ -package vault - -import ( - "context" - "fmt" - - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "github.com/unkeyed/unkey/svc/agent/services/vault/storage" -) - -func (s *Service) RollDeks(ctx context.Context) error { - ctx, span := tracing.Start(ctx, tracing.NewSpanName("service.vault", "RollDeks")) - defer span.End() - lookupKeys, err := s.storage.ListObjectKeys(ctx, "keyring/") - if err != nil { - return fmt.Errorf("failed to list keys: %w", err) - } - - for _, objectKey := range lookupKeys { - b, found, err := s.storage.GetObject(ctx, objectKey) - if err != nil { - return fmt.Errorf("failed to get object: %w", err) - } - if !found { - return storage.ErrObjectNotFound - } - dek, kekID, err := s.keyring.DecodeAndDecryptKey(ctx, b) - if err != nil { - return fmt.Errorf("failed to decode and decrypt key: %w", err) - } - if kekID == s.encryptionKey.Id { - s.logger.Info().Str("keyId", dek.Id).Msg("key already encrypted with latest kek") - continue - } - reencrypted, err := s.keyring.EncryptAndEncodeKey(ctx, dek) - if err != nil { - return fmt.Errorf("failed to re-encrypt key: %w", err) - } - err = s.storage.PutObject(ctx, objectKey, reencrypted) - if err != nil { - return fmt.Errorf("failed to put re-encrypted key: %w", err) - } - } - - return nil -} diff --git a/web/apps/agent/services/vault/service.go b/web/apps/agent/services/vault/service.go deleted file mode 100644 index 3de48629d6..0000000000 --- a/web/apps/agent/services/vault/service.go +++ /dev/null @@ -1,101 +0,0 @@ -package vault - -import ( - "encoding/base64" - "fmt" - "time" - - vaultv1 "github.com/unkeyed/unkey/svc/agent/gen/proto/vault/v1" - "github.com/unkeyed/unkey/svc/agent/pkg/cache" - cacheMiddleware "github.com/unkeyed/unkey/svc/agent/pkg/cache/middleware" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" - "github.com/unkeyed/unkey/svc/agent/pkg/metrics" - "github.com/unkeyed/unkey/svc/agent/services/vault/keyring" - "github.com/unkeyed/unkey/svc/agent/services/vault/storage" - "google.golang.org/protobuf/proto" -) - -const LATEST = "LATEST" - -type Service struct { - logger logging.Logger - keyCache cache.Cache[*vaultv1.DataEncryptionKey] - - storage storage.Storage - - decryptionKeys map[string]*vaultv1.KeyEncryptionKey - encryptionKey *vaultv1.KeyEncryptionKey - - keyring *keyring.Keyring -} - -type Config struct { - Logger logging.Logger - Storage storage.Storage - Metrics metrics.Metrics - MasterKeys []string -} - -func New(cfg Config) (*Service, error) { - encryptionKey, decryptionKeys, err := loadMasterKeys(cfg.MasterKeys) - if err != nil { - return nil, fmt.Errorf("unable to load master keys: %w", err) - - } - - keyring, err := keyring.New(keyring.Config{ - Store: cfg.Storage, - Logger: cfg.Logger, - DecryptionKeys: decryptionKeys, - EncryptionKey: encryptionKey, - }) - if err != nil { - return nil, fmt.Errorf("failed to create keyring: %w", err) - } - - cache, err := cache.New[*vaultv1.DataEncryptionKey](cache.Config[*vaultv1.DataEncryptionKey]{ - Fresh: time.Hour, - Stale: 24 * time.Hour, - MaxSize: 10000, - Logger: cfg.Logger, - Metrics: cfg.Metrics, - Resource: "data_encryption_key", - }) - - return &Service{ - logger: cfg.Logger, - storage: cfg.Storage, - keyCache: cacheMiddleware.WithTracing(cache), - decryptionKeys: decryptionKeys, - - encryptionKey: encryptionKey, - keyring: keyring, - }, nil -} - -func loadMasterKeys(masterKeys []string) (*vaultv1.KeyEncryptionKey, map[string]*vaultv1.KeyEncryptionKey, error) { - if len(masterKeys) == 0 { - return nil, nil, fmt.Errorf("no master keys provided") - } - encryptionKey := &vaultv1.KeyEncryptionKey{} - decryptionKeys := make(map[string]*vaultv1.KeyEncryptionKey) - - for _, mk := range masterKeys { - kek := &vaultv1.KeyEncryptionKey{} - b, err := base64.StdEncoding.DecodeString(mk) - if err != nil { - return nil, nil, fmt.Errorf("failed to decode master key: %w", err) - } - - err = proto.Unmarshal(b, kek) - if err != nil { - return nil, nil, fmt.Errorf("failed to unmarshal master key: %w", err) - } - - decryptionKeys[kek.Id] = kek - // this way, the last key in the list is used for encryption - encryptionKey = kek - - } - return encryptionKey, decryptionKeys, nil -} diff --git a/web/apps/agent/services/vault/storage/interface.go b/web/apps/agent/services/vault/storage/interface.go deleted file mode 100644 index 68b21777bc..0000000000 --- a/web/apps/agent/services/vault/storage/interface.go +++ /dev/null @@ -1,32 +0,0 @@ -package storage - -import ( - "context" - "errors" - "time" -) - -var ( - ErrObjectNotFound = errors.New("object not found") -) - -type GetObjectOptions struct { - IfUnModifiedSince time.Time -} - -type Storage interface { - // PutObject stores the object data for the given key - PutObject(ctx context.Context, key string, object []byte) error - - // GetObject returns the object data for the given key - GetObject(ctx context.Context, key string) ([]byte, bool, error) - - // ListObjects returns a list of object keys that match the given prefix - ListObjectKeys(ctx context.Context, prefix string) ([]string, error) - - // Key returns the object key for the given shard and version - Key(shard string, dekID string) string - - // Latest returns the object key for the latest version of the given workspace - Latest(shard string) string -} diff --git a/web/apps/agent/services/vault/storage/memory.go b/web/apps/agent/services/vault/storage/memory.go deleted file mode 100644 index e1e3f70f1c..0000000000 --- a/web/apps/agent/services/vault/storage/memory.go +++ /dev/null @@ -1,74 +0,0 @@ -package storage - -import ( - "context" - "fmt" - "strings" - "sync" - - "github.com/unkeyed/unkey/svc/agent/pkg/logging" -) - -// memory is an in-memory storage implementation for testing purposes. -type memory struct { - config MemoryConfig - sync.RWMutex - data map[string][]byte - logger logging.Logger -} - -type MemoryConfig struct { - Logger logging.Logger -} - -func NewMemory(config MemoryConfig) (Storage, error) { - - logger := config.Logger.With().Str("service", "storage").Logger() - - return &memory{config: config, logger: logger, data: make(map[string][]byte)}, nil -} - -func (s *memory) Key(workspaceId string, dekID string) string { - return fmt.Sprintf("%s/%s", workspaceId, dekID) -} - -func (s *memory) Latest(workspaceId string) string { - return s.Key(workspaceId, "LATEST") -} - -func (s *memory) PutObject(ctx context.Context, key string, b []byte) error { - - s.Lock() - defer s.Unlock() - - s.data[key] = b - return nil -} - -func (s *memory) GetObject(ctx context.Context, key string) ([]byte, bool, error) { - s.RLock() - defer s.RUnlock() - - b, ok := s.data[key] - if !ok { - return nil, false, nil - } - - return b, true, nil - -} -func (s *memory) ListObjectKeys(ctx context.Context, prefix string) ([]string, error) { - s.RLock() - defer s.RUnlock() - keys := []string{} - for key := range s.data { - if prefix == "" || !strings.HasPrefix(key, prefix) { - continue - } - - keys = append(keys, key) - - } - return keys, nil - -} diff --git a/web/apps/agent/services/vault/storage/middleware/tracing.go b/web/apps/agent/services/vault/storage/middleware/tracing.go deleted file mode 100644 index 31b6bfb091..0000000000 --- a/web/apps/agent/services/vault/storage/middleware/tracing.go +++ /dev/null @@ -1,64 +0,0 @@ -package middleware - -import ( - "context" - "fmt" - - "github.com/unkeyed/unkey/svc/agent/pkg/tracing" - "github.com/unkeyed/unkey/svc/agent/services/vault/storage" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/codes" -) - -type tracingMiddleware struct { - name string - next storage.Storage -} - -func WithTracing(name string, next storage.Storage) storage.Storage { - return &tracingMiddleware{ - name: name, - next: next, - } -} - -func (tm *tracingMiddleware) PutObject(ctx context.Context, key string, object []byte) error { - ctx, span := tracing.Start(ctx, tracing.NewSpanName(fmt.Sprintf("storage.%s", tm.name), "PutObject")) - defer span.End() - span.SetAttributes(attribute.String("key", key)) - err := tm.next.PutObject(ctx, key, object) - if err != nil { - span.SetStatus(codes.Error, err.Error()) - } - return err - -} -func (tm *tracingMiddleware) GetObject(ctx context.Context, key string) ([]byte, bool, error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName(fmt.Sprintf("storage.%s", tm.name), "GetObject")) - defer span.End() - span.SetAttributes(attribute.String("key", key)) - object, found, err := tm.next.GetObject(ctx, key) - span.SetAttributes(attribute.Bool("found", found)) - if err != nil { - span.SetStatus(codes.Error, err.Error()) - } - return object, found, err - -} -func (tm *tracingMiddleware) ListObjectKeys(ctx context.Context, prefix string) ([]string, error) { - ctx, span := tracing.Start(ctx, tracing.NewSpanName(fmt.Sprintf("storage.%s", tm.name), "ListObjectKeys")) - defer span.End() - span.SetAttributes(attribute.String("prefix", prefix)) - keys, err := tm.next.ListObjectKeys(ctx, prefix) - if err != nil { - span.SetStatus(codes.Error, err.Error()) - } - return keys, err - -} -func (tm *tracingMiddleware) Key(shard string, dekID string) string { - return tm.next.Key(shard, dekID) -} -func (tm *tracingMiddleware) Latest(shard string) string { - return tm.next.Latest(shard) -} diff --git a/web/apps/agent/services/vault/storage/s3.go b/web/apps/agent/services/vault/storage/s3.go deleted file mode 100644 index 2a323c6770..0000000000 --- a/web/apps/agent/services/vault/storage/s3.go +++ /dev/null @@ -1,136 +0,0 @@ -package storage - -import ( - "bytes" - "context" - "fmt" - "io" - "strings" - - "github.com/aws/aws-sdk-go-v2/aws" - awsConfig "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/credentials" - awsS3 "github.com/aws/aws-sdk-go-v2/service/s3" - - "github.com/Southclaws/fault" - "github.com/Southclaws/fault/fmsg" - "github.com/unkeyed/unkey/svc/agent/pkg/logging" -) - -type s3 struct { - client *awsS3.Client - config S3Config - logger logging.Logger -} - -type S3Config struct { - S3URL string - S3Bucket string - S3AccessKeyId string - S3AccessKeySecret string - Logger logging.Logger -} - -func NewS3(config S3Config) (Storage, error) { - - logger := config.Logger.With().Str("service", "storage").Logger() - - logger.Info().Msg("using s3 storage") - - r2Resolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...any) (aws.Endpoint, error) { - return aws.Endpoint{ - URL: config.S3URL, - HostnameImmutable: true, - }, nil - - }) - - cfg, err := awsConfig.LoadDefaultConfig(context.Background(), - awsConfig.WithEndpointResolverWithOptions(r2Resolver), - awsConfig.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(config.S3AccessKeyId, config.S3AccessKeySecret, "")), - awsConfig.WithRegion("auto"), - awsConfig.WithRetryMode(aws.RetryModeStandard), - awsConfig.WithRetryMaxAttempts(3), - ) - - if err != nil { - return nil, fault.Wrap(err, fmsg.With("failed to load aws config")) - } - - client := awsS3.NewFromConfig(cfg) - logger.Info().Msg("creating bucket if necessary") - logger.Info().Msgf("url: %s", config.S3URL) - _, err = client.CreateBucket(context.Background(), &awsS3.CreateBucketInput{ - Bucket: aws.String(config.S3Bucket), - }) - if err != nil && !strings.Contains(err.Error(), "BucketAlreadyOwnedByYou") { - return nil, fault.Wrap(err, fmsg.With("failed to create bucket")) - } - - logger.Info().Msg("s3 storage initialized") - - return &s3{config: config, client: client, logger: logger}, nil -} - -func (s *s3) Key(workspaceId string, dekID string) string { - return fmt.Sprintf("%s/%s", workspaceId, dekID) -} - -func (s *s3) Latest(workspaceId string) string { - return s.Key(workspaceId, "LATEST") -} - -func (s *s3) PutObject(ctx context.Context, key string, data []byte) error { - - _, err := s.client.PutObject(ctx, &awsS3.PutObjectInput{ - Bucket: aws.String(s.config.S3Bucket), - Key: aws.String(key), - Body: bytes.NewReader(data), - }) - if err != nil { - return fmt.Errorf("failed to put object: %w", err) - } - return nil -} - -func (s *s3) GetObject(ctx context.Context, key string) ([]byte, bool, error) { - - o, err := s.client.GetObject(ctx, &awsS3.GetObjectInput{ - Bucket: aws.String(s.config.S3Bucket), - Key: aws.String(key), - }) - if err != nil { - - if strings.Contains(err.Error(), "StatusCode: 404") { - return nil, false, nil - } - return nil, false, fmt.Errorf("failed to get object: %w", err) - } - defer o.Body.Close() - b, err := io.ReadAll(o.Body) - if err != nil { - return nil, false, fmt.Errorf("failed to read object: %w", err) - } - return b, true, nil -} - -func (s *s3) ListObjectKeys(ctx context.Context, prefix string) ([]string, error) { - - input := &awsS3.ListObjectsV2Input{ - Bucket: aws.String(s.config.S3Bucket), - } - if prefix != "" { - input.Prefix = aws.String(prefix) - } - - o, err := s.client.ListObjectsV2(ctx, input) - - if err != nil { - return nil, fault.Wrap(err, fmsg.With("failed to list objects")) - } - keys := make([]string, len(o.Contents)) - for i, obj := range o.Contents { - keys[i] = *obj.Key - } - return keys, nil -}