From 916f4c6014be04ddc6a8cd36df59de0faf3403e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 21:51:27 +0000 Subject: [PATCH 01/71] chore(deps): bump google.golang.org/grpc from 1.64.0 to 1.64.1 in /caddy Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.64.0 to 1.64.1. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.64.0...v1.64.1) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: indirect ... Signed-off-by: dependabot[bot] --- caddy/go.mod | 8 ++++---- caddy/go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index 0a15466d..322067f6 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -165,20 +165,20 @@ require ( go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap/exp v0.2.0 // indirect - golang.org/x/crypto v0.23.0 // indirect + golang.org/x/crypto v0.24.0 // indirect golang.org/x/crypto/x509roots/fallback v0.0.0-20240603234054-0b431c7de36a // indirect golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect golang.org/x/mod v0.18.0 // indirect - golang.org/x/net v0.25.0 // indirect + golang.org/x/net v0.26.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.20.0 // indirect + golang.org/x/term v0.21.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect - google.golang.org/grpc v1.64.0 // indirect + google.golang.org/grpc v1.64.1 // indirect google.golang.org/protobuf v1.34.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect diff --git a/caddy/go.sum b/caddy/go.sum index c35d5823..cc627714 100644 --- a/caddy/go.sum +++ b/caddy/go.sum @@ -581,8 +581,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/crypto/x509roots/fallback v0.0.0-20240603234054-0b431c7de36a h1:1mZr4dBUGHEdypxOCNajMoDtL+fYBEI1stTJ6JeK2YU= golang.org/x/crypto/x509roots/fallback v0.0.0-20240603234054-0b431c7de36a/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg= @@ -604,8 +604,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -648,8 +648,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.3.0/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= @@ -690,8 +690,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1: google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= +google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 37f91f236e4cbf985896dc762c6af4e12cefe3f5 Mon Sep 17 00:00:00 2001 From: Julian Date: Wed, 10 Jul 2024 01:08:18 +0200 Subject: [PATCH 02/71] feat(helm): allow passing existing secret in helm chart values (#809) --- charts/mercure/templates/_helpers.tpl | 11 +++++++++++ charts/mercure/templates/deployment.yaml | 12 ++++++------ charts/mercure/templates/secrets.yaml | 2 ++ charts/mercure/values.yaml | 10 ++++++++++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/charts/mercure/templates/_helpers.tpl b/charts/mercure/templates/_helpers.tpl index 2548986d..2c0b365f 100644 --- a/charts/mercure/templates/_helpers.tpl +++ b/charts/mercure/templates/_helpers.tpl @@ -60,3 +60,14 @@ Create the name of the service account to use {{- default "default" .Values.serviceAccount.name }} {{- end }} {{- end }} + +{{/* +Get the secret name. +*/}} +{{- define "mercure.secretName" -}} +{{- if .Values.existingSecret -}} +{{- printf "%s" (tpl .Values.existingSecret $) -}} +{{- else -}} +{{- printf "%s" (include "mercure.fullname" .) -}} +{{- end -}} +{{- end -}} diff --git a/charts/mercure/templates/deployment.yaml b/charts/mercure/templates/deployment.yaml index 9fb9bada..8dc59e25 100644 --- a/charts/mercure/templates/deployment.yaml +++ b/charts/mercure/templates/deployment.yaml @@ -55,17 +55,17 @@ spec: - name: CADDY_SERVER_EXTRA_DIRECTIVES valueFrom: secretKeyRef: - name: {{ include "mercure.fullname" . }} + name: {{ include "mercure.secretName" . }} key: caddy-extra-directives - name: MERCURE_TRANSPORT_URL valueFrom: secretKeyRef: - name: {{ include "mercure.fullname" . }} + name: {{ include "mercure.secretName" . }} key: transport-url - name: MERCURE_PUBLISHER_JWT_KEY valueFrom: secretKeyRef: - name: {{ include "mercure.fullname" . }} + name: {{ include "mercure.secretName" . }} key: publisher-jwt-key - name: MERCURE_PUBLISHER_JWT_ALG valueFrom: @@ -75,7 +75,7 @@ spec: - name: MERCURE_SUBSCRIBER_JWT_KEY valueFrom: secretKeyRef: - name: {{ include "mercure.fullname" . }} + name: {{ include "mercure.secretName" . }} key: subscriber-jwt-key - name: MERCURE_SUBSCRIBER_JWT_ALG valueFrom: @@ -85,12 +85,12 @@ spec: - name: MERCURE_EXTRA_DIRECTIVES valueFrom: secretKeyRef: - name: {{ include "mercure.fullname" . }} + name: {{ include "mercure.secretName" . }} key: extra-directives - name: MERCURE_LICENSE valueFrom: secretKeyRef: - name: {{ include "mercure.fullname" . }} + name: {{ include "mercure.secretName" . }} key: license {{- if .Values.persistence.enabled }} volumeMounts: diff --git a/charts/mercure/templates/secrets.yaml b/charts/mercure/templates/secrets.yaml index a2b5f551..de703c2c 100644 --- a/charts/mercure/templates/secrets.yaml +++ b/charts/mercure/templates/secrets.yaml @@ -1,3 +1,4 @@ +{{- if not .Values.existingSecret }} apiVersion: v1 kind: Secret metadata: @@ -13,3 +14,4 @@ data: license: {{ .Values.license | b64enc | quote }} caddy-extra-config: {{ .Values.caddyExtraConfig | b64enc | quote }} caddy-extra-directives: {{ .Values.caddyExtraDirectives | b64enc | quote }} +{{- end}} diff --git a/charts/mercure/values.yaml b/charts/mercure/values.yaml index ee7e3550..d01b5755 100644 --- a/charts/mercure/values.yaml +++ b/charts/mercure/values.yaml @@ -25,6 +25,16 @@ subscriberJwtKey: "" # -- The JWT algorithm to use for subscribers. subscriberJwtAlg: HS256 +# -- Allows to pass an existing secret name, the above values will be used if empty. +existingSecret: "" +# These keys must exist in the provided secret: +# - transport-url +# - publisher-jwt-key +# - subscriber-jwt-key +# - extra-directives: +# - license: +# - caddy-extra-directives: + # -- The license key for [the High Availability version](https://mercure.rocks/docs/hub/cluster) (not necessary is you use the FOSS version). license: "" From a29710b9ce723c0aae1897037cccd27b1a2e05a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 14 Aug 2024 16:57:32 +0200 Subject: [PATCH 03/71] fix: use log_skip instead of the deprecated skip_log directive --- Caddyfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Caddyfile b/Caddyfile index 580dc189..6507ca76 100644 --- a/Caddyfile +++ b/Caddyfile @@ -31,9 +31,9 @@ {$CADDY_SERVER_EXTRA_DIRECTIVES} - skip_log /robots.txt - skip_log /healthz - skip_log /favicon.ico + log_skip /robots.txt + log_skip /healthz + log_skip /favicon.ico header / Content-Type "text/html; charset=utf-8" respond / ` From d8b640d1f436edad4def0796c625b357ee335c1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 14 Aug 2024 17:08:58 +0200 Subject: [PATCH 04/71] ci: upgrade to super-linter 6 (#930) * ci: upgrade to super-linter 6 * chore: various style fixes * docs: Symfony Mercure * fix --- .github/workflows/lint.yml | 17 +++++++++++++---- CONTRIBUTING.md | 4 ++-- docs/ecosystem/help.md | 2 +- docs/getting-started.md | 2 +- examples/publish/php.php | 2 ++ release.sh | 22 +++++++++++----------- tests/use-go-deadlock.sh | 8 ++++---- 7 files changed, 34 insertions(+), 23 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 36318d92..a3cb8f5d 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -10,6 +10,11 @@ on: tags: - v*.*.* +permissions: + contents: read + packages: read + statuses: write + jobs: lint: runs-on: ubuntu-latest @@ -18,14 +23,18 @@ jobs: with: fetch-depth: 0 - name: Lint Code Base - uses: super-linter/super-linter/slim@v5 + uses: super-linter/super-linter/slim@v6 env: + DEFAULT_BRANCH: main + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} VALIDATE_ALL_CODEBASE: true + VALIDATE_CHECKOV: false VALIDATE_GITLEAKS: false VALIDATE_GO: false + VALIDATE_GO_MODULES: false VALIDATE_PHP_PHPCS: false VALIDATE_KUBERNETES_KUBECONFORM: false - VALIDATE_KUBERNETES_KUBEVAL: false + VALIDATE_JAVASCRIPT_PRETTIER: false + VALIDATE_TYPESCRIPT_PRETTIER: false VALIDATE_TYPESCRIPT_STANDARD: false - DEFAULT_BRANCH: main - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VALIDATE_PYTHON_PYLINT: false diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d8065cbc..7ff08cde 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -69,8 +69,8 @@ When you send a PR, make sure that: ### Configuring Visual Studio Code -A configuration for VSCode is provided in the `.vscode/` directory of the repository. -It is automatically loaded by VS Code. +A configuration for Visual Studio Code is provided in the `.vscode/` directory of the repository. +It is automatically loaded by Visual Studio Code. ### Finding Deadlocks diff --git a/docs/ecosystem/help.md b/docs/ecosystem/help.md index 5a20bee3..0f92aced 100644 --- a/docs/ecosystem/help.md +++ b/docs/ecosystem/help.md @@ -6,7 +6,7 @@ For support requests related to the [Cloud](../hub/cloud.md) or the [On Premise] ## Community Support -* [StackOverflow: ask questions using the `mercure` tag](https://stackoverflow.com/questions/tagged/mercure) +* [Stack Overflow: ask questions using the `mercure` tag](https://stackoverflow.com/questions/tagged/mercure) * [Slack: chat with the community on the `#mercure` channel on Symfony's Slack](https://symfony.com/slack) ## Commercial Support diff --git a/docs/getting-started.md b/docs/getting-started.md index 2a40eb0a..d1844da9 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -33,7 +33,7 @@ The `EventSource` class is available [in all modern web browsers](https://canius It is important to close this connection between the client and the hub if it is no longer needed. Opened connections have a continuous buffer that will drain your application resources. -This is especially true when using Single Page Applications (based on e.g. ReactJS): the connection is maintained even if the component that created it is unmounted. +This is especially true when using Single Page Applications (based on e.g. React): the connection is maintained even if the component that created it is unmounted. To close the connection, call `eventSource.close()`. diff --git a/examples/publish/php.php b/examples/publish/php.php index 36571fcd..4737e321 100644 --- a/examples/publish/php.php +++ b/examples/publish/php.php @@ -1,5 +1,7 @@ /dev/null; then - echo "The \"git\" command must be installed." - exit 1 +if ! type "git" >/dev/null; then + echo "The \"git\" command must be installed." + exit 1 fi -if ! type "helm-docs" > /dev/null; then - echo "The \"helm-docs\" command (https://github.com/norwoodj/helm-docs) must be installed." - exit 1 +if ! type "helm-docs" >/dev/null; then + echo "The \"helm-docs\" command (https://github.com/norwoodj/helm-docs) must be installed." + exit 1 fi -if [ $# -ne 1 ]; then - echo "Usage: ./release.sh version" >&2 - exit 1 +if [[ $# -ne 1 ]]; then + echo "Usage: ./release.sh version" >&2 + exit 1 fi # Adapted from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string if [[ ! $1 =~ ^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*))?(\+([0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*))?$ ]]; then - echo "Invalid version number: $1" >&2 - exit 1 + echo "Invalid version number: $1" >&2 + exit 1 fi git checkout main diff --git a/tests/use-go-deadlock.sh b/tests/use-go-deadlock.sh index 0e689058..ae1d2a69 100755 --- a/tests/use-go-deadlock.sh +++ b/tests/use-go-deadlock.sh @@ -2,10 +2,10 @@ # Install github.com/sasha-s/go-deadlock and use it to test mutexes SEP="\n\t" -args=( "-i" ) -if [[ "$(uname)" = "Darwin" ]]; then - SEP=$'\\\n\\\t' - args=( "-i" "" ) +args=("-i") +if [[ "$(uname || true)" = "Darwin" ]]; then + SEP=$'\\\n\\\t' + args=("-i" "") fi go install golang.org/x/tools/cmd/goimports@latest From 07a4733e1dde5356c7ca3f026d710d8df7ad8723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 14 Aug 2024 17:13:07 +0200 Subject: [PATCH 05/71] ci: generate SLSA attestations for binaries (#928) * ci: generate SLSA attestations for binaries * add missing permissions * fix linter --- .github/workflows/cd.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index a939c74c..18e0bcc6 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -14,6 +14,8 @@ on: permissions: contents: write + id-token: write + attestations: write jobs: release: @@ -62,6 +64,12 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GPG_FINGERPRINT: ${{ startsWith(github.ref, 'refs/tags/v') && steps.import_gpg.outputs.fingerprint || '' }} + - name: Attest + if: startsWith(github.ref, 'refs/tags/v') + uses: actions/attest-build-provenance@v1 + with: + subject-path: '${{ github.workspace }}/dist/**/mercure' + - name: Display version run: dist/caddy_linux_amd64_v1/mercure version From bb859e1f5606b5167725299094c8599a207bdb12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 14 Aug 2024 20:09:11 +0200 Subject: [PATCH 06/71] feat: compile with Go 1.23 (#933) * feat: compile with Go 1.23 * tests: improve TestClientClosesThenReconnects * ci: upgrade golangci config --- .github/workflows/cd.yml | 2 +- .github/workflows/ci.yml | 6 +- .golangci.yml | 11 +- caddy/go.mod | 95 +++++---- caddy/go.sum | 422 ++++++++++++++------------------------- go.mod | 26 +-- go.sum | 58 +++--- hub_test.go | 3 +- server_test.go | 24 +-- 9 files changed, 255 insertions(+), 392 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 18e0bcc6..f92fad51 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -29,7 +29,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: '1.23' cache-dependency-path: | go.sum caddy/go.sum diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 680f7d75..33d350d9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: '1.23' cache-dependency-path: | go.sum caddy/go.sum @@ -37,7 +37,7 @@ jobs: test: strategy: matrix: - go: [ '1.21', '1.22' ] + go: [ '1.21', '1.22', '1.23' ] fail-fast: false name: Test runs-on: ubuntu-latest @@ -57,6 +57,8 @@ jobs: caddy/go.sum - name: Use go-deadlock + # Blocked by https://github.com/sasha-s/go-deadlock/issues/34 + if: matrix.go != '1.23' run: ./tests/use-go-deadlock.sh - name: Test diff --git a/.golangci.yml b/.golangci.yml index b0603ecc..613b66d0 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -28,16 +28,7 @@ linters: - canonicalheader # deprecated - - interfacer - - maligned - - scopelint - - golint - - exhaustivestruct - - varcheck - - ifshort - - deadcode - - nosnakecase - - structcheck + - execinquery issues: exclude-rules: diff --git a/caddy/go.mod b/caddy/go.mod index 322067f6..e4183aca 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -13,7 +13,7 @@ require ( github.com/MicahParks/keyfunc/v3 v3.3.3 github.com/caddyserver/caddy/v2 v2.8.4 github.com/dunglas/mercure v0.16.2 - github.com/prometheus/client_golang v1.19.1 + github.com/prometheus/client_golang v1.20.0 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 ) @@ -52,98 +52,95 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/fxamacker/cbor/v2 v2.6.0 // indirect - github.com/go-chi/chi/v5 v5.0.12 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-chi/chi/v5 v5.1.0 // indirect github.com/go-jose/go-jose/v3 v3.0.3 // indirect github.com/go-kit/kit v0.13.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gofrs/uuid v4.4.0+incompatible // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect - github.com/golang/glog v1.2.1 // indirect + github.com/golang/glog v1.2.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/cel-go v0.20.1 // indirect + github.com/google/cel-go v0.21.0 // indirect github.com/google/certificate-transparency-go v1.1.8-0.20240110162603-74a5dd331745 // indirect github.com/google/go-tpm v0.9.0 // indirect github.com/google/go-tspi v0.3.0 // indirect - github.com/google/pprof v0.0.0-20240528025155-186aa0362fba // indirect + github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/huandu/xstrings v1.4.0 // indirect + github.com/huandu/xstrings v1.5.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jackc/chunkreader/v2 v2.0.1 // indirect - github.com/jackc/pgconn v1.14.3 // indirect - github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgproto3/v2 v2.3.3 // indirect - github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect - github.com/jackc/pgtype v1.14.3 // indirect - github.com/jackc/pgx/v4 v4.18.3 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/jackc/pgx/v5 v5.6.0 // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/kevburnsjr/skipfilter v0.0.1 // indirect - github.com/klauspost/compress v1.17.8 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/libdns/libdns v0.2.2 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect - github.com/mholt/acmez/v2 v2.0.1 // indirect - github.com/miekg/dns v1.1.59 // indirect + github.com/mholt/acmez/v2 v2.0.2 // indirect + github.com/miekg/dns v1.1.62 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mschoch/smat v0.2.0 // indirect - github.com/onsi/ginkgo/v2 v2.19.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/onsi/ginkgo/v2 v2.20.0 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pires/go-proxyproto v0.7.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.54.0 // indirect + github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.44.0 // indirect + github.com/quic-go/quic-go v0.46.0 // indirect github.com/rs/xid v1.5.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sagikazarmark/locafero v0.5.0 // indirect + github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/slackhq/nebula v1.9.2 // indirect - github.com/smallstep/certificates v0.26.1 // indirect - github.com/smallstep/nosql v0.6.1 // indirect - github.com/smallstep/pkcs7 v0.0.0-20240411202544-a82ada2bab6b // indirect + github.com/slackhq/nebula v1.9.3 // indirect + github.com/smallstep/certificates v0.27.2 // indirect + github.com/smallstep/nosql v0.7.0 // indirect + github.com/smallstep/pkcs7 v0.0.0-20240723090913-5e2c6a136dfa // indirect github.com/smallstep/scep v0.0.0-20240214080410-892e41795b99 // indirect github.com/smallstep/truststore v0.13.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/cast v1.7.0 // indirect + github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.19.0 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/tailscale/tscert v0.0.0-20240517230440-bbccfbf48933 // indirect - github.com/unrolled/secure v1.14.0 // indirect + github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53 // indirect + github.com/unrolled/secure v1.15.0 // indirect github.com/urfave/cli v1.22.15 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect github.com/yuin/goldmark v1.7.1 // indirect github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc // indirect - github.com/zeebo/blake3 v0.2.3 // indirect + github.com/zeebo/blake3 v0.2.4 // indirect go.etcd.io/bbolt v1.3.10 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/contrib/propagators/autoprop v0.42.0 // indirect @@ -159,27 +156,27 @@ require ( go.opentelemetry.io/otel/trace v1.24.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.step.sm/cli-utils v0.9.0 // indirect - go.step.sm/crypto v0.46.0 // indirect - go.step.sm/linkedca v0.20.1 // indirect + go.step.sm/crypto v0.51.1 // indirect + go.step.sm/linkedca v0.22.1 // indirect go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap/exp v0.2.0 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/crypto/x509roots/fallback v0.0.0-20240603234054-0b431c7de36a // indirect - golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect - golang.org/x/mod v0.18.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect - google.golang.org/grpc v1.64.1 // indirect - google.golang.org/protobuf v1.34.1 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/crypto/x509roots/fallback v0.0.0-20240806160748-b2d3a6a4b4d3 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/time v0.6.0 // indirect + golang.org/x/tools v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 // indirect + google.golang.org/grpc v1.65.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/caddy/go.sum b/caddy/go.sum index cc627714..347e0955 100644 --- a/caddy/go.sum +++ b/caddy/go.sum @@ -1,18 +1,18 @@ -cloud.google.com/go v0.113.0 h1:g3C70mn3lWfckKBiCVsAshabrDg01pQ0pnX1MNtnMkA= -cloud.google.com/go v0.113.0/go.mod h1:glEqlogERKYeePz6ZdkcLJ28Q2I6aERgDDErBg9GzO8= -cloud.google.com/go/auth v0.4.1 h1:Z7YNIhlWRtrnKlZke7z3GMqzvuYzdc2z98F9D1NV5Hg= -cloud.google.com/go/auth v0.4.1/go.mod h1:QVBuVEKpCn4Zp58hzRGvL0tjRGU0YqdRTdCHM1IHnro= -cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= -cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= -cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= -cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0= -cloud.google.com/go/iam v1.1.8/go.mod h1:GvE6lyMmfxXauzNq8NbgJbeVQNspG+tcdL/W8QO1+zE= -cloud.google.com/go/kms v1.17.1 h1:5k0wXqkxL+YcXd4viQzTqCgzzVKKxzgrK+rCZJytEQs= -cloud.google.com/go/kms v1.17.1/go.mod h1:DCMnCF/apA6fZk5Cj4XsD979OyHAqFasPuA5Sd0kGlQ= -cloud.google.com/go/longrunning v0.5.7 h1:WLbHekDbjK1fVFD3ibpFFVoyizlLRl73I7YKuAKilhU= -cloud.google.com/go/longrunning v0.5.7/go.mod h1:8GClkudohy1Fxm3owmBGid8W0pSgodEMwEAztp38Xng= +cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= +cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= +cloud.google.com/go/auth v0.7.2 h1:uiha352VrCDMXg+yoBtaD0tUF4Kv9vrtrWPYXwutnDE= +cloud.google.com/go/auth v0.7.2/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= +cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= +cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= +cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= +cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= +cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= +cloud.google.com/go/iam v1.1.10 h1:ZSAr64oEhQSClwBL670MsJAW5/RLiC6kfw3Bqmd5ZDI= +cloud.google.com/go/iam v1.1.10/go.mod h1:iEgMq62sg8zx446GCaijmA2Miwg5o3UbO+nI47WHJps= +cloud.google.com/go/kms v1.18.3 h1:8+Z2S4bQDSCdghB5ZA5dVDDJTLmnkRlowtFiXqMFd74= +cloud.google.com/go/kms v1.18.3/go.mod h1:y/Lcf6fyhbdn7MrG1VaDqXxM8rhOBc5rWcWAhcvZjQU= +cloud.google.com/go/longrunning v0.5.9 h1:haH9pAuXdPAMqHvzX0zlWQigXT7B0+CL4/2nXXdBo5k= +cloud.google.com/go/longrunning v0.5.9/go.mod h1:HD+0l9/OOW0za6UWdKJtXoFAX/BGg/3Wj8p10NeWF7c= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= @@ -22,7 +22,6 @@ github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8 github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= @@ -56,34 +55,34 @@ github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmO github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b h1:uUXgbcPDK3KpW29o4iy7GtuappbWT0l5NaMo9H9pJDw= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-sdk-go-v2 v1.27.0 h1:7bZWKoXhzI+mMR/HjdMx8ZCC5+6fY0lS5tr0bbgiLlo= -github.com/aws/aws-sdk-go-v2 v1.27.0/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= -github.com/aws/aws-sdk-go-v2/config v1.27.16 h1:knpCuH7laFVGYTNd99Ns5t+8PuRjDn4HnnZK48csipM= -github.com/aws/aws-sdk-go-v2/config v1.27.16/go.mod h1:vutqgRhDUktwSge3hrC3nkuirzkJ4E/mLj5GvI0BQas= -github.com/aws/aws-sdk-go-v2/credentials v1.17.16 h1:7d2QxY83uYl0l58ceyiSpxg9bSbStqBC6BeEeHEchwo= -github.com/aws/aws-sdk-go-v2/credentials v1.17.16/go.mod h1:Ae6li/6Yc6eMzysRL2BXlPYvnrLLBg3D11/AmOjw50k= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.3 h1:dQLK4TjtnlRGb0czOht2CevZ5l6RSyRWAnKeGd7VAFE= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.3/go.mod h1:TL79f2P6+8Q7dTsILpiVST+AL9lkF6PPGI167Ny0Cjw= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7 h1:lf/8VTF2cM+N4SLzaYJERKEWAXq8MOMpZfU6wEPWsPk= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7/go.mod h1:4SjkU7QiqK2M9oozyMzfZ/23LmUY+h3oFqhdeP5OMiI= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.7 h1:4OYVp0705xu8yjdyoWix0r9wPIRXnIzzOoUpQVHIJ/g= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.7/go.mod h1:vd7ESTEvI76T2Na050gODNmNU7+OyKrIKroYTu4ABiI= +github.com/aws/aws-sdk-go-v2 v1.30.3 h1:jUeBtG0Ih+ZIFH0F4UkmL9w3cSpaMv9tYYDbzILP8dY= +github.com/aws/aws-sdk-go-v2 v1.30.3/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc= +github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90= +github.com/aws/aws-sdk-go-v2/config v1.27.27/go.mod h1:MVYamCg76dFNINkZFu4n4RjDixhVr51HLj4ErWzrVwg= +github.com/aws/aws-sdk-go-v2/credentials v1.17.27 h1:2raNba6gr2IfA0eqqiP2XiQ0UVOpGPgDSi0I9iAP+UI= +github.com/aws/aws-sdk-go-v2/credentials v1.17.27/go.mod h1:gniiwbGahQByxan6YjQUMcW4Aov6bLC3m+evgcoN4r4= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 h1:KreluoV8FZDEtI6Co2xuNk/UqI9iwMrOx/87PBNIKqw= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11/go.mod h1:SeSUYBLsMYFoRvHE0Tjvn7kbxaUhl75CJi1sbfhMxkU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 h1:SoNJ4RlFEQEbtDcCEt+QG56MY4fm4W8rYirAmq+/DdU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15/go.mod h1:U9ke74k1n2bf+RIgoX1SXFed1HLs51OgUSs+Ph0KJP8= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 h1:C6WHdGnTDIYETAm5iErQUiVNsclNx9qbJVPIt03B6bI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15/go.mod h1:ZQLZqhcu+JhSrA9/NXRm8SkDvsycE+JkV3WGY41e+IM= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.9 h1:Wx0rlZoEJR7JwlSZcHnEa7CNjrSIyVxMFWGAaXy4fJY= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.9/go.mod h1:aVMHdE0aHO3v+f/iw01fmXV/5DbfQ3Bi9nN7nd9bE9Y= -github.com/aws/aws-sdk-go-v2/service/kms v1.32.1 h1:FARrQLRQXpCFYylIUVF1dRij6YbPCmtwudq9NBk4kFc= -github.com/aws/aws-sdk-go-v2/service/kms v1.32.1/go.mod h1:8lETO9lelSG2B6KMXFh2OwPPqGV6WQM3RqLAEjP1xaU= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.9 h1:aD7AGQhvPuAxlSUfo0CWU7s6FpkbyykMhGYMvlqTjVs= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.9/go.mod h1:c1qtZUWtygI6ZdvKppzCSXsDOq5I4luJPZ0Ud3juFCA= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.3 h1:Pav5q3cA260Zqez42T9UhIlsd9QeypszRPwC9LdSSsQ= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.3/go.mod h1:9lmoVDVLz/yUZwLaQ676TK02fhCu4+PgRSmMaKR1ozk= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.10 h1:69tpbPED7jKPyzMcrwSvhWcJ9bPnZsZs18NT40JwM0g= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.10/go.mod h1:0Aqn1MnEuitqfsCNyKsdKLhDUOr4txD/g19EfiUqgws= -github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= -github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 h1:HGErhhrxZlQ044RiM+WdoZxp0p+EGM62y3L6pwA4olE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17/go.mod h1:RkZEx4l0EHYDJpWppMJ3nD9wZJAa8/0lq9aVC+r2UII= +github.com/aws/aws-sdk-go-v2/service/kms v1.35.3 h1:UPTdlTOwWUX49fVi7cymEN6hDqCwe3LNv1vi7TXUutk= +github.com/aws/aws-sdk-go-v2/service/kms v1.35.3/go.mod h1:gjDP16zn+WWalyaUqwCCioQ8gU8lzttCCc9jYsiQI/8= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 h1:BXx0ZIxvrJdSgSvKTZ+yRBeSqqgPM89VPlulEcl37tM= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.4/go.mod h1:ooyCOXjvJEsUw7x+ZDHeISPMhtwI3ZCB7ggFMcFfWLU= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 h1:yiwVzJW2ZxZTurVbYWA7QOrAaCYQR72t0wrSBfoesUE= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4/go.mod h1:0oxfLkpz3rQ/CHlx5hB7H69YUpFiI1tql6Q6Ne+1bCw= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudrvuKpDKgMVRlepGE= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.3/go.mod h1:zwySh8fpFyXp9yOr/KVzxOl8SRqgf/IDw5aUt9UKFcQ= +github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= +github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= 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/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= @@ -112,18 +111,12 @@ github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObk github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= -github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= -github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= 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= @@ -153,41 +146,37 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= -github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= -github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= +github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-kit/kit v0.4.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU= github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +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-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.6.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 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/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= -github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= +github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -198,8 +187,8 @@ github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= -github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= +github.com/google/cel-go v0.21.0 h1:cl6uW/gxN+Hy50tNYvI691+sXxioCnstFzLp2WO4GCI= +github.com/google/cel-go v0.21.0/go.mod h1:rHUlWCcBKgyEk+eV03RPdZUekPp6YcJwV0FxuUksYxc= github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/certificate-transparency-go v1.1.8-0.20240110162603-74a5dd331745 h1:heyoXNxkRT155x4jTAiSv5BVSVkueifPUm+Q8LUXMRo= github.com/google/certificate-transparency-go v1.1.8-0.20240110162603-74a5dd331745/go.mod h1:zN0wUQgV9LjwLZeFHnrAbQi8hzMVvEWePyk+MhPOk7k= @@ -212,9 +201,8 @@ github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxB github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus= github.com/google/go-tspi v0.3.0/go.mod h1:xfMGI3G0PhxCdNVcYr1C4C+EizojDg/TXuX5by8CiHI= -github.com/google/pprof v0.0.0-20240528025155-186aa0362fba h1:ql1qNgCyOB7iAEk8JTNM+zJrgIbnyCKX/wdlyPufP5g= -github.com/google/pprof v0.0.0-20240528025155-186aa0362fba/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +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/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -222,8 +210,8 @@ 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/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -github.com/googleapis/gax-go/v2 v2.12.4 h1:9gWcmF85Wvq4ryPFvGFaOgPIs1AQX0d0bcbGw4Z96qg= -github.com/googleapis/gax-go/v2 v2.12.4/go.mod h1:KYEYLorsnIGDi/rPC8b5TdlB9kbKoFubselGIoBMCwI= +github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s= +github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= @@ -238,92 +226,40 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= -github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= +github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= 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/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/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= -github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= -github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= -github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= -github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= -github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= -github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= -github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= -github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w= -github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM= -github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= -github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= -github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= -github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= -github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= -github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= -github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= -github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= -github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= -github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= -github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag= -github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA= -github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= -github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= -github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= -github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= -github.com/jackc/pgtype v1.14.3 h1:h6W9cPuHsRWQFTWUZMAKMgG5jSwQI0Zurzdvlx3Plus= -github.com/jackc/pgtype v1.14.3/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA= -github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= -github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= -github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= -github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.18.2/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= -github.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA= -github.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= -github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY= +github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/kevburnsjr/skipfilter v0.0.1 h1:EWl1lWUJfIehrKYIEkps0Cl67lCfS2pUM9iZFNajp7g= github.com/kevburnsjr/skipfilter v0.0.1/go.mod h1:jfaRyFOYVUtIa6IIC+0mB1qiZqhHw+DKvFowCBuijSk= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -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/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= 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/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= 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/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= -github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +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/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -331,22 +267,17 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= -github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 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/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/mholt/acmez/v2 v2.0.1 h1:3/3N0u1pLjMK4sNEAFSI+bcvzbPhRpY383sy1kLHJ6k= -github.com/mholt/acmez/v2 v2.0.1/go.mod h1:fX4c9r5jYwMyMsC+7tkYRxHibkOTgta5DIFGoe67e1U= -github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs= -github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk= +github.com/mholt/acmez/v2 v2.0.2 h1:OmK6xckte2JfKGPz4OAA8aNHTiLvGp8tLzmrd/wfSyw= +github.com/mholt/acmez/v2 v2.0.2/go.mod h1:fX4c9r5jYwMyMsC+7tkYRxHibkOTgta5DIFGoe67e1U= +github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= +github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -361,10 +292,12 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= -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.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= -github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= +github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= @@ -380,60 +313,52 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= +github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= 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.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= -github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= 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/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0= -github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= +github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= -github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= 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/sagikazarmark/locafero v0.5.0 h1:zXz2JnQDgE5gDg0R9ThkNT0orQzm47i8IuO6hk6XSYY= -github.com/sagikazarmark/locafero v0.5.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= +github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= +github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/jsonstore v1.1.0 h1:WZBDjgezFS34CHI+myb4s8GGpir3UMpy7vWoCeO0n6E= github.com/schollz/jsonstore v1.1.0/go.mod h1:15c6+9guw8vDRyozGjN3FoILt0wpruJk9Pi66vjaZfg= -github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -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.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/slackhq/nebula v1.9.2 h1:R+E8nR3OjYYIA8/tY4wgatY18NrfJ+KpuN31SlKU8sw= -github.com/slackhq/nebula v1.9.2/go.mod h1:PMJer5rZe0H/O+kUiKOL9AJ/pL9+ryzNXtSN7ABfjfM= +github.com/slackhq/nebula v1.9.3 h1:WK5Oipy4NsVfNm41pywGmdy048F8RRkfSRG+lPHxcJQ= +github.com/slackhq/nebula v1.9.3/go.mod h1:PMJer5rZe0H/O+kUiKOL9AJ/pL9+ryzNXtSN7ABfjfM= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262 h1:unQFBIznI+VYD1/1fApl1A+9VcBk+9dcqGfnePY87LY= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262/go.mod h1:MyOHs9Po2fbM1LHej6sBUT8ozbxmMOFG+E+rx/GSGuc= -github.com/smallstep/certificates v0.26.1 h1:FIUliEBcExSfJJDhRFA/s8aZgMIFuorexnRSKQd884o= -github.com/smallstep/certificates v0.26.1/go.mod h1:OQMrW39IrGKDViKSHrKcgSQArMZ8c7EcjhYKK7mYqis= +github.com/smallstep/certificates v0.27.2 h1:MrSJvJviS9pCUtGYYguYyB1VQzZBmkL6ngLQZfVwRqU= +github.com/smallstep/certificates v0.27.2/go.mod h1:v+u39A+fMBM3cFELPfAweaNce4RPm9AHUx9iwE0ene8= github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 h1:kjYvkvS/Wdy0PVRDUAA0gGJIVSEZYhiAJtfwYgOYoGA= github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935/go.mod h1:vNAduivU014fubg6ewygkAvQC0IQVXqdc8vaGl/0er4= -github.com/smallstep/nosql v0.6.1 h1:X8IBZFTRIp1gmuf23ne/jlD/BWKJtDQbtatxEn7Et1Y= -github.com/smallstep/nosql v0.6.1/go.mod h1:vrN+CftYYNnDM+DQqd863ATynvYFm/6FuY9D4TeAm2Y= +github.com/smallstep/nosql v0.7.0 h1:YiWC9ZAHcrLCrayfaF+QJUv16I2bZ7KdLC3RpJcnAnE= +github.com/smallstep/nosql v0.7.0/go.mod h1:H5VnKMCbeq9QA6SRY5iqPylfxLfYcLwvUff3onQ8+HU= github.com/smallstep/pkcs7 v0.0.0-20231024181729-3b98ecc1ca81/go.mod h1:SoUAr/4M46rZ3WaLstHxGhLEgoYIDRqxQEXLOmOEB0Y= -github.com/smallstep/pkcs7 v0.0.0-20240411202544-a82ada2bab6b h1:WwKnv9cYAjKHQ7IXQ/b88kfJjofMcjFjSV8ZXzpcMCk= -github.com/smallstep/pkcs7 v0.0.0-20240411202544-a82ada2bab6b/go.mod h1:SoUAr/4M46rZ3WaLstHxGhLEgoYIDRqxQEXLOmOEB0Y= +github.com/smallstep/pkcs7 v0.0.0-20240723090913-5e2c6a136dfa h1:FtxzVccOwaK+bK4bnWBPGua0FpCOhrVyeo6Fy9nxdlo= +github.com/smallstep/pkcs7 v0.0.0-20240723090913-5e2c6a136dfa/go.mod h1:SoUAr/4M46rZ3WaLstHxGhLEgoYIDRqxQEXLOmOEB0Y= github.com/smallstep/scep v0.0.0-20240214080410-892e41795b99 h1:e85HuLX5/MW15yJ7yWb/PMNFW1Kx1N+DeQtpQnlMUbw= github.com/smallstep/scep v0.0.0-20240214080410-892e41795b99/go.mod h1:4d0ub42ut1mMtvGyMensjuHYEUpRrASvkzLEJvoRQcU= github.com/smallstep/truststore v0.13.0 h1:90if9htAOblavbMeWlqNLnO9bsjjgVv2hQeQJCi/py4= @@ -448,11 +373,11 @@ 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 v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= +github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +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 v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -463,8 +388,6 @@ github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+ github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= 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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= @@ -481,11 +404,11 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/tailscale/tscert v0.0.0-20240517230440-bbccfbf48933 h1:pV0H+XIvFoP7pl1MRtyPXh5hqoxB5I7snOtTHgrn6HU= -github.com/tailscale/tscert v0.0.0-20240517230440-bbccfbf48933/go.mod h1:kNGUQ3VESx3VZwRwA9MSCUegIl6+saPL8Noq82ozCaU= +github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53 h1:uxMgm0C+EjytfAqyfBG55ZONKQ7mvd7x4YYCWsf8QHQ= +github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53/go.mod h1:kNGUQ3VESx3VZwRwA9MSCUegIl6+saPL8Noq82ozCaU= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/unrolled/secure v1.14.0 h1:u9vJTU/pR4Bny0ntLUMxdfLtmIRGvQf2sEFuA0TG9AE= -github.com/unrolled/secure v1.14.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= +github.com/unrolled/secure v1.15.0 h1:q7x+pdp8jAHnbzxu6UheP8fRlG/rwYTb8TPuQ3rn9Og= +github.com/unrolled/secure v1.15.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM= github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -501,11 +424,10 @@ github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+ github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I= github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= -github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= -github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= +github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= +github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= -github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= @@ -540,92 +462,57 @@ go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lI go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.step.sm/cli-utils v0.9.0 h1:55jYcsQbnArNqepZyAwcato6Zy2MoZDRkWW+jF+aPfQ= go.step.sm/cli-utils v0.9.0/go.mod h1:Y/CRoWl1FVR9j+7PnAewufAwKmBOTzR6l9+7EYGAnp8= -go.step.sm/crypto v0.46.0 h1:cuVZMpDbmEsUX+atC24+VineQr4gO+zO46MxbIVai4Y= -go.step.sm/crypto v0.46.0/go.mod h1:hcr0oTS2vGRTGSZxoVYxE+RRcsd4xP3rpqt3wPwYGqc= -go.step.sm/linkedca v0.20.1 h1:bHDn1+UG1NgRrERkWbbCiAIvv4lD5NOFaswPDTyO5vU= -go.step.sm/linkedca v0.20.1/go.mod h1:Vaq4+Umtjh7DLFI1KuIxeo598vfBzgSYZUjgVJ7Syxw= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.step.sm/crypto v0.51.1 h1:ktUg/2hetEMiBAqgz502ktZDGoDoGrcHFg3XpkmkvvA= +go.step.sm/crypto v0.51.1/go.mod h1:PdrhttNU/tG9/YsVd4fdlysBN+UV503p0o2irFZQlAw= +go.step.sm/linkedca v0.22.1 h1:GvprpH9P4Sv9U+eZ3bxDgRSSpW14cFDYpe1kS6yWLkw= +go.step.sm/linkedca v0.22.1/go.mod h1:dOKdF4HSn73YUEkfS5/FECngZmBtj2Il5DTKWXY4S6Y= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= 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.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.uber.org/zap/exp v0.2.0 h1:FtGenNNeCATRB3CmB/yEUnjEFeJWpB/pMcy7e2bKPYs= go.uber.org/zap/exp v0.2.0/go.mod h1:t0gqAIdh1MfKv9EwN/dLwfZnJxe9ITAZN78HEWPFWDQ= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/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-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/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.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= -golang.org/x/crypto/x509roots/fallback v0.0.0-20240603234054-0b431c7de36a h1:1mZr4dBUGHEdypxOCNajMoDtL+fYBEI1stTJ6JeK2YU= -golang.org/x/crypto/x509roots/fallback v0.0.0-20240603234054-0b431c7de36a/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= -golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg= -golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto/x509roots/fallback v0.0.0-20240806160748-b2d3a6a4b4d3 h1:oWb21rU9Q9XrRwXLB7jHc1rbp6EiiimZZv5MLxpu4T0= +golang.org/x/crypto/x509roots/fallback v0.0.0-20240806160748-b2d3a6a4b4d3/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= -golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/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-20190403152447-81d4e9dc473e/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-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -639,68 +526,50 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/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.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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +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-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/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-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= 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-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.181.0 h1:rPdjwnWgiPPOJx3IcSAQ2III5aX5tCer6wMpa/xmZi4= -google.golang.org/api v0.181.0/go.mod h1:MnQ+M0CFsfUwA5beZ+g/vCBCPXvtmZwRz2qzZk8ih1k= -google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda h1:wu/KJm9KJwpfHWhkkZGohVC6KRrc1oJNr4jwtQMOQXw= -google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda/go.mod h1:g2LLCvCeCSir/JJSWosk19BR4NVxGqHUC6rxIRsd7Aw= -google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= -google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= -google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/api v0.189.0 h1:equMo30LypAkdkLMBqfeIqtyAnlyig1JSZArl4XPwdI= +google.golang.org/api v0.189.0/go.mod h1:FLWGJKb0hb+pU2j+rJqwbnsF+ym+fQs73rbJ+KAUgy8= +google.golang.org/genproto v0.0.0-20240722135656-d784300faade h1:lKFsS7wpngDgSCeFn7MoLy+wBDQZ1UQIJD4UNM1Qvkg= +google.golang.org/genproto v0.0.0-20240722135656-d784300faade/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= +google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 h1:+/tmTy5zAieooKIXfzDm9KiA3Bv6JBwriRN9LY+yayk= +google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988/go.mod h1:4+X6GvPs+25wZKbQq9qyAXrwIRExv7w0Ea6MgZLZiDM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 h1:V71AcdLZr2p8dC9dbOIMCpqi4EmRl8wUwnJzXXLmbmc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= 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-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/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= 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/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= @@ -712,6 +581,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM= howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= diff --git a/go.mod b/go.mod index 0a7222ea..a0640b41 100644 --- a/go.mod +++ b/go.mod @@ -17,17 +17,17 @@ require ( github.com/gorilla/mux v1.8.1 github.com/hashicorp/golang-lru v1.0.2 github.com/kevburnsjr/skipfilter v0.0.1 - github.com/prometheus/client_golang v1.19.1 + github.com/prometheus/client_golang v1.20.0 github.com/prometheus/client_model v0.6.1 github.com/spf13/cobra v1.6.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 - github.com/unrolled/secure v1.14.0 + github.com/unrolled/secure v1.15.0 github.com/yosida95/uritemplate/v3 v3.0.2 go.etcd.io/bbolt v1.3.10 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.23.0 + golang.org/x/crypto v0.26.0 ) require ( @@ -41,29 +41,31 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/golang/glog v1.2.1 // indirect + github.com/golang/glog v1.2.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mschoch/smat v0.2.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/common v0.54.0 // indirect + github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/sagikazarmark/locafero v0.5.0 // indirect + github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/cast v1.7.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/protobuf v1.34.1 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index d1a50bcc..6f59ff59 100644 --- a/go.sum +++ b/go.sum @@ -37,8 +37,8 @@ github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= -github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= +github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= 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/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= @@ -54,16 +54,22 @@ github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7P github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/kevburnsjr/skipfilter v0.0.1 h1:EWl1lWUJfIehrKYIEkps0Cl67lCfS2pUM9iZFNajp7g= github.com/kevburnsjr/skipfilter v0.0.1/go.mod h1:jfaRyFOYVUtIa6IIC+0mB1qiZqhHw+DKvFowCBuijSk= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 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/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= 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/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= +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/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -71,27 +77,27 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE 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/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= +github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= 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.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= -github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= 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/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.5.0 h1:zXz2JnQDgE5gDg0R9ThkNT0orQzm47i8IuO6hk6XSYY= -github.com/sagikazarmark/locafero v0.5.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= +github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= +github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= 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 v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= +github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -111,8 +117,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/unrolled/secure v1.14.0 h1:u9vJTU/pR4Bny0ntLUMxdfLtmIRGvQf2sEFuA0TG9AE= -github.com/unrolled/secure v1.14.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= +github.com/unrolled/secure v1.15.0 h1:q7x+pdp8jAHnbzxu6UheP8fRlG/rwYTb8TPuQ3rn9Og= +github.com/unrolled/secure v1.15.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= @@ -123,21 +129,21 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg= -golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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= diff --git a/hub_test.go b/hub_test.go index b54763b2..45c0774e 100644 --- a/hub_test.go +++ b/hub_test.go @@ -76,7 +76,8 @@ func TestStartCrash(t *testing.T) { } func TestStop(t *testing.T) { - numberOfSubscribers := 2 + const numberOfSubscribers = 2 + hub := createAnonymousDummy() go func() { diff --git a/server_test.go b/server_test.go index 1745e4cc..32685003 100644 --- a/server_test.go +++ b/server_test.go @@ -231,7 +231,6 @@ func TestClientClosesThenReconnects(t *testing.T) { defer os.Remove("test.db") h := createAnonymousDummy(WithLogger(l), WithTransport(bt)) - transport := h.transport.(*BoltTransport) go h.Serve() // loop until the web server is ready @@ -242,7 +241,7 @@ func TestClientClosesThenReconnects(t *testing.T) { } require.NoError(t, resp.Body.Close()) - var wg sync.WaitGroup + var wg, subscribingWG sync.WaitGroup subscribe := func(expectedBodyData string) { cx, cancel := context.WithCancel(context.Background()) @@ -251,6 +250,8 @@ func TestClientClosesThenReconnects(t *testing.T) { resp, err := http.DefaultClient.Do(req) require.NoError(t, err) + subscribingWG.Done() + var receivedBody strings.Builder buf := make([]byte, 1024) for { @@ -271,15 +272,8 @@ func TestClientClosesThenReconnects(t *testing.T) { wg.Done() } - publish := func(data string, waitForSubscribers int) { - for { - transport.RLock() - l := transport.subscribers.Len() - transport.RUnlock() - if l >= waitForSubscribers { - break - } - } + publish := func(data string) { + subscribingWG.Wait() body := url.Values{"topic": {"http://example.com/foo/1"}, "data": {data}, "id": {data}} req, err := http.NewRequest(http.MethodPost, testURL, strings.NewReader(body.Encode())) @@ -296,29 +290,31 @@ func TestClientClosesThenReconnects(t *testing.T) { } nbSubscribers := 10 + subscribingWG.Add(nbSubscribers) wg.Add(nbSubscribers + 1) for i := 0; i < nbSubscribers; i++ { go subscribe("first") } - publish("first", nbSubscribers) + publish("first") wg.Wait() nbPublishers := 5 wg.Add(nbPublishers) for i := 0; i < nbPublishers; i++ { - go publish("lost", 0) + go publish("lost") } wg.Wait() nbSubscribers = 20 nbPublishers = 10 + subscribingWG.Add(nbSubscribers) wg.Add(nbSubscribers + nbPublishers) for i := 0; i < nbSubscribers; i++ { go subscribe("second") } for i := 0; i < nbPublishers; i++ { - go publish("second", nbSubscribers) + go publish("second") } wg.Wait() h.server.Shutdown(context.Background()) From 8c762753c48bf413d62a9143a3ffc5c068b4e0c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 18 Aug 2024 10:58:54 +0200 Subject: [PATCH 07/71] chore: bump deps --- caddy/go.mod | 4 ++-- caddy/go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index e4183aca..2820cdfd 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -173,8 +173,8 @@ require ( golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.24.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/grpc v1.65.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/caddy/go.sum b/caddy/go.sum index 347e0955..dd1b0f0c 100644 --- a/caddy/go.sum +++ b/caddy/go.sum @@ -558,10 +558,10 @@ google.golang.org/api v0.189.0 h1:equMo30LypAkdkLMBqfeIqtyAnlyig1JSZArl4XPwdI= google.golang.org/api v0.189.0/go.mod h1:FLWGJKb0hb+pU2j+rJqwbnsF+ym+fQs73rbJ+KAUgy8= google.golang.org/genproto v0.0.0-20240722135656-d784300faade h1:lKFsS7wpngDgSCeFn7MoLy+wBDQZ1UQIJD4UNM1Qvkg= google.golang.org/genproto v0.0.0-20240722135656-d784300faade/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= -google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988 h1:+/tmTy5zAieooKIXfzDm9KiA3Bv6JBwriRN9LY+yayk= -google.golang.org/genproto/googleapis/api v0.0.0-20240812133136-8ffd90a71988/go.mod h1:4+X6GvPs+25wZKbQq9qyAXrwIRExv7w0Ea6MgZLZiDM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988 h1:V71AcdLZr2p8dC9dbOIMCpqi4EmRl8wUwnJzXXLmbmc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240812133136-8ffd90a71988/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= From 6196fa06c9fd411abf1268c9652b83951aa0369e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 18 Aug 2024 11:48:17 +0200 Subject: [PATCH 08/71] chore: prepare release 0.16.3 --- caddy/go.mod | 2 +- charts/mercure/Chart.yaml | 4 ++-- charts/mercure/README.md | 3 ++- examples/chat/chart/mercure-example-chat/README.md | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index 2820cdfd..b148941b 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -12,7 +12,7 @@ replace github.com/dunglas/mercure => ../ require ( github.com/MicahParks/keyfunc/v3 v3.3.3 github.com/caddyserver/caddy/v2 v2.8.4 - github.com/dunglas/mercure v0.16.2 + github.com/dunglas/mercure v0.16.3 github.com/prometheus/client_golang v1.20.0 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 diff --git a/charts/mercure/Chart.yaml b/charts/mercure/Chart.yaml index b9811f21..dbbd25dd 100644 --- a/charts/mercure/Chart.yaml +++ b/charts/mercure/Chart.yaml @@ -12,8 +12,8 @@ keywords: - streaming-api - async-api type: application -version: 0.16.2 -appVersion: "v0.16.2" +version: 0.16.3 +appVersion: "v0.16.3" maintainers: - name: dunglas email: kevin@dunglas.fr diff --git a/charts/mercure/README.md b/charts/mercure/README.md index aa6742ca..ee52967c 100644 --- a/charts/mercure/README.md +++ b/charts/mercure/README.md @@ -1,7 +1,7 @@ # Mercure Chart for Kubernetes -![Version: 0.16.2](https://img.shields.io/badge/Version-0.16.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.16.2](https://img.shields.io/badge/AppVersion-v0.16.2-informational?style=flat-square) +![Version: 0.16.3](https://img.shields.io/badge/Version-0.16.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.16.3](https://img.shields.io/badge/AppVersion-v0.16.3-informational?style=flat-square) A Helm chart to install a Mercure Hub in a Kubernetes cluster. Mercure is a protocol to push data updates to web browsers and other HTTP clients in a convenient, fast, reliable and battery-efficient way. @@ -23,6 +23,7 @@ To install the chart with the release name `my-release`, run the following comma | caddyExtraConfig | string | `""` | Inject snippet or named-routes options in the Caddyfile | | caddyExtraDirectives | string | `""` | Inject extra Caddy directives in the Caddyfile. | | dev | bool | `false` | Enable the development mode, including the debug UI and the demo. | +| existingSecret | string | `""` | Allows to pass an existing secret name, the above values will be used if empty. | | extraDirectives | string | `""` | Inject extra Mercure directives in the Caddyfile. | | fullnameOverride | string | `""` | A name to substitute for the full names of resources. | | globalOptions | string | `""` | Inject global options in the Caddyfile. | diff --git a/examples/chat/chart/mercure-example-chat/README.md b/examples/chat/chart/mercure-example-chat/README.md index 2a391954..b24dfe30 100644 --- a/examples/chat/chart/mercure-example-chat/README.md +++ b/examples/chat/chart/mercure-example-chat/README.md @@ -42,4 +42,4 @@ A minimalist chat system, using Mercure and the Flask microframework to handle c | tolerations | list | `[]` | | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) +Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) From f0deae72b3996ba87c645f94d88eb761fb2ba412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 18 Aug 2024 15:57:53 +0200 Subject: [PATCH 09/71] chore: add Docker labels --- Dockerfile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Dockerfile b/Dockerfile index eb246a83..657733f8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,13 @@ +# syntax=docker/dockerfile:1 FROM caddy:2-alpine +LABEL org.opencontainers.image.title=Mercure.rocks +LABEL org.opencontainers.image.description="Real-time made easy" +LABEL org.opencontainers.image.url=https://mercure.rocks +LABEL org.opencontainers.image.source=https://github.com/dunglas/mercure +LABEL org.opencontainers.image.licenses=AGPL-3.0-or-later +LABEL org.opencontainers.image.vendor="Kévin Dunglas" + ENV MERCURE_TRANSPORT_URL=bolt:///data/mercure.db COPY mercure /usr/bin/caddy From 4e2e253d2c68b78026cccdb2adabfc6b125e14de Mon Sep 17 00:00:00 2001 From: Dimitri Allegoet Date: Thu, 22 Aug 2024 00:11:49 +0200 Subject: [PATCH 10/71] docs: use wget instead of curl for Docker healthcheck (#941) I replaced `curl` by `wget` in the healthcheck of `docker-compose.yml`, because curl is not available in the image `dunglas/mercure`. - `-q` : quiet, no output - `--spider` : don't download anything If there is no error wget returns 0, else 1 --- docs/hub/install.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/hub/install.md b/docs/hub/install.md index 1279a204..110f1275 100644 --- a/docs/hub/install.md +++ b/docs/hub/install.md @@ -127,7 +127,7 @@ services: # Uncomment the following line to enable the development mode #command: /usr/bin/caddy run --config /etc/caddy/dev.Caddyfile healthcheck: - test: ["CMD", "curl", "-f", "https://localhost/healthz"] + test: ["CMD", "wget", "-q", "--spider", "https://localhost/healthz"] timeout: 5s retries: 5 start_period: 60s From c76003d8725ef3e34e0bbb0554469b139678a746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 26 Aug 2024 14:35:32 +0200 Subject: [PATCH 11/71] docs: fix typos in Mercure --- docs/hub/troubleshooting.md | 2 +- docs/spec/use-cases.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/hub/troubleshooting.md b/docs/hub/troubleshooting.md index b3bbd16d..55c413e2 100644 --- a/docs/hub/troubleshooting.md +++ b/docs/hub/troubleshooting.md @@ -33,7 +33,7 @@ Try [our URI template tester](https://uri-template-tester.mercure.rocks/) to ens ## Disconnection With the Inability To Reconnect After Some Time -If the JWT supplied to the Mercury hub contains [an `exp` (expiration time) claim](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.3) (this is the default for tokens generated with most JWT libraries), the hub will automatically disconnect when the expiry date is reached. +If the JWT supplied to the Mercure hub contains [an `exp` (expiration time) claim](https://www.rfc-editor.org/rfc/rfc7519#section-4.1.3) (this is the default for tokens generated with most JWT libraries), the hub will automatically disconnect when the expiry date is reached. After that, it is no longer possible to reconnect with the same JWT, as it has expired. The hub will return an HTTP 401 error. One solution is to generate a new, valid JWT before reconnecting. diff --git a/docs/spec/use-cases.md b/docs/spec/use-cases.md index 71a3462c..dbf6fe75 100644 --- a/docs/spec/use-cases.md +++ b/docs/spec/use-cases.md @@ -5,7 +5,7 @@ From building a chat room to expose a fully-featured event store, Mercure covers ## Case Studies -* [How Raven Controls is using Mercury to power major events such as Cop 21 and Euro 2020](https://api-platform.com/con/2022/conferences/real-time-and-beyond-with-mercure/) +* [How Raven Controls is using Mercure to power major events such as Cop 21 and Euro 2020](https://api-platform.com/con/2022/conferences/real-time-and-beyond-with-mercure/) * [Pushing 8 million of Mercure notifications per day to run mail.tm](https://les-tilleuls.coop/en/blog/mail-tm-mercure-rocks-and-api-platform) * [100,000 simultaneous Mercure users to power iGraal](https://speakerdeck.com/dunglas/mercure-real-time-for-php-made-easy?slide=52) From a9545aa839174bdc00914a1e70149ed450258230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 28 Aug 2024 22:24:49 +0200 Subject: [PATCH 12/71] spec: remove redundant sentence --- spec/mercure.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spec/mercure.md b/spec/mercure.md index 705d53c6..0b1b3ca9 100644 --- a/spec/mercure.md +++ b/spec/mercure.md @@ -549,9 +549,8 @@ Variables are templated and expanded in accordance with [@!RFC6570]. ## Subscription Events -If the hub supports the active subscriptions feature, it **MUST** publish an update when a -subscription is created or terminated. If this feature is implemented by the hub, an update **MUST** -be dispatched every time a subscription is created or terminated. +If the hub supports the active subscriptions feature, it **MUST** publish an update every time a +subscription is created or terminated. The topic of these updates **MUST** be an expansion of `/.well-known/mercure/subscriptions/{topic}/{subscriber}`. `{topic}` is the topic selector used for From 55664bc7499e6a6e022dd0d7222924115e4f32ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 19 Aug 2024 17:56:59 +0200 Subject: [PATCH 13/71] feat: use Caddy modules for transports --- Caddyfile | 2 - bolt_transport.go | 38 ++++-- bolt_transport_test.go | 14 +- caddy/bolt_transport.go | 128 ++++++++++++++++++ caddy/caddy.go | 158 ++++++++++++++-------- caddy/caddy_test.go | 244 +++++++++++++++++++++++++++------- caddy/local_transport.go | 60 +++++++++ caddy/transport.go | 20 +++ dev.Caddyfile | 2 - docs/UPGRADE.md | 25 ++++ docs/hub/config.md | 55 ++++---- hub.go | 2 +- local_transport.go | 15 ++- local_transport_bench_test.go | 2 +- local_transport_test.go | 12 +- transport.go | 3 + 16 files changed, 622 insertions(+), 158 deletions(-) create mode 100644 caddy/bolt_transport.go create mode 100644 caddy/local_transport.go create mode 100644 caddy/transport.go diff --git a/Caddyfile b/Caddyfile index 6507ca76..f93379d3 100644 --- a/Caddyfile +++ b/Caddyfile @@ -19,8 +19,6 @@ encode zstd gzip mercure { - # Transport to use (default to Bolt) - transport_url {$MERCURE_TRANSPORT_URL:bolt://mercure.db} # Publisher JWT key publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG} # Subscriber JWT key diff --git a/bolt_transport.go b/bolt_transport.go index 2a55770e..4df7254c 100644 --- a/bolt_transport.go +++ b/bolt_transport.go @@ -18,7 +18,7 @@ import ( const BoltDefaultCleanupFrequency = 0.3 func init() { //nolint:gochecknoinits - RegisterTransportFactory("bolt", NewBoltTransport) + RegisterTransportFactory("bolt", DeprecatedNewBoltTransport) } const defaultBoltBucketName = "updates" @@ -38,8 +38,10 @@ type BoltTransport struct { lastEventID string } -// NewBoltTransport create a new boltTransport. -func NewBoltTransport(u *url.URL, l Logger) (Transport, error) { //nolint:ireturn +// DeprecatedNewBoltTransport creates a new BoltTransport. +// +// Deprecated: use NewBoltTransport() instead. +func DeprecatedNewBoltTransport(u *url.URL, l Logger) (Transport, error) { //nolint:ireturn var err error q := u.Query() bucketName := defaultBoltBucketName @@ -72,20 +74,40 @@ func NewBoltTransport(u *url.URL, l Logger) (Transport, error) { //nolint:iretur return nil, &TransportError{u.Redacted(), "missing path", err} } + return NewBoltTransport(l, path, bucketName, size, cleanupFrequency) +} + +// NewBoltTransport creates a new BoltTransport. +func NewBoltTransport( + logger Logger, + path string, + bucketName string, + size uint64, + cleanupFrequency float64, +) (*BoltTransport, error) { + if path == "" { + path = "bolt.db" + } + + if bucketName == "" { + bucketName = defaultBoltBucketName + } + db, err := bolt.Open(path, 0o600, &bolt.Options{Timeout: 1 * time.Second}) if err != nil { - return nil, &TransportError{dsn: u.Redacted(), err: err} + return nil, &TransportError{err: err} } return &BoltTransport{ - logger: l, + logger: logger, db: db, bucketName: bucketName, size: size, cleanupFrequency: cleanupFrequency, - subscribers: NewSubscriberList(1e5), - closed: make(chan struct{}), - lastEventID: getDBLastEventID(db, bucketName), + + subscribers: NewSubscriberList(1e5), + closed: make(chan struct{}), + lastEventID: getDBLastEventID(db, bucketName), }, nil } diff --git a/bolt_transport_test.go b/bolt_transport_test.go index 5dfaca49..ac92877a 100644 --- a/bolt_transport_test.go +++ b/bolt_transport_test.go @@ -17,7 +17,7 @@ import ( func createBoltTransport(dsn string) *BoltTransport { u, _ := url.Parse(dsn) - transport, _ := NewBoltTransport(u, zap.NewNop()) + transport, _ := DeprecatedNewBoltTransport(u, zap.NewNop()) return transport.(*BoltTransport) } @@ -57,7 +57,7 @@ func TestBoltTransportLogsBogusLastEventID(t *testing.T) { defer sink.Reset() u, _ := url.Parse("bolt://test.db") - transport, _ := NewBoltTransport(u, logger) + transport, _ := DeprecatedNewBoltTransport(u, logger) defer transport.Close() defer os.Remove("test.db") @@ -191,27 +191,27 @@ func TestBoltTransportPurgeHistory(t *testing.T) { func TestNewBoltTransport(t *testing.T) { u, _ := url.Parse("bolt://test.db?bucket_name=demo") - transport, err := NewBoltTransport(u, zap.NewNop()) + transport, err := DeprecatedNewBoltTransport(u, zap.NewNop()) require.NoError(t, err) require.NotNil(t, transport) transport.Close() u, _ = url.Parse("bolt://") - _, err = NewBoltTransport(u, zap.NewNop()) + _, err = DeprecatedNewBoltTransport(u, zap.NewNop()) require.EqualError(t, err, `"bolt:": invalid transport: missing path`) u, _ = url.Parse("bolt:///test.db") - _, err = NewBoltTransport(u, zap.NewNop()) + _, err = DeprecatedNewBoltTransport(u, zap.NewNop()) // The exact error message depends of the OS assert.Contains(t, err.Error(), "open /test.db:") u, _ = url.Parse("bolt://test.db?cleanup_frequency=invalid") - _, err = NewBoltTransport(u, zap.NewNop()) + _, err = DeprecatedNewBoltTransport(u, zap.NewNop()) require.EqualError(t, err, `"bolt://test.db?cleanup_frequency=invalid": invalid "cleanup_frequency" parameter "invalid": invalid transport: strconv.ParseFloat: parsing "invalid": invalid syntax`) u, _ = url.Parse("bolt://test.db?size=invalid") - _, err = NewBoltTransport(u, zap.NewNop()) + _, err = DeprecatedNewBoltTransport(u, zap.NewNop()) require.EqualError(t, err, `"bolt://test.db?size=invalid": invalid "size" parameter "invalid": invalid transport: strconv.ParseUint: parsing "invalid": invalid syntax`) } diff --git a/caddy/bolt_transport.go b/caddy/bolt_transport.go new file mode 100644 index 00000000..81ddd136 --- /dev/null +++ b/caddy/bolt_transport.go @@ -0,0 +1,128 @@ +package caddy + +import ( + "bytes" + "encoding/gob" + "strconv" + + "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" + "github.com/dunglas/mercure" +) + +func init() { //nolint:gochecknoinits + caddy.RegisterModule(Bolt{}) +} + +type Bolt struct { + Path string `json:"path,omitempty"` + BucketName string `json:"bucket_name,omitempty"` + Size uint64 `json:"size,omitempty"` + CleanupFrequency float64 `json:"cleanup_frequency,omitempty"` + + transport *mercure.BoltTransport + transportKey string +} + +// CaddyModule returns the Caddy module information. +func (Bolt) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + ID: "http.handlers.mercure.bolt", + New: func() caddy.Module { return new(Bolt) }, + } +} + +func (b *Bolt) GetTransport() mercure.Transport { //nolint:ireturn + return b.transport +} + +// Provision provisions b's configuration. +// +//nolint:wrapcheck +func (b *Bolt) Provision(ctx caddy.Context) error { + var key bytes.Buffer + if err := gob.NewEncoder(&key).Encode(b); err != nil { + return err + } + b.transportKey = key.String() + + destructor, _, err := transport.LoadOrNew(b.transportKey, func() (caddy.Destructor, error) { + t, err := mercure.NewBoltTransport(ctx.Logger(), b.Path, b.BucketName, b.Size, b.CleanupFrequency) + if err != nil { + return nil, err + } + + return transportDestructor[*mercure.BoltTransport]{transport: t}, nil + }) + if err != nil { + return err + } + + b.transport = destructor.(transportDestructor[*mercure.BoltTransport]).transport + + return nil +} + +//nolint:wrapcheck +func (b *Bolt) Cleanup() error { + _, err := transport.Delete(b.transportKey) + + return err +} + +// UnmarshalCaddyfile sets up the handler from Caddyfile tokens. +// +//nolint:wrapcheck +func (b *Bolt) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { + for d.Next() { + for d.NextBlock(0) { + switch d.Val() { + case "path": + if !d.NextArg() { + return d.ArgErr() + } + + b.Path = d.Val() + + case "bucket_name": + if !d.NextArg() { + return d.ArgErr() + } + + b.BucketName = d.Val() + + case "cleanup_frequency": + if !d.NextArg() { + return d.ArgErr() + } + + f, e := strconv.ParseFloat(d.Val(), 64) + if e != nil { + return e + } + + b.CleanupFrequency = f + + case "size": + if !d.NextArg() { + return d.ArgErr() + } + + s, e := strconv.ParseUint(d.Val(), 10, 64) + if e != nil { + return e + } + + b.Size = s + } + } + } + + return nil +} + +var ( + _ caddy.Provisioner = (*Bolt)(nil) + _ caddy.CleanerUpper = (*Bolt)(nil) + _ caddyfile.Unmarshaler = (*Bolt)(nil) +) diff --git a/caddy/caddy.go b/caddy/caddy.go index 9b0249fc..9af441cd 100644 --- a/caddy/caddy.go +++ b/caddy/caddy.go @@ -3,6 +3,7 @@ package caddy import ( + "encoding/json" "errors" "fmt" "net/http" @@ -13,6 +14,7 @@ import ( "github.com/MicahParks/keyfunc/v3" "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig" "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" "github.com/caddyserver/caddy/v2/modules/caddyhttp" @@ -26,8 +28,10 @@ const defaultHubURL = "/.well-known/mercure" var ( ErrCompatibility = errors.New("compatibility mode only supports protocol version 7") - transports = caddy.NewUsagePool() //nolint:gochecknoglobals metrics = mercure.NewPrometheusMetrics(prometheus.DefaultRegisterer) //nolint:gochecknoglobals + + // Deprecated: use transports Caddy modules. + transports = caddy.NewUsagePool() //nolint:gochecknoglobals ) func init() { //nolint:gochecknoinits @@ -41,14 +45,6 @@ type JWTConfig struct { Alg string `json:"alg,omitempty"` } -type transportDestructor struct { - transport mercure.Transport -} - -func (d *transportDestructor) Destruct() error { - return d.transport.Close() //nolint:wrapcheck -} - // Mercure implements a Mercure hub as a Caddy module. Mercure is a protocol allowing to push data updates to web browsers and other HTTP clients in a convenient, fast, reliable and battery-efficient way. type Mercure struct { // Allow subscribers with no valid JWT. @@ -91,6 +87,8 @@ type Mercure struct { CORSOrigins []string `json:"cors_origins,omitempty"` // Transport to use. + // + // Deprecated: use transports Caddy modules. TransportURL string `json:"transport_url,omitempty"` // Triggers use of LRU topic selector cache and avoidance of select priority queue (recommend 10,000 - 1,000,000) @@ -102,6 +100,9 @@ type Mercure struct { // The version of the Mercure protocol to be backward compatible with (only version 7 is supported) ProtocolVersionCompatibility int `json:"protocol_version_compatibility,omitempty"` + // The transport configuration. + TransportRaw json.RawMessage `json:"transport,omitempty" caddy:"namespace=http.handlers.mercure inline_key=name"` //nolint:tagalign + hub *mercure.Hub logger *zap.Logger } @@ -148,26 +149,12 @@ func (m *Mercure) populateJWTConfig() error { return nil } -func (m *Mercure) Provision(ctx caddy.Context) error { //nolint:funlen,gocognit - if err := m.populateJWTConfig(); err != nil { - return err - } - - if m.TransportURL == "" { - m.TransportURL = "bolt://mercure.db" - } +// Deprecated +// +//nolint:wrapcheck,ireturn +func createTransportLegacy(m *Mercure) (mercure.Transport, error) { + m.logger.Warn(`Setting transport_url is deprecated, use the "transport" directive instead`) - maxEntriesPerShard := mercure.DefaultTopicSelectorStoreLRUMaxEntriesPerShard - if m.LRUShardSize != nil { - maxEntriesPerShard = *m.LRUShardSize - } - - tss, err := mercure.NewTopicSelectorStoreLRU(maxEntriesPerShard, mercure.DefaultTopicSelectorStoreLRUShardCount) - if err != nil { - return err //nolint:wrapcheck - } - - m.logger = ctx.Logger(m) destructor, _, err := transports.LoadOrNew(m.TransportURL, func() (caddy.Destructor, error) { u, err := url.Parse(m.TransportURL) if err != nil { @@ -187,19 +174,57 @@ func (m *Mercure) Provision(ctx caddy.Context) error { //nolint:funlen,gocognit transport, err := mercure.NewTransport(u, m.logger) if err != nil { - return nil, err //nolint:wrapcheck + return nil, err } - return &transportDestructor{transport}, nil + return &transportDestructor[mercure.Transport]{transport}, nil }) if err != nil { - return err //nolint:wrapcheck + return nil, err + } + + return destructor.(*transportDestructor[mercure.Transport]).transport, nil +} + +//nolint:wrapcheck +func (m *Mercure) Provision(ctx caddy.Context) error { //nolint:funlen,gocognit + if err := m.populateJWTConfig(); err != nil { + return err + } + + maxEntriesPerShard := mercure.DefaultTopicSelectorStoreLRUMaxEntriesPerShard + if m.LRUShardSize != nil { + maxEntriesPerShard = *m.LRUShardSize + } + + tss, err := mercure.NewTopicSelectorStoreLRU(maxEntriesPerShard, mercure.DefaultTopicSelectorStoreLRUShardCount) + if err != nil { + return err + } + + m.logger = ctx.Logger() + + var transport mercure.Transport + if m.TransportURL == "" { + var mod any + if m.TransportRaw == nil { + mod, err = ctx.LoadModuleByID("http.handlers.mercure.bolt", nil) + } else { + mod, err = ctx.LoadModule(m, "TransportRaw") + } + if err != nil { + return err + } + + transport = mod.(Transport).GetTransport() + } else if transport, err = createTransportLegacy(m); err != nil { + return err } opts := []mercure.Option{ mercure.WithLogger(m.logger), mercure.WithTopicSelectorStore(tss), - mercure.WithTransport(destructor.(*transportDestructor).transport), + mercure.WithTransport(transport), mercure.WithMetrics(metrics), mercure.WithCookieName(m.CookieName), } @@ -261,7 +286,7 @@ func (m *Mercure) Provision(ctx caddy.Context) error { //nolint:funlen,gocognit h, err := mercure.NewHub(opts...) if err != nil { - return err //nolint:wrapcheck + return err } m.hub = h @@ -269,10 +294,17 @@ func (m *Mercure) Provision(ctx caddy.Context) error { //nolint:funlen,gocognit return nil } +// Deprecated: use transports Caddy modules. +// +//nolint:wrapcheck func (m *Mercure) Cleanup() error { + if m.TransportURL == "" { + return nil + } + _, err := transports.Delete(m.TransportURL) - return err //nolint:wrapcheck + return err } func (m Mercure) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { @@ -286,6 +318,8 @@ func (m Mercure) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhtt } // UnmarshalCaddyfile sets up the handler from Caddyfile tokens. +// +//nolint:wrapcheck func (m *Mercure) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { //nolint:funlen,gocognit,gocyclo for d.Next() { for d.NextBlock(0) { @@ -304,12 +338,12 @@ func (m *Mercure) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { //nolint:fu case "write_timeout": if !d.NextArg() { - return d.ArgErr() //nolint:wrapcheck + return d.ArgErr() } d, err := caddy.ParseDuration(d.Val()) if err != nil { - return err //nolint:wrapcheck + return err } cd := caddy.Duration(d) @@ -317,12 +351,12 @@ func (m *Mercure) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { //nolint:fu case "dispatch_timeout": if !d.NextArg() { - return d.ArgErr() //nolint:wrapcheck + return d.ArgErr() } d, err := caddy.ParseDuration(d.Val()) if err != nil { - return err //nolint:wrapcheck + return err } cd := caddy.Duration(d) @@ -330,12 +364,12 @@ func (m *Mercure) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { //nolint:fu case "heartbeat": if !d.NextArg() { - return d.ArgErr() //nolint:wrapcheck + return d.ArgErr() } d, err := caddy.ParseDuration(d.Val()) if err != nil { - return err //nolint:wrapcheck + return err } cd := caddy.Duration(d) @@ -343,14 +377,14 @@ func (m *Mercure) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { //nolint:fu case "publisher_jwks_url": if !d.NextArg() { - return d.ArgErr() //nolint:wrapcheck + return d.ArgErr() } m.PublisherJWKSURL = d.Val() case "publisher_jwt": if !d.NextArg() { - return d.ArgErr() //nolint:wrapcheck + return d.ArgErr() } m.PublisherJWT.Key = d.Val() @@ -360,14 +394,14 @@ func (m *Mercure) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { //nolint:fu case "subscriber_jwks_url": if !d.NextArg() { - return d.ArgErr() //nolint:wrapcheck + return d.ArgErr() } m.SubscriberJWKSURL = d.Val() case "subscriber_jwt": if !d.NextArg() { - return d.ArgErr() //nolint:wrapcheck + return d.ArgErr() } m.SubscriberJWT.Key = d.Val() @@ -378,7 +412,7 @@ func (m *Mercure) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { //nolint:fu case "publish_origins": ra := d.RemainingArgs() if len(ra) == 0 { - return d.ArgErr() //nolint:wrapcheck + return d.ArgErr() } m.PublishOrigins = ra @@ -386,45 +420,65 @@ func (m *Mercure) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { //nolint:fu case "cors_origins": ra := d.RemainingArgs() if len(ra) == 0 { - return d.ArgErr() //nolint:wrapcheck + return d.ArgErr() } m.CORSOrigins = ra + case "transport": + if !d.NextArg() { + return d.ArgErr() + } + + name := d.Val() + modID := "http.handlers.mercure." + name + + unm, err := caddyfile.UnmarshalModule(d, modID) + if err != nil { + return err + } + + t, ok := unm.(Transport) + if !ok { + return d.Errf(`module %s (%T) is not a supported transport implementation (requires "github.com/dunglas/mercure/caddy".Transport)`, modID, unm) + } + + m.TransportRaw = caddyconfig.JSONModuleObject(t, "name", name, nil) + case "transport_url": if !d.NextArg() { - return d.ArgErr() //nolint:wrapcheck + return d.ArgErr() } m.TransportURL = d.Val() case "lru_cache": if !d.NextArg() { - return d.ArgErr() //nolint:wrapcheck + return d.ArgErr() } v, err := strconv.ParseInt(d.Val(), 10, 64) if err != nil { - return err //nolint:wrapcheck + return err } m.LRUShardSize = &v case "cookie_name": if !d.NextArg() { - return d.ArgErr() //nolint:wrapcheck + return d.ArgErr() } m.CookieName = d.Val() case "protocol_version_compatibility": if !d.NextArg() { - return d.ArgErr() //nolint:wrapcheck + return d.ArgErr() } v, err := strconv.Atoi(d.Val()) if err != nil { - return err //nolint:wrapcheck + return err } if v != 7 { diff --git a/caddy/caddy_test.go b/caddy/caddy_test.go index e0f14da4..33ae50df 100644 --- a/caddy/caddy_test.go +++ b/caddy/caddy_test.go @@ -3,6 +3,7 @@ package caddy import ( "context" "errors" + "fmt" "io" "net/http" "net/url" @@ -12,6 +13,7 @@ import ( "testing" "github.com/caddyserver/caddy/v2/caddytest" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -23,75 +25,96 @@ const ( ) func TestMercure(t *testing.T) { - tester := caddytest.NewTester(t) - tester.InitServer(` - { - skip_install_trust - admin localhost:2999 - http_port 9080 - https_port 9443 + data := []struct { + name string + transportConfig string + }{ + {"bolt", ""}, + {"local", "transport local\n"}, } - localhost:9080 { - route { - mercure { - anonymous - publisher_jwt !ChangeMe! + for _, d := range data { + t.Run(d.name, func(t *testing.T) { + if d.name == "bolt" { + defer os.Remove("bolt.db") } - - respond 404 + + tester := caddytest.NewTester(t) + tester.InitServer(fmt.Sprintf(`{ + skip_install_trust + admin localhost:2999 + http_port 9080 + https_port 9443 +} + +localhost:9080 { + route { + mercure { + anonymous + publisher_jwt !ChangeMe! + %s } + + respond 404 } - `, "caddyfile") +}`, d.transportConfig), "caddyfile") - var connected sync.WaitGroup - var received sync.WaitGroup - connected.Add(1) - received.Add(1) + var connected sync.WaitGroup + var received sync.WaitGroup + connected.Add(1) + received.Add(1) - go func() { - cx, cancel := context.WithCancel(context.Background()) - req, _ := http.NewRequest(http.MethodGet, "http://localhost:9080/.well-known/mercure?topic=http%3A%2F%2Fexample.com%2Ffoo%2F1", nil) - req = req.WithContext(cx) - resp := tester.AssertResponseCode(req, http.StatusOK) + go func() { + cx, cancel := context.WithCancel(context.Background()) + req, _ := http.NewRequest(http.MethodGet, "http://localhost:9080/.well-known/mercure?topic=http%3A%2F%2Fexample.com%2Ffoo%2F1", nil) + req = req.WithContext(cx) + resp := tester.AssertResponseCode(req, http.StatusOK) - connected.Done() + connected.Done() - var receivedBody strings.Builder - buf := make([]byte, 1024) - for { - _, err := resp.Body.Read(buf) - if errors.Is(err, io.EOF) { - panic("EOF") - } + var receivedBody strings.Builder + buf := make([]byte, 1024) + for { + _, err := resp.Body.Read(buf) + if errors.Is(err, io.EOF) { + panic("EOF") + } - receivedBody.Write(buf) - if strings.Contains(receivedBody.String(), "data: bar\n") { - cancel() + receivedBody.Write(buf) + if strings.Contains(receivedBody.String(), "data: bar\n") { + cancel() - break - } - } + break + } + } - resp.Body.Close() - received.Done() - }() + resp.Body.Close() + received.Done() + }() - connected.Wait() + connected.Wait() - body := url.Values{"topic": {"http://example.com/foo/1"}, "data": {"bar"}, "id": {"bar"}} - req, err := http.NewRequest(http.MethodPost, "http://localhost:9080/.well-known/mercure", strings.NewReader(body.Encode())) - require.NoError(t, err) - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - req.Header.Add("Authorization", bearerPrefix+publisherJWT) + body := url.Values{"topic": {"http://example.com/foo/1"}, "data": {"bar"}, "id": {"bar"}} + req, err := http.NewRequest(http.MethodPost, "http://localhost:9080/.well-known/mercure", strings.NewReader(body.Encode())) + require.NoError(t, err) + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + req.Header.Add("Authorization", bearerPrefix+publisherJWT) - resp := tester.AssertResponseCode(req, http.StatusOK) - resp.Body.Close() + resp := tester.AssertResponseCode(req, http.StatusOK) + resp.Body.Close() - received.Wait() + received.Wait() + + if d.name != "bolt" { + assert.NoFileExists(t, "bolt.db") + } + }) + } } func TestJWTPlaceholders(t *testing.T) { + defer os.Remove("bolt.db") + k, _ := os.ReadFile("../fixtures/jwt/RS256.key.pub") t.Setenv("TEST_JWT_KEY", string(k)) t.Setenv("TEST_JWT_ALG", "RS256") @@ -165,6 +188,8 @@ func TestJWTPlaceholders(t *testing.T) { } func TestSubscriptionAPI(t *testing.T) { + defer os.Remove("bolt.db") + tester := caddytest.NewTester(t) tester.InitServer(` { @@ -193,6 +218,8 @@ func TestSubscriptionAPI(t *testing.T) { } func TestCookieName(t *testing.T) { + defer os.Remove("bolt.db") + tester := caddytest.NewTester(t) tester.InitServer(` { @@ -264,3 +291,120 @@ func TestCookieName(t *testing.T) { received.Wait() } + +func TestBoltConfig(t *testing.T) { + defer os.Remove("test.db") + + tester := caddytest.NewTester(t) + tester.InitServer(` +{ + skip_install_trust + admin localhost:2999 + http_port 9080 + https_port 9443 +} + +localhost:9080 { + route { + mercure { + anonymous + publisher_jwt !ChangeMe! + transport bolt { + path test.db + bucket_name foo + size 20 + cleanup_frequency 0.2 + } + } + + respond 404 + } +}`, "caddyfile") + + assert.FileExists(t, "test.db") +} + +func TestAdaptBoltConfig(t *testing.T) { + caddytest.AssertAdapt(t, `http:// + +mercure { + publisher_jwt !ChangeMe! + transport bolt { + path test.db + bucket_name foo + size 20 + cleanup_frequency 0.2 + } +} +`, "caddyfile", `{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":80" + ], + "routes": [ + { + "handle": [ + { + "handler": "mercure", + "publisher_jwt": { + "key": "!ChangeMe!" + }, + "subscriber_jwt": {}, + "transport": { + "bucket_name": "foo", + "cleanup_frequency": 0.2, + "name": "bolt", + "path": "test.db", + "size": 20 + } + } + ] + } + ] + } + } + } + } +}`) +} + +func TestAdaptLocalConfig(t *testing.T) { + caddytest.AssertAdapt(t, `http:// + +mercure { + publisher_jwt !ChangeMe! + transport local +} +`, "caddyfile", `{ + "apps": { + "http": { + "servers": { + "srv0": { + "listen": [ + ":80" + ], + "routes": [ + { + "handle": [ + { + "handler": "mercure", + "publisher_jwt": { + "key": "!ChangeMe!" + }, + "subscriber_jwt": {}, + "transport": { + "name": "local" + } + } + ] + } + ] + } + } + } + } +}`) +} diff --git a/caddy/local_transport.go b/caddy/local_transport.go new file mode 100644 index 00000000..23874b64 --- /dev/null +++ b/caddy/local_transport.go @@ -0,0 +1,60 @@ +package caddy + +import ( + "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" + "github.com/dunglas/mercure" +) + +type localTransportKeyStruct struct{} + +var localTransportKey = localTransportKeyStruct{} //nolint:gochecknoglobals + +func init() { //nolint:gochecknoinits + caddy.RegisterModule(Local{}) +} + +type Local struct { + transport *mercure.LocalTransport +} + +// CaddyModule returns the Caddy module information. +func (Local) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + ID: "http.handlers.mercure.local", + New: func() caddy.Module { return new(Local) }, + } +} + +func (l *Local) GetTransport() mercure.Transport { //nolint:ireturn + return l.transport +} + +// Provision provisions b's configuration. +func (l *Local) Provision(_ caddy.Context) error { + destructor, _, _ := transport.LoadOrNew(localTransportKey, func() (caddy.Destructor, error) { + return transportDestructor[*mercure.LocalTransport]{transport: mercure.NewLocalTransport()}, nil + }) + + l.transport = destructor.(transportDestructor[*mercure.LocalTransport]).transport + + return nil +} + +//nolint:wrapcheck +func (l *Local) Cleanup() error { + _, err := transport.Delete(localTransportKey) + + return err +} + +// UnmarshalCaddyfile sets up the handler from Caddyfile tokens. +func (l *Local) UnmarshalCaddyfile(_ *caddyfile.Dispenser) error { + return nil +} + +var ( + _ caddy.Provisioner = (*Bolt)(nil) + _ caddy.CleanerUpper = (*Bolt)(nil) + _ caddyfile.Unmarshaler = (*Bolt)(nil) +) diff --git a/caddy/transport.go b/caddy/transport.go new file mode 100644 index 00000000..8a33559f --- /dev/null +++ b/caddy/transport.go @@ -0,0 +1,20 @@ +package caddy + +import ( + "github.com/caddyserver/caddy/v2" + "github.com/dunglas/mercure" +) + +var transport = caddy.NewUsagePool() //nolint:gochecknoglobals + +type Transport interface { + GetTransport() mercure.Transport +} + +type transportDestructor[T mercure.Transport] struct { + transport T +} + +func (d transportDestructor[T]) Destruct() error { + return d.transport.Close() //nolint:wrapcheck +} diff --git a/dev.Caddyfile b/dev.Caddyfile index 8d50589d..c4dff9ec 100644 --- a/dev.Caddyfile +++ b/dev.Caddyfile @@ -19,8 +19,6 @@ encode zstd gzip mercure { - # Transport to use (default to Bolt) - transport_url {$MERCURE_TRANSPORT_URL:bolt://mercure.db} # Publisher JWT key publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG} # Subscriber JWT key diff --git a/docs/UPGRADE.md b/docs/UPGRADE.md index edc521ac..ab204c81 100644 --- a/docs/UPGRADE.md +++ b/docs/UPGRADE.md @@ -1,5 +1,30 @@ # Upgrade +## 0.17 + +The `TRANSPORT_URL` environment variable has been removed and the `transport_url` directive has been deprecated. +Use the new `transport` directive instead. + +Before: + +```caddyfile +transport_url bolt://mercure.db?cleanup_frequency=0.2 +``` + +After: + +```caddyfile +transport bolt { + cleanup_frequency 0.2 +} +``` + +To configure the transport using an environment variable, append the `transport directive` to the `MERCURE_EXTRA_DIRECTIVES` environment variable. + +To prevent security issues, be sure to not pass credentials such as API tokens or password in `MERCURE_EXTRA_DIRECTIVES` (ex: when using transports [provided by the paid version](hub/cluster.md) such as Redis). + +To pass credentials security, create a custom `Caddyfile` an use the `{env.MY_ENV_VAR}` syntax, which is interpreted at runtime. + ## 0.16.2 The `Caddyfile.dev` file has been renamed `dev.Caddyfile` to match new Caddy best practices diff --git a/docs/hub/config.md b/docs/hub/config.md index 4f0d4342..3ffec91a 100644 --- a/docs/hub/config.md +++ b/docs/hub/config.md @@ -38,25 +38,26 @@ Note that HTTPS is automatically disabled if you set the server port to 80. The following Mercure-specific directives are available: -| Directive | Description | Default | -|--------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------| -| `publisher_jwt []` | the JWT key and algorithm to use for publishers, can contain [placeholders](https://caddyserver.com/docs/conventions#placeholders) | | -| `subscriber_jwt []` | the JWT key and algorithm to use for subscribers, can contain [placeholders](https://caddyserver.com/docs/conventions#placeholders) | | -| `publisher_jwks_url` | the URL of the JSON Web Key Set (JWK Set) URL (provided by identity providers such as Keycloak or AWS Cognito) to use for validating publishers JWT (take precedence over `publisher_jwt`) | | -| `subscriber_jwks_url` | the URL of the JSON Web Key Set (JWK Set) URL to use for validating publishers JWT (take precedence over `publisher_jwt`) | | -| `anonymous` | allow subscribers with no valid JWT to connect | `false` | -| `publish_origins ` | a list of origins allowed publishing, can be `*` for all (only applicable when using cookie-based auth) | | -| `cors_origins ` | a list of allowed CORS origins, ([troubleshoot CORS issues](troubleshooting.md#cors-issues)) | | -| `cookie_name ` | the name of the cookie to use for the authorization mechanism | `mercureAuthorization` | -| `subscriptions` | expose the subscription web API and dispatch private updates when a subscription between the Hub and a subscriber is established or closed. The topic follows the template `/.well-known/mercure/subscriptions/{topicSelector}/{subscriberID}` | | -| `heartbeat` | interval between heartbeats (useful with some proxies, and old browsers), set to `0s` disable | `40s` | -| `transport_url ` | URL representation of the transport to use. Use `local://local` to disabled history, (example `bolt:///var/run/mercure.db?size=100&cleanup_frequency=0.4`), see also [the cluster mode](cluster.md) | `bolt://mercure.db` | -| `dispatch_timeout ` | maximum duration of the dispatch of a single update, set to `0s` disable | `5s` | -| `write_timeout ` | maximum duration before closing the connection, set to `0s` disable | `600s` | -| `protocol_version_compatibility` | version of the protocol to be backward compatible with (only version 7 is supported) | disabled | -| `demo` | enable the UI and expose demo endpoints | | -| `ui` | enable the UI but do not expose demo endpoints | | -| `cache ` | cache configuration (see [Ristretto's docs](https://github.com/dgraph-io/ristretto)), set to -1 to disable the cache | `6e7` `1e8` (100MB) | +| Directive | Description | Default | +|---------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------| +| `publisher_jwt []` | the JWT key and algorithm to use for publishers, can contain [placeholders](https://caddyserver.com/docs/conventions#placeholders) | | +| `subscriber_jwt []` | the JWT key and algorithm to use for subscribers, can contain [placeholders](https://caddyserver.com/docs/conventions#placeholders) | | +| `publisher_jwks_url` | the URL of the JSON Web Key Set (JWK Set) URL (provided by identity providers such as Keycloak or AWS Cognito) to use for validating publishers JWT (take precedence over `publisher_jwt`) | | +| `subscriber_jwks_url` | the URL of the JSON Web Key Set (JWK Set) URL to use for validating publishers JWT (take precedence over `publisher_jwt`) | | +| `anonymous` | allow subscribers with no valid JWT to connect | `false` | +| `publish_origins ` | a list of origins allowed publishing, can be `*` for all (only applicable when using cookie-based auth) | | +| `cors_origins ` | a list of allowed CORS origins, ([troubleshoot CORS issues](troubleshooting.md#cors-issues)) | | +| `cookie_name ` | the name of the cookie to use for the authorization mechanism | `mercureAuthorization` | +| `subscriptions` | expose the subscription web API and dispatch private updates when a subscription between the Hub and a subscriber is established or closed. The topic follows the template `/.well-known/mercure/subscriptions/{topicSelector}/{subscriberID}` | | +| `heartbeat` | interval between heartbeats (useful with some proxies, and old browsers), set to `0s` disable | `40s` | +| `transport [{ }]` | The transport to use. Options are transport-specific. See also [the cluster mode](cluster.md) | `bolt://mercure.db` | +| `dispatch_timeout ` | maximum duration of the dispatch of a single update, set to `0s` disable | `5s` | +| `write_timeout ` | maximum duration before closing the connection, set to `0s` disable | `600s` | +| `protocol_version_compatibility` | version of the protocol to be backward compatible with (only version 7 is supported) | disabled | +| `demo` | enable the UI and expose demo endpoints | | +| `ui` | enable the UI but do not expose demo endpoints | | +| `cache ` | cache configuration (see [Ristretto's docs](https://github.com/dgraph-io/ristretto)), set to -1 to disable the cache | `6e7` `1e8` (100MB) | +| `transport_url ` | **Deprecated: use `transport` instead.** URL representation of the transport to use. Use `local://local` to disable the history, (example `bolt:///var/run/mercure.db?size=100&cleanup_frequency=0.4`), see also [the cluster mode](cluster.md) | `bolt://mercure.db` | See also [the list of built-in Caddyfile directives](https://caddyserver.com/docs/caddyfile/directives). @@ -70,7 +71,6 @@ The provided `Caddyfile` and the Docker image provide convenient environment var | `CADDY_EXTRA_CONFIG` | the [snippet](https://caddyserver.com/docs/caddyfile/concepts#snippets) or the [named-routes](https://caddyserver.com/docs/caddyfile/concepts#named-routes) options block to inject in the `Caddyfile`, one per line | | | `CADDY_SERVER_EXTRA_DIRECTIVES`| [`Caddyfile` directives](https://caddyserver.com/docs/caddyfile/concepts#directives) | | | `SERVER_NAME` | the server name or address | `localhost` | -| `MERCURE_TRANSPORT_URL` | the value passed to the `transport_url` directive | `bolt://mercure.db` | | `MERCURE_PUBLISHER_JWT_KEY` | the JWT key to use for publishers | | | `MERCURE_PUBLISHER_JWT_ALG` | the JWT algorithm to use for publishers | `HS256` | | `MERCURE_SUBSCRIBER_JWT_KEY` | the JWT key to use for subscribers | | @@ -126,14 +126,21 @@ MERCURE_SUBSCRIBER_JWT_ALG=RS256 \ ## Bolt Adapter -The [Data Source Name (DSN)](https://en.wikipedia.org/wiki/Data_source_name) specifies the path to the [bolt](https://github.com/etcd-io/bbolt) database as well as options - -| Parameter | Description | +| Option | Description | |---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `path` | path of the database file (default: `mercure.db`) | | `bucket_name` | name of the bolt bucket to store events. default to `updates` | | `cleanup_frequency` | chances to trigger history cleanup when an update occurs, must be a number between `0` (never cleanup) and `1` (cleanup after every publication), default to `0.3`. | | `size` | size of the history (to retrieve lost messages using the `Last-Event-ID` header), set to `0` to never remove old events (default) | +You can visualize and edit the content of the database using [boltdbweb](https://github.com/evnix/boltdbweb). + +### Legacy URL + +**This feature is deprecated: use the new `transport` directive instead**. + +The [Data Source Name (DSN)](https://en.wikipedia.org/wiki/Data_source_name) specifies the path to the [bolt](https://github.com/etcd-io/bbolt) database as well as options. All options available as directive except `path` can be passed. + Below are common examples of valid DSNs showing a combination of available values: ```Caddyfile @@ -147,8 +154,6 @@ transport_url bolt://database.db transport_url bolt://database.db?bucket_name=demo&size=1000&cleanup_frequency=0.5 ``` -You can visualize and edit the content of the database using [boltdbweb](https://github.com/evnix/boltdbweb). - ## Legacy Server **The legacy server is deprecated and will be removed in the next version. Consider upgrading to the Caddy-based build.** diff --git a/hub.go b/hub.go index cddbdb89..f11462f0 100644 --- a/hub.go +++ b/hub.go @@ -325,7 +325,7 @@ func NewHub(options ...Option) (*Hub, error) { } if opt.transport == nil { - t, _ := NewLocalTransport(nil, nil) + t, _ := DeprecatedNewLocalTransport(nil, nil) opt.transport = t } diff --git a/local_transport.go b/local_transport.go index f6a8d246..53ce1aa9 100644 --- a/local_transport.go +++ b/local_transport.go @@ -6,7 +6,7 @@ import ( ) func init() { //nolint:gochecknoinits - RegisterTransportFactory("local", NewLocalTransport) + RegisterTransportFactory("local", DeprecatedNewLocalTransport) } // LocalTransport implements the TransportInterface without database and simply broadcast the live Updates. @@ -18,13 +18,20 @@ type LocalTransport struct { closedOnce sync.Once } -// NewLocalTransport create a new LocalTransport. -func NewLocalTransport(_ *url.URL, _ Logger) (Transport, error) { //nolint:ireturn +// DeprecatedNewLocalTransport creates a new LocalTransport. +// +// Deprecated: use NewLocalTransport() instead. +func DeprecatedNewLocalTransport(_ *url.URL, _ Logger) (Transport, error) { //nolint:ireturn + return NewLocalTransport(), nil +} + +// NewLocalTransport creates a new LocalTransport. +func NewLocalTransport() *LocalTransport { return &LocalTransport{ subscribers: NewSubscriberList(1e5), closed: make(chan struct{}), lastEventID: EarliestLastEventID, - }, nil + } } // Dispatch dispatches an update to all subscribers. diff --git a/local_transport_bench_test.go b/local_transport_bench_test.go index c6ddd2b1..e38cd699 100644 --- a/local_transport_bench_test.go +++ b/local_transport_bench_test.go @@ -18,7 +18,7 @@ func BenchmarkLocalTransport(b *testing.B) { func subBenchLocalTransport(b *testing.B, topics, concurrency, matchPct int, testName string) { b.Helper() - tr, err := NewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) + tr, err := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) if err != nil { panic(err) } diff --git a/local_transport_test.go b/local_transport_test.go index 15852bfa..14ba3721 100644 --- a/local_transport_test.go +++ b/local_transport_test.go @@ -11,7 +11,7 @@ import ( ) func TestLocalTransportDoNotDispatchUntilListen(t *testing.T) { - transport, _ := NewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) + transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) defer transport.Close() assert.Implements(t, (*Transport)(nil), transport) @@ -37,7 +37,7 @@ func TestLocalTransportDoNotDispatchUntilListen(t *testing.T) { } func TestLocalTransportDispatch(t *testing.T) { - transport, _ := NewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) + transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) defer transport.Close() assert.Implements(t, (*Transport)(nil), transport) @@ -51,7 +51,7 @@ func TestLocalTransportDispatch(t *testing.T) { } func TestLocalTransportClosed(t *testing.T) { - transport, _ := NewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) + transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) defer transport.Close() assert.Implements(t, (*Transport)(nil), transport) @@ -66,7 +66,7 @@ func TestLocalTransportClosed(t *testing.T) { } func TestLiveCleanDisconnectedSubscribers(t *testing.T) { - tr, _ := NewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) + tr, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) transport := tr.(*LocalTransport) defer transport.Close() @@ -88,7 +88,7 @@ func TestLiveCleanDisconnectedSubscribers(t *testing.T) { } func TestLiveReading(t *testing.T) { - transport, _ := NewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) + transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) defer transport.Close() assert.Implements(t, (*Transport)(nil), transport) @@ -104,7 +104,7 @@ func TestLiveReading(t *testing.T) { } func TestLocalTransportGetSubscribers(t *testing.T) { - transport, _ := NewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) + transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) defer transport.Close() require.NotNil(t, transport) diff --git a/transport.go b/transport.go index f5b6645b..be58e36d 100644 --- a/transport.go +++ b/transport.go @@ -14,16 +14,19 @@ const EarliestLastEventID = "earliest" type TransportFactory = func(u *url.URL, l Logger) (Transport, error) var ( + // Deprecated: directly instantiate the transport or use transports Caddy modules. transportFactories = make(map[string]TransportFactory) //nolint:gochecknoglobals transportFactoriesMu sync.RWMutex //nolint:gochecknoglobals ) +// Deprecated: directly instantiate the transport or use transports Caddy modules. func RegisterTransportFactory(scheme string, factory TransportFactory) { transportFactoriesMu.Lock() transportFactories[scheme] = factory transportFactoriesMu.Unlock() } +// Deprecated: directly instantiate the transport or use transports Caddy modules. func NewTransport(u *url.URL, l Logger) (Transport, error) { //nolint:ireturn transportFactoriesMu.RLock() f, ok := transportFactories[u.Scheme] From 62b6f20baecddd5efe8db919031866e1e3388bb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 19 Aug 2024 22:36:41 +0200 Subject: [PATCH 14/71] feat: add backward compatibility layer --- Dockerfile | 2 -- caddy/caddy.go | 12 +++++++++++- charts/mercure/templates/deployment.yaml | 5 +++++ charts/mercure/templates/secrets.yaml | 2 ++ charts/mercure/values.yaml | 14 +++++++++++--- docs/UPGRADE.md | 9 ++++++++- 6 files changed, 37 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 657733f8..1e9fe0d8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,8 +8,6 @@ LABEL org.opencontainers.image.source=https://github.com/dunglas/mercure LABEL org.opencontainers.image.licenses=AGPL-3.0-or-later LABEL org.opencontainers.image.vendor="Kévin Dunglas" -ENV MERCURE_TRANSPORT_URL=bolt:///data/mercure.db - COPY mercure /usr/bin/caddy COPY Caddyfile /etc/caddy/Caddyfile COPY dev.Caddyfile /etc/caddy/dev.Caddyfile diff --git a/caddy/caddy.go b/caddy/caddy.go index 9af441cd..864fe995 100644 --- a/caddy/caddy.go +++ b/caddy/caddy.go @@ -8,6 +8,7 @@ import ( "fmt" "net/http" "net/url" + "os" "strconv" "strings" "time" @@ -153,7 +154,7 @@ func (m *Mercure) populateJWTConfig() error { // //nolint:wrapcheck,ireturn func createTransportLegacy(m *Mercure) (mercure.Transport, error) { - m.logger.Warn(`Setting transport_url is deprecated, use the "transport" directive instead`) + m.logger.Warn(`Setting the transport_url or the MERCURE_TRANSPORT_URL environment variable is deprecated, use the "transport" directive instead`) destructor, _, err := transports.LoadOrNew(m.TransportURL, func() (caddy.Destructor, error) { u, err := url.Parse(m.TransportURL) @@ -490,6 +491,15 @@ func (m *Mercure) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { //nolint:fu } } + // BC layer with old versions of the built-in Caddyfile + if m.TransportRaw == nil && m.TransportURL == "" { + deprecatedTransportURL := os.Getenv("MERCURE_TRANSPORT_URL") + + if deprecatedTransportURL != "" { + m.TransportURL = deprecatedTransportURL + } + } + return nil } diff --git a/charts/mercure/templates/deployment.yaml b/charts/mercure/templates/deployment.yaml index 8dc59e25..1fa5577d 100644 --- a/charts/mercure/templates/deployment.yaml +++ b/charts/mercure/templates/deployment.yaml @@ -57,11 +57,13 @@ spec: secretKeyRef: name: {{ include "mercure.secretName" . }} key: caddy-extra-directives + {{- if .Values.transportUrl }} - name: MERCURE_TRANSPORT_URL valueFrom: secretKeyRef: name: {{ include "mercure.secretName" . }} key: transport-url + {{- end }} - name: MERCURE_PUBLISHER_JWT_KEY valueFrom: secretKeyRef: @@ -92,6 +94,9 @@ spec: secretKeyRef: name: {{ include "mercure.secretName" . }} key: license + {{- if .Values.extraEnvs }} + {{- toYaml .Values.extraEnvs | nindent 12 }} + {{- end }} {{- if .Values.persistence.enabled }} volumeMounts: - mountPath: /data diff --git a/charts/mercure/templates/secrets.yaml b/charts/mercure/templates/secrets.yaml index de703c2c..f7a1b724 100644 --- a/charts/mercure/templates/secrets.yaml +++ b/charts/mercure/templates/secrets.yaml @@ -7,7 +7,9 @@ metadata: {{- include "mercure.labels" . | nindent 4 }} type: Opaque data: + {{- if .Values.transportUrl }} transport-url: {{ .Values.transportUrl | b64enc | quote }} + {{- end }} publisher-jwt-key: {{ .Values.publisherJwtKey | default (randAlphaNum 40) | b64enc | quote }} subscriber-jwt-key: {{ .Values.subscriberJwtKey | default (randAlphaNum 40) | b64enc | quote }} extra-directives: {{ .Values.extraDirectives | b64enc | quote }} diff --git a/charts/mercure/values.yaml b/charts/mercure/values.yaml index d01b5755..091c9fa9 100644 --- a/charts/mercure/values.yaml +++ b/charts/mercure/values.yaml @@ -8,8 +8,8 @@ globalOptions: "" caddyExtraConfig: "" # -- Enable the development mode, including the debug UI and the demo. dev: false -# -- The URL representation of the transport to use. -transportUrl: bolt:///data/mercure.db +# -- Deprecated: The URL representation of the transport to use. +transportUrl: "" # -- Inject extra Mercure directives in the Caddyfile. extraDirectives: "" # -- Inject extra Caddy directives in the Caddyfile. @@ -25,10 +25,18 @@ subscriberJwtKey: "" # -- The JWT algorithm to use for subscribers. subscriberJwtAlg: HS256 +# -- Additional environment variables to set +extraEnvs: [] +# extraEnvs: +# - name: FOO +# valueFrom: +# secretKeyRef: +# key: FOO +# name: secret-resource + # -- Allows to pass an existing secret name, the above values will be used if empty. existingSecret: "" # These keys must exist in the provided secret: -# - transport-url # - publisher-jwt-key # - subscriber-jwt-key # - extra-directives: diff --git a/docs/UPGRADE.md b/docs/UPGRADE.md index ab204c81..adb00474 100644 --- a/docs/UPGRADE.md +++ b/docs/UPGRADE.md @@ -2,9 +2,16 @@ ## 0.17 -The `TRANSPORT_URL` environment variable has been removed and the `transport_url` directive has been deprecated. +The `MERCURE_TRANSPORT_URL` environment variable and the `transport_url` directive have been deprecated. Use the new `transport` directive instead. +The `MERCURE_TRANSPORT_URL` environement variable has been removed from the default `Caddyfile`s, +but a backward compatibility layer is provided. + +If both the `transport` and the deprecated `transport_url` are not explicitly set +and the `MERCURE_TRANSPORT_URL` environement variable is set, the `transport_url` will be automatically populated. +To disable this behavior, unset `MERCURE_TRANSPORT_URL` or set it to an empty string. + Before: ```caddyfile From ab445d36bde326d990268135707bd924ce3010cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 30 Aug 2024 22:29:44 +0200 Subject: [PATCH 15/71] perf!: use topic selector store in subscriber (#944) * perf: fast check for URI template in topic * better fix --- bolt_transport_test.go | 24 ++++++++--------- local_transport_bench_test.go | 3 ++- local_transport_test.go | 42 +++++++++++++++++++----------- metrics_test.go | 14 +++++++--- publish_test.go | 4 +-- subscribe.go | 3 ++- subscribe_test.go | 10 +++++-- subscriber.go | 49 ++++++----------------------------- subscriber_bench_test.go | 2 +- subscriber_list_test.go | 3 ++- subscriber_test.go | 10 +++---- subscription_test.go | 25 +++++++++++------- 12 files changed, 95 insertions(+), 94 deletions(-) diff --git a/bolt_transport_test.go b/bolt_transport_test.go index ac92877a..0e31a364 100644 --- a/bolt_transport_test.go +++ b/bolt_transport_test.go @@ -35,7 +35,7 @@ func TestBoltTransportHistory(t *testing.T) { }) } - s := NewSubscriber("8", transport.logger) + s := NewSubscriber("8", transport.logger, &TopicSelectorStore{}) s.SetTopics(topics, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -68,7 +68,7 @@ func TestBoltTransportLogsBogusLastEventID(t *testing.T) { Topics: topics, }) - s := NewSubscriber("711131", logger) + s := NewSubscriber("711131", logger, &TopicSelectorStore{}) s.SetTopics(topics, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -87,7 +87,7 @@ func TestBoltTopicSelectorHistory(t *testing.T) { transport.Dispatch(&Update{Topics: []string{"http://example.com/subscribed-public-only"}, Private: true, Event: Event{ID: "3"}}) transport.Dispatch(&Update{Topics: []string{"http://example.com/subscribed-public-only"}, Event: Event{ID: "4"}}) - s := NewSubscriber(EarliestLastEventID, transport.logger) + s := NewSubscriber(EarliestLastEventID, transport.logger, &TopicSelectorStore{}) s.SetTopics([]string{"http://example.com/subscribed", "http://example.com/subscribed-public-only"}, []string{"http://example.com/subscribed"}) require.NoError(t, transport.AddSubscriber(s)) @@ -109,7 +109,7 @@ func TestBoltTransportRetrieveAllHistory(t *testing.T) { }) } - s := NewSubscriber(EarliestLastEventID, transport.logger) + s := NewSubscriber(EarliestLastEventID, transport.logger, &TopicSelectorStore{}) s.SetTopics(topics, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -139,7 +139,7 @@ func TestBoltTransportHistoryAndLive(t *testing.T) { }) } - s := NewSubscriber("8", transport.logger) + s := NewSubscriber("8", transport.logger, &TopicSelectorStore{}) s.SetTopics(topics, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -221,7 +221,7 @@ func TestBoltTransportDoNotDispatchUntilListen(t *testing.T) { defer os.Remove("test.db") assert.Implements(t, (*Transport)(nil), transport) - s := NewSubscriber("", transport.logger) + s := NewSubscriber("", transport.logger, &TopicSelectorStore{}) require.NoError(t, transport.AddSubscriber(s)) var wg sync.WaitGroup @@ -245,7 +245,7 @@ func TestBoltTransportDispatch(t *testing.T) { defer os.Remove("test.db") assert.Implements(t, (*Transport)(nil), transport) - s := NewSubscriber("", transport.logger) + s := NewSubscriber("", transport.logger, &TopicSelectorStore{}) s.SetTopics([]string{"https://example.com/foo", "https://example.com/private"}, []string{"https://example.com/private"}) require.NoError(t, transport.AddSubscriber(s)) @@ -274,7 +274,7 @@ func TestBoltTransportClosed(t *testing.T) { defer os.Remove("test.db") assert.Implements(t, (*Transport)(nil), transport) - s := NewSubscriber("", transport.logger) + s := NewSubscriber("", transport.logger, &TopicSelectorStore{}) s.SetTopics([]string{"https://example.com/foo"}, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -293,11 +293,11 @@ func TestBoltCleanDisconnectedSubscribers(t *testing.T) { defer transport.Close() defer os.Remove("test.db") - s1 := NewSubscriber("", transport.logger) + s1 := NewSubscriber("", transport.logger, &TopicSelectorStore{}) s1.SetTopics([]string{"foo"}, []string{}) require.NoError(t, transport.AddSubscriber(s1)) - s2 := NewSubscriber("", transport.logger) + s2 := NewSubscriber("", transport.logger, &TopicSelectorStore{}) s2.SetTopics([]string{"foo"}, []string{}) require.NoError(t, transport.AddSubscriber(s2)) @@ -318,10 +318,10 @@ func TestBoltGetSubscribers(t *testing.T) { defer transport.Close() defer os.Remove("test.db") - s1 := NewSubscriber("", transport.logger) + s1 := NewSubscriber("", transport.logger, &TopicSelectorStore{}) require.NoError(t, transport.AddSubscriber(s1)) - s2 := NewSubscriber("", transport.logger) + s2 := NewSubscriber("", transport.logger, &TopicSelectorStore{}) require.NoError(t, transport.AddSubscriber(s2)) lastEventID, subscribers, err := transport.GetSubscribers() diff --git a/local_transport_bench_test.go b/local_transport_bench_test.go index e38cd699..78984356 100644 --- a/local_transport_bench_test.go +++ b/local_transport_bench_test.go @@ -39,8 +39,9 @@ func subBenchLocalTransport(b *testing.B, topics, concurrency, matchPct int, tes } } out := make(chan *Update, 50000) + tss := &TopicSelectorStore{} for i := 0; i < concurrency; i++ { - s := NewSubscriber("", zap.NewNop()) + s := NewSubscriber("", zap.NewNop(), tss) if i%100 < matchPct { s.SetTopics(tsMatch, nil) } else { diff --git a/local_transport_test.go b/local_transport_test.go index 14ba3721..964c5ec7 100644 --- a/local_transport_test.go +++ b/local_transport_test.go @@ -11,7 +11,8 @@ import ( ) func TestLocalTransportDoNotDispatchUntilListen(t *testing.T) { - transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) + logger := zap.NewNop() + transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, logger) defer transport.Close() assert.Implements(t, (*Transport)(nil), transport) @@ -19,7 +20,7 @@ func TestLocalTransportDoNotDispatchUntilListen(t *testing.T) { err := transport.Dispatch(u) require.NoError(t, err) - s := NewSubscriber("", zap.NewNop()) + s := NewSubscriber("", logger, &TopicSelectorStore{}) s.SetTopics(u.Topics, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -37,11 +38,12 @@ func TestLocalTransportDoNotDispatchUntilListen(t *testing.T) { } func TestLocalTransportDispatch(t *testing.T) { - transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) + logger := zap.NewNop() + transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, logger) defer transport.Close() assert.Implements(t, (*Transport)(nil), transport) - s := NewSubscriber("", zap.NewNop()) + s := NewSubscriber("", logger, &TopicSelectorStore{}) s.SetTopics([]string{"http://example.com/foo"}, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -51,14 +53,17 @@ func TestLocalTransportDispatch(t *testing.T) { } func TestLocalTransportClosed(t *testing.T) { - transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) + logger := zap.NewNop() + transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, logger) defer transport.Close() assert.Implements(t, (*Transport)(nil), transport) - s := NewSubscriber("", zap.NewNop()) + tss := &TopicSelectorStore{} + + s := NewSubscriber("", logger, tss) require.NoError(t, transport.AddSubscriber(s)) require.NoError(t, transport.Close()) - assert.Equal(t, transport.AddSubscriber(NewSubscriber("", zap.NewNop())), ErrClosedTransport) + assert.Equal(t, transport.AddSubscriber(NewSubscriber("", logger, tss)), ErrClosedTransport) assert.Equal(t, transport.Dispatch(&Update{}), ErrClosedTransport) _, ok := <-s.out @@ -66,14 +71,17 @@ func TestLocalTransportClosed(t *testing.T) { } func TestLiveCleanDisconnectedSubscribers(t *testing.T) { - tr, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) + logger := zap.NewNop() + tr, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, logger) transport := tr.(*LocalTransport) defer transport.Close() - s1 := NewSubscriber("", zap.NewNop()) + tss := &TopicSelectorStore{} + + s1 := NewSubscriber("", logger, tss) require.NoError(t, transport.AddSubscriber(s1)) - s2 := NewSubscriber("", zap.NewNop()) + s2 := NewSubscriber("", logger, tss) require.NoError(t, transport.AddSubscriber(s2)) assert.Equal(t, 2, transport.subscribers.Len()) @@ -88,11 +96,12 @@ func TestLiveCleanDisconnectedSubscribers(t *testing.T) { } func TestLiveReading(t *testing.T) { - transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) + logger := zap.NewNop() + transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, logger) defer transport.Close() assert.Implements(t, (*Transport)(nil), transport) - s := NewSubscriber("", zap.NewNop()) + s := NewSubscriber("", logger, &TopicSelectorStore{}) s.SetTopics([]string{"https://example.com"}, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -104,14 +113,17 @@ func TestLiveReading(t *testing.T) { } func TestLocalTransportGetSubscribers(t *testing.T) { - transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, zap.NewNop()) + logger := zap.NewNop() + transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, logger) defer transport.Close() require.NotNil(t, transport) - s1 := NewSubscriber("", zap.NewNop()) + tss := &TopicSelectorStore{} + + s1 := NewSubscriber("", logger, tss) require.NoError(t, transport.AddSubscriber(s1)) - s2 := NewSubscriber("", zap.NewNop()) + s2 := NewSubscriber("", logger, tss) require.NoError(t, transport.AddSubscriber(s2)) lastEventID, subscribers, err := transport.(TransportSubscribers).GetSubscribers() diff --git a/metrics_test.go b/metrics_test.go index ca183b34..88e82b8c 100644 --- a/metrics_test.go +++ b/metrics_test.go @@ -12,12 +12,15 @@ import ( func TestNumberOfRunningSubscribers(t *testing.T) { m := NewPrometheusMetrics(nil) - s1 := NewSubscriber("", zap.NewNop()) + logger := zap.NewNop() + tss := &TopicSelectorStore{} + + s1 := NewSubscriber("", logger, tss) s1.SetTopics([]string{"topic1", "topic2"}, nil) m.SubscriberConnected(s1) assertGaugeValue(t, 1.0, m.subscribers) - s2 := NewSubscriber("", zap.NewNop()) + s2 := NewSubscriber("", logger, tss) s2.SetTopics([]string{"topic2"}, nil) m.SubscriberConnected(s2) assertGaugeValue(t, 2.0, m.subscribers) @@ -32,12 +35,15 @@ func TestNumberOfRunningSubscribers(t *testing.T) { func TestTotalNumberOfHandledSubscribers(t *testing.T) { m := NewPrometheusMetrics(nil) - s1 := NewSubscriber("", zap.NewNop()) + logger := zap.NewNop() + tss := &TopicSelectorStore{} + + s1 := NewSubscriber("", logger, tss) s1.SetTopics([]string{"topic1", "topic2"}, nil) m.SubscriberConnected(s1) assertCounterValue(t, 1.0, m.subscribersTotal) - s2 := NewSubscriber("", zap.NewNop()) + s2 := NewSubscriber("", logger, tss) s2.SetTopics([]string{"topic2"}, nil) m.SubscriberConnected(s2) assertCounterValue(t, 2.0, m.subscribersTotal) diff --git a/publish_test.go b/publish_test.go index 38da318f..92dc2d16 100644 --- a/publish_test.go +++ b/publish_test.go @@ -174,7 +174,7 @@ func TestPublishOK(t *testing.T) { hub := createDummy() topics := []string{"http://example.com/books/1"} - s := NewSubscriber("", zap.NewNop()) + s := NewSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.SetTopics(topics, topics) s.Claims = &claims{Mercure: mercureClaim{Subscribe: topics}} @@ -238,7 +238,7 @@ func TestPublishNoData(t *testing.T) { func TestPublishGenerateUUID(t *testing.T) { h := createDummy() - s := NewSubscriber("", zap.NewNop()) + s := NewSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.SetTopics([]string{"http://example.com/books/1"}, s.SubscribedTopics) require.NoError(t, h.transport.AddSubscriber(s)) diff --git a/subscribe.go b/subscribe.go index 6ee9dd7e..476e83b9 100644 --- a/subscribe.go +++ b/subscribe.go @@ -156,7 +156,8 @@ func (h *Hub) SubscribeHandler(w http.ResponseWriter, r *http.Request) { // registerSubscriber initializes the connection. func (h *Hub) registerSubscriber(w http.ResponseWriter, r *http.Request) (*Subscriber, *responseController) { - s := NewSubscriber(retrieveLastEventID(r, h.opt, h.logger), h.logger) + s := NewSubscriber(retrieveLastEventID(r, h.opt, h.logger), h.logger, &TopicSelectorStore{}) + s.topicSelectorStore = h.topicSelectorStore s.Debug = h.debug s.RemoteAddr = r.RemoteAddr var privateTopics []string diff --git a/subscribe_test.go b/subscribe_test.go index ba39c2f3..24083513 100644 --- a/subscribe_test.go +++ b/subscribe_test.go @@ -3,6 +3,7 @@ package mercure import ( "context" "errors" + "fmt" "io" "net/http" "net/http/httptest" @@ -56,8 +57,13 @@ func (rt *responseTester) Write(buf []byte) (int, error) { if rt.body == rt.expectedBody { rt.cancel() } else if !strings.HasPrefix(rt.expectedBody, rt.body) { - rt.t.Errorf(`Received body "%s" doesn't match expected body "%s"`, rt.body, rt.expectedBody) - rt.cancel() + defer rt.cancel() + + mess := fmt.Sprintf(`Received body "%s" doesn't match expected body "%s"`, rt.body, rt.expectedBody) + if rt.t == nil { + panic(mess) + } + rt.t.Error(mess) } return len(buf), nil diff --git a/subscriber.go b/subscriber.go index 8edade9f..b22ac03b 100644 --- a/subscriber.go +++ b/subscriber.go @@ -8,7 +8,6 @@ import ( "sync/atomic" "github.com/gofrs/uuid" - uritemplate "github.com/yosida95/uritemplate/v3" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) @@ -35,12 +34,13 @@ type Subscriber struct { ready int32 liveQueue []*Update liveMutex sync.RWMutex + topicSelectorStore *TopicSelectorStore } const outBufferLength = 1000 // NewSubscriber creates a new subscriber. -func NewSubscriber(lastEventID string, logger Logger) *Subscriber { +func NewSubscriber(lastEventID string, logger Logger, topicSelectorStore *TopicSelectorStore) *Subscriber { id := "urn:uuid:" + uuid.Must(uuid.NewV4()).String() s := &Subscriber{ ID: id, @@ -49,6 +49,7 @@ func NewSubscriber(lastEventID string, logger Logger) *Subscriber { responseLastEventID: make(chan string, 1), out: make(chan *Update, outBufferLength), logger: logger, + topicSelectorStore: topicSelectorStore, } return s @@ -142,23 +143,7 @@ func (s *Subscriber) Disconnect() { // SetTopics compiles topic selector regexps. func (s *Subscriber) SetTopics(subscribedTopics, allowedPrivateTopics []string) { s.SubscribedTopics = subscribedTopics - s.SubscribedTopicRegexps = make([]*regexp.Regexp, len(subscribedTopics)) - for i, ts := range subscribedTopics { - var r *regexp.Regexp - if tpl, err := uritemplate.New(ts); err == nil { - r = tpl.Regexp() - } - s.SubscribedTopicRegexps[i] = r - } s.AllowedPrivateTopics = allowedPrivateTopics - s.AllowedPrivateRegexps = make([]*regexp.Regexp, len(allowedPrivateTopics)) - for i, ts := range allowedPrivateTopics { - var r *regexp.Regexp - if tpl, err := uritemplate.New(ts); err == nil { - r = tpl.Regexp() - } - s.AllowedPrivateRegexps[i] = r - } s.EscapedTopics = escapeTopics(subscribedTopics) } @@ -180,15 +165,8 @@ func (s *Subscriber) MatchTopics(topics []string, private bool) bool { for _, topic := range topics { if !subscribed { - for i, ts := range s.SubscribedTopics { - if ts == "*" || ts == topic { - subscribed = true - - break - } - - r := s.SubscribedTopicRegexps[i] - if r != nil && r.MatchString(topic) { + for _, ts := range s.SubscribedTopics { + if s.topicSelectorStore.match(topic, ts) { subscribed = true break @@ -197,28 +175,17 @@ func (s *Subscriber) MatchTopics(topics []string, private bool) bool { } if !canAccess { - for i, ts := range s.AllowedPrivateTopics { - if ts == "*" || ts == topic { - canAccess = true - - break - } - - r := s.AllowedPrivateRegexps[i] - if r != nil && r.MatchString(topic) { + for _, ts := range s.AllowedPrivateTopics { + if s.topicSelectorStore.match(topic, ts) { canAccess = true break } } } - - if subscribed && canAccess { - return true - } } - return false + return subscribed && canAccess } // Match checks if the current subscriber can receive the given update. diff --git a/subscriber_bench_test.go b/subscriber_bench_test.go index 3659a802..18cfd5d7 100644 --- a/subscriber_bench_test.go +++ b/subscriber_bench_test.go @@ -85,7 +85,7 @@ func strInt(s string) int { func subBenchSubscriber(b *testing.B, topics, concurrency, matchPct int, testName string) { b.Helper() - s := NewSubscriber("0e249241-6432-4ce1-b9b9-5d170163c253", zap.NewNop()) + s := NewSubscriber("0e249241-6432-4ce1-b9b9-5d170163c253", zap.NewNop(), &TopicSelectorStore{}) ts := make([]string, topics) tsMatch := make([]string, topics) tsNoMatch := make([]string, topics) diff --git a/subscriber_list_test.go b/subscriber_list_test.go index a52f6c76..a9e69834 100644 --- a/subscriber_list_test.go +++ b/subscriber_list_test.go @@ -22,10 +22,11 @@ func TestDecode(t *testing.T) { func BenchmarkSubscriberList(b *testing.B) { logger := zap.NewNop() + tss := &TopicSelectorStore{} l := NewSubscriberList(100) for i := 0; i < 100; i++ { - s := NewSubscriber("", logger) + s := NewSubscriber("", logger, tss) t := fmt.Sprintf("https://example.com/%d", (i % 10)) s.SetTopics([]string{"https://example.org/foo", t}, []string{"https://example.net/bar", t}) diff --git a/subscriber_test.go b/subscriber_test.go index 1432ada9..7c324b5f 100644 --- a/subscriber_test.go +++ b/subscriber_test.go @@ -9,7 +9,7 @@ import ( ) func TestDispatch(t *testing.T) { - s := NewSubscriber("1", zap.NewNop()) + s := NewSubscriber("1", zap.NewNop(), &TopicSelectorStore{}) s.SubscribedTopics = []string{"http://example.com"} s.SubscribedTopics = []string{"http://example.com"} defer s.Disconnect() @@ -32,7 +32,7 @@ func TestDispatch(t *testing.T) { } func TestDisconnect(t *testing.T) { - s := NewSubscriber("", zap.NewNop()) + s := NewSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.Disconnect() // can be called two times without crashing s.Disconnect() @@ -44,7 +44,7 @@ func TestLogSubscriber(t *testing.T) { sink, logger := newTestLogger(t) defer sink.Reset() - s := NewSubscriber("123", logger) + s := NewSubscriber("123", logger, &TopicSelectorStore{}) s.RemoteAddr = "127.0.0.1" s.SetTopics([]string{"https://example.com/bar"}, []string{"https://example.com/foo"}) @@ -59,7 +59,7 @@ func TestLogSubscriber(t *testing.T) { } func TestMatchTopic(t *testing.T) { - s := NewSubscriber("", zap.NewNop()) + s := NewSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.SetTopics([]string{"https://example.com/no-match", "https://example.com/books/{id}"}, []string{"https://example.com/users/foo/{?topic}"}) assert.False(t, s.Match(&Update{Topics: []string{"https://example.com/not-subscribed"}})) @@ -73,7 +73,7 @@ func TestMatchTopic(t *testing.T) { } func TestSubscriberDoesNotBlockWhenChanIsFull(t *testing.T) { - s := NewSubscriber("", zap.NewNop()) + s := NewSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.Ready() for i := 0; i <= outBufferLength; i++ { diff --git a/subscription_test.go b/subscription_test.go index b832265b..13363b8a 100644 --- a/subscription_test.go +++ b/subscription_test.go @@ -82,13 +82,16 @@ func TestSubscriptionHandlersETag(t *testing.T) { } func TestSubscriptionsHandler(t *testing.T) { - hub := createDummy() + logger := zap.NewNop() + + hub := createDummy(WithLogger(logger)) + tss := &TopicSelectorStore{} - s1 := NewSubscriber("", zap.NewNop()) + s1 := NewSubscriber("", logger, tss) s1.SetTopics([]string{"http://example.com/foo"}, nil) require.NoError(t, hub.transport.AddSubscriber(s1)) - s2 := NewSubscriber("", zap.NewNop()) + s2 := NewSubscriber("", logger, tss) s2.SetTopics([]string{"http://example.com/bar"}, nil) require.NoError(t, hub.transport.AddSubscriber(s2)) @@ -121,13 +124,15 @@ func TestSubscriptionsHandler(t *testing.T) { } func TestSubscriptionsHandlerForTopic(t *testing.T) { - hub := createDummy() + logger := zap.NewNop() + hub := createDummy(WithLogger(logger)) + tss := &TopicSelectorStore{} - s1 := NewSubscriber("", zap.NewNop()) + s1 := NewSubscriber("", logger, tss) s1.SetTopics([]string{"http://example.com/foo"}, nil) require.NoError(t, hub.transport.AddSubscriber(s1)) - s2 := NewSubscriber("", zap.NewNop()) + s2 := NewSubscriber("", logger, tss) s2.SetTopics([]string{"http://example.com/bar"}, nil) require.NoError(t, hub.transport.AddSubscriber(s2)) @@ -166,13 +171,15 @@ func TestSubscriptionsHandlerForTopic(t *testing.T) { } func TestSubscriptionHandler(t *testing.T) { - hub := createDummy() + logger := zap.NewNop() + hub := createDummy(WithLogger(logger)) + tss := &TopicSelectorStore{} - otherS := NewSubscriber("", zap.NewNop()) + otherS := NewSubscriber("", logger, tss) otherS.SetTopics([]string{"http://example.com/other"}, nil) require.NoError(t, hub.transport.AddSubscriber(otherS)) - s := NewSubscriber("", zap.NewNop()) + s := NewSubscriber("", logger, tss) s.SetTopics([]string{"http://example.com/other", "http://example.com/{foo}"}, nil) require.NoError(t, hub.transport.AddSubscriber(s)) From 849c7b399ba8ca2f0103d422c5b2c5c44b59afda Mon Sep 17 00:00:00 2001 From: coibib <45861541+coibib@users.noreply.github.com> Date: Mon, 9 Sep 2024 13:36:03 +0200 Subject: [PATCH 16/71] feat(helm): add support for metrics in the chart (#924) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add support for metrics in chart Signed-off-by: François BIBRON * feat: add serviceMonitor Signed-off-by: François BIBRON * feat: fix values Signed-off-by: François BIBRON * feat: fix values Signed-off-by: François BIBRON * feat: fix values Signed-off-by: François BIBRON * fix values and typos Signed-off-by: François Bibron * fix typo Signed-off-by: François Bibron * fix CS --------- Signed-off-by: François BIBRON Signed-off-by: François Bibron Co-authored-by: Kévin Dunglas --- charts/mercure/templates/deployment.yaml | 5 ++++ charts/mercure/templates/service.yaml | 24 +++++++++++++++++ charts/mercure/templates/serviceMonitor.yaml | 28 ++++++++++++++++++++ charts/mercure/values.yaml | 27 +++++++++++++++++-- 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 charts/mercure/templates/serviceMonitor.yaml diff --git a/charts/mercure/templates/deployment.yaml b/charts/mercure/templates/deployment.yaml index 1fa5577d..fc68b1b2 100644 --- a/charts/mercure/templates/deployment.yaml +++ b/charts/mercure/templates/deployment.yaml @@ -106,6 +106,11 @@ spec: - name: http containerPort: {{ .Values.service.targetPort }} protocol: TCP + {{- if .Values.metrics.enabled }} + - name: metrics + containerPort: {{ .Values.metrics.port }} + protocol: TCP + {{- end }} livenessProbe: httpGet: path: /healthz diff --git a/charts/mercure/templates/service.yaml b/charts/mercure/templates/service.yaml index 2490f8b3..3c87295c 100644 --- a/charts/mercure/templates/service.yaml +++ b/charts/mercure/templates/service.yaml @@ -18,3 +18,27 @@ spec: name: http selector: {{- include "mercure.selectorLabels" . | nindent 4 }} +--- +{{- if .Values.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "mercure.fullname" . }}-metrics + labels: + {{- include "mercure.labels" . | nindent 4 }} + app.kubernetes.io/component: metrics + {{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + +spec: + type: ClusterIP + ports: + - port: {{ .Values.metrics.port }} + targetPort: metrics + protocol: TCP + name: metrics + selector: + {{- include "mercure.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/charts/mercure/templates/serviceMonitor.yaml b/charts/mercure/templates/serviceMonitor.yaml new file mode 100644 index 00000000..39888d6e --- /dev/null +++ b/charts/mercure/templates/serviceMonitor.yaml @@ -0,0 +1,28 @@ +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "mercure.fullname" . }}-metrics + labels: + {{- include "mercure.labels" . | nindent 4 }} + app.kubernetes.io/component: metrics +spec: + selector: + matchLabels: + app.kubernetes.io/component: metrics + endpoints: + - port: metrics + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + honorLabels: {{ .Values.metrics.serviceMonitor.honorLabels }} + {{- if .Values.metrics.serviceMonitor.relabelings }} + metricRelabelings: {{- toYaml .Values.metrics.serviceMonitor.relabelings | nindent 8 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.relabelings }} + relabelings: {{- toYaml .Values.metrics.serviceMonitor.relabelings | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/mercure/values.yaml b/charts/mercure/values.yaml index 091c9fa9..8669ba2f 100644 --- a/charts/mercure/values.yaml +++ b/charts/mercure/values.yaml @@ -46,6 +46,29 @@ existingSecret: "" # -- The license key for [the High Availability version](https://mercure.rocks/docs/hub/cluster) (not necessary is you use the FOSS version). license: "" +metrics: + # -- Enable metrics. You must also add a `servers` block with a [`metrics` directive](https://caddyserver.com/docs/caddyfile/options#metrics) in the `globalOptions` value. + # servers { + # metrics + # } + enabled: false + # -- The port to use for exposing the metrics. + port: 2019 + + serviceMonitor: + # -- Whether to create a ServiceMonitor for Prometheus Operator. + enabled: false + # -- The interval to use for the ServiceMonitor to scrape the metrics. + interval: 15s + # -- Timeout after which the scrape is ended + scrapeTimeout: "" + # -- Additional labels that can be used so ServiceMonitor will be discovered by Prometheus + selector: {} + # -- RelabelConfigs to apply to samples before scraping + relabelings: [] + # -- Specify honorLabels parameter to add the scrape endpoint + honorLabels: false + # -- The number of replicas (pods) to launch, must be 1 unless you are using [the High Availability version](https://mercure.rocks/docs/hub/cluster). replicaCount: 1 @@ -114,8 +137,8 @@ ingress: hosts: - host: mercure-example.local paths: - - path: / - pathType: ImplementationSpecific + - path: / + pathType: ImplementationSpecific # -- Ingress TLS configuration. # @default -- See [values.yaml](values.yaml). tls: [] From 2ccc32f87bc196e115867bf592ebaf627f8c9fe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 5 Sep 2024 11:04:19 +0200 Subject: [PATCH 17/71] docs: recommend using Microsoft's fetch-event-source --- docs/ecosystem/awesome.md | 1 + docs/getting-started.md | 4 +++- docs/mercure.md | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/ecosystem/awesome.md b/docs/ecosystem/awesome.md index 0478ea79..e9084b73 100644 --- a/docs/ecosystem/awesome.md +++ b/docs/ecosystem/awesome.md @@ -45,6 +45,7 @@ ## Useful Related Libraries +* [Microsoft's Fetch Event Source, a better JavaScript API for making Event Source requests](https://github.com/Azure/fetch-event-source) * [`EventSource` polyfill for Edge/IE and old browsers](https://github.com/Yaffle/EventSource) * [`EventSource` polyfill for React Native](https://github.com/jordanbyron/react-native-event-source) * [`EventSource` implementation for Node](https://github.com/EventSource/eventsource) diff --git a/docs/getting-started.md b/docs/getting-started.md index d1844da9..36c8e71f 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -27,7 +27,9 @@ const eventSource = new EventSource(url); eventSource.onmessage = e => console.log(e); // do something with the payload ``` -The `EventSource` class is available [in all modern web browsers](https://caniuse.com/eventsource). And for legacy browsers, [there are polyfills](ecosystem/awesome.md#useful-related-libraries). +The `EventSource` class is available [in all modern web browsers](https://caniuse.com/eventsource). + +Although the native `EventSource` class is generally quite good, we recommend [Microsoft's `fetch-event-source` library](https://github.com/Azure/fetch-event-source) for advanced use cases, as it allows finer-grained error handling and supports authentication via the `Authorization` header. ## Closing Connection diff --git a/docs/mercure.md b/docs/mercure.md index db86bd62..6c3a4e65 100644 --- a/docs/mercure.md +++ b/docs/mercure.md @@ -18,7 +18,7 @@ A free (as in beer, and as in speech) reference server, a commercial High Availa * designed with [hypermedia in mind](https://en.wikipedia.org/wiki/HATEOAS), also supports [GraphQL](https://graphql.org/) * auto-discoverable through [web linking](https://tools.ietf.org/html/rfc5988) * message encryption support -* can work with old browsers (IE7+) using an `EventSource` polyfill +* can work with old browsers (IE7+) using [an `EventSource` polyfill](ecosystem/awesome.md#useful-related-libraries) * [connection-less push](https://html.spec.whatwg.org/multipage/server-sent-events.html#eventsource-push) in controlled environments (e.g. browsers on mobile handsets tied to specific carriers) [Read the specification](../spec/mercure.md) From 95d332dd37a75ab2eae7e6d54fac1ef3627f937a Mon Sep 17 00:00:00 2001 From: Erki Aring Date: Fri, 13 Sep 2024 10:33:45 +0300 Subject: [PATCH 18/71] feat: support ECDSA and Ed25519 JWT public keys --- jwt_keyfunc.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/jwt_keyfunc.go b/jwt_keyfunc.go index af2d8f0a..9c810383 100644 --- a/jwt_keyfunc.go +++ b/jwt_keyfunc.go @@ -23,6 +23,20 @@ func createJWTKeyfunc(key []byte, alg string) (jwt.Keyfunc, error) { return nil, fmt.Errorf("unable to parse RSA public key: %w", err) } + k = pub + case *jwt.SigningMethodECDSA: + pub, err := jwt.ParseECPublicKeyFromPEM(key) + if err != nil { + return nil, fmt.Errorf("unable to parse EC public key: %w", err) + } + + k = pub + case *jwt.SigningMethodEd25519: + pub, err := jwt.ParseEdPublicKeyFromPEM(key) + if err != nil { + return nil, fmt.Errorf("unable to parse Ed public key: %w", err) + } + k = pub default: return nil, fmt.Errorf("%T: %w", signingMethod, ErrUnexpectedSigningMethod) From f54b2b5551fea5e25cc67d390066b31d13c50334 Mon Sep 17 00:00:00 2001 From: Erki Aring Date: Sat, 14 Sep 2024 09:01:31 +0300 Subject: [PATCH 19/71] test: refactor authorization tests - removes code duplication - makes it easier to add tests for more algorithms --- authorization_test.go | 704 ++++++++++++++++++++++-------------------- 1 file changed, 365 insertions(+), 339 deletions(-) diff --git a/authorization_test.go b/authorization_test.go index a4eb82d6..0a0bfb3a 100644 --- a/authorization_test.go +++ b/authorization_test.go @@ -4,23 +4,10 @@ import ( "net/http" "testing" - "github.com/golang-jwt/jwt/v5" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -const ( - validEmptyHeader = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30._esyynAyo2Z6PyGe0mM_SuQ3c-C7sMQJ1YxVLvlj80A" - validFullHeader = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX19.e7USPnr2YHHqLYSu9-jEVsynuTXGtAQUDAZuzoR8lxQ" -) - -const ( - validEmptyHeaderRsa = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.e30.YbkSeO9GIBYedph1uSQz0Y6zp1NwDEB8O7ek3cc3Vw4Fjh6DwrJAwmXoNSqT6FhHDv14QG70qPIuyzsR0Q9nHFo7hGEqE8E85F8z3Pj5eBjHKBMJFno7jww514Vyp35c490ZHD6_d3F9PmxWrPkKezc1mcwlCegwiMJIS2CeR7k" - validFullHeaderRsa = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX19.B-ZBdmCbtDaP27wB_DvF9xIetQm88M2Q1d-LP2DZoEHrz6lYDuHkgXzSDnFdbLCZ653e0r_VOaKxe2Pc6R4F0ok2vksC6P5gHhqIUcQuTSlzNFyTrg4tyy4mMkcm1h85te9gkV4LR6TABfZpFPqqIS4t7fpCMxvtAkyf_RR5Fq4" - validFullHeaderRsaForCert = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkxIbzlPMmNNUzBqbzRsQWwtRk11ayJ9.eyJodHRwczovL21lcmN1cmUucm9ja3MvIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX0sImlzcyI6Imh0dHBzOi8vbWVyY3VyZS10ZXN0LmV1LmF1dGgwLmNvbS8iLCJzdWIiOiJhdXRoMHw1ZmRjM2U4OGUzYjA0YjAwNzZhNTQxM2MiLCJhdWQiOlsiaHR0cHM6Ly9tZXJjdXJlLnJvY2tzL2FwaSIsImh0dHBzOi8vbWVyY3VyZS10ZXN0LmV1LmF1dGgwLmNvbS91c2VyaW5mbyJdLCJpYXQiOjE2MDgyNzAxMTQsImF6cCI6IjMwMWh6bUJBMnZ5ZzdnSlZiSEVMUlRDell0dUJrVU52Iiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCJ9.QAZKFSYpDJ39Cln-khjyjVzKJkiSCO4o9qIzw395fuP09rPfoLYcbdEoWg_pHN6GqO6oDNr9I2RR7p0FGhZAamXVtZzSd2V8Fv-BM0TfUBeJbb0sCMaSA2Nv3izs2dk_0zoQjGFH_LSNExGkJjwKLBj059GT6o_abtr2iz_77A8" - validFullHeaderNamespacedRsa = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczovL21lcmN1cmUucm9ja3MvIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX19.SmTVZkxlNbzHlaF4MfA3Fp5d1W2COmHlYPgc6SodAJOQtHh1Uxz0jkhA611w0OSwCaA8C5gqUd-GgekgHVPCBkIzV0qPmmhhJpTtotkeCX3N7oBOJOi58xXouNCNt0vnUH6xACqiZJq_FhNG9ZqP5saa4xNd1E-F1E9Vo1mFji4" -) - const publicKeyRsa = `-----BEGIN PUBLIC KEY----- MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHVwuJsFmzsFnOkGj+OgAp4lTNqR CF0RZSmjY+ECWOJ3sSEzQ8qtkJe61uSjr/PKmqvBxxex0YtUL7waSS4jvq3ws8Bm @@ -65,470 +52,509 @@ Utb8p35tfj97usdiEB0AN8ray4wZbVWj -----END CERTIFICATE----- ` -var keyfuncHS256 = func() jwt.Keyfunc { - keyfunc, _ := createJWTKeyfunc([]byte("!ChangeMe!"), "HS256") - - return keyfunc -}() - -var keyfuncRS256publicKey = func() jwt.Keyfunc { - keyfunc, _ := createJWTKeyfunc([]byte(publicKeyRsa), "RS256") - - return keyfunc -}() - -func TestAuthorizeMultipleAuthorizationHeader(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.Header.Add("Authorization", validEmptyHeader) - r.Header.Add("Authorization", validEmptyHeader) - - keyfunc, _ := createJWTKeyfunc([]byte{}, "HS256") - - claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) - require.Error(t, err, `invalid "Authorization" HTTP header`) - require.Nil(t, claims) +type AuthorizationTestData struct { + algorithm string + privateKey string + publicKey string + certificate string + validEmpty string + valid string + validForCert string + validNamespaced string +} + +var AuthTestData = []AuthorizationTestData{ + { + algorithm: "HS256", + privateKey: "!ChangeMe!", + publicKey: "!ChangeMe!", + certificate: "", + validEmpty: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30._esyynAyo2Z6PyGe0mM_SuQ3c-C7sMQJ1YxVLvlj80A", + valid: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX19.e7USPnr2YHHqLYSu9-jEVsynuTXGtAQUDAZuzoR8lxQ", + validForCert: "", + validNamespaced: "", + }, + { + algorithm: "RS256", + privateKey: privateKeyRsa, + publicKey: publicKeyRsa, + certificate: certificateRsa, + validEmpty: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.e30.YbkSeO9GIBYedph1uSQz0Y6zp1NwDEB8O7ek3cc3Vw4Fjh6DwrJAwmXoNSqT6FhHDv14QG70qPIuyzsR0Q9nHFo7hGEqE8E85F8z3Pj5eBjHKBMJFno7jww514Vyp35c490ZHD6_d3F9PmxWrPkKezc1mcwlCegwiMJIS2CeR7k", + valid: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX19.B-ZBdmCbtDaP27wB_DvF9xIetQm88M2Q1d-LP2DZoEHrz6lYDuHkgXzSDnFdbLCZ653e0r_VOaKxe2Pc6R4F0ok2vksC6P5gHhqIUcQuTSlzNFyTrg4tyy4mMkcm1h85te9gkV4LR6TABfZpFPqqIS4t7fpCMxvtAkyf_RR5Fq4", + validForCert: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkxIbzlPMmNNUzBqbzRsQWwtRk11ayJ9.eyJodHRwczovL21lcmN1cmUucm9ja3MvIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX0sImlzcyI6Imh0dHBzOi8vbWVyY3VyZS10ZXN0LmV1LmF1dGgwLmNvbS8iLCJzdWIiOiJhdXRoMHw1ZmRjM2U4OGUzYjA0YjAwNzZhNTQxM2MiLCJhdWQiOlsiaHR0cHM6Ly9tZXJjdXJlLnJvY2tzL2FwaSIsImh0dHBzOi8vbWVyY3VyZS10ZXN0LmV1LmF1dGgwLmNvbS91c2VyaW5mbyJdLCJpYXQiOjE2MDgyNzAxMTQsImF6cCI6IjMwMWh6bUJBMnZ5ZzdnSlZiSEVMUlRDell0dUJrVU52Iiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCJ9.QAZKFSYpDJ39Cln-khjyjVzKJkiSCO4o9qIzw395fuP09rPfoLYcbdEoWg_pHN6GqO6oDNr9I2RR7p0FGhZAamXVtZzSd2V8Fv-BM0TfUBeJbb0sCMaSA2Nv3izs2dk_0zoQjGFH_LSNExGkJjwKLBj059GT6o_abtr2iz_77A8", + validNamespaced: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczovL21lcmN1cmUucm9ja3MvIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX19.SmTVZkxlNbzHlaF4MfA3Fp5d1W2COmHlYPgc6SodAJOQtHh1Uxz0jkhA611w0OSwCaA8C5gqUd-GgekgHVPCBkIzV0qPmmhhJpTtotkeCX3N7oBOJOi58xXouNCNt0vnUH6xACqiZJq_FhNG9ZqP5saa4xNd1E-F1E9Vo1mFji4", + }, } -func TestAuthorizeMultipleAuthorizationHeaderRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.Header.Add("Authorization", validEmptyHeaderRsa) - r.Header.Add("Authorization", validEmptyHeaderRsa) +func TestAuthorizeMultipleAuthorizationHeader(t *testing.T) { + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.Header.Add("Authorization", testdata.validEmpty) + r.Header.Add("Authorization", testdata.validEmpty) - keyfunc, _ := createJWTKeyfunc([]byte{}, "RS256") + keyfunc, _ := createJWTKeyfunc([]byte{}, testdata.algorithm) - claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) - require.Error(t, err, `invalid "Authorization" HTTP header`) - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.EqualError(t, err, `invalid "Authorization" HTTP header`, testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } func TestAuthorizeAuthorizationHeaderTooShort(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.Header.Add("Authorization", "Bearer x") + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.Header.Add("Authorization", "Bearer x") - keyfunc, _ := createJWTKeyfunc([]byte{}, "HS256") + keyfunc, _ := createJWTKeyfunc([]byte{}, testdata.algorithm) - claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) - require.Error(t, err, `invalid "Authorization" HTTP header`) - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.EqualError(t, err, `invalid "Authorization" HTTP header`, testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } func TestAuthorizeAuthorizationHeaderNoBearer(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.Header.Add("Authorization", "Greater "+validEmptyHeader) + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.Header.Add("Authorization", "Greater "+testdata.validEmpty) - keyfunc, _ := createJWTKeyfunc([]byte{}, "HS256") + keyfunc, _ := createJWTKeyfunc([]byte{}, testdata.algorithm) - claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) - require.EqualError(t, err, `invalid "Authorization" HTTP header`) - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.EqualError(t, err, `invalid "Authorization" HTTP header`, testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } -func TestAuthorizeAuthorizationHeaderNoBearerRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.Header.Add("Authorization", "Greater "+validEmptyHeaderRsa) +func TestAuthorizeAuthorizationHeaderInvalidAlg(t *testing.T) { + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.Header.Add("Authorization", bearerPrefix+createDummyNoneSignedJWT()) - keyfunc, _ := createJWTKeyfunc([]byte{}, "RS256") + keyfunc, _ := createJWTKeyfunc([]byte{}, testdata.algorithm) - claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) - require.EqualError(t, err, `invalid "Authorization" HTTP header`) - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.Error(t, err, testdata.algorithm) + require.Regexp(t, "^unable to parse JWT: token is unverifiable: ", err.Error(), testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } -func TestAuthorizeAuthorizationHeaderInvalidAlg(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.Header.Add("Authorization", bearerPrefix+createDummyNoneSignedJWT()) +func TestAuthorizeAuthorizationHeaderInvalidKey(t *testing.T) { + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.Header.Add("Authorization", bearerPrefix+testdata.validEmpty) - keyfunc, _ := createJWTKeyfunc([]byte{}, "HS256") + keyfunc, _ := createJWTKeyfunc([]byte{}, testdata.algorithm) - claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) - require.EqualError(t, err, "unable to parse JWT: token is unverifiable: error while executing keyfunc: *jwt.signingMethodNone: unexpected signing method") - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.Error(t, err, testdata.algorithm) + require.Regexp(t, "^unable to parse JWT: ", err.Error(), testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } -func TestAuthorizeAuthorizationHeaderInvalidKey(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.Header.Add("Authorization", bearerPrefix+validEmptyHeader) +func TestAuthorizeAuthorizationHeaderInvalidSignature(t *testing.T) { + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.Header.Add("Authorization", bearerPrefix+testdata.validEmpty[:len(testdata.validEmpty)-8]+"12345678") - keyfunc, _ := createJWTKeyfunc([]byte{}, "HS256") + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) - require.EqualError(t, err, "unable to parse JWT: token signature is invalid: signature is invalid") - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.Error(t, err, testdata.algorithm) + require.Regexp(t, "^unable to parse JWT: token signature is invalid: ", err.Error(), testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } func TestAuthorizeAuthorizationHeaderNoContent(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.Header.Add("Authorization", bearerPrefix+validEmptyHeader) + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.Header.Add("Authorization", bearerPrefix+testdata.validEmpty) - claims, err := authorize(r, keyfuncHS256, []string{}, defaultCookieName) - require.NoError(t, err) - require.Nil(t, claims.Mercure.Publish) - require.Nil(t, claims.Mercure.Subscribe) -} - -func TestAuthorizeAuthorizationHeaderNoContentRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.Header.Add("Authorization", bearerPrefix+validEmptyHeaderRsa) + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfuncRS256publicKey, []string{}, defaultCookieName) - require.NoError(t, err) - require.Nil(t, claims.Mercure.Publish) - require.Nil(t, claims.Mercure.Subscribe) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.NoError(t, err, testdata.algorithm) + require.Nil(t, claims.Mercure.Publish, testdata.algorithm) + require.Nil(t, claims.Mercure.Subscribe, testdata.algorithm) + } } func TestAuthorizeAuthorizationHeader(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.Header.Add("Authorization", bearerPrefix+validFullHeader) - - claims, err := authorize(r, keyfuncHS256, []string{}, defaultCookieName) - require.NoError(t, err) - assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) - assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) -} + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.Header.Add("Authorization", bearerPrefix+testdata.valid) -func TestAuthorizeAuthorizationHeaderRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.Header.Add("Authorization", bearerPrefix+validFullHeaderRsa) + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfuncRS256publicKey, []string{}, defaultCookieName) - require.NoError(t, err) - assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) - assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.NoError(t, err, testdata.algorithm) + assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) + assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + } } -func TestAuthorizeAuthorizationHeaderNamespacedRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.Header.Add("Authorization", bearerPrefix+validFullHeaderNamespacedRsa) +func TestAuthorizeAuthorizationHeaderWithCert(t *testing.T) { + for _, testdata := range AuthTestData { + if testdata.validForCert != "" { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.Header.Add("Authorization", bearerPrefix+testdata.validForCert) + + keyfunc, _ := createJWTKeyfunc([]byte(testdata.certificate), testdata.algorithm) - claims, err := authorize(r, keyfuncRS256publicKey, []string{}, defaultCookieName) - require.NoError(t, err) - assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) - assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.NoError(t, err, testdata.algorithm) + assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) + assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + } + } } -func TestAuthorizeAuthorizationHeaderRsaWithCert(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.Header.Add("Authorization", bearerPrefix+validFullHeaderRsaForCert) +func TestAuthorizeAuthorizationHeaderNamespaced(t *testing.T) { + for _, testdata := range AuthTestData { + if testdata.validNamespaced != "" { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.Header.Add("Authorization", bearerPrefix+testdata.validNamespaced) - keyfunc, _ := createJWTKeyfunc([]byte(certificateRsa), "RS256") + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) - require.NoError(t, err) - assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) - assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.NoError(t, err, testdata.algorithm) + assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) + assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + } + } } func TestAuthorizeAuthorizationHeaderWrongAlgorithm(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.Header.Add("Authorization", bearerPrefix+validFullHeaderRsa) + for idx, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.Header.Add("Authorization", bearerPrefix+testdata.valid) + + nextIdx := (idx + 1) % len(AuthTestData) + keyfunc, _ := createJWTKeyfunc([]byte(AuthTestData[nextIdx].publicKey), AuthTestData[nextIdx].algorithm) - claims, err := authorize(r, keyfuncHS256, []string{}, defaultCookieName) - require.EqualError(t, err, "unable to parse JWT: token is unverifiable: error while executing keyfunc: *jwt.SigningMethodRSA: unexpected signing method") - assert.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.Error(t, err, testdata.algorithm) + require.Regexp(t, "^unable to parse JWT: token is unverifiable: error while executing keyfunc: (.*): unexpected signing method$", err.Error()) + assert.Nil(t, claims) + } } func TestAuthorizeAuthorizationQueryTooShort(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - query := r.URL.Query() - query.Set("authorization", "x") - r.URL.RawQuery = query.Encode() + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + query := r.URL.Query() + query.Set("authorization", "x") + r.URL.RawQuery = query.Encode() - keyfunc, _ := createJWTKeyfunc([]byte{}, "HS256") + keyfunc, _ := createJWTKeyfunc([]byte{}, testdata.algorithm) - claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) - require.EqualError(t, err, `invalid "authorization" Query parameter`) - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.EqualError(t, err, `invalid "authorization" Query parameter`, testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } func TestAuthorizeAuthorizationQueryInvalidAlg(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - query := r.URL.Query() - query.Set("authorization", createDummyNoneSignedJWT()) - r.URL.RawQuery = query.Encode() + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + query := r.URL.Query() + query.Set("authorization", createDummyNoneSignedJWT()) + r.URL.RawQuery = query.Encode() - keyfunc, _ := createJWTKeyfunc([]byte{}, "HS256") + keyfunc, _ := createJWTKeyfunc([]byte{}, testdata.algorithm) - claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) - require.EqualError(t, err, "unable to parse JWT: token is unverifiable: error while executing keyfunc: *jwt.signingMethodNone: unexpected signing method") - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.Error(t, err, testdata.algorithm) + require.Regexp(t, "^unable to parse JWT: token is unverifiable: ", err.Error(), testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } func TestAuthorizeAuthorizationQueryInvalidKey(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - query := r.URL.Query() - query.Set("authorization", validEmptyHeader) - r.URL.RawQuery = query.Encode() + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + query := r.URL.Query() + query.Set("authorization", testdata.validEmpty) + r.URL.RawQuery = query.Encode() - keyfunc, _ := createJWTKeyfunc([]byte{}, "HS256") + keyfunc, _ := createJWTKeyfunc([]byte{}, testdata.algorithm) - claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) - require.EqualError(t, err, "unable to parse JWT: token signature is invalid: signature is invalid") - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.Error(t, err, testdata.algorithm) + require.Regexp(t, "^unable to parse JWT: ", err.Error(), testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } -func TestAuthorizeAuthorizationQueryNoContent(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - query := r.URL.Query() - query.Set("authorization", validEmptyHeader) - r.URL.RawQuery = query.Encode() +func TestAuthorizeAuthorizationQueryInvalidSignature(t *testing.T) { + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + query := r.URL.Query() + query.Set("authorization", testdata.validEmpty[:len(testdata.validEmpty)-8]+"12345678") + r.URL.RawQuery = query.Encode() + + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfuncHS256, []string{}, defaultCookieName) - require.NoError(t, err) - require.Nil(t, claims.Mercure.Publish) - require.Nil(t, claims.Mercure.Subscribe) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.Error(t, err, testdata.algorithm) + require.Regexp(t, "^unable to parse JWT: token signature is invalid: ", err.Error(), testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } -func TestAuthorizeAuthorizationQueryNoContentRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - query := r.URL.Query() - query.Set("authorization", validEmptyHeaderRsa) - r.URL.RawQuery = query.Encode() +func TestAuthorizeAuthorizationQueryNoContent(t *testing.T) { + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + query := r.URL.Query() + query.Set("authorization", testdata.validEmpty) + r.URL.RawQuery = query.Encode() - claims, err := authorize(r, keyfuncRS256publicKey, []string{}, defaultCookieName) - require.NoError(t, err) - require.Nil(t, claims.Mercure.Publish) - require.Nil(t, claims.Mercure.Subscribe) + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) + + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.NoError(t, err, testdata.algorithm) + require.Nil(t, claims.Mercure.Publish, testdata.algorithm) + require.Nil(t, claims.Mercure.Subscribe, testdata.algorithm) + } } func TestAuthorizeAuthorizationQuery(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - query := r.URL.Query() - query.Set("authorization", validFullHeader) - r.URL.RawQuery = query.Encode() - - claims, err := authorize(r, keyfuncHS256, []string{}, defaultCookieName) - require.NoError(t, err) - assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) - assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) -} + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + query := r.URL.Query() + query.Set("authorization", testdata.valid) + r.URL.RawQuery = query.Encode() -func TestAuthorizeAuthorizationQueryRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - query := r.URL.Query() - query.Set("authorization", validFullHeaderRsa) - r.URL.RawQuery = query.Encode() + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfuncRS256publicKey, []string{}, defaultCookieName) - require.NoError(t, err) - assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) - assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.NoError(t, err, testdata.algorithm) + assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) + assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + } } -func TestAuthorizeAuthorizationQueryNamespacedRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - query := r.URL.Query() - query.Set("authorization", validFullHeaderNamespacedRsa) - r.URL.RawQuery = query.Encode() +func TestAuthorizeAuthorizationQueryNamespaced(t *testing.T) { + for _, testdata := range AuthTestData { + if testdata.validNamespaced != "" { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + query := r.URL.Query() + query.Set("authorization", testdata.validNamespaced) + r.URL.RawQuery = query.Encode() - claims, err := authorize(r, keyfuncRS256publicKey, []string{}, defaultCookieName) - require.NoError(t, err) - assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) - assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) + + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.NoError(t, err, testdata.algorithm) + assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) + assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + } + } } func TestAuthorizeAuthorizationQueryRsaWithCert(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - query := r.URL.Query() - query.Set("authorization", validFullHeaderRsaForCert) - r.URL.RawQuery = query.Encode() + for _, testdata := range AuthTestData { + if testdata.validForCert != "" { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + query := r.URL.Query() + query.Set("authorization", testdata.validForCert) + r.URL.RawQuery = query.Encode() - keyfunc, _ := createJWTKeyfunc([]byte(certificateRsa), "RS256") + keyfunc, _ := createJWTKeyfunc([]byte(testdata.certificate), testdata.algorithm) - claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) - require.NoError(t, err) - assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) - assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.NoError(t, err, testdata.algorithm) + assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) + assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + } + } } func TestAuthorizeAuthorizationQueryWrongAlgorithm(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - query := r.URL.Query() - query.Set("authorization", validFullHeaderRsa) - r.URL.RawQuery = query.Encode() + for idx, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + query := r.URL.Query() + query.Set("authorization", testdata.valid) + r.URL.RawQuery = query.Encode() + + nextIdx := (idx + 1) % len(AuthTestData) + keyfunc, _ := createJWTKeyfunc([]byte(AuthTestData[nextIdx].publicKey), AuthTestData[nextIdx].algorithm) - claims, err := authorize(r, keyfuncHS256, []string{}, defaultCookieName) - require.EqualError(t, err, "unable to parse JWT: token is unverifiable: error while executing keyfunc: *jwt.SigningMethodRSA: unexpected signing method") - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.Error(t, err, testdata.algorithm) + require.Regexp(t, "^unable to parse JWT: token is unverifiable: error while executing keyfunc: (.*): unexpected signing method$", err.Error(), testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } func TestAuthorizeCookieInvalidAlg(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: createDummyNoneSignedJWT()}) + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: createDummyNoneSignedJWT()}) + + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfuncHS256, []string{}, defaultCookieName) - require.EqualError(t, err, "unable to parse JWT: token is unverifiable: error while executing keyfunc: *jwt.signingMethodNone: unexpected signing method") - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.EqualError(t, err, "unable to parse JWT: token is unverifiable: error while executing keyfunc: *jwt.signingMethodNone: unexpected signing method", testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } func TestAuthorizeCookieInvalidKey(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validEmptyHeader}) + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.validEmpty}) - keyfunc, _ := createJWTKeyfunc([]byte{}, "HS256") + keyfunc, _ := createJWTKeyfunc([]byte{}, testdata.algorithm) - claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) - require.EqualError(t, err, "unable to parse JWT: token signature is invalid: signature is invalid") - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.Error(t, err, testdata.algorithm) + require.Regexp(t, "^unable to parse JWT: ", err.Error(), testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } -func TestAuthorizeCookieNoContent(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validEmptyHeader}) +func TestAuthorizeCookieInvalidSignature(t *testing.T) { + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.validEmpty[:len(testdata.validEmpty)-8] + "12345678"}) + + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfuncHS256, []string{}, defaultCookieName) - require.NoError(t, err) - require.Nil(t, claims.Mercure.Publish) - require.Nil(t, claims.Mercure.Subscribe) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.Error(t, err, testdata.algorithm) + require.Regexp(t, "^unable to parse JWT: token signature is invalid: ", err.Error(), testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } -func TestAuthorizeCookieNoContentRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validEmptyHeaderRsa}) +func TestAuthorizeCookieNoContent(t *testing.T) { + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.validEmpty}) + + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfuncRS256publicKey, []string{}, defaultCookieName) - require.NoError(t, err) - require.Nil(t, claims.Mercure.Publish) - require.Nil(t, claims.Mercure.Subscribe) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.NoError(t, err, testdata.algorithm) + require.Nil(t, claims.Mercure.Publish, testdata.algorithm) + require.Nil(t, claims.Mercure.Subscribe, testdata.algorithm) + } } func TestAuthorizeCookie(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validFullHeader}) - - claims, err := authorize(r, keyfuncHS256, []string{}, defaultCookieName) - require.NoError(t, err) - assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) - assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) -} + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) + r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.valid}) -func TestAuthorizeCookieRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validFullHeaderRsa}) + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfuncRS256publicKey, []string{}, defaultCookieName) - require.NoError(t, err) - assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) - assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.NoError(t, err, testdata.algorithm) + assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) + assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + } } func TestAuthorizeCookieNoOriginNoReferer(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validFullHeader}) + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) + r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.valid}) - claims, err := authorize(r, keyfuncHS256, []string{}, defaultCookieName) - require.EqualError(t, err, `an "Origin" or a "Referer" HTTP header must be present to use the cookie-based authorization mechanism`) - require.Nil(t, claims) -} - -func TestAuthorizeCookieNoOriginNoRefererRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validFullHeaderRsa}) + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfuncRS256publicKey, []string{}, defaultCookieName) - require.EqualError(t, err, `an "Origin" or a "Referer" HTTP header must be present to use the cookie-based authorization mechanism`) - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{}, defaultCookieName) + require.EqualError(t, err, `an "Origin" or a "Referer" HTTP header must be present to use the cookie-based authorization mechanism`, testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } func TestAuthorizeCookieOriginNotAllowed(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) - r.Header.Add("Origin", "http://example.com") - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validFullHeader}) - - claims, err := authorize(r, keyfuncHS256, []string{"http://example.net"}, defaultCookieName) - require.EqualError(t, err, `"http://example.com": origin not allowed to post updates`) - require.Nil(t, claims) -} + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) + r.Header.Add("Origin", "http://example.com") + r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.valid}) -func TestAuthorizeCookieOriginNotAllowedRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) - r.Header.Add("Origin", "http://example.com") - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validFullHeaderRsa}) + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfuncRS256publicKey, []string{"http://example.net"}, defaultCookieName) - require.EqualError(t, err, `"http://example.com": origin not allowed to post updates`) - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{"http://example.net"}, defaultCookieName) + require.EqualError(t, err, `"http://example.com": origin not allowed to post updates`, testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } func TestAuthorizeCookieRefererNotAllowed(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) - r.Header.Add("Referer", "http://example.com/foo/bar") - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validFullHeader}) - - claims, err := authorize(r, keyfuncHS256, []string{"http://example.net"}, defaultCookieName) - require.EqualError(t, err, `"http://example.com": origin not allowed to post updates`) - require.Nil(t, claims) -} + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) + r.Header.Add("Referer", "http://example.com/foo/bar") + r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.valid}) -func TestAuthorizeCookieRefererNotAllowedRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) - r.Header.Add("Referer", "http://example.com/foo/bar") - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validFullHeaderRsa}) + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfuncRS256publicKey, []string{"http://example.net"}, defaultCookieName) - require.EqualError(t, err, `"http://example.com": origin not allowed to post updates`) - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{"http://example.net"}, defaultCookieName) + require.EqualError(t, err, `"http://example.com": origin not allowed to post updates`, testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } func TestAuthorizeCookieInvalidReferer(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) - r.Header.Add("Referer", "http://192.168.0.%31/") - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validFullHeader}) + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) + r.Header.Add("Referer", "http://192.168.0.%31/") + r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.valid}) - claims, err := authorize(r, keyfuncHS256, []string{"http://example.net"}, defaultCookieName) - require.EqualError(t, err, `unable to parse referer: parse "http://192.168.0.%31/": invalid URL escape "%31"`) - require.Nil(t, claims) -} - -func TestAuthorizeCookieInvalidRefererRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) - r.Header.Add("Referer", "http://192.168.0.%31/") - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validFullHeaderRsa}) + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfuncRS256publicKey, []string{"http://example.net"}, defaultCookieName) - require.EqualError(t, err, `unable to parse referer: parse "http://192.168.0.%31/": invalid URL escape "%31"`) - require.Nil(t, claims) + claims, err := authorize(r, keyfunc, []string{"http://example.net"}, defaultCookieName) + require.EqualError(t, err, `unable to parse referer: parse "http://192.168.0.%31/": invalid URL escape "%31"`, testdata.algorithm) + require.Nil(t, claims, testdata.algorithm) + } } func TestAuthorizeCookieOriginHasPriority(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) - r.Header.Add("Origin", "http://example.net") - r.Header.Add("Referer", "http://example.com") - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validFullHeader}) - - claims, err := authorize(r, keyfuncHS256, []string{"http://example.net"}, defaultCookieName) - require.NoError(t, err) - assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) - assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) -} + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) + r.Header.Add("Origin", "http://example.net") + r.Header.Add("Referer", "http://example.com") + r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.valid}) -func TestAuthorizeCookieOriginHasPriorityRsa(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) - r.Header.Add("Origin", "http://example.net") - r.Header.Add("Referer", "http://example.com") - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validFullHeaderRsa}) + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - claims, err := authorize(r, keyfuncRS256publicKey, []string{"http://example.net"}, defaultCookieName) - require.NoError(t, err) - assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) - assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + claims, err := authorize(r, keyfunc, []string{"http://example.net"}, defaultCookieName) + require.NoError(t, err, testdata.algorithm) + assert.Equal(t, []string{"foo", "bar"}, claims.Mercure.Publish) + assert.Equal(t, []string{"foo", "baz"}, claims.Mercure.Subscribe) + } } func TestAuthorizeAllOriginsAllowed(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) - r.Header.Add("Origin", "http://example.com") - r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: validFullHeader}) + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) + r.Header.Add("Origin", "http://example.com") + r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.valid}) + + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - _, err := authorize(r, keyfuncHS256, []string{"*"}, defaultCookieName) - require.NoError(t, err) + _, err := authorize(r, keyfunc, []string{"*"}, defaultCookieName) + require.NoError(t, err, testdata.algorithm) + } } func TestAuthorizeCustomCookieName(t *testing.T) { - r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) - r.Header.Add("Origin", "http://example.com") - r.AddCookie(&http.Cookie{Name: "foo", Value: validFullHeader}) + for _, testdata := range AuthTestData { + r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) + r.Header.Add("Origin", "http://example.com") + r.AddCookie(&http.Cookie{Name: "foo", Value: testdata.valid}) + + keyfunc, _ := createJWTKeyfunc([]byte(testdata.publicKey), testdata.algorithm) - _, err := authorize(r, keyfuncHS256, []string{"*"}, "foo") - require.NoError(t, err) + _, err := authorize(r, keyfunc, []string{"*"}, "foo") + require.NoError(t, err, testdata.algorithm) + } } func TestCanReceive(t *testing.T) { From 546eb357e2f919159dfbb16f4a5472985ed84884 Mon Sep 17 00:00:00 2001 From: Erki Aring Date: Sat, 14 Sep 2024 10:49:22 +0300 Subject: [PATCH 20/71] test: add ECDSA and Ed25519 authentication tests --- authorization_test.go | 80 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/authorization_test.go b/authorization_test.go index 0a0bfb3a..de5728b5 100644 --- a/authorization_test.go +++ b/authorization_test.go @@ -52,6 +52,64 @@ Utb8p35tfj97usdiEB0AN8ray4wZbVWj -----END CERTIFICATE----- ` +const publicKeyEcdsa = `-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOnSJ6Iht/FleVEz4s3ZFGcWQCM/I +rX2Ld/0veRv8vTAm3NU/fErGzL/raNhOxt+BcXqZ6IpQQ4aWOFZh3hDd+Q== +-----END PUBLIC KEY----- +` + +//nolint:gosec +const privateKeyEcdsa = `-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIDZCo0gXrI9bKtspq8mLSrQ7BrGRm4WQylp4V2tx4MewoAoGCCqGSM49 +AwEHoUQDQgAEOnSJ6Iht/FleVEz4s3ZFGcWQCM/IrX2Ld/0veRv8vTAm3NU/fErG +zL/raNhOxt+BcXqZ6IpQQ4aWOFZh3hDd+Q== +-----END EC PRIVATE KEY----- +` + +const certificateEcdsa = `-----BEGIN CERTIFICATE----- +MIICYjCCAgmgAwIBAgIUXRW9kusU+9K8dehUwIMiRYfJjC8wCgYIKoZIzj0EAwIw +gYUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1T +YW4gRnJhbmNpc2NvMRIwEAYDVQQKDAlBY21lLCBJbmMxFDASBgNVBAMMC2V4YW1w +bGUuY29tMR8wHQYJKoZIhvcNAQkBFhBhY21lQGV4YW1wbGUuY29tMCAXDTI0MDkx +NDA3MjEzM1oYDzMwMjAwODIzMDcyMTMzWjCBhTELMAkGA1UEBhMCVVMxEzARBgNV +BAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xEjAQBgNVBAoM +CUFjbWUsIEluYzEUMBIGA1UEAwwLZXhhbXBsZS5jb20xHzAdBgkqhkiG9w0BCQEW +EGFjbWVAZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ6dIno +iG38WV5UTPizdkUZxZAIz8itfYt3/S95G/y9MCbc1T98SsbMv+to2E7G34Fxepno +ilBDhpY4VmHeEN35o1MwUTAdBgNVHQ4EFgQUfE5wC1hbiE60iRLKmevGqbeMSyww +HwYDVR0jBBgwFoAUfE5wC1hbiE60iRLKmevGqbeMSywwDwYDVR0TAQH/BAUwAwEB +/zAKBggqhkjOPQQDAgNHADBEAiB84zB7sZrNN8KzDO1JgeS8h2mtUeceAqnCnBwZ +krdhhAIgQg4ytVMOy0m51tnOJ+B9nq9keVwNlsJOf7rwGVpRlFQ= +-----END CERTIFICATE----- +` + +const publicKeyEd25519 = `-----BEGIN PUBLIC KEY----- +MCowBQYDK2VwAyEAKdgAvlExrnPk8TYc9cNuk4fmruFOd88FYgg9M6SQKm4= +-----END PUBLIC KEY----- +` + +//nolint:gosec +const privateKeyEd25519 = `-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIEYj1RXJNLVFPWeuXZfpZJBW/s/Z+gTIsP0SGRCOEHKo +-----END PRIVATE KEY----- +` + +const certificateEd25519 = `-----BEGIN CERTIFICATE----- +MIICIzCCAdWgAwIBAgIUJ1OPv+s3BuDm6amXrQimaDEq9AowBQYDK2VwMIGFMQsw +CQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZy +YW5jaXNjbzESMBAGA1UECgwJQWNtZSwgSW5jMRQwEgYDVQQDDAtleGFtcGxlLmNv +bTEfMB0GCSqGSIb3DQEJARYQYWNtZUBleGFtcGxlLmNvbTAgFw0yNDA5MTQwNjE2 +MjdaGA8zMDIwMDgyMzA2MTYyN1owgYUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApD +YWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMRIwEAYDVQQKDAlBY21l +LCBJbmMxFDASBgNVBAMMC2V4YW1wbGUuY29tMR8wHQYJKoZIhvcNAQkBFhBhY21l +QGV4YW1wbGUuY29tMCowBQYDK2VwAyEAKdgAvlExrnPk8TYc9cNuk4fmruFOd88F +Ygg9M6SQKm6jUzBRMB0GA1UdDgQWBBS75Y11AoWgeHyumy6sNTJCozENuDAfBgNV +HSMEGDAWgBS75Y11AoWgeHyumy6sNTJCozENuDAPBgNVHRMBAf8EBTADAQH/MAUG +AytlcANBANLnIRgPfKYAzigLMsUOgEoZ80tMFimhsZpgsJ2pmmzjXoX5+Zaah+kj +x3wF0MFr23e1kD/sOFatjV6h5sBZNQo= +-----END CERTIFICATE----- +` + type AuthorizationTestData struct { algorithm string privateKey string @@ -84,6 +142,28 @@ var AuthTestData = []AuthorizationTestData{ validForCert: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IkxIbzlPMmNNUzBqbzRsQWwtRk11ayJ9.eyJodHRwczovL21lcmN1cmUucm9ja3MvIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX0sImlzcyI6Imh0dHBzOi8vbWVyY3VyZS10ZXN0LmV1LmF1dGgwLmNvbS8iLCJzdWIiOiJhdXRoMHw1ZmRjM2U4OGUzYjA0YjAwNzZhNTQxM2MiLCJhdWQiOlsiaHR0cHM6Ly9tZXJjdXJlLnJvY2tzL2FwaSIsImh0dHBzOi8vbWVyY3VyZS10ZXN0LmV1LmF1dGgwLmNvbS91c2VyaW5mbyJdLCJpYXQiOjE2MDgyNzAxMTQsImF6cCI6IjMwMWh6bUJBMnZ5ZzdnSlZiSEVMUlRDell0dUJrVU52Iiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCJ9.QAZKFSYpDJ39Cln-khjyjVzKJkiSCO4o9qIzw395fuP09rPfoLYcbdEoWg_pHN6GqO6oDNr9I2RR7p0FGhZAamXVtZzSd2V8Fv-BM0TfUBeJbb0sCMaSA2Nv3izs2dk_0zoQjGFH_LSNExGkJjwKLBj059GT6o_abtr2iz_77A8", validNamespaced: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczovL21lcmN1cmUucm9ja3MvIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX19.SmTVZkxlNbzHlaF4MfA3Fp5d1W2COmHlYPgc6SodAJOQtHh1Uxz0jkhA611w0OSwCaA8C5gqUd-GgekgHVPCBkIzV0qPmmhhJpTtotkeCX3N7oBOJOi58xXouNCNt0vnUH6xACqiZJq_FhNG9ZqP5saa4xNd1E-F1E9Vo1mFji4", }, + { + algorithm: "ES256", + privateKey: privateKeyEcdsa, + publicKey: publicKeyEcdsa, + certificate: certificateEcdsa, + validEmpty: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.e30.hINnU7MroT7vlOH_DHCesipKULonewy_jnc7pNBrqCD-C9I-FjFOK8dBwbb1zG9nppYvvMDt5filtIwvcVDZUw", + valid: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX19.5iVzGj4lm-MxaqKGOcBUdu3nAajsH1H0nq2mTyOdc9dvEyRqkKWShK-cK6KC5rkKv7vWNt8gRjR4-aV5ckvRzA", + validForCert: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczovL21lcmN1cmUucm9ja3MvIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX0sImlzcyI6Imh0dHBzOi8vbWVyY3VyZS10ZXN0LmV1LmF1dGgwLmNvbS8iLCJzdWIiOiJhdXRoMHw1ZmRjM2U4OGUzYjA0YjAwNzZhNTQxM2MiLCJhdWQiOlsiaHR0cHM6Ly9tZXJjdXJlLnJvY2tzL2FwaSIsImh0dHBzOi8vbWVyY3VyZS10ZXN0LmV1LmF1dGgwLmNvbS91c2VyaW5mbyJdLCJpYXQiOjE2MDgyNzAxMTQsImF6cCI6IjMwMWh6bUJBMnZ5ZzdnSlZiSEVMUlRDell0dUJrVU52Iiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCJ9.iyOpr6Dxgs5yBKuUKJFvbTTaFRo65r55eEHQfWgGt0H0iRzCx5D3kheDe29Da1aRClRfunrpoxhpr8EqeO7Pxg", + validNamespaced: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwczovL21lcmN1cmUucm9ja3MvIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX19.MczmR4h4eS_cetXZ-cP8NwONOpYzDec-Wijl0u78n9GCnqYFmYbWczln250fFuYYqbnHAbtX_br84YxBdoQv3Q", + }, + { + algorithm: "EdDSA", + privateKey: privateKeyEd25519, + publicKey: publicKeyEd25519, + certificate: certificateEd25519, + validEmpty: "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.e30.p6y-JMVdkSrjtj1qChGi8Z5PQnAu8GiTJsq8_Txp7Yg_RATrJi6IgDlNaobyaxaHy_ypwS4G4RTmQ9mlPwFNDQ", + valid: "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX19.A2EbfgruNGekfK-VTPDX_MsrYlJdvZcAF4K5i9aKy4US2Syo4tmn9yT7aYBBdRZNBkRDqhF1sF1u26pvMLlNAw", + // jwt.ParseEdPublicKeyFromPEM() doesn't support certificates yet + // validForCert: "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJodHRwczovL21lcmN1cmUucm9ja3MvIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX0sImlzcyI6Imh0dHBzOi8vbWVyY3VyZS10ZXN0LmV1LmF1dGgwLmNvbS8iLCJzdWIiOiJhdXRoMHw1ZmRjM2U4OGUzYjA0YjAwNzZhNTQxM2MiLCJhdWQiOlsiaHR0cHM6Ly9tZXJjdXJlLnJvY2tzL2FwaSIsImh0dHBzOi8vbWVyY3VyZS10ZXN0LmV1LmF1dGgwLmNvbS91c2VyaW5mbyJdLCJpYXQiOjE2MDgyNzAxMTQsImF6cCI6IjMwMWh6bUJBMnZ5ZzdnSlZiSEVMUlRDell0dUJrVU52Iiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCJ9.FBWmpbdYpuU58d3p-e_RPu-Szzj_ZPbZtwvHbUD6nQJOe83RTrsBbVpVnI54ISG6D4N5c2mLeksC_I7OAw1KCA", + validForCert: "", + validNamespaced: "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJodHRwczovL21lcmN1cmUucm9ja3MvIjp7InB1Ymxpc2giOlsiZm9vIiwiYmFyIl0sInN1YnNjcmliZSI6WyJmb28iLCJiYXoiXX19.yBpIkxTSACRxEpFSiDOVhpSNRbhvhJy2ds90MycP9mK7oxiyRVyvZkRHRwbH26haa7PhR-HRzw828mGids2xDA", + }, } func TestAuthorizeMultipleAuthorizationHeader(t *testing.T) { From 31d0dfb5aec0b0fa918e7fe2463e7e5e394bf8c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 16 Sep 2024 10:36:56 +0200 Subject: [PATCH 21/71] spec!: make payloads topic-specific (#946) --- docs/UPGRADE.md | 30 +++++++++++++++++++++++++++++- spec/mercure.md | 34 +++++++++++++++++++++++++++------- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/docs/UPGRADE.md b/docs/UPGRADE.md index adb00474..667f6b29 100644 --- a/docs/UPGRADE.md +++ b/docs/UPGRADE.md @@ -1,6 +1,34 @@ # Upgrade -## 0.17 +## 0.20 + +The `mercure.payload` JWT key has been deprecated. It is now possible to make topic-specific data +available in subscriptions events and through the subscription API. +To make data available in all events and API responses describing subscriptions, use the `*` topic selector. + +Before: + +```json +{ + "mercure": { + "payload": {"foo": "bar"} + } +} +``` + +After: + +```json +{ + "mercure": { + "payloads": { + "*": {"foo": "bar"} + } + } +} +``` + +[Read the updated specification](../spec/mercure.md#payloads) to learn how to leverage this new feature. The `MERCURE_TRANSPORT_URL` environment variable and the `transport_url` directive have been deprecated. Use the new `transport` directive instead. diff --git a/spec/mercure.md b/spec/mercure.md index 0b1b3ca9..ced233d1 100644 --- a/spec/mercure.md +++ b/spec/mercure.md @@ -472,14 +472,34 @@ Consequently, this private update will be received by this subscriber, while oth a canonical topic matched by the selector provided in a `topic` query parameter but not matched by selectors in the `mercure.subscribe` claim will not. -## Payload +## Payloads + +User-defined data can be attached to subscriptions and made available through the subscription API +and in subscription events. -The `mercure` claim of the JWS **CAN** also contain user-defined values under the `payload` key. -This JSON document will be attached to the subscription and made available in subscription events. See (#subscription-events). -For instance, `mercure.payload` can contain the user ID of the subscriber, a list of groups it -belongs to, or its IP address. Storing data in `mercure.payload` is a convenient way to share data +The `mercure` claim of the JWS **CAN** contain a JSON object under the `payloads` key. +This JSON document **MUST** have selectors as keys, and user-defined data as values. + +The value associated with the first topic selector matching the topic of the subscription +**MUST** be included under the `payload` key in the JSON object describing a subscription in +the subscription API and in subscription events. + +Example JWT document containing payloads: + +~~~ json +{ + "subscribe": ["https://example.com/foo", "https://example.com/bar/baz"] + "payloads": { + "https://example.com/bar/{val}": {"custom": "data only available for subscriptions matching this selector"}, + "*": {"data": "available for all other topics"} + } +} +~~~ + +For instance, payloads can contain the user ID of the subscriber, its username, a list of groups it +belongs to, or its IP address. Storing data in `mercure.payloads` is a convenient way to share data related to one subscriber to other subscribers. # Reconnection, State Reconciliation and Event Sourcing {#reconciliation} @@ -575,8 +595,8 @@ least the following properties: * `topic`: the topic selector used of this subscription * `subscriber`: the topic identifier of the subscriber. It **SHOULD** be an IRI. * `active`: `true` when the subscription is active, and `false` when it is terminated -* `payload` (optional): the content of `mercure.payload` in the subscriber's JWS (see - (#authorization)) +* `payload` (optional): content of the `mercure.payloads` in the subscriber's JWS matching the topic + (see (#authorization)) The JSON-LD document **MAY** contain other properties. From fb42dfa635c120cc8799399d4732ff3c0a8d366c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 16 Sep 2024 10:37:12 +0200 Subject: [PATCH 22/71] feat: payload for a specific topic (#945) --- .golangci.yml | 1 + authorization.go | 8 +++++--- hub_test.go | 11 ++++++----- subscribe.go | 46 ++++++++++++++++++++++++++++++++++++-------- subscribe_test.go | 18 ++++++++--------- subscriber.go | 17 ++++++++++++++-- subscription_test.go | 35 +++++++++++++++++++++++++++++++++ 7 files changed, 109 insertions(+), 27 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 613b66d0..ea638235 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -29,6 +29,7 @@ linters: # deprecated - execinquery + - exportloopref issues: exclude-rules: diff --git a/authorization.go b/authorization.go index c073b77e..3c8ed646 100644 --- a/authorization.go +++ b/authorization.go @@ -19,9 +19,11 @@ type claims struct { } type mercureClaim struct { - Publish []string `json:"publish"` - Subscribe []string `json:"subscribe"` - Payload interface{} `json:"payload"` + Publish []string `json:"publish"` + Subscribe []string `json:"subscribe"` + // Deprecated: use the Payloads field instead + Payload interface{} `json:"payload"` + Payloads map[string]interface{} `json:"payloads"` } type role int diff --git a/hub_test.go b/hub_test.go index 45c0774e..247af9c4 100644 --- a/hub_test.go +++ b/hub_test.go @@ -264,12 +264,13 @@ func createAnonymousDummy(options ...Option) *Hub { } func createDummyAuthorizedJWT(r role, topics []string) string { - return createDummyAuthorizedJWTWithPayload(r, topics, struct { - Foo string `json:"foo"` - }{Foo: "bar"}) + payloads := map[string]interface{}{"*": make(map[string]string)} + payloads["*"].(map[string]string)["foo"] = "bar" + + return createDummyAuthorizedJWTWithPayload(r, topics, payloads) } -func createDummyAuthorizedJWTWithPayload(r role, topics []string, payload interface{}) string { +func createDummyAuthorizedJWTWithPayload(r role, topics []string, payloads map[string]interface{}) string { token := jwt.New(jwt.SigningMethodHS256) var key []byte @@ -282,7 +283,7 @@ func createDummyAuthorizedJWTWithPayload(r role, topics []string, payload interf token.Claims = &claims{ Mercure: mercureClaim{ Subscribe: topics, - Payload: payload, + Payloads: payloads, }, RegisteredClaims: jwt.RegisteredClaims{}, } diff --git a/subscribe.go b/subscribe.go index 476e83b9..201c401d 100644 --- a/subscribe.go +++ b/subscribe.go @@ -182,7 +182,7 @@ func (h *Hub) registerSubscriber(w http.ResponseWriter, r *http.Request) (*Subsc topics := r.URL.Query()["topic"] if len(topics) == 0 { - http.Error(w, "Missing \"topic\" parameter.", http.StatusBadRequest) + http.Error(w, `Missing "topic" parameter.`, http.StatusBadRequest) return nil, nil } @@ -203,17 +203,47 @@ func (h *Hub) registerSubscriber(w http.ResponseWriter, r *http.Request) (*Subsc rc := h.newResponseController(w, s) rc.flush() - if c := h.logger.Check(zap.InfoLevel, "New subscriber"); c != nil { - fields := []LogField{zap.Object("subscriber", s)} - if claims != nil && h.logger.Level() == zap.DebugLevel { - fields = append(fields, zap.Reflect("payload", claims.Mercure.Payload)) + h.normalizeClaims(claims) + h.logNewSubscriber(claims, s) + h.metrics.SubscriberConnected(s) + + return s, rc +} + +func (h *Hub) logNewSubscriber(claims *claims, s *Subscriber) { + c := h.logger.Check(zap.InfoLevel, "New subscriber") + if c == nil { + return + } + + fields := []LogField{zap.Object("subscriber", s)} + if claims != nil && h.logger.Level() == zap.DebugLevel { + if claims.Mercure.Payload != nil && h.opt.isBackwardCompatiblyEnabledWith(8) { + fields = append( + fields, + zap.Reflect("payload", claims.Mercure.Payload), + ) } - c.Write(fields...) + fields = append( + fields, + zap.Reflect("payloads", claims.Mercure.Payloads), + ) } - h.metrics.SubscriberConnected(s) - return s, rc + c.Write(fields...) +} + +func (h *Hub) normalizeClaims(c *claims) { + if c == nil || c.Mercure.Payload == nil { + return + } + + if h.opt.isBackwardCompatiblyEnabledWith(8) { + h.logger.Info(`Deprecated: the "mercure.payload" JWT claim deprecated since the version 8 of the protocol, use "mercure.payloads" claim with a "*" key instead.`) + } else { + c.Mercure.Payload = nil + } } // sendHeaders sends correct HTTP headers to create a keep-alive connection. diff --git a/subscribe_test.go b/subscribe_test.go index 24083513..0eb1de34 100644 --- a/subscribe_test.go +++ b/subscribe_test.go @@ -332,12 +332,12 @@ func TestSubscribe(t *testing.T) { testSubscribe(t, 3) } -func testSubscribeLogs(t *testing.T, hub *Hub, payload interface{}) { +func testSubscribeLogs(t *testing.T, hub *Hub, payloads map[string]interface{}) { t.Helper() ctx, cancel := context.WithCancel(context.Background()) req := httptest.NewRequest(http.MethodGet, defaultHubURL+"?topic=http://example.com/reviews/{id}", nil).WithContext(ctx) - req.AddCookie(&http.Cookie{Name: "mercureAuthorization", Value: createDummyAuthorizedJWTWithPayload(roleSubscriber, []string{"http://example.com/reviews/22"}, payload)}) + req.AddCookie(&http.Cookie{Name: "mercureAuthorization", Value: createDummyAuthorizedJWTWithPayload(roleSubscriber, []string{"http://example.com/reviews/22"}, payloads)}) w := &responseTester{ expectedStatusCode: http.StatusOK, @@ -351,18 +351,18 @@ func testSubscribeLogs(t *testing.T, hub *Hub, payload interface{}) { func TestSubscribeWithLogLevelDebug(t *testing.T) { core, logs := observer.New(zapcore.DebugLevel) - payload := map[string]interface{}{ - "bar": "baz", - "foo": "bar", + payloads := map[string]interface{}{ + "*": make(map[string]string), } + payloads["*"].(map[string]string)["bar"] = "baz" + payloads["*"].(map[string]string)["foo"] = "bar" + testSubscribeLogs(t, createDummy( WithLogger(zap.New(core)), - ), payload) + ), payloads) - assert.Equal(t, 1, logs.FilterMessage("New subscriber").FilterField( - zap.Reflect("payload", payload)).Len(), - ) + assert.Equal(t, 1, logs.FilterMessage("New subscriber").FilterFieldKey("payloads").Len()) } func TestSubscribeLogLevelInfo(t *testing.T) { diff --git a/subscriber.go b/subscriber.go index b22ac03b..b6807bf0 100644 --- a/subscriber.go +++ b/subscriber.go @@ -209,8 +209,21 @@ func (s *Subscriber) getSubscriptions(topic, context string, active bool) []subs Topic: t, Active: active, } - if s.Claims != nil && s.Claims.Mercure.Payload != nil { - subscription.Payload = s.Claims.Mercure.Payload + if s.Claims != nil { //nolint:nestif + if s.Claims.Mercure.Payloads == nil { + if s.Claims.Mercure.Payload != nil { + subscription.Payload = s.Claims.Mercure.Payload + } + } else { + for k, v := range s.Claims.Mercure.Payloads { + if !s.topicSelectorStore.match(t, k) { + continue + } + subscription.Payload = v + + break + } + } } subscriptions = append(subscriptions, subscription) diff --git a/subscription_test.go b/subscription_test.go index 13363b8a..12fef4c7 100644 --- a/subscription_test.go +++ b/subscription_test.go @@ -210,3 +210,38 @@ func TestSubscriptionHandler(t *testing.T) { assert.Equal(t, http.StatusNotFound, res.StatusCode) res.Body.Close() } + +func TestSubscriptionPayload(t *testing.T) { + logger := zap.NewNop() + tss := &TopicSelectorStore{} + + for _, selector := range []string{"*", "http://example.com/foo", "http://example.com/{var}"} { + t.Run("selector "+selector, func(t *testing.T) { + hub := createDummy(WithLogger(logger)) + + s1 := NewSubscriber("", logger, tss) + s1.SetTopics([]string{"http://example.com/foo"}, nil) + + s1.Claims = &claims{} + s1.Claims.Mercure.Payloads = map[string]interface{}{} + s1.Claims.Mercure.Payloads[selector] = "foo" + s1.Claims.Mercure.Payloads["http://example.com/bar"] = "bar" + + require.NoError(t, hub.transport.AddSubscriber(s1)) + + req := httptest.NewRequest(http.MethodGet, defaultHubURL+subscriptionsPath, nil) + req.AddCookie(&http.Cookie{Name: "mercureAuthorization", Value: createDummyAuthorizedJWT(roleSubscriber, []string{"/.well-known/mercure/subscriptions"})}) + w := httptest.NewRecorder() + hub.SubscriptionsHandler(w, req) + res := w.Result() + assert.Equal(t, http.StatusOK, res.StatusCode) + res.Body.Close() + + var subscriptions subscriptionCollection + json.Unmarshal(w.Body.Bytes(), &subscriptions) + + require.Len(t, subscriptions.Subscriptions, 1) + assert.Equal(t, "foo", subscriptions.Subscriptions[0].Payload) + }) + } +} From a2a57508ae5807d4d66bca6aeb4046cd9e449de8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20G=C4=85sowski?= Date: Fri, 27 Sep 2024 11:15:16 +0200 Subject: [PATCH 23/71] docs: fix Traefik example - curl is not installed (#954) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: fix in Traefik Hub example - curl is not installed in the docker image * Update docs/hub/traefik.md Co-authored-by: Kévin Dunglas --------- Co-authored-by: Kévin Dunglas --- docs/hub/traefik.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/hub/traefik.md b/docs/hub/traefik.md index 8420aa8d..c468c24c 100644 --- a/docs/hub/traefik.md +++ b/docs/hub/traefik.md @@ -32,7 +32,7 @@ services: # Enables the development mode, comment the following line to run the hub in prod mode command: /usr/bin/caddy run --config /etc/caddy/dev.Caddyfile healthcheck: - test: ["CMD", "curl", "-f", "https://localhost/healthz"] + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/healthz"] timeout: 5s retries: 5 start_period: 60s From e5878c12e4317d83e418b68a6c5f70b52f7f9716 Mon Sep 17 00:00:00 2001 From: Damien Fernandes Date: Mon, 30 Sep 2024 10:56:13 +0200 Subject: [PATCH 24/71] docs: replace curl with wget in healthcheck example --- docs/hub/config.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/hub/config.md b/docs/hub/config.md index 3ffec91a..c0167354 100644 --- a/docs/hub/config.md +++ b/docs/hub/config.md @@ -89,7 +89,7 @@ services: mercure: # ... healthcheck: - test: ["CMD", "curl", "-f", "https://localhost/healthz"] + test: ["CMD", "wget", "-O-", "https://localhost/healthz"] timeout: 5s retries: 5 start_period: 60s From aade3fb01117526c491a6f8265737ef475cfc937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 22 Oct 2024 17:13:28 +0200 Subject: [PATCH 25/71] chore: bump deps (#960) --- .github/workflows/ci.yml | 4 +- .github/workflows/lint.yml | 1 + .golangci.yml | 3 + .goreleaser.yml | 5 +- CONTRIBUTING.md | 4 +- caddy/go.mod | 146 +++++----- caddy/go.sum | 447 +++++++++++++++---------------- go.mod | 38 ++- go.sum | 79 +++--- hub.go | 2 +- topic_selector.go | 4 +- topic_selector_lru.go | 4 +- topic_selector_ristretto.go | 2 +- topic_selector_ristretto_test.go | 2 +- 14 files changed, 365 insertions(+), 376 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 33d350d9..ce6d9df0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,7 +67,7 @@ jobs: - name: Test Caddy module working-directory: caddy/ run: | - go test -timeout 1m -race -covermode atomic -coverprofile=profile.cov -coverpkg=github.com/dunglas/mercure ./... + go test -timeout 1m -race -covermode atomic -tags=nobadger,nomysql,nopgx -coverprofile=profile.cov -coverpkg=github.com/dunglas/mercure ./... sed '1d' profile.cov >> ../profile.cov - name: Upload coverage results @@ -78,7 +78,7 @@ jobs: - name: Start Mercure working-directory: caddy/mercure/ - run: sudo MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' go run main.go start --config ../../dev.Caddyfile + run: sudo MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' go run -tags=nobadger,nomysql,nopgx main.go start --config ../../dev.Caddyfile - uses: actions/setup-node@v4 with: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a3cb8f5d..e4f60975 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -32,6 +32,7 @@ jobs: VALIDATE_GITLEAKS: false VALIDATE_GO: false VALIDATE_GO_MODULES: false + VALIDATE_GO_RELEASER: false VALIDATE_PHP_PHPCS: false VALIDATE_KUBERNETES_KUBECONFORM: false VALIDATE_JAVASCRIPT_PRETTIER: false diff --git a/.golangci.yml b/.golangci.yml index ea638235..95e4715d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -23,6 +23,9 @@ linters: - depguard - mnd + # Go 1.22+ + - intrange + # weird issues - nolintlint - canonicalheader diff --git a/.goreleaser.yml b/.goreleaser.yml index ffbf6587..b8dfed7b 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,10 +1,11 @@ +version: 2 before: hooks: - go mod tidy checksum: name_template: "checksums.txt" snapshot: - name_template: "{{ incpatch .Version }}-next" + version_template: "{{ incpatch .Version }}-next" changelog: sort: asc filters: @@ -22,6 +23,8 @@ env: builds: - id: caddy dir: caddy/mercure + flags: + -tags=nobadger,nomysql,nopgx ldflags: - -X 'github.com/caddyserver/caddy/v2.CustomVersion=Mercure.rocks {{ .Version }} Caddy' goos: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7ff08cde..b180394a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,14 +48,14 @@ To run the test suite: To test the Caddy module: cd caddy/mercure - MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' go run main.go run --config ../../dev.Caddyfile + MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' go run -tags nobadger,nomysql,nopgx main.go run --config ../../dev.Caddyfile Go to `https://localhost` and enjoy! To test the legacy server: cd cmd/mercure - go run main.go + go run -tags=nobadger,nomysql,nopgx main.go Go to `http://localhost:3000` and enjoy! diff --git a/caddy/go.mod b/caddy/go.mod index b148941b..191afe5b 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -10,83 +10,79 @@ retract ( replace github.com/dunglas/mercure => ../ require ( - github.com/MicahParks/keyfunc/v3 v3.3.3 + github.com/MicahParks/keyfunc/v3 v3.3.5 github.com/caddyserver/caddy/v2 v2.8.4 github.com/dunglas/mercure v0.16.3 - github.com/prometheus/client_golang v1.20.0 + github.com/prometheus/client_golang v1.20.5 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 ) -require github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 // indirect - require ( + dario.cat/mergo v1.0.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect - github.com/BurntSushi/toml v1.3.2 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.2.1 // indirect - github.com/Masterminds/sprig/v3 v3.2.3 // indirect + github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145 // indirect - github.com/MicahParks/jwkset v0.5.18 // indirect + github.com/MicahParks/jwkset v0.5.20 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/RoaringBitmap/roaring v1.9.4 // indirect - github.com/alecthomas/chroma/v2 v2.13.0 // indirect + github.com/alecthomas/chroma/v2 v2.14.0 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.13.0 // indirect - github.com/caddyserver/certmagic v0.21.3 // indirect + github.com/bits-and-blooms/bitset v1.14.3 // indirect + github.com/caddyserver/certmagic v0.21.4 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect + github.com/coreos/go-oidc/v3 v3.11.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect - github.com/dgraph-io/ristretto v0.1.1 // indirect - github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect - github.com/dlclark/regexp2 v1.11.0 // indirect + github.com/dgraph-io/ristretto v1.0.0 // indirect + github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da // indirect + github.com/dlclark/regexp2 v1.11.4 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-chi/chi/v5 v5.1.0 // indirect github.com/go-jose/go-jose/v3 v3.0.3 // indirect - github.com/go-kit/kit v0.13.0 // indirect - github.com/go-kit/log v0.2.1 // indirect - github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gofrs/uuid v4.4.0+incompatible // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect - github.com/golang/glog v1.2.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/cel-go v0.21.0 // indirect - github.com/google/certificate-transparency-go v1.1.8-0.20240110162603-74a5dd331745 // indirect - github.com/google/go-tpm v0.9.0 // indirect + github.com/google/certificate-transparency-go v1.2.1 // indirect + github.com/google/go-tpm v0.9.1 // indirect github.com/google/go-tspi v0.3.0 // indirect - github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect + github.com/google/pprof v0.0.0-20241021161924-4cf4322d492d // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/mux v1.8.1 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect - github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/pgx/v5 v5.6.0 // indirect - github.com/jackc/puddle/v2 v2.2.1 // indirect + github.com/jackc/pgx/v5 v5.7.1 // indirect + github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/kevburnsjr/skipfilter v0.0.1 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/libdns/libdns v0.2.2 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -94,7 +90,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect - github.com/mholt/acmez/v2 v2.0.2 // indirect + github.com/mholt/acmez/v2 v2.0.3 // indirect github.com/miekg/dns v1.1.62 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect @@ -102,28 +98,29 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mschoch/smat v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/ginkgo/v2 v2.20.0 // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/pires/go-proxyproto v0.7.0 // indirect + github.com/onsi/ginkgo/v2 v2.20.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/pires/go-proxyproto v0.8.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.46.0 // indirect - github.com/rs/xid v1.5.0 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.48.0 // indirect + github.com/rs/xid v1.6.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/slackhq/nebula v1.9.3 // indirect - github.com/smallstep/certificates v0.27.2 // indirect + github.com/slackhq/nebula v1.9.4 // indirect + github.com/smallstep/certificates v0.27.5 // indirect + github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 // indirect github.com/smallstep/nosql v0.7.0 // indirect - github.com/smallstep/pkcs7 v0.0.0-20240723090913-5e2c6a136dfa // indirect - github.com/smallstep/scep v0.0.0-20240214080410-892e41795b99 // indirect + github.com/smallstep/pkcs7 v0.0.0-20240911091500-b1cae6277023 // indirect + github.com/smallstep/scep v0.0.0-20240926084937-8cf1ca453101 // indirect github.com/smallstep/truststore v0.13.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect @@ -134,49 +131,50 @@ require ( github.com/stoewer/go-strcase v1.3.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53 // indirect - github.com/unrolled/secure v1.15.0 // indirect - github.com/urfave/cli v1.22.15 // indirect + github.com/unrolled/secure v1.16.0 // indirect + github.com/urfave/cli v1.22.16 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect - github.com/yuin/goldmark v1.7.1 // indirect + github.com/yuin/goldmark v1.7.8 // indirect github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc // indirect github.com/zeebo/blake3 v0.2.4 // indirect - go.etcd.io/bbolt v1.3.10 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect - go.opentelemetry.io/contrib/propagators/autoprop v0.42.0 // indirect - go.opentelemetry.io/contrib/propagators/aws v1.17.0 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.17.0 // indirect - go.opentelemetry.io/contrib/propagators/jaeger v1.17.0 // indirect - go.opentelemetry.io/contrib/propagators/ot v1.17.0 // indirect - go.opentelemetry.io/otel v1.24.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.24.0 // indirect - go.opentelemetry.io/otel/sdk v1.21.0 // indirect - go.opentelemetry.io/otel/trace v1.24.0 // indirect - go.opentelemetry.io/proto/otlp v1.0.0 // indirect + go.etcd.io/bbolt v1.3.11 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect + go.opentelemetry.io/contrib/propagators/autoprop v0.56.0 // indirect + go.opentelemetry.io/contrib/propagators/aws v1.31.0 // indirect + go.opentelemetry.io/contrib/propagators/b3 v1.31.0 // indirect + go.opentelemetry.io/contrib/propagators/jaeger v1.31.0 // indirect + go.opentelemetry.io/contrib/propagators/ot v1.31.0 // indirect + go.opentelemetry.io/otel v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 // indirect + go.opentelemetry.io/otel/metric v1.31.0 // indirect + go.opentelemetry.io/otel/sdk v1.31.0 // indirect + go.opentelemetry.io/otel/trace v1.31.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.step.sm/cli-utils v0.9.0 // indirect - go.step.sm/crypto v0.51.1 // indirect + go.step.sm/crypto v0.54.0 // indirect go.step.sm/linkedca v0.22.1 // indirect - go.uber.org/automaxprocs v1.5.3 // indirect - go.uber.org/mock v0.4.0 // indirect + go.uber.org/automaxprocs v1.6.0 // indirect + go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap/exp v0.2.0 // indirect - golang.org/x/crypto v0.26.0 // indirect - golang.org/x/crypto/x509roots/fallback v0.0.0-20240806160748-b2d3a6a4b4d3 // indirect - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect + golang.org/x/crypto v0.28.0 // indirect + golang.org/x/crypto/x509roots/fallback v0.0.0-20241021190220-c17aa50fbd32 // indirect + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/net v0.30.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect - golang.org/x/time v0.6.0 // indirect - golang.org/x/tools v0.24.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/grpc v1.65.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/term v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/time v0.7.0 // indirect + golang.org/x/tools v0.26.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect + google.golang.org/grpc v1.67.1 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/caddy/go.sum b/caddy/go.sum index dd1b0f0c..a652a690 100644 --- a/caddy/go.sum +++ b/caddy/go.sum @@ -1,39 +1,40 @@ -cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= -cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= -cloud.google.com/go/auth v0.7.2 h1:uiha352VrCDMXg+yoBtaD0tUF4Kv9vrtrWPYXwutnDE= -cloud.google.com/go/auth v0.7.2/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= -cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= -cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= -cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= -cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= -cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= -cloud.google.com/go/iam v1.1.10 h1:ZSAr64oEhQSClwBL670MsJAW5/RLiC6kfw3Bqmd5ZDI= -cloud.google.com/go/iam v1.1.10/go.mod h1:iEgMq62sg8zx446GCaijmA2Miwg5o3UbO+nI47WHJps= -cloud.google.com/go/kms v1.18.3 h1:8+Z2S4bQDSCdghB5ZA5dVDDJTLmnkRlowtFiXqMFd74= -cloud.google.com/go/kms v1.18.3/go.mod h1:y/Lcf6fyhbdn7MrG1VaDqXxM8rhOBc5rWcWAhcvZjQU= -cloud.google.com/go/longrunning v0.5.9 h1:haH9pAuXdPAMqHvzX0zlWQigXT7B0+CL4/2nXXdBo5k= -cloud.google.com/go/longrunning v0.5.9/go.mod h1:HD+0l9/OOW0za6UWdKJtXoFAX/BGg/3Wj8p10NeWF7c= +cloud.google.com/go v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ= +cloud.google.com/go v0.115.1/go.mod h1:DuujITeaufu3gL68/lOFIirVNJwQeyf5UXyi+Wbgknc= +cloud.google.com/go/auth v0.9.8 h1:+CSJ0Gw9iVeSENVCKJoLHhdUykDgXSc4Qn+gu2BRtR8= +cloud.google.com/go/auth v0.9.8/go.mod h1:xxA5AqpDrvS+Gkmo9RqrGGRh6WSNKKOXhY3zNOr38tI= +cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY= +cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc= +cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= +cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo= +cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= +cloud.google.com/go/iam v1.2.1 h1:QFct02HRb7H12J/3utj0qf5tobFh9V4vR6h9eX5EBRU= +cloud.google.com/go/iam v1.2.1/go.mod h1:3VUIJDPpwT6p/amXRC5GY8fCCh70lxPygguVtI0Z4/g= +cloud.google.com/go/kms v1.20.0 h1:uKUvjGqbBlI96xGE669hcVnEMw1Px/Mvfa62dhM5UrY= +cloud.google.com/go/kms v1.20.0/go.mod h1:/dMbFF1tLLFnQV44AoI2GlotbjowyUfgVwezxW291fM= +cloud.google.com/go/longrunning v0.6.1 h1:lOLTFxYpr8hcRtcwWir5ITh1PAKUD/sG2lKrTSYjyMc= +cloud.google.com/go/longrunning v0.6.1/go.mod h1:nHISoOZpBcmlwbJmiVk5oDRz0qG/ZxPynEGs1iZ79s0= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= -github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= -github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= -github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +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/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= +github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/MauriceGit/skiplist v0.0.0-20191117202105-643e379adb62/go.mod h1:877WBceefKn14QwVVn4xRFUsHsZb9clICgdeTj4XsUg= github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145 h1:1yw6O62BReQ+uA1oyk9XaQTvLhcoHWmoQAgXmDFXpIY= github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145/go.mod h1:877WBceefKn14QwVVn4xRFUsHsZb9clICgdeTj4XsUg= -github.com/MicahParks/jwkset v0.5.18 h1:WLdyMngF7rCrnstQxA7mpRoxeaWqGzPM/0z40PJUK4w= -github.com/MicahParks/jwkset v0.5.18/go.mod h1:q8ptTGn/Z9c4MwbcfeCDssADeVQb3Pk7PnVxrvi+2QY= -github.com/MicahParks/keyfunc/v3 v3.3.3 h1:c6j9oSu1YUo0k//KwF1miIQlEMtqNlj7XBFLB8jtEmY= -github.com/MicahParks/keyfunc/v3 v3.3.3/go.mod h1:f/UMyXdKfkZzmBeBFUeYk+zu066J1Fcl48f7Wnl5Z48= +github.com/MicahParks/jwkset v0.5.20 h1:gTIKx9AofTqQJ0srd8AL7ty9NeadP5WUXSPOZadTpOI= +github.com/MicahParks/jwkset v0.5.20/go.mod h1:q8ptTGn/Z9c4MwbcfeCDssADeVQb3Pk7PnVxrvi+2QY= +github.com/MicahParks/keyfunc/v3 v3.3.5 h1:7ceAJLUAldnoueHDNzF8Bx06oVcQ5CfJnYwNt1U3YYo= +github.com/MicahParks/keyfunc/v3 v3.3.5/go.mod h1:SdCCyMJn/bYqWDvARspC6nCT8Sk74MjuAY22C7dCST8= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= @@ -42,11 +43,11 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA= github.com/RoaringBitmap/roaring v1.9.4 h1:yhEIoH4YezLYT04s1nHehNO64EKFTop/wBhxv2QzDdQ= github.com/RoaringBitmap/roaring v1.9.4/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90= -github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU= -github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/assert/v2 v2.7.0 h1:QtqSACNS3tF7oasA8CU6A6sXZSBDqnm7RfpLl9bZqbE= +github.com/alecthomas/assert/v2 v2.7.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs= -github.com/alecthomas/chroma/v2 v2.13.0 h1:VP72+99Fb2zEcYM0MeaWJmV+xQvz5v5cxRHd+ooU1lI= -github.com/alecthomas/chroma/v2 v2.13.0/go.mod h1:BUGjjsD+ndS6eX37YgTchSEG+Jg9Jv1GiZs9sqPqztk= +github.com/alecthomas/chroma/v2 v2.14.0 h1:R3+wzpnUArGcQz7fCETQBzO5n9IMNi13iIs46aU4V9E= +github.com/alecthomas/chroma/v2 v2.14.0/go.mod h1:QolEbTfmUHIMVpBqxeDnNBj2uoeI4EbYP4i6n68SG4I= github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= @@ -55,51 +56,50 @@ github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmO github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b h1:uUXgbcPDK3KpW29o4iy7GtuappbWT0l5NaMo9H9pJDw= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-sdk-go-v2 v1.30.3 h1:jUeBtG0Ih+ZIFH0F4UkmL9w3cSpaMv9tYYDbzILP8dY= -github.com/aws/aws-sdk-go-v2 v1.30.3/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc= -github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90= -github.com/aws/aws-sdk-go-v2/config v1.27.27/go.mod h1:MVYamCg76dFNINkZFu4n4RjDixhVr51HLj4ErWzrVwg= -github.com/aws/aws-sdk-go-v2/credentials v1.17.27 h1:2raNba6gr2IfA0eqqiP2XiQ0UVOpGPgDSi0I9iAP+UI= -github.com/aws/aws-sdk-go-v2/credentials v1.17.27/go.mod h1:gniiwbGahQByxan6YjQUMcW4Aov6bLC3m+evgcoN4r4= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 h1:KreluoV8FZDEtI6Co2xuNk/UqI9iwMrOx/87PBNIKqw= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11/go.mod h1:SeSUYBLsMYFoRvHE0Tjvn7kbxaUhl75CJi1sbfhMxkU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 h1:SoNJ4RlFEQEbtDcCEt+QG56MY4fm4W8rYirAmq+/DdU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15/go.mod h1:U9ke74k1n2bf+RIgoX1SXFed1HLs51OgUSs+Ph0KJP8= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 h1:C6WHdGnTDIYETAm5iErQUiVNsclNx9qbJVPIt03B6bI= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15/go.mod h1:ZQLZqhcu+JhSrA9/NXRm8SkDvsycE+JkV3WGY41e+IM= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 h1:HGErhhrxZlQ044RiM+WdoZxp0p+EGM62y3L6pwA4olE= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17/go.mod h1:RkZEx4l0EHYDJpWppMJ3nD9wZJAa8/0lq9aVC+r2UII= -github.com/aws/aws-sdk-go-v2/service/kms v1.35.3 h1:UPTdlTOwWUX49fVi7cymEN6hDqCwe3LNv1vi7TXUutk= -github.com/aws/aws-sdk-go-v2/service/kms v1.35.3/go.mod h1:gjDP16zn+WWalyaUqwCCioQ8gU8lzttCCc9jYsiQI/8= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 h1:BXx0ZIxvrJdSgSvKTZ+yRBeSqqgPM89VPlulEcl37tM= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.4/go.mod h1:ooyCOXjvJEsUw7x+ZDHeISPMhtwI3ZCB7ggFMcFfWLU= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 h1:yiwVzJW2ZxZTurVbYWA7QOrAaCYQR72t0wrSBfoesUE= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4/go.mod h1:0oxfLkpz3rQ/CHlx5hB7H69YUpFiI1tql6Q6Ne+1bCw= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudrvuKpDKgMVRlepGE= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.3/go.mod h1:zwySh8fpFyXp9yOr/KVzxOl8SRqgf/IDw5aUt9UKFcQ= -github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= -github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= +github.com/aws/aws-sdk-go-v2 v1.31.0 h1:3V05LbxTSItI5kUqNwhJrrrY1BAXxXt0sN0l72QmG5U= +github.com/aws/aws-sdk-go-v2 v1.31.0/go.mod h1:ztolYtaEUtdpf9Wftr31CJfLVjOnD/CVRkKOOYgF8hA= +github.com/aws/aws-sdk-go-v2/config v1.27.39 h1:FCylu78eTGzW1ynHcongXK9YHtoXD5AiiUqq3YfJYjU= +github.com/aws/aws-sdk-go-v2/config v1.27.39/go.mod h1:wczj2hbyskP4LjMKBEZwPRO1shXY+GsQleab+ZXT2ik= +github.com/aws/aws-sdk-go-v2/credentials v1.17.37 h1:G2aOH01yW8X373JK419THj5QVqu9vKEwxSEsGxihoW0= +github.com/aws/aws-sdk-go-v2/credentials v1.17.37/go.mod h1:0ecCjlb7htYCptRD45lXJ6aJDQac6D2NlKGpZqyTG6A= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 h1:C/d03NAmh8C4BZXhuRNboF/DqhBkBCeDiJDcaqIT5pA= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14/go.mod h1:7I0Ju7p9mCIdlrfS+JCgqcYD0VXz/N4yozsox+0o078= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 h1:kYQ3H1u0ANr9KEKlGs/jTLrBFPo8P8NaH/w7A01NeeM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18/go.mod h1:r506HmK5JDUh9+Mw4CfGJGSSoqIiLCndAuqXuhbv67Y= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 h1:Z7IdFUONvTcvS7YuhtVxN99v2cCoHRXOS4mTr0B/pUc= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18/go.mod h1:DkKMmksZVVyat+Y+r1dEOgJEfUeA7UngIHWeKsi0yNc= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 h1:QFASJGfT8wMXtuP3D5CRmMjARHv9ZmzFUMJznHDOY3w= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5/go.mod h1:QdZ3OmoIjSX+8D1OPAzPxDfjXASbBMDsz9qvtyIhtik= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 h1:Xbwbmk44URTiHNx6PNo0ujDE6ERlsCKJD3u1zfnzAPg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20/go.mod h1:oAfOFzUB14ltPZj1rWwRc3d/6OgD76R8KlvU3EqM9Fg= +github.com/aws/aws-sdk-go-v2/service/kms v1.36.3 h1:iHi6lC6LfW6SNvB2bixmlOW3WMyWFrHZCWX+P+CCxMk= +github.com/aws/aws-sdk-go-v2/service/kms v1.36.3/go.mod h1:OHmlX4+o0XIlJAQGAHPIy0N9yZcYS/vNG+T7geSNcFw= +github.com/aws/aws-sdk-go-v2/service/sso v1.23.3 h1:rs4JCczF805+FDv2tRhZ1NU0RB2H6ryAvsWPanAr72Y= +github.com/aws/aws-sdk-go-v2/service/sso v1.23.3/go.mod h1:XRlMvmad0ZNL+75C5FYdMvbbLkd6qiqz6foR1nA1PXY= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.3 h1:S7EPdMVZod8BGKQQPTBK+FcX9g7bKR7c4+HxWqHP7Vg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.3/go.mod h1:FnvDM4sfa+isJ3kDXIzAB9GAwVSzFzSy97uZ3IsHo4E= +github.com/aws/aws-sdk-go-v2/service/sts v1.31.3 h1:VzudTFrDCIDakXtemR7l6Qzt2+JYsVqo2MxBPt5k8T8= +github.com/aws/aws-sdk-go-v2/service/sts v1.31.3/go.mod h1:yMWe0F+XG0DkRZK5ODZhG7BEFYhLXi2dqGsv6tX0cgI= +github.com/aws/smithy-go v1.21.0 h1:H7L8dtDRk0P1Qm6y0ji7MCYMQObJ5R9CRpyPhRUkLYA= +github.com/aws/smithy-go v1.21.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= 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/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= -github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.14.3 h1:Gd2c8lSNf9pKXom5JtD7AaKO8o7fGQ2LtFj1436qilA= +github.com/bits-and-blooms/bitset v1.14.3/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/caddyserver/caddy/v2 v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk= github.com/caddyserver/caddy/v2 v2.8.4/go.mod h1:vmDAHp3d05JIvuhc24LmnxVlsZmWnUwbP5WMjzcMPWw= -github.com/caddyserver/certmagic v0.21.3 h1:pqRRry3yuB4CWBVq9+cUqu+Y6E2z8TswbhNx1AZeYm0= -github.com/caddyserver/certmagic v0.21.3/go.mod h1:Zq6pklO9nVRl3DIFUw9gVUfXKdpc/0qwTUAQMBlfgtI= +github.com/caddyserver/certmagic v0.21.4 h1:e7VobB8rffHv8ZZpSiZtEwnLDHUwLVYLWzWSa1FfKI0= +github.com/caddyserver/certmagic v0.21.4/go.mod h1:swUXjQ1T9ZtMv95qj7/InJvWLXURU85r+CfG0T+ZbDE= github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +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/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= 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.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= @@ -113,10 +113,13 @@ github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI= +github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= +github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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= @@ -127,15 +130,15 @@ github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdw github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= -github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgraph-io/ristretto v1.0.0 h1:SYG07bONKMlFDUYu5pEu3DGAh8c2OFNzKm6G9J4Si84= +github.com/dgraph-io/ristretto v1.0.0/go.mod h1:jTi2FiYEhQ1NsMmA7DeBykizjOuY88NhKBkepyu1jPc= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38= +github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -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/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo= +github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= @@ -152,14 +155,8 @@ github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= -github.com/go-kit/kit v0.4.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU= -github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg= -github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= -github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= +github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= 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= @@ -167,16 +164,12 @@ 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-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -github.com/go-stack/stack v1.6.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 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/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= -github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -190,34 +183,33 @@ github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl76 github.com/google/cel-go v0.21.0 h1:cl6uW/gxN+Hy50tNYvI691+sXxioCnstFzLp2WO4GCI= github.com/google/cel-go v0.21.0/go.mod h1:rHUlWCcBKgyEk+eV03RPdZUekPp6YcJwV0FxuUksYxc= github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= -github.com/google/certificate-transparency-go v1.1.8-0.20240110162603-74a5dd331745 h1:heyoXNxkRT155x4jTAiSv5BVSVkueifPUm+Q8LUXMRo= -github.com/google/certificate-transparency-go v1.1.8-0.20240110162603-74a5dd331745/go.mod h1:zN0wUQgV9LjwLZeFHnrAbQi8hzMVvEWePyk+MhPOk7k= +github.com/google/certificate-transparency-go v1.2.1 h1:4iW/NwzqOqYEEoCBEFP+jPbBXbLqMpq3CifMyOnDUME= +github.com/google/certificate-transparency-go v1.2.1/go.mod h1:bvn/ytAccv+I6+DGkqpvSsEdiVGramgaSC6RD3tEmeE= 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-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= -github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= +github.com/google/go-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM= +github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus= github.com/google/go-tspi v0.3.0/go.mod h1:xfMGI3G0PhxCdNVcYr1C4C+EizojDg/TXuX5by8CiHI= -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/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= -github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/pprof v0.0.0-20241021161924-4cf4322d492d h1:dcUSYLuKITgwgLZJZpB+CKecsC8mXHhErghMX9ohbf4= +github.com/google/pprof v0.0.0-20241021161924-4cf4322d492d/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= +github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= 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/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= +github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s= github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp42aoYI92+PCrVotyR5e8Vqlk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= 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= @@ -225,12 +217,8 @@ 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/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= -github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -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/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= @@ -238,16 +226,16 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY= -github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= -github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= -github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs= +github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/kevburnsjr/skipfilter v0.0.1 h1:EWl1lWUJfIehrKYIEkps0Cl67lCfS2pUM9iZFNajp7g= github.com/kevburnsjr/skipfilter v0.0.1/go.mod h1:jfaRyFOYVUtIa6IIC+0mB1qiZqhHw+DKvFowCBuijSk= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -274,11 +262,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 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/mholt/acmez/v2 v2.0.2 h1:OmK6xckte2JfKGPz4OAA8aNHTiLvGp8tLzmrd/wfSyw= -github.com/mholt/acmez/v2 v2.0.2/go.mod h1:fX4c9r5jYwMyMsC+7tkYRxHibkOTgta5DIFGoe67e1U= +github.com/mholt/acmez/v2 v2.0.3 h1:CgDBlEwg3QBp6s45tPQmFIBrkRIkBT4rW4orMM6p4sw= +github.com/mholt/acmez/v2 v2.0.3/go.mod h1:pQ1ysaDeGrIMvJ9dfJMk5kJNkn7L2sb3UhyrX6Q91cw= github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -287,24 +274,23 @@ github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= -github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= +github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= +github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +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/peterbourgon/diskv/v3 v3.0.1 h1:x06SQA46+PKIUftmEujdwSEpIx8kR+M9eLYsUxeYveU= github.com/peterbourgon/diskv/v3 v3.0.1/go.mod h1:kJ5Ny7vLdARGU3WUuy6uzO6T0nb/2gWcT1JiBvRmb5o= -github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs= -github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4= +github.com/pires/go-proxyproto v0.8.0 h1:5unRmEAPbHXHuLjDg01CxJWf91cw3lKHc/0xzKpXEe0= +github.com/pires/go-proxyproto v0.8.0/go.mod h1:iknsfgnH8EkjrMeMyvfKByp9TiBZCKZM0jx2xmKqnVY= 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= @@ -313,22 +299,22 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= -github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= -github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +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.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= 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/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= -github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.48.0 h1:2TCyvBrMu1Z25rvIAlnp2dPT4lgh/uTqLqiXVpp5AeU= +github.com/quic-go/quic-go v0.48.0/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= +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/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= 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= @@ -338,7 +324,6 @@ github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6g github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/schollz/jsonstore v1.1.0 h1:WZBDjgezFS34CHI+myb4s8GGpir3UMpy7vWoCeO0n6E= github.com/schollz/jsonstore v1.1.0/go.mod h1:15c6+9guw8vDRyozGjN3FoILt0wpruJk9Pi66vjaZfg= -github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= @@ -346,21 +331,20 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/slackhq/nebula v1.9.3 h1:WK5Oipy4NsVfNm41pywGmdy048F8RRkfSRG+lPHxcJQ= -github.com/slackhq/nebula v1.9.3/go.mod h1:PMJer5rZe0H/O+kUiKOL9AJ/pL9+ryzNXtSN7ABfjfM= +github.com/slackhq/nebula v1.9.4 h1:p06JxtXT/OBMWt2OQkY7F0phOBb42X93YWNsS1yqC9o= +github.com/slackhq/nebula v1.9.4/go.mod h1:1+4q4wd3dDAjO8rKCttSb9JIVbklQhuJiBp5I0lbIsQ= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262 h1:unQFBIznI+VYD1/1fApl1A+9VcBk+9dcqGfnePY87LY= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262/go.mod h1:MyOHs9Po2fbM1LHej6sBUT8ozbxmMOFG+E+rx/GSGuc= -github.com/smallstep/certificates v0.27.2 h1:MrSJvJviS9pCUtGYYguYyB1VQzZBmkL6ngLQZfVwRqU= -github.com/smallstep/certificates v0.27.2/go.mod h1:v+u39A+fMBM3cFELPfAweaNce4RPm9AHUx9iwE0ene8= +github.com/smallstep/certificates v0.27.5 h1:EOfaHdo/eMv0aVF11iuF4PoY/UmDBS7+TxYD0MSKTFA= +github.com/smallstep/certificates v0.27.5/go.mod h1:0rLS7iQtfG3X0fcxZWeBXSkFVnBoeCLXxHWVnPD+zzg= github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 h1:kjYvkvS/Wdy0PVRDUAA0gGJIVSEZYhiAJtfwYgOYoGA= github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935/go.mod h1:vNAduivU014fubg6ewygkAvQC0IQVXqdc8vaGl/0er4= github.com/smallstep/nosql v0.7.0 h1:YiWC9ZAHcrLCrayfaF+QJUv16I2bZ7KdLC3RpJcnAnE= github.com/smallstep/nosql v0.7.0/go.mod h1:H5VnKMCbeq9QA6SRY5iqPylfxLfYcLwvUff3onQ8+HU= -github.com/smallstep/pkcs7 v0.0.0-20231024181729-3b98ecc1ca81/go.mod h1:SoUAr/4M46rZ3WaLstHxGhLEgoYIDRqxQEXLOmOEB0Y= -github.com/smallstep/pkcs7 v0.0.0-20240723090913-5e2c6a136dfa h1:FtxzVccOwaK+bK4bnWBPGua0FpCOhrVyeo6Fy9nxdlo= -github.com/smallstep/pkcs7 v0.0.0-20240723090913-5e2c6a136dfa/go.mod h1:SoUAr/4M46rZ3WaLstHxGhLEgoYIDRqxQEXLOmOEB0Y= -github.com/smallstep/scep v0.0.0-20240214080410-892e41795b99 h1:e85HuLX5/MW15yJ7yWb/PMNFW1Kx1N+DeQtpQnlMUbw= -github.com/smallstep/scep v0.0.0-20240214080410-892e41795b99/go.mod h1:4d0ub42ut1mMtvGyMensjuHYEUpRrASvkzLEJvoRQcU= +github.com/smallstep/pkcs7 v0.0.0-20240911091500-b1cae6277023 h1:klMnoL/Mrw9MJaAZdGUuEAKSskSoy14KIUpRwGOd4Vo= +github.com/smallstep/pkcs7 v0.0.0-20240911091500-b1cae6277023/go.mod h1:CM5KrX7rxWgwDdMj9yef/pJB2OPgy/56z4IEx2UIbpc= +github.com/smallstep/scep v0.0.0-20240926084937-8cf1ca453101 h1:LyZqn24/ZiVg8v9Hq07K6mx6RqPtpDeK+De5vf4QEY4= +github.com/smallstep/scep v0.0.0-20240926084937-8cf1ca453101/go.mod h1:EuKQjYGQwhUa1mgD21zxIgOgUYLsqikJmvxNscxpS/Y= github.com/smallstep/truststore v0.13.0 h1:90if9htAOblavbMeWlqNLnO9bsjjgVv2hQeQJCi/py4= github.com/smallstep/truststore v0.13.0/go.mod h1:3tmMp2aLKZ/OA/jnFUB0cYPcho402UG2knuJoPh4j7A= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= @@ -372,7 +356,6 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B 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 v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= @@ -394,7 +377,6 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/ 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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -407,10 +389,10 @@ github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSW github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53 h1:uxMgm0C+EjytfAqyfBG55ZONKQ7mvd7x4YYCWsf8QHQ= github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53/go.mod h1:kNGUQ3VESx3VZwRwA9MSCUegIl6+saPL8Noq82ozCaU= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/unrolled/secure v1.15.0 h1:q7x+pdp8jAHnbzxu6UheP8fRlG/rwYTb8TPuQ3rn9Og= -github.com/unrolled/secure v1.15.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= -github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM= -github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0= +github.com/unrolled/secure v1.16.0 h1:XgdAsS/Zl50ZfZPRJK6WpicFttfrsFYFd0+ONDBJubU= +github.com/unrolled/secure v1.16.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= +github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ= +github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po= 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/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= @@ -418,8 +400,8 @@ github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zI github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= -github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= +github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ= github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I= github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= @@ -428,50 +410,50 @@ github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= -go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= -go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ= +go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= +go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= -go.opentelemetry.io/contrib/propagators/autoprop v0.42.0 h1:s2RzYOAqHVgG23q8fPWYChobUoZM6rJZ98EnylJr66w= -go.opentelemetry.io/contrib/propagators/autoprop v0.42.0/go.mod h1:Mv/tWNtZn+NbALDb2XcItP0OM3lWWZjAfSroINxfW+Y= -go.opentelemetry.io/contrib/propagators/aws v1.17.0 h1:IX8d7l2uRw61BlmZBOTQFaK+y22j6vytMVTs9wFrO+c= -go.opentelemetry.io/contrib/propagators/aws v1.17.0/go.mod h1:pAlCYRWff4uGqRXOVn3WP8pDZ5E0K56bEoG7a1VSL4k= -go.opentelemetry.io/contrib/propagators/b3 v1.17.0 h1:ImOVvHnku8jijXqkwCSyYKRDt2YrnGXD4BbhcpfbfJo= -go.opentelemetry.io/contrib/propagators/b3 v1.17.0/go.mod h1:IkfUfMpKWmynvvE0264trz0sf32NRTZL4nuAN9AbWRc= -go.opentelemetry.io/contrib/propagators/jaeger v1.17.0 h1:Zbpbmwav32Ea5jSotpmkWEl3a6Xvd4tw/3xxGO1i05Y= -go.opentelemetry.io/contrib/propagators/jaeger v1.17.0/go.mod h1:tcTUAlmO8nuInPDSBVfG+CP6Mzjy5+gNV4mPxMbL0IA= -go.opentelemetry.io/contrib/propagators/ot v1.17.0 h1:ufo2Vsz8l76eI47jFjuVyjyB3Ae2DmfiCV/o6Vc8ii0= -go.opentelemetry.io/contrib/propagators/ot v1.17.0/go.mod h1:SbKPj5XGp8K/sGm05XblaIABgMgw2jDczP8gGeuaVLk= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +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/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= +go.opentelemetry.io/contrib/propagators/autoprop v0.56.0 h1:FtwGTy9ka2eBVnBotuligqO2V+il+Hp74APIJsWNbd8= +go.opentelemetry.io/contrib/propagators/autoprop v0.56.0/go.mod h1:XzSaHSuUiWveyQwmofA3IEK23+SpzfSEcVZXpqfBh+E= +go.opentelemetry.io/contrib/propagators/aws v1.31.0 h1:OJHDboLd4zH1j0UrxoQbSDPEykmBJ/epVa/v+fRCRi0= +go.opentelemetry.io/contrib/propagators/aws v1.31.0/go.mod h1:mtT7x7gY+jL4fH34l8dkZeo6Jvf+3Fy002rjuEdRnTM= +go.opentelemetry.io/contrib/propagators/b3 v1.31.0 h1:PQPXYscmwbCp76QDvO4hMngF2j8Bx/OTV86laEl8uqo= +go.opentelemetry.io/contrib/propagators/b3 v1.31.0/go.mod h1:jbqfV8wDdqSDrAYxVpXQnpM0XFMq2FtDesblJ7blOwQ= +go.opentelemetry.io/contrib/propagators/jaeger v1.31.0 h1:k9P5RQEWIKUP6N18/ouSvPD/uTjc7s+8WPnuVK6lWOI= +go.opentelemetry.io/contrib/propagators/jaeger v1.31.0/go.mod h1:OpgiBRssaVKOTM5lSKkOBIGQh/ixvfZRmxQXARK/kGQ= +go.opentelemetry.io/contrib/propagators/ot v1.31.0 h1:PtlNuoEn5sa2Mfz1Jb+NhOVgT4SjAw90XmziOloj87E= +go.opentelemetry.io/contrib/propagators/ot v1.31.0/go.mod h1:5W00bdNbK3dCy/Eqxgi1nLq4qYbAekf7b7IGETqZgVE= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 h1:FFeLy03iVTXP6ffeN2iXrxfGsZGCjVx0/4KlizjyBwU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0/go.mod h1:TMu73/k1CP8nBUpDLc71Wj/Kf7ZS9FK5b53VapRsP9o= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.step.sm/cli-utils v0.9.0 h1:55jYcsQbnArNqepZyAwcato6Zy2MoZDRkWW+jF+aPfQ= go.step.sm/cli-utils v0.9.0/go.mod h1:Y/CRoWl1FVR9j+7PnAewufAwKmBOTzR6l9+7EYGAnp8= -go.step.sm/crypto v0.51.1 h1:ktUg/2hetEMiBAqgz502ktZDGoDoGrcHFg3XpkmkvvA= -go.step.sm/crypto v0.51.1/go.mod h1:PdrhttNU/tG9/YsVd4fdlysBN+UV503p0o2irFZQlAw= +go.step.sm/crypto v0.54.0 h1:V8p+12Ld0NRA/RBMYoKXA0dWmVKZSdCwP56IwzweT9g= +go.step.sm/crypto v0.54.0/go.mod h1:vQJyTngfZDW+UyZdFzOMCY/txWDAmcwViEUC7Gn4YfU= go.step.sm/linkedca v0.22.1 h1:GvprpH9P4Sv9U+eZ3bxDgRSSpW14cFDYpe1kS6yWLkw= go.step.sm/linkedca v0.22.1/go.mod h1:dOKdF4HSn73YUEkfS5/FECngZmBtj2Il5DTKWXY4S6Y= -go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= -go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= 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/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= @@ -481,31 +463,41 @@ go.uber.org/zap/exp v0.2.0/go.mod h1:t0gqAIdh1MfKv9EwN/dLwfZnJxe9ITAZN78HEWPFWDQ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= -golang.org/x/crypto/x509roots/fallback v0.0.0-20240806160748-b2d3a6a4b4d3 h1:oWb21rU9Q9XrRwXLB7jHc1rbp6EiiimZZv5MLxpu4T0= -golang.org/x/crypto/x509roots/fallback v0.0.0-20240806160748-b2d3a6a4b4d3/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto/x509roots/fallback v0.0.0-20241021190220-c17aa50fbd32 h1:u+wXJTTHk+l3A3eJLqzMOflOiT03pV+eRadSt1N4VNs= +golang.org/x/crypto/x509roots/fallback v0.0.0-20241021190220-c17aa50fbd32/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -520,52 +512,60 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc 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.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -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/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= +golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.189.0 h1:equMo30LypAkdkLMBqfeIqtyAnlyig1JSZArl4XPwdI= -google.golang.org/api v0.189.0/go.mod h1:FLWGJKb0hb+pU2j+rJqwbnsF+ym+fQs73rbJ+KAUgy8= -google.golang.org/genproto v0.0.0-20240722135656-d784300faade h1:lKFsS7wpngDgSCeFn7MoLy+wBDQZ1UQIJD4UNM1Qvkg= -google.golang.org/genproto v0.0.0-20240722135656-d784300faade/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= -google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= -google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/api v0.200.0 h1:0ytfNWn101is6e9VBoct2wrGDjOi5vn7jw5KtaQgDrU= +google.golang.org/api v0.200.0/go.mod h1:Tc5u9kcbjO7A8SwGlYj4IiVifJU01UqXtEgDMYmBmV8= +google.golang.org/genproto v0.0.0-20241007155032-5fefd90f89a9 h1:nFS3IivktIU5Mk6KQa+v6RKkHUpdQpphqGNLxqNnbEk= +google.golang.org/genproto v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:tEzYTYZxbmVNOu0OAFH9HzdJtLn6h4Aj89zzlBCdHms= +google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1:fVoAXEKA4+yufmbdVYv+SE73+cPZbbbe8paLsHfkK+U= +google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= @@ -576,7 +576,6 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v2 v2.2.2/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/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/go.mod b/go.mod index a0640b41..d51f10a2 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module github.com/dunglas/mercure -go 1.21 +go 1.22.0 -toolchain go1.22.0 +toolchain go1.23.2 retract ( v0.14.7 // CI problem @@ -10,49 +10,47 @@ retract ( ) require ( - github.com/dgraph-io/ristretto v0.1.1 + github.com/dgraph-io/ristretto v1.0.0 github.com/gofrs/uuid v4.4.0+incompatible github.com/golang-jwt/jwt/v5 v5.2.1 github.com/gorilla/handlers v1.5.2 github.com/gorilla/mux v1.8.1 github.com/hashicorp/golang-lru v1.0.2 github.com/kevburnsjr/skipfilter v0.0.1 - github.com/prometheus/client_golang v1.20.0 + github.com/prometheus/client_golang v1.20.5 github.com/prometheus/client_model v0.6.1 - github.com/spf13/cobra v1.6.1 + github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 - github.com/unrolled/secure v1.15.0 + github.com/unrolled/secure v1.16.0 github.com/yosida95/uritemplate/v3 v3.0.2 - go.etcd.io/bbolt v1.3.10 + go.etcd.io/bbolt v1.3.11 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.26.0 + golang.org/x/crypto v0.28.0 ) require ( github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145 // indirect github.com/RoaringBitmap/roaring v1.9.4 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.13.0 // indirect + github.com/bits-and-blooms/bitset v1.14.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/golang/glog v1.2.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/inconshreveable/mousetrap v1.0.1 // indirect - github.com/klauspost/compress v1.17.9 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mschoch/smat v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect @@ -61,11 +59,11 @@ require ( github.com/spf13/cast v1.7.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect + golang.org/x/net v0.30.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 6f59ff59..76c5578f 100644 --- a/go.sum +++ b/go.sum @@ -8,22 +8,19 @@ 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/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= -github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/bits-and-blooms/bitset v1.14.3 h1:Gd2c8lSNf9pKXom5JtD7AaKO8o7fGQ2LtFj1436qilA= +github.com/bits-and-blooms/bitset v1.14.3/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= 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/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= -github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgraph-io/ristretto v1.0.0 h1:SYG07bONKMlFDUYu5pEu3DGAh8c2OFNzKm6G9J4Si84= +github.com/dgraph-io/ristretto v1.0.0/go.mod h1:jTi2FiYEhQ1NsMmA7DeBykizjOuY88NhKBkepyu1jPc= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -36,9 +33,6 @@ github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1 github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= -github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= 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/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= @@ -50,12 +44,12 @@ github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iP 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/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= -github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/kevburnsjr/skipfilter v0.0.1 h1:EWl1lWUJfIehrKYIEkps0Cl67lCfS2pUM9iZFNajp7g= github.com/kevburnsjr/skipfilter v0.0.1/go.mod h1:jfaRyFOYVUtIa6IIC+0mB1qiZqhHw+DKvFowCBuijSk= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -70,19 +64,19 @@ github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= 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/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= -github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +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/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= -github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +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.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= 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/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -98,52 +92,45 @@ 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 v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= -github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +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/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 v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/unrolled/secure v1.15.0 h1:q7x+pdp8jAHnbzxu6UheP8fRlG/rwYTb8TPuQ3rn9Og= -github.com/unrolled/secure v1.15.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= +github.com/unrolled/secure v1.16.0 h1:XgdAsS/Zl50ZfZPRJK6WpicFttfrsFYFd0+ONDBJubU= +github.com/unrolled/secure v1.16.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= -go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= -go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ= +go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= +go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= 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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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= diff --git a/hub.go b/hub.go index f11462f0..b35e6d5a 100644 --- a/hub.go +++ b/hub.go @@ -330,7 +330,7 @@ func NewHub(options ...Option) (*Hub, error) { } if opt.topicSelectorStore == nil { - tss, err := NewTopicSelectorStoreRistretto(TopicSelectorStoreRistrettoDefaultCacheNumCounters, TopicSelectorStoreRistrettoCacheMaxCost) + tss, err := NewTopicSelectorStoreLRU(DefaultTopicSelectorStoreLRUMaxEntriesPerShard, DefaultTopicSelectorStoreLRUShardCount) if err != nil { return nil, err } diff --git a/topic_selector.go b/topic_selector.go index 09f74eb6..dd975197 100644 --- a/topic_selector.go +++ b/topic_selector.go @@ -8,8 +8,8 @@ import ( ) type TopicSelectorStoreCache interface { - Get(key interface{}) (interface{}, bool) - Set(key interface{}, value interface{}, n int64) bool + Get(key string) (interface{}, bool) + Set(key string, value interface{}, n int64) bool } // TopicSelectorStore caches compiled templates to improve memory and CPU usage. diff --git a/topic_selector_lru.go b/topic_selector_lru.go index 068f8ced..8076dae5 100644 --- a/topic_selector_lru.go +++ b/topic_selector_lru.go @@ -31,11 +31,11 @@ func NewTopicSelectorStoreLRU(maxEntriesPerShard, shardCount int64) (*TopicSelec type shardedLRUCache map[int]*lru.Cache -func (c *shardedLRUCache) Get(k interface{}) (interface{}, bool) { +func (c *shardedLRUCache) Get(k string) (interface{}, bool) { return c.getShard(k).Get(k) } -func (c *shardedLRUCache) Set(k interface{}, v interface{}, _ int64) bool { +func (c *shardedLRUCache) Set(k string, v interface{}, _ int64) bool { c.getShard(k).Add(k, v) return true diff --git a/topic_selector_ristretto.go b/topic_selector_ristretto.go index 673b45ea..f96266f2 100644 --- a/topic_selector_ristretto.go +++ b/topic_selector_ristretto.go @@ -21,7 +21,7 @@ func NewTopicSelectorStoreRistretto(cacheNumCounters, cacheMaxCost int64) (*Topi return &TopicSelectorStore{}, nil } - cache, err := ristretto.NewCache(&ristretto.Config{ + cache, err := ristretto.NewCache(&ristretto.Config[string, interface{}]{ NumCounters: cacheNumCounters, MaxCost: cacheMaxCost, BufferItems: 64, diff --git a/topic_selector_ristretto_test.go b/topic_selector_ristretto_test.go index 6275fbea..f29f47de 100644 --- a/topic_selector_ristretto_test.go +++ b/topic_selector_ristretto_test.go @@ -9,7 +9,7 @@ import ( ) func TestMatchRistretto(t *testing.T) { - cache, _ := ristretto.NewCache(&ristretto.Config{ + cache, _ := ristretto.NewCache(&ristretto.Config[string, interface{}]{ NumCounters: TopicSelectorStoreRistrettoDefaultCacheNumCounters, MaxCost: TopicSelectorStoreRistrettoCacheMaxCost, BufferItems: 64, From bf5e08da4f9e7121fbd8bc09d4fde965ec64d438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 22 Oct 2024 22:30:32 +0200 Subject: [PATCH 26/71] ci: better GoReleaser config for tags --- .goreleaser.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index b8dfed7b..104e4f60 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -23,10 +23,12 @@ env: builds: - id: caddy dir: caddy/mercure - flags: - -tags=nobadger,nomysql,nopgx ldflags: - -X 'github.com/caddyserver/caddy/v2.CustomVersion=Mercure.rocks {{ .Version }} Caddy' + tags: + - nobadger + - nomysql + - nopgx goos: - linux - darwin From 6c511ee5de67dea2ed241ee61d10d165a70b031d Mon Sep 17 00:00:00 2001 From: Benedikt Heine Date: Tue, 22 Oct 2024 14:39:18 +0200 Subject: [PATCH 27/71] Make the nodePort configurable in case NodePort is used as a service. --- charts/mercure/README.md | 1 + charts/mercure/templates/service.yaml | 3 +++ charts/mercure/values.yaml | 2 ++ 3 files changed, 6 insertions(+) diff --git a/charts/mercure/README.md b/charts/mercure/README.md index ee52967c..157074bb 100644 --- a/charts/mercure/README.md +++ b/charts/mercure/README.md @@ -52,6 +52,7 @@ To install the chart with the release name `my-release`, run the following comma | securityContext | object | `{}` | Container [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container). See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) for details. | | service.annotations | object | `{}` | | | service.port | int | `80` | Service port. | +| service.nodePort | int | 0 | The exposed nodePort. Required when `service.type` is [`"NodePort"`](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport). | | service.targetPort | int | `80` | Service target port. | | service.type | string | `"ClusterIP"` | Kubernetes [service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types). | | serviceAccount.annotations | object | `{}` | Annotations to add to the service account. | diff --git a/charts/mercure/templates/service.yaml b/charts/mercure/templates/service.yaml index 3c87295c..d4c84eff 100644 --- a/charts/mercure/templates/service.yaml +++ b/charts/mercure/templates/service.yaml @@ -16,6 +16,9 @@ spec: targetPort: {{ .Values.service.targetPort }} protocol: TCP name: http + {{- if .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} selector: {{- include "mercure.selectorLabels" . | nindent 4 }} --- diff --git a/charts/mercure/values.yaml b/charts/mercure/values.yaml index 8669ba2f..399173b5 100644 --- a/charts/mercure/values.yaml +++ b/charts/mercure/values.yaml @@ -121,6 +121,8 @@ service: port: 80 # -- Service target port. targetPort: 80 + # -- Set this, to pin the external nodePort in case `service.type` is `NodePort`. + nodePort: annotations: {} ingress: From 04030c18d7ea63bb240cb50b6bb3cfd215c9c807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 23 Oct 2024 17:50:45 +0200 Subject: [PATCH 28/71] ci: bump super-linter (#961) --- .github/dependabot.yml | 3 +- .github/linters/.markdown-lint.yml | 14 +- .github/pull_request_template.md | 2 +- .github/workflows/cd-chart.yml | 2 +- .github/workflows/cd.yml | 4 +- .github/workflows/ci-chart.yml | 2 +- .github/workflows/ci.yml | 10 +- .github/workflows/lint.yml | 3 +- .prettierignore | 9 + .vscode/launch.json | 38 +- CONTRIBUTING.md | 36 +- README.md | 8 +- cmd/mercure/mercure.yaml | 18 +- conformance-tests/mercure.spec.ts | 274 +++++---- conformance-tests/playwright.config.ts | 28 +- docs/README.md | 44 +- docs/UPGRADE.md | 24 +- docs/ecosystem/awesome.md | 108 ++-- docs/ecosystem/conformance-tests.md | 6 +- docs/ecosystem/github-actions.md | 34 +- docs/ecosystem/help.md | 4 +- docs/ecosystem/hotwire.md | 15 +- docs/getting-started.md | 63 ++- docs/hub/cloud.md | 8 +- docs/hub/cluster.md | 49 +- docs/hub/config.md | 37 +- docs/hub/cookbooks.md | 5 +- docs/hub/debug.md | 2 +- docs/hub/install.md | 19 +- docs/hub/license.md | 8 +- docs/hub/load-test.md | 26 +- docs/hub/traefik.md | 22 +- docs/hub/troubleshooting.md | 24 +- docs/mercure.md | 34 +- docs/spec/faq.md | 9 +- docs/spec/use-cases.md | 23 +- .../chat/chart/mercure-example-chat/README.md | 71 +-- examples/chat/static/chat.js | 132 ++--- examples/chat/templates/chat.html | 92 +-- examples/chat/templates/join.html | 37 +- examples/chat/templates/layout.html | 82 +-- examples/publish/node.js | 44 +- public/app.js | 319 +++++------ public/index.html | 526 ++++++++++-------- spec/openapi.yaml | 4 +- 45 files changed, 1262 insertions(+), 1060 deletions(-) create mode 100644 .prettierignore diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e993f44f..f8fe74b1 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,7 +1,6 @@ version: 2 updates: - - - package-ecosystem: github-actions + - package-ecosystem: github-actions directory: / schedule: interval: weekly diff --git a/.github/linters/.markdown-lint.yml b/.github/linters/.markdown-lint.yml index f10f13af..e4c5bd91 100644 --- a/.github/linters/.markdown-lint.yml +++ b/.github/linters/.markdown-lint.yml @@ -18,19 +18,19 @@ ############### # Rules by id # ############### -MD004: false # Unordered list style +MD004: false # Unordered list style MD007: - indent: 2 # Unordered list indentation + indent: 2 # Unordered list indentation MD010: ignore_code_languages: [caddyfile] MD013: false MD026: - punctuation: ".,;:!。,;:" # List of not allowed -MD029: false # Ordered list item prefix -MD033: false # Allow inline HTML -MD036: false # Emphasis used instead of a heading + punctuation: ".,;:!。,;:" # List of not allowed +MD029: false # Ordered list item prefix +MD033: false # Allow inline HTML +MD036: false # Emphasis used instead of a heading ################# # Rules by tags # ################# -blank_lines: false # Error on blank lines +blank_lines: false # Error on blank lines diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index ff231e09..45b95197 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -22,4 +22,4 @@ Examples: docs: Add docs for X spec: Z disambiguation ---> \ No newline at end of file +--> diff --git a/.github/workflows/cd-chart.yml b/.github/workflows/cd-chart.yml index 332feae2..07cc7aa9 100644 --- a/.github/workflows/cd-chart.yml +++ b/.github/workflows/cd-chart.yml @@ -3,7 +3,7 @@ name: Release Chart on: push: tags: - - 'v*' + - "v*" jobs: release: diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index f92fad51..1c837d11 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -29,7 +29,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: '1.23' + go-version: "1.23" cache-dependency-path: | go.sum caddy/go.sum @@ -68,7 +68,7 @@ jobs: if: startsWith(github.ref, 'refs/tags/v') uses: actions/attest-build-provenance@v1 with: - subject-path: '${{ github.workspace }}/dist/**/mercure' + subject-path: "${{ github.workspace }}/dist/**/mercure" - name: Display version run: dist/caddy_linux_amd64_v1/mercure version diff --git a/.github/workflows/ci-chart.yml b/.github/workflows/ci-chart.yml index 541f2613..f5726202 100644 --- a/.github/workflows/ci-chart.yml +++ b/.github/workflows/ci-chart.yml @@ -26,7 +26,7 @@ jobs: - uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: "3.10" - name: Set up chart-testing uses: helm/chart-testing-action@v2 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ce6d9df0..dc40f345 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ on: - v*.*.* env: - GO111MODULE: 'on' + GO111MODULE: "on" jobs: golangci: @@ -23,7 +23,7 @@ jobs: - uses: actions/setup-go@v5 with: - go-version: '1.23' + go-version: "1.23" cache-dependency-path: | go.sum caddy/go.sum @@ -37,7 +37,7 @@ jobs: test: strategy: matrix: - go: [ '1.21', '1.22', '1.23' ] + go: ["1.21", "1.22", "1.23"] fail-fast: false name: Test runs-on: ubuntu-latest @@ -82,8 +82,8 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: '16' - cache: 'npm' + node-version: "16" + cache: "npm" cache-dependency-path: conformance-tests/package-lock.json - name: Install Playwrigth dependencies diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e4f60975..d7697f45 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -35,7 +35,6 @@ jobs: VALIDATE_GO_RELEASER: false VALIDATE_PHP_PHPCS: false VALIDATE_KUBERNETES_KUBECONFORM: false - VALIDATE_JAVASCRIPT_PRETTIER: false - VALIDATE_TYPESCRIPT_PRETTIER: false + VALIDATE_JAVASCRIPT_STANDARD: false VALIDATE_TYPESCRIPT_STANDARD: false VALIDATE_PYTHON_PYLINT: false diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..a85af267 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,9 @@ +# The spec is in the IETF flavor of Markdown +spec/mercure.md + +# Ignore Kubernetes templates +**/charts/**/*.yaml +**/chart/**/*.yaml +charts/mercure/README.md + +*cache diff --git a/.vscode/launch.json b/.vscode/launch.json index f410a5c4..de748d38 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,21 +1,21 @@ { - "version": "0.2.0", - "configurations": [ - { - "name": "Launch the hub", - "type": "go", - "request": "launch", - "mode": "auto", - "program": "${workspaceFolder}/caddy/mercure", - "env": { - "MERCURE_PUBLISHER_JWT_KEY": "!ChangeThisMercureHubJWTSecretKey!", - "MERCURE_SUBSCRIBER_JWT_KEY": "!ChangeThisMercureHubJWTSecretKey!", - "MERCURE_EXTRA_DIRECTIVES": "anonymous\nwrite_timeout 10s", - "GLOBAL_OPTIONS": "debug", - "SERVER_NAME": "localhost, host.docker.internal", - "CADDY_SERVER_EXTRA_DIRECTIVES": "tls internal" - }, - "args": ["run", "--config", "../../dev.Caddyfile"] - } - ] + "version": "0.2.0", + "configurations": [ + { + "name": "Launch the hub", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/caddy/mercure", + "env": { + "MERCURE_PUBLISHER_JWT_KEY": "!ChangeThisMercureHubJWTSecretKey!", + "MERCURE_SUBSCRIBER_JWT_KEY": "!ChangeThisMercureHubJWTSecretKey!", + "MERCURE_EXTRA_DIRECTIVES": "anonymous\nwrite_timeout 10s", + "GLOBAL_OPTIONS": "debug", + "SERVER_NAME": "localhost, host.docker.internal", + "CADDY_SERVER_EXTRA_DIRECTIVES": "tls internal" + }, + "args": ["run", "--config", "../../dev.Caddyfile"] + } + ] } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b180394a..2bc2dd93 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,13 +14,13 @@ If you include code from another project, please mention it in the Pull Request The commit message must follow the [Conventional Commits specification](https://www.conventionalcommits.org/). The following types are allowed: -* `fix`: bugfix -* `feat`: new feature -* `docs`: change in the documentation -* `spec`: spec change -* `test`: test-related change -* `perf`: performance optimization -* `ci`: CI-related change +- `fix`: bugfix +- `feat`: new feature +- `docs`: change in the documentation +- `spec`: spec change +- `test`: test-related change +- `perf`: performance optimization +- `ci`: CI-related change Examples: @@ -61,10 +61,10 @@ Go to `http://localhost:3000` and enjoy! When you send a PR, make sure that: -* You add valid test cases. -* Tests are green. -* You make a PR on the related documentation. -* You make the PR on the same branch you based your changes on. If you see commits +- You add valid test cases. +- Tests are green. +- You make a PR on the related documentation. +- You make the PR on the same branch you based your changes on. If you see commits that you did not make in your PR, you're doing it wrong. ### Configuring Visual Studio Code @@ -88,10 +88,10 @@ It is then converted in the [the "xml2rfc" Version 3 Vocabulary](https://tools.i To contribute to the protocol itself: -* Make your changes -* [Download Mmark](https://github.com/mmarkdown/mmark/releases) -* [Download `xml2rfc` using pip](https://pypi.org/project/xml2rfc/): `pip install xml2rfc` -* Generate the XML file: `mmark spec/mercure.md > spec/mercure.xml` -* Validate the generated XML file and generate the text file: `xml2rfc --text --v3 spec/mercure.xml` -* Remove non-ASCII characters from the generated `mercure.txt` file (example: K**é**vin) -* If appropriate, be sure to update the reference implementation accordingly +- Make your changes +- [Download Mmark](https://github.com/mmarkdown/mmark/releases) +- [Download `xml2rfc` using pip](https://pypi.org/project/xml2rfc/): `pip install xml2rfc` +- Generate the XML file: `mmark spec/mercure.md > spec/mercure.xml` +- Validate the generated XML file and generate the text file: `xml2rfc --text --v3 spec/mercure.xml` +- Remove non-ASCII characters from the generated `mercure.txt` file (example: K**é**vin) +- If appropriate, be sure to update the reference implementation accordingly diff --git a/README.md b/README.md index d2e742cd..69ad0c36 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

Mercure: Real-time Made Easy

-*Protocol and Reference Implementation* +_Protocol and Reference Implementation_ Mercure is a protocol for pushing data updates to web browsers and other HTTP clients in a convenient, fast, reliable, and battery-efficient way. It is especially useful to publish async and real-time updates of resources served through web APIs, to reactive web and mobile apps. @@ -14,9 +14,9 @@ It is especially useful to publish async and real-time updates of resources serv ![Subscriptions Schema](spec/subscriptions.png) -* [Getting started](https://mercure.rocks/docs/getting-started) -* [Full documentation](https://mercure.rocks/docs) -* [Demo](https://demo.mercure.rocks/) +- [Getting started](https://mercure.rocks/docs/getting-started) +- [Full documentation](https://mercure.rocks/docs) +- [Demo](https://demo.mercure.rocks/) [The protocol](https://mercure.rocks/spec) is maintained in this repository and is also available as [an Internet-Draft](https://datatracker.ietf.org/doc/draft-dunglas-mercure/). diff --git a/cmd/mercure/mercure.yaml b/cmd/mercure/mercure.yaml index 2f4fbf6d..59f1677b 100644 --- a/cmd/mercure/mercure.yaml +++ b/cmd/mercure/mercure.yaml @@ -3,10 +3,22 @@ debug: true allow_anonymous: true #cert_file: fixtures/tls/server.crt #key_file: fixtures/tls/server.key -cors_allowed_origins: [http://localhost:3000, http://localhost:3001, http://localhost:5000, http://localhost:8000] +cors_allowed_origins: + [ + http://localhost:3000, + http://localhost:3001, + http://localhost:5000, + http://localhost:8000, + ] transport_url: bolt://update.db -jwt_key: '!ChangeThisMercureHubJWTSecretKey!' -publish_allowed_origins: [http://localhost:3000, http://localhost:3001, http://localhost:5000, http://localhost:8000] +jwt_key: "!ChangeThisMercureHubJWTSecretKey!" +publish_allowed_origins: + [ + http://localhost:3000, + http://localhost:3001, + http://localhost:5000, + http://localhost:8000, + ] subscriptions: true metrics_enabled: false diff --git a/conformance-tests/mercure.spec.ts b/conformance-tests/mercure.spec.ts index d62b76d4..411a85d0 100644 --- a/conformance-tests/mercure.spec.ts +++ b/conformance-tests/mercure.spec.ts @@ -1,124 +1,204 @@ -import { test, expect } from '@playwright/test'; +import { test, expect } from "@playwright/test"; import { randomBytes } from "crypto"; function randomString() { - return randomBytes(20).toString('hex'); + return randomBytes(20).toString("hex"); } -test.beforeEach(async ({ page }) => await page.goto('/')); +test.beforeEach(async ({ page }) => await page.goto("/")); -test.describe('Publish update', () => { +test.describe("Publish update", () => { const randomStrings: string[] = Array.from({ length: 6 }, randomString); - type Data = { name: string, updateTopics: string[], topicSelectors: string[], mustBeReceived: boolean, updateID?: string, private?: true }; + type Data = { + name: string; + updateTopics: string[]; + topicSelectors: string[]; + mustBeReceived: boolean; + updateID?: string; + private?: true; + }; const dataset: Data[] = [ - { name: 'raw string', mustBeReceived: true, updateTopics: [randomStrings[0]], topicSelectors: [randomStrings[0]] }, - { name: 'multiple topics', mustBeReceived: true, updateTopics: [randomString(), randomStrings[1]], topicSelectors: [randomStrings[1]] }, - { name: 'multiple topic selectors', mustBeReceived: true, updateTopics: [randomStrings[2]], topicSelectors: ['foo', randomStrings[2]] }, - { name: 'URI', mustBeReceived: true, updateTopics: [`https://example.net/foo/${randomStrings[3]}`], topicSelectors: [`https://example.net/foo/${randomStrings[3]}`] }, - { name: 'URI template', mustBeReceived: true, updateTopics: [`https://example.net/foo/${randomStrings[4]}`], topicSelectors: ['https://example.net/foo/{random}'] }, - { name: 'nonmatching raw string', mustBeReceived: false, updateTopics: [`will-not-match}`], topicSelectors: ['another-name'] }, - { name: 'nonmatching URI', mustBeReceived: false, updateTopics: [`https://example.net/foo/will-not-match}`], topicSelectors: ['https://example.net/foo/another-name'] }, - { name: 'nonmatching URI template', mustBeReceived: false, updateTopics: [`https://example.net/foo/will-not-match}`], topicSelectors: ['https://example.net/bar/{var}'] }, - { name: 'private raw string', mustBeReceived: false, private: true, updateTopics: [randomStrings[0]], topicSelectors: [randomStrings[0]] }, - { name: 'private URI', mustBeReceived: false, private: true, updateTopics: [`https://example.net/foo/${randomStrings[3]}`], topicSelectors: [`https://example.net/foo/${randomStrings[3]}`] }, - { name: 'private URI template', mustBeReceived: false, private: true, updateTopics: [`https://example.net/foo/${randomStrings[4]}`], topicSelectors: ['https://example.net/foo/{random}'] }, + { + name: "raw string", + mustBeReceived: true, + updateTopics: [randomStrings[0]], + topicSelectors: [randomStrings[0]], + }, + { + name: "multiple topics", + mustBeReceived: true, + updateTopics: [randomString(), randomStrings[1]], + topicSelectors: [randomStrings[1]], + }, + { + name: "multiple topic selectors", + mustBeReceived: true, + updateTopics: [randomStrings[2]], + topicSelectors: ["foo", randomStrings[2]], + }, + { + name: "URI", + mustBeReceived: true, + updateTopics: [`https://example.net/foo/${randomStrings[3]}`], + topicSelectors: [`https://example.net/foo/${randomStrings[3]}`], + }, + { + name: "URI template", + mustBeReceived: true, + updateTopics: [`https://example.net/foo/${randomStrings[4]}`], + topicSelectors: ["https://example.net/foo/{random}"], + }, + { + name: "nonmatching raw string", + mustBeReceived: false, + updateTopics: [`will-not-match}`], + topicSelectors: ["another-name"], + }, + { + name: "nonmatching URI", + mustBeReceived: false, + updateTopics: [`https://example.net/foo/will-not-match}`], + topicSelectors: ["https://example.net/foo/another-name"], + }, + { + name: "nonmatching URI template", + mustBeReceived: false, + updateTopics: [`https://example.net/foo/will-not-match}`], + topicSelectors: ["https://example.net/bar/{var}"], + }, + { + name: "private raw string", + mustBeReceived: false, + private: true, + updateTopics: [randomStrings[0]], + topicSelectors: [randomStrings[0]], + }, + { + name: "private URI", + mustBeReceived: false, + private: true, + updateTopics: [`https://example.net/foo/${randomStrings[3]}`], + topicSelectors: [`https://example.net/foo/${randomStrings[3]}`], + }, + { + name: "private URI template", + mustBeReceived: false, + private: true, + updateTopics: [`https://example.net/foo/${randomStrings[4]}`], + topicSelectors: ["https://example.net/foo/{random}"], + }, ]; for (const data of dataset) { test(data.name, async ({ page }) => { - page.on('console', msg => console.log(msg.text())); + page.on("console", (msg) => console.log(msg.text())); data.updateID = `id-${JSON.stringify(data.updateTopics)}`; - const { received, contentType, status, body } = await page.evaluate(async (data) => { - const receivedResult = Symbol('received'); - const notReceivedResult = Symbol('not received'); - - let resolveReady: () => void; - const ready = new Promise((resolve) => { - resolveReady = () => resolve(true); - }); - - let resolveReceived: () => void; - const received = new Promise((resolve) => { - resolveReceived = () => resolve(receivedResult); - }); - - const timeout = new Promise((resolve) => setTimeout(resolve, 2000, notReceivedResult)); - - const url = new window.URL('/.well-known/mercure', window.origin); - data.topicSelectors.forEach(topicSelector => url.searchParams.append('topic', topicSelector)); - - const event = new window.URLSearchParams(); - data.updateTopics.forEach(updateTopic => event.append('topic', updateTopic)); - event.set('id', data.updateID); - event.set('data', `data for - - ${data.name}`); - if (data.private) event.set('private', 'on'); - - console.log(`data: ${JSON.stringify(data)}`); - - console.log(`creating EventSource: ${url}`); - const es = new EventSource(url); - console.log('EventSource created'); - - es.onopen = () => { - console.log('EventSource opened'); - resolveReady(); - } - - let id: string; - es.onmessage = (e) => { - console.log(`EventSource event received: ${e.data}`); - if ( - e.type === 'message' && - e.lastEventId === event.get('id') && - e.data === event.get('data') - ) { - es.close(); - resolveReceived(); - } - }; - - await ready; // Wait for the EventSource to be ready - - console.log(`Creating POST request: ${event.toString()}`); - const resp = await fetch(`/.well-known/mercure`, { - method: 'POST', - headers: { 'Authorization': 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiKiJdfX0.bVXdlWXwfw9ySx7-iV5OpUSHo34RkjUdVzDLBcc6l_g' }, - body: event, - }); - - id = await resp.text(); - console.log(`POST request done: ${JSON.stringify({ status: resp.status, id, event: event.toString() })}`); - - switch (await Promise.race([received, timeout])) { - case receivedResult: - return { - received: true, - contentType: resp.headers.get('Content-Type'), - status: resp.status, - body: id, - }; - - case notReceivedResult: - return { - received: false, + const { received, contentType, status, body } = await page.evaluate( + async (data) => { + const receivedResult = Symbol("received"); + const notReceivedResult = Symbol("not received"); + + let resolveReady: () => void; + const ready = new Promise((resolve) => { + resolveReady = () => resolve(true); + }); + + let resolveReceived: () => void; + const received = new Promise((resolve) => { + resolveReceived = () => resolve(receivedResult); + }); + + const timeout = new Promise((resolve) => + setTimeout(resolve, 2000, notReceivedResult), + ); + + const url = new window.URL("/.well-known/mercure", window.origin); + data.topicSelectors.forEach((topicSelector) => + url.searchParams.append("topic", topicSelector), + ); + + const event = new window.URLSearchParams(); + data.updateTopics.forEach((updateTopic) => + event.append("topic", updateTopic), + ); + event.set("id", data.updateID); + event.set( + "data", + `data for + + ${data.name}`, + ); + if (data.private) event.set("private", "on"); + + console.log(`data: ${JSON.stringify(data)}`); + + console.log(`creating EventSource: ${url}`); + const es = new EventSource(url); + console.log("EventSource created"); + + es.onopen = () => { + console.log("EventSource opened"); + resolveReady(); + }; + + let id: string; + es.onmessage = (e) => { + console.log(`EventSource event received: ${e.data}`); + if ( + e.type === "message" && + e.lastEventId === event.get("id") && + e.data === event.get("data") + ) { + es.close(); + resolveReceived(); } - } - - }, data); + }; + + await ready; // Wait for the EventSource to be ready + + console.log(`Creating POST request: ${event.toString()}`); + const resp = await fetch(`/.well-known/mercure`, { + method: "POST", + headers: { + Authorization: + "Bearer eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiKiJdfX0.bVXdlWXwfw9ySx7-iV5OpUSHo34RkjUdVzDLBcc6l_g", + }, + body: event, + }); + + id = await resp.text(); + console.log( + `POST request done: ${JSON.stringify({ status: resp.status, id, event: event.toString() })}`, + ); + + switch (await Promise.race([received, timeout])) { + case receivedResult: + return { + received: true, + contentType: resp.headers.get("Content-Type"), + status: resp.status, + body: id, + }; + + case notReceivedResult: + return { + received: false, + }; + } + }, + data, + ); expect(received).toBe(data.mustBeReceived); if (data.mustBeReceived) { expect(contentType).toMatch(/^text\/plain(?:$|;.*)/); expect(status).toBe(200); - if (process.env.CUSTOM_ID) - expect(body).toBe(data.updateID); + if (process.env.CUSTOM_ID) expect(body).toBe(data.updateID); } }); } diff --git a/conformance-tests/playwright.config.ts b/conformance-tests/playwright.config.ts index 8a410c57..0168b611 100644 --- a/conformance-tests/playwright.config.ts +++ b/conformance-tests/playwright.config.ts @@ -1,17 +1,17 @@ -import type { PlaywrightTestConfig } from '@playwright/test'; -import { devices } from '@playwright/test'; +import type { PlaywrightTestConfig } from "@playwright/test"; +import { devices } from "@playwright/test"; /** * Read environment variables from file. * https://github.com/motdotla/dotenv */ -require('dotenv').config(); +require("dotenv").config(); /** * See https://playwright.dev/docs/test-configuration. */ const config: PlaywrightTestConfig = { - testDir: './.', + testDir: "./.", /* Maximum time one test can run for. */ timeout: 10 * 1000, expect: { @@ -19,7 +19,7 @@ const config: PlaywrightTestConfig = { * Maximum time expect() should wait for the condition to be met. * For example in `await expect(locator).toHaveText();` */ - timeout: 5000 + timeout: 5000, }, /* Fail the build on CI if you accidentally left test.only in the source code. */ forbidOnly: !!process.env.CI, @@ -28,15 +28,15 @@ const config: PlaywrightTestConfig = { /* Opt out of parallel tests on CI. */ workers: process.env.CI ? 1 : undefined, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ - reporter: 'html', + reporter: "html", /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ use: { /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ actionTimeout: 0, /* Base URL to use in actions like `await page.goto('/')`. */ - baseURL: process.env.BASE_URL ?? 'https://localhost/.well-known/mercure', + baseURL: process.env.BASE_URL ?? "https://localhost/.well-known/mercure", /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: 'on-first-retry', + trace: "on-first-retry", /* ignore HTTPS errors */ ignoreHTTPSErrors: true, }, @@ -44,23 +44,23 @@ const config: PlaywrightTestConfig = { /* Configure projects for major browsers */ projects: [ { - name: 'chromium', + name: "chromium", use: { - ...devices['Desktop Chrome'], + ...devices["Desktop Chrome"], }, }, { - name: 'firefox', + name: "firefox", use: { - ...devices['Desktop Firefox'], + ...devices["Desktop Firefox"], }, }, { - name: 'webkit', + name: "webkit", use: { - ...devices['Desktop Safari'], + ...devices["Desktop Safari"], }, }, diff --git a/docs/README.md b/docs/README.md index 9734c02a..a134f36a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,33 +1,33 @@ # Mercure Documentation -* [Mercure in a Few Words](mercure.md) -* [Getting Started](getting-started.md) +- [Mercure in a Few Words](mercure.md) +- [Getting Started](getting-started.md) ## Protocol Specification -* [The Specification](../spec/mercure.md) (also available as an [IETF's Internet Draft](https://datatracker.ietf.org/doc/draft-dunglas-mercure/) designed to be published as an RFC) -* [Case studies and use cases](spec/use-cases.md) -* [Frequently Asked Questions](spec/faq.md) -* [OpenAPI spec](https://github.com/dunglas/mercure/blob/master/spec/openapi.yaml) +- [The Specification](../spec/mercure.md) (also available as an [IETF's Internet Draft](https://datatracker.ietf.org/doc/draft-dunglas-mercure/) designed to be published as an RFC) +- [Case studies and use cases](spec/use-cases.md) +- [Frequently Asked Questions](spec/faq.md) +- [OpenAPI spec](https://github.com/dunglas/mercure/blob/master/spec/openapi.yaml) ## Mercure.rocks Hub -* [Installing the Mercure.rocks Hub](hub/install.md) -* [Configuration](hub/config.md) -* [The Cloud version](hub/cloud.md) -* [Creating a cluster of hubs](hub/cluster.md) -* [Cookbooks](hub/cookbooks.md) -* [Running behind NGINX](hub/nginx.md) -* [Running behind Traefik Proxy](hub/traefik.md) -* [Troubleshooting](hub/troubleshooting.md) -* [Debug the Mercure.rocks Hub](hub/debug.md) -* [Upgrade to new versions](UPGRADE.md) -* [Load Testing](hub/load-test.md) +- [Installing the Mercure.rocks Hub](hub/install.md) +- [Configuration](hub/config.md) +- [The Cloud version](hub/cloud.md) +- [Creating a cluster of hubs](hub/cluster.md) +- [Cookbooks](hub/cookbooks.md) +- [Running behind NGINX](hub/nginx.md) +- [Running behind Traefik Proxy](hub/traefik.md) +- [Troubleshooting](hub/troubleshooting.md) +- [Debug the Mercure.rocks Hub](hub/debug.md) +- [Upgrade to new versions](UPGRADE.md) +- [Load Testing](hub/load-test.md) ## Ecosystem -* [Awesome Mercure: Libraries, Examples and Learning Resources](ecosystem/awesome.md) -* [Using a Mercure Service in Your GitHub Actions](ecosystem/github-actions.md) -* [Using Mercure and Hotwire to Stream Page Changes](ecosystem/hotwire.md) -* [Getting Help](ecosystem/help.md) -* [Conformance Tests](ecosystem/conformance-tests.md) +- [Awesome Mercure: Libraries, Examples and Learning Resources](ecosystem/awesome.md) +- [Using a Mercure Service in Your GitHub Actions](ecosystem/github-actions.md) +- [Using Mercure and Hotwire to Stream Page Changes](ecosystem/hotwire.md) +- [Getting Help](ecosystem/help.md) +- [Conformance Tests](ecosystem/conformance-tests.md) diff --git a/docs/UPGRADE.md b/docs/UPGRADE.md index 667f6b29..faf45aac 100644 --- a/docs/UPGRADE.md +++ b/docs/UPGRADE.md @@ -11,7 +11,7 @@ Before: ```json { "mercure": { - "payload": {"foo": "bar"} + "payload": { "foo": "bar" } } } ``` @@ -22,7 +22,7 @@ After: { "mercure": { "payloads": { - "*": {"foo": "bar"} + "*": { "foo": "bar" } } } } @@ -117,18 +117,18 @@ Before switching to the Caddy build, be sure to [migrate your configuration](hub This version is in sync with the latest version of the specification, which changed a lot. Upgrading to 0.10 **requires to change your code**. Carefully read this guide before upgrading the hub. -* Private updates are now handled differently. *Targets* don't exist anymore. They have been superseded by the concept of *topic selectors*. +- Private updates are now handled differently. _Targets_ don't exist anymore. They have been superseded by the concept of _topic selectors_. To send a private update, the publisher must now set the new `private` field to `on` when sending the `POST` request. The topics of the update must also match at least one selector (a URI Template, a raw string or `*` to match all topics) provided in the `mercure.publish` claim of the JWT. To receive a private update, at least one topic of this update must match at least one selector provided in the `mercure.subscribe` claim of the JWT. -* The structure of the JSON-LD document included in subscription events changed. Especially, `"@type": "https://mercure.rocks/Subscription"` is now `"type": "Subscription"` and `"@id": "/.well-known/mercure/subscriptions/foo/bar"` is now `"id": "/.well-known/mercure/subscriptions/foo/bar"`. -* The `dispatch_subscriptions` config option has been renamed `subscriptions`. -* The `subscriptions_include_ip` config option doesn't exist anymore. To include the subscriber IP (or any other value) in subscription events, use the new `mercure.payload` property of the JWT. -* All IDs generated by the hub (updates ID, subscriptions IDs...) are now URN following the template `urn:uuid:{the-uuid}` (it was `{the-uuid}` before). You may need to update your code if you deal with these IDs. -* The topic `*` is now reserved and allows to subscribe to all topics. +- The structure of the JSON-LD document included in subscription events changed. Especially, `"@type": "https://mercure.rocks/Subscription"` is now `"type": "Subscription"` and `"@id": "/.well-known/mercure/subscriptions/foo/bar"` is now `"id": "/.well-known/mercure/subscriptions/foo/bar"`. +- The `dispatch_subscriptions` config option has been renamed `subscriptions`. +- The `subscriptions_include_ip` config option doesn't exist anymore. To include the subscriber IP (or any other value) in subscription events, use the new `mercure.payload` property of the JWT. +- All IDs generated by the hub (updates ID, subscriptions IDs...) are now URN following the template `urn:uuid:{the-uuid}` (it was `{the-uuid}` before). You may need to update your code if you deal with these IDs. +- The topic `*` is now reserved and allows to subscribe to all topics. ## 0.8 -* According to the new version of the spec, the URL of the Hub changed moved from `/hub` to `/.well-known/mercure` -* `HISTORY_CLEANUP_FREQUENCY`, `HISTORY_SIZE` and `DB_PATH` environment variables have been replaced by the new `TRANSPORT_URL` environment variable -* Lists in `ACME_HOSTS`, `CORS_ALLOWED_ORIGINS`, `PUBLISH_ALLOWED_ORIGINS` must now be space separated -* The public API of the Go library has been totally revamped +- According to the new version of the spec, the URL of the Hub changed moved from `/hub` to `/.well-known/mercure` +- `HISTORY_CLEANUP_FREQUENCY`, `HISTORY_SIZE` and `DB_PATH` environment variables have been replaced by the new `TRANSPORT_URL` environment variable +- Lists in `ACME_HOSTS`, `CORS_ALLOWED_ORIGINS`, `PUBLISH_ALLOWED_ORIGINS` must now be space separated +- The public API of the Go library has been totally revamped diff --git a/docs/ecosystem/awesome.md b/docs/ecosystem/awesome.md index e9084b73..5bcfe131 100644 --- a/docs/ecosystem/awesome.md +++ b/docs/ecosystem/awesome.md @@ -2,89 +2,89 @@ ## Demos -* [Demo hub and debug UI](https://demo.mercure.rocks) ([source code](https://github.com/dunglas/mercure/tree/master/public)): a managed demo hub and the official debugging tools (written in JavaScript) -* [Chat](https://demo-chat.mercure.rocks/) ([source code](https://github.com/dunglas/mercure/tree/master/examples/chat)): a chat, including the list of currently connected users (written in JavaScript and Python) +- [Demo hub and debug UI](https://demo.mercure.rocks) ([source code](https://github.com/dunglas/mercure/tree/master/public)): a managed demo hub and the official debugging tools (written in JavaScript) +- [Chat](https://demo-chat.mercure.rocks/) ([source code](https://github.com/dunglas/mercure/tree/master/examples/chat)): a chat, including the list of currently connected users (written in JavaScript and Python) ## Examples -* [JavaScript (publish, subscribe and presence API)](https://github.com/dunglas/mercure/blob/master/public/app.js) -* [JavaScript (subscribe and presence API)](https://github.com/dunglas/mercure/blob/master/examples/chat/static/chat.js) -* [Node.js (publish)](https://github.com/dunglas/mercure/tree/master/examples/publish/node.js) -* [PHP (publish)](https://github.com/dunglas/mercure/tree/master/examples/publish/php.php) -* [Ruby (publish)](https://github.com/dunglas/mercure/tree/master/examples/publish/ruby.rb) -* [Python (subscribe)](https://github.com/dunglas/mercure/tree/master/examples/subscribe/python.py) -* [Python (cookie authorization)](https://github.com/dunglas/mercure/blob/master/examples/chat/chat.py) -* [API Platform (publish and subscribe)](https://github.com/api-platform/demo): a book catalog updated in real-time using Mercure +- [JavaScript (publish, subscribe and presence API)](https://github.com/dunglas/mercure/blob/master/public/app.js) +- [JavaScript (subscribe and presence API)](https://github.com/dunglas/mercure/blob/master/examples/chat/static/chat.js) +- [Node.js (publish)](https://github.com/dunglas/mercure/tree/master/examples/publish/node.js) +- [PHP (publish)](https://github.com/dunglas/mercure/tree/master/examples/publish/php.php) +- [Ruby (publish)](https://github.com/dunglas/mercure/tree/master/examples/publish/ruby.rb) +- [Python (subscribe)](https://github.com/dunglas/mercure/tree/master/examples/subscribe/python.py) +- [Python (cookie authorization)](https://github.com/dunglas/mercure/blob/master/examples/chat/chat.py) +- [API Platform (publish and subscribe)](https://github.com/api-platform/demo): a book catalog updated in real-time using Mercure ## Documentation and Code Generation -* The Mercure protocol is natively supported by [the AsyncAPI ecosystem](https://www.asyncapi.com/) +- The Mercure protocol is natively supported by [the AsyncAPI ecosystem](https://www.asyncapi.com/) ## Hubs and Server Libraries -* [Go Hub and Server library](https://mercure.rocks) -* [Node.js Hub and Server library](https://github.com/Ilshidur/node-mercure) +- [Go Hub and Server library](https://mercure.rocks) +- [Node.js Hub and Server library](https://github.com/Ilshidur/node-mercure) ## Client Libraries -* [PHP (publish)](https://github.com/symfony/mercure) -* [Python (publish and subscribe)](https://github.com/vitorluis/python-mercure) -* [Dart (publish and subscribe)](https://github.com/wallforfry/dart_mercure) -* [Amphp (publish)](https://github.com/eislambey/amp-mercure-publisher) -* [Java (publish)](https://github.com/vitorluis/java-mercure) +- [PHP (publish)](https://github.com/symfony/mercure) +- [Python (publish and subscribe)](https://github.com/vitorluis/python-mercure) +- [Dart (publish and subscribe)](https://github.com/wallforfry/dart_mercure) +- [Amphp (publish)](https://github.com/eislambey/amp-mercure-publisher) +- [Java (publish)](https://github.com/vitorluis/java-mercure) ## Frameworks and Services Integrations -* [Official Mercure support for the Symfony framework](https://symfony.com/doc/current/mercure.html) -* [Official Mercure support for the API Platform framework](https://api-platform.com/docs/core/mercure/) -* [Using Mercure and Hotwire to stream page changes](hotwire.md) -* [Laravel Mercure Broadcaster](https://github.com/mvanduijker/laravel-mercure-broadcaster) -* [Yii Mercure Behavior](https://github.com/bizley/mercure-behavior) -* [Add a Mercure service in GitHub Actions](github-actions.md) -* [Send a Mercure publish event from GitHub Actions](https://github.com/Ilshidur/action-mercure) +- [Official Mercure support for the Symfony framework](https://symfony.com/doc/current/mercure.html) +- [Official Mercure support for the API Platform framework](https://api-platform.com/docs/core/mercure/) +- [Using Mercure and Hotwire to stream page changes](hotwire.md) +- [Laravel Mercure Broadcaster](https://github.com/mvanduijker/laravel-mercure-broadcaster) +- [Yii Mercure Behavior](https://github.com/bizley/mercure-behavior) +- [Add a Mercure service in GitHub Actions](github-actions.md) +- [Send a Mercure publish event from GitHub Actions](https://github.com/Ilshidur/action-mercure) ## Useful Related Libraries -* [Microsoft's Fetch Event Source, a better JavaScript API for making Event Source requests](https://github.com/Azure/fetch-event-source) -* [`EventSource` polyfill for Edge/IE and old browsers](https://github.com/Yaffle/EventSource) -* [`EventSource` polyfill for React Native](https://github.com/jordanbyron/react-native-event-source) -* [`EventSource` implementation for Node](https://github.com/EventSource/eventsource) -* [Server-Sent Events client for Go](https://github.com/donovanhide/eventsource) -* [Server-Sent Events client for Android and Java](https://github.com/heremaps/oksse) -* [Server-Sent Events client for Swift](https://github.com/inaka/EventSource) -* [JavaScript library to parse `Link` headers](https://github.com/thlorenz/parse-link-header) -* [JavaScript library to decrypt JWE using the WebCrypto API](https://github.com/square/js-jose) +- [Microsoft's Fetch Event Source, a better JavaScript API for making Event Source requests](https://github.com/Azure/fetch-event-source) +- [`EventSource` polyfill for Edge/IE and old browsers](https://github.com/Yaffle/EventSource) +- [`EventSource` polyfill for React Native](https://github.com/jordanbyron/react-native-event-source) +- [`EventSource` implementation for Node](https://github.com/EventSource/eventsource) +- [Server-Sent Events client for Go](https://github.com/donovanhide/eventsource) +- [Server-Sent Events client for Android and Java](https://github.com/heremaps/oksse) +- [Server-Sent Events client for Swift](https://github.com/inaka/EventSource) +- [JavaScript library to parse `Link` headers](https://github.com/thlorenz/parse-link-header) +- [JavaScript library to decrypt JWE using the WebCrypto API](https://github.com/square/js-jose) ## Projects Using Mercure -* [HTTP Broadcast: a scalable and fault resilient HTTP broadcaster](https://github.com/jderusse/http-broadcast) +- [HTTP Broadcast: a scalable and fault resilient HTTP broadcaster](https://github.com/jderusse/http-broadcast) ## Learning Resources ### English 🇺🇸 -* 📺 [API Updates in Real Time w. Mercure.rocks](https://www.youtube.com/watch?v=odNsxoHSkT4) -* 📺 [Building async public APIs using HTTP/2+ and the Mercure protocol](https://www.youtube.com/watch?v=IUx47Tx0O8E) -* 📺 [Real-time Notifications with Symfony and Mercure (Basics)](https://www.youtube.com/watch?v=kYNC47V7R_0) -* 📺 [Real-time Chat App with Symfony and Mercure](https://www.youtube.com/watch?v=wnr2A4aKnPU) -* [Official Push and Real-Time Capabilities for Symfony and API Platform using Mercure (Symfony blog)](https://dunglas.fr/2019/03/official-push-and-real-time-capabilities-for-symfony-and-api-platform-mercure-protocol/) -* [Tech Workshop: Mercure by Kévin Dunglas at SensioLabs (SensioLabs)](https://blog.sensiolabs.com/2019/01/24/tech-workshop-mercure-kevin-dunglas-sensiolabs/) -* [Real-time messages with Mercure using Laravel](http://thedevopsguide.com/real-time-notifications-with-mercure/) -* [Using Mercure on Stackhero](https://www.stackhero.io/en/documentations/mercure-hub/getting-started) -* [Mercure - install and run](https://mysiar.github.io/dev/2020/04/12/mercure-part1.html) +- 📺 [API Updates in Real Time w. Mercure.rocks](https://www.youtube.com/watch?v=odNsxoHSkT4) +- 📺 [Building async public APIs using HTTP/2+ and the Mercure protocol](https://www.youtube.com/watch?v=IUx47Tx0O8E) +- 📺 [Real-time Notifications with Symfony and Mercure (Basics)](https://www.youtube.com/watch?v=kYNC47V7R_0) +- 📺 [Real-time Chat App with Symfony and Mercure](https://www.youtube.com/watch?v=wnr2A4aKnPU) +- [Official Push and Real-Time Capabilities for Symfony and API Platform using Mercure (Symfony blog)](https://dunglas.fr/2019/03/official-push-and-real-time-capabilities-for-symfony-and-api-platform-mercure-protocol/) +- [Tech Workshop: Mercure by Kévin Dunglas at SensioLabs (SensioLabs)](https://blog.sensiolabs.com/2019/01/24/tech-workshop-mercure-kevin-dunglas-sensiolabs/) +- [Real-time messages with Mercure using Laravel](http://thedevopsguide.com/real-time-notifications-with-mercure/) +- [Using Mercure on Stackhero](https://www.stackhero.io/en/documentations/mercure-hub/getting-started) +- [Mercure - install and run](https://mysiar.github.io/dev/2020/04/12/mercure-part1.html) ### French 🇫🇷 -* 📺 [Notifications instantanées avec Mercure (Grafikart)](https://www.grafikart.fr/tutoriels/symfony-mercure-1151) -* 📺 [Live Coding : Notifications temps réel avec Mercure](https://www.youtube.com/watch?v=tqqJ1ul2M-E) -* 📺 [Explication des Server Sent Events (SSE) avec Mercure](https://www.youtube.com/watch?v=Q4LRN2wXuIc) -* 📺 [Mercure : des UIs toujours synchronisées avec les données en BDD](https://www.youtube.com/watch?v=UcBa4AugNTE) -* 📺 [Mercure, et PHP s'enamoure enfin du temps réel](https://www.youtube.com/watch?v=GugURP88Rgg) -* 📺 [Async avec Messenger, AMQP et Mercure](https://www.youtube.com/watch?v=cHPbcuydJiA) -* [Mercure, un protocole pour pousser des mises à jour vers des navigateurs et app mobiles en temps réel (Les-Tilleuls.coop)](https://les-tilleuls.coop/blog/mercure-un-protocole-pour-pousser-des-mises-a-jour-vers-des-navigateurs-et-app-mobiles-en-temps-reel) -* [Symfony et Mercure](https://afsy.fr/avent/2019/21-symfony-et-mercure) -* [À la découverte de Mercure](https://blog.eleven-labs.com/fr/a-la-decouverte-de-mercure/) +- 📺 [Notifications instantanées avec Mercure (Grafikart)](https://www.grafikart.fr/tutoriels/symfony-mercure-1151) +- 📺 [Live Coding : Notifications temps réel avec Mercure](https://www.youtube.com/watch?v=tqqJ1ul2M-E) +- 📺 [Explication des Server Sent Events (SSE) avec Mercure](https://www.youtube.com/watch?v=Q4LRN2wXuIc) +- 📺 [Mercure : des UIs toujours synchronisées avec les données en BDD](https://www.youtube.com/watch?v=UcBa4AugNTE) +- 📺 [Mercure, et PHP s'enamoure enfin du temps réel](https://www.youtube.com/watch?v=GugURP88Rgg) +- 📺 [Async avec Messenger, AMQP et Mercure](https://www.youtube.com/watch?v=cHPbcuydJiA) +- [Mercure, un protocole pour pousser des mises à jour vers des navigateurs et app mobiles en temps réel (Les-Tilleuls.coop)](https://les-tilleuls.coop/blog/mercure-un-protocole-pour-pousser-des-mises-a-jour-vers-des-navigateurs-et-app-mobiles-en-temps-reel) +- [Symfony et Mercure](https://afsy.fr/avent/2019/21-symfony-et-mercure) +- [À la découverte de Mercure](https://blog.eleven-labs.com/fr/a-la-decouverte-de-mercure/) ### German 🇩🇪 -* [Neue Symfony-Komponente: Mercure ermöglicht Echtzeitübertragung](https://entwickler.de/online/php/symfony-mercure-komponente-579885243.html) +- [Neue Symfony-Komponente: Mercure ermöglicht Echtzeitübertragung](https://entwickler.de/online/php/symfony-mercure-komponente-579885243.html) diff --git a/docs/ecosystem/conformance-tests.md b/docs/ecosystem/conformance-tests.md index 08ce25e8..41e8d9f0 100644 --- a/docs/ecosystem/conformance-tests.md +++ b/docs/ecosystem/conformance-tests.md @@ -15,9 +15,9 @@ This test suite is based on [Playwright](https://playwright.dev/). The test suite can be configured by setting environment variables: -* `BASE_URL`: the URL of the hub to test -* `CUSTOM_ID`: enable or disable tests related to custom IDs support +- `BASE_URL`: the URL of the hub to test +- `CUSTOM_ID`: enable or disable tests related to custom IDs support ## See Also -* [The load test](../hub/load-test.md) +- [The load test](../hub/load-test.md) diff --git a/docs/ecosystem/github-actions.md b/docs/ecosystem/github-actions.md index e76c65f6..884dd3ef 100644 --- a/docs/ecosystem/github-actions.md +++ b/docs/ecosystem/github-actions.md @@ -9,24 +9,24 @@ name: Create a Mercure service on: push jobs: - my-job-using-mercure: - runs-on: ubuntu-latest + my-job-using-mercure: + runs-on: ubuntu-latest - services: - mercure: - image: dunglas/mercure - env: - SERVER_NAME: :1337 - MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!' - MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!' - MERCURE_EXTRA_DIRECTIVES: | - # Custom directives, see https://mercure.rocks/docs/hub/config - anonymous - cors_origins * - ports: - - 1337:1337 - steps: - # ... + services: + mercure: + image: dunglas/mercure + env: + SERVER_NAME: :1337 + MERCURE_PUBLISHER_JWT_KEY: "!ChangeThisMercureHubJWTSecretKey!" + MERCURE_SUBSCRIBER_JWT_KEY: "!ChangeThisMercureHubJWTSecretKey!" + MERCURE_EXTRA_DIRECTIVES: | + # Custom directives, see https://mercure.rocks/docs/hub/config + anonymous + cors_origins * + ports: + - 1337:1337 + steps: + # ... ``` A Mercure hub is available at the address `http://localhost:1337/.well-known/mercure`. diff --git a/docs/ecosystem/help.md b/docs/ecosystem/help.md index 0f92aced..82dacf54 100644 --- a/docs/ecosystem/help.md +++ b/docs/ecosystem/help.md @@ -6,8 +6,8 @@ For support requests related to the [Cloud](../hub/cloud.md) or the [On Premise] ## Community Support -* [Stack Overflow: ask questions using the `mercure` tag](https://stackoverflow.com/questions/tagged/mercure) -* [Slack: chat with the community on the `#mercure` channel on Symfony's Slack](https://symfony.com/slack) +- [Stack Overflow: ask questions using the `mercure` tag](https://stackoverflow.com/questions/tagged/mercure) +- [Slack: chat with the community on the `#mercure` channel on Symfony's Slack](https://symfony.com/slack) ## Commercial Support diff --git a/docs/ecosystem/hotwire.md b/docs/ecosystem/hotwire.md index 062f2229..dfe75f08 100644 --- a/docs/ecosystem/hotwire.md +++ b/docs/ecosystem/hotwire.md @@ -11,7 +11,9 @@ Using Mercure to power a Turbo Stream is straightforward, and doesn't require an import { connectStreamSource } from "@hotwired/turbo"; // The "topic" parameter can be any string or URI -const es = new EventSource("https://example.com/.well-known/mercure?topic=my-stream"); +const es = new EventSource( + "https://example.com/.well-known/mercure?topic=my-stream", +); connectStreamSource(es); ``` @@ -30,9 +32,9 @@ curl \ https://example.com/.well-known/mercure ``` -* `topic` must be the same topic we used in the JavaScript code ; -* `data` contains the [Turbo Streams messages](https://turbo.hotwire.dev/handbook/streams#stream-messages-and-actions) to broadcast ; -* the `Authorization` header must contain [a valid publisher JWT](../../spec/mercure.md#publication). +- `topic` must be the same topic we used in the JavaScript code ; +- `data` contains the [Turbo Streams messages](https://turbo.hotwire.dev/handbook/streams#stream-messages-and-actions) to broadcast ; +- the `Authorization` header must contain [a valid publisher JWT](../../spec/mercure.md#publication). [Other Mercure features](../../spec/mercure.md#publication), including broadcasting private updates to authorized subscribers, are also supported. @@ -75,7 +77,10 @@ export default class extends Controller { ``` ```html -
+
``` diff --git a/docs/getting-started.md b/docs/getting-started.md index 36c8e71f..c8680282 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -16,15 +16,15 @@ Subscribing to updates from a web browser or any other platform supporting [Serv ```javascript // The subscriber subscribes to updates for the https://example.com/users/dunglas topic // and to any topic matching https://example.com/books/{id} -const url = new URL('https://localhost/.well-known/mercure'); -url.searchParams.append('topic', 'https://example.com/books/{id}'); -url.searchParams.append('topic', 'https://example.com/users/dunglas'); +const url = new URL("https://localhost/.well-known/mercure"); +url.searchParams.append("topic", "https://example.com/books/{id}"); +url.searchParams.append("topic", "https://example.com/users/dunglas"); // The URL class is a convenient way to generate URLs such as https://localhost/.well-known/mercure?topic=https://example.com/books/{id}&topic=https://example.com/users/dunglas const eventSource = new EventSource(url); // The callback will be called every time an update is published -eventSource.onmessage = e => console.log(e); // do something with the payload +eventSource.onmessage = (e) => console.log(e); // do something with the payload ``` The `EventSource` class is available [in all modern web browsers](https://caniuse.com/eventsource). @@ -54,12 +54,14 @@ Also optionally, the hub URL can be automatically discovered: Here is a snippet to extract the URL of the hub from the `Link` HTTP header. ```javascript -fetch('https://example.com/books/1') // Has this header `Link: ; rel="mercure"` - .then(response => { - // Extract the hub URL from the Link header - const hubUrl = response.headers.get('Link').match(/<([^>]+)>;\s+rel=(?:mercure|"[^"]*mercure[^"]*")/)[1]; - // Subscribe to updates using the first snippet, do something with response's body... - }); +fetch("https://example.com/books/1") // Has this header `Link: ; rel="mercure"` + .then((response) => { + // Extract the hub URL from the Link header + const hubUrl = response.headers + .get("Link") + .match(/<([^>]+)>;\s+rel=(?:mercure|"[^"]*mercure[^"]*")/)[1]; + // Subscribe to updates using the first snippet, do something with response's body... + }); ``` ## Publishing @@ -84,27 +86,30 @@ Example using [Node.js](https://nodejs.org/) / [Serverless](https://serverless.c ```javascript // Handle a POST, PUT, PATCH or DELETE request or finish an async job... // and notify the hub -const http = require('http'); -const querystring = require('querystring'); +const http = require("http"); +const querystring = require("querystring"); const postData = querystring.stringify({ - 'topic': 'https://example.com/books/1', - 'data': JSON.stringify({ foo: 'updated value' }), + topic: "https://example.com/books/1", + data: JSON.stringify({ foo: "updated value" }), }); -const req = http.request({ - hostname: 'localhost', - port: '3000', - path: '/.well-known/mercure', - method: 'POST', +const req = http.request( + { + hostname: "localhost", + port: "3000", + path: "/.well-known/mercure", + method: "POST", headers: { - Authorization: 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS9teS1wcml2YXRlLXRvcGljIiwie3NjaGVtZX06Ly97K2hvc3R9L2RlbW8vYm9va3Mve2lkfS5qc29ubGQiLCIvLndlbGwta25vd24vbWVyY3VyZS9zdWJzY3JpcHRpb25zey90b3BpY317L3N1YnNjcmliZXJ9Il0sInBheWxvYWQiOnsidXNlciI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdXNlcnMvZHVuZ2xhcyIsInJlbW90ZUFkZHIiOiIxMjcuMC4wLjEifX19.KKPIikwUzRuB3DTpVw6ajzwSChwFw5omBMmMcWKiDcM', - // the JWT must have a mercure.publish key containing an array of topic selectors (can contain "*" for all topics, and be empty for public updates) - // the JWT key must be shared between the hub and the server - 'Content-Type': 'application/x-www-form-urlencoded', - 'Content-Length': Buffer.byteLength(postData), - } -}, /* optional response handler */); + Authorization: + "Bearer eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS9teS1wcml2YXRlLXRvcGljIiwie3NjaGVtZX06Ly97K2hvc3R9L2RlbW8vYm9va3Mve2lkfS5qc29ubGQiLCIvLndlbGwta25vd24vbWVyY3VyZS9zdWJzY3JpcHRpb25zey90b3BpY317L3N1YnNjcmliZXJ9Il0sInBheWxvYWQiOnsidXNlciI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdXNlcnMvZHVuZ2xhcyIsInJlbW90ZUFkZHIiOiIxMjcuMC4wLjEifX19.KKPIikwUzRuB3DTpVw6ajzwSChwFw5omBMmMcWKiDcM", + // the JWT must have a mercure.publish key containing an array of topic selectors (can contain "*" for all topics, and be empty for public updates) + // the JWT key must be shared between the hub and the server + "Content-Type": "application/x-www-form-urlencoded", + "Content-Length": Buffer.byteLength(postData), + }, + } /* optional response handler */, +); req.write(postData); req.end(); @@ -124,6 +129,6 @@ Mercure dispatches events every time a new subscription is created or terminated ## Going Further -* [Read the full specification](../spec/mercure.md) -* [Install the hub](hub/install.md) -* [Checkout the examples](ecosystem/awesome.md#examples) +- [Read the full specification](../spec/mercure.md) +- [Install the hub](hub/install.md) +- [Checkout the examples](ecosystem/awesome.md#examples) diff --git a/docs/hub/cloud.md b/docs/hub/cloud.md index 409d7f52..13555666 100644 --- a/docs/hub/cloud.md +++ b/docs/hub/cloud.md @@ -15,10 +15,10 @@ After purchase, your hub will be instantly provisionned and available under a `m You'll have access to an administration interface allowing you to: -* configure your hub (the same [configuration settings](config.md) as for the free and open-source hub are available) -* access to the logs of your hub -* [set a custom domain name](#custom-domain) -* [switch to another plan](#switching-between-plans) +- configure your hub (the same [configuration settings](config.md) as for the free and open-source hub are available) +- access to the logs of your hub +- [set a custom domain name](#custom-domain) +- [switch to another plan](#switching-between-plans) ## Custom Domain diff --git a/docs/hub/cluster.md b/docs/hub/cluster.md index 5365f32b..8e64628f 100644 --- a/docs/hub/cluster.md +++ b/docs/hub/cluster.md @@ -27,10 +27,10 @@ The High Availability On Premise Mercure.rocks Hub is a drop-in replacement for The HA version is shipped with transports having node synchronization capabilities. These transports can rely on: -* Redis -* Postgres `LISTEN`/`NOTIFY` -* Apache Kafka -* Apache Pulsar +- Redis +- Postgres `LISTEN`/`NOTIFY` +- Apache Kafka +- Apache Pulsar We can help you to decide which synchronization mechanism will be the best suited for your needs, and help you to install and configure it on your infrastructure. @@ -71,7 +71,7 @@ To install Redis, [read the documentation](https://redis.io/topics/quickstart). Most Cloud Computing platforms also provide managed versions of Redis. | Feature | Supported | -|-----------------|-----------| +| --------------- | --------- | | History | ✅ | | Presence API | ✅ | | Custom event ID | ✅ | @@ -91,11 +91,10 @@ To use Redis, the `MERCURE_TRANSPORT_URL` environment variable must be set like The following options can be passed as query parameters of the URL set in `transport_url`: | Parameter | Description | Default | -|------------------|--------------------------------------------------------------------------------------------------------|---------| +| ---------------- | ------------------------------------------------------------------------------------------------------ | ------- | | `tls` | set to `1` to enable TLS support | `0` | | `max_len_approx` | the approximative maximum number of messages to store in the history, set to `0` to store all messages | `0` | - #### PostgreSQL Transport The PostgreSQL Transport allows to store permanently the event and to query them using the full power of SQL. @@ -105,7 +104,7 @@ To install PostgreSQL, [read the documentation](https://www.postgresql.org/docs/ Most Cloud Computing platforms also provide managed versions of PostgreSQL. | Feature | Supported | -|-----------------|--------------| +| --------------- | ------------ | | History | ✅ | | Presence API | ❌ (planned) | | Custom event ID | ✅ | @@ -133,16 +132,16 @@ To install Apache Kafka, [read the quickstart guide](https://kafka.apache.org/qu Most Cloud Computing platforms also provide managed versions of Kafka. The Mercure.rocks hub has been tested with: -* Bitnami's Kafka Docker images (Kubernetes and the like) -* Amazon Managed Streaming for Apache Kafka (Amazon MSK) -* IBM Event Streams for IBM Cloud -* Heroku Kafka +- Bitnami's Kafka Docker images (Kubernetes and the like) +- Amazon Managed Streaming for Apache Kafka (Amazon MSK) +- IBM Event Streams for IBM Cloud +- Heroku Kafka -| Feature | Supported | -|-----------------|--------------| -| History | ✅ | -| Presence API | ❌ | -| Custom event ID | ✅ | +| Feature | Supported | +| --------------- | --------- | +| History | ✅ | +| Presence API | ❌ | +| Custom event ID | ✅ | ##### Kafka Configuration @@ -159,10 +158,10 @@ To use Kafka, the `MERCURE_TRANSPORT_URL` environment variable must be set like The following options can be passed as query parameters of the URL set in `transport_url`: | Parameter | Description | -|------------------|---------------------------------------------------------------------------------------------------------------------------------------------| +| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | `addr` | addresses of the Kafka servers, you can pass several `addr` parameters to use several Kafka servers (ex: `addr=host1:9092&addr=host2:9092`) | -| `topic` | the name of the Kafka topic to use (ex: `topic=mercure-ha`), **all Mercure.rocks hub instances must use the same topic** | -| `consumer_group` | consumer group, **must be different for every instance of the Mercure.rocks hub** (ex: `consumer_group=`) | +| `topic` | the name of the Kafka topic to use (ex: `topic=mercure-ha`), **all Mercure.rocks hub instances must use the same topic** | +| `consumer_group` | consumer group, **must be different for every instance of the Mercure.rocks hub** (ex: `consumer_group=`) | | `user` | Kafka SASL user (optional, ex: `user=kevin`) | | `password` | Kafka SASL password (optional, ex: `password=maman`) | | `tls` | Set to `1` to enable TLS (ex: `tls=1`) | @@ -174,7 +173,7 @@ The Pulsar transport should only be used when Pulsar is already part of your sta To install Apache Pulsar, [read the documentation](https://pulsar.apache.org/docs/en/standalone/). | Feature | Supported | -|-----------------|--------------| +| --------------- | ------------ | | History | ✅ | | Presence API | ❌ | | Custom event ID | ❌ (planned) | @@ -193,10 +192,10 @@ To use Pulsar, the `MERCURE_TRANSPORT_URL` environment variable must be set like The following options can be passed as query parameters of the URL set in `transport_url`: -| Parameters | Description | | -|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------|---| -| `topic` | the name of the Pulsar topic to use (ex: `topic=mercure`), **all Mercure.rocks hub instances must use the same topic** | | -| `subscription_name` | the subscription name for this node, **must be different for every instance of the Mercure.rocks hub** (ex: `subscription_name=`) | | +| Parameters | Description | | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | --- | +| `topic` | the name of the Pulsar topic to use (ex: `topic=mercure`), **all Mercure.rocks hub instances must use the same topic** | | +| `subscription_name` | the subscription name for this node, **must be different for every instance of the Mercure.rocks hub** (ex: `subscription_name=`) | | ### Docker Images and Kubernetes Chart diff --git a/docs/hub/config.md b/docs/hub/config.md index c0167354..b7573654 100644 --- a/docs/hub/config.md +++ b/docs/hub/config.md @@ -39,7 +39,7 @@ Note that HTTPS is automatically disabled if you set the server port to 80. The following Mercure-specific directives are available: | Directive | Description | Default | -|---------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------| +| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | | `publisher_jwt []` | the JWT key and algorithm to use for publishers, can contain [placeholders](https://caddyserver.com/docs/conventions#placeholders) | | | `subscriber_jwt []` | the JWT key and algorithm to use for subscribers, can contain [placeholders](https://caddyserver.com/docs/conventions#placeholders) | | | `publisher_jwks_url` | the URL of the JSON Web Key Set (JWK Set) URL (provided by identity providers such as Keycloak or AWS Cognito) to use for validating publishers JWT (take precedence over `publisher_jwt`) | | @@ -65,24 +65,25 @@ See also [the list of built-in Caddyfile directives](https://caddyserver.com/doc The provided `Caddyfile` and the Docker image provide convenient environment variables: -| Environment variable | Description | Default value | -| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | -| `GLOBAL_OPTIONS` | the [global options block](https://caddyserver.com/docs/caddyfile/options#global-options) to inject in the `Caddyfile`, one per line | | -| `CADDY_EXTRA_CONFIG` | the [snippet](https://caddyserver.com/docs/caddyfile/concepts#snippets) or the [named-routes](https://caddyserver.com/docs/caddyfile/concepts#named-routes) options block to inject in the `Caddyfile`, one per line | | -| `CADDY_SERVER_EXTRA_DIRECTIVES`| [`Caddyfile` directives](https://caddyserver.com/docs/caddyfile/concepts#directives) | | -| `SERVER_NAME` | the server name or address | `localhost` | -| `MERCURE_PUBLISHER_JWT_KEY` | the JWT key to use for publishers | | -| `MERCURE_PUBLISHER_JWT_ALG` | the JWT algorithm to use for publishers | `HS256` | -| `MERCURE_SUBSCRIBER_JWT_KEY` | the JWT key to use for subscribers | | -| `MERCURE_SUBSCRIBER_JWT_ALG` | the JWT algorithm to use for subscribers | `HS256` | -| `MERCURE_EXTRA_DIRECTIVES` | a list of extra [Mercure directives](#directives) inject in the Caddy file, one per line | | -| `MERCURE_LICENSE` | the license to use ([only applicable for the HA version](cluster.md)) | | +| Environment variable | Description | Default value | +| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `GLOBAL_OPTIONS` | the [global options block](https://caddyserver.com/docs/caddyfile/options#global-options) to inject in the `Caddyfile`, one per line | | +| `CADDY_EXTRA_CONFIG` | the [snippet](https://caddyserver.com/docs/caddyfile/concepts#snippets) or the [named-routes](https://caddyserver.com/docs/caddyfile/concepts#named-routes) options block to inject in the `Caddyfile`, one per line | | +| `CADDY_SERVER_EXTRA_DIRECTIVES` | [`Caddyfile` directives](https://caddyserver.com/docs/caddyfile/concepts#directives) | | +| `SERVER_NAME` | the server name or address | `localhost` | +| `MERCURE_PUBLISHER_JWT_KEY` | the JWT key to use for publishers | | +| `MERCURE_PUBLISHER_JWT_ALG` | the JWT algorithm to use for publishers | `HS256` | +| `MERCURE_SUBSCRIBER_JWT_KEY` | the JWT key to use for subscribers | | +| `MERCURE_SUBSCRIBER_JWT_ALG` | the JWT algorithm to use for subscribers | `HS256` | +| `MERCURE_EXTRA_DIRECTIVES` | a list of extra [Mercure directives](#directives) inject in the Caddy file, one per line | | +| `MERCURE_LICENSE` | the license to use ([only applicable for the HA version](cluster.md)) | | ## HealthCheck The Mercure.rocks Hub provides a `/healthz` endpoint that returns a `200 OK` status code if the server is healthy. Here is an example of how to use the health check in a Docker Compose file: + ```yaml # compose.yaml services: @@ -127,7 +128,7 @@ MERCURE_SUBSCRIBER_JWT_ALG=RS256 \ ## Bolt Adapter | Option | Description | -|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `path` | path of the database file (default: `mercure.db`) | | `bucket_name` | name of the bolt bucket to store events. default to `updates` | | `cleanup_frequency` | chances to trigger history cleanup when an update occurs, must be a number between `0` (never cleanup) and `1` (cleanup after every publication), default to `0.3`. | @@ -165,16 +166,16 @@ Run `./mercure -h` to see all available command-line flags. Configuration files must be named `mercure.` (ex: `mercure.yaml`) and stored in one of the following directories: -* the current directory (`$PWD`) -* `~/.config/mercure/` (or any other XDG configuration directory set with the `XDG_CONFIG_HOME` environment variable) -* `/etc/mercure` +- the current directory (`$PWD`) +- `~/.config/mercure/` (or any other XDG configuration directory set with the `XDG_CONFIG_HOME` environment variable) +- `/etc/mercure` Most configuration parameters are hot reloaded: changes made to environment variables or configuration files are immediately taken into account, without having to restart the hub. When using environment variables, list must be space separated. As flags parameters, they must be comma separated. | Parameter | Description | Default | -|----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------| +| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | | `acme_cert_dir` | the directory where to store Let's Encrypt certificates | | | `acme_hosts` | a list of hosts for which Let's Encrypt certificates must be issued | | | `acme_http01_addr` | the address used by the acme server to listen on (example: `0.0.0.0:8080`) | `:http` | diff --git a/docs/hub/cookbooks.md b/docs/hub/cookbooks.md index 9931ff95..a39b5dd3 100644 --- a/docs/hub/cookbooks.md +++ b/docs/hub/cookbooks.md @@ -12,11 +12,10 @@ You may also be interested in spreading the load across several servers using [t To reproduce the problem, we provide [a load test](load-test.md) that you can use to stress your infrastructure. - ## Using Mercure Behind a Reverse Proxy Mercure hubs run perfectly well behind reverse proxies. Here are some configuration for popular proxies: -* [NGINX](nginx.md) -* [Traefik](traefik.md) +- [NGINX](nginx.md) +- [Traefik](traefik.md) diff --git a/docs/hub/debug.md b/docs/hub/debug.md index c4a26a9d..c5e50ca1 100644 --- a/docs/hub/debug.md +++ b/docs/hub/debug.md @@ -14,7 +14,7 @@ To enable the profiler, add the `debug` global directive to your `Caddyfile`: # ... ``` -If you use the default `Caddyfile`, you can also set the `GLOBAL_OPTIONS` environment variable to `debug`. +If you use the default `Caddyfile`, you can also set the `GLOBAL_OPTIONS` environment variable to `debug`. The route exposing profiling data is now available at `http://localhost:2019/debug/pprof/`. You can use [the `pprof` tool](https://golang.org/pkg/net/http/pprof/) to visualize it. diff --git a/docs/hub/install.md b/docs/hub/install.md index 110f1275..852dc91c 100644 --- a/docs/hub/install.md +++ b/docs/hub/install.md @@ -11,7 +11,7 @@ The Mercure.rocks hub is available as a custom build of the [Caddy web server](h First, download the archive corresponding to your operating system and architecture [from the release page](https://github.com/dunglas/mercure/releases), extract the archive and open a shell in the resulting directory. -*Note:* macOS users must download the `Darwin` binary, then run `xattr -d com.apple.quarantine ./mercure` [to release the hub from quarantine](troubleshooting.md#macos-localhost-installation-error). +_Note:_ macOS users must download the `Darwin` binary, then run `xattr -d com.apple.quarantine ./mercure` [to release the hub from quarantine](troubleshooting.md#macos-localhost-installation-error). To start the Mercure.rocks Hub in development mode on Linux and macOS, run: @@ -27,13 +27,13 @@ On Windows, start PowerShell, go into the extracted directory and run: $env:MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!'; $env:MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!'; .\mercure.exe run --config dev.Caddyfile ``` -*Note:* The Windows Defender Firewall will ask you if you want to allow `mercure.exe` to communicate through it. +_Note:_ The Windows Defender Firewall will ask you if you want to allow `mercure.exe` to communicate through it. Allow it for both public and private networks. If you use an antivirus, or another firewall software, be sure to whitelist `mercure.exe`. The server is now available on `https://localhost` (TLS is automatically enabled, [learn how to disable it](config.md)). In development mode, anonymous subscribers are allowed and the debug UI is available on `https://localhost/.well-known/mercure/ui/`. -*Note:* if you get an error similar to `bind: address already in use`, it means that the port `80` or `443` is already used by another service (the usual suspects are Apache and NGINX). Before starting Mercure, stop the service using the port(s) first, or set the `SERVER_NAME` environment variable to use a free port (ex: `SERVER_NAME=:3000`). +_Note:_ if you get an error similar to `bind: address already in use`, it means that the port `80` or `443` is already used by another service (the usual suspects are Apache and NGINX). Before starting Mercure, stop the service using the port(s) first, or set the `SERVER_NAME` environment variable to use a free port (ex: `SERVER_NAME=:3000`). To run the server in production mode, run this command: @@ -48,8 +48,8 @@ To change these default settings, [learn how to configure the Mercure.rocks hub] When the server is up and running, the following endpoints are available: -* `POST https://localhost/.well-known/mercure`: to publish updates -* `GET https://localhost/.well-known/mercure`: to subscribe to updates +- `POST https://localhost/.well-known/mercure`: to publish updates +- `GET https://localhost/.well-known/mercure`: to subscribe to updates See [the protocol](../../spec/mercure.md) for more details about these endpoints. @@ -122,8 +122,8 @@ services: environment: # Uncomment the following line to disable HTTPS #SERVER_NAME: ':80' - MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!' - MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!' + MERCURE_PUBLISHER_JWT_KEY: "!ChangeThisMercureHubJWTSecretKey!" + MERCURE_SUBSCRIBER_JWT_KEY: "!ChangeThisMercureHubJWTSecretKey!" # Uncomment the following line to enable the development mode #command: /usr/bin/caddy run --config /etc/caddy/dev.Caddyfile healthcheck: @@ -132,8 +132,8 @@ services: retries: 5 start_period: 60s ports: - - '80:80' - - '443:443' + - "80:80" + - "443:443" volumes: - mercure_data:/data - mercure_config:/config @@ -152,6 +152,7 @@ Mercure.rocks is available [on the AUR](https://aur.archlinux.org/packages/mercu ```console yay -S mercure ``` + Or download the `PKGBUILD` and compile and install it: `makepkg -sri`. ## Custom Caddy Build diff --git a/docs/hub/license.md b/docs/hub/license.md index 5128570b..8eff1557 100644 --- a/docs/hub/license.md +++ b/docs/hub/license.md @@ -2,10 +2,10 @@ tl;dr: -* proprietary software **can** implement the Mercure specification -* proprietary publishers and subscribers **can** be used with the Mercure.rocks Hub without having to share their sources -* modifications made to the Mercure.rocks Hub **must** be shared -* alternatively, [commercial licenses are available for the Mercure.rocks Hub](https://mercure.rocks/pricing) +- proprietary software **can** implement the Mercure specification +- proprietary publishers and subscribers **can** be used with the Mercure.rocks Hub without having to share their sources +- modifications made to the Mercure.rocks Hub **must** be shared +- alternatively, [commercial licenses are available for the Mercure.rocks Hub](https://mercure.rocks/pricing) [The specification](../../spec/mercure.md) is available under [the IETF copyright policy](https://trustee.ietf.org/copyright-faq.html). The Mercure **specification** can be implemented by any software, including proprietary software. diff --git a/docs/hub/load-test.md b/docs/hub/load-test.md index 788ec5ed..ae3ae1f5 100644 --- a/docs/hub/load-test.md +++ b/docs/hub/load-test.md @@ -15,19 +15,19 @@ To test your own infrastructure, we provide a [Gatling](https://gatling.io)-base Available environment variables (all are optional): -* `HUB_URL`: the URL of the hub to test -* `JWT`: the JWT to use for authenticating publishers -* `SUBSCRIBER_JWT`: the JWT to use for authenticating subscribers, fallbacks to `JWT` not set and `PRIVATE_UPDATES` set -* `INITIAL_SUBSCRIBERS`: the number of concurrent subscribers initially connected -* `SUBSCRIBERS_RATE_FROM`: minimum rate (per second) of additional subscribers to connect -* `SUBSCRIBERS_RATE_TO`: maximum rate (per second) of additional subscribers to connect -* `PUBLISHERS_RATE_FROM`: minimum rate (per second) of publications -* `PUBLISHERS_RATE_TO`: maximum rate (per second) of publications -* `INJECTION_DURATION`: duration of the publishers injection -* `CONNECTION_DURATION`: duration of subscribers' connection -* `RANDOM_CONNECTION_DURATION`: to randomize the connection duration (will longs `CONNECTION_DURATION` at max) -* `PRIVATE_UPDATES`: to send private updates with random topics instead of public updates always with the same topic +- `HUB_URL`: the URL of the hub to test +- `JWT`: the JWT to use for authenticating publishers +- `SUBSCRIBER_JWT`: the JWT to use for authenticating subscribers, fallbacks to `JWT` not set and `PRIVATE_UPDATES` set +- `INITIAL_SUBSCRIBERS`: the number of concurrent subscribers initially connected +- `SUBSCRIBERS_RATE_FROM`: minimum rate (per second) of additional subscribers to connect +- `SUBSCRIBERS_RATE_TO`: maximum rate (per second) of additional subscribers to connect +- `PUBLISHERS_RATE_FROM`: minimum rate (per second) of publications +- `PUBLISHERS_RATE_TO`: maximum rate (per second) of publications +- `INJECTION_DURATION`: duration of the publishers injection +- `CONNECTION_DURATION`: duration of subscribers' connection +- `RANDOM_CONNECTION_DURATION`: to randomize the connection duration (will longs `CONNECTION_DURATION` at max) +- `PRIVATE_UPDATES`: to send private updates with random topics instead of public updates always with the same topic ## See Also -* [Conformance tests](../ecosystem/conformance-tests.md) +- [Conformance tests](../ecosystem/conformance-tests.md) diff --git a/docs/hub/traefik.md b/docs/hub/traefik.md index c468c24c..9cbea484 100644 --- a/docs/hub/traefik.md +++ b/docs/hub/traefik.md @@ -1,6 +1,6 @@ # Use the Mercure.rocks Hub with Traefik Proxy -[Traefik](https://doc.traefik.io/traefik/) is a free and open source *edge router* poular in the Docker and Kubernetes ecosystems. +[Traefik](https://doc.traefik.io/traefik/) is a free and open source _edge router_ poular in the Docker and Kubernetes ecosystems. The following Docker Compose file exposes a Mercure.rocks hub through Traefik: @@ -13,9 +13,9 @@ services: command: --api.insecure=true --providers.docker ports: # The HTTP port - - '80:80' + - "80:80" # The Web UI (enabled by --api.insecure=true) - - '8080:8080' + - "8080:8080" volumes: # So that Traefik can listen to the Docker events - /var/run/docker.sock:/var/run/docker.sock @@ -26,13 +26,21 @@ services: restart: unless-stopped environment: # Disables Mercure.rocks auto-HTTPS feature, HTTPS must be handled at edge by Traefik or another proxy in front of it - SERVER_NAME: ':80' - MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!' - MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!' + SERVER_NAME: ":80" + MERCURE_PUBLISHER_JWT_KEY: "!ChangeThisMercureHubJWTSecretKey!" + MERCURE_SUBSCRIBER_JWT_KEY: "!ChangeThisMercureHubJWTSecretKey!" # Enables the development mode, comment the following line to run the hub in prod mode command: /usr/bin/caddy run --config /etc/caddy/dev.Caddyfile healthcheck: - test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/healthz"] + test: + [ + "CMD", + "wget", + "--no-verbose", + "--tries=1", + "--spider", + "http://localhost/healthz", + ] timeout: 5s retries: 5 start_period: 60s diff --git a/docs/hub/troubleshooting.md b/docs/hub/troubleshooting.md index 55c413e2..d32dbce4 100644 --- a/docs/hub/troubleshooting.md +++ b/docs/hub/troubleshooting.md @@ -2,13 +2,13 @@ ## 401 Unauthorized -* Double-check that the request to the hub includes an authorization cookie (the default name is `mercureAuthorization`) or an `Authorization` HTTP header -* If the cookie isn't set, you may have to explicitly include [the request credentials](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) (`new EventSource(url, {withCredentials: true})` and `fetch(url, {credentials: 'include'})`) -* Check the logs written by the hub on `stderr`, they contain the exact reason why the token has been rejected -* Be sure to set a **secret key** (and not a JWT) in `JWT_KEY` (or in `SUBSCRIBER_JWT_KEY` and `PUBLISHER_JWT_KEY`) -* If the secret key contains special characters, be sure to escape them properly, especially if you set the environment variable in a shell, or in a YAML file (Kubernetes...) -* The publisher always needs a valid JWT, even if the `anonymous` directive is present in the `Caddyfile`, this JWT **must** have a property named `publish`. To dispatch private updates, the `publish` property must contain the list of topic selectors this publisher can use ([example](https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS9teS1wcml2YXRlLXRvcGljIiwie3NjaGVtZX06Ly97K2hvc3R9L2RlbW8vYm9va3Mve2lkfS5qc29ubGQiLCIvLndlbGwta25vd24vbWVyY3VyZS9zdWJzY3JpcHRpb25zey90b3BpY317L3N1YnNjcmliZXJ9Il0sInBheWxvYWQiOnsidXNlciI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdXNlcnMvZHVuZ2xhcyIsInJlbW90ZUFkZHIiOiIxMjcuMC4wLjEifX19.KKPIikwUzRuB3DTpVw6ajzwSChwFw5omBMmMcWKiDcM)) -* The subscriber needs a valid JWT only if the `anonymous` directive isn't present in the `Caddyfile`, or to subscribe to private updates, in this case the JWT **must** have a property named `subscribe` and containing an array of topic selectors ([example](https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS9teS1wcml2YXRlLXRvcGljIiwie3NjaGVtZX06Ly97K2hvc3R9L2RlbW8vYm9va3Mve2lkfS5qc29ubGQiLCIvLndlbGwta25vd24vbWVyY3VyZS9zdWJzY3JpcHRpb25zey90b3BpY317L3N1YnNjcmliZXJ9Il0sInBheWxvYWQiOnsidXNlciI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdXNlcnMvZHVuZ2xhcyIsInJlbW90ZUFkZHIiOiIxMjcuMC4wLjEifX19.KKPIikwUzRuB3DTpVw6ajzwSChwFw5omBMmMcWKiDcM)) +- Double-check that the request to the hub includes an authorization cookie (the default name is `mercureAuthorization`) or an `Authorization` HTTP header +- If the cookie isn't set, you may have to explicitly include [the request credentials](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) (`new EventSource(url, {withCredentials: true})` and `fetch(url, {credentials: 'include'})`) +- Check the logs written by the hub on `stderr`, they contain the exact reason why the token has been rejected +- Be sure to set a **secret key** (and not a JWT) in `JWT_KEY` (or in `SUBSCRIBER_JWT_KEY` and `PUBLISHER_JWT_KEY`) +- If the secret key contains special characters, be sure to escape them properly, especially if you set the environment variable in a shell, or in a YAML file (Kubernetes...) +- The publisher always needs a valid JWT, even if the `anonymous` directive is present in the `Caddyfile`, this JWT **must** have a property named `publish`. To dispatch private updates, the `publish` property must contain the list of topic selectors this publisher can use ([example](https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS9teS1wcml2YXRlLXRvcGljIiwie3NjaGVtZX06Ly97K2hvc3R9L2RlbW8vYm9va3Mve2lkfS5qc29ubGQiLCIvLndlbGwta25vd24vbWVyY3VyZS9zdWJzY3JpcHRpb25zey90b3BpY317L3N1YnNjcmliZXJ9Il0sInBheWxvYWQiOnsidXNlciI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdXNlcnMvZHVuZ2xhcyIsInJlbW90ZUFkZHIiOiIxMjcuMC4wLjEifX19.KKPIikwUzRuB3DTpVw6ajzwSChwFw5omBMmMcWKiDcM)) +- The subscriber needs a valid JWT only if the `anonymous` directive isn't present in the `Caddyfile`, or to subscribe to private updates, in this case the JWT **must** have a property named `subscribe` and containing an array of topic selectors ([example](https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS9teS1wcml2YXRlLXRvcGljIiwie3NjaGVtZX06Ly97K2hvc3R9L2RlbW8vYm9va3Mve2lkfS5qc29ubGQiLCIvLndlbGwta25vd24vbWVyY3VyZS9zdWJzY3JpcHRpb25zey90b3BpY317L3N1YnNjcmliZXJ9Il0sInBheWxvYWQiOnsidXNlciI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdXNlcnMvZHVuZ2xhcyIsInJlbW90ZUFkZHIiOiIxMjcuMC4wLjEifX19.KKPIikwUzRuB3DTpVw6ajzwSChwFw5omBMmMcWKiDcM)) For both the `publish` property, the array can be empty to publish only public updates. For both `publish` and `subscribe`, you can use `["*"]` to match all topics. @@ -18,8 +18,8 @@ If the app connecting to the Mercure hub and the hub itself are not served from The usual symptoms of a CORS misconfiguration are errors about missing CORS HTTP headers in the console of the browser: -* Chrome: `Refused to connect to 'https://hub.example.com/.well-known/mercure?topic=foo' because it violates the following Content Security Policy directive` -* Firefox: `Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://hub.example.com/.well-known/mercure?topic=foo. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)` +- Chrome: `Refused to connect to 'https://hub.example.com/.well-known/mercure?topic=foo' because it violates the following Content Security Policy directive` +- Firefox: `Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://hub.example.com/.well-known/mercure?topic=foo. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)` To fix these errors, set the list of domains allowed to connect to the hub as value of the `cors_origins` in the `Caddyfile`. Example: `cors_origins https://example.com https://example.net`. Don't forget the `https://` prefix before the domain name! @@ -60,9 +60,9 @@ The attribute only needs to be deleted once. On macOS Catalina and later versions, follow these steps: -* In the Finder on your Mac, locate the app that you want to open -* Control-click on the app icon, then choose "Open" from the shortcut menu -* Click "Open" +- In the Finder on your Mac, locate the app that you want to open +- Control-click on the app icon, then choose "Open" from the shortcut menu +- Click "Open" Then you will have a warning, ignore it and close the Terminal. diff --git a/docs/mercure.md b/docs/mercure.md index 6c3a4e65..c9735250 100644 --- a/docs/mercure.md +++ b/docs/mercure.md @@ -10,27 +10,27 @@ A free (as in beer, and as in speech) reference server, a commercial High Availa ## The Protocol -* native browser support, no lib nor SDK required (built on top of HTTP and [server-sent events](https://www.smashingmagazine.com/2018/02/sse-websockets-data-flow-http2/)) -* compatible with all existing servers, even those who don't support persistent connections (serverless architecture, PHP, FastCGI...) -* built-in connection re-establishment and state reconciliation -* [JWT](https://jwt.io/)-based authorization mechanism (securely dispatch an update to some selected subscribers) -* performant, leverages [HTTP multiplexing](https://web.dev/performance-http2/#request-and-response-multiplexing) -* designed with [hypermedia in mind](https://en.wikipedia.org/wiki/HATEOAS), also supports [GraphQL](https://graphql.org/) -* auto-discoverable through [web linking](https://tools.ietf.org/html/rfc5988) -* message encryption support -* can work with old browsers (IE7+) using [an `EventSource` polyfill](ecosystem/awesome.md#useful-related-libraries) -* [connection-less push](https://html.spec.whatwg.org/multipage/server-sent-events.html#eventsource-push) in controlled environments (e.g. browsers on mobile handsets tied to specific carriers) +- native browser support, no lib nor SDK required (built on top of HTTP and [server-sent events](https://www.smashingmagazine.com/2018/02/sse-websockets-data-flow-http2/)) +- compatible with all existing servers, even those who don't support persistent connections (serverless architecture, PHP, FastCGI...) +- built-in connection re-establishment and state reconciliation +- [JWT](https://jwt.io/)-based authorization mechanism (securely dispatch an update to some selected subscribers) +- performant, leverages [HTTP multiplexing](https://web.dev/performance-http2/#request-and-response-multiplexing) +- designed with [hypermedia in mind](https://en.wikipedia.org/wiki/HATEOAS), also supports [GraphQL](https://graphql.org/) +- auto-discoverable through [web linking](https://tools.ietf.org/html/rfc5988) +- message encryption support +- can work with old browsers (IE7+) using [an `EventSource` polyfill](ecosystem/awesome.md#useful-related-libraries) +- [connection-less push](https://html.spec.whatwg.org/multipage/server-sent-events.html#eventsource-push) in controlled environments (e.g. browsers on mobile handsets tied to specific carriers) [Read the specification](../spec/mercure.md) ## The Hub -* Fast, written in Go -* Works everywhere: [static binaries](hub/install.md#prebuilt-binary), [Docker image](hub/install.md#docker-image) and [Kubernetes chart](hub/install.md#kubernetes) -* Automatic HTTP/2, HTTP/3 and HTTPS (using Let's Encrypt) support -* [Clustering and High Availability support](hub/cluster.md) -* CORS support, CSRF protection mechanism -* Cloud Native, follows [the Twelve-Factor App](https://12factor.net) methodology -* Free and Open source (AGPL), SaaS, and commercial versions available +- Fast, written in Go +- Works everywhere: [static binaries](hub/install.md#prebuilt-binary), [Docker image](hub/install.md#docker-image) and [Kubernetes chart](hub/install.md#kubernetes) +- Automatic HTTP/2, HTTP/3 and HTTPS (using Let's Encrypt) support +- [Clustering and High Availability support](hub/cluster.md) +- CORS support, CSRF protection mechanism +- Cloud Native, follows [the Twelve-Factor App](https://12factor.net) methodology +- Free and Open source (AGPL), SaaS, and commercial versions available [Get your hub](hub/install.md) diff --git a/docs/spec/faq.md b/docs/spec/faq.md index b6774593..b652f2b9 100644 --- a/docs/spec/faq.md +++ b/docs/spec/faq.md @@ -56,7 +56,10 @@ Also, Mercure can easily be integrated with Apollo GraphQL by creating [a dedica Cookies are automatically sent by the browser when opening an `EventSource` connection if the `withCredentials` property is set to `true`: ```javascript -const eventSource = new EventSource('https://example.com/.well-known/mercure?topic=foo', { - withCredentials: true -}); +const eventSource = new EventSource( + "https://example.com/.well-known/mercure?topic=foo", + { + withCredentials: true, + }, +); ``` diff --git a/docs/spec/use-cases.md b/docs/spec/use-cases.md index dbf6fe75..fe295379 100644 --- a/docs/spec/use-cases.md +++ b/docs/spec/use-cases.md @@ -1,13 +1,12 @@ - # Case Studies and Use Cases From building a chat room to expose a fully-featured event store, Mercure covers a broad spectrum of use cases related to realtime and async APIs. ## Case Studies -* [How Raven Controls is using Mercure to power major events such as Cop 21 and Euro 2020](https://api-platform.com/con/2022/conferences/real-time-and-beyond-with-mercure/) -* [Pushing 8 million of Mercure notifications per day to run mail.tm](https://les-tilleuls.coop/en/blog/mail-tm-mercure-rocks-and-api-platform) -* [100,000 simultaneous Mercure users to power iGraal](https://speakerdeck.com/dunglas/mercure-real-time-for-php-made-easy?slide=52) +- [How Raven Controls is using Mercure to power major events such as Cop 21 and Euro 2020](https://api-platform.com/con/2022/conferences/real-time-and-beyond-with-mercure/) +- [Pushing 8 million of Mercure notifications per day to run mail.tm](https://les-tilleuls.coop/en/blog/mail-tm-mercure-rocks-and-api-platform) +- [100,000 simultaneous Mercure users to power iGraal](https://speakerdeck.com/dunglas/mercure-real-time-for-php-made-easy?slide=52) Example of usage: the Mercure integration in [API Platform](https://api-platform.com/docs/client-generator): @@ -19,20 +18,20 @@ Here are some popular use cases: ### Live Availability -* a webapp retrieves the availability status of a product from a REST API and displays it: only one is still available -* 3 minutes later, the last product is bought by another customer -* the webapp's view instantly shows that this product isn't available anymore +- a webapp retrieves the availability status of a product from a REST API and displays it: only one is still available +- 3 minutes later, the last product is bought by another customer +- the webapp's view instantly shows that this product isn't available anymore ### Asynchronous Jobs -* a webapp tells the server to compute a report, this task is costly and will take some time to complete -* the server delegates the computation of the report to an asynchronous worker (using message queue), and closes the connection with the webapp -* the worker sends the report to the webapp when it is computed +- a webapp tells the server to compute a report, this task is costly and will take some time to complete +- the server delegates the computation of the report to an asynchronous worker (using message queue), and closes the connection with the webapp +- the worker sends the report to the webapp when it is computed ### Collaborative Editing -* a webapp allows several users to edit the same document concurrently -* changes made are immediately broadcasted to all connected users +- a webapp allows several users to edit the same document concurrently +- changes made are immediately broadcasted to all connected users **Mercure gets you covered!** diff --git a/examples/chat/chart/mercure-example-chat/README.md b/examples/chat/chart/mercure-example-chat/README.md index b24dfe30..60a40953 100644 --- a/examples/chat/chart/mercure-example-chat/README.md +++ b/examples/chat/chart/mercure-example-chat/README.md @@ -6,40 +6,41 @@ A minimalist chat system, using Mercure and the Flask microframework to handle c ## Values -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| affinity | object | `{}` | | -| autoscaling.enabled | bool | `false` | | -| autoscaling.maxReplicas | int | `100` | | -| autoscaling.minReplicas | int | `1` | | -| autoscaling.targetCPUUtilizationPercentage | int | `80` | | -| cookieDomain | string | `".mercure.rocks"` | | -| fullnameOverride | string | `""` | | -| hubUrl | string | `"https://demo.mercure.rocks/.well-known/mercure"` | | -| image.pullPolicy | string | `"Always"` | | -| image.repository | string | `"dunglas/mercure-example-chat"` | | -| image.tag | string | `"latest"` | | -| imagePullSecrets | list | `[]` | | -| ingress.annotations | object | `{}` | | -| ingress.enabled | bool | `false` | | -| ingress.hosts[0].host | string | `"chart-example.local"` | | -| ingress.hosts[0].paths | list | `[]` | | -| ingress.tls | list | `[]` | | -| jwtKey | string | `"!ChangeThisMercureHubJWTSecretKey!"` | | -| messageUriTemplate | string | `"https://chat.example.com/messages/{id}"` | | -| nameOverride | string | `""` | | -| nodeSelector | object | `{}` | | -| podAnnotations | object | `{}` | | -| podSecurityContext | object | `{}` | | -| replicaCount | int | `1` | | -| resources | object | `{}` | | -| securityContext | object | `{}` | | -| service.port | int | `80` | | -| service.type | string | `"ClusterIP"` | | -| serviceAccount.annotations | object | `{}` | | -| serviceAccount.create | bool | `true` | | -| serviceAccount.name | string | `""` | | -| tolerations | list | `[]` | | +| Key | Type | Default | Description | +| ------------------------------------------ | ------ | -------------------------------------------------- | ----------- | +| affinity | object | `{}` | | +| autoscaling.enabled | bool | `false` | | +| autoscaling.maxReplicas | int | `100` | | +| autoscaling.minReplicas | int | `1` | | +| autoscaling.targetCPUUtilizationPercentage | int | `80` | | +| cookieDomain | string | `".mercure.rocks"` | | +| fullnameOverride | string | `""` | | +| hubUrl | string | `"https://demo.mercure.rocks/.well-known/mercure"` | | +| image.pullPolicy | string | `"Always"` | | +| image.repository | string | `"dunglas/mercure-example-chat"` | | +| image.tag | string | `"latest"` | | +| imagePullSecrets | list | `[]` | | +| ingress.annotations | object | `{}` | | +| ingress.enabled | bool | `false` | | +| ingress.hosts[0].host | string | `"chart-example.local"` | | +| ingress.hosts[0].paths | list | `[]` | | +| ingress.tls | list | `[]` | | +| jwtKey | string | `"!ChangeThisMercureHubJWTSecretKey!"` | | +| messageUriTemplate | string | `"https://chat.example.com/messages/{id}"` | | +| nameOverride | string | `""` | | +| nodeSelector | object | `{}` | | +| podAnnotations | object | `{}` | | +| podSecurityContext | object | `{}` | | +| replicaCount | int | `1` | | +| resources | object | `{}` | | +| securityContext | object | `{}` | | +| service.port | int | `80` | | +| service.type | string | `"ClusterIP"` | | +| serviceAccount.annotations | object | `{}` | | +| serviceAccount.create | bool | `true` | | +| serviceAccount.name | string | `""` | | +| tolerations | list | `[]` | | + +--- ----------------------------------------------- Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/examples/chat/static/chat.js b/examples/chat/static/chat.js index fb9488ba..9e6cf46d 100644 --- a/examples/chat/static/chat.js +++ b/examples/chat/static/chat.js @@ -1,107 +1,109 @@ /* eslint-env browser */ -const type = 'https://chat.example.com/Message' +const type = "https://chat.example.com/Message"; const { hubURL, messageURITemplate, subscriptionsTopic, username } = JSON.parse( - document.getElementById('config').textContent -) + document.getElementById("config").textContent, +); -document.getElementById('username').textContent = username +document.getElementById("username").textContent = username; -const $messages = document.getElementById('messages') -const $messageTemplate = document.getElementById('message') -const $userList = document.getElementById('user-list') -const $onlineUserTemplate = document.getElementById('online-user') +const $messages = document.getElementById("messages"); +const $messageTemplate = document.getElementById("message"); +const $userList = document.getElementById("user-list"); +const $onlineUserTemplate = document.getElementById("online-user"); let userList; (async () => { const resp = await fetch(new URL(subscriptionsTopic, hubURL), { - credentials: 'include' - }) - const subscriptionCollection = await resp.json() + credentials: "include", + }); + const subscriptionCollection = await resp.json(); userList = new Map( subscriptionCollection.subscriptions .reduce((acc, { payload }) => { - if (payload.username !== username) acc.push([payload.username, true]) - return acc + if (payload.username !== username) acc.push([payload.username, true]); + return acc; }, []) - .sort() - ) - updateUserListView() + .sort(), + ); + updateUserListView(); - const subscribeURL = new URL(hubURL) + const subscribeURL = new URL(hubURL); subscribeURL.searchParams.append( - 'lastEventID', - subscriptionCollection.lastEventID - ) - subscribeURL.searchParams.append('topic', messageURITemplate) + "lastEventID", + subscriptionCollection.lastEventID, + ); + subscribeURL.searchParams.append("topic", messageURITemplate); subscribeURL.searchParams.append( - 'topic', - `${subscriptionsTopic}{/subscriber}` - ) + "topic", + `${subscriptionsTopic}{/subscriber}`, + ); - const es = new EventSource(subscribeURL, { withCredentials: true }) + const es = new EventSource(subscribeURL, { withCredentials: true }); es.onmessage = ({ data }) => { - const update = JSON.parse(data) + const update = JSON.parse(data); - if (update['@type'] === type) { - displayMessage(update) - return + if (update["@type"] === type) { + displayMessage(update); + return; } - if (update.type === 'Subscription') { - updateUserList(update) - return + if (update.type === "Subscription") { + updateUserList(update); + return; } - console.warn('Received an unsupported update type', update) - } -})() + console.warn("Received an unsupported update type", update); + }; +})(); const updateUserListView = () => { - $userList.textContent = '' + $userList.textContent = ""; userList.forEach((_, username) => { - const el = document.importNode($onlineUserTemplate.content, true) - el.querySelector('.username').textContent = username - $userList.append(el) - }) -} + const el = document.importNode($onlineUserTemplate.content, true); + el.querySelector(".username").textContent = username; + $userList.append(el); + }); +}; const displayMessage = ({ username, message }) => { - const el = document.importNode($messageTemplate.content, true) - el.querySelector('.username').textContent = username - el.querySelector('.msg').textContent = message - $messages.append(el) + const el = document.importNode($messageTemplate.content, true); + el.querySelector(".username").textContent = username; + el.querySelector(".msg").textContent = message; + $messages.append(el); // scroll at the bottom when a new message is received - $messages.scrollTop = $messages.scrollHeight -} + $messages.scrollTop = $messages.scrollHeight; +}; const updateUserList = ({ active, payload }) => { - if (username === payload.username) return + if (username === payload.username) return; - active ? userList.set(payload.username, true) : userList.delete(payload.username) - userList = new Map([...userList.entries()].sort()) + active + ? userList.set(payload.username, true) + : userList.delete(payload.username); + userList = new Map([...userList.entries()].sort()); - updateUserListView() -} + updateUserListView(); +}; -document.querySelector('form').onsubmit = function (e) { - e.preventDefault() +document.querySelector("form").onsubmit = function (e) { + e.preventDefault(); - const uid = window.crypto.getRandomValues(new Uint8Array(10)).join('') - const messageTopic = messageURITemplate.replace('{id}', uid) + const uid = window.crypto.getRandomValues(new Uint8Array(10)).join(""); + const messageTopic = messageURITemplate.replace("{id}", uid); const body = new URLSearchParams({ data: JSON.stringify({ - '@type': type, - '@id': messageTopic, + "@type": type, + "@id": messageTopic, username, - message: this.elements.message.value + message: this.elements.message.value, }), topic: messageTopic, - private: true - }) - fetch(hubURL, { method: 'POST', body, credentials: 'include' }) - this.elements.message.value = '' - this.elements.message.focus() -} + private: true, + }); + fetch(hubURL, { method: "POST", body, credentials: "include" }); + this.elements.message.value = ""; + this.elements.message.focus(); +}; diff --git a/examples/chat/templates/chat.html b/examples/chat/templates/chat.html index b18ce3e0..6a87ba0d 100644 --- a/examples/chat/templates/chat.html +++ b/examples/chat/templates/chat.html @@ -1,54 +1,62 @@ -{% extends "layout.html" %} -{% block content %} +{% extends "layout.html" %} {% block content %}
-
-
-
- -
+
+
+
+ +
-
-
-
- -
-
- -
-
-
+
+
+
+
-
- -
-
-

Online

+
+ +
+
+ +
+
- +
+
+

Online

-
- - - - -
+ -
-
+
+ + + +
+ +
+
+
- + {% endblock %} diff --git a/examples/chat/templates/join.html b/examples/chat/templates/join.html index 8d6be4c7..a5beaa2b 100644 --- a/examples/chat/templates/join.html +++ b/examples/chat/templates/join.html @@ -1,19 +1,24 @@ -{% extends "layout.html" %} -{% block content %} +{% extends "layout.html" %} {% block content %}
-

Join the chat

-
-
-
- - - - -
-
- -
-
-
+

Join the chat

+
+
+
+ + + + +
+
+ +
+
+
{% endblock %} diff --git a/examples/chat/templates/layout.html b/examples/chat/templates/layout.html index 141c1bf3..3650d3fd 100644 --- a/examples/chat/templates/layout.html +++ b/examples/chat/templates/layout.html @@ -1,40 +1,54 @@ - + + + + + + A chat using Mercure + + + + - - - - - A chat using Mercure - - - - - - -
-
-
-
-

- Mercure -

-

Demo Chat App (sources)

+ +
+
+
+
+

+ Mercure +

+

+ Demo Chat App (sources) +

+
-
-
{% block content %}{% endblock %}
- - - +
{% block content %}{% endblock %}
+ + diff --git a/examples/publish/node.js b/examples/publish/node.js index f3e0e677..f046d2d9 100644 --- a/examples/publish/node.js +++ b/examples/publish/node.js @@ -1,35 +1,35 @@ -const http = require('http') -const querystring = require('querystring') +const http = require("http"); +const querystring = require("querystring"); const demoJwt = - 'eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS9teS1wcml2YXRlLXRvcGljIiwie3NjaGVtZX06Ly97K2hvc3R9L2RlbW8vYm9va3Mve2lkfS5qc29ubGQiLCIvLndlbGwta25vd24vbWVyY3VyZS9zdWJzY3JpcHRpb25zey90b3BpY317L3N1YnNjcmliZXJ9Il0sInBheWxvYWQiOnsidXNlciI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdXNlcnMvZHVuZ2xhcyIsInJlbW90ZUFkZHIiOiIxMjcuMC4wLjEifX19.KKPIikwUzRuB3DTpVw6ajzwSChwFw5omBMmMcWKiDcM' + "eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS9teS1wcml2YXRlLXRvcGljIiwie3NjaGVtZX06Ly97K2hvc3R9L2RlbW8vYm9va3Mve2lkfS5qc29ubGQiLCIvLndlbGwta25vd24vbWVyY3VyZS9zdWJzY3JpcHRpb25zey90b3BpY317L3N1YnNjcmliZXJ9Il0sInBheWxvYWQiOnsidXNlciI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdXNlcnMvZHVuZ2xhcyIsInJlbW90ZUFkZHIiOiIxMjcuMC4wLjEifX19.KKPIikwUzRuB3DTpVw6ajzwSChwFw5omBMmMcWKiDcM"; const postData = querystring.stringify({ - topic: 'https://localhost/demo/books/1.jsonld', - data: JSON.stringify({ key: 'updated value' }) -}) + topic: "https://localhost/demo/books/1.jsonld", + data: JSON.stringify({ key: "updated value" }), +}); const req = http.request( { - hostname: 'localhost', - port: '3000', - path: '/.well-known/mercure', - method: 'POST', + hostname: "localhost", + port: "3000", + path: "/.well-known/mercure", + method: "POST", headers: { Authorization: `Bearer ${demoJwt}`, - 'Content-Type': 'application/x-www-form-urlencoded', - 'Content-Length': Buffer.byteLength(postData) - } + "Content-Type": "application/x-www-form-urlencoded", + "Content-Length": Buffer.byteLength(postData), + }, }, (res) => { - console.log(`Status: ${res.statusCode}`) - console.log(`Headers: ${JSON.stringify(res.headers)}`) - } -) + console.log(`Status: ${res.statusCode}`); + console.log(`Headers: ${JSON.stringify(res.headers)}`); + }, +); -req.on('error', (e) => { - console.error(`An error occurred: ${e.message}`) -}) +req.on("error", (e) => { + console.error(`An error occurred: ${e.message}`); +}); -req.write(postData) -req.end() +req.write(postData); +req.end(); diff --git a/public/app.js b/public/app.js index 7ecd8709..439b8f67 100644 --- a/public/app.js +++ b/public/app.js @@ -1,278 +1,285 @@ -'use strict'; +"use strict"; /* eslint-env browser */ /* global EventSourcePolyfill */ (function () { - const origin = window.location.origin - const defaultTopic = document.URL + 'demo/books/1.jsonld' - const placeholderTopic = 'https://example.com/my-private-topic' + const origin = window.location.origin; + const defaultTopic = document.URL + "demo/books/1.jsonld"; + const placeholderTopic = "https://example.com/my-private-topic"; const defaultJwt = - 'eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS9teS1wcml2YXRlLXRvcGljIiwie3NjaGVtZX06Ly97K2hvc3R9L2RlbW8vYm9va3Mve2lkfS5qc29ubGQiLCIvLndlbGwta25vd24vbWVyY3VyZS9zdWJzY3JpcHRpb25zey90b3BpY317L3N1YnNjcmliZXJ9Il0sInBheWxvYWQiOnsidXNlciI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdXNlcnMvZHVuZ2xhcyIsInJlbW90ZUFkZHIiOiIxMjcuMC4wLjEifX19.KKPIikwUzRuB3DTpVw6ajzwSChwFw5omBMmMcWKiDcM' + "eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJzdWJzY3JpYmUiOlsiaHR0cHM6Ly9leGFtcGxlLmNvbS9teS1wcml2YXRlLXRvcGljIiwie3NjaGVtZX06Ly97K2hvc3R9L2RlbW8vYm9va3Mve2lkfS5qc29ubGQiLCIvLndlbGwta25vd24vbWVyY3VyZS9zdWJzY3JpcHRpb25zey90b3BpY317L3N1YnNjcmliZXJ9Il0sInBheWxvYWQiOnsidXNlciI6Imh0dHBzOi8vZXhhbXBsZS5jb20vdXNlcnMvZHVuZ2xhcyIsInJlbW90ZUFkZHIiOiIxMjcuMC4wLjEifX19.KKPIikwUzRuB3DTpVw6ajzwSChwFw5omBMmMcWKiDcM"; - const $updates = document.getElementById('updates') - const $subscriptions = document.getElementById('subscriptions') - const $settingsForm = document.forms.settings - const $discoverForm = document.forms.discover - const $subscribeForm = document.forms.subscribe - const $publishForm = document.forms.publish - const $subscriptionsForm = document.forms.subscriptions + const $updates = document.getElementById("updates"); + const $subscriptions = document.getElementById("subscriptions"); + const $settingsForm = document.forms.settings; + const $discoverForm = document.forms.discover; + const $subscribeForm = document.forms.subscribe; + const $publishForm = document.forms.publish; + const $subscriptionsForm = document.forms.subscriptions; const error = (e) => { - if (!e.error || e.error.message?.includes?.('Reconnecting')) { + if (!e.error || e.error.message?.includes?.("Reconnecting")) { // Silent reconnecting messages from the polyfill - console.log('Connection closed, reconnecting...', e) + console.log("Connection closed, reconnecting...", e); - return + return; } - console.log(e) + console.log(e); if (e.toString !== Object.prototype.toString) { // Display relevant error message - alert(e.toString()) + alert(e.toString()); - return + return; } if (e.statusText) { // Special handling of errors from the polyfill - alert(e.statusText) + alert(e.statusText); - return + return; } - alert('An error occured, details have been logged.') - } + alert("An error occured, details have been logged."); + }; const getHubUrl = (resp) => { - const link = resp.headers.get('Link') + const link = resp.headers.get("Link"); if (!link) { - error('No rel="mercure" Link header provided.') + error('No rel="mercure" Link header provided.'); } - const match = link.match(/<(.*)>.*rel="mercure".*/) - if (match && match[1]) return match[1] - } + const match = link.match(/<(.*)>.*rel="mercure".*/); + if (match && match[1]) return match[1]; + }; // Set default values - document.addEventListener('DOMContentLoaded', () => { - $settingsForm.hubUrl.value = origin + '/.well-known/mercure' - $settingsForm.jwt.value = defaultJwt + document.addEventListener("DOMContentLoaded", () => { + $settingsForm.hubUrl.value = origin + "/.well-known/mercure"; + $settingsForm.jwt.value = defaultJwt; - $discoverForm.topic.value = defaultTopic + $discoverForm.topic.value = defaultTopic; $discoverForm.body.value = JSON.stringify( { - '@id': defaultTopic, - availability: 'https://schema.org/InStock' + "@id": defaultTopic, + availability: "https://schema.org/InStock", }, null, - 2 - ) + 2, + ); $publishForm.data.value = JSON.stringify( { - '@id': defaultTopic, - availability: 'https://schema.org/OutOfStock' + "@id": defaultTopic, + availability: "https://schema.org/OutOfStock", }, null, - 2 - ) + 2, + ); - document.getElementById( - 'subscribeTopicsExamples' - ).textContent = `${document.URL}demo/novels/{id}.jsonld + document.getElementById("subscribeTopicsExamples").textContent = + `${document.URL}demo/novels/{id}.jsonld ${defaultTopic} -foo` - }) +foo`; + }); // Discover $discoverForm.onsubmit = async function (e) { - e.preventDefault() + e.preventDefault(); const { - elements: { topic, body } - } = this - const jwt = $settingsForm.jwt.value + elements: { topic, body }, + } = this; + const jwt = $settingsForm.jwt.value; - const url = new URL(topic.value) - if (body.value) url.searchParams.append('body', body.value) - if (jwt) url.searchParams.append('jwt', jwt) + const url = new URL(topic.value); + if (body.value) url.searchParams.append("body", body.value); + if (jwt) url.searchParams.append("jwt", jwt); try { - const resp = await fetch(url) - if (!resp.ok) throw new Error(resp.statusText) + const resp = await fetch(url); + if (!resp.ok) throw new Error(resp.statusText); // Set hub default - const hubUrl = getHubUrl(resp) - if (hubUrl) $settingsForm.hubUrl.value = new URL(hubUrl, topic.value) + const hubUrl = getHubUrl(resp); + if (hubUrl) $settingsForm.hubUrl.value = new URL(hubUrl, topic.value); - const subscribeTopics = $subscribeForm.topics - if (subscribeTopics.value === placeholderTopic) { subscribeTopics.value = topic.value } + const subscribeTopics = $subscribeForm.topics; + if (subscribeTopics.value === placeholderTopic) { + subscribeTopics.value = topic.value; + } // Set publish default values - const publishTopics = $publishForm.topics - if (publishTopics.value === placeholderTopic) { publishTopics.value = topic.value } + const publishTopics = $publishForm.topics; + if (publishTopics.value === placeholderTopic) { + publishTopics.value = topic.value; + } - const text = await resp.text() - body.value = text + const text = await resp.text(); + body.value = text; } catch (e) { - error(e) + error(e); } - } + }; // Subscribe - const $updateTemplate = document.getElementById('update') - let updateEventSource + const $updateTemplate = document.getElementById("update"); + let updateEventSource; $subscribeForm.onsubmit = function (e) { - e.preventDefault() + e.preventDefault(); - updateEventSource && updateEventSource.close() - $updates.textContent = 'No updates pushed yet.' + updateEventSource && updateEventSource.close(); + $updates.textContent = "No updates pushed yet."; const { - elements: { topics, lastEventId } - } = this - - const topicList = topics.value.split('\n') - const u = new URL($settingsForm.hubUrl.value) - topicList.forEach((topic) => u.searchParams.append('topic', topic)) - if (lastEventId.value) { u.searchParams.append('lastEventID', lastEventId.value) } + elements: { topics, lastEventId }, + } = this; + + const topicList = topics.value.split("\n"); + const u = new URL($settingsForm.hubUrl.value); + topicList.forEach((topic) => u.searchParams.append("topic", topic)); + if (lastEventId.value) { + u.searchParams.append("lastEventID", lastEventId.value); + } - let ol = null - if ($settingsForm.authorization.value === 'header') { + let ol = null; + if ($settingsForm.authorization.value === "header") { updateEventSource = new EventSourcePolyfill(u, { headers: { - Authorization: `Bearer ${$settingsForm.jwt.value}` - } - }) - } else updateEventSource = new EventSource(u) + Authorization: `Bearer ${$settingsForm.jwt.value}`, + }, + }); + } else updateEventSource = new EventSource(u); updateEventSource.onmessage = function (e) { if (!ol) { - ol = document.createElement('ol') - ol.reversed = true + ol = document.createElement("ol"); + ol.reversed = true; - $updates.textContent = '' - $updates.appendChild(ol) + $updates.textContent = ""; + $updates.appendChild(ol); } - const li = document.importNode($updateTemplate.content, true) - li.querySelector('h2').textContent = e.lastEventId - li.querySelector('pre').textContent = e.data - ol.firstChild ? ol.insertBefore(li, ol.firstChild) : ol.appendChild(li) - } - updateEventSource.onerror = error - this.elements.unsubscribe.disabled = false - } + const li = document.importNode($updateTemplate.content, true); + li.querySelector("h2").textContent = e.lastEventId; + li.querySelector("pre").textContent = e.data; + ol.firstChild ? ol.insertBefore(li, ol.firstChild) : ol.appendChild(li); + }; + updateEventSource.onerror = error; + this.elements.unsubscribe.disabled = false; + }; $subscribeForm.elements.unsubscribe.onclick = function (e) { - e.preventDefault() + e.preventDefault(); - updateEventSource && updateEventSource.close() - this.disabled = true - $updates.textContent = 'Unsubscribed.' - } + updateEventSource && updateEventSource.close(); + this.disabled = true; + $updates.textContent = "Unsubscribed."; + }; // Publish $publishForm.onsubmit = async function (e) { - e.preventDefault() + e.preventDefault(); const { - elements: { topics, data, priv, id, type, retry } - } = this + elements: { topics, data, priv, id, type, retry }, + } = this; const body = new URLSearchParams({ data: data.value, id: id.value, type: type.value, - retry: retry.value - }) + retry: retry.value, + }); - topics.value.split('\n').forEach((topic) => body.append('topic', topic)) - priv.checked && body.append('private', 'on') + topics.value.split("\n").forEach((topic) => body.append("topic", topic)); + priv.checked && body.append("private", "on"); - const opt = { method: 'POST', body } - if ($settingsForm.authorization.value === 'header') { opt.headers = { Authorization: `Bearer ${$settingsForm.jwt.value}` } } + const opt = { method: "POST", body }; + if ($settingsForm.authorization.value === "header") { + opt.headers = { Authorization: `Bearer ${$settingsForm.jwt.value}` }; + } try { - const resp = await fetch($settingsForm.hubUrl.value, opt) - if (!resp.ok) throw new Error(resp.statusText) + const resp = await fetch($settingsForm.hubUrl.value, opt); + if (!resp.ok) throw new Error(resp.statusText); } catch (e) { - error(e) + error(e); } - } + }; // Subscriptions - const $subscriptionTemplate = document.getElementById('subscription') - let subscriptionEventSource + const $subscriptionTemplate = document.getElementById("subscription"); + let subscriptionEventSource; const addSubscription = (s) => { const subscription = document.importNode( $subscriptionTemplate.content, - true - ) - subscription.querySelector('div').setAttribute('id', s.id) - subscription.querySelector('.card-header-title').textContent = s.id - subscription.querySelector('.topic').textContent = s.topic - subscription.querySelector('.subscriber').textContent = s.subscriber - subscription.querySelector('code').textContent = JSON.stringify( + true, + ); + subscription.querySelector("div").setAttribute("id", s.id); + subscription.querySelector(".card-header-title").textContent = s.id; + subscription.querySelector(".topic").textContent = s.topic; + subscription.querySelector(".subscriber").textContent = s.subscriber; + subscription.querySelector("code").textContent = JSON.stringify( s.payload, null, - 2 - ) - $subscriptions.appendChild(subscription) - } + 2, + ); + $subscriptions.appendChild(subscription); + }; $subscriptionsForm.onsubmit = async (e) => { - e.preventDefault() + e.preventDefault(); - subscriptionEventSource && subscriptionEventSource.close() - $subscriptions.textContent = '' + subscriptionEventSource && subscriptionEventSource.close(); + $subscriptions.textContent = ""; try { const opt = - $settingsForm.authorization.value === 'header' + $settingsForm.authorization.value === "header" ? { headers: { Authorization: `Bearer ${$settingsForm.jwt.value}` } } - : undefined + : undefined; const resp = await fetch( `${$settingsForm.hubUrl.value}/subscriptions`, - opt - ) - if (!resp.ok) throw new Error(resp.statusText) - const json = await resp.json() + opt, + ); + if (!resp.ok) throw new Error(resp.statusText); + const json = await resp.json(); - json.subscriptions.forEach(addSubscription) + json.subscriptions.forEach(addSubscription); - const u = new URL($settingsForm.hubUrl.value) + const u = new URL($settingsForm.hubUrl.value); u.searchParams.append( - 'topic', - '/.well-known/mercure/subscriptions{/topic}{/subscriber}' - ) - u.searchParams.append('lastEventID', json.lastEventID) + "topic", + "/.well-known/mercure/subscriptions{/topic}{/subscriber}", + ); + u.searchParams.append("lastEventID", json.lastEventID); - if (opt) subscriptionEventSource = new EventSourcePolyfill(u, opt) - else subscriptionEventSource = new EventSource(u) + if (opt) subscriptionEventSource = new EventSourcePolyfill(u, opt); + else subscriptionEventSource = new EventSource(u); subscriptionEventSource.onmessage = function (e) { - const s = JSON.parse(e.data) + const s = JSON.parse(e.data); if (s.active) { - addSubscription(s) - return + addSubscription(s); + return; } - document.getElementById(s.id).remove() - } - subscriptionEventSource.onerror = error + document.getElementById(s.id).remove(); + }; + subscriptionEventSource.onerror = error; - $subscriptionsForm.elements.unsubscribe.disabled = false + $subscriptionsForm.elements.unsubscribe.disabled = false; } catch (e) { - error(e) + error(e); } - } + }; $subscriptionsForm.elements.unsubscribe.onclick = function (e) { - e.preventDefault() + e.preventDefault(); - subscriptionEventSource.close() - this.disabled = true - $subscriptions.textContent = '' - } -})() + subscriptionEventSource.close(); + this.disabled = true; + $subscriptions.textContent = ""; + }; +})(); diff --git a/public/index.html b/public/index.html index 4c5f02e2..356fa893 100644 --- a/public/index.html +++ b/public/index.html @@ -1,278 +1,324 @@ - + - - + Mercure - + - + - +
-
-
-
-

- Mercure -

-

Debugging Tools

-
-
+
+
+
+

+ Mercure +

+

Debugging Tools

+
+
-
-
-
-

Subscribe

-
-
- -
- -
- -
-

- One - URI template - or string per line (try the - tester). -

-

Use * to subscribe to all topics.

-

Examples:

-
-
-
- -
- -
- -
-
- - - -
+
+
+
+

Subscribe

+
+
+ +
+ +
-
Not subscribed.
+
+

+ One + URI template + or string per line (try the tester). +

+

Use * to subscribe to all topics.

+

Examples:

+
+
+
+ +
+ +
+ +
+
+ + + +
+ +
Not subscribed.
+ + +
+
- -
+
+

Publish

+ +
+
+ +
+ +
+ +

+ First line: canonical + IRI or + string.
+ Next lines: alternate IRIs or strings. +

-
-

Publish

- - -
- -
- -
- -

- First line: canonical - IRI or - string.
- Next lines: alternate IRIs or strings. -

-
- -
- -
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
+
+ +
- - -
-
-
-
-
-

Settings

+
+ +
+ +
+
-
-
- - +
+ +
+ +
+
-

- Will be filled automatically if you - discover a resource. -

-
+
+ +
+ +
+
-
- +
+ +
+ +
+
-
- - -
+ + +
+
+
+
+
+

Settings

+ +
+
+ + + +

+ Will be filled automatically if you + discover a resource. +

+
-

- The authorization cookie will be set - automatically by the server only if you - discover a demo endpoint. -

-
+
+ + +
+ + +
+ +

+ The authorization cookie will be set automatically by the server + only if you + discover a demo endpoint. +

+
-
- - +
+ + -
-

- Required to publish, or to subscribe to private updates.
- Claim structure to use: -

-
{
+              
+

+ Required to publish, or to subscribe to private updates.
+ Claim structure to use: +

+
{
   "mercure": {
     "subscribe": ["list of topic selectors, * for all, omit for public only"],
     "publish": ["list of topic selectors, * for all, omit to not allow to publish"]
   }
 }
-
- Create a - token - (demo key: !ChangeThisMercureHubJWTSecretKey!) -
-
- - - -
-

Discover

- -
-
- -
- -
- -

- URL returning a Link rel="mercure" HTTP header to - init the discovery.
- Demo endpoints: any subpath of /demo. -

-
- -
- -
- -
+
+ Create a token + (demo key: !ChangeThisMercureHubJWTSecretKey!) +
+
+ + + +
+

Discover

+ +
+
+ +
+ +
+ +

+ URL returning a Link rel="mercure" HTTP header to + init the discovery.
+ Demo endpoints: any subpath of /demo. +

+
-

- Data to return. Supported only by demo endpoints. -

-
+
+ +
+ +
- - - -
-
-
-
-

Active subscriptions

-
- - -
+

+ Data to return. Supported only by demo endpoints. +

+ + + + +
+
+
+
+

Active subscriptions

+
+ + +
-
- +
- - + diff --git a/spec/openapi.yaml b/spec/openapi.yaml index 79b7ae08..92e51409 100644 --- a/spec/openapi.yaml +++ b/spec/openapi.yaml @@ -86,7 +86,7 @@ paths: "text/plain": {} "401": $ref: "#/components/responses/401" - '400': + "400": description: Invalid request "/.well-known/mercure/subscriptions": get: @@ -174,7 +174,7 @@ components: subscriptions: type: array items: - $ref: '#/components/schemas/Subscription' + $ref: "#/components/schemas/Subscription" Subscription: type: object required: ["id", "type", "topic", "subscriber", "active"] From 7857d786fdd54e001801120aae9c0779e865baa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 23 Oct 2024 18:12:40 +0200 Subject: [PATCH 29/71] chore: revert payloads-related changes (#964) --- authorization.go | 8 +++----- docs/UPGRADE.md | 30 +----------------------------- hub_test.go | 11 +++++------ spec/mercure.md | 34 +++++++--------------------------- subscribe.go | 44 +++++++------------------------------------- subscribe_test.go | 18 +++++++++--------- subscriber.go | 17 ++--------------- subscription_test.go | 35 ----------------------------------- 8 files changed, 34 insertions(+), 163 deletions(-) diff --git a/authorization.go b/authorization.go index 3c8ed646..c073b77e 100644 --- a/authorization.go +++ b/authorization.go @@ -19,11 +19,9 @@ type claims struct { } type mercureClaim struct { - Publish []string `json:"publish"` - Subscribe []string `json:"subscribe"` - // Deprecated: use the Payloads field instead - Payload interface{} `json:"payload"` - Payloads map[string]interface{} `json:"payloads"` + Publish []string `json:"publish"` + Subscribe []string `json:"subscribe"` + Payload interface{} `json:"payload"` } type role int diff --git a/docs/UPGRADE.md b/docs/UPGRADE.md index faf45aac..f7582e57 100644 --- a/docs/UPGRADE.md +++ b/docs/UPGRADE.md @@ -1,34 +1,6 @@ # Upgrade -## 0.20 - -The `mercure.payload` JWT key has been deprecated. It is now possible to make topic-specific data -available in subscriptions events and through the subscription API. -To make data available in all events and API responses describing subscriptions, use the `*` topic selector. - -Before: - -```json -{ - "mercure": { - "payload": { "foo": "bar" } - } -} -``` - -After: - -```json -{ - "mercure": { - "payloads": { - "*": { "foo": "bar" } - } - } -} -``` - -[Read the updated specification](../spec/mercure.md#payloads) to learn how to leverage this new feature. +## 0.17 The `MERCURE_TRANSPORT_URL` environment variable and the `transport_url` directive have been deprecated. Use the new `transport` directive instead. diff --git a/hub_test.go b/hub_test.go index 247af9c4..45c0774e 100644 --- a/hub_test.go +++ b/hub_test.go @@ -264,13 +264,12 @@ func createAnonymousDummy(options ...Option) *Hub { } func createDummyAuthorizedJWT(r role, topics []string) string { - payloads := map[string]interface{}{"*": make(map[string]string)} - payloads["*"].(map[string]string)["foo"] = "bar" - - return createDummyAuthorizedJWTWithPayload(r, topics, payloads) + return createDummyAuthorizedJWTWithPayload(r, topics, struct { + Foo string `json:"foo"` + }{Foo: "bar"}) } -func createDummyAuthorizedJWTWithPayload(r role, topics []string, payloads map[string]interface{}) string { +func createDummyAuthorizedJWTWithPayload(r role, topics []string, payload interface{}) string { token := jwt.New(jwt.SigningMethodHS256) var key []byte @@ -283,7 +282,7 @@ func createDummyAuthorizedJWTWithPayload(r role, topics []string, payloads map[s token.Claims = &claims{ Mercure: mercureClaim{ Subscribe: topics, - Payloads: payloads, + Payload: payload, }, RegisteredClaims: jwt.RegisteredClaims{}, } diff --git a/spec/mercure.md b/spec/mercure.md index ced233d1..0b1b3ca9 100644 --- a/spec/mercure.md +++ b/spec/mercure.md @@ -472,34 +472,14 @@ Consequently, this private update will be received by this subscriber, while oth a canonical topic matched by the selector provided in a `topic` query parameter but not matched by selectors in the `mercure.subscribe` claim will not. -## Payloads - -User-defined data can be attached to subscriptions and made available through the subscription API -and in subscription events. +## Payload +The `mercure` claim of the JWS **CAN** also contain user-defined values under the `payload` key. +This JSON document will be attached to the subscription and made available in subscription events. See (#subscription-events). -The `mercure` claim of the JWS **CAN** contain a JSON object under the `payloads` key. -This JSON document **MUST** have selectors as keys, and user-defined data as values. - -The value associated with the first topic selector matching the topic of the subscription -**MUST** be included under the `payload` key in the JSON object describing a subscription in -the subscription API and in subscription events. - -Example JWT document containing payloads: - -~~~ json -{ - "subscribe": ["https://example.com/foo", "https://example.com/bar/baz"] - "payloads": { - "https://example.com/bar/{val}": {"custom": "data only available for subscriptions matching this selector"}, - "*": {"data": "available for all other topics"} - } -} -~~~ - -For instance, payloads can contain the user ID of the subscriber, its username, a list of groups it -belongs to, or its IP address. Storing data in `mercure.payloads` is a convenient way to share data +For instance, `mercure.payload` can contain the user ID of the subscriber, a list of groups it +belongs to, or its IP address. Storing data in `mercure.payload` is a convenient way to share data related to one subscriber to other subscribers. # Reconnection, State Reconciliation and Event Sourcing {#reconciliation} @@ -595,8 +575,8 @@ least the following properties: * `topic`: the topic selector used of this subscription * `subscriber`: the topic identifier of the subscriber. It **SHOULD** be an IRI. * `active`: `true` when the subscription is active, and `false` when it is terminated -* `payload` (optional): content of the `mercure.payloads` in the subscriber's JWS matching the topic - (see (#authorization)) +* `payload` (optional): the content of `mercure.payload` in the subscriber's JWS (see + (#authorization)) The JSON-LD document **MAY** contain other properties. diff --git a/subscribe.go b/subscribe.go index 201c401d..c70bae70 100644 --- a/subscribe.go +++ b/subscribe.go @@ -203,47 +203,17 @@ func (h *Hub) registerSubscriber(w http.ResponseWriter, r *http.Request) (*Subsc rc := h.newResponseController(w, s) rc.flush() - h.normalizeClaims(claims) - h.logNewSubscriber(claims, s) - h.metrics.SubscriberConnected(s) - - return s, rc -} - -func (h *Hub) logNewSubscriber(claims *claims, s *Subscriber) { - c := h.logger.Check(zap.InfoLevel, "New subscriber") - if c == nil { - return - } - - fields := []LogField{zap.Object("subscriber", s)} - if claims != nil && h.logger.Level() == zap.DebugLevel { - if claims.Mercure.Payload != nil && h.opt.isBackwardCompatiblyEnabledWith(8) { - fields = append( - fields, - zap.Reflect("payload", claims.Mercure.Payload), - ) + if c := h.logger.Check(zap.InfoLevel, "New subscriber"); c != nil { + fields := []LogField{zap.Object("subscriber", s)} + if claims != nil && h.logger.Level() == zap.DebugLevel { + fields = append(fields, zap.Reflect("payload", claims.Mercure.Payload)) } - fields = append( - fields, - zap.Reflect("payloads", claims.Mercure.Payloads), - ) - } - - c.Write(fields...) -} - -func (h *Hub) normalizeClaims(c *claims) { - if c == nil || c.Mercure.Payload == nil { - return + c.Write(fields...) } + h.metrics.SubscriberConnected(s) - if h.opt.isBackwardCompatiblyEnabledWith(8) { - h.logger.Info(`Deprecated: the "mercure.payload" JWT claim deprecated since the version 8 of the protocol, use "mercure.payloads" claim with a "*" key instead.`) - } else { - c.Mercure.Payload = nil - } + return s, rc } // sendHeaders sends correct HTTP headers to create a keep-alive connection. diff --git a/subscribe_test.go b/subscribe_test.go index 0eb1de34..24083513 100644 --- a/subscribe_test.go +++ b/subscribe_test.go @@ -332,12 +332,12 @@ func TestSubscribe(t *testing.T) { testSubscribe(t, 3) } -func testSubscribeLogs(t *testing.T, hub *Hub, payloads map[string]interface{}) { +func testSubscribeLogs(t *testing.T, hub *Hub, payload interface{}) { t.Helper() ctx, cancel := context.WithCancel(context.Background()) req := httptest.NewRequest(http.MethodGet, defaultHubURL+"?topic=http://example.com/reviews/{id}", nil).WithContext(ctx) - req.AddCookie(&http.Cookie{Name: "mercureAuthorization", Value: createDummyAuthorizedJWTWithPayload(roleSubscriber, []string{"http://example.com/reviews/22"}, payloads)}) + req.AddCookie(&http.Cookie{Name: "mercureAuthorization", Value: createDummyAuthorizedJWTWithPayload(roleSubscriber, []string{"http://example.com/reviews/22"}, payload)}) w := &responseTester{ expectedStatusCode: http.StatusOK, @@ -351,18 +351,18 @@ func testSubscribeLogs(t *testing.T, hub *Hub, payloads map[string]interface{}) func TestSubscribeWithLogLevelDebug(t *testing.T) { core, logs := observer.New(zapcore.DebugLevel) - payloads := map[string]interface{}{ - "*": make(map[string]string), + payload := map[string]interface{}{ + "bar": "baz", + "foo": "bar", } - payloads["*"].(map[string]string)["bar"] = "baz" - payloads["*"].(map[string]string)["foo"] = "bar" - testSubscribeLogs(t, createDummy( WithLogger(zap.New(core)), - ), payloads) + ), payload) - assert.Equal(t, 1, logs.FilterMessage("New subscriber").FilterFieldKey("payloads").Len()) + assert.Equal(t, 1, logs.FilterMessage("New subscriber").FilterField( + zap.Reflect("payload", payload)).Len(), + ) } func TestSubscribeLogLevelInfo(t *testing.T) { diff --git a/subscriber.go b/subscriber.go index b6807bf0..b22ac03b 100644 --- a/subscriber.go +++ b/subscriber.go @@ -209,21 +209,8 @@ func (s *Subscriber) getSubscriptions(topic, context string, active bool) []subs Topic: t, Active: active, } - if s.Claims != nil { //nolint:nestif - if s.Claims.Mercure.Payloads == nil { - if s.Claims.Mercure.Payload != nil { - subscription.Payload = s.Claims.Mercure.Payload - } - } else { - for k, v := range s.Claims.Mercure.Payloads { - if !s.topicSelectorStore.match(t, k) { - continue - } - subscription.Payload = v - - break - } - } + if s.Claims != nil && s.Claims.Mercure.Payload != nil { + subscription.Payload = s.Claims.Mercure.Payload } subscriptions = append(subscriptions, subscription) diff --git a/subscription_test.go b/subscription_test.go index 12fef4c7..13363b8a 100644 --- a/subscription_test.go +++ b/subscription_test.go @@ -210,38 +210,3 @@ func TestSubscriptionHandler(t *testing.T) { assert.Equal(t, http.StatusNotFound, res.StatusCode) res.Body.Close() } - -func TestSubscriptionPayload(t *testing.T) { - logger := zap.NewNop() - tss := &TopicSelectorStore{} - - for _, selector := range []string{"*", "http://example.com/foo", "http://example.com/{var}"} { - t.Run("selector "+selector, func(t *testing.T) { - hub := createDummy(WithLogger(logger)) - - s1 := NewSubscriber("", logger, tss) - s1.SetTopics([]string{"http://example.com/foo"}, nil) - - s1.Claims = &claims{} - s1.Claims.Mercure.Payloads = map[string]interface{}{} - s1.Claims.Mercure.Payloads[selector] = "foo" - s1.Claims.Mercure.Payloads["http://example.com/bar"] = "bar" - - require.NoError(t, hub.transport.AddSubscriber(s1)) - - req := httptest.NewRequest(http.MethodGet, defaultHubURL+subscriptionsPath, nil) - req.AddCookie(&http.Cookie{Name: "mercureAuthorization", Value: createDummyAuthorizedJWT(roleSubscriber, []string{"/.well-known/mercure/subscriptions"})}) - w := httptest.NewRecorder() - hub.SubscriptionsHandler(w, req) - res := w.Result() - assert.Equal(t, http.StatusOK, res.StatusCode) - res.Body.Close() - - var subscriptions subscriptionCollection - json.Unmarshal(w.Body.Bytes(), &subscriptions) - - require.Len(t, subscriptions.Subscriptions, 1) - assert.Equal(t, "foo", subscriptions.Subscriptions[0].Payload) - }) - } -} From eee809a62949442319115f27c8f7fbd93435d8ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 25 Oct 2024 14:05:08 +0200 Subject: [PATCH 30/71] chore: various cleanups (#965) --- CONTRIBUTING.md | 2 +- bolt_transport.go | 31 +++++++++++++++++++++++-------- bolt_transport_test.go | 4 ++-- config.go | 2 +- demo.go | 2 +- docs/UPGRADE.md | 12 ++++++------ docs/getting-started.md | 5 +++-- docs/hub/cloud.md | 2 +- docs/hub/cluster.md | 40 ++++++++++++++++++++-------------------- docs/hub/config.md | 4 ++-- docs/hub/install.md | 2 +- docs/hub/traefik.md | 2 +- docs/spec/faq.md | 5 +++-- event.go | 6 +++--- hub.go | 4 ++-- jwt_keyfunc_test.go | 2 +- metrics.go | 2 +- publish.go | 7 ++++++- spec/mercure.md | 28 ++++++++++++++-------------- subscribe.go | 25 +++++++++++++++++++------ subscribe_test.go | 4 ++-- subscriber.go | 2 +- subscriber_bench_test.go | 2 +- subscriber_list_test.go | 2 +- subscription.go | 16 ++++++++++++---- topic_selector.go | 4 ++-- topic_selector_lru.go | 2 +- update.go | 2 +- 28 files changed, 132 insertions(+), 89 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2bc2dd93..dc23e4e1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -84,7 +84,7 @@ To debug potential deadlocks: ## Spec The spec is written in Markdown, compatible with [Mmark](https://mmark.miek.nl/). -It is then converted in the [the "xml2rfc" Version 3 Vocabulary](https://tools.ietf.org/html/rfc7991). +It is then converted in [the "xml2rfc" Version 3 Vocabulary](https://tools.ietf.org/html/rfc7991). To contribute to the protocol itself: diff --git a/bolt_transport.go b/bolt_transport.go index 4df7254c..0843eb64 100644 --- a/bolt_transport.go +++ b/bolt_transport.go @@ -98,6 +98,11 @@ func NewBoltTransport( return nil, &TransportError{err: err} } + lastEventID, err := getDBLastEventID(db, bucketName) + if err != nil { + return nil, &TransportError{err: err} + } + return &BoltTransport{ logger: logger, db: db, @@ -107,13 +112,13 @@ func NewBoltTransport( subscribers: NewSubscriberList(1e5), closed: make(chan struct{}), - lastEventID: getDBLastEventID(db, bucketName), + lastEventID: lastEventID, }, nil } -func getDBLastEventID(db *bolt.DB, bucketName string) string { +func getDBLastEventID(db *bolt.DB, bucketName string) (string, error) { lastEventID := EarliestLastEventID - db.View(func(tx *bolt.Tx) error { + err := db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(bucketName)) if b == nil { return nil // No data @@ -125,8 +130,11 @@ func getDBLastEventID(db *bolt.DB, bucketName string) string { return nil }) + if err != nil { + return "", fmt.Errorf("unable to get lastEventID from BoltDB: %w", err) + } - return lastEventID + return lastEventID, nil } // Dispatch dispatches an update to all subscribers and persists it in Bolt DB. @@ -176,7 +184,7 @@ func (t *BoltTransport) persist(updateID string, updateJSON []byte) error { // The sequence value is prepended to the update id to create an ordered list key := bytes.Join([][]byte{prefix, []byte(updateID)}, []byte{}) - // The DB is append only + // The DB is append-only bucket.FillPercent = 1 t.lastSeq = seq @@ -207,7 +215,9 @@ func (t *BoltTransport) AddSubscriber(s *Subscriber) error { t.Unlock() if s.RequestLastEventID != "" { - t.dispatchHistory(s, toSeq) + if err := t.dispatchHistory(s, toSeq); err != nil { + return err + } } s.Ready() @@ -239,8 +249,8 @@ func (t *BoltTransport) GetSubscribers() (string, []*Subscriber, error) { } //nolint:gocognit -func (t *BoltTransport) dispatchHistory(s *Subscriber, toSeq uint64) { - t.db.View(func(tx *bolt.Tx) error { +func (t *BoltTransport) dispatchHistory(s *Subscriber, toSeq uint64) error { + err := t.db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(t.bucketName)) if b == nil { s.HistoryDispatched(EarliestLastEventID) @@ -286,6 +296,11 @@ func (t *BoltTransport) dispatchHistory(s *Subscriber, toSeq uint64) { return nil }) + if err != nil { + return fmt.Errorf("unable to retrieve history from BoltDB: %w", err) + } + + return nil } // Close closes the Transport. diff --git a/bolt_transport_test.go b/bolt_transport_test.go index 0e31a364..ba78612c 100644 --- a/bolt_transport_test.go +++ b/bolt_transport_test.go @@ -203,7 +203,7 @@ func TestNewBoltTransport(t *testing.T) { u, _ = url.Parse("bolt:///test.db") _, err = DeprecatedNewBoltTransport(u, zap.NewNop()) - // The exact error message depends of the OS + // The exact error message depends on the OS assert.Contains(t, err.Error(), "open /test.db:") u, _ = url.Parse("bolt://test.db?cleanup_frequency=invalid") @@ -351,7 +351,7 @@ func TestBoltLastEventID(t *testing.T) { // The sequence value is prepended to the update id to create an ordered list key := bytes.Join([][]byte{prefix, []byte("foo")}, []byte{}) - // The DB is append only + // The DB is append-only bucket.FillPercent = 1 return bucket.Put(key, []byte("invalid")) diff --git a/config.go b/config.go index c90a737f..088cf15b 100644 --- a/config.go +++ b/config.go @@ -244,7 +244,7 @@ func NewHubFromViper(v *viper.Viper) (*Hub, error) { //nolint:funlen,gocognit return h, err } -// Start is an helper method to start the Mercure Hub. +// Start is a helper method to start the Mercure Hub. // // Deprecated: use the Caddy server module or the standalone library instead. func Start() { diff --git a/demo.go b/demo.go index 4789eb62..e7ae2816 100644 --- a/demo.go +++ b/demo.go @@ -22,7 +22,7 @@ var uiContent embed.FS // The Content-Type header will automatically be set according to the URL's extension. func (h *Hub) Demo(w http.ResponseWriter, r *http.Request) { // JSON-LD is the preferred format - mime.AddExtensionType(".jsonld", "application/ld+json") + _ = mime.AddExtensionType(".jsonld", "application/ld+json") url := r.URL.String() mimeType := mime.TypeByExtension(filepath.Ext(r.URL.Path)) diff --git a/docs/UPGRADE.md b/docs/UPGRADE.md index f7582e57..cbd940e6 100644 --- a/docs/UPGRADE.md +++ b/docs/UPGRADE.md @@ -5,11 +5,11 @@ The `MERCURE_TRANSPORT_URL` environment variable and the `transport_url` directive have been deprecated. Use the new `transport` directive instead. -The `MERCURE_TRANSPORT_URL` environement variable has been removed from the default `Caddyfile`s, +The `MERCURE_TRANSPORT_URL` environment variable has been removed from the default `Caddyfile`s, but a backward compatibility layer is provided. If both the `transport` and the deprecated `transport_url` are not explicitly set -and the `MERCURE_TRANSPORT_URL` environement variable is set, the `transport_url` will be automatically populated. +and the `MERCURE_TRANSPORT_URL` environment variable is set, the `transport_url` will be automatically populated. To disable this behavior, unset `MERCURE_TRANSPORT_URL` or set it to an empty string. Before: @@ -30,12 +30,12 @@ To configure the transport using an environment variable, append the `transport To prevent security issues, be sure to not pass credentials such as API tokens or password in `MERCURE_EXTRA_DIRECTIVES` (ex: when using transports [provided by the paid version](hub/cluster.md) such as Redis). -To pass credentials security, create a custom `Caddyfile` an use the `{env.MY_ENV_VAR}` syntax, which is interpreted at runtime. +To pass credentials security, create a custom `Caddyfile` and use the `{env.MY_ENV_VAR}` syntax, which is interpreted at runtime. ## 0.16.2 The `Caddyfile.dev` file has been renamed `dev.Caddyfile` to match new Caddy best practices -and prevent "ambigous adapter" issues. +and prevent "ambiguous adapter" issues. ## 0.14.4 @@ -52,9 +52,9 @@ The default dev key changed from `!ChangeMe!` to `!ChangeThisMercureHubJWTSecret ## 0.14 -The query parameter allowing to fetch past events has been renamed `lastEventID`: in your clients, replace all occurences of the `Last-Event-ID` query parameter by `lastEventID`. +The query parameter allowing to fetch past events has been renamed `lastEventID`: in your clients, replace all occurrences of the `Last-Event-ID` query parameter by `lastEventID`. -Publishing public updates in topics not explictly listed in the `mercure.publish` JWT claim isn't supported anymore. +Publishing public updates in topics not explicitly listed in the `mercure.publish` JWT claim isn't supported anymore. To let your publishers publish (public and private updates) in all topics, use the special `*` topic selector: ```patch diff --git a/docs/getting-started.md b/docs/getting-started.md index c8680282..2c34a74c 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -5,7 +5,8 @@ ## Starting the Hub The easiest way to get started is to [install the official Mercure.rocks -Hub](hub/install.md). When it's done, go directly to the next step. There are also other unofficial [libraries implementing Mercure](ecosystem/awesome.md#hubs-and-server-libraries). In the rest of this tutorial, we'll assume that the hub is running on `https://localhost` and that the `JWT_KEY` is `!ChangeThisMercureHubJWTSecretKey!`. +Hub](hub/install.md). When it's done, go directly to the next step. +There are other unofficial [libraries implementing Mercure](ecosystem/awesome.md#hubs-and-server-libraries). In the rest of this tutorial, we'll assume that the hub is running on `https://localhost` and that the `JWT_KEY` is `!ChangeThisMercureHubJWTSecretKey!`. Please note that the hub is entirely optional when using the Mercure protocol. Your app can also implement the Mercure protocol directly. @@ -47,7 +48,7 @@ Optionally, [the authorization mechanism](../spec/mercure.md#authorization) can ## Discovering the Mercure Hub -Also optionally, the hub URL can be automatically discovered: +Also, optionally, the hub URL can be automatically discovered: ![Discovery Schema](../spec/discovery.png) diff --git a/docs/hub/cloud.md b/docs/hub/cloud.md index 13555666..1c1584de 100644 --- a/docs/hub/cloud.md +++ b/docs/hub/cloud.md @@ -11,7 +11,7 @@ The Cloud service is built on top of the free and open-source hub and helps fund Purchase your managed Mercure.rocks hub [directly online](https://mercure.rocks/pricing)! -After purchase, your hub will be instantly provisionned and available under a `mercure.rocks` subdomain. A TLS certificate is also automatically created. +After purchase, your hub will be instantly provisioned and available under a `mercure.rocks` subdomain. A TLS certificate is also automatically created. You'll have access to an administration interface allowing you to: diff --git a/docs/hub/cluster.md b/docs/hub/cluster.md index 8e64628f..760c253c 100644 --- a/docs/hub/cluster.md +++ b/docs/hub/cluster.md @@ -22,7 +22,7 @@ To use it, just configure your custom domain name (if any) and your secret JWT k ## High Availability On Premise Version -The High Availability On Premise Mercure.rocks Hub is a drop-in replacement for the free Hub which allows to spread the load across as many servers as you want. It is designed to run on your own servers and is fault tolerant by default. +The High Availability On Premise Mercure.rocks Hub is a drop-in replacement for the free Hub which allows to spread the load across as many servers as you want. It is designed to run on your own servers and is fault-tolerant by default. The HA version is shipped with transports having node synchronization capabilities. These transports can rely on: @@ -59,7 +59,7 @@ If you use the Helm chart, set the `license` value and change the Docker image t ### Transports -The clustered mode of the Mercure.rocks Hub requires a transport to work. +The clustered mode of the Mercure.rocks Hub requires transport to work. Supported transports are Apache Pulsar, Apache Kafka and PostgreSQL. #### Redis Transport @@ -71,10 +71,10 @@ To install Redis, [read the documentation](https://redis.io/topics/quickstart). Most Cloud Computing platforms also provide managed versions of Redis. | Feature | Supported | -| --------------- | --------- | -| History | ✅ | -| Presence API | ✅ | -| Custom event ID | ✅ | +|-----------------|-----------| +| History | ✅ | +| Presence API | ✅ | +| Custom event ID | ✅ | ##### Configuration @@ -90,10 +90,10 @@ To use Redis, the `MERCURE_TRANSPORT_URL` environment variable must be set like The following options can be passed as query parameters of the URL set in `transport_url`: -| Parameter | Description | Default | -| ---------------- | ------------------------------------------------------------------------------------------------------ | ------- | -| `tls` | set to `1` to enable TLS support | `0` | -| `max_len_approx` | the approximative maximum number of messages to store in the history, set to `0` to store all messages | `0` | +| Parameter | Description | Default | +|------------------|------------------------------------------------------------------------------------------------------|---------| +| `tls` | set to `1` to enable TLS support | `0` | +| `max_len_approx` | the approximate maximum number of messages to store in the history, set to `0` to store all messages | `0` | #### PostgreSQL Transport @@ -103,8 +103,8 @@ It is mostly useful when using the Mercure.rocks Hub as an event store, or as a To install PostgreSQL, [read the documentation](https://www.postgresql.org/docs/12/tutorial-install.html). Most Cloud Computing platforms also provide managed versions of PostgreSQL. -| Feature | Supported | -| --------------- | ------------ | +| Feature | Supported | +|-----------------|-------------| | History | ✅ | | Presence API | ❌ (planned) | | Custom event ID | ✅ | @@ -138,10 +138,10 @@ The Mercure.rocks hub has been tested with: - Heroku Kafka | Feature | Supported | -| --------------- | --------- | -| History | ✅ | -| Presence API | ❌ | -| Custom event ID | ✅ | +|-----------------|-----------| +| History | ✅ | +| Presence API | ❌ | +| Custom event ID | ✅ | ##### Kafka Configuration @@ -158,7 +158,7 @@ To use Kafka, the `MERCURE_TRANSPORT_URL` environment variable must be set like The following options can be passed as query parameters of the URL set in `transport_url`: | Parameter | Description | -| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +|------------------|---------------------------------------------------------------------------------------------------------------------------------------------| | `addr` | addresses of the Kafka servers, you can pass several `addr` parameters to use several Kafka servers (ex: `addr=host1:9092&addr=host2:9092`) | | `topic` | the name of the Kafka topic to use (ex: `topic=mercure-ha`), **all Mercure.rocks hub instances must use the same topic** | | `consumer_group` | consumer group, **must be different for every instance of the Mercure.rocks hub** (ex: `consumer_group=`) | @@ -172,8 +172,8 @@ The Pulsar transport should only be used when Pulsar is already part of your sta To install Apache Pulsar, [read the documentation](https://pulsar.apache.org/docs/en/standalone/). -| Feature | Supported | -| --------------- | ------------ | +| Feature | Supported | +|-----------------|-------------| | History | ✅ | | Presence API | ❌ | | Custom event ID | ❌ (planned) | @@ -193,7 +193,7 @@ To use Pulsar, the `MERCURE_TRANSPORT_URL` environment variable must be set like The following options can be passed as query parameters of the URL set in `transport_url`: | Parameters | Description | | -| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | --- | +|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|-----| | `topic` | the name of the Pulsar topic to use (ex: `topic=mercure`), **all Mercure.rocks hub instances must use the same topic** | | | `subscription_name` | the subscription name for this node, **must be different for every instance of the Mercure.rocks hub** (ex: `subscription_name=`) | | diff --git a/docs/hub/config.md b/docs/hub/config.md index b7573654..d97f59f3 100644 --- a/docs/hub/config.md +++ b/docs/hub/config.md @@ -98,12 +98,12 @@ services: ## JWT Verification -JWT can validated using HMAC and RSA algorithms. +JWT can be validated using HMAC and RSA algorithms. In addition, it's possible to use JSON Web Key Sets (JWK Sets) (usually provided by OAuth and OIDC providers such as Keycloak or Amazon Cognito) to validate the keys. When using RSA public keys for verification make sure the key is properly formatted and make sure to set the correct algorithm as second parameter of the `publisher_jwt` or `subscriber_jwt` directives (for example `RS256`). -Here is an example of how to use environments variables with a RSA public key. +Here is an example of how to use environments variables with an RSA public key. Generate keys (if you don't already have them): diff --git a/docs/hub/install.md b/docs/hub/install.md index 852dc91c..e1b292ec 100644 --- a/docs/hub/install.md +++ b/docs/hub/install.md @@ -81,7 +81,7 @@ docker run \ dunglas/mercure ``` -HTTPS support is automatically enabled. If you run the Mercure hub behind a reverse proxy [such as NGINX](cookbooks.md#using-nginx-as-an-http-2-reverse-proxy-in-front-of-the-hub), you usually want to use unencrypted HTTP. +HTTPS support is automatically enabled. If you run the Mercure hub behind a reverse proxy [such as NGINX](nginx.md), you usually want to use unencrypted HTTP. This can be done like that: ```console diff --git a/docs/hub/traefik.md b/docs/hub/traefik.md index 9cbea484..59858abc 100644 --- a/docs/hub/traefik.md +++ b/docs/hub/traefik.md @@ -1,6 +1,6 @@ # Use the Mercure.rocks Hub with Traefik Proxy -[Traefik](https://doc.traefik.io/traefik/) is a free and open source _edge router_ poular in the Docker and Kubernetes ecosystems. +[Traefik](https://doc.traefik.io/traefik/) is a free and open source _edge router_ popular in the Docker and Kubernetes ecosystems. The following Docker Compose file exposes a Mercure.rocks hub through Traefik: diff --git a/docs/spec/faq.md b/docs/spec/faq.md index b652f2b9..74251a3d 100644 --- a/docs/spec/faq.md +++ b/docs/spec/faq.md @@ -5,7 +5,8 @@ In a nutshell [the WebSocket API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) is low level, Mercure is a high level. Mercure provides convenient built-in features such as authorization, re-connection, state reconciliation and a presence API ; while with WebSockets, you need to implement them yourself. -Also WebSockets [are not designed to leverage HTTP/2+](https://www.infoq.com/articles/websocket-and-http2-coexist) and are known to be [hard to secure](https://gravitational.com/blog/kubernetes-websocket-upgrade-security-vulnerability/). On the other hand Mercure relies on plain HTTP connections and benefits from the performance an security improvement built-in the latest versions of this protocol. +Also, WebSockets [are not designed to leverage HTTP/2+](https://www.infoq.com/articles/websocket-and-http2-coexist) and are known to be [hard to secure](https://gravitational.com/blog/kubernetes-websocket-upgrade-security-vulnerability/). +On the other hand Mercure relies on plain HTTP connections and benefits from the performance and security improvement built-in the latest versions of this protocol. HTTP/2 connections are multiplexed and bidirectional by default (it was not the case of HTTP/1). When using Mercure over a h2 connection (recommended), your app can receive data through Server-Sent Events, and send data to the server with regular `POST` (or `PUT`/`PATCH`/`DELETE`) requests, with no overhead. @@ -34,7 +35,7 @@ In summary, use the Push API to send notifications to offline users (that will b When using HTTP/2+ ([the default for almost all users](https://caniuse.com/#feat=http2)), the maximum number of simultaneous HTTP **streams** is negotiated between the server and the client (it defaults to 100). When using HTTP 1.1, this limit is of 6. -By using template selectors and by passing several `topic` parameters, it's possible to subscribe to an unlimited of topics using a single HTTP connection. +By using template selectors and by passing several `topic` parameters, it's possible to subscribe to an unlimited number of topics using a single HTTP connection. ## How to Use Mercure with GraphQL? diff --git a/event.go b/event.go index cbcadfc8..1140c6db 100644 --- a/event.go +++ b/event.go @@ -26,14 +26,14 @@ func (e *Event) String() string { var b strings.Builder if e.Type != "" { - fmt.Fprintf(&b, "event: %s\n", e.Type) + _, _ = fmt.Fprintf(&b, "event: %s\n", e.Type) } if e.Retry != 0 { - fmt.Fprintf(&b, "retry: %d\n", e.Retry) + _, _ = fmt.Fprintf(&b, "retry: %d\n", e.Retry) } r := strings.NewReplacer("\r\n", "\ndata: ", "\r", "\ndata: ", "\n", "\ndata: ") - fmt.Fprintf(&b, "id: %s\ndata: %s\n\n", e.ID, r.Replace(e.Data)) + _, _ = fmt.Fprintf(&b, "id: %s\ndata: %s\n\n", e.ID, r.Replace(e.Data)) return b.String() } diff --git a/hub.go b/hub.go index b35e6d5a..18ee3a59 100644 --- a/hub.go +++ b/hub.go @@ -1,5 +1,5 @@ -// Package mercure helps implementing the Mercure protocol (https://mercure.rocks) in Go projects. -// It provides an implementation of a Mercure hub as a HTTP handler. +// Package mercure helps implement the Mercure protocol (https://mercure.rocks) in Go projects. +// It provides an implementation of a Mercure hub as an HTTP handler. package mercure import ( diff --git a/jwt_keyfunc_test.go b/jwt_keyfunc_test.go index 044d43eb..02493e86 100644 --- a/jwt_keyfunc_test.go +++ b/jwt_keyfunc_test.go @@ -7,7 +7,7 @@ import ( ) func TestCreateJWTKeyfunc(t *testing.T) { - f, err := createJWTKeyfunc(([]byte{}), "invalid") + f, err := createJWTKeyfunc([]byte{}, "invalid") require.Error(t, err) require.Nil(t, f) } diff --git a/metrics.go b/metrics.go index e73bc9d7..8f4dc97e 100644 --- a/metrics.go +++ b/metrics.go @@ -35,7 +35,7 @@ type PrometheusMetrics struct { } // NewPrometheusMetrics creates a Prometheus metrics collector. -// This method must be called only one time or it will panic. +// This method must be called only one time, or it will panic. func NewPrometheusMetrics(registry prometheus.Registerer) *PrometheusMetrics { if registry == nil { registry = prometheus.NewRegistry() diff --git a/publish.go b/publish.go index b5efcc6d..11f2c150 100644 --- a/publish.go +++ b/publish.go @@ -75,7 +75,12 @@ func (h *Hub) PublishHandler(w http.ResponseWriter, r *http.Request) { panic(err) } - io.WriteString(w, u.ID) + if _, err := io.WriteString(w, u.ID); err != nil { + if c := h.logger.Check(zap.WarnLevel, "Failed to write publish response"); c != nil { + c.Write(zap.Object("update", u), zap.Error(err), zap.String("remote_addr", r.RemoteAddr)) + } + } + if c := h.logger.Check(zap.DebugLevel, "Update published"); c != nil { c.Write(zap.Object("update", u), zap.String("remote_addr", r.RemoteAddr)) } diff --git a/spec/mercure.md b/spec/mercure.md index 0b1b3ca9..3c026b59 100644 --- a/spec/mercure.md +++ b/spec/mercure.md @@ -51,11 +51,11 @@ interpreted as described in [@!RFC2119]. private, consequently, it must be dispatched only to subscribers allowed to receive it. * Topic selector: An expression matching one or several topics. * Publisher: An owner of a topic. Notifies the hub when the topic feed has been updated. As in - almost all pubsub systems, the publisher is unaware of the subscribers, if any. Other pubsub - systems might call the publisher the "source". Typically a site or a web API, but can also be + almost all pub-sub systems, the publisher is unaware of the subscribers, if any. Other pub-sub + systems might call the publisher the "source". Typically, a site or a web API, but can also be a web browser. * Subscriber: A client application that subscribes to real-time updates of topics using topic - selectors. Typically a web or a mobile application, but can also be a server. + selectors. Typically, a web or a mobile application, but can also be a server. * Subscription: A topic selector used by a subscriber to receive updates. A single subscriber can have several subscriptions, when it provides several topic selectors. * Hub: A server that handles subscription requests and distributes the content to subscribers when @@ -73,7 +73,7 @@ The URL of the hub **MUST** be the "well-known" [@!RFC5785] fixed path `/.well-k If the publisher is a server, it **SHOULD** advertise the URL of one or more hubs to the subscriber, allowing it to receive live updates when topics are updated. If more than one hub URL is specified, -the publisher **MUST** notifies each hub, so the subscriber **MAY** subscribe to one or more of +the publisher **MUST** notify each hub, so the subscriber **MAY** subscribe to one or more of them. Note: Publishers may wish to advertise and publish to more than one hub for fault tolerance and @@ -201,7 +201,7 @@ To determine if a string matches a selector, the following steps must be followe characteristic allows to compare a URI Template with another one. 3. If the topic selector is a valid URI Template, and that the string matches this URI Template, the string matches the selector. -4. Otherwise the string does not match the selector. +4. Otherwise, the string does not match the selector. # Subscription @@ -295,7 +295,7 @@ The request **MUST** be encoded using the `application/x-www-form-urlencoded` fo but it **CAN** contain any value including an empty string. * `id` (optional): the topic's revision identifier: it will be used as the SSE's `id` property. The provided ID **MUST NOT** start with the `#` character. The provided ID **SHOULD** be a valid - IRI. If omitted, the hub **MUST** generate a valid IRI [@!RFC3987]. An UUID [@RFC4122] or a + IRI. If omitted, the hub **MUST** generate a valid IRI [@!RFC3987]. A UUID [@RFC4122] or a [DID](https://www.w3.org/TR/did-core/) **MAY** be used. Alternatively the hub **MAY** generate a relative URI composed of a fragment (starting with `#`). This is convenient to return an offset or a sequence that is unique for this hub. Even if provided, the hub **MAY** ignore the ID @@ -415,7 +415,7 @@ array of topic selectors. See (#topic-selectors). If `mercure.publish` is not defined, or contains an empty array, then the publisher **MUST NOT** be authorized to dispatch any update. -Otherwise, the hub **MUST** check that every topics of the update to dispatch matches at least one +Otherwise, the hub **MUST** check that every topic of the update to dispatch matches at least one of the topic selectors contained in `mercure.publish`. If the publisher is not authorized for all the topics of an update, the hub **MUST NOT** dispatch @@ -488,8 +488,8 @@ The protocol allows to reconciliate states after a reconnection. It can also be [Event store](https://en.wikipedia.org/wiki/Event_store). To allow re-establishment in case of connection lost, events dispatched by the hub **MUST** include -an `id` property. The value contained in this `id` property **SHOULD** be an IRI [@!RFC3987]. An -UUID [@RFC4122] or a [DID](https://www.w3.org/TR/did-core/) **MAY** be used. +an `id` property. The value contained in this `id` property **SHOULD** be an IRI [@!RFC3987]. +A UUID [@RFC4122] or a [DID](https://www.w3.org/TR/did-core/) **MAY** be used. According to the server-sent events specification, in case of connection lost the subscriber will try to automatically re-connect. During the @@ -529,7 +529,7 @@ hub stores only a limited number of events in its history). In some cases (for i partial updates in the JSON Patch [@RFC6902] format, or when using the hub as an event store), updates lost can cause data lost. -To detect if a data lost ocurred, the subscriber **CAN** compare the value of the `Last-Event-ID` +To detect if a data lost occurred, the subscriber **CAN** compare the value of the `Last-Event-ID` response HTTP header with the last event ID it requested. In case of data lost, the subscriber **SHOULD** re-fetch the original topic. @@ -554,14 +554,14 @@ subscription is created or terminated. The topic of these updates **MUST** be an expansion of `/.well-known/mercure/subscriptions/{topic}/{subscriber}`. `{topic}` is the topic selector used for -this subscription and `{subscriber}` is an unique identifier for the subscriber. +this subscription and `{subscriber}` is a unique identifier for the subscriber. Note: Because it is recommended to use URI Templates and IRIs for the `{topic}` and `{subscriber}` variables, values will usually contain the `:`, `/`, `{` and `}` characters. Per [@!RFC6570], these characters are reserved. They **MUST** be percent encoded during the expansion process. If a subscriber has several subscriptions, it **SHOULD** be identified by the same -identifier. `{subscriber}` **SHOULD** be an IRI [@!RFC3987]. An UUID [@RFC4122] or a +identifier. `{subscriber}` **SHOULD** be an IRI [@!RFC3987]. A UUID [@RFC4122] or a [DID](https://www.w3.org/TR/did-core/) **MAY** be used. The content of the update **MUST** be a JSON-LD [@!W3C.REC-json-ld-20140116] document containing at @@ -775,7 +775,7 @@ The JSON-LD context available at `https://mercure.rocks` is the following: # Encryption -Using HTTPS does not prevent the hub from accessing the update's content. Depending of the intended +Using HTTPS does not prevent the hub from accessing the update's content. Depending on the intended privacy of information contained in the update, it **MAY** be necessary to prevent eavesdropping by the hub. @@ -1320,7 +1320,7 @@ Other implementations can be found on GitHub: Date: Tue, 5 Nov 2024 00:34:53 +0100 Subject: [PATCH 31/71] fix(helm): support autoscaling/v2 (#967) autoscaling/v2beta1 isn't supported on Kubernetes v1.25. See: https://kubernetes.io/docs/reference/using-api/deprecation-guide/ --- charts/mercure/templates/hpa.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/charts/mercure/templates/hpa.yaml b/charts/mercure/templates/hpa.yaml index beb77858..60fd9ee4 100644 --- a/charts/mercure/templates/hpa.yaml +++ b/charts/mercure/templates/hpa.yaml @@ -1,5 +1,9 @@ {{- if .Values.autoscaling.enabled }} +{{- if .Capabilities.APIVersions.Has "autoscaling/v2" }} +apiVersion: autoscaling/v2 +{{- else }} apiVersion: autoscaling/v2beta1 +{{- end }} kind: HorizontalPodAutoscaler metadata: name: {{ include "mercure.fullname" . }} From 5474a233612e718e050e9944c2e45e57accbbc60 Mon Sep 17 00:00:00 2001 From: Niek Neuij <80959825+xip-niekneuij@users.noreply.github.com> Date: Tue, 5 Nov 2024 11:58:04 +0100 Subject: [PATCH 32/71] fix(helm): support autoscaling/v2 formatting (#968) --- charts/mercure/templates/hpa.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/charts/mercure/templates/hpa.yaml b/charts/mercure/templates/hpa.yaml index 60fd9ee4..a1edc9f5 100644 --- a/charts/mercure/templates/hpa.yaml +++ b/charts/mercure/templates/hpa.yaml @@ -21,12 +21,24 @@ spec: - type: Resource resource: name: cpu + {{- if .Capabilities.APIVersions.Has "autoscaling/v2" }} + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- else }} targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} {{- end }} {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} - type: Resource resource: name: memory + {{- if .Capabilities.APIVersions.Has "autoscaling/v2" }} + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- else }} targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} {{- end }} {{- end }} From d98b77c2bac8b2b66cd76eccbba0e0b5256afae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 5 Nov 2024 20:43:02 +0100 Subject: [PATCH 33/71] refactor!: simplify filenames, remove dead code and bump deps --- bolt_transport.go => bolt.go | 0 bolt_transport_test.go => bolt_test.go | 0 caddy/{bolt_transport.go => bolt.go} | 0 caddy/go.mod | 26 +++---- caddy/go.sum | 75 ++++++++++--------- caddy/{local_transport.go => local.go} | 0 caddy/{caddy.go => mercure.go} | 0 go.mod | 6 +- go.sum | 12 +-- jwt_keyfunc.go => jwtkeyfunc.go | 0 jwt_keyfunc_test.go => jwtkeyfunc_test.go | 0 local_transport.go => local.go | 0 ...sport_bench_test.go => local_bench_test.go | 0 local_transport_test.go => local_test.go | 0 subscribe.go | 4 +- subscriber.go | 1 - subscriber_list.go => subscriberlist.go | 0 ...ber_list_test.go => subscriberlist_test.go | 0 topic_selector_lru.go => topicselectorlru.go | 0 ...or_lru_test.go => topicselectorlru_test.go | 0 ..._ristretto.go => topicselectorristretto.go | 0 ..._test.go => topicselectorristretto_test.go | 0 22 files changed, 61 insertions(+), 63 deletions(-) rename bolt_transport.go => bolt.go (100%) rename bolt_transport_test.go => bolt_test.go (100%) rename caddy/{bolt_transport.go => bolt.go} (100%) rename caddy/{local_transport.go => local.go} (100%) rename caddy/{caddy.go => mercure.go} (100%) rename jwt_keyfunc.go => jwtkeyfunc.go (100%) rename jwt_keyfunc_test.go => jwtkeyfunc_test.go (100%) rename local_transport.go => local.go (100%) rename local_transport_bench_test.go => local_bench_test.go (100%) rename local_transport_test.go => local_test.go (100%) rename subscriber_list.go => subscriberlist.go (100%) rename subscriber_list_test.go => subscriberlist_test.go (100%) rename topic_selector_lru.go => topicselectorlru.go (100%) rename topic_selector_lru_test.go => topicselectorlru_test.go (100%) rename topic_selector_ristretto.go => topicselectorristretto.go (100%) rename topic_selector_ristretto_test.go => topicselectorristretto_test.go (100%) diff --git a/bolt_transport.go b/bolt.go similarity index 100% rename from bolt_transport.go rename to bolt.go diff --git a/bolt_transport_test.go b/bolt_test.go similarity index 100% rename from bolt_transport_test.go rename to bolt_test.go diff --git a/caddy/bolt_transport.go b/caddy/bolt.go similarity index 100% rename from caddy/bolt_transport.go rename to caddy/bolt.go diff --git a/caddy/go.mod b/caddy/go.mod index 191afe5b..df2bcc91 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -51,7 +51,7 @@ require ( github.com/dlclark/regexp2 v1.11.4 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-chi/chi/v5 v5.1.0 // indirect github.com/go-jose/go-jose/v3 v3.0.3 // indirect @@ -68,7 +68,7 @@ require ( github.com/google/certificate-transparency-go v1.2.1 // indirect github.com/google/go-tpm v0.9.1 // indirect github.com/google/go-tspi v0.3.0 // indirect - github.com/google/pprof v0.0.0-20241021161924-4cf4322d492d // indirect + github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/mux v1.8.1 // indirect @@ -98,16 +98,16 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mschoch/smat v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/ginkgo/v2 v2.20.2 // indirect + github.com/onsi/ginkgo/v2 v2.21.0 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pires/go-proxyproto v0.8.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.60.0 // indirect + github.com/prometheus/common v0.60.1 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/quic-go/qpack v0.5.1 // indirect - github.com/quic-go/quic-go v0.48.0 // indirect + github.com/quic-go/quic-go v0.48.1 // indirect github.com/rs/xid v1.6.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect @@ -116,10 +116,11 @@ require ( github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/slackhq/nebula v1.9.4 // indirect - github.com/smallstep/certificates v0.27.5 // indirect + github.com/smallstep/certificates v0.28.0 // indirect + github.com/smallstep/cli-utils v0.10.0 // indirect github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 // indirect github.com/smallstep/nosql v0.7.0 // indirect - github.com/smallstep/pkcs7 v0.0.0-20240911091500-b1cae6277023 // indirect + github.com/smallstep/pkcs7 v0.0.0-20241029111203-fbab67b7673f // indirect github.com/smallstep/scep v0.0.0-20240926084937-8cf1ca453101 // indirect github.com/smallstep/truststore v0.13.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect @@ -131,7 +132,7 @@ require ( github.com/stoewer/go-strcase v1.3.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53 // indirect - github.com/unrolled/secure v1.16.0 // indirect + github.com/unrolled/secure v1.17.0 // indirect github.com/urfave/cli v1.22.16 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect @@ -152,15 +153,14 @@ require ( go.opentelemetry.io/otel/sdk v1.31.0 // indirect go.opentelemetry.io/otel/trace v1.31.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect - go.step.sm/cli-utils v0.9.0 // indirect go.step.sm/crypto v0.54.0 // indirect - go.step.sm/linkedca v0.22.1 // indirect + go.step.sm/linkedca v0.22.2 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap/exp v0.2.0 // indirect golang.org/x/crypto v0.28.0 // indirect - golang.org/x/crypto/x509roots/fallback v0.0.0-20241021190220-c17aa50fbd32 // indirect + golang.org/x/crypto/x509roots/fallback v0.0.0-20241104001025-71ed71b4faf9 // indirect golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.30.0 // indirect @@ -171,8 +171,8 @@ require ( golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.7.0 // indirect golang.org/x/tools v0.26.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect google.golang.org/grpc v1.67.1 // indirect google.golang.org/protobuf v1.35.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/caddy/go.sum b/caddy/go.sum index a652a690..98ef7cdc 100644 --- a/caddy/go.sum +++ b/caddy/go.sum @@ -1,7 +1,7 @@ -cloud.google.com/go v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ= -cloud.google.com/go v0.115.1/go.mod h1:DuujITeaufu3gL68/lOFIirVNJwQeyf5UXyi+Wbgknc= -cloud.google.com/go/auth v0.9.8 h1:+CSJ0Gw9iVeSENVCKJoLHhdUykDgXSc4Qn+gu2BRtR8= -cloud.google.com/go/auth v0.9.8/go.mod h1:xxA5AqpDrvS+Gkmo9RqrGGRh6WSNKKOXhY3zNOr38tI= +cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= +cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= +cloud.google.com/go/auth v0.9.9 h1:BmtbpNQozo8ZwW2t7QJjnrQtdganSdmqeIBxHxNkEZQ= +cloud.google.com/go/auth v0.9.9/go.mod h1:xxA5AqpDrvS+Gkmo9RqrGGRh6WSNKKOXhY3zNOr38tI= cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY= cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc= cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= @@ -11,8 +11,8 @@ cloud.google.com/go/iam v1.2.1 h1:QFct02HRb7H12J/3utj0qf5tobFh9V4vR6h9eX5EBRU= cloud.google.com/go/iam v1.2.1/go.mod h1:3VUIJDPpwT6p/amXRC5GY8fCCh70lxPygguVtI0Z4/g= cloud.google.com/go/kms v1.20.0 h1:uKUvjGqbBlI96xGE669hcVnEMw1Px/Mvfa62dhM5UrY= cloud.google.com/go/kms v1.20.0/go.mod h1:/dMbFF1tLLFnQV44AoI2GlotbjowyUfgVwezxW291fM= -cloud.google.com/go/longrunning v0.6.1 h1:lOLTFxYpr8hcRtcwWir5ITh1PAKUD/sG2lKrTSYjyMc= -cloud.google.com/go/longrunning v0.6.1/go.mod h1:nHISoOZpBcmlwbJmiVk5oDRz0qG/ZxPynEGs1iZ79s0= +cloud.google.com/go/longrunning v0.6.2 h1:xjDfh1pQcWPEvnfjZmwjKQEcHnpz6lHjfy7Fo0MK+hc= +cloud.google.com/go/longrunning v0.6.2/go.mod h1:k/vIs83RN4bE3YCswdXC5PFfWVILjm3hpEUlSko4PiI= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= @@ -147,8 +147,8 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -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/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= @@ -194,8 +194,8 @@ github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxB github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus= github.com/google/go-tspi v0.3.0/go.mod h1:xfMGI3G0PhxCdNVcYr1C4C+EizojDg/TXuX5by8CiHI= -github.com/google/pprof v0.0.0-20241021161924-4cf4322d492d h1:dcUSYLuKITgwgLZJZpB+CKecsC8mXHhErghMX9ohbf4= -github.com/google/pprof v0.0.0-20241021161924-4cf4322d492d/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 h1:sAGdeJj0bnMgUNVeUpp6AYlVdCt3/GdI3pGRqsNSQLs= +github.com/google/pprof v0.0.0-20241101162523-b92577c0c142/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -280,10 +280,10 @@ github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= -github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= -github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= -github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= +github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= +github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= +github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 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= @@ -303,14 +303,14 @@ github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+ github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= 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.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= -github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= +github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc= +github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= 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/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= -github.com/quic-go/quic-go v0.48.0 h1:2TCyvBrMu1Z25rvIAlnp2dPT4lgh/uTqLqiXVpp5AeU= -github.com/quic-go/quic-go v0.48.0/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= +github.com/quic-go/quic-go v0.48.1 h1:y/8xmfWI9qmGTc+lBr4jKRUWLGSlSigv847ULJ4hYXA= +github.com/quic-go/quic-go v0.48.1/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= 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/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= @@ -335,14 +335,17 @@ github.com/slackhq/nebula v1.9.4 h1:p06JxtXT/OBMWt2OQkY7F0phOBb42X93YWNsS1yqC9o= github.com/slackhq/nebula v1.9.4/go.mod h1:1+4q4wd3dDAjO8rKCttSb9JIVbklQhuJiBp5I0lbIsQ= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262 h1:unQFBIznI+VYD1/1fApl1A+9VcBk+9dcqGfnePY87LY= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262/go.mod h1:MyOHs9Po2fbM1LHej6sBUT8ozbxmMOFG+E+rx/GSGuc= -github.com/smallstep/certificates v0.27.5 h1:EOfaHdo/eMv0aVF11iuF4PoY/UmDBS7+TxYD0MSKTFA= -github.com/smallstep/certificates v0.27.5/go.mod h1:0rLS7iQtfG3X0fcxZWeBXSkFVnBoeCLXxHWVnPD+zzg= +github.com/smallstep/certificates v0.28.0 h1:EM/lH/5vizfs1sMSBADSJt2PfQikRCBYtzgRNrtNjlA= +github.com/smallstep/certificates v0.28.0/go.mod h1:kJE6IWqokSv34dWy/Qqcl2FuQvmwruxn2Yhg/tIqs4Y= +github.com/smallstep/cli-utils v0.10.0 h1:CfXNvHtIN5pAzGvGP0NEUZoGFcj5epNEB6RSpSfduek= +github.com/smallstep/cli-utils v0.10.0/go.mod h1:jIeNa5ctrVg89lU5TaQKYd6o1eFxi9mtZu1sXSxpEBg= github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 h1:kjYvkvS/Wdy0PVRDUAA0gGJIVSEZYhiAJtfwYgOYoGA= github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935/go.mod h1:vNAduivU014fubg6ewygkAvQC0IQVXqdc8vaGl/0er4= github.com/smallstep/nosql v0.7.0 h1:YiWC9ZAHcrLCrayfaF+QJUv16I2bZ7KdLC3RpJcnAnE= github.com/smallstep/nosql v0.7.0/go.mod h1:H5VnKMCbeq9QA6SRY5iqPylfxLfYcLwvUff3onQ8+HU= -github.com/smallstep/pkcs7 v0.0.0-20240911091500-b1cae6277023 h1:klMnoL/Mrw9MJaAZdGUuEAKSskSoy14KIUpRwGOd4Vo= github.com/smallstep/pkcs7 v0.0.0-20240911091500-b1cae6277023/go.mod h1:CM5KrX7rxWgwDdMj9yef/pJB2OPgy/56z4IEx2UIbpc= +github.com/smallstep/pkcs7 v0.0.0-20241029111203-fbab67b7673f h1:yGZK213dsHF8FEe/fHlt7s7p4lLiW1CFfghbMAi6ph0= +github.com/smallstep/pkcs7 v0.0.0-20241029111203-fbab67b7673f/go.mod h1:gmVfG4kelRxZm+8CSk0aS+/mRoR2h8y/khVRMh0eTfg= github.com/smallstep/scep v0.0.0-20240926084937-8cf1ca453101 h1:LyZqn24/ZiVg8v9Hq07K6mx6RqPtpDeK+De5vf4QEY4= github.com/smallstep/scep v0.0.0-20240926084937-8cf1ca453101/go.mod h1:EuKQjYGQwhUa1mgD21zxIgOgUYLsqikJmvxNscxpS/Y= github.com/smallstep/truststore v0.13.0 h1:90if9htAOblavbMeWlqNLnO9bsjjgVv2hQeQJCi/py4= @@ -389,8 +392,8 @@ github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSW github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53 h1:uxMgm0C+EjytfAqyfBG55ZONKQ7mvd7x4YYCWsf8QHQ= github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53/go.mod h1:kNGUQ3VESx3VZwRwA9MSCUegIl6+saPL8Noq82ozCaU= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/unrolled/secure v1.16.0 h1:XgdAsS/Zl50ZfZPRJK6WpicFttfrsFYFd0+ONDBJubU= -github.com/unrolled/secure v1.16.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= +github.com/unrolled/secure v1.17.0 h1:Io7ifFgo99Bnh0J7+Q+qcMzWM6kaDPCA5FroFZEdbWU= +github.com/unrolled/secure v1.17.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ= github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -442,12 +445,10 @@ go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HY go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.step.sm/cli-utils v0.9.0 h1:55jYcsQbnArNqepZyAwcato6Zy2MoZDRkWW+jF+aPfQ= -go.step.sm/cli-utils v0.9.0/go.mod h1:Y/CRoWl1FVR9j+7PnAewufAwKmBOTzR6l9+7EYGAnp8= go.step.sm/crypto v0.54.0 h1:V8p+12Ld0NRA/RBMYoKXA0dWmVKZSdCwP56IwzweT9g= go.step.sm/crypto v0.54.0/go.mod h1:vQJyTngfZDW+UyZdFzOMCY/txWDAmcwViEUC7Gn4YfU= -go.step.sm/linkedca v0.22.1 h1:GvprpH9P4Sv9U+eZ3bxDgRSSpW14cFDYpe1kS6yWLkw= -go.step.sm/linkedca v0.22.1/go.mod h1:dOKdF4HSn73YUEkfS5/FECngZmBtj2Il5DTKWXY4S6Y= +go.step.sm/linkedca v0.22.2 h1:zmFIyDC77gFHo6FLQJ8OIXYpLYDIsgDWaYqtYs6A9/Q= +go.step.sm/linkedca v0.22.2/go.mod h1:ESY8r5VfhJA8ZVzI6hXIQcEX9LwaY3aoPnT+Hb9jpbw= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -469,8 +470,8 @@ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/crypto/x509roots/fallback v0.0.0-20241021190220-c17aa50fbd32 h1:u+wXJTTHk+l3A3eJLqzMOflOiT03pV+eRadSt1N4VNs= -golang.org/x/crypto/x509roots/fallback v0.0.0-20241021190220-c17aa50fbd32/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= +golang.org/x/crypto/x509roots/fallback v0.0.0-20241104001025-71ed71b4faf9 h1:4cEcP5+OjGppY79LCQ5Go2B1Boix2x0v6pvA01P3FoA= +golang.org/x/crypto/x509roots/fallback v0.0.0-20241104001025-71ed71b4faf9/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -554,14 +555,14 @@ golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxb golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.200.0 h1:0ytfNWn101is6e9VBoct2wrGDjOi5vn7jw5KtaQgDrU= -google.golang.org/api v0.200.0/go.mod h1:Tc5u9kcbjO7A8SwGlYj4IiVifJU01UqXtEgDMYmBmV8= -google.golang.org/genproto v0.0.0-20241007155032-5fefd90f89a9 h1:nFS3IivktIU5Mk6KQa+v6RKkHUpdQpphqGNLxqNnbEk= -google.golang.org/genproto v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:tEzYTYZxbmVNOu0OAFH9HzdJtLn6h4Aj89zzlBCdHms= -google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1:fVoAXEKA4+yufmbdVYv+SE73+cPZbbbe8paLsHfkK+U= -google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/api v0.203.0 h1:SrEeuwU3S11Wlscsn+LA1kb/Y5xT8uggJSkIhD08NAU= +google.golang.org/api v0.203.0/go.mod h1:BuOVyCSYEPwJb3npWvDnNmFI92f3GeRnHNkETneT3SI= +google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53 h1:Df6WuGvthPzc+JiQ/G+m+sNX24kc0aTBqoDN/0yyykE= +google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53/go.mod h1:fheguH3Am2dGp1LfXkrvwqC/KlFq8F0nLq3LryOMrrE= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= diff --git a/caddy/local_transport.go b/caddy/local.go similarity index 100% rename from caddy/local_transport.go rename to caddy/local.go diff --git a/caddy/caddy.go b/caddy/mercure.go similarity index 100% rename from caddy/caddy.go rename to caddy/mercure.go diff --git a/go.mod b/go.mod index d51f10a2..d4324ecb 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 - github.com/unrolled/secure v1.16.0 + github.com/unrolled/secure v1.17.0 github.com/yosida95/uritemplate/v3 v3.0.2 go.etcd.io/bbolt v1.3.11 go.uber.org/zap v1.27.0 @@ -39,7 +39,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/klauspost/compress v1.17.11 // indirect @@ -50,7 +50,7 @@ require ( github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/common v0.60.0 // indirect + github.com/prometheus/common v0.60.1 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect diff --git a/go.sum b/go.sum index 76c5578f..f88dc422 100644 --- a/go.sum +++ b/go.sum @@ -27,8 +27,8 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -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/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= @@ -75,8 +75,8 @@ github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+ github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= 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.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= -github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= +github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc= +github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= 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/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -105,8 +105,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/unrolled/secure v1.16.0 h1:XgdAsS/Zl50ZfZPRJK6WpicFttfrsFYFd0+ONDBJubU= -github.com/unrolled/secure v1.16.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= +github.com/unrolled/secure v1.17.0 h1:Io7ifFgo99Bnh0J7+Q+qcMzWM6kaDPCA5FroFZEdbWU= +github.com/unrolled/secure v1.17.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= diff --git a/jwt_keyfunc.go b/jwtkeyfunc.go similarity index 100% rename from jwt_keyfunc.go rename to jwtkeyfunc.go diff --git a/jwt_keyfunc_test.go b/jwtkeyfunc_test.go similarity index 100% rename from jwt_keyfunc_test.go rename to jwtkeyfunc_test.go diff --git a/local_transport.go b/local.go similarity index 100% rename from local_transport.go rename to local.go diff --git a/local_transport_bench_test.go b/local_bench_test.go similarity index 100% rename from local_transport_bench_test.go rename to local_bench_test.go diff --git a/local_transport_test.go b/local_test.go similarity index 100% rename from local_transport_test.go rename to local_test.go diff --git a/subscribe.go b/subscribe.go index bc9fa92e..293a8902 100644 --- a/subscribe.go +++ b/subscribe.go @@ -156,9 +156,7 @@ func (h *Hub) SubscribeHandler(w http.ResponseWriter, r *http.Request) { // registerSubscriber initializes the connection. func (h *Hub) registerSubscriber(w http.ResponseWriter, r *http.Request) (*Subscriber, *responseController) { - s := NewSubscriber(retrieveLastEventID(r, h.opt, h.logger), h.logger, &TopicSelectorStore{}) - s.topicSelectorStore = h.topicSelectorStore - s.Debug = h.debug + s := NewSubscriber(retrieveLastEventID(r, h.opt, h.logger), h.logger, h.topicSelectorStore) s.RemoteAddr = r.RemoteAddr var privateTopics []string var claims *claims diff --git a/subscriber.go b/subscriber.go index 87f2040b..3e68ff0b 100644 --- a/subscriber.go +++ b/subscriber.go @@ -24,7 +24,6 @@ type Subscriber struct { SubscribedTopicRegexps []*regexp.Regexp AllowedPrivateTopics []string AllowedPrivateRegexps []*regexp.Regexp - Debug bool disconnected int32 out chan *Update diff --git a/subscriber_list.go b/subscriberlist.go similarity index 100% rename from subscriber_list.go rename to subscriberlist.go diff --git a/subscriber_list_test.go b/subscriberlist_test.go similarity index 100% rename from subscriber_list_test.go rename to subscriberlist_test.go diff --git a/topic_selector_lru.go b/topicselectorlru.go similarity index 100% rename from topic_selector_lru.go rename to topicselectorlru.go diff --git a/topic_selector_lru_test.go b/topicselectorlru_test.go similarity index 100% rename from topic_selector_lru_test.go rename to topicselectorlru_test.go diff --git a/topic_selector_ristretto.go b/topicselectorristretto.go similarity index 100% rename from topic_selector_ristretto.go rename to topicselectorristretto.go diff --git a/topic_selector_ristretto_test.go b/topicselectorristretto_test.go similarity index 100% rename from topic_selector_ristretto_test.go rename to topicselectorristretto_test.go From 7b7ccb995d65a5e1da5d2c37af8a1b2e0027247d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 5 Nov 2024 20:13:51 +0100 Subject: [PATCH 34/71] refactor!: remove legacy Ristretto cache --- caddy/go.mod | 8 +++--- caddy/go.sum | 14 +++++----- docs/hub/config.md | 10 ++++---- go.mod | 3 --- go.sum | 8 ------ local_bench_test.go | 25 +++--------------- subscriber_bench_test.go | 29 ++++----------------- topicselectorristretto.go | 34 ------------------------ topicselectorristretto_test.go | 47 ---------------------------------- 9 files changed, 26 insertions(+), 152 deletions(-) delete mode 100644 topicselectorristretto.go delete mode 100644 topicselectorristretto_test.go diff --git a/caddy/go.mod b/caddy/go.mod index df2bcc91..4cc6c23c 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -1,6 +1,8 @@ module github.com/dunglas/mercure/caddy -go 1.22.0 +go 1.22.7 + +toolchain go1.23.2 retract ( v0.14.7 // CI problem @@ -65,14 +67,14 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/cel-go v0.21.0 // indirect - github.com/google/certificate-transparency-go v1.2.1 // indirect + github.com/google/certificate-transparency-go v1.2.2 // indirect github.com/google/go-tpm v0.9.1 // indirect github.com/google/go-tspi v0.3.0 // indirect github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/mux v1.8.1 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect diff --git a/caddy/go.sum b/caddy/go.sum index 98ef7cdc..be2e2d0a 100644 --- a/caddy/go.sum +++ b/caddy/go.sum @@ -4,7 +4,7 @@ cloud.google.com/go/auth v0.9.9 h1:BmtbpNQozo8ZwW2t7QJjnrQtdganSdmqeIBxHxNkEZQ= cloud.google.com/go/auth v0.9.9/go.mod h1:xxA5AqpDrvS+Gkmo9RqrGGRh6WSNKKOXhY3zNOr38tI= cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY= cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc= -cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= +cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo= cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= cloud.google.com/go/iam v1.2.1 h1:QFct02HRb7H12J/3utj0qf5tobFh9V4vR6h9eX5EBRU= @@ -178,13 +178,13 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6 github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +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/cel-go v0.21.0 h1:cl6uW/gxN+Hy50tNYvI691+sXxioCnstFzLp2WO4GCI= github.com/google/cel-go v0.21.0/go.mod h1:rHUlWCcBKgyEk+eV03RPdZUekPp6YcJwV0FxuUksYxc= github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= -github.com/google/certificate-transparency-go v1.2.1 h1:4iW/NwzqOqYEEoCBEFP+jPbBXbLqMpq3CifMyOnDUME= -github.com/google/certificate-transparency-go v1.2.1/go.mod h1:bvn/ytAccv+I6+DGkqpvSsEdiVGramgaSC6RD3tEmeE= +github.com/google/certificate-transparency-go v1.2.2 h1:5TAzjQnCfN1vps2XWUgU6Svt++rgy9a+b8CBYXaKUAo= +github.com/google/certificate-transparency-go v1.2.2/go.mod h1:d1o5XNQzK/yz8IXzEce6KXgMxfter/EcMP9vG4dBRNE= 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= @@ -208,8 +208,8 @@ github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyE github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= 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= diff --git a/docs/hub/config.md b/docs/hub/config.md index d97f59f3..c85b6d66 100644 --- a/docs/hub/config.md +++ b/docs/hub/config.md @@ -39,7 +39,7 @@ Note that HTTPS is automatically disabled if you set the server port to 80. The following Mercure-specific directives are available: | Directive | Description | Default | -| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +|---------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------| | `publisher_jwt []` | the JWT key and algorithm to use for publishers, can contain [placeholders](https://caddyserver.com/docs/conventions#placeholders) | | | `subscriber_jwt []` | the JWT key and algorithm to use for subscribers, can contain [placeholders](https://caddyserver.com/docs/conventions#placeholders) | | | `publisher_jwks_url` | the URL of the JSON Web Key Set (JWK Set) URL (provided by identity providers such as Keycloak or AWS Cognito) to use for validating publishers JWT (take precedence over `publisher_jwt`) | | @@ -56,7 +56,7 @@ The following Mercure-specific directives are available: | `protocol_version_compatibility` | version of the protocol to be backward compatible with (only version 7 is supported) | disabled | | `demo` | enable the UI and expose demo endpoints | | | `ui` | enable the UI but do not expose demo endpoints | | -| `cache ` | cache configuration (see [Ristretto's docs](https://github.com/dgraph-io/ristretto)), set to -1 to disable the cache | `6e7` `1e8` (100MB) | +| `lru_cache ` | LRU cache size (see [golang-lru docs](https://github.com/hashicorp/golang-lru)), set to -1 to disable the cache | `6e7` `1e8` (100MB) | | `transport_url ` | **Deprecated: use `transport` instead.** URL representation of the transport to use. Use `local://local` to disable the history, (example `bolt:///var/run/mercure.db?size=100&cleanup_frequency=0.4`), see also [the cluster mode](cluster.md) | `bolt://mercure.db` | See also [the list of built-in Caddyfile directives](https://caddyserver.com/docs/caddyfile/directives). @@ -66,7 +66,7 @@ See also [the list of built-in Caddyfile directives](https://caddyserver.com/doc The provided `Caddyfile` and the Docker image provide convenient environment variables: | Environment variable | Description | Default value | -| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------| | `GLOBAL_OPTIONS` | the [global options block](https://caddyserver.com/docs/caddyfile/options#global-options) to inject in the `Caddyfile`, one per line | | | `CADDY_EXTRA_CONFIG` | the [snippet](https://caddyserver.com/docs/caddyfile/concepts#snippets) or the [named-routes](https://caddyserver.com/docs/caddyfile/concepts#named-routes) options block to inject in the `Caddyfile`, one per line | | | `CADDY_SERVER_EXTRA_DIRECTIVES` | [`Caddyfile` directives](https://caddyserver.com/docs/caddyfile/concepts#directives) | | @@ -128,7 +128,7 @@ MERCURE_SUBSCRIBER_JWT_ALG=RS256 \ ## Bolt Adapter | Option | Description | -| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `path` | path of the database file (default: `mercure.db`) | | `bucket_name` | name of the bolt bucket to store events. default to `updates` | | `cleanup_frequency` | chances to trigger history cleanup when an update occurs, must be a number between `0` (never cleanup) and `1` (cleanup after every publication), default to `0.3`. | @@ -175,7 +175,7 @@ Most configuration parameters are hot reloaded: changes made to environment vari When using environment variables, list must be space separated. As flags parameters, they must be comma separated. | Parameter | Description | Default | -| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | +|----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------| | `acme_cert_dir` | the directory where to store Let's Encrypt certificates | | | `acme_hosts` | a list of hosts for which Let's Encrypt certificates must be issued | | | `acme_http01_addr` | the address used by the acme server to listen on (example: `0.0.0.0:8080`) | `:http` | diff --git a/go.mod b/go.mod index d4324ecb..f7890a37 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,6 @@ retract ( ) require ( - github.com/dgraph-io/ristretto v1.0.0 github.com/gofrs/uuid v4.4.0+incompatible github.com/golang-jwt/jwt/v5 v5.2.1 github.com/gorilla/handlers v1.5.2 @@ -37,7 +36,6 @@ require ( github.com/bits-and-blooms/bitset v1.14.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/dustin/go-humanize v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -48,7 +46,6 @@ require ( github.com/mschoch/smat v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/common v0.60.1 // indirect github.com/prometheus/procfs v0.15.1 // indirect diff --git a/go.sum b/go.sum index f88dc422..7d5e3dd1 100644 --- a/go.sum +++ b/go.sum @@ -17,12 +17,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs 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/dgraph-io/ristretto v1.0.0 h1:SYG07bONKMlFDUYu5pEu3DGAh8c2OFNzKm6G9J4Si84= -github.com/dgraph-io/ristretto v1.0.0/go.mod h1:jTi2FiYEhQ1NsMmA7DeBykizjOuY88NhKBkepyu1jPc= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -66,8 +60,6 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= 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/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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= diff --git a/local_bench_test.go b/local_bench_test.go index 78984356..c00eabbe 100644 --- a/local_bench_test.go +++ b/local_bench_test.go @@ -86,35 +86,18 @@ set -e mkdir -p _dist -# --- Generating a diff --- - -SUB_TEST_CONCURRENCY=5000 \ -SUB_TEST_CACHE=ristretto \ -SUB_TEST_SHARDS=256 \ -go test -bench=. -run=BenchmarkLocalTransport -benchmem -count 5 | tee _dist/output.5kc.noskip.ristretto.256.txt - -SUB_TEST_CONCURRENCY=5000 \ -SUB_TEST_CACHE=lru \ -SUB_TEST_SHARDS=256 \ -go test -bench=. -run=BenchmarkLocalTransport -benchmem -count 5 | tee _dist/output.5kc.skip.lru.256.txt - -benchstat _dist/output.5kc.noskip.ristretto.256.txt \ - _dist/output.5kc.skip.lru.256.txt \ - > _dist/diff-cache.5kc.256.txt - - # --- Generating a cpu call graph --- SUB_TEST_CONCURRENCY=20000 \ SUB_TEST_TOPICS=20 \ SUB_TEST_MATCHPCT=50 \ -SUB_TEST_CACHE=ristretto \ +SUB_TEST_CACHE=lru \ SUB_TEST_SHARDS=256 \ -go test -bench=. -run=BenchmarkLocalTransport -cpuprofile _dist/profile.20kc.20top.50pct.noskip.ristretto.256sh.out -benchmem +go test -bench=. -run=BenchmarkLocalTransport -cpuprofile _dist/profile.20kc.20top.50pct.noskip.lru.256sh.out -benchmem go build -o _dist/bin -go tool pprof --pdf _dist/bin _dist/profile.20kc.20top.50pct.noskip.ristretto.256sh.out \ - > _dist/profile.20kc.20top.50pct.noskip.ristretto.256sh.pdf +go tool pprof --pdf _dist/bin _dist/profile.20kc.20top.50pct.noskip.lru.256sh.out \ + > _dist/profile.20kc.20top.50pct.noskip.lru.256sh.pdf */ diff --git a/subscriber_bench_test.go b/subscriber_bench_test.go index 94768509..3b5e5ba0 100644 --- a/subscriber_bench_test.go +++ b/subscriber_bench_test.go @@ -133,7 +133,7 @@ func subBenchSubscriber(b *testing.B, topics, concurrency, matchPct int, testNam /* --- test.sh --- These are example commands that can be used to run subsets of this test for analysis. -Omission of any environment variable causes the test to enumate a few meaningful options. +Omission of any environment variable causes the test to enumerate a few meaningful options. #!/usr/bin/sh @@ -141,38 +141,19 @@ set -e mkdir -p _dist -# --- Generating a diff --- - -SUB_TEST_CONCURRENCY=5000 \ -SUB_TEST_SKIPSELECT=false \ -SUB_TEST_CACHE=ristretto \ -SUB_TEST_SHARDS=256 \ -go test -bench=. -run=BenchmarkSubscriber -benchmem -count 5 | tee _dist/output.5kc.noskip.ristretto.256.txt - -SUB_TEST_CONCURRENCY=5000 \ -SUB_TEST_SKIPSELECT=true \ -SUB_TEST_CACHE=lru \ -SUB_TEST_SHARDS=256 \ -go test -bench=. -run=BenchmarkSubscriber -benchmem -count 5 | tee _dist/output.5kc.skip.lru.256.txt - -benchstat _dist/output.5kc.noskip.ristretto.256.txt \ - _dist/output.5kc.skip.lru.256.txt \ - > _dist/diff-cache.5kc.256.txt - - # --- Generating a cpu call graph --- SUB_TEST_CONCURRENCY=20000 \ SUB_TEST_TOPICS=20 \ SUB_TEST_MATCHPCT=50 \ SUB_TEST_SKIPSELECT=false \ -SUB_TEST_CACHE=ristretto \ +SUB_TEST_CACHE=lru \ SUB_TEST_SHARDS=256 \ -go test -bench=. -run=BenchmarkSubscriber -cpuprofile _dist/profile.20kc.20top.50pct.noskip.ristretto.256sh.out -benchmem +go test -bench=. -run=BenchmarkSubscriber -cpuprofile _dist/profile.20kc.20top.50pct.noskip.lru.256sh.out -benchmem go build -o _dist/bin -go tool pprof --pdf _dist/bin _dist/profile.20kc.20top.50pct.noskip.ristretto.256sh.out \ - > _dist/profile.20kc.20top.50pct.noskip.ristretto.256sh.pdf +go tool pprof --pdf _dist/bin _dist/profile.20kc.20top.50pct.noskip.lru.256sh.out \ + > _dist/profile.20kc.20top.50pct.noskip.lru.256sh.pdf */ diff --git a/topicselectorristretto.go b/topicselectorristretto.go deleted file mode 100644 index f96266f2..00000000 --- a/topicselectorristretto.go +++ /dev/null @@ -1,34 +0,0 @@ -package mercure - -import ( - "fmt" - - "github.com/dgraph-io/ristretto" -) - -// Gather stats to find the best default values. -const ( - TopicSelectorStoreRistrettoDefaultCacheNumCounters = int64(6e7) - TopicSelectorStoreRistrettoCacheMaxCost = int64(1e8) // 100 MB -) - -// NewTopicSelectorStoreRistretto creates a TopicSelectorStore instance with a ristretto cache. -// See https://github.com/dgraph-io/ristretto, set values to 0 to disable. -// -// Deprecated: use NewTopicSelectorStoreLRU instead. -func NewTopicSelectorStoreRistretto(cacheNumCounters, cacheMaxCost int64) (*TopicSelectorStore, error) { - if cacheNumCounters == 0 { - return &TopicSelectorStore{}, nil - } - - cache, err := ristretto.NewCache(&ristretto.Config[string, interface{}]{ - NumCounters: cacheNumCounters, - MaxCost: cacheMaxCost, - BufferItems: 64, - }) - if err != nil { - return nil, fmt.Errorf("unable to create cache: %w", err) - } - - return &TopicSelectorStore{cache: cache}, nil -} diff --git a/topicselectorristretto_test.go b/topicselectorristretto_test.go deleted file mode 100644 index f29f47de..00000000 --- a/topicselectorristretto_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package mercure - -import ( - "testing" - "time" - - "github.com/dgraph-io/ristretto" - "github.com/stretchr/testify/assert" -) - -func TestMatchRistretto(t *testing.T) { - cache, _ := ristretto.NewCache(&ristretto.Config[string, interface{}]{ - NumCounters: TopicSelectorStoreRistrettoDefaultCacheNumCounters, - MaxCost: TopicSelectorStoreRistrettoCacheMaxCost, - BufferItems: 64, - }) - tss := &TopicSelectorStore{cache, false} - - assert.True(t, tss.match("https://example.com/foo/bar", "https://example.com/{foo}/bar")) - - // wait for value to pass through ristretto's buffers - cache.Wait() - - _, found := tss.cache.Get("t_https://example.com/{foo}/bar") - assert.True(t, found) - - _, found = tss.cache.Get("m_https://example.com/{foo}/bar_https://example.com/foo/bar") - assert.True(t, found) - - assert.True(t, tss.match("https://example.com/foo/bar", "https://example.com/{foo}/bar")) - assert.False(t, tss.match("https://example.com/foo/bar/baz", "https://example.com/{foo}/bar")) - - // wait for value to pass through ristretto's buffers, see https://discuss.dgraph.io/t/there-should-be-a-test-only-blocking-mode/8424 - time.Sleep(10 * time.Millisecond) - - _, found = tss.cache.Get("t_https://example.com/{foo}/bar") - assert.True(t, found) - - _, found = tss.cache.Get("m_https://example.com/{foo}/bar_https://example.com/foo/bar") - assert.True(t, found) - - assert.True(t, tss.match("https://example.com/kevin/dunglas", "https://example.com/{fistname}/{lastname}")) - assert.True(t, tss.match("https://example.com/foo/bar", "*")) - assert.True(t, tss.match("https://example.com/foo/bar", "https://example.com/foo/bar")) - assert.True(t, tss.match("foo", "foo")) - assert.False(t, tss.match("foo", "bar")) -} From 7d42cd12fcb1095a8a3fa8f4bb3585bf31839274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 5 Nov 2024 23:51:27 +0100 Subject: [PATCH 35/71] refactor: rename topiselector file --- topic_selector.go => topicselector.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename topic_selector.go => topicselector.go (100%) diff --git a/topic_selector.go b/topicselector.go similarity index 100% rename from topic_selector.go rename to topicselector.go From 473d5f4e5d11e4b60d243d387af40fefa8694ae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 5 Nov 2024 23:59:14 +0100 Subject: [PATCH 36/71] feat: allow passing the topic selector store to the transport --- hub.go | 13 ++++++++----- transport.go | 7 ++++++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/hub.go b/hub.go index 18ee3a59..4a353bd0 100644 --- a/hub.go +++ b/hub.go @@ -324,11 +324,6 @@ func NewHub(options ...Option) (*Hub, error) { opt.logger = l } - if opt.transport == nil { - t, _ := DeprecatedNewLocalTransport(nil, nil) - opt.transport = t - } - if opt.topicSelectorStore == nil { tss, err := NewTopicSelectorStoreLRU(DefaultTopicSelectorStoreLRUMaxEntriesPerShard, DefaultTopicSelectorStoreLRUShardCount) if err != nil { @@ -338,6 +333,14 @@ func NewHub(options ...Option) (*Hub, error) { opt.topicSelectorStore = tss } + if opt.transport == nil { + opt.transport = NewLocalTransport() + } + + if ttss, ok := opt.transport.(TransportTopicSelectorStore); ok { + ttss.SetTopicSelectorStore(opt.topicSelectorStore) + } + if opt.metrics == nil { opt.metrics = NopMetrics{} } diff --git a/transport.go b/transport.go index be58e36d..1bb4c477 100644 --- a/transport.go +++ b/transport.go @@ -54,12 +54,17 @@ type Transport interface { Close() error } -// TransportSubscribers provide a method to retrieve the list of active subscribers. +// TransportSubscribers provides a method to retrieve the list of active subscribers. type TransportSubscribers interface { // GetSubscribers gets the last event ID and the list of active subscribers at this time. GetSubscribers() (string, []*Subscriber, error) } +// TransportTopicSelectorStore provides a method to pass the TopicSelectorStore to the transport. +type TransportTopicSelectorStore interface { + SetTopicSelectorStore(store *TopicSelectorStore) +} + // ErrClosedTransport is returned by the Transport's Dispatch and AddSubscriber methods after a call to Close. var ErrClosedTransport = errors.New("hub: read/write on closed Transport") From fbd473b88442dae130d67fc2abb37fe82713bfdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 6 Nov 2024 16:42:24 +0100 Subject: [PATCH 37/71] refactor!: split subscribers and local subscribers --- bolt.go | 8 +-- bolt_test.go | 28 ++++---- local.go | 6 +- local_bench_test.go | 2 +- local_test.go | 28 ++++---- localsubscriber.go | 136 +++++++++++++++++++++++++++++++++++++++ metrics.go | 14 ++-- metrics_test.go | 8 +-- publish_test.go | 4 +- subscribe.go | 20 +++--- subscribe_test.go | 10 +-- subscriber.go | 131 ++----------------------------------- subscriber_bench_test.go | 2 +- subscriber_test.go | 10 +-- subscriberlist.go | 14 ++-- subscriberlist_test.go | 2 +- subscription_test.go | 12 ++-- transport.go | 8 +-- 18 files changed, 231 insertions(+), 212 deletions(-) create mode 100644 localsubscriber.go diff --git a/bolt.go b/bolt.go index 0843eb64..03f871da 100644 --- a/bolt.go +++ b/bolt.go @@ -202,7 +202,7 @@ func (t *BoltTransport) persist(updateID string, updateJSON []byte) error { } // AddSubscriber adds a new subscriber to the transport. -func (t *BoltTransport) AddSubscriber(s *Subscriber) error { +func (t *BoltTransport) AddSubscriber(s *LocalSubscriber) error { select { case <-t.closed: return ErrClosedTransport @@ -226,7 +226,7 @@ func (t *BoltTransport) AddSubscriber(s *Subscriber) error { } // RemoveSubscriber removes a new subscriber from the transport. -func (t *BoltTransport) RemoveSubscriber(s *Subscriber) error { +func (t *BoltTransport) RemoveSubscriber(s *LocalSubscriber) error { select { case <-t.closed: return ErrClosedTransport @@ -249,7 +249,7 @@ func (t *BoltTransport) GetSubscribers() (string, []*Subscriber, error) { } //nolint:gocognit -func (t *BoltTransport) dispatchHistory(s *Subscriber, toSeq uint64) error { +func (t *BoltTransport) dispatchHistory(s *LocalSubscriber, toSeq uint64) error { err := t.db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte(t.bucketName)) if b == nil { @@ -311,7 +311,7 @@ func (t *BoltTransport) Close() (err error) { t.Lock() defer t.Unlock() - t.subscribers.Walk(0, func(s *Subscriber) bool { + t.subscribers.Walk(0, func(s *LocalSubscriber) bool { s.Disconnect() return true diff --git a/bolt_test.go b/bolt_test.go index ba78612c..4d17f6d0 100644 --- a/bolt_test.go +++ b/bolt_test.go @@ -35,7 +35,7 @@ func TestBoltTransportHistory(t *testing.T) { }) } - s := NewSubscriber("8", transport.logger, &TopicSelectorStore{}) + s := NewLocalSubscriber("8", transport.logger, &TopicSelectorStore{}) s.SetTopics(topics, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -68,7 +68,7 @@ func TestBoltTransportLogsBogusLastEventID(t *testing.T) { Topics: topics, }) - s := NewSubscriber("711131", logger, &TopicSelectorStore{}) + s := NewLocalSubscriber("711131", logger, &TopicSelectorStore{}) s.SetTopics(topics, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -87,7 +87,7 @@ func TestBoltTopicSelectorHistory(t *testing.T) { transport.Dispatch(&Update{Topics: []string{"http://example.com/subscribed-public-only"}, Private: true, Event: Event{ID: "3"}}) transport.Dispatch(&Update{Topics: []string{"http://example.com/subscribed-public-only"}, Event: Event{ID: "4"}}) - s := NewSubscriber(EarliestLastEventID, transport.logger, &TopicSelectorStore{}) + s := NewLocalSubscriber(EarliestLastEventID, transport.logger, &TopicSelectorStore{}) s.SetTopics([]string{"http://example.com/subscribed", "http://example.com/subscribed-public-only"}, []string{"http://example.com/subscribed"}) require.NoError(t, transport.AddSubscriber(s)) @@ -109,7 +109,7 @@ func TestBoltTransportRetrieveAllHistory(t *testing.T) { }) } - s := NewSubscriber(EarliestLastEventID, transport.logger, &TopicSelectorStore{}) + s := NewLocalSubscriber(EarliestLastEventID, transport.logger, &TopicSelectorStore{}) s.SetTopics(topics, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -139,7 +139,7 @@ func TestBoltTransportHistoryAndLive(t *testing.T) { }) } - s := NewSubscriber("8", transport.logger, &TopicSelectorStore{}) + s := NewLocalSubscriber("8", transport.logger, &TopicSelectorStore{}) s.SetTopics(topics, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -221,7 +221,7 @@ func TestBoltTransportDoNotDispatchUntilListen(t *testing.T) { defer os.Remove("test.db") assert.Implements(t, (*Transport)(nil), transport) - s := NewSubscriber("", transport.logger, &TopicSelectorStore{}) + s := NewLocalSubscriber("", transport.logger, &TopicSelectorStore{}) require.NoError(t, transport.AddSubscriber(s)) var wg sync.WaitGroup @@ -245,7 +245,7 @@ func TestBoltTransportDispatch(t *testing.T) { defer os.Remove("test.db") assert.Implements(t, (*Transport)(nil), transport) - s := NewSubscriber("", transport.logger, &TopicSelectorStore{}) + s := NewLocalSubscriber("", transport.logger, &TopicSelectorStore{}) s.SetTopics([]string{"https://example.com/foo", "https://example.com/private"}, []string{"https://example.com/private"}) require.NoError(t, transport.AddSubscriber(s)) @@ -274,7 +274,7 @@ func TestBoltTransportClosed(t *testing.T) { defer os.Remove("test.db") assert.Implements(t, (*Transport)(nil), transport) - s := NewSubscriber("", transport.logger, &TopicSelectorStore{}) + s := NewLocalSubscriber("", transport.logger, &TopicSelectorStore{}) s.SetTopics([]string{"https://example.com/foo"}, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -293,11 +293,11 @@ func TestBoltCleanDisconnectedSubscribers(t *testing.T) { defer transport.Close() defer os.Remove("test.db") - s1 := NewSubscriber("", transport.logger, &TopicSelectorStore{}) + s1 := NewLocalSubscriber("", transport.logger, &TopicSelectorStore{}) s1.SetTopics([]string{"foo"}, []string{}) require.NoError(t, transport.AddSubscriber(s1)) - s2 := NewSubscriber("", transport.logger, &TopicSelectorStore{}) + s2 := NewLocalSubscriber("", transport.logger, &TopicSelectorStore{}) s2.SetTopics([]string{"foo"}, []string{}) require.NoError(t, transport.AddSubscriber(s2)) @@ -318,10 +318,10 @@ func TestBoltGetSubscribers(t *testing.T) { defer transport.Close() defer os.Remove("test.db") - s1 := NewSubscriber("", transport.logger, &TopicSelectorStore{}) + s1 := NewLocalSubscriber("", transport.logger, &TopicSelectorStore{}) require.NoError(t, transport.AddSubscriber(s1)) - s2 := NewSubscriber("", transport.logger, &TopicSelectorStore{}) + s2 := NewLocalSubscriber("", transport.logger, &TopicSelectorStore{}) require.NoError(t, transport.AddSubscriber(s2)) lastEventID, subscribers, err := transport.GetSubscribers() @@ -329,8 +329,8 @@ func TestBoltGetSubscribers(t *testing.T) { assert.Equal(t, EarliestLastEventID, lastEventID) assert.Len(t, subscribers, 2) - assert.Contains(t, subscribers, s1) - assert.Contains(t, subscribers, s2) + assert.Contains(t, subscribers, &s1.Subscriber) + assert.Contains(t, subscribers, &s2.Subscriber) } func TestBoltLastEventID(t *testing.T) { diff --git a/local.go b/local.go index 53ce1aa9..b8e160e0 100644 --- a/local.go +++ b/local.go @@ -54,7 +54,7 @@ func (t *LocalTransport) Dispatch(update *Update) error { } // AddSubscriber adds a new subscriber to the transport. -func (t *LocalTransport) AddSubscriber(s *Subscriber) error { +func (t *LocalTransport) AddSubscriber(s *LocalSubscriber) error { select { case <-t.closed: return ErrClosedTransport @@ -74,7 +74,7 @@ func (t *LocalTransport) AddSubscriber(s *Subscriber) error { } // RemoveSubscriber removes a subscriber from the transport. -func (t *LocalTransport) RemoveSubscriber(s *Subscriber) error { +func (t *LocalTransport) RemoveSubscriber(s *LocalSubscriber) error { select { case <-t.closed: return ErrClosedTransport @@ -102,7 +102,7 @@ func (t *LocalTransport) Close() (err error) { t.Lock() defer t.Unlock() close(t.closed) - t.subscribers.Walk(0, func(s *Subscriber) bool { + t.subscribers.Walk(0, func(s *LocalSubscriber) bool { s.Disconnect() return true diff --git a/local_bench_test.go b/local_bench_test.go index c00eabbe..58287295 100644 --- a/local_bench_test.go +++ b/local_bench_test.go @@ -41,7 +41,7 @@ func subBenchLocalTransport(b *testing.B, topics, concurrency, matchPct int, tes out := make(chan *Update, 50000) tss := &TopicSelectorStore{} for i := 0; i < concurrency; i++ { - s := NewSubscriber("", zap.NewNop(), tss) + s := NewLocalSubscriber("", zap.NewNop(), tss) if i%100 < matchPct { s.SetTopics(tsMatch, nil) } else { diff --git a/local_test.go b/local_test.go index 964c5ec7..33e89add 100644 --- a/local_test.go +++ b/local_test.go @@ -20,7 +20,7 @@ func TestLocalTransportDoNotDispatchUntilListen(t *testing.T) { err := transport.Dispatch(u) require.NoError(t, err) - s := NewSubscriber("", logger, &TopicSelectorStore{}) + s := NewLocalSubscriber("", logger, &TopicSelectorStore{}) s.SetTopics(u.Topics, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -43,7 +43,7 @@ func TestLocalTransportDispatch(t *testing.T) { defer transport.Close() assert.Implements(t, (*Transport)(nil), transport) - s := NewSubscriber("", logger, &TopicSelectorStore{}) + s := NewLocalSubscriber("", logger, &TopicSelectorStore{}) s.SetTopics([]string{"http://example.com/foo"}, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -60,10 +60,10 @@ func TestLocalTransportClosed(t *testing.T) { tss := &TopicSelectorStore{} - s := NewSubscriber("", logger, tss) + s := NewLocalSubscriber("", logger, tss) require.NoError(t, transport.AddSubscriber(s)) require.NoError(t, transport.Close()) - assert.Equal(t, transport.AddSubscriber(NewSubscriber("", logger, tss)), ErrClosedTransport) + assert.Equal(t, transport.AddSubscriber(NewLocalSubscriber("", logger, tss)), ErrClosedTransport) assert.Equal(t, transport.Dispatch(&Update{}), ErrClosedTransport) _, ok := <-s.out @@ -78,10 +78,10 @@ func TestLiveCleanDisconnectedSubscribers(t *testing.T) { tss := &TopicSelectorStore{} - s1 := NewSubscriber("", logger, tss) + s1 := NewLocalSubscriber("", logger, tss) require.NoError(t, transport.AddSubscriber(s1)) - s2 := NewSubscriber("", logger, tss) + s2 := NewLocalSubscriber("", logger, tss) require.NoError(t, transport.AddSubscriber(s2)) assert.Equal(t, 2, transport.subscribers.Len()) @@ -101,7 +101,7 @@ func TestLiveReading(t *testing.T) { defer transport.Close() assert.Implements(t, (*Transport)(nil), transport) - s := NewSubscriber("", logger, &TopicSelectorStore{}) + s := NewLocalSubscriber("", logger, &TopicSelectorStore{}) s.SetTopics([]string{"https://example.com"}, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -113,23 +113,23 @@ func TestLiveReading(t *testing.T) { } func TestLocalTransportGetSubscribers(t *testing.T) { - logger := zap.NewNop() - transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, logger) + transport := NewLocalTransport() defer transport.Close() require.NotNil(t, transport) + logger := zap.NewNop() tss := &TopicSelectorStore{} - s1 := NewSubscriber("", logger, tss) + s1 := NewLocalSubscriber("", logger, tss) require.NoError(t, transport.AddSubscriber(s1)) - s2 := NewSubscriber("", logger, tss) + s2 := NewLocalSubscriber("", logger, tss) require.NoError(t, transport.AddSubscriber(s2)) - lastEventID, subscribers, err := transport.(TransportSubscribers).GetSubscribers() + lastEventID, subscribers, err := transport.GetSubscribers() require.NoError(t, err) assert.Equal(t, EarliestLastEventID, lastEventID) assert.Len(t, subscribers, 2) - assert.Contains(t, subscribers, s1) - assert.Contains(t, subscribers, s2) + assert.Contains(t, subscribers, &s1.Subscriber) + assert.Contains(t, subscribers, &s2.Subscriber) } diff --git a/localsubscriber.go b/localsubscriber.go new file mode 100644 index 00000000..b821cb67 --- /dev/null +++ b/localsubscriber.go @@ -0,0 +1,136 @@ +package mercure + +import ( + "net/url" + "sync" + "sync/atomic" + + "github.com/gofrs/uuid" + "go.uber.org/zap" +) + +// LocalSubscriber represents a client subscribed to a list of topics on the current hub. +type LocalSubscriber struct { + Subscriber + + disconnected int32 + out chan *Update + outMutex sync.RWMutex + responseLastEventID chan string + ready int32 + liveQueue []*Update + liveMutex sync.RWMutex +} + +const outBufferLength = 1000 + +// NewLocalSubscriber creates a new subscriber. +func NewLocalSubscriber(lastEventID string, logger Logger, topicSelectorStore *TopicSelectorStore) *LocalSubscriber { + id := "urn:uuid:" + uuid.Must(uuid.NewV4()).String() + s := &LocalSubscriber{ + Subscriber: *NewSubscriber(logger, topicSelectorStore), + responseLastEventID: make(chan string, 1), + out: make(chan *Update, outBufferLength), + } + + s.ID = id + s.EscapedID = url.QueryEscape(id) + s.RequestLastEventID = lastEventID + + return s +} + +// Dispatch an update to the subscriber. +// Security checks must (topics matching) be done before calling Dispatch, +// for instance by calling Match. +func (s *LocalSubscriber) Dispatch(u *Update, fromHistory bool) bool { + if atomic.LoadInt32(&s.disconnected) > 0 { + return false + } + + if !fromHistory && atomic.LoadInt32(&s.ready) < 1 { + s.liveMutex.Lock() + if s.ready < 1 { + s.liveQueue = append(s.liveQueue, u) + s.liveMutex.Unlock() + + return true + } + s.liveMutex.Unlock() + } + + s.outMutex.Lock() + if atomic.LoadInt32(&s.disconnected) > 0 { + s.outMutex.Unlock() + + return false + } + + select { + case s.out <- u: + s.outMutex.Unlock() + default: + s.handleFullChan() + + return false + } + + return true +} + +// Ready flips the ready flag to true and flushes queued live updates returning number of events flushed. +func (s *LocalSubscriber) Ready() (n int) { + s.liveMutex.Lock() + s.outMutex.Lock() + + for _, u := range s.liveQueue { + select { + case s.out <- u: + n++ + default: + s.handleFullChan() + s.liveMutex.Unlock() + + return n + } + } + atomic.StoreInt32(&s.ready, 1) + + s.outMutex.Unlock() + s.liveMutex.Unlock() + + return n +} + +// Receive returns a chan when incoming updates are dispatched. +func (s *LocalSubscriber) Receive() <-chan *Update { + return s.out +} + +// HistoryDispatched must be called when all messages coming from the history have been dispatched. +func (s *LocalSubscriber) HistoryDispatched(responseLastEventID string) { + s.responseLastEventID <- responseLastEventID +} + +// Disconnect disconnects the subscriber. +func (s *LocalSubscriber) Disconnect() { + if atomic.LoadInt32(&s.disconnected) > 0 { + return + } + + s.outMutex.Lock() + defer s.outMutex.Unlock() + + atomic.StoreInt32(&s.disconnected, 1) + close(s.out) +} + +// handleFullChan disconnects the subscriber when the out channel is full. +func (s *LocalSubscriber) handleFullChan() { + atomic.StoreInt32(&s.disconnected, 1) + s.outMutex.Unlock() + + if c := s.logger.Check(zap.ErrorLevel, "subscriber unable to receive updates fast enough"); c != nil { + c.Write(zap.Object("subscriber", s)) + } +} diff --git a/metrics.go b/metrics.go index 8f4dc97e..e5398bfe 100644 --- a/metrics.go +++ b/metrics.go @@ -13,18 +13,18 @@ const metricsPath = "/metrics" type Metrics interface { // SubscriberConnected collects metrics about subscriber connections. - SubscriberConnected(s *Subscriber) + SubscriberConnected(s *LocalSubscriber) // SubscriberDisconnected collects metrics about subscriber disconnections. - SubscriberDisconnected(s *Subscriber) + SubscriberDisconnected(s *LocalSubscriber) // UpdatePublished collects metrics about update publications. UpdatePublished(u *Update) } type NopMetrics struct{} -func (NopMetrics) SubscriberConnected(_ *Subscriber) {} -func (NopMetrics) SubscriberDisconnected(_ *Subscriber) {} -func (NopMetrics) UpdatePublished(_ *Update) {} +func (NopMetrics) SubscriberConnected(_ *LocalSubscriber) {} +func (NopMetrics) SubscriberDisconnected(_ *LocalSubscriber) {} +func (NopMetrics) UpdatePublished(_ *Update) {} // PrometheusMetrics store Hub collected metrics. type PrometheusMetrics struct { @@ -84,12 +84,12 @@ func (m *PrometheusMetrics) Register(r *mux.Router) { r.Handle(metricsPath, promhttp.HandlerFor(m.registry.(*prometheus.Registry), promhttp.HandlerOpts{})).Methods(http.MethodGet) } -func (m *PrometheusMetrics) SubscriberConnected(_ *Subscriber) { +func (m *PrometheusMetrics) SubscriberConnected(_ *LocalSubscriber) { m.subscribersTotal.Inc() m.subscribers.Inc() } -func (m *PrometheusMetrics) SubscriberDisconnected(_ *Subscriber) { +func (m *PrometheusMetrics) SubscriberDisconnected(_ *LocalSubscriber) { m.subscribers.Dec() } diff --git a/metrics_test.go b/metrics_test.go index 88e82b8c..5af78744 100644 --- a/metrics_test.go +++ b/metrics_test.go @@ -15,12 +15,12 @@ func TestNumberOfRunningSubscribers(t *testing.T) { logger := zap.NewNop() tss := &TopicSelectorStore{} - s1 := NewSubscriber("", logger, tss) + s1 := NewLocalSubscriber("", logger, tss) s1.SetTopics([]string{"topic1", "topic2"}, nil) m.SubscriberConnected(s1) assertGaugeValue(t, 1.0, m.subscribers) - s2 := NewSubscriber("", logger, tss) + s2 := NewLocalSubscriber("", logger, tss) s2.SetTopics([]string{"topic2"}, nil) m.SubscriberConnected(s2) assertGaugeValue(t, 2.0, m.subscribers) @@ -38,12 +38,12 @@ func TestTotalNumberOfHandledSubscribers(t *testing.T) { logger := zap.NewNop() tss := &TopicSelectorStore{} - s1 := NewSubscriber("", logger, tss) + s1 := NewLocalSubscriber("", logger, tss) s1.SetTopics([]string{"topic1", "topic2"}, nil) m.SubscriberConnected(s1) assertCounterValue(t, 1.0, m.subscribersTotal) - s2 := NewSubscriber("", logger, tss) + s2 := NewLocalSubscriber("", logger, tss) s2.SetTopics([]string{"topic2"}, nil) m.SubscriberConnected(s2) assertCounterValue(t, 2.0, m.subscribersTotal) diff --git a/publish_test.go b/publish_test.go index 92dc2d16..b3b2164e 100644 --- a/publish_test.go +++ b/publish_test.go @@ -174,7 +174,7 @@ func TestPublishOK(t *testing.T) { hub := createDummy() topics := []string{"http://example.com/books/1"} - s := NewSubscriber("", zap.NewNop(), &TopicSelectorStore{}) + s := NewLocalSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.SetTopics(topics, topics) s.Claims = &claims{Mercure: mercureClaim{Subscribe: topics}} @@ -238,7 +238,7 @@ func TestPublishNoData(t *testing.T) { func TestPublishGenerateUUID(t *testing.T) { h := createDummy() - s := NewSubscriber("", zap.NewNop(), &TopicSelectorStore{}) + s := NewLocalSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.SetTopics([]string{"http://example.com/books/1"}, s.SubscribedTopics) require.NoError(t, h.transport.AddSubscriber(s)) diff --git a/subscribe.go b/subscribe.go index 293a8902..86499b61 100644 --- a/subscribe.go +++ b/subscribe.go @@ -17,7 +17,7 @@ type responseController struct { // writeDeadline is the JWT expiration date or time.Now() + hub.writeTimeout writeDeadline time.Time hub *Hub - subscriber *Subscriber + subscriber *LocalSubscriber } func (rc *responseController) setDispatchWriteDeadline() bool { @@ -73,13 +73,13 @@ func (rc *responseController) flush() bool { return true } -func (h *Hub) newResponseController(w http.ResponseWriter, s *Subscriber) *responseController { +func (h *Hub) newResponseController(w http.ResponseWriter, s *LocalSubscriber) *responseController { wd := h.getWriteDeadline(s) return &responseController{*http.NewResponseController(w), w, wd.Add(-h.dispatchTimeout), wd, h, s} // nolint:bodyclose } -func (h *Hub) getWriteDeadline(s *Subscriber) (deadline time.Time) { +func (h *Hub) getWriteDeadline(s *LocalSubscriber) (deadline time.Time) { if h.writeTimeout != 0 { deadline = time.Now().Add(h.writeTimeout) } @@ -155,8 +155,8 @@ func (h *Hub) SubscribeHandler(w http.ResponseWriter, r *http.Request) { } // registerSubscriber initializes the connection. -func (h *Hub) registerSubscriber(w http.ResponseWriter, r *http.Request) (*Subscriber, *responseController) { - s := NewSubscriber(retrieveLastEventID(r, h.opt, h.logger), h.logger, h.topicSelectorStore) +func (h *Hub) registerSubscriber(w http.ResponseWriter, r *http.Request) (*LocalSubscriber, *responseController) { + s := NewLocalSubscriber(retrieveLastEventID(r, h.opt, h.logger), h.logger, h.topicSelectorStore) s.RemoteAddr = r.RemoteAddr var privateTopics []string var claims *claims @@ -170,7 +170,7 @@ func (h *Hub) registerSubscriber(w http.ResponseWriter, r *http.Request) (*Subsc } if err != nil || (claims == nil && !h.anonymous) { http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) - if c := h.logger.Check(zap.DebugLevel, "Subscriber unauthorized"); c != nil { + if c := h.logger.Check(zap.DebugLevel, "LocalSubscriber unauthorized"); c != nil { c.Write(zap.Object("subscriber", s), zap.Error(err)) } @@ -215,7 +215,7 @@ func (h *Hub) registerSubscriber(w http.ResponseWriter, r *http.Request) (*Subsc } // sendHeaders sends correct HTTP headers to create a keep-alive connection. -func (h *Hub) sendHeaders(w http.ResponseWriter, s *Subscriber) { +func (h *Hub) sendHeaders(w http.ResponseWriter, s *LocalSubscriber) { // Keep alive, useful only for HTTP 1 clients https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive w.Header().Set("Connection", "keep-alive") @@ -287,7 +287,7 @@ func (h *Hub) write(rc *responseController, data string) bool { return rc.flush() && rc.setDefaultWriteDeadline() } -func (h *Hub) shutdown(s *Subscriber) { +func (h *Hub) shutdown(s *LocalSubscriber) { // Notify that the client is closing the connection s.Disconnect() if err := h.transport.RemoveSubscriber(s); err != nil { @@ -297,13 +297,13 @@ func (h *Hub) shutdown(s *Subscriber) { } h.dispatchSubscriptionUpdate(s, false) - if c := h.logger.Check(zap.InfoLevel, "Subscriber disconnected"); c != nil { + if c := h.logger.Check(zap.InfoLevel, "LocalSubscriber disconnected"); c != nil { c.Write(zap.Object("subscriber", s)) } h.metrics.SubscriberDisconnected(s) } -func (h *Hub) dispatchSubscriptionUpdate(s *Subscriber, active bool) { +func (h *Hub) dispatchSubscriptionUpdate(s *LocalSubscriber, active bool) { if !h.subscriptions { return } diff --git a/subscribe_test.go b/subscribe_test.go index f3550709..81f7be21 100644 --- a/subscribe_test.go +++ b/subscribe_test.go @@ -238,16 +238,16 @@ func (*addSubscriberErrorTransport) Dispatch(*Update) error { return nil } -func (*addSubscriberErrorTransport) AddSubscriber(*Subscriber) error { +func (*addSubscriberErrorTransport) AddSubscriber(*LocalSubscriber) error { return errFailedToAddSubscriber } -func (*addSubscriberErrorTransport) RemoveSubscriber(*Subscriber) error { +func (*addSubscriberErrorTransport) RemoveSubscriber(*LocalSubscriber) error { return nil } -func (*addSubscriberErrorTransport) GetSubscribers() (string, []*Subscriber, error) { - return "", []*Subscriber{}, nil +func (*addSubscriberErrorTransport) GetSubscribers() (string, []*LocalSubscriber, error) { + return "", []*LocalSubscriber{}, nil } func (*addSubscriberErrorTransport) Close() error { @@ -412,7 +412,7 @@ func TestUnsubscribe(t *testing.T) { req := httptest.NewRequest(http.MethodGet, defaultHubURL+"?topic=http://example.com/books/1", nil).WithContext(ctx) hub.SubscribeHandler(newSubscribeRecorder(), req) assert.Equal(t, 0, s.subscribers.Len()) - s.subscribers.Walk(0, func(s *Subscriber) bool { + s.subscribers.Walk(0, func(s *LocalSubscriber) bool { _, ok := <-s.out assert.False(t, ok) diff --git a/subscriber.go b/subscriber.go index 3e68ff0b..44212e15 100644 --- a/subscriber.go +++ b/subscriber.go @@ -4,15 +4,11 @@ import ( "fmt" "net/url" "regexp" - "sync" - "sync/atomic" - "github.com/gofrs/uuid" - "go.uber.org/zap" "go.uber.org/zap/zapcore" ) -// Subscriber represents a client subscribed to a list of topics. +// Subscriber represents a client subscribed to a list of topics on a remote or on the current hub. type Subscriber struct { ID string EscapedID string @@ -25,118 +21,15 @@ type Subscriber struct { AllowedPrivateTopics []string AllowedPrivateRegexps []*regexp.Regexp - disconnected int32 - out chan *Update - outMutex sync.RWMutex - responseLastEventID chan string - logger Logger - ready int32 - liveQueue []*Update - liveMutex sync.RWMutex - topicSelectorStore *TopicSelectorStore + logger Logger + topicSelectorStore *TopicSelectorStore } -const outBufferLength = 1000 - -// NewSubscriber creates a new subscriber. -func NewSubscriber(lastEventID string, logger Logger, topicSelectorStore *TopicSelectorStore) *Subscriber { - id := "urn:uuid:" + uuid.Must(uuid.NewV4()).String() - s := &Subscriber{ - ID: id, - EscapedID: url.QueryEscape(id), - RequestLastEventID: lastEventID, - responseLastEventID: make(chan string, 1), - out: make(chan *Update, outBufferLength), - logger: logger, - topicSelectorStore: topicSelectorStore, +func NewSubscriber(logger Logger, topicSelectorStore *TopicSelectorStore) *Subscriber { + return &Subscriber{ + logger: logger, + topicSelectorStore: topicSelectorStore, } - - return s -} - -// Dispatch an update to the subscriber. -// Security checks must (topics matching) be done before calling Dispatch, -// for instance by calling Match. -func (s *Subscriber) Dispatch(u *Update, fromHistory bool) bool { - if atomic.LoadInt32(&s.disconnected) > 0 { - return false - } - - if !fromHistory && atomic.LoadInt32(&s.ready) < 1 { - s.liveMutex.Lock() - if s.ready < 1 { - s.liveQueue = append(s.liveQueue, u) - s.liveMutex.Unlock() - - return true - } - s.liveMutex.Unlock() - } - - s.outMutex.Lock() - if atomic.LoadInt32(&s.disconnected) > 0 { - s.outMutex.Unlock() - - return false - } - - select { - case s.out <- u: - s.outMutex.Unlock() - default: - s.handleFullChan() - - return false - } - - return true -} - -// Ready flips the ready flag to true and flushes queued live updates returning number of events flushed. -func (s *Subscriber) Ready() (n int) { - s.liveMutex.Lock() - s.outMutex.Lock() - - for _, u := range s.liveQueue { - select { - case s.out <- u: - n++ - default: - s.handleFullChan() - s.liveMutex.Unlock() - - return n - } - } - atomic.StoreInt32(&s.ready, 1) - - s.outMutex.Unlock() - s.liveMutex.Unlock() - - return n -} - -// Receive returns a chan when incoming updates are dispatched. -func (s *Subscriber) Receive() <-chan *Update { - return s.out -} - -// HistoryDispatched must be called when all messages coming from the history have been dispatched. -func (s *Subscriber) HistoryDispatched(responseLastEventID string) { - s.responseLastEventID <- responseLastEventID -} - -// Disconnect disconnects the subscriber. -func (s *Subscriber) Disconnect() { - if atomic.LoadInt32(&s.disconnected) > 0 { - return - } - - s.outMutex.Lock() - defer s.outMutex.Unlock() - - atomic.StoreInt32(&s.disconnected, 1) - close(s.out) } // SetTopics compiles topic selector regexps. @@ -237,13 +130,3 @@ func (s *Subscriber) MarshalLogObject(enc zapcore.ObjectEncoder) error { return nil } - -// handleFullChan disconnects the subscriber when the out channel is full. -func (s *Subscriber) handleFullChan() { - atomic.StoreInt32(&s.disconnected, 1) - s.outMutex.Unlock() - - if c := s.logger.Check(zap.ErrorLevel, "subscriber unable to receive updates fast enough"); c != nil { - c.Write(zap.Object("subscriber", s)) - } -} diff --git a/subscriber_bench_test.go b/subscriber_bench_test.go index 3b5e5ba0..d78c5f54 100644 --- a/subscriber_bench_test.go +++ b/subscriber_bench_test.go @@ -85,7 +85,7 @@ func strInt(s string) int { func subBenchSubscriber(b *testing.B, topics, concurrency, matchPct int, testName string) { b.Helper() - s := NewSubscriber("0e249241-6432-4ce1-b9b9-5d170163c253", zap.NewNop(), &TopicSelectorStore{}) + s := NewLocalSubscriber("0e249241-6432-4ce1-b9b9-5d170163c253", zap.NewNop(), &TopicSelectorStore{}) ts := make([]string, topics) tsMatch := make([]string, topics) tsNoMatch := make([]string, topics) diff --git a/subscriber_test.go b/subscriber_test.go index 7c324b5f..b3fe3fff 100644 --- a/subscriber_test.go +++ b/subscriber_test.go @@ -9,7 +9,7 @@ import ( ) func TestDispatch(t *testing.T) { - s := NewSubscriber("1", zap.NewNop(), &TopicSelectorStore{}) + s := NewLocalSubscriber("1", zap.NewNop(), &TopicSelectorStore{}) s.SubscribedTopics = []string{"http://example.com"} s.SubscribedTopics = []string{"http://example.com"} defer s.Disconnect() @@ -32,7 +32,7 @@ func TestDispatch(t *testing.T) { } func TestDisconnect(t *testing.T) { - s := NewSubscriber("", zap.NewNop(), &TopicSelectorStore{}) + s := NewLocalSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.Disconnect() // can be called two times without crashing s.Disconnect() @@ -44,7 +44,7 @@ func TestLogSubscriber(t *testing.T) { sink, logger := newTestLogger(t) defer sink.Reset() - s := NewSubscriber("123", logger, &TopicSelectorStore{}) + s := NewLocalSubscriber("123", logger, &TopicSelectorStore{}) s.RemoteAddr = "127.0.0.1" s.SetTopics([]string{"https://example.com/bar"}, []string{"https://example.com/foo"}) @@ -59,7 +59,7 @@ func TestLogSubscriber(t *testing.T) { } func TestMatchTopic(t *testing.T) { - s := NewSubscriber("", zap.NewNop(), &TopicSelectorStore{}) + s := NewLocalSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.SetTopics([]string{"https://example.com/no-match", "https://example.com/books/{id}"}, []string{"https://example.com/users/foo/{?topic}"}) assert.False(t, s.Match(&Update{Topics: []string{"https://example.com/not-subscribed"}})) @@ -73,7 +73,7 @@ func TestMatchTopic(t *testing.T) { } func TestSubscriberDoesNotBlockWhenChanIsFull(t *testing.T) { - s := NewSubscriber("", zap.NewNop(), &TopicSelectorStore{}) + s := NewLocalSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.Ready() for i := 0; i <= outBufferLength; i++ { diff --git a/subscriberlist.go b/subscriberlist.go index 97221ab1..57ef57dc 100644 --- a/subscriberlist.go +++ b/subscriberlist.go @@ -26,7 +26,7 @@ var replacer = strings.NewReplacer( func NewSubscriberList(size int) *SubscriberList { return &SubscriberList{ skipfilter: skipfilter.New(func(s interface{}, filter interface{}) bool { - return s.(*Subscriber).MatchTopics(decode(filter.(string))) + return s.(*LocalSubscriber).MatchTopics(decode(filter.(string))) }, size), } } @@ -89,25 +89,25 @@ func decode(f string) (topics []string, private bool) { return topics, private } -func (sl *SubscriberList) MatchAny(u *Update) (res []*Subscriber) { +func (sl *SubscriberList) MatchAny(u *Update) (res []*LocalSubscriber) { for _, m := range sl.skipfilter.MatchAny(encode(u.Topics, u.Private)) { - res = append(res, m.(*Subscriber)) + res = append(res, m.(*LocalSubscriber)) } return } -func (sl *SubscriberList) Walk(start uint64, callback func(s *Subscriber) bool) uint64 { +func (sl *SubscriberList) Walk(start uint64, callback func(s *LocalSubscriber) bool) uint64 { return sl.skipfilter.Walk(start, func(val interface{}) bool { - return callback(val.(*Subscriber)) + return callback(val.(*LocalSubscriber)) }) } -func (sl *SubscriberList) Add(s *Subscriber) { +func (sl *SubscriberList) Add(s *LocalSubscriber) { sl.skipfilter.Add(s) } -func (sl *SubscriberList) Remove(s *Subscriber) { +func (sl *SubscriberList) Remove(s *LocalSubscriber) { sl.skipfilter.Remove(s) } diff --git a/subscriberlist_test.go b/subscriberlist_test.go index 0c25b5ed..5cd6a255 100644 --- a/subscriberlist_test.go +++ b/subscriberlist_test.go @@ -26,7 +26,7 @@ func BenchmarkSubscriberList(b *testing.B) { l := NewSubscriberList(100) for i := 0; i < 100; i++ { - s := NewSubscriber("", logger, tss) + s := NewLocalSubscriber("", logger, tss) t := fmt.Sprintf("https://example.com/%d", i%10) s.SetTopics([]string{"https://example.org/foo", t}, []string{"https://example.net/bar", t}) diff --git a/subscription_test.go b/subscription_test.go index 13363b8a..25334c01 100644 --- a/subscription_test.go +++ b/subscription_test.go @@ -87,11 +87,11 @@ func TestSubscriptionsHandler(t *testing.T) { hub := createDummy(WithLogger(logger)) tss := &TopicSelectorStore{} - s1 := NewSubscriber("", logger, tss) + s1 := NewLocalSubscriber("", logger, tss) s1.SetTopics([]string{"http://example.com/foo"}, nil) require.NoError(t, hub.transport.AddSubscriber(s1)) - s2 := NewSubscriber("", logger, tss) + s2 := NewLocalSubscriber("", logger, tss) s2.SetTopics([]string{"http://example.com/bar"}, nil) require.NoError(t, hub.transport.AddSubscriber(s2)) @@ -128,11 +128,11 @@ func TestSubscriptionsHandlerForTopic(t *testing.T) { hub := createDummy(WithLogger(logger)) tss := &TopicSelectorStore{} - s1 := NewSubscriber("", logger, tss) + s1 := NewLocalSubscriber("", logger, tss) s1.SetTopics([]string{"http://example.com/foo"}, nil) require.NoError(t, hub.transport.AddSubscriber(s1)) - s2 := NewSubscriber("", logger, tss) + s2 := NewLocalSubscriber("", logger, tss) s2.SetTopics([]string{"http://example.com/bar"}, nil) require.NoError(t, hub.transport.AddSubscriber(s2)) @@ -175,11 +175,11 @@ func TestSubscriptionHandler(t *testing.T) { hub := createDummy(WithLogger(logger)) tss := &TopicSelectorStore{} - otherS := NewSubscriber("", logger, tss) + otherS := NewLocalSubscriber("", logger, tss) otherS.SetTopics([]string{"http://example.com/other"}, nil) require.NoError(t, hub.transport.AddSubscriber(otherS)) - s := NewSubscriber("", logger, tss) + s := NewLocalSubscriber("", logger, tss) s.SetTopics([]string{"http://example.com/other", "http://example.com/{foo}"}, nil) require.NoError(t, hub.transport.AddSubscriber(s)) diff --git a/transport.go b/transport.go index 1bb4c477..41c3d4ca 100644 --- a/transport.go +++ b/transport.go @@ -45,10 +45,10 @@ type Transport interface { Dispatch(update *Update) error // AddSubscriber adds a new subscriber to the transport. - AddSubscriber(s *Subscriber) error + AddSubscriber(s *LocalSubscriber) error // RemoveSubscriber removes a subscriber from the transport. - RemoveSubscriber(s *Subscriber) error + RemoveSubscriber(s *LocalSubscriber) error // Close closes the Transport. Close() error @@ -96,8 +96,8 @@ func (e *TransportError) Unwrap() error { } func getSubscribers(sl *SubscriberList) (subscribers []*Subscriber) { - sl.Walk(0, func(s *Subscriber) bool { - subscribers = append(subscribers, s) + sl.Walk(0, func(s *LocalSubscriber) bool { + subscribers = append(subscribers, &s.Subscriber) return true }) From 05e5ef29badc32c9fb240f3e3f09e452bdf92555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sat, 9 Nov 2024 16:07:14 +0100 Subject: [PATCH 38/71] ci: build for single target --- .github/workflows/cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 1c837d11..ccecb6b4 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -59,7 +59,7 @@ jobs: uses: goreleaser/goreleaser-action@v6 with: version: latest - args: release --clean --timeout 60m ${{ !startsWith(github.ref, 'refs/tags/v') && '--snapshot --skip=sign' || '' }} + args: ${{ startsWith(github.ref, 'refs/tags/v') && 'release' || 'build --single-target --snapshot' }} --clean --timeout 60m env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GPG_FINGERPRINT: ${{ startsWith(github.ref, 'refs/tags/v') && steps.import_gpg.outputs.fingerprint || '' }} From 0a6bd9f2b29ec59f2ef72b509316b7993caddc51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 10 Nov 2024 16:03:15 +0100 Subject: [PATCH 39/71] refactor: better infrastructure for transports as Caddy modules (#975) --- caddy/bolt.go | 8 ++++---- caddy/local.go | 10 +++++----- caddy/mercure.go | 19 +++++++++---------- caddy/transport.go | 20 +++++++++++++++----- 4 files changed, 33 insertions(+), 24 deletions(-) diff --git a/caddy/bolt.go b/caddy/bolt.go index 81ddd136..50fd235d 100644 --- a/caddy/bolt.go +++ b/caddy/bolt.go @@ -46,26 +46,26 @@ func (b *Bolt) Provision(ctx caddy.Context) error { } b.transportKey = key.String() - destructor, _, err := transport.LoadOrNew(b.transportKey, func() (caddy.Destructor, error) { + destructor, _, err := TransportUsagePool.LoadOrNew(b.transportKey, func() (caddy.Destructor, error) { t, err := mercure.NewBoltTransport(ctx.Logger(), b.Path, b.BucketName, b.Size, b.CleanupFrequency) if err != nil { return nil, err } - return transportDestructor[*mercure.BoltTransport]{transport: t}, nil + return TransportDestructor[*mercure.BoltTransport]{Transport: t}, nil }) if err != nil { return err } - b.transport = destructor.(transportDestructor[*mercure.BoltTransport]).transport + b.transport = destructor.(TransportDestructor[*mercure.BoltTransport]).Transport return nil } //nolint:wrapcheck func (b *Bolt) Cleanup() error { - _, err := transport.Delete(b.transportKey) + _, err := TransportUsagePool.Delete(b.transportKey) return err } diff --git a/caddy/local.go b/caddy/local.go index 23874b64..56de3ac5 100644 --- a/caddy/local.go +++ b/caddy/local.go @@ -30,20 +30,20 @@ func (l *Local) GetTransport() mercure.Transport { //nolint:ireturn return l.transport } -// Provision provisions b's configuration. +// Provision provisions l's configuration. func (l *Local) Provision(_ caddy.Context) error { - destructor, _, _ := transport.LoadOrNew(localTransportKey, func() (caddy.Destructor, error) { - return transportDestructor[*mercure.LocalTransport]{transport: mercure.NewLocalTransport()}, nil + destructor, _, _ := TransportUsagePool.LoadOrNew(localTransportKey, func() (caddy.Destructor, error) { + return TransportDestructor[*mercure.LocalTransport]{Transport: mercure.NewLocalTransport()}, nil }) - l.transport = destructor.(transportDestructor[*mercure.LocalTransport]).transport + l.transport = destructor.(TransportDestructor[*mercure.LocalTransport]).Transport return nil } //nolint:wrapcheck func (l *Local) Cleanup() error { - _, err := transport.Delete(localTransportKey) + _, err := TransportUsagePool.Delete(localTransportKey) return err } diff --git a/caddy/mercure.go b/caddy/mercure.go index 864fe995..304869f2 100644 --- a/caddy/mercure.go +++ b/caddy/mercure.go @@ -178,13 +178,13 @@ func createTransportLegacy(m *Mercure) (mercure.Transport, error) { return nil, err } - return &transportDestructor[mercure.Transport]{transport}, nil + return &TransportDestructor[mercure.Transport]{transport}, nil }) if err != nil { return nil, err } - return destructor.(*transportDestructor[mercure.Transport]).transport, nil + return destructor.(*TransportDestructor[mercure.Transport]).Transport, nil } //nolint:wrapcheck @@ -203,6 +203,9 @@ func (m *Mercure) Provision(ctx caddy.Context) error { //nolint:funlen,gocognit return err } + ctx = ctx.WithValue(SubscriptionsContextKey, m.Subscriptions) + ctx = ctx.WithValue(WriteTimeoutContextKey, m.WriteTimeout) + m.logger = ctx.Logger() var transport mercure.Transport @@ -411,21 +414,17 @@ func (m *Mercure) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { //nolint:fu } case "publish_origins": - ra := d.RemainingArgs() - if len(ra) == 0 { + m.PublishOrigins = d.RemainingArgs() + if len(m.PublishOrigins) == 0 { return d.ArgErr() } - m.PublishOrigins = ra - case "cors_origins": - ra := d.RemainingArgs() - if len(ra) == 0 { + m.CORSOrigins = d.RemainingArgs() + if len(m.CORSOrigins) == 0 { return d.ArgErr() } - m.CORSOrigins = ra - case "transport": if !d.NextArg() { return d.ArgErr() diff --git a/caddy/transport.go b/caddy/transport.go index 8a33559f..a1f7b946 100644 --- a/caddy/transport.go +++ b/caddy/transport.go @@ -5,16 +5,26 @@ import ( "github.com/dunglas/mercure" ) -var transport = caddy.NewUsagePool() //nolint:gochecknoglobals +var TransportUsagePool = caddy.NewUsagePool() //nolint:gochecknoglobals type Transport interface { GetTransport() mercure.Transport } -type transportDestructor[T mercure.Transport] struct { - transport T +type TransportDestructor[T mercure.Transport] struct { + Transport T } -func (d transportDestructor[T]) Destruct() error { - return d.transport.Close() //nolint:wrapcheck +func (d TransportDestructor[T]) Destruct() error { + return d.Transport.Close() //nolint:wrapcheck } + +type ( + subscriptionsKeyType struct{} + writeTimeoutKeyType struct{} +) + +var ( + SubscriptionsContextKey = subscriptionsKeyType{} //nolint:gochecknoglobals + WriteTimeoutContextKey = writeTimeoutKeyType{} //nolint:gochecknoglobals +) From 59c8e6c44700a336d41126f53d0577660c7d610c Mon Sep 17 00:00:00 2001 From: Ernesto Serrano Date: Sun, 10 Nov 2024 16:21:18 +0100 Subject: [PATCH 40/71] ci: build deb, rpm and apk packages (#973) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kévin Dunglas --- .goreleaser.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index 104e4f60..a6d8b7c4 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -152,6 +152,22 @@ docker_manifests: image_templates: - dunglas/mercure:latest-amd64 - dunglas/mercure:latest-arm64v8 +nfpms: + - id: linux_packages + package_name: mercure + file_name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }}.{{ .Format }}" + builds: + - caddy + formats: + - apk + - deb + - rpm + maintainer: "Kévin Dunglas " + description: "An open, easy, fast, reliable and battery-efficient solution for real-time communications." + license: "AGPL-3.0-or-later" + vendor: "Dunglas Services SAS" + homepage: "https://mercure.rocks" + bindir: /usr/bin signs: - artifacts: checksum args: From 255e63bc09258730b28d803f95584720266267d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 10 Nov 2024 16:00:09 +0100 Subject: [PATCH 41/71] chore: fix Caddyfile indentation --- Caddyfile | 16 ++++++++-------- dev.Caddyfile | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Caddyfile b/Caddyfile index f93379d3..09d4f7e9 100644 --- a/Caddyfile +++ b/Caddyfile @@ -35,15 +35,15 @@ header / Content-Type "text/html; charset=utf-8" respond / ` - - - -Welcome to Mercure -

Welcome to Mercure

-

The URL of your hub is /.well-known/mercure. -Read the documentation on Mercure.rocks, real-time apps made easy.` + + + + Welcome to Mercure +

Welcome to Mercure

+

The URL of your hub is /.well-known/mercure. + Read the documentation on Mercure.rocks, real-time apps made easy.` respond /robots.txt `User-agent: * -Disallow: /` + Disallow: /` respond /healthz 200 respond "Not Found" 404 } diff --git a/dev.Caddyfile b/dev.Caddyfile index c4dff9ec..de5ef8c1 100644 --- a/dev.Caddyfile +++ b/dev.Caddyfile @@ -39,6 +39,6 @@ respond /healthz 200 respond /robots.txt `User-agent: * -Disallow: /` + Disallow: /` respond "Not Found" 404 } From cbec56f7d28ec9daaff331e69e186fe242b77dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 10 Nov 2024 19:31:07 +0100 Subject: [PATCH 42/71] chore: prepare release 0.17.0 --- caddy/go.mod | 2 +- charts/mercure/Chart.yaml | 4 +- charts/mercure/README.md | 15 +++- .../chat/chart/mercure-example-chat/README.md | 71 +++++++++---------- 4 files changed, 50 insertions(+), 42 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index 4cc6c23c..b1a798c2 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -14,7 +14,7 @@ replace github.com/dunglas/mercure => ../ require ( github.com/MicahParks/keyfunc/v3 v3.3.5 github.com/caddyserver/caddy/v2 v2.8.4 - github.com/dunglas/mercure v0.16.3 + github.com/dunglas/mercure v0.17.0 github.com/prometheus/client_golang v1.20.5 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 diff --git a/charts/mercure/Chart.yaml b/charts/mercure/Chart.yaml index dbbd25dd..3d6c3748 100644 --- a/charts/mercure/Chart.yaml +++ b/charts/mercure/Chart.yaml @@ -12,8 +12,8 @@ keywords: - streaming-api - async-api type: application -version: 0.16.3 -appVersion: "v0.16.3" +version: 0.17.0 +appVersion: "v0.17.0" maintainers: - name: dunglas email: kevin@dunglas.fr diff --git a/charts/mercure/README.md b/charts/mercure/README.md index 157074bb..a00f3865 100644 --- a/charts/mercure/README.md +++ b/charts/mercure/README.md @@ -1,7 +1,7 @@ # Mercure Chart for Kubernetes -![Version: 0.16.3](https://img.shields.io/badge/Version-0.16.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.16.3](https://img.shields.io/badge/AppVersion-v0.16.3-informational?style=flat-square) +![Version: 0.17.0](https://img.shields.io/badge/Version-0.17.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.17.0](https://img.shields.io/badge/AppVersion-v0.17.0-informational?style=flat-square) A Helm chart to install a Mercure Hub in a Kubernetes cluster. Mercure is a protocol to push data updates to web browsers and other HTTP clients in a convenient, fast, reliable and battery-efficient way. @@ -25,6 +25,7 @@ To install the chart with the release name `my-release`, run the following comma | dev | bool | `false` | Enable the development mode, including the debug UI and the demo. | | existingSecret | string | `""` | Allows to pass an existing secret name, the above values will be used if empty. | | extraDirectives | string | `""` | Inject extra Mercure directives in the Caddyfile. | +| extraEnvs | list | `[]` | Additional environment variables to set | | fullnameOverride | string | `""` | A name to substitute for the full names of resources. | | globalOptions | string | `""` | Inject global options in the Caddyfile. | | image.pullPolicy | string | `"IfNotPresent"` | [Image pull policy](https://kubernetes.io/docs/concepts/containers/images/#updating-images) for updating already existing images on a node. | @@ -37,6 +38,14 @@ To install the chart with the release name `my-release`, run the following comma | ingress.hosts | list | See [values.yaml](values.yaml). | Ingress host configuration. | | ingress.tls | list | See [values.yaml](values.yaml). | Ingress TLS configuration. | | license | string | `""` | The license key for [the High Availability version](https://mercure.rocks/docs/hub/cluster) (not necessary is you use the FOSS version). | +| metrics.enabled | bool | `false` | Enable metrics. You must also add a `servers` block with a [`metrics` directive](https://caddyserver.com/docs/caddyfile/options#metrics) in the `globalOptions` value. servers { metrics } | +| metrics.port | int | `2019` | The port to use for exposing the metrics. | +| metrics.serviceMonitor.enabled | bool | `false` | Whether to create a ServiceMonitor for Prometheus Operator. | +| metrics.serviceMonitor.honorLabels | bool | `false` | Specify honorLabels parameter to add the scrape endpoint | +| metrics.serviceMonitor.interval | string | `"15s"` | The interval to use for the ServiceMonitor to scrape the metrics. | +| metrics.serviceMonitor.relabelings | list | `[]` | RelabelConfigs to apply to samples before scraping | +| metrics.serviceMonitor.scrapeTimeout | string | `""` | Timeout after which the scrape is ended | +| metrics.serviceMonitor.selector | object | `{}` | Additional labels that can be used so ServiceMonitor will be discovered by Prometheus | | nameOverride | string | `""` | A name in place of the chart name for `app:` labels. | | nodeSelector | object | `{}` | [Node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) configuration. | | persistence | object | `{"accessMode":"ReadWriteOnce","enabled":false,"existingClaim":"","size":"1Gi","storageClass":""}` | Enable persistence using [Persistent Volume Claims](http://kubernetes.io/docs/user-guide/persistent-volumes/), only useful if you the BoltDB transport. | @@ -51,8 +60,8 @@ To install the chart with the release name `my-release`, run the following comma | resources | object | No requests or limits. | Container resource [requests and limits](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) for details. | | securityContext | object | `{}` | Container [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container). See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) for details. | | service.annotations | object | `{}` | | +| service.nodePort | string | `nil` | Set this, to pin the external nodePort in case `service.type` is `NodePort`. | | service.port | int | `80` | Service port. | -| service.nodePort | int | 0 | The exposed nodePort. Required when `service.type` is [`"NodePort"`](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport). | | service.targetPort | int | `80` | Service target port. | | service.type | string | `"ClusterIP"` | Kubernetes [service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types). | | serviceAccount.annotations | object | `{}` | Annotations to add to the service account. | @@ -61,5 +70,5 @@ To install the chart with the release name `my-release`, run the following comma | subscriberJwtAlg | string | `"HS256"` | The JWT algorithm to use for subscribers. | | subscriberJwtKey | string | `""` | The JWT key to use for subscribers, a random key will be generated if empty. | | tolerations | list | `[]` | [Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) for node taints. See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) for details. | -| transportUrl | string | `"bolt:///data/mercure.db"` | The URL representation of the transport to use. | +| transportUrl | string | `""` | Deprecated: The URL representation of the transport to use. | diff --git a/examples/chat/chart/mercure-example-chat/README.md b/examples/chat/chart/mercure-example-chat/README.md index 60a40953..b24dfe30 100644 --- a/examples/chat/chart/mercure-example-chat/README.md +++ b/examples/chat/chart/mercure-example-chat/README.md @@ -6,41 +6,40 @@ A minimalist chat system, using Mercure and the Flask microframework to handle c ## Values -| Key | Type | Default | Description | -| ------------------------------------------ | ------ | -------------------------------------------------- | ----------- | -| affinity | object | `{}` | | -| autoscaling.enabled | bool | `false` | | -| autoscaling.maxReplicas | int | `100` | | -| autoscaling.minReplicas | int | `1` | | -| autoscaling.targetCPUUtilizationPercentage | int | `80` | | -| cookieDomain | string | `".mercure.rocks"` | | -| fullnameOverride | string | `""` | | -| hubUrl | string | `"https://demo.mercure.rocks/.well-known/mercure"` | | -| image.pullPolicy | string | `"Always"` | | -| image.repository | string | `"dunglas/mercure-example-chat"` | | -| image.tag | string | `"latest"` | | -| imagePullSecrets | list | `[]` | | -| ingress.annotations | object | `{}` | | -| ingress.enabled | bool | `false` | | -| ingress.hosts[0].host | string | `"chart-example.local"` | | -| ingress.hosts[0].paths | list | `[]` | | -| ingress.tls | list | `[]` | | -| jwtKey | string | `"!ChangeThisMercureHubJWTSecretKey!"` | | -| messageUriTemplate | string | `"https://chat.example.com/messages/{id}"` | | -| nameOverride | string | `""` | | -| nodeSelector | object | `{}` | | -| podAnnotations | object | `{}` | | -| podSecurityContext | object | `{}` | | -| replicaCount | int | `1` | | -| resources | object | `{}` | | -| securityContext | object | `{}` | | -| service.port | int | `80` | | -| service.type | string | `"ClusterIP"` | | -| serviceAccount.annotations | object | `{}` | | -| serviceAccount.create | bool | `true` | | -| serviceAccount.name | string | `""` | | -| tolerations | list | `[]` | | - ---- +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | | +| autoscaling.enabled | bool | `false` | | +| autoscaling.maxReplicas | int | `100` | | +| autoscaling.minReplicas | int | `1` | | +| autoscaling.targetCPUUtilizationPercentage | int | `80` | | +| cookieDomain | string | `".mercure.rocks"` | | +| fullnameOverride | string | `""` | | +| hubUrl | string | `"https://demo.mercure.rocks/.well-known/mercure"` | | +| image.pullPolicy | string | `"Always"` | | +| image.repository | string | `"dunglas/mercure-example-chat"` | | +| image.tag | string | `"latest"` | | +| imagePullSecrets | list | `[]` | | +| ingress.annotations | object | `{}` | | +| ingress.enabled | bool | `false` | | +| ingress.hosts[0].host | string | `"chart-example.local"` | | +| ingress.hosts[0].paths | list | `[]` | | +| ingress.tls | list | `[]` | | +| jwtKey | string | `"!ChangeThisMercureHubJWTSecretKey!"` | | +| messageUriTemplate | string | `"https://chat.example.com/messages/{id}"` | | +| nameOverride | string | `""` | | +| nodeSelector | object | `{}` | | +| podAnnotations | object | `{}` | | +| podSecurityContext | object | `{}` | | +| replicaCount | int | `1` | | +| resources | object | `{}` | | +| securityContext | object | `{}` | | +| service.port | int | `80` | | +| service.type | string | `"ClusterIP"` | | +| serviceAccount.annotations | object | `{}` | | +| serviceAccount.create | bool | `true` | | +| serviceAccount.name | string | `""` | | +| tolerations | list | `[]` | | +---------------------------------------------- Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) From 3a6558f6b6f10c193b325f06e915c6a7d85214dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 11 Nov 2024 18:33:26 +0100 Subject: [PATCH 43/71] docs: improve upgrade instructions for 0.17 (#979) --- docs/UPGRADE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/UPGRADE.md b/docs/UPGRADE.md index cbd940e6..8df21b4c 100644 --- a/docs/UPGRADE.md +++ b/docs/UPGRADE.md @@ -22,6 +22,7 @@ After: ```caddyfile transport bolt { + path mercure.db cleanup_frequency 0.2 } ``` From d764b977b937f1a7df9e401685e3434be6c9fef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 11 Nov 2024 18:36:39 +0100 Subject: [PATCH 44/71] chore: fix golangci-lint --- .golangci.yml | 2 -- server_test.go | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 95e4715d..5085e030 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -9,7 +9,6 @@ linters: - errcheck - lll - wsl - - gomnd - testpackage - exhaustruct - paralleltest @@ -31,7 +30,6 @@ linters: - canonicalheader # deprecated - - execinquery - exportloopref issues: diff --git a/server_test.go b/server_test.go index 32685003..2c6ce778 100644 --- a/server_test.go +++ b/server_test.go @@ -8,7 +8,6 @@ import ( "net/http" "net/url" "os" - "regexp" "strings" "sync" "testing" @@ -402,7 +401,7 @@ func TestMetricsVersionIsAccessible(t *testing.T) { require.NoError(t, err) pattern := "mercure_version_info{architecture=\".+\",built_at=\".*\",commit=\".*\",go_version=\".+\",os=\".+\",version=\"dev\"} 1" - assert.Regexp(t, regexp.MustCompile(pattern), string(b)) + assert.Regexp(t, pattern, string(b)) server.assertMetric("mercure_version_info") } From f9315355486bb75021e4025fbd93217eeea74e40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 11 Nov 2024 18:44:51 +0100 Subject: [PATCH 45/71] ci: use GitHub's native changelog generator --- .goreleaser.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index a6d8b7c4..3eb4ca7c 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -7,17 +7,10 @@ checksum: snapshot: version_template: "{{ incpatch .Version }}-next" changelog: - sort: asc - filters: - exclude: - - "^docs:" - - "^test:" - - "^ci:" - - "^build:" - - "^chore:" - - "^Merge" + use: github-native release: prerelease: auto + draft: true env: - CGO_ENABLED=0 builds: From e5d342d54967f75a0516ecfccb1475e389300681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 11 Nov 2024 18:29:51 +0100 Subject: [PATCH 46/71] chore: bump deps and downgrade Ristretto --- caddy/go.mod | 59 ++++++++++++++------------- caddy/go.sum | 113 +++++++++++++++++++++++++++------------------------ go.mod | 12 +++--- go.sum | 28 ++++++------- 4 files changed, 110 insertions(+), 102 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index b1a798c2..a5c614f9 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -21,6 +21,7 @@ require ( ) require ( + cel.dev/expr v0.18.0 // indirect dario.cat/mergo v1.0.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect @@ -36,7 +37,7 @@ require ( github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.14.3 // indirect + github.com/bits-and-blooms/bitset v1.15.0 // indirect github.com/caddyserver/certmagic v0.21.4 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect @@ -48,7 +49,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect - github.com/dgraph-io/ristretto v1.0.0 // indirect + github.com/dgraph-io/ristretto v0.2.0 // indirect github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da // indirect github.com/dlclark/regexp2 v1.11.4 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -66,7 +67,7 @@ require ( github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/cel-go v0.21.0 // indirect + github.com/google/cel-go v0.22.0 // indirect github.com/google/certificate-transparency-go v1.2.2 // indirect github.com/google/go-tpm v0.9.1 // indirect github.com/google/go-tspi v0.3.0 // indirect @@ -85,7 +86,7 @@ require ( github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/kevburnsjr/skipfilter v0.0.1 // indirect github.com/klauspost/compress v1.17.11 // indirect - github.com/klauspost/cpuid/v2 v2.2.8 // indirect + github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/libdns/libdns v0.2.2 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/manifoldco/promptui v0.9.0 // indirect @@ -142,18 +143,18 @@ require ( github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc // indirect github.com/zeebo/blake3 v0.2.4 // indirect go.etcd.io/bbolt v1.3.11 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect - go.opentelemetry.io/contrib/propagators/autoprop v0.56.0 // indirect - go.opentelemetry.io/contrib/propagators/aws v1.31.0 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.31.0 // indirect - go.opentelemetry.io/contrib/propagators/jaeger v1.31.0 // indirect - go.opentelemetry.io/contrib/propagators/ot v1.31.0 // indirect - go.opentelemetry.io/otel v1.31.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 // indirect - go.opentelemetry.io/otel/metric v1.31.0 // indirect - go.opentelemetry.io/otel/sdk v1.31.0 // indirect - go.opentelemetry.io/otel/trace v1.31.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 // indirect + go.opentelemetry.io/contrib/propagators/autoprop v0.57.0 // indirect + go.opentelemetry.io/contrib/propagators/aws v1.32.0 // indirect + go.opentelemetry.io/contrib/propagators/b3 v1.32.0 // indirect + go.opentelemetry.io/contrib/propagators/jaeger v1.32.0 // indirect + go.opentelemetry.io/contrib/propagators/ot v1.32.0 // indirect + go.opentelemetry.io/otel v1.32.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 // indirect + go.opentelemetry.io/otel/metric v1.32.0 // indirect + go.opentelemetry.io/otel/sdk v1.32.0 // indirect + go.opentelemetry.io/otel/trace v1.32.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.step.sm/crypto v0.54.0 // indirect go.step.sm/linkedca v0.22.2 // indirect @@ -161,21 +162,21 @@ require ( go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap/exp v0.2.0 // indirect - golang.org/x/crypto v0.28.0 // indirect - golang.org/x/crypto/x509roots/fallback v0.0.0-20241104001025-71ed71b4faf9 // indirect - golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect - golang.org/x/mod v0.21.0 // indirect - golang.org/x/net v0.30.0 // indirect - golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/term v0.25.0 // indirect - golang.org/x/text v0.19.0 // indirect - golang.org/x/time v0.7.0 // indirect - golang.org/x/tools v0.26.0 // indirect + golang.org/x/crypto v0.29.0 // indirect + golang.org/x/crypto/x509roots/fallback v0.0.0-20241107225453-6018723c7405 // indirect + golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/net v0.31.0 // indirect + golang.org/x/oauth2 v0.24.0 // indirect + golang.org/x/sync v0.9.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/term v0.26.0 // indirect + golang.org/x/text v0.20.0 // indirect + golang.org/x/time v0.8.0 // indirect + golang.org/x/tools v0.27.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect - google.golang.org/grpc v1.67.1 // indirect + google.golang.org/grpc v1.68.0 // indirect google.golang.org/protobuf v1.35.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect diff --git a/caddy/go.sum b/caddy/go.sum index be2e2d0a..15e8de57 100644 --- a/caddy/go.sum +++ b/caddy/go.sum @@ -1,3 +1,5 @@ +cel.dev/expr v0.18.0 h1:CJ6drgk+Hf96lkLikr4rFf19WrU0BOWEihyZnI2TAzo= +cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= cloud.google.com/go/auth v0.9.9 h1:BmtbpNQozo8ZwW2t7QJjnrQtdganSdmqeIBxHxNkEZQ= @@ -88,8 +90,8 @@ 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/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/bits-and-blooms/bitset v1.14.3 h1:Gd2c8lSNf9pKXom5JtD7AaKO8o7fGQ2LtFj1436qilA= -github.com/bits-and-blooms/bitset v1.14.3/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.15.0 h1:DiCRMscZsGyYePE9AR3sVhKqUXCt5IZvkX5AfAc5xLQ= +github.com/bits-and-blooms/bitset v1.15.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/caddyserver/caddy/v2 v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk= github.com/caddyserver/caddy/v2 v2.8.4/go.mod h1:vmDAHp3d05JIvuhc24LmnxVlsZmWnUwbP5WMjzcMPWw= github.com/caddyserver/certmagic v0.21.4 h1:e7VobB8rffHv8ZZpSiZtEwnLDHUwLVYLWzWSa1FfKI0= @@ -130,8 +132,8 @@ github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdw github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v1.0.0 h1:SYG07bONKMlFDUYu5pEu3DGAh8c2OFNzKm6G9J4Si84= -github.com/dgraph-io/ristretto v1.0.0/go.mod h1:jTi2FiYEhQ1NsMmA7DeBykizjOuY88NhKBkepyu1jPc= +github.com/dgraph-io/ristretto v0.2.0 h1:XAfl+7cmoUDWW/2Lx8TGZQjjxIQ2Ley9DSf52dru4WE= +github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38= github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= @@ -180,8 +182,8 @@ github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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/cel-go v0.21.0 h1:cl6uW/gxN+Hy50tNYvI691+sXxioCnstFzLp2WO4GCI= -github.com/google/cel-go v0.21.0/go.mod h1:rHUlWCcBKgyEk+eV03RPdZUekPp6YcJwV0FxuUksYxc= +github.com/google/cel-go v0.22.0 h1:b3FJZxpiv1vTMo2/5RDUqAHPxkT8mmMfJIrq1llbf7g= +github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8= github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/certificate-transparency-go v1.2.2 h1:5TAzjQnCfN1vps2XWUgU6Svt++rgy9a+b8CBYXaKUAo= github.com/google/certificate-transparency-go v1.2.2/go.mod h1:d1o5XNQzK/yz8IXzEce6KXgMxfter/EcMP9vG4dBRNE= @@ -236,8 +238,8 @@ github.com/kevburnsjr/skipfilter v0.0.1/go.mod h1:jfaRyFOYVUtIa6IIC+0mB1qiZqhHw+ github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= -github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= -github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= +github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= 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= @@ -419,30 +421,30 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= 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/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= -go.opentelemetry.io/contrib/propagators/autoprop v0.56.0 h1:FtwGTy9ka2eBVnBotuligqO2V+il+Hp74APIJsWNbd8= -go.opentelemetry.io/contrib/propagators/autoprop v0.56.0/go.mod h1:XzSaHSuUiWveyQwmofA3IEK23+SpzfSEcVZXpqfBh+E= -go.opentelemetry.io/contrib/propagators/aws v1.31.0 h1:OJHDboLd4zH1j0UrxoQbSDPEykmBJ/epVa/v+fRCRi0= -go.opentelemetry.io/contrib/propagators/aws v1.31.0/go.mod h1:mtT7x7gY+jL4fH34l8dkZeo6Jvf+3Fy002rjuEdRnTM= -go.opentelemetry.io/contrib/propagators/b3 v1.31.0 h1:PQPXYscmwbCp76QDvO4hMngF2j8Bx/OTV86laEl8uqo= -go.opentelemetry.io/contrib/propagators/b3 v1.31.0/go.mod h1:jbqfV8wDdqSDrAYxVpXQnpM0XFMq2FtDesblJ7blOwQ= -go.opentelemetry.io/contrib/propagators/jaeger v1.31.0 h1:k9P5RQEWIKUP6N18/ouSvPD/uTjc7s+8WPnuVK6lWOI= -go.opentelemetry.io/contrib/propagators/jaeger v1.31.0/go.mod h1:OpgiBRssaVKOTM5lSKkOBIGQh/ixvfZRmxQXARK/kGQ= -go.opentelemetry.io/contrib/propagators/ot v1.31.0 h1:PtlNuoEn5sa2Mfz1Jb+NhOVgT4SjAw90XmziOloj87E= -go.opentelemetry.io/contrib/propagators/ot v1.31.0/go.mod h1:5W00bdNbK3dCy/Eqxgi1nLq4qYbAekf7b7IGETqZgVE= -go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= -go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 h1:FFeLy03iVTXP6ffeN2iXrxfGsZGCjVx0/4KlizjyBwU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0/go.mod h1:TMu73/k1CP8nBUpDLc71Wj/Kf7ZS9FK5b53VapRsP9o= -go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= -go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= -go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= -go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= -go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= -go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 h1:DheMAlT6POBP+gh8RUH19EOTnQIor5QE0uSRPtzCpSw= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0/go.mod h1:wZcGmeVO9nzP67aYSLDqXNWK87EZWhi7JWj1v7ZXf94= +go.opentelemetry.io/contrib/propagators/autoprop v0.57.0 h1:bNPJOdT5154XxzeFmrh8R+PXnV4t3TZEczy8gHEpcpg= +go.opentelemetry.io/contrib/propagators/autoprop v0.57.0/go.mod h1:Tb0j0mK+QatKdCxCKPN7CSzc7kx/q34/KaohJx/N96s= +go.opentelemetry.io/contrib/propagators/aws v1.32.0 h1:NELzr8bW7a7aHVZj5gaep1PfkvoSCGx+1qNGZx/uhhU= +go.opentelemetry.io/contrib/propagators/aws v1.32.0/go.mod h1:XKMrzHNka3eOA+nGEcNKYVL9s77TAhkwQEynYuaRFnQ= +go.opentelemetry.io/contrib/propagators/b3 v1.32.0 h1:MazJBz2Zf6HTN/nK/s3Ru1qme+VhWU5hm83QxEP+dvw= +go.opentelemetry.io/contrib/propagators/b3 v1.32.0/go.mod h1:B0s70QHYPrJwPOwD1o3V/R8vETNOG9N3qZf4LDYvA30= +go.opentelemetry.io/contrib/propagators/jaeger v1.32.0 h1:K/fOyTMD6GELKTIJBaJ9k3ppF2Njt8MeUGBOwfaWXXA= +go.opentelemetry.io/contrib/propagators/jaeger v1.32.0/go.mod h1:ISE6hda//MTWvtngG7p4et3OCngsrTVfl7c6DjN17f8= +go.opentelemetry.io/contrib/propagators/ot v1.32.0 h1:Poy02A4wOZubHyd2hpHPDgZW+rn6EIq0vCwTZJ6Lmu8= +go.opentelemetry.io/contrib/propagators/ot v1.32.0/go.mod h1:cbhaURV+VR3NIMarzDYZU1RDEkXG1fNd1WMP1XCcGkY= +go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= +go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 h1:IJFEoHiytixx8cMiVAO+GmHR6Frwu+u5Ur8njpFO6Ac= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0/go.mod h1:3rHrKNtLIoS0oZwkY2vxi+oJcwFRWdtUyRII+so45p8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 h1:9kV11HXBHZAvuPUZxmMWrH8hZn/6UnHX4K0mu36vNsU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0/go.mod h1:JyA0FHXe22E1NeNiHmVp7kFHglnexDQ7uRWDiiJ1hKQ= +go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= +go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= +go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= +go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= +go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= +go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.step.sm/crypto v0.54.0 h1:V8p+12Ld0NRA/RBMYoKXA0dWmVKZSdCwP56IwzweT9g= @@ -468,19 +470,20 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/crypto/x509roots/fallback v0.0.0-20241104001025-71ed71b4faf9 h1:4cEcP5+OjGppY79LCQ5Go2B1Boix2x0v6pvA01P3FoA= -golang.org/x/crypto/x509roots/fallback v0.0.0-20241104001025-71ed71b4faf9/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= -golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= -golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/crypto/x509roots/fallback v0.0.0-20241107225453-6018723c7405 h1:VAHMMzTf+Febj933dn5dxsbBHAHHqCv0fJj3UFB7PZM= +golang.org/x/crypto/x509roots/fallback v0.0.0-20241107225453-6018723c7405/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -489,18 +492,19 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= -golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= -golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= -golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= +golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -520,8 +524,9 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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= @@ -531,8 +536,9 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= -golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= +golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -542,18 +548,19 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= -golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= +golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= -golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= +golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= +golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.203.0 h1:SrEeuwU3S11Wlscsn+LA1kb/Y5xT8uggJSkIhD08NAU= google.golang.org/api v0.203.0/go.mod h1:BuOVyCSYEPwJb3npWvDnNmFI92f3GeRnHNkETneT3SI= @@ -563,8 +570,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1: google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4= google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= +google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/go.mod b/go.mod index f7890a37..0d0654e6 100644 --- a/go.mod +++ b/go.mod @@ -26,14 +26,14 @@ require ( github.com/yosida95/uritemplate/v3 v3.0.2 go.etcd.io/bbolt v1.3.11 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.28.0 + golang.org/x/crypto v0.29.0 ) require ( github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145 // indirect github.com/RoaringBitmap/roaring v1.9.4 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.14.3 // indirect + github.com/bits-and-blooms/bitset v1.15.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -56,10 +56,10 @@ require ( github.com/spf13/cast v1.7.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect - golang.org/x/net v0.30.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect + golang.org/x/net v0.31.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/text v0.20.0 // indirect google.golang.org/protobuf v1.35.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 7d5e3dd1..6b4b6cbb 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,8 @@ 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/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/bits-and-blooms/bitset v1.14.3 h1:Gd2c8lSNf9pKXom5JtD7AaKO8o7fGQ2LtFj1436qilA= -github.com/bits-and-blooms/bitset v1.14.3/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.15.0 h1:DiCRMscZsGyYePE9AR3sVhKqUXCt5IZvkX5AfAc5xLQ= +github.com/bits-and-blooms/bitset v1.15.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= 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/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -109,18 +109,18 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= -golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= -golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= -golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 0e9cc025495dfef52e0fc2fb72ef99279a6434b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 11 Nov 2024 18:47:29 +0100 Subject: [PATCH 47/71] chore: prepare release 0.17.1 --- caddy/go.mod | 2 +- charts/mercure/Chart.yaml | 4 ++-- charts/mercure/README.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index a5c614f9..eba408fa 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -14,7 +14,7 @@ replace github.com/dunglas/mercure => ../ require ( github.com/MicahParks/keyfunc/v3 v3.3.5 github.com/caddyserver/caddy/v2 v2.8.4 - github.com/dunglas/mercure v0.17.0 + github.com/dunglas/mercure v0.17.1 github.com/prometheus/client_golang v1.20.5 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 diff --git a/charts/mercure/Chart.yaml b/charts/mercure/Chart.yaml index 3d6c3748..59bc02f9 100644 --- a/charts/mercure/Chart.yaml +++ b/charts/mercure/Chart.yaml @@ -12,8 +12,8 @@ keywords: - streaming-api - async-api type: application -version: 0.17.0 -appVersion: "v0.17.0" +version: 0.17.1 +appVersion: "v0.17.1" maintainers: - name: dunglas email: kevin@dunglas.fr diff --git a/charts/mercure/README.md b/charts/mercure/README.md index a00f3865..af8652e9 100644 --- a/charts/mercure/README.md +++ b/charts/mercure/README.md @@ -1,7 +1,7 @@ # Mercure Chart for Kubernetes -![Version: 0.17.0](https://img.shields.io/badge/Version-0.17.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.17.0](https://img.shields.io/badge/AppVersion-v0.17.0-informational?style=flat-square) +![Version: 0.17.1](https://img.shields.io/badge/Version-0.17.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.17.1](https://img.shields.io/badge/AppVersion-v0.17.1-informational?style=flat-square) A Helm chart to install a Mercure Hub in a Kubernetes cluster. Mercure is a protocol to push data updates to web browsers and other HTTP clients in a convenient, fast, reliable and battery-efficient way. From d8e07b20c658a0934e9c801ccb6c32c4ea1169b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 25 Nov 2024 19:43:39 +0100 Subject: [PATCH 48/71] fix: log messages for subscribers --- subscribe.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subscribe.go b/subscribe.go index 86499b61..a8f45b7a 100644 --- a/subscribe.go +++ b/subscribe.go @@ -170,7 +170,7 @@ func (h *Hub) registerSubscriber(w http.ResponseWriter, r *http.Request) (*Local } if err != nil || (claims == nil && !h.anonymous) { http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) - if c := h.logger.Check(zap.DebugLevel, "LocalSubscriber unauthorized"); c != nil { + if c := h.logger.Check(zap.DebugLevel, "Subscriber unauthorized"); c != nil { c.Write(zap.Object("subscriber", s), zap.Error(err)) } @@ -297,7 +297,7 @@ func (h *Hub) shutdown(s *LocalSubscriber) { } h.dispatchSubscriptionUpdate(s, false) - if c := h.logger.Check(zap.InfoLevel, "LocalSubscriber disconnected"); c != nil { + if c := h.logger.Check(zap.InfoLevel, "Subscriber disconnected"); c != nil { c.Write(zap.Object("subscriber", s)) } h.metrics.SubscriberDisconnected(s) From 0019f6fc34a877934ff21276a45e92941cdc4478 Mon Sep 17 00:00:00 2001 From: Pauline Vos Date: Thu, 26 Dec 2024 08:38:53 +0100 Subject: [PATCH 49/71] docs: mention dev.Caddyfile file change in docs (#993) Users on Docker images older than v0.16.2 may be confused when they run the container, as the file `dev.Caddyfile` doesn't exist on those containers (v0.16.2 changed it from `Caddyfile.dev` to `dev.Caddyfile`) Co-authored-by: Pauline Vos --- docs/hub/install.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/hub/install.md b/docs/hub/install.md index e1b292ec..9885a7e3 100644 --- a/docs/hub/install.md +++ b/docs/hub/install.md @@ -67,6 +67,7 @@ docker run \ -p 443:443 \ dunglas/mercure caddy run --config /etc/caddy/dev.Caddyfile ``` +_Note:_ Docker images before tag v0.16.2 use **Caddyfile.dev** instead of dev.Caddyfile The server is then available on `https://localhost`. Anonymous subscribers are allowed and the debugger UI is available on `https://localhost/.well-known/mercure/ui/`. From 9a8d1543825ffc74831225a11e67203ff524bcef Mon Sep 17 00:00:00 2001 From: Mathieu Santostefano Date: Sun, 29 Dec 2024 17:26:36 +0100 Subject: [PATCH 50/71] docs: fix Stackhero docs link (#995) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix Stackhero documentation link cc @Bacto * Update awesome.md --------- Co-authored-by: Kévin Dunglas --- docs/ecosystem/awesome.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ecosystem/awesome.md b/docs/ecosystem/awesome.md index 5bcfe131..7f20bfba 100644 --- a/docs/ecosystem/awesome.md +++ b/docs/ecosystem/awesome.md @@ -70,7 +70,7 @@ - [Official Push and Real-Time Capabilities for Symfony and API Platform using Mercure (Symfony blog)](https://dunglas.fr/2019/03/official-push-and-real-time-capabilities-for-symfony-and-api-platform-mercure-protocol/) - [Tech Workshop: Mercure by Kévin Dunglas at SensioLabs (SensioLabs)](https://blog.sensiolabs.com/2019/01/24/tech-workshop-mercure-kevin-dunglas-sensiolabs/) - [Real-time messages with Mercure using Laravel](http://thedevopsguide.com/real-time-notifications-with-mercure/) -- [Using Mercure on Stackhero](https://www.stackhero.io/en/documentations/mercure-hub/getting-started) +- [Using Mercure on Stackhero](https://www.stackhero.io/services/Mercure-Hub/documentations) - [Mercure - install and run](https://mysiar.github.io/dev/2020/04/12/mercure-part1.html) ### French 🇫🇷 From 540cdb412c81c55a979c4ef1bf91f1ffacf09b9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 04:00:54 +0000 Subject: [PATCH 51/71] ci: bump actions/attest-build-provenance from 1 to 2 Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 1 to 2. - [Release notes](https://github.com/actions/attest-build-provenance/releases) - [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md) - [Commits](https://github.com/actions/attest-build-provenance/compare/v1...v2) --- updated-dependencies: - dependency-name: actions/attest-build-provenance dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index ccecb6b4..53e59c2d 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -66,7 +66,7 @@ jobs: - name: Attest if: startsWith(github.ref, 'refs/tags/v') - uses: actions/attest-build-provenance@v1 + uses: actions/attest-build-provenance@v2 with: subject-path: "${{ github.workspace }}/dist/**/mercure" From 02ce65fe2c77b1de35fd63c7bb17504881bd9844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 8 Jan 2025 12:44:21 +0100 Subject: [PATCH 52/71] feat: upgrade to Caddy 2.9 --- caddy/go.mod | 77 +++++----- caddy/go.sum | 403 ++++++++++++++++++++++++++++++++++----------------- go.mod | 22 +-- go.sum | 48 +++--- 4 files changed, 345 insertions(+), 205 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index eba408fa..c29b413e 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -13,21 +13,21 @@ replace github.com/dunglas/mercure => ../ require ( github.com/MicahParks/keyfunc/v3 v3.3.5 - github.com/caddyserver/caddy/v2 v2.8.4 + github.com/caddyserver/caddy/v2 v2.9.0 github.com/dunglas/mercure v0.17.1 github.com/prometheus/client_golang v1.20.5 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 go.uber.org/zap v1.27.0 ) require ( - cel.dev/expr v0.18.0 // indirect + cel.dev/expr v0.19.1 // indirect dario.cat/mergo v1.0.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/BurntSushi/toml v1.4.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145 // indirect github.com/MicahParks/jwkset v0.5.20 // indirect @@ -37,15 +37,15 @@ require ( github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.15.0 // indirect - github.com/caddyserver/certmagic v0.21.4 // indirect + github.com/bits-and-blooms/bitset v1.20.0 // indirect + github.com/caddyserver/certmagic v0.21.5 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect - github.com/coreos/go-oidc/v3 v3.11.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect + github.com/coreos/go-oidc/v3 v3.12.0 // 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/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect @@ -54,6 +54,7 @@ require ( github.com/dlclark/regexp2 v1.11.4 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-chi/chi/v5 v5.1.0 // indirect @@ -67,11 +68,11 @@ require ( github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/cel-go v0.22.0 // indirect + github.com/google/cel-go v0.22.1 // indirect github.com/google/certificate-transparency-go v1.2.2 // indirect - github.com/google/go-tpm v0.9.1 // indirect + github.com/google/go-tpm v0.9.2 // indirect github.com/google/go-tspi v0.3.0 // indirect - github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 // indirect + github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/mux v1.8.1 // indirect @@ -82,18 +83,18 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/pgx/v5 v5.7.1 // indirect + github.com/jackc/pgx/v5 v5.7.2 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/kevburnsjr/skipfilter v0.0.1 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/libdns/libdns v0.2.2 // indirect - github.com/magiconair/properties v1.8.7 // indirect + github.com/magiconair/properties v1.8.9 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect - github.com/mholt/acmez/v2 v2.0.3 // indirect + github.com/mholt/acmez/v3 v3.0.0 // indirect github.com/miekg/dns v1.1.62 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect @@ -101,16 +102,16 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mschoch/smat v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/ginkgo/v2 v2.21.0 // indirect + github.com/onsi/ginkgo/v2 v2.22.2 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pires/go-proxyproto v0.8.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.60.1 // indirect + github.com/prometheus/common v0.61.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/quic-go/qpack v0.5.1 // indirect - github.com/quic-go/quic-go v0.48.1 // indirect + github.com/quic-go/quic-go v0.48.2 // indirect github.com/rs/xid v1.6.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect @@ -119,16 +120,16 @@ require ( github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/slackhq/nebula v1.9.4 // indirect - github.com/smallstep/certificates v0.28.0 // indirect + github.com/smallstep/certificates v0.28.1 // indirect github.com/smallstep/cli-utils v0.10.0 // indirect github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 // indirect github.com/smallstep/nosql v0.7.0 // indirect - github.com/smallstep/pkcs7 v0.0.0-20241029111203-fbab67b7673f // indirect - github.com/smallstep/scep v0.0.0-20240926084937-8cf1ca453101 // indirect + github.com/smallstep/pkcs7 v0.1.1 // indirect + github.com/smallstep/scep v0.0.0-20241223071629-a37a330173bc // indirect github.com/smallstep/truststore v0.13.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.7.0 // indirect + github.com/spf13/cast v1.7.1 // indirect github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.19.0 // indirect @@ -156,28 +157,28 @@ require ( go.opentelemetry.io/otel/sdk v1.32.0 // indirect go.opentelemetry.io/otel/trace v1.32.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect - go.step.sm/crypto v0.54.0 // indirect + go.step.sm/crypto v0.56.0 // indirect go.step.sm/linkedca v0.22.2 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap/exp v0.2.0 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/crypto/x509roots/fallback v0.0.0-20241107225453-6018723c7405 // indirect - golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect + go.uber.org/zap/exp v0.3.0 // indirect + golang.org/x/crypto v0.32.0 // indirect + golang.org/x/crypto/x509roots/fallback v0.0.0-20250106144430-8929309228b4 // indirect + golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect golang.org/x/mod v0.22.0 // indirect - golang.org/x/net v0.31.0 // indirect - golang.org/x/oauth2 v0.24.0 // indirect - golang.org/x/sync v0.9.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/term v0.26.0 // indirect - golang.org/x/text v0.20.0 // indirect - golang.org/x/time v0.8.0 // indirect - golang.org/x/tools v0.27.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect - google.golang.org/grpc v1.68.0 // indirect - google.golang.org/protobuf v1.35.1 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/oauth2 v0.25.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/term v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + golang.org/x/time v0.9.0 // indirect + golang.org/x/tools v0.29.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422 // indirect + google.golang.org/grpc v1.69.2 // indirect + google.golang.org/protobuf v1.36.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/caddy/go.sum b/caddy/go.sum index 15e8de57..d9491d29 100644 --- a/caddy/go.sum +++ b/caddy/go.sum @@ -1,24 +1,33 @@ -cel.dev/expr v0.18.0 h1:CJ6drgk+Hf96lkLikr4rFf19WrU0BOWEihyZnI2TAzo= -cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4= +cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.31.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.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= -cloud.google.com/go/auth v0.9.9 h1:BmtbpNQozo8ZwW2t7QJjnrQtdganSdmqeIBxHxNkEZQ= -cloud.google.com/go/auth v0.9.9/go.mod h1:xxA5AqpDrvS+Gkmo9RqrGGRh6WSNKKOXhY3zNOr38tI= -cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY= -cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc= +cloud.google.com/go/auth v0.13.0 h1:8Fu8TZy167JkW8Tj3q7dIkr2v4cndv41ouecJx0PAHs= +cloud.google.com/go/auth v0.13.0/go.mod h1:COOjD9gwfKNKz+IIduatIhYJQIc0mG3H102r/EMxX6Q= +cloud.google.com/go/auth/oauth2adapt v0.2.6 h1:V6a6XDu2lTwPZWOawrAa9HUK+DB2zfJyTuciBG5hFkU= +cloud.google.com/go/auth/oauth2adapt v0.2.6/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8= cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= -cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo= -cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= -cloud.google.com/go/iam v1.2.1 h1:QFct02HRb7H12J/3utj0qf5tobFh9V4vR6h9eX5EBRU= -cloud.google.com/go/iam v1.2.1/go.mod h1:3VUIJDPpwT6p/amXRC5GY8fCCh70lxPygguVtI0Z4/g= -cloud.google.com/go/kms v1.20.0 h1:uKUvjGqbBlI96xGE669hcVnEMw1Px/Mvfa62dhM5UrY= -cloud.google.com/go/kms v1.20.0/go.mod h1:/dMbFF1tLLFnQV44AoI2GlotbjowyUfgVwezxW291fM= +cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= +cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= +cloud.google.com/go/iam v1.2.2 h1:ozUSofHUGf/F4tCNy/mu9tHLTaxZFLOUiKzjcgWHGIA= +cloud.google.com/go/iam v1.2.2/go.mod h1:0Ys8ccaZHdI1dEUilwzqng/6ps2YB6vRsjIe00/+6JY= +cloud.google.com/go/kms v1.20.2 h1:NGTHOxAyhDVUGVU5KngeyGScrg2D39X76Aphe6NC7S0= +cloud.google.com/go/kms v1.20.2/go.mod h1:LywpNiVCvzYNJWS9JUcGJSVTNSwPwi0vBAotzDqn2nc= cloud.google.com/go/longrunning v0.6.2 h1:xjDfh1pQcWPEvnfjZmwjKQEcHnpz6lHjfy7Fo0MK+hc= cloud.google.com/go/longrunning v0.6.2/go.mod h1:k/vIs83RN4bE3YCswdXC5PFfWVILjm3hpEUlSko4PiI= 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/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= +dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= +dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= +dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -26,8 +35,8 @@ github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0 github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -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/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= +github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/MauriceGit/skiplist v0.0.0-20191117202105-643e379adb62/go.mod h1:877WBceefKn14QwVVn4xRFUsHsZb9clICgdeTj4XsUg= @@ -53,49 +62,53 @@ github.com/alecthomas/chroma/v2 v2.14.0/go.mod h1:QolEbTfmUHIMVpBqxeDnNBj2uoeI4E github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b h1:uUXgbcPDK3KpW29o4iy7GtuappbWT0l5NaMo9H9pJDw= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-sdk-go-v2 v1.31.0 h1:3V05LbxTSItI5kUqNwhJrrrY1BAXxXt0sN0l72QmG5U= -github.com/aws/aws-sdk-go-v2 v1.31.0/go.mod h1:ztolYtaEUtdpf9Wftr31CJfLVjOnD/CVRkKOOYgF8hA= -github.com/aws/aws-sdk-go-v2/config v1.27.39 h1:FCylu78eTGzW1ynHcongXK9YHtoXD5AiiUqq3YfJYjU= -github.com/aws/aws-sdk-go-v2/config v1.27.39/go.mod h1:wczj2hbyskP4LjMKBEZwPRO1shXY+GsQleab+ZXT2ik= -github.com/aws/aws-sdk-go-v2/credentials v1.17.37 h1:G2aOH01yW8X373JK419THj5QVqu9vKEwxSEsGxihoW0= -github.com/aws/aws-sdk-go-v2/credentials v1.17.37/go.mod h1:0ecCjlb7htYCptRD45lXJ6aJDQac6D2NlKGpZqyTG6A= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14 h1:C/d03NAmh8C4BZXhuRNboF/DqhBkBCeDiJDcaqIT5pA= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.14/go.mod h1:7I0Ju7p9mCIdlrfS+JCgqcYD0VXz/N4yozsox+0o078= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18 h1:kYQ3H1u0ANr9KEKlGs/jTLrBFPo8P8NaH/w7A01NeeM= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.18/go.mod h1:r506HmK5JDUh9+Mw4CfGJGSSoqIiLCndAuqXuhbv67Y= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18 h1:Z7IdFUONvTcvS7YuhtVxN99v2cCoHRXOS4mTr0B/pUc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.18/go.mod h1:DkKMmksZVVyat+Y+r1dEOgJEfUeA7UngIHWeKsi0yNc= +github.com/aws/aws-sdk-go-v2 v1.32.6 h1:7BokKRgRPuGmKkFMhEg/jSul+tB9VvXhcViILtfG8b4= +github.com/aws/aws-sdk-go-v2 v1.32.6/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= +github.com/aws/aws-sdk-go-v2/config v1.28.6 h1:D89IKtGrs/I3QXOLNTH93NJYtDhm8SYa9Q5CsPShmyo= +github.com/aws/aws-sdk-go-v2/config v1.28.6/go.mod h1:GDzxJ5wyyFSCoLkS+UhGB0dArhb9mI+Co4dHtoTxbko= +github.com/aws/aws-sdk-go-v2/credentials v1.17.47 h1:48bA+3/fCdi2yAwVt+3COvmatZ6jUDNkDTIsqDiMUdw= +github.com/aws/aws-sdk-go-v2/credentials v1.17.47/go.mod h1:+KdckOejLW3Ks3b0E3b5rHsr2f9yuORBum0WPnE5o5w= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 h1:AmoU1pziydclFT/xRV+xXE/Vb8fttJCLRPv8oAkprc0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21/go.mod h1:AjUdLYe4Tgs6kpH4Bv7uMZo7pottoyHMn4eTcIcneaY= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 h1:s/fF4+yDQDoElYhfIVvSNyeCydfbuTKzhxSXDXCPasU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25/go.mod h1:IgPfDv5jqFIzQSNbUEMoitNooSMXjRSDkhXv8jiROvU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 h1:ZntTCl5EsYnhN/IygQEUugpdwbhdkom9uHcbCftiGgA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25/go.mod h1:DBdPrgeocww+CSl1C8cEV8PN1mHMBhuCDLpXezyvWkE= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5 h1:QFASJGfT8wMXtuP3D5CRmMjARHv9ZmzFUMJznHDOY3w= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.5/go.mod h1:QdZ3OmoIjSX+8D1OPAzPxDfjXASbBMDsz9qvtyIhtik= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20 h1:Xbwbmk44URTiHNx6PNo0ujDE6ERlsCKJD3u1zfnzAPg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.20/go.mod h1:oAfOFzUB14ltPZj1rWwRc3d/6OgD76R8KlvU3EqM9Fg= -github.com/aws/aws-sdk-go-v2/service/kms v1.36.3 h1:iHi6lC6LfW6SNvB2bixmlOW3WMyWFrHZCWX+P+CCxMk= -github.com/aws/aws-sdk-go-v2/service/kms v1.36.3/go.mod h1:OHmlX4+o0XIlJAQGAHPIy0N9yZcYS/vNG+T7geSNcFw= -github.com/aws/aws-sdk-go-v2/service/sso v1.23.3 h1:rs4JCczF805+FDv2tRhZ1NU0RB2H6ryAvsWPanAr72Y= -github.com/aws/aws-sdk-go-v2/service/sso v1.23.3/go.mod h1:XRlMvmad0ZNL+75C5FYdMvbbLkd6qiqz6foR1nA1PXY= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.3 h1:S7EPdMVZod8BGKQQPTBK+FcX9g7bKR7c4+HxWqHP7Vg= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.27.3/go.mod h1:FnvDM4sfa+isJ3kDXIzAB9GAwVSzFzSy97uZ3IsHo4E= -github.com/aws/aws-sdk-go-v2/service/sts v1.31.3 h1:VzudTFrDCIDakXtemR7l6Qzt2+JYsVqo2MxBPt5k8T8= -github.com/aws/aws-sdk-go-v2/service/sts v1.31.3/go.mod h1:yMWe0F+XG0DkRZK5ODZhG7BEFYhLXi2dqGsv6tX0cgI= -github.com/aws/smithy-go v1.21.0 h1:H7L8dtDRk0P1Qm6y0ji7MCYMQObJ5R9CRpyPhRUkLYA= -github.com/aws/smithy-go v1.21.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 h1:50+XsN70RS7dwJ2CkVNXzj7U2L1HKP8nqTd3XWEXBN4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6/go.mod h1:WqgLmwY7so32kG01zD8CPTJWVWM+TzJoOVHwTg4aPug= +github.com/aws/aws-sdk-go-v2/service/kms v1.37.7 h1:dZmNIRtPUvtvUIIDVNpvtnJQ8N8Iqm7SQAxf18htZYw= +github.com/aws/aws-sdk-go-v2/service/kms v1.37.7/go.mod h1:vj8PlfJH9mnGeIzd6uMLPi5VgiqzGG7AZoe1kf1uTXM= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 h1:rLnYAfXQ3YAccocshIH5mzNNwZBkBo+bP6EhIxak6Hw= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.7/go.mod h1:ZHtuQJ6t9A/+YDuxOLnbryAmITtr8UysSny3qcyvJTc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 h1:JnhTZR3PiYDNKlXy50/pNeix9aGMo6lLpXwJ1mw8MD4= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6/go.mod h1:URronUEGfXZN1VpdktPSD1EkAL9mfrV+2F4sjH38qOY= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 h1:s4074ZO1Hk8qv65GqNXqDjmkf4HSQqJukaLuuW0TpDA= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.2/go.mod h1:mVggCnIWoM09jP71Wh+ea7+5gAp53q+49wDFs1SW5z8= +github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= +github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 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/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/bits-and-blooms/bitset v1.15.0 h1:DiCRMscZsGyYePE9AR3sVhKqUXCt5IZvkX5AfAc5xLQ= -github.com/bits-and-blooms/bitset v1.15.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/caddyserver/caddy/v2 v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk= -github.com/caddyserver/caddy/v2 v2.8.4/go.mod h1:vmDAHp3d05JIvuhc24LmnxVlsZmWnUwbP5WMjzcMPWw= -github.com/caddyserver/certmagic v0.21.4 h1:e7VobB8rffHv8ZZpSiZtEwnLDHUwLVYLWzWSa1FfKI0= -github.com/caddyserver/certmagic v0.21.4/go.mod h1:swUXjQ1T9ZtMv95qj7/InJvWLXURU85r+CfG0T+ZbDE= +github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= +github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= +github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/caddyserver/caddy/v2 v2.9.0 h1:rteY8N18LsQn+2KVk6R10Vg/AlNsID1N/Ek9JLjm2yE= +github.com/caddyserver/caddy/v2 v2.9.0/go.mod h1:BYELOc32ZTQRzPy1UGngt3A9nQMTDWDN68fBaoHf4tI= +github.com/caddyserver/certmagic v0.21.5 h1:iIga4nZRgd27EIEbX7RZmoRMul+EVBn/h7bAGL83dnY= +github.com/caddyserver/certmagic v0.21.5/go.mod h1:n1sCo7zV1Ez2j+89wrzDxo4N/T1Ws/Vx8u5NvuBFabw= github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= @@ -113,15 +126,18 @@ github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObk github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI= -github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= +github.com/coreos/go-oidc/v3 v3.12.0 h1:sJk+8G2qq94rDI6ehZ71Bol3oUHy63qNYmkiSjrc/Jo= +github.com/coreos/go-oidc/v3 v3.12.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= github.com/cpuguy83/go-md2man/v2 v2.0.5/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/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= @@ -146,6 +162,9 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= +github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -153,8 +172,11 @@ github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/ github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= @@ -170,46 +192,62 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -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/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= +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/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.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/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/cel-go v0.22.0 h1:b3FJZxpiv1vTMo2/5RDUqAHPxkT8mmMfJIrq1llbf7g= -github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8= +github.com/google/cel-go v0.22.1 h1:AfVXx3chM2qwoSbM7Da8g8hX8OVSkBFwX+rz2+PcK40= +github.com/google/cel-go v0.22.1/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8= github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/certificate-transparency-go v1.2.2 h1:5TAzjQnCfN1vps2XWUgU6Svt++rgy9a+b8CBYXaKUAo= github.com/google/certificate-transparency-go v1.2.2/go.mod h1:d1o5XNQzK/yz8IXzEce6KXgMxfter/EcMP9vG4dBRNE= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 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-tpm v0.9.1 h1:0pGc4X//bAlmZzMKf8iz6IsDo1nYTbYJ6FZN/rg4zdM= -github.com/google/go-tpm v0.9.1/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-tpm v0.9.2 h1:Gh8CMnMm06b09DmcsuY9fI3oF69188lGXCpiT/a05T4= +github.com/google/go-tpm v0.9.2/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus= github.com/google/go-tspi v0.3.0/go.mod h1:xfMGI3G0PhxCdNVcYr1C4C+EizojDg/TXuX5by8CiHI= -github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 h1:sAGdeJj0bnMgUNVeUpp6AYlVdCt3/GdI3pGRqsNSQLs= -github.com/google/pprof v0.0.0-20241101162523-b92577c0c142/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= 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/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= -github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s= -github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A= +github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU= +github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= +github.com/googleapis/gax-go/v2 v2.14.0 h1:f+jMrjBPl+DL9nI4IQzLUxMq7XrAqFYB7hBPqMNIe8o= +github.com/googleapis/gax-go/v2 v2.14.0/go.mod h1:lhBCnjdLrWRaPvLWhmc8IS24m9mr07qSYnHncrgo+zk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= @@ -228,13 +266,17 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs= -github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA= +github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI= +github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kevburnsjr/skipfilter v0.0.1 h1:EWl1lWUJfIehrKYIEkps0Cl67lCfS2pUM9iZFNajp7g= github.com/kevburnsjr/skipfilter v0.0.1/go.mod h1:jfaRyFOYVUtIa6IIC+0mB1qiZqhHw+DKvFowCBuijSk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= @@ -245,6 +287,7 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn 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/pty v1.1.3/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= @@ -252,9 +295,11 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= +github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= +github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -262,10 +307,12 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 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/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 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/mholt/acmez/v2 v2.0.3 h1:CgDBlEwg3QBp6s45tPQmFIBrkRIkBT4rW4orMM6p4sw= -github.com/mholt/acmez/v2 v2.0.3/go.mod h1:pQ1ysaDeGrIMvJ9dfJMk5kJNkn7L2sb3UhyrX6Q91cw= +github.com/mholt/acmez/v3 v3.0.0 h1:r1NcjuWR0VaKP2BTjDK9LRFBw/WvURx3jlaEUl9Ht8E= +github.com/mholt/acmez/v3 v3.0.0/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= +github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= @@ -278,14 +325,19 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= -github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= -github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU= +github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk= +github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= +github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= +github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 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= @@ -301,18 +353,22 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= +github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 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-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 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.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc= -github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= +github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ= +github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s= +github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 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/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= -github.com/quic-go/quic-go v0.48.1 h1:y/8xmfWI9qmGTc+lBr4jKRUWLGSlSigv847ULJ4hYXA= -github.com/quic-go/quic-go v0.48.1/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= +github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE= +github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= 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/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= @@ -326,10 +382,33 @@ github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6g github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/schollz/jsonstore v1.1.0 h1:WZBDjgezFS34CHI+myb4s8GGpir3UMpy7vWoCeO0n6E= github.com/schollz/jsonstore v1.1.0/go.mod h1:15c6+9guw8vDRyozGjN3FoILt0wpruJk9Pi66vjaZfg= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= +github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= +github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= +github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= +github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= +github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= +github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= +github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= +github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= +github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= +github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= +github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= +github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= +github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= +github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= @@ -337,23 +416,24 @@ github.com/slackhq/nebula v1.9.4 h1:p06JxtXT/OBMWt2OQkY7F0phOBb42X93YWNsS1yqC9o= github.com/slackhq/nebula v1.9.4/go.mod h1:1+4q4wd3dDAjO8rKCttSb9JIVbklQhuJiBp5I0lbIsQ= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262 h1:unQFBIznI+VYD1/1fApl1A+9VcBk+9dcqGfnePY87LY= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262/go.mod h1:MyOHs9Po2fbM1LHej6sBUT8ozbxmMOFG+E+rx/GSGuc= -github.com/smallstep/certificates v0.28.0 h1:EM/lH/5vizfs1sMSBADSJt2PfQikRCBYtzgRNrtNjlA= -github.com/smallstep/certificates v0.28.0/go.mod h1:kJE6IWqokSv34dWy/Qqcl2FuQvmwruxn2Yhg/tIqs4Y= +github.com/smallstep/certificates v0.28.1 h1:hLYz1It9mecJD0DqQ+qLldQnTUkanFIztuyqmxKRZkY= +github.com/smallstep/certificates v0.28.1/go.mod h1:/xlSParPTewKBdhyp/vHcoOmtwK8AbPiXdmbu6c4J3A= github.com/smallstep/cli-utils v0.10.0 h1:CfXNvHtIN5pAzGvGP0NEUZoGFcj5epNEB6RSpSfduek= github.com/smallstep/cli-utils v0.10.0/go.mod h1:jIeNa5ctrVg89lU5TaQKYd6o1eFxi9mtZu1sXSxpEBg= github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 h1:kjYvkvS/Wdy0PVRDUAA0gGJIVSEZYhiAJtfwYgOYoGA= github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935/go.mod h1:vNAduivU014fubg6ewygkAvQC0IQVXqdc8vaGl/0er4= github.com/smallstep/nosql v0.7.0 h1:YiWC9ZAHcrLCrayfaF+QJUv16I2bZ7KdLC3RpJcnAnE= github.com/smallstep/nosql v0.7.0/go.mod h1:H5VnKMCbeq9QA6SRY5iqPylfxLfYcLwvUff3onQ8+HU= -github.com/smallstep/pkcs7 v0.0.0-20240911091500-b1cae6277023/go.mod h1:CM5KrX7rxWgwDdMj9yef/pJB2OPgy/56z4IEx2UIbpc= -github.com/smallstep/pkcs7 v0.0.0-20241029111203-fbab67b7673f h1:yGZK213dsHF8FEe/fHlt7s7p4lLiW1CFfghbMAi6ph0= -github.com/smallstep/pkcs7 v0.0.0-20241029111203-fbab67b7673f/go.mod h1:gmVfG4kelRxZm+8CSk0aS+/mRoR2h8y/khVRMh0eTfg= -github.com/smallstep/scep v0.0.0-20240926084937-8cf1ca453101 h1:LyZqn24/ZiVg8v9Hq07K6mx6RqPtpDeK+De5vf4QEY4= -github.com/smallstep/scep v0.0.0-20240926084937-8cf1ca453101/go.mod h1:EuKQjYGQwhUa1mgD21zxIgOgUYLsqikJmvxNscxpS/Y= +github.com/smallstep/pkcs7 v0.1.1 h1:x+rPdt2W088V9Vkjho4KtoggyktZJlMduZAtRHm68LU= +github.com/smallstep/pkcs7 v0.1.1/go.mod h1:dL6j5AIz9GHjVEBTXtW+QliALcgM19RtXaTeyxI+AfA= +github.com/smallstep/scep v0.0.0-20241223071629-a37a330173bc h1:gJ1mkz/iJhKnKUJit5DCFxNRWo9mxIkVm9SI8DiUugI= +github.com/smallstep/scep v0.0.0-20241223071629-a37a330173bc/go.mod h1:bENyEPpujhqigQx115AitJTc11LZmGUNk0ftgyhcNus= github.com/smallstep/truststore v0.13.0 h1:90if9htAOblavbMeWlqNLnO9bsjjgVv2hQeQJCi/py4= github.com/smallstep/truststore v0.13.0/go.mod h1:3tmMp2aLKZ/OA/jnFUB0cYPcho402UG2knuJoPh4j7A= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -361,8 +441,8 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B 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 v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= -github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= +github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= 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= @@ -387,17 +467,21 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +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.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53 h1:uxMgm0C+EjytfAqyfBG55ZONKQ7mvd7x4YYCWsf8QHQ= github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53/go.mod h1:kNGUQ3VESx3VZwRwA9MSCUegIl6+saPL8Noq82ozCaU= +github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/unrolled/secure v1.17.0 h1:Io7ifFgo99Bnh0J7+Q+qcMzWM6kaDPCA5FroFZEdbWU= github.com/unrolled/secure v1.17.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ= github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po= +github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= +github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= 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/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= @@ -417,8 +501,7 @@ github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= 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/otelhttp v0.57.0 h1:DheMAlT6POBP+gh8RUH19EOTnQIor5QE0uSRPtzCpSw= @@ -443,12 +526,14 @@ go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZk go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= +go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= +go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.step.sm/crypto v0.54.0 h1:V8p+12Ld0NRA/RBMYoKXA0dWmVKZSdCwP56IwzweT9g= -go.step.sm/crypto v0.54.0/go.mod h1:vQJyTngfZDW+UyZdFzOMCY/txWDAmcwViEUC7Gn4YfU= +go.step.sm/crypto v0.56.0 h1:KcFfV76cI9Xaw8bdSc9x55skyuSdcHcTdL37vvVZnvY= +go.step.sm/crypto v0.56.0/go.mod h1:snWNloxY9s1W+HsFqcviq55nvzbqqX6LxVt0Vktv5mw= go.step.sm/linkedca v0.22.2 h1:zmFIyDC77gFHo6FLQJ8OIXYpLYDIsgDWaYqtYs6A9/Q= go.step.sm/linkedca v0.22.2/go.mod h1:ESY8r5VfhJA8ZVzI6hXIQcEX9LwaY3aoPnT+Hb9jpbw= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= @@ -461,22 +546,29 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.uber.org/zap/exp v0.2.0 h1:FtGenNNeCATRB3CmB/yEUnjEFeJWpB/pMcy7e2bKPYs= -go.uber.org/zap/exp v0.2.0/go.mod h1:t0gqAIdh1MfKv9EwN/dLwfZnJxe9ITAZN78HEWPFWDQ= +go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U= +go.uber.org/zap/exp v0.3.0/go.mod h1:5I384qq7XGxYyByIhHm6jg5CHkGY0nsTfbDLgDDlgJQ= +go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/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-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/crypto/x509roots/fallback v0.0.0-20241107225453-6018723c7405 h1:VAHMMzTf+Febj933dn5dxsbBHAHHqCv0fJj3UFB7PZM= -golang.org/x/crypto/x509roots/fallback v0.0.0-20241107225453-6018723c7405/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= -golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= -golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto/x509roots/fallback v0.0.0-20250106144430-8929309228b4 h1:2UmVXDw2sT/v4mRp1tucroUkHyqAbK1SXfh+ss3sKsE= +golang.org/x/crypto/x509roots/fallback v0.0.0-20250106144430-8929309228b4/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +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/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -484,6 +576,14 @@ golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.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-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/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-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -492,22 +592,34 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= -golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= +golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= +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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/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-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -523,10 +635,9 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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= @@ -535,11 +646,11 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= -golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= -golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= -golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= 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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= @@ -547,46 +658,74 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= -golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/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-20181030000716-a0a13e073c7b/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-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= -golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= +golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= +golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.203.0 h1:SrEeuwU3S11Wlscsn+LA1kb/Y5xT8uggJSkIhD08NAU= -google.golang.org/api v0.203.0/go.mod h1:BuOVyCSYEPwJb3npWvDnNmFI92f3GeRnHNkETneT3SI= -google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53 h1:Df6WuGvthPzc+JiQ/G+m+sNX24kc0aTBqoDN/0yyykE= -google.golang.org/genproto v0.0.0-20241015192408-796eee8c2d53/go.mod h1:fheguH3Am2dGp1LfXkrvwqC/KlFq8F0nLq3LryOMrrE= -google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g= -google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= -google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= -google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= +google.golang.org/api v0.212.0 h1:BcRj3MJfHF3FYD29rk7u9kuu1SyfGqfHcA0hSwKqkHg= +google.golang.org/api v0.212.0/go.mod h1:gICpLlpp12/E8mycRMzgy3SQ9cFh2XnVJ6vJi/kQbvI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= +google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk= +google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc= +google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 h1:GVIKPyP/kLIyVOgOnTwFOrvQaQUzOzGMCxgFUOEmm24= +google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422 h1:3UsHvIr4Wc2aW4brOaSCmcxh9ksica6fHEr8P1XhkYw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU= +google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= +google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= +google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= 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/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= +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.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= +grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +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= howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM= howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= +sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/go.mod b/go.mod index 0d0654e6..b79312fb 100644 --- a/go.mod +++ b/go.mod @@ -21,19 +21,19 @@ require ( github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/unrolled/secure v1.17.0 github.com/yosida95/uritemplate/v3 v3.0.2 go.etcd.io/bbolt v1.3.11 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.29.0 + golang.org/x/crypto v0.32.0 ) require ( github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145 // indirect github.com/RoaringBitmap/roaring v1.9.4 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.15.0 // indirect + github.com/bits-and-blooms/bitset v1.20.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -41,26 +41,26 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/klauspost/compress v1.17.11 // indirect - github.com/magiconair/properties v1.8.7 // indirect + github.com/magiconair/properties v1.8.9 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mschoch/smat v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/common v0.60.1 // indirect + github.com/prometheus/common v0.61.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.7.0 // indirect + github.com/spf13/cast v1.7.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect - golang.org/x/net v0.31.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect - google.golang.org/protobuf v1.35.1 // indirect + golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/protobuf v1.36.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 6b4b6cbb..6d76a870 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,8 @@ 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/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/bits-and-blooms/bitset v1.15.0 h1:DiCRMscZsGyYePE9AR3sVhKqUXCt5IZvkX5AfAc5xLQ= -github.com/bits-and-blooms/bitset v1.15.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= +github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= 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/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -50,8 +50,8 @@ 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/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= +github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= 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/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= @@ -67,8 +67,8 @@ github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+ github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= 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.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc= -github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= +github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ= +github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s= 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/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -82,8 +82,8 @@ github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9yS github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= 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 v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= -github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= +github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= 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/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -93,8 +93,8 @@ github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +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.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/unrolled/secure v1.17.0 h1:Io7ifFgo99Bnh0J7+Q+qcMzWM6kaDPCA5FroFZEdbWU= @@ -109,20 +109,20 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= -golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= +google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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= From b170b9ef619d0c01ec6a117f89c60150dbeaa9ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 8 Jan 2025 12:46:53 +0100 Subject: [PATCH 53/71] ci: fix linter --- server_test.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/server_test.go b/server_test.go index 2c6ce778..0f631a13 100644 --- a/server_test.go +++ b/server_test.go @@ -320,13 +320,10 @@ func TestClientClosesThenReconnects(t *testing.T) { } func TestServeAcme(t *testing.T) { - dir, _ := os.MkdirTemp("", "cert") - defer os.RemoveAll(dir) - h := createAnonymousDummy(WithAllowedHosts([]string{"example.com"})) h.config.Set("acme_http01_addr", ":8080") h.config.Set("acme_http01_addr", ":8080") - h.config.Set("acme_cert_dir", dir) + h.config.Set("acme_cert_dir", t.TempDir()) go h.Serve() client := &http.Client{ From f46d76f2d55471c9c4043519a68ac2ffd13ad4dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 8 Jan 2025 13:04:23 +0100 Subject: [PATCH 54/71] ci: bump Playwright version --- .github/workflows/ci.yml | 2 +- conformance-tests/package-lock.json | 55 ++++++++++++++++++----------- conformance-tests/package.json | 2 +- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc40f345..4f885102 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,7 +82,7 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: "16" + node-version: "latest" cache: "npm" cache-dependency-path: conformance-tests/package-lock.json diff --git a/conformance-tests/package-lock.json b/conformance-tests/package-lock.json index d9460f29..99f46736 100644 --- a/conformance-tests/package-lock.json +++ b/conformance-tests/package-lock.json @@ -12,34 +12,25 @@ "dotenv": "^16.0.0" }, "devDependencies": { - "@playwright/test": "^1.19.1" + "@playwright/test": "^1.49.1" } }, "node_modules/@playwright/test": { - "version": "1.34.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.34.0.tgz", - "integrity": "sha512-GIALJVODOIrMflLV54H3Cow635OfrTwOu24ZTDyKC66uchtFX2NcCRq83cLdakMjZKYK78lODNLQSYBj2OgaTw==", + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.1.tgz", + "integrity": "sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@types/node": "*", - "playwright-core": "1.34.0" + "playwright": "1.49.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=14" - }, - "optionalDependencies": { - "fsevents": "2.3.2" + "node": ">=18" } }, - "node_modules/@types/node": { - "version": "20.2.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.3.tgz", - "integrity": "sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==", - "dev": true - }, "node_modules/dotenv": { "version": "16.0.3", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", @@ -54,6 +45,7 @@ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -62,13 +54,36 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/playwright": { + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz", + "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.49.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, "node_modules/playwright-core": { - "version": "1.34.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.34.0.tgz", - "integrity": "sha512-fMUY1+iR6kYbJF/EsOOqzBA99ZHXbw9sYPNjwA4X/oV0hVF/1aGlWYBGPVUEqxBkGANDKMziYoOdKGU5DIP5Gg==", + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz", + "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==", "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, "engines": { - "node": ">=14" + "node": ">=18" } } } diff --git a/conformance-tests/package.json b/conformance-tests/package.json index a2cda71a..f988ab35 100644 --- a/conformance-tests/package.json +++ b/conformance-tests/package.json @@ -13,7 +13,7 @@ "author": "Kévin Dunglas", "license": "AGPL-3.0-or-later", "devDependencies": { - "@playwright/test": "^1.19.1" + "@playwright/test": "^1.49.1" }, "dependencies": { "dotenv": "^16.0.0" From 14b89c83d7960d9abd9525c54a6070190ff0d91a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 8 Jan 2025 14:15:48 +0100 Subject: [PATCH 55/71] chore: prepare release 0.18.0 --- caddy/go.mod | 2 +- charts/mercure/Chart.yaml | 4 ++-- charts/mercure/README.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index c29b413e..bc682b5e 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -14,7 +14,7 @@ replace github.com/dunglas/mercure => ../ require ( github.com/MicahParks/keyfunc/v3 v3.3.5 github.com/caddyserver/caddy/v2 v2.9.0 - github.com/dunglas/mercure v0.17.1 + github.com/dunglas/mercure v0.18.0 github.com/prometheus/client_golang v1.20.5 github.com/stretchr/testify v1.10.0 go.uber.org/zap v1.27.0 diff --git a/charts/mercure/Chart.yaml b/charts/mercure/Chart.yaml index 59bc02f9..62b96945 100644 --- a/charts/mercure/Chart.yaml +++ b/charts/mercure/Chart.yaml @@ -12,8 +12,8 @@ keywords: - streaming-api - async-api type: application -version: 0.17.1 -appVersion: "v0.17.1" +version: 0.18.0 +appVersion: "v0.18.0" maintainers: - name: dunglas email: kevin@dunglas.fr diff --git a/charts/mercure/README.md b/charts/mercure/README.md index af8652e9..b34968be 100644 --- a/charts/mercure/README.md +++ b/charts/mercure/README.md @@ -1,7 +1,7 @@ # Mercure Chart for Kubernetes -![Version: 0.17.1](https://img.shields.io/badge/Version-0.17.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.17.1](https://img.shields.io/badge/AppVersion-v0.17.1-informational?style=flat-square) +![Version: 0.18.0](https://img.shields.io/badge/Version-0.18.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.18.0](https://img.shields.io/badge/AppVersion-v0.18.0-informational?style=flat-square) A Helm chart to install a Mercure Hub in a Kubernetes cluster. Mercure is a protocol to push data updates to web browsers and other HTTP clients in a convenient, fast, reliable and battery-efficient way. From 2d9089eaad2fc703e1c70cfa87b73591ec73e82e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 8 Jan 2025 21:27:09 +0100 Subject: [PATCH 56/71] chore: upgrade to Caddy 2.9.1 --- caddy/go.mod | 4 ++-- caddy/go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index bc682b5e..9ae61473 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -13,7 +13,7 @@ replace github.com/dunglas/mercure => ../ require ( github.com/MicahParks/keyfunc/v3 v3.3.5 - github.com/caddyserver/caddy/v2 v2.9.0 + github.com/caddyserver/caddy/v2 v2.9.1 github.com/dunglas/mercure v0.18.0 github.com/prometheus/client_golang v1.20.5 github.com/stretchr/testify v1.10.0 @@ -38,7 +38,7 @@ require ( github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.20.0 // indirect - github.com/caddyserver/certmagic v0.21.5 // indirect + github.com/caddyserver/certmagic v0.21.6 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect diff --git a/caddy/go.sum b/caddy/go.sum index d9491d29..6e964a94 100644 --- a/caddy/go.sum +++ b/caddy/go.sum @@ -105,10 +105,10 @@ github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3M github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/caddyserver/caddy/v2 v2.9.0 h1:rteY8N18LsQn+2KVk6R10Vg/AlNsID1N/Ek9JLjm2yE= -github.com/caddyserver/caddy/v2 v2.9.0/go.mod h1:BYELOc32ZTQRzPy1UGngt3A9nQMTDWDN68fBaoHf4tI= -github.com/caddyserver/certmagic v0.21.5 h1:iIga4nZRgd27EIEbX7RZmoRMul+EVBn/h7bAGL83dnY= -github.com/caddyserver/certmagic v0.21.5/go.mod h1:n1sCo7zV1Ez2j+89wrzDxo4N/T1Ws/Vx8u5NvuBFabw= +github.com/caddyserver/caddy/v2 v2.9.1 h1:OEYiZ7DbCzAWVb6TNEkjRcSCRGHVoZsJinoDR/n9oaY= +github.com/caddyserver/caddy/v2 v2.9.1/go.mod h1:ImUELya2el1FDVp3ahnSO2iH1or1aHxlQEQxd/spP68= +github.com/caddyserver/certmagic v0.21.6 h1:1th6GfprVfsAtFNOu4StNMF5IxK5XiaI0yZhAHlZFPE= +github.com/caddyserver/certmagic v0.21.6/go.mod h1:n1sCo7zV1Ez2j+89wrzDxo4N/T1Ws/Vx8u5NvuBFabw= github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= From baba61c34c05db5524146bb8054270cb0de5337c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 8 Jan 2025 22:07:46 +0100 Subject: [PATCH 57/71] chore: prepare release 0.18.1 --- caddy/go.mod | 2 +- charts/mercure/Chart.yaml | 4 ++-- charts/mercure/README.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index 9ae61473..7420b11e 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -14,7 +14,7 @@ replace github.com/dunglas/mercure => ../ require ( github.com/MicahParks/keyfunc/v3 v3.3.5 github.com/caddyserver/caddy/v2 v2.9.1 - github.com/dunglas/mercure v0.18.0 + github.com/dunglas/mercure v0.18.1 github.com/prometheus/client_golang v1.20.5 github.com/stretchr/testify v1.10.0 go.uber.org/zap v1.27.0 diff --git a/charts/mercure/Chart.yaml b/charts/mercure/Chart.yaml index 62b96945..cb2fc5b6 100644 --- a/charts/mercure/Chart.yaml +++ b/charts/mercure/Chart.yaml @@ -12,8 +12,8 @@ keywords: - streaming-api - async-api type: application -version: 0.18.0 -appVersion: "v0.18.0" +version: 0.18.1 +appVersion: "v0.18.1" maintainers: - name: dunglas email: kevin@dunglas.fr diff --git a/charts/mercure/README.md b/charts/mercure/README.md index b34968be..cebf7ffb 100644 --- a/charts/mercure/README.md +++ b/charts/mercure/README.md @@ -1,7 +1,7 @@ # Mercure Chart for Kubernetes -![Version: 0.18.0](https://img.shields.io/badge/Version-0.18.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.18.0](https://img.shields.io/badge/AppVersion-v0.18.0-informational?style=flat-square) +![Version: 0.18.1](https://img.shields.io/badge/Version-0.18.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.18.1](https://img.shields.io/badge/AppVersion-v0.18.1-informational?style=flat-square) A Helm chart to install a Mercure Hub in a Kubernetes cluster. Mercure is a protocol to push data updates to web browsers and other HTTP clients in a convenient, fast, reliable and battery-efficient way. From 617e827c95d10e83ffafdceac9838ae70a4203a7 Mon Sep 17 00:00:00 2001 From: Michael Mior Date: Thu, 9 Jan 2025 10:04:06 -0500 Subject: [PATCH 58/71] docs: fix typo in README (#998) --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index a134f36a..edec1477 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,7 +5,7 @@ ## Protocol Specification -- [The Specification](../spec/mercure.md) (also available as an [IETF's Internet Draft](https://datatracker.ietf.org/doc/draft-dunglas-mercure/) designed to be published as an RFC) +- [The Specification](../spec/mercure.md) (also available as an [IETF Internet Draft](https://datatracker.ietf.org/doc/draft-dunglas-mercure/) designed to be published as an RFC) - [Case studies and use cases](spec/use-cases.md) - [Frequently Asked Questions](spec/faq.md) - [OpenAPI spec](https://github.com/dunglas/mercure/blob/master/spec/openapi.yaml) From 7695d27adbc4a805b92008707ca68a063f0613f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 17:25:07 +0000 Subject: [PATCH 59/71] chore(deps): bump github.com/MicahParks/jwkset in /caddy Bumps [github.com/MicahParks/jwkset](https://github.com/MicahParks/jwkset) from 0.5.20 to 0.6.0. - [Release notes](https://github.com/MicahParks/jwkset/releases) - [Commits](https://github.com/MicahParks/jwkset/compare/v0.5.20...v0.6.0) --- updated-dependencies: - dependency-name: github.com/MicahParks/jwkset dependency-type: indirect ... Signed-off-by: dependabot[bot] --- caddy/go.mod | 2 +- caddy/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index 7420b11e..ff12f32f 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -30,7 +30,7 @@ require ( github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145 // indirect - github.com/MicahParks/jwkset v0.5.20 // indirect + github.com/MicahParks/jwkset v0.6.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/RoaringBitmap/roaring v1.9.4 // indirect github.com/alecthomas/chroma/v2 v2.14.0 // indirect diff --git a/caddy/go.sum b/caddy/go.sum index 6e964a94..4780dcd7 100644 --- a/caddy/go.sum +++ b/caddy/go.sum @@ -42,8 +42,8 @@ github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSC github.com/MauriceGit/skiplist v0.0.0-20191117202105-643e379adb62/go.mod h1:877WBceefKn14QwVVn4xRFUsHsZb9clICgdeTj4XsUg= github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145 h1:1yw6O62BReQ+uA1oyk9XaQTvLhcoHWmoQAgXmDFXpIY= github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145/go.mod h1:877WBceefKn14QwVVn4xRFUsHsZb9clICgdeTj4XsUg= -github.com/MicahParks/jwkset v0.5.20 h1:gTIKx9AofTqQJ0srd8AL7ty9NeadP5WUXSPOZadTpOI= -github.com/MicahParks/jwkset v0.5.20/go.mod h1:q8ptTGn/Z9c4MwbcfeCDssADeVQb3Pk7PnVxrvi+2QY= +github.com/MicahParks/jwkset v0.6.0 h1:l9BdSMVzhmEFXTTlTPIhK2FuDTFYawMA1hrpxQRajBI= +github.com/MicahParks/jwkset v0.6.0/go.mod h1:lNJLP4R63A/8lT9GO6FWOr/fIooTSwViFijyxwIW9EU= github.com/MicahParks/keyfunc/v3 v3.3.5 h1:7ceAJLUAldnoueHDNzF8Bx06oVcQ5CfJnYwNt1U3YYo= github.com/MicahParks/keyfunc/v3 v3.3.5/go.mod h1:SdCCyMJn/bYqWDvARspC6nCT8Sk74MjuAY22C7dCST8= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= From d781993b6fa5b34b19b31a1ea3f1a67e5ef46346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 27 Jan 2025 21:50:32 +0100 Subject: [PATCH 60/71] chore: bump deps # Conflicts: # caddy/go.mod # caddy/go.sum --- caddy/go.mod | 40 +++++++-------- caddy/go.sum | 142 +++++++++++++++++++++++++-------------------------- go.mod | 8 +-- go.sum | 8 +++ 4 files changed, 102 insertions(+), 96 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index ff12f32f..6d42b6a6 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -12,7 +12,7 @@ retract ( replace github.com/dunglas/mercure => ../ require ( - github.com/MicahParks/keyfunc/v3 v3.3.5 + github.com/MicahParks/keyfunc/v3 v3.3.10 github.com/caddyserver/caddy/v2 v2.9.1 github.com/dunglas/mercure v0.18.1 github.com/prometheus/client_golang v1.20.5 @@ -21,7 +21,7 @@ require ( ) require ( - cel.dev/expr v0.19.1 // indirect + cel.dev/expr v0.19.2 // indirect dario.cat/mergo v1.0.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect @@ -30,7 +30,7 @@ require ( github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145 // indirect - github.com/MicahParks/jwkset v0.6.0 // indirect + github.com/MicahParks/jwkset v0.8.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/RoaringBitmap/roaring v1.9.4 // indirect github.com/alecthomas/chroma/v2 v2.14.0 // indirect @@ -38,7 +38,7 @@ require ( github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.20.0 // indirect - github.com/caddyserver/certmagic v0.21.6 // indirect + github.com/caddyserver/certmagic v0.21.7 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect @@ -68,11 +68,11 @@ require ( github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/cel-go v0.22.1 // indirect + github.com/google/cel-go v0.23.0 // indirect github.com/google/certificate-transparency-go v1.2.2 // indirect - github.com/google/go-tpm v0.9.2 // indirect + github.com/google/go-tpm v0.9.3 // indirect github.com/google/go-tspi v0.3.0 // indirect - github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect + github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/mux v1.8.1 // indirect @@ -91,11 +91,11 @@ require ( github.com/libdns/libdns v0.2.2 // indirect github.com/magiconair/properties v1.8.9 // indirect github.com/manifoldco/promptui v0.9.0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect - github.com/mholt/acmez/v3 v3.0.0 // indirect - github.com/miekg/dns v1.1.62 // indirect + github.com/mholt/acmez/v3 v3.0.1 // indirect + github.com/miekg/dns v1.1.63 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -108,13 +108,13 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.61.0 // indirect + github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/quic-go/qpack v0.5.1 // indirect - github.com/quic-go/quic-go v0.48.2 // indirect + github.com/quic-go/quic-go v0.49.0 // indirect github.com/rs/xid v1.6.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sagikazarmark/locafero v0.6.0 // indirect + github.com/sagikazarmark/locafero v0.7.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect @@ -128,7 +128,7 @@ require ( github.com/smallstep/scep v0.0.0-20241223071629-a37a330173bc // indirect github.com/smallstep/truststore v0.13.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/afero v1.12.0 // indirect github.com/spf13/cast v1.7.1 // indirect github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect @@ -157,14 +157,14 @@ require ( go.opentelemetry.io/otel/sdk v1.32.0 // indirect go.opentelemetry.io/otel/trace v1.32.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect - go.step.sm/crypto v0.56.0 // indirect + go.step.sm/crypto v0.57.0 // indirect go.step.sm/linkedca v0.22.2 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap/exp v0.3.0 // indirect golang.org/x/crypto v0.32.0 // indirect - golang.org/x/crypto/x509roots/fallback v0.0.0-20250106144430-8929309228b4 // indirect + golang.org/x/crypto/x509roots/fallback v0.0.0-20250118192723-a8ea4be81f07 // indirect golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect golang.org/x/mod v0.22.0 // indirect golang.org/x/net v0.34.0 // indirect @@ -175,10 +175,10 @@ require ( golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.9.0 // indirect golang.org/x/tools v0.29.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422 // indirect - google.golang.org/grpc v1.69.2 // indirect - google.golang.org/protobuf v1.36.2 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250127172529-29210b9bc287 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 // indirect + google.golang.org/grpc v1.70.0 // indirect + google.golang.org/protobuf v1.36.4 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/caddy/go.sum b/caddy/go.sum index 4780dcd7..e4d5aac2 100644 --- a/caddy/go.sum +++ b/caddy/go.sum @@ -1,5 +1,5 @@ -cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4= -cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +cel.dev/expr v0.19.2 h1:V354PbqIXr9IQdwy4SYA4xa0HXaWq1BUPAGzugBY5V4= +cel.dev/expr v0.19.2/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -15,8 +15,8 @@ cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4 cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/iam v1.2.2 h1:ozUSofHUGf/F4tCNy/mu9tHLTaxZFLOUiKzjcgWHGIA= cloud.google.com/go/iam v1.2.2/go.mod h1:0Ys8ccaZHdI1dEUilwzqng/6ps2YB6vRsjIe00/+6JY= -cloud.google.com/go/kms v1.20.2 h1:NGTHOxAyhDVUGVU5KngeyGScrg2D39X76Aphe6NC7S0= -cloud.google.com/go/kms v1.20.2/go.mod h1:LywpNiVCvzYNJWS9JUcGJSVTNSwPwi0vBAotzDqn2nc= +cloud.google.com/go/kms v1.20.4 h1:CJ0hMpOg1ANN9tx/a/GPJ+Uxudy8k6f3fvGFuTHiE5A= +cloud.google.com/go/kms v1.20.4/go.mod h1:gPLsp1r4FblUgBYPOcvI/bUPpdMg2Jm1ZVKU4tQUfcc= cloud.google.com/go/longrunning v0.6.2 h1:xjDfh1pQcWPEvnfjZmwjKQEcHnpz6lHjfy7Fo0MK+hc= cloud.google.com/go/longrunning v0.6.2/go.mod h1:k/vIs83RN4bE3YCswdXC5PFfWVILjm3hpEUlSko4PiI= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= @@ -42,10 +42,10 @@ github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSC github.com/MauriceGit/skiplist v0.0.0-20191117202105-643e379adb62/go.mod h1:877WBceefKn14QwVVn4xRFUsHsZb9clICgdeTj4XsUg= github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145 h1:1yw6O62BReQ+uA1oyk9XaQTvLhcoHWmoQAgXmDFXpIY= github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145/go.mod h1:877WBceefKn14QwVVn4xRFUsHsZb9clICgdeTj4XsUg= -github.com/MicahParks/jwkset v0.6.0 h1:l9BdSMVzhmEFXTTlTPIhK2FuDTFYawMA1hrpxQRajBI= -github.com/MicahParks/jwkset v0.6.0/go.mod h1:lNJLP4R63A/8lT9GO6FWOr/fIooTSwViFijyxwIW9EU= -github.com/MicahParks/keyfunc/v3 v3.3.5 h1:7ceAJLUAldnoueHDNzF8Bx06oVcQ5CfJnYwNt1U3YYo= -github.com/MicahParks/keyfunc/v3 v3.3.5/go.mod h1:SdCCyMJn/bYqWDvARspC6nCT8Sk74MjuAY22C7dCST8= +github.com/MicahParks/jwkset v0.8.0 h1:jHtclI38Gibmu17XMI6+6/UB59srp58pQVxePHRK5o8= +github.com/MicahParks/jwkset v0.8.0/go.mod h1:fVrj6TmG1aKlJEeceAz7JsXGTXEn72zP1px3us53JrA= +github.com/MicahParks/keyfunc/v3 v3.3.10 h1:JtEGE8OcNeI297AMrR4gVXivV8fyAawFUMkbwNreJRk= +github.com/MicahParks/keyfunc/v3 v3.3.10/go.mod h1:1TEt+Q3FO7Yz2zWeYO//fMxZMOiar808NqjWQQpBPtU= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= @@ -68,32 +68,32 @@ github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmO github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b h1:uUXgbcPDK3KpW29o4iy7GtuappbWT0l5NaMo9H9pJDw= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-sdk-go-v2 v1.32.6 h1:7BokKRgRPuGmKkFMhEg/jSul+tB9VvXhcViILtfG8b4= -github.com/aws/aws-sdk-go-v2 v1.32.6/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= -github.com/aws/aws-sdk-go-v2/config v1.28.6 h1:D89IKtGrs/I3QXOLNTH93NJYtDhm8SYa9Q5CsPShmyo= -github.com/aws/aws-sdk-go-v2/config v1.28.6/go.mod h1:GDzxJ5wyyFSCoLkS+UhGB0dArhb9mI+Co4dHtoTxbko= -github.com/aws/aws-sdk-go-v2/credentials v1.17.47 h1:48bA+3/fCdi2yAwVt+3COvmatZ6jUDNkDTIsqDiMUdw= -github.com/aws/aws-sdk-go-v2/credentials v1.17.47/go.mod h1:+KdckOejLW3Ks3b0E3b5rHsr2f9yuORBum0WPnE5o5w= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 h1:AmoU1pziydclFT/xRV+xXE/Vb8fttJCLRPv8oAkprc0= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21/go.mod h1:AjUdLYe4Tgs6kpH4Bv7uMZo7pottoyHMn4eTcIcneaY= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 h1:s/fF4+yDQDoElYhfIVvSNyeCydfbuTKzhxSXDXCPasU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25/go.mod h1:IgPfDv5jqFIzQSNbUEMoitNooSMXjRSDkhXv8jiROvU= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 h1:ZntTCl5EsYnhN/IygQEUugpdwbhdkom9uHcbCftiGgA= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25/go.mod h1:DBdPrgeocww+CSl1C8cEV8PN1mHMBhuCDLpXezyvWkE= +github.com/aws/aws-sdk-go-v2 v1.32.8 h1:cZV+NUS/eGxKXMtmyhtYPJ7Z4YLoI/V8bkTdRZfYhGo= +github.com/aws/aws-sdk-go-v2 v1.32.8/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= +github.com/aws/aws-sdk-go-v2/config v1.28.10 h1:fKODZHfqQu06pCzR69KJ3GuttraRJkhlC8g80RZ0Dfg= +github.com/aws/aws-sdk-go-v2/config v1.28.10/go.mod h1:PvdxRYZ5Um9QMq9PQ0zHHNdtKK+he2NHtFCUFMXWXeg= +github.com/aws/aws-sdk-go-v2/credentials v1.17.51 h1:F/9Sm6Y6k4LqDesZDPJCLxQGXNNHd/ZtJiWd0lCZKRk= +github.com/aws/aws-sdk-go-v2/credentials v1.17.51/go.mod h1:TKbzCHm43AoPyA+iLGGcruXd4AFhF8tOmLex2R9jWNQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.23 h1:IBAoD/1d8A8/1aA8g4MBVtTRHhXRiNAgwdbo/xRM2DI= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.23/go.mod h1:vfENuCM7dofkgKpYzuzf1VT1UKkA/YL3qanfBn7HCaA= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.27 h1:jSJjSBzw8VDIbWv+mmvBSP8ezsztMYJGH+eKqi9AmNs= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.27/go.mod h1:/DAhLbFRgwhmvJdOfSm+WwikZrCuUJiA4WgJG0fTNSw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.27 h1:l+X4K77Dui85pIj5foXDhPlnqcNRG2QUyvca300lXh8= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.27/go.mod h1:KvZXSFEXm6x84yE8qffKvT3x8J5clWnVFXphpohhzJ8= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 h1:50+XsN70RS7dwJ2CkVNXzj7U2L1HKP8nqTd3XWEXBN4= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6/go.mod h1:WqgLmwY7so32kG01zD8CPTJWVWM+TzJoOVHwTg4aPug= -github.com/aws/aws-sdk-go-v2/service/kms v1.37.7 h1:dZmNIRtPUvtvUIIDVNpvtnJQ8N8Iqm7SQAxf18htZYw= -github.com/aws/aws-sdk-go-v2/service/kms v1.37.7/go.mod h1:vj8PlfJH9mnGeIzd6uMLPi5VgiqzGG7AZoe1kf1uTXM= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 h1:rLnYAfXQ3YAccocshIH5mzNNwZBkBo+bP6EhIxak6Hw= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.7/go.mod h1:ZHtuQJ6t9A/+YDuxOLnbryAmITtr8UysSny3qcyvJTc= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 h1:JnhTZR3PiYDNKlXy50/pNeix9aGMo6lLpXwJ1mw8MD4= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6/go.mod h1:URronUEGfXZN1VpdktPSD1EkAL9mfrV+2F4sjH38qOY= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 h1:s4074ZO1Hk8qv65GqNXqDjmkf4HSQqJukaLuuW0TpDA= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.2/go.mod h1:mVggCnIWoM09jP71Wh+ea7+5gAp53q+49wDFs1SW5z8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.8 h1:cWno7lefSH6Pp+mSznagKCgfDGeZRin66UvYUqAkyeA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.8/go.mod h1:tPD+VjU3ABTBoEJ3nctu5Nyg4P4yjqSH5bJGGkY4+XE= +github.com/aws/aws-sdk-go-v2/service/kms v1.37.8 h1:KbLZjYqhQ9hyB4HwXiheiflTlYQa0+Fz0Ms/rh5f3mk= +github.com/aws/aws-sdk-go-v2/service/kms v1.37.8/go.mod h1:ANs9kBhK4Ghj9z1W+bsr3WsNaPF71qkgd6eE6Ekol/Y= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.9 h1:YqtxripbjWb2QLyzRK9pByfEDvgg95gpC2AyDq4hFE8= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.9/go.mod h1:lV8iQpg6OLOfBnqbGMBKYjilBlf633qwHnBEiMSPoHY= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.8 h1:6dBT1Lz8fK11m22R+AqfRsFn8320K0T5DTGxxOQBSMw= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.8/go.mod h1:/kiBvRQXBc6xeJTYzhSdGvJ5vm1tjaDEjH+MSeRJnlY= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.6 h1:VwhTrsTuVn52an4mXx29PqRzs2Dvu921NpGk7y43tAM= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.6/go.mod h1:+8h7PZb3yY5ftmVLD7ocEoE98hdc8PoKS0H3wfx1dlc= github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -107,8 +107,8 @@ github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBT github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/caddyserver/caddy/v2 v2.9.1 h1:OEYiZ7DbCzAWVb6TNEkjRcSCRGHVoZsJinoDR/n9oaY= github.com/caddyserver/caddy/v2 v2.9.1/go.mod h1:ImUELya2el1FDVp3ahnSO2iH1or1aHxlQEQxd/spP68= -github.com/caddyserver/certmagic v0.21.6 h1:1th6GfprVfsAtFNOu4StNMF5IxK5XiaI0yZhAHlZFPE= -github.com/caddyserver/certmagic v0.21.6/go.mod h1:n1sCo7zV1Ez2j+89wrzDxo4N/T1Ws/Vx8u5NvuBFabw= +github.com/caddyserver/certmagic v0.21.7 h1:66KJioPFJwttL43KYSWk7ErSmE6LfaJgCQuhm8Sg6fg= +github.com/caddyserver/certmagic v0.21.7/go.mod h1:LCPG3WLxcnjVKl/xpjzM0gqh0knrKKKiO5WVttX2eEI= github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= @@ -209,8 +209,8 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/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/cel-go v0.22.1 h1:AfVXx3chM2qwoSbM7Da8g8hX8OVSkBFwX+rz2+PcK40= -github.com/google/cel-go v0.22.1/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8= +github.com/google/cel-go v0.23.0 h1:knsnzeUOcREUFo0ZFJqZI8Rk6uEVyobAlir7GEbf5v0= +github.com/google/cel-go v0.23.0/go.mod h1:52Pb6QsDbC5kvgxvZhiL9QX1oZEkcUF/ZqaPx1J5Wwo= github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/certificate-transparency-go v1.2.2 h1:5TAzjQnCfN1vps2XWUgU6Svt++rgy9a+b8CBYXaKUAo= github.com/google/certificate-transparency-go v1.2.2/go.mod h1:d1o5XNQzK/yz8IXzEce6KXgMxfter/EcMP9vG4dBRNE= @@ -220,16 +220,16 @@ 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-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/go-tpm v0.9.2 h1:Gh8CMnMm06b09DmcsuY9fI3oF69188lGXCpiT/a05T4= -github.com/google/go-tpm v0.9.2/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= +github.com/google/go-tpm v0.9.3 h1:+yx0/anQuGzi+ssRqeD6WpXjW2L/V0dItUayO0i9sRc= +github.com/google/go-tpm v0.9.3/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= github.com/google/go-tpm-tools v0.4.4 h1:oiQfAIkc6xTy9Fl5NKTeTJkBTlXdHsxAofmQyxBKY98= github.com/google/go-tpm-tools v0.4.4/go.mod h1:T8jXkp2s+eltnCDIsXR84/MTcVU9Ja7bh3Mit0pa4AY= github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus= github.com/google/go-tspi v0.3.0/go.mod h1:xfMGI3G0PhxCdNVcYr1C4C+EizojDg/TXuX5by8CiHI= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0 h1:my2ucqBZmv+cWHIhZNSIYKzgN8EBGyHdC7zD5sASRAg= +github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -239,8 +239,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKG github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= -github.com/googleapis/gax-go/v2 v2.14.0 h1:f+jMrjBPl+DL9nI4IQzLUxMq7XrAqFYB7hBPqMNIe8o= -github.com/googleapis/gax-go/v2 v2.14.0/go.mod h1:lhBCnjdLrWRaPvLWhmc8IS24m9mr07qSYnHncrgo+zk= +github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= +github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= @@ -302,19 +302,18 @@ github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3v github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +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.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 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/mholt/acmez/v3 v3.0.0 h1:r1NcjuWR0VaKP2BTjDK9LRFBw/WvURx3jlaEUl9Ht8E= -github.com/mholt/acmez/v3 v3.0.0/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= +github.com/mholt/acmez/v3 v3.0.1 h1:4PcjKjaySlgXK857aTfDuRbmnM5gb3Ruz3tvoSJAUp8= +github.com/mholt/acmez/v3 v3.0.1/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= -github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= -github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= +github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY= +github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -360,15 +359,15 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: 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-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ= -github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s= +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-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 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/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= -github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE= -github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= +github.com/quic-go/quic-go v0.49.0 h1:w5iJHXwHxs1QxyBv1EHKuC50GX5to8mJAxvtnttJp94= +github.com/quic-go/quic-go v0.49.0/go.mod h1:s2wDnmCdooUQBmQfpUSTCYBl1/D4FcqbULMMkASvR6s= 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/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= @@ -376,8 +375,8 @@ github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= 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/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= -github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= +github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= +github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/schollz/jsonstore v1.1.0 h1:WZBDjgezFS34CHI+myb4s8GGpir3UMpy7vWoCeO0n6E= @@ -438,8 +437,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= +github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= @@ -526,14 +525,14 @@ go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZk go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= -go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= -go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= +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.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.step.sm/crypto v0.56.0 h1:KcFfV76cI9Xaw8bdSc9x55skyuSdcHcTdL37vvVZnvY= -go.step.sm/crypto v0.56.0/go.mod h1:snWNloxY9s1W+HsFqcviq55nvzbqqX6LxVt0Vktv5mw= +go.step.sm/crypto v0.57.0 h1:YjoRQDaJYAxHLVwjst0Bl0xcnoKzVwuHCJtEo2VSHYU= +go.step.sm/crypto v0.57.0/go.mod h1:+Lwp5gOVPaTa3H/Ul/TzGbxQPXZZcKIUGMS0lG6n9Go= go.step.sm/linkedca v0.22.2 h1:zmFIyDC77gFHo6FLQJ8OIXYpLYDIsgDWaYqtYs6A9/Q= go.step.sm/linkedca v0.22.2/go.mod h1:ESY8r5VfhJA8ZVzI6hXIQcEX9LwaY3aoPnT+Hb9jpbw= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= @@ -561,8 +560,8 @@ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/crypto/x509roots/fallback v0.0.0-20250106144430-8929309228b4 h1:2UmVXDw2sT/v4mRp1tucroUkHyqAbK1SXfh+ss3sKsE= -golang.org/x/crypto/x509roots/fallback v0.0.0-20250106144430-8929309228b4/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= +golang.org/x/crypto/x509roots/fallback v0.0.0-20250118192723-a8ea4be81f07 h1:Tuk3hxOkRoX4Xwph6/tRU1wGumEsVYM2TZfvAC6MllM= +golang.org/x/crypto/x509roots/fallback v0.0.0-20250118192723-a8ea4be81f07/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= @@ -628,7 +627,6 @@ golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBc 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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -680,8 +678,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/api v0.212.0 h1:BcRj3MJfHF3FYD29rk7u9kuu1SyfGqfHcA0hSwKqkHg= -google.golang.org/api v0.212.0/go.mod h1:gICpLlpp12/E8mycRMzgy3SQ9cFh2XnVJ6vJi/kQbvI= +google.golang.org/api v0.216.0 h1:xnEHy+xWFrtYInWPy8OdGFsyIfWJjtVnO39g7pz2BFY= +google.golang.org/api v0.216.0/go.mod h1:K9wzQMvWi47Z9IU7OgdOofvZuw75Ge3PPITImZR/UyI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -693,18 +691,18 @@ google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk= google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc= -google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 h1:GVIKPyP/kLIyVOgOnTwFOrvQaQUzOzGMCxgFUOEmm24= -google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422 h1:3UsHvIr4Wc2aW4brOaSCmcxh9ksica6fHEr8P1XhkYw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4= +google.golang.org/genproto/googleapis/api v0.0.0-20250127172529-29210b9bc287 h1:A2ni10G3UlplFrWdCDJTl7D7mJ7GSRm37S+PDimaKRw= +google.golang.org/genproto/googleapis/api v0.0.0-20250127172529-29210b9bc287/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 h1:J1H9f+LEdWAfHcez/4cvaVBox7cOYT+IU6rgqj5x++8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU= -google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= -google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= -google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +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/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= +google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/go.mod b/go.mod index b79312fb..c6aa933c 100644 --- a/go.mod +++ b/go.mod @@ -47,12 +47,12 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/common v0.61.0 // indirect + github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/sagikazarmark/locafero v0.6.0 // indirect + github.com/sagikazarmark/locafero v0.7.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/afero v1.12.0 // indirect github.com/spf13/cast v1.7.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect @@ -60,7 +60,7 @@ require ( golang.org/x/net v0.34.0 // indirect golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect - google.golang.org/protobuf v1.36.2 // indirect + google.golang.org/protobuf v1.36.4 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 6d76a870..9dbe3133 100644 --- a/go.sum +++ b/go.sum @@ -69,6 +69,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ= github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s= +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.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -76,12 +78,16 @@ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncj github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= +github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= +github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= +github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= @@ -123,6 +129,8 @@ golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= +google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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= From 1b58398f1a11575d227f9721b79da4f22dc982b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 27 Jan 2025 22:17:10 +0100 Subject: [PATCH 61/71] chore: prepare release 0.18.2 --- caddy/go.mod | 2 +- charts/mercure/Chart.yaml | 4 ++-- charts/mercure/README.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index 6d42b6a6..db7b94ec 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -14,7 +14,7 @@ replace github.com/dunglas/mercure => ../ require ( github.com/MicahParks/keyfunc/v3 v3.3.10 github.com/caddyserver/caddy/v2 v2.9.1 - github.com/dunglas/mercure v0.18.1 + github.com/dunglas/mercure v0.18.2 github.com/prometheus/client_golang v1.20.5 github.com/stretchr/testify v1.10.0 go.uber.org/zap v1.27.0 diff --git a/charts/mercure/Chart.yaml b/charts/mercure/Chart.yaml index cb2fc5b6..de75cbee 100644 --- a/charts/mercure/Chart.yaml +++ b/charts/mercure/Chart.yaml @@ -12,8 +12,8 @@ keywords: - streaming-api - async-api type: application -version: 0.18.1 -appVersion: "v0.18.1" +version: 0.18.2 +appVersion: "v0.18.2" maintainers: - name: dunglas email: kevin@dunglas.fr diff --git a/charts/mercure/README.md b/charts/mercure/README.md index cebf7ffb..7aeaf3ae 100644 --- a/charts/mercure/README.md +++ b/charts/mercure/README.md @@ -1,7 +1,7 @@ # Mercure Chart for Kubernetes -![Version: 0.18.1](https://img.shields.io/badge/Version-0.18.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.18.1](https://img.shields.io/badge/AppVersion-v0.18.1-informational?style=flat-square) +![Version: 0.18.2](https://img.shields.io/badge/Version-0.18.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.18.2](https://img.shields.io/badge/AppVersion-v0.18.2-informational?style=flat-square) A Helm chart to install a Mercure Hub in a Kubernetes cluster. Mercure is a protocol to push data updates to web browsers and other HTTP clients in a convenient, fast, reliable and battery-efficient way. From 6c2d07d96b9f140d412a622cf07bc78b28e0415c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 30 Jan 2025 14:10:29 +0100 Subject: [PATCH 62/71] docs: updated docs for Mercure On Premise (#1002) * docs: updated docs for Mercure On Premise * linter --- docs/hub/cluster.md | 77 ++++++++++++++++++++++++++++++--------------- docs/hub/config.md | 12 +++---- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/docs/hub/cluster.md b/docs/hub/cluster.md index 760c253c..ac7e3fba 100644 --- a/docs/hub/cluster.md +++ b/docs/hub/cluster.md @@ -70,23 +70,31 @@ The Redis transport should fit most use cases. To install Redis, [read the documentation](https://redis.io/topics/quickstart). Most Cloud Computing platforms also provide managed versions of Redis. + + | Feature | Supported | |-----------------|-----------| | History | ✅ | | Presence API | ✅ | | Custom event ID | ✅ | -##### Configuration +##### Redis Configuration + +The following options can be passed to the `transport` directive: + +| Option | Description | +|--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------| +| `address` or `addresses` | the address(es) of the Redis server(s), you can pass several addresses to use several Redis servers (ex: `addresses host1:6379 host2:6379`, required) | +| `stream` | the name of the Redis stream to use (required) | +| `password` | the Redis password | +| `tls` | enable TLS support | +| `max_length` | the approximate maximum number of messages to store in the history, set to `0` to store all messages | All [the configuration parameters and formats](https://mercure.rocks/docs/hub/config) supported by the free Mercure.rocks Hub are also available. -To use Redis, the `MERCURE_TRANSPORT_URL` environment variable must be set like in this example: +###### Legacy Redis URL - MERCURE_TRANSPORT_URL=redis://127.0.0.1:6379/mercure-ha \ - MERCURE_LICENSE=snip \ - MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \ - MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \ - ./mercure run +**This feature is deprecated: use the new `transport` directive instead**. The following options can be passed as query parameters of the URL set in `transport_url`: @@ -100,6 +108,8 @@ The following options can be passed as query parameters of the URL set in `trans The PostgreSQL Transport allows to store permanently the event and to query them using the full power of SQL. It is mostly useful when using the Mercure.rocks Hub as an event store, or as a primary data store. +This feature uses PostgreSQL `LISTEN`/`NOTIFY`. + To install PostgreSQL, [read the documentation](https://www.postgresql.org/docs/12/tutorial-install.html). Most Cloud Computing platforms also provide managed versions of PostgreSQL. @@ -111,15 +121,19 @@ Most Cloud Computing platforms also provide managed versions of PostgreSQL. ##### PostgreSQL Configuration +The following options can be passed to the `transport` directive: + +| Option | Description | +|--------|-------------------------------------------------------------------------------------------------------------| +| `url` | The URL (DSN) to use to connect to Postgres (ex: `postgres://user:password@127.0.0.1/mercure-ha`, required) | + +[Options supported by `libpq`](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING) can be passed as query parameters of the URL set in `_url`. + All [the configuration parameters and formats](https://mercure.rocks/docs/hub/config) supported by the free Mercure.rocks Hub are also available. -To use PostgreSQL `LISTEN`/`NOTIFY`, the `MERCURE_TRANSPORT_URL` environment variable must be set like in this example: +###### Legacy PostgreSQL URL - MERCURE_TRANSPORT_URL=postgres://user:password@127.0.0.1/mercure-ha \ - MERCURE_LICENSE=snip \ - MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \ - MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \ - ./mercure run +**This feature is deprecated: use the new `transport` directive instead**. [Options supported by `libpq`](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING) can be passed as query parameters of the URL set in `transport_url`. @@ -145,15 +159,22 @@ The Mercure.rocks hub has been tested with: ##### Kafka Configuration +The following options can be passed to the `transport` directive: + +| Option | Description | +|--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------| +| `address` or `addresses` | the address(es) of the Kafka server(s), you can pass several addresses to use several Kafka servers (ex: `addresses host1:9092 host2:9092`, required) | +| `topic` | the name of the Kafka topic to use, **all Mercure.rocks hub instances must use the same topic** (required) | +| `consumer_group` | the consumer group of this node, **must be different for every instance of the Mercure.rocks hub** | +| `user` | the Kafka SASL user (optional) | +| `password` | the Kafka SASL password (optional) | +| `tls` | enable TLS support | + All [the configuration parameters and formats](https://mercure.rocks/docs/hub/config) supported by the free Mercure.rocks Hub are also available. -To use Kafka, the `MERCURE_TRANSPORT_URL` environment variable must be set like in this example: +###### Legacy Kafka URL - MERCURE_TRANSPORT_URL=kafka://kafka/?addr=localhost:9092&topic=mercure-ha \ - MERCURE_LICENSE=snip \ - MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \ - MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \ - ./mercure run +**This feature is deprecated: use the new `transport` directive instead**. The following options can be passed as query parameters of the URL set in `transport_url`: @@ -161,7 +182,7 @@ The following options can be passed as query parameters of the URL set in `trans |------------------|---------------------------------------------------------------------------------------------------------------------------------------------| | `addr` | addresses of the Kafka servers, you can pass several `addr` parameters to use several Kafka servers (ex: `addr=host1:9092&addr=host2:9092`) | | `topic` | the name of the Kafka topic to use (ex: `topic=mercure-ha`), **all Mercure.rocks hub instances must use the same topic** | -| `consumer_group` | consumer group, **must be different for every instance of the Mercure.rocks hub** (ex: `consumer_group=`) | +| `consumer_group` | the consumer group of this node, **must be different for every instance of the Mercure.rocks hub** (ex: `consumer_group=`) | | `user` | Kafka SASL user (optional, ex: `user=kevin`) | | `password` | Kafka SASL password (optional, ex: `password=maman`) | | `tls` | Set to `1` to enable TLS (ex: `tls=1`) | @@ -180,15 +201,19 @@ To install Apache Pulsar, [read the documentation](https://pulsar.apache.org/doc ##### Pulsar Configuration +The following options can be passed to the `transport` directive: + +| Option | Description | +|---------------------|-------------------------------------------------------------------------------------------------------------| +| `url` | the address of the Pulsar server (required) | +| `topic` | the name of the Pulsar topic to use, **all Mercure.rocks hub instances must use the same topic** (required) | +| `subscription_name` | the subscription name for this node, **must be different for every instance of the Mercure.rocks hub** | + All [the configuration parameters and formats](https://mercure.rocks/docs/hub/config) supported by the free Mercure.rocks Hub are also available. -To use Pulsar, the `MERCURE_TRANSPORT_URL` environment variable must be set like in this example: +###### Legacy Pulsar URL - MERCURE_TRANSPORT_URL=pulsar://localhost:6650?topic=mercure-ha&subscription_name=the-node-id \ - MERCURE_LICENSE=snip \ - MERCURE_PUBLISHER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \ - MERCURE_SUBSCRIBER_JWT_KEY='!ChangeThisMercureHubJWTSecretKey!' \ - ./mercure run +**This feature is deprecated: use the new `transport` directive instead**. The following options can be passed as query parameters of the URL set in `transport_url`: diff --git a/docs/hub/config.md b/docs/hub/config.md index c85b6d66..08afd91c 100644 --- a/docs/hub/config.md +++ b/docs/hub/config.md @@ -127,12 +127,12 @@ MERCURE_SUBSCRIBER_JWT_ALG=RS256 \ ## Bolt Adapter -| Option | Description | -|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `path` | path of the database file (default: `mercure.db`) | -| `bucket_name` | name of the bolt bucket to store events. default to `updates` | -| `cleanup_frequency` | chances to trigger history cleanup when an update occurs, must be a number between `0` (never cleanup) and `1` (cleanup after every publication), default to `0.3`. | -| `size` | size of the history (to retrieve lost messages using the `Last-Event-ID` header), set to `0` to never remove old events (default) | +| Option | Description | +|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `path` | path of the database file (default: `mercure.db`) | +| `bucket_name` | name of the bolt bucket to store events (default: `updates`) | +| `cleanup_frequency` | chances to trigger history cleanup when an update occurs, must be a number between `0` (never cleanup) and `1` (cleanup after every publication, default to `0.3`) | +| `size` | size of the history (to retrieve lost messages using the `Last-Event-ID` header), set to `0` to never remove old events (default) | You can visualize and edit the content of the database using [boltdbweb](https://github.com/evnix/boltdbweb). From 107e6b8c8fa0699a1721390a2208ad5f259f7652 Mon Sep 17 00:00:00 2001 From: Indra Gunawan Date: Wed, 12 Feb 2025 19:56:44 +0800 Subject: [PATCH 63/71] fix: missing metrics with Caddy 2.9 (#1007) --- caddy/mercure.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/caddy/mercure.go b/caddy/mercure.go index 304869f2..0adc0fbd 100644 --- a/caddy/mercure.go +++ b/caddy/mercure.go @@ -20,7 +20,6 @@ import ( "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" "github.com/caddyserver/caddy/v2/modules/caddyhttp" "github.com/dunglas/mercure" - "github.com/prometheus/client_golang/prometheus" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) @@ -29,7 +28,6 @@ const defaultHubURL = "/.well-known/mercure" var ( ErrCompatibility = errors.New("compatibility mode only supports protocol version 7") - metrics = mercure.NewPrometheusMetrics(prometheus.DefaultRegisterer) //nolint:gochecknoglobals // Deprecated: use transports Caddy modules. transports = caddy.NewUsagePool() //nolint:gochecknoglobals @@ -189,6 +187,8 @@ func createTransportLegacy(m *Mercure) (mercure.Transport, error) { //nolint:wrapcheck func (m *Mercure) Provision(ctx caddy.Context) error { //nolint:funlen,gocognit + metrics := mercure.NewPrometheusMetrics(ctx.GetMetricsRegistry()) + if err := m.populateJWTConfig(); err != nil { return err } From 53f2d855640671c832a79658b5660df537eb90f0 Mon Sep 17 00:00:00 2001 From: Ernesto Serrano Date: Mon, 17 Feb 2025 10:16:51 +0100 Subject: [PATCH 64/71] Fixed the ssl error on proxied nginx (#1005) --- docs/hub/nginx.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/hub/nginx.md b/docs/hub/nginx.md index c5b1e6e8..bf3464ea 100644 --- a/docs/hub/nginx.md +++ b/docs/hub/nginx.md @@ -16,6 +16,9 @@ server { proxy_http_version 1.1; proxy_set_header Connection ""; + # Enable fast reply in SSE + proxy_buffering off; + ## Be sure to set USE_FORWARDED_HEADERS=1 to allow the hub to use those headers ## proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; From a2c0f38c50a2afac13c26d477fa249483fd58302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 17 Feb 2025 10:33:28 +0100 Subject: [PATCH 65/71] chore: upgrade to Go 1.24 (#1008) * chore: upgrade to Go 1.24 * ci: fix goreleaser deprecations --- .github/workflows/cd.yml | 6 +- .github/workflows/ci.yml | 11 +-- .goreleaser.yml | 4 +- caddy/go.mod | 54 ++++++------- caddy/go.sum | 170 ++++++++++++++++++++------------------- go.mod | 22 ++--- go.sum | 50 +++++------- publish_test.go | 6 +- 8 files changed, 159 insertions(+), 164 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 53e59c2d..e1ffcd47 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -17,6 +17,9 @@ permissions: id-token: write attestations: write +env: + GOTOOLCHAIN: local + jobs: release: runs-on: ubuntu-latest @@ -29,7 +32,8 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "1.23" + go-version: "1.24" + check-latest: true cache-dependency-path: | go.sum caddy/go.sum diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4f885102..2c9ccd14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ on: - v*.*.* env: - GO111MODULE: "on" + GOTOOLCHAIN: local jobs: golangci: @@ -23,7 +23,7 @@ jobs: - uses: actions/setup-go@v5 with: - go-version: "1.23" + go-version: "1.24" cache-dependency-path: | go.sum caddy/go.sum @@ -37,13 +37,10 @@ jobs: test: strategy: matrix: - go: ["1.21", "1.22", "1.23"] + go: ["1.23", "1.24"] fail-fast: false name: Test runs-on: ubuntu-latest - env: - # Temporary workaround for https://github.com/golang/go/issues/65653 - GOEXPERIMENT: nocoverageredesign steps: - name: Checkout uses: actions/checkout@v4 @@ -57,8 +54,6 @@ jobs: caddy/go.sum - name: Use go-deadlock - # Blocked by https://github.com/sasha-s/go-deadlock/issues/34 - if: matrix.go != '1.23' run: ./tests/use-go-deadlock.sh - name: Test diff --git a/.goreleaser.yml b/.goreleaser.yml index 3eb4ca7c..2766f624 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -71,7 +71,7 @@ archives: - dev.Caddyfile format_overrides: - goos: windows - format: zip + formats: [ zip ] - id: legacy builds: - legacy @@ -88,7 +88,7 @@ archives: - README.md format_overrides: - goos: windows - format: zip + formats: [ zip ] dockers: - ids: - caddy diff --git a/caddy/go.mod b/caddy/go.mod index db7b94ec..2b6f916f 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -1,8 +1,8 @@ module github.com/dunglas/mercure/caddy -go 1.22.7 +go 1.23.0 -toolchain go1.23.2 +toolchain go1.24.0 retract ( v0.14.7 // CI problem @@ -15,13 +15,12 @@ require ( github.com/MicahParks/keyfunc/v3 v3.3.10 github.com/caddyserver/caddy/v2 v2.9.1 github.com/dunglas/mercure v0.18.2 - github.com/prometheus/client_golang v1.20.5 github.com/stretchr/testify v1.10.0 go.uber.org/zap v1.27.0 ) require ( - cel.dev/expr v0.19.2 // indirect + cel.dev/expr v0.20.0 // indirect dario.cat/mergo v1.0.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect @@ -68,11 +67,11 @@ require ( github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/cel-go v0.23.0 // indirect + github.com/google/cel-go v0.23.2 // indirect github.com/google/certificate-transparency-go v1.2.2 // indirect github.com/google/go-tpm v0.9.3 // indirect github.com/google/go-tspi v0.3.0 // indirect - github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0 // indirect + github.com/google/pprof v0.0.0-20250208200701-d0013a598941 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/mux v1.8.1 // indirect @@ -88,7 +87,7 @@ require ( github.com/kevburnsjr/skipfilter v0.0.1 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect - github.com/libdns/libdns v0.2.2 // indirect + github.com/libdns/libdns v0.2.3 // indirect github.com/magiconair/properties v1.8.9 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect @@ -107,6 +106,7 @@ require ( github.com/pires/go-proxyproto v0.8.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_golang v1.20.5 // 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 @@ -124,14 +124,14 @@ require ( github.com/smallstep/cli-utils v0.10.0 // indirect github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 // indirect github.com/smallstep/nosql v0.7.0 // indirect - github.com/smallstep/pkcs7 v0.1.1 // indirect + github.com/smallstep/pkcs7 v0.2.1 // indirect github.com/smallstep/scep v0.0.0-20241223071629-a37a330173bc // indirect github.com/smallstep/truststore v0.13.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.12.0 // indirect github.com/spf13/cast v1.7.1 // indirect - github.com/spf13/cobra v1.8.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/cobra v1.9.1 // indirect + github.com/spf13/pflag v1.0.6 // indirect github.com/spf13/viper v1.19.0 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect @@ -143,7 +143,7 @@ require ( github.com/yuin/goldmark v1.7.8 // indirect github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc // indirect github.com/zeebo/blake3 v0.2.4 // indirect - go.etcd.io/bbolt v1.3.11 // indirect + go.etcd.io/bbolt v1.4.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 // indirect go.opentelemetry.io/contrib/propagators/autoprop v0.57.0 // indirect go.opentelemetry.io/contrib/propagators/aws v1.32.0 // indirect @@ -157,28 +157,28 @@ require ( go.opentelemetry.io/otel/sdk v1.32.0 // indirect go.opentelemetry.io/otel/trace v1.32.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect - go.step.sm/crypto v0.57.0 // indirect + go.step.sm/crypto v0.57.1 // indirect go.step.sm/linkedca v0.22.2 // indirect go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap/exp v0.3.0 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/crypto/x509roots/fallback v0.0.0-20250118192723-a8ea4be81f07 // indirect - golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect - golang.org/x/mod v0.22.0 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/oauth2 v0.25.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/term v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect - golang.org/x/time v0.9.0 // indirect - golang.org/x/tools v0.29.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250127172529-29210b9bc287 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 // indirect + golang.org/x/crypto v0.33.0 // indirect + golang.org/x/crypto/x509roots/fallback v0.0.0-20250214233241-911360c8a4f4 // indirect + golang.org/x/exp v0.0.0-20250215185904-eff6e970281f // indirect + golang.org/x/mod v0.23.0 // indirect + golang.org/x/net v0.35.0 // indirect + golang.org/x/oauth2 v0.26.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/term v0.29.0 // indirect + golang.org/x/text v0.22.0 // indirect + golang.org/x/time v0.10.0 // indirect + golang.org/x/tools v0.30.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b // indirect google.golang.org/grpc v1.70.0 // indirect - google.golang.org/protobuf v1.36.4 // indirect + google.golang.org/protobuf v1.36.5 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/caddy/go.sum b/caddy/go.sum index e4d5aac2..9ed320ea 100644 --- a/caddy/go.sum +++ b/caddy/go.sum @@ -1,22 +1,22 @@ -cel.dev/expr v0.19.2 h1:V354PbqIXr9IQdwy4SYA4xa0HXaWq1BUPAGzugBY5V4= -cel.dev/expr v0.19.2/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +cel.dev/expr v0.20.0 h1:OunBvVCfvpWlt4dN7zg3FM6TDkzOePe1+foGJ9AXeeI= +cel.dev/expr v0.20.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.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.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= -cloud.google.com/go/auth v0.13.0 h1:8Fu8TZy167JkW8Tj3q7dIkr2v4cndv41ouecJx0PAHs= -cloud.google.com/go/auth v0.13.0/go.mod h1:COOjD9gwfKNKz+IIduatIhYJQIc0mG3H102r/EMxX6Q= -cloud.google.com/go/auth/oauth2adapt v0.2.6 h1:V6a6XDu2lTwPZWOawrAa9HUK+DB2zfJyTuciBG5hFkU= -cloud.google.com/go/auth/oauth2adapt v0.2.6/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8= +cloud.google.com/go/auth v0.14.0 h1:A5C4dKV/Spdvxcl0ggWwWEzzP7AZMJSEIgrkngwhGYM= +cloud.google.com/go/auth v0.14.0/go.mod h1:CYsoRL1PdiDuqeQpZE0bP2pnPrGqFcOkI0nldEQis+A= +cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M= +cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc= cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/iam v1.2.2 h1:ozUSofHUGf/F4tCNy/mu9tHLTaxZFLOUiKzjcgWHGIA= cloud.google.com/go/iam v1.2.2/go.mod h1:0Ys8ccaZHdI1dEUilwzqng/6ps2YB6vRsjIe00/+6JY= -cloud.google.com/go/kms v1.20.4 h1:CJ0hMpOg1ANN9tx/a/GPJ+Uxudy8k6f3fvGFuTHiE5A= -cloud.google.com/go/kms v1.20.4/go.mod h1:gPLsp1r4FblUgBYPOcvI/bUPpdMg2Jm1ZVKU4tQUfcc= +cloud.google.com/go/kms v1.20.5 h1:aQQ8esAIVZ1atdJRxihhdxGQ64/zEbJoJnCz/ydSmKg= +cloud.google.com/go/kms v1.20.5/go.mod h1:C5A8M1sv2YWYy1AE6iSrnddSG9lRGdJq5XEdBy28Lmw= cloud.google.com/go/longrunning v0.6.2 h1:xjDfh1pQcWPEvnfjZmwjKQEcHnpz6lHjfy7Fo0MK+hc= cloud.google.com/go/longrunning v0.6.2/go.mod h1:k/vIs83RN4bE3YCswdXC5PFfWVILjm3hpEUlSko4PiI= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= @@ -68,34 +68,34 @@ github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmO github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b h1:uUXgbcPDK3KpW29o4iy7GtuappbWT0l5NaMo9H9pJDw= github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-sdk-go-v2 v1.32.8 h1:cZV+NUS/eGxKXMtmyhtYPJ7Z4YLoI/V8bkTdRZfYhGo= -github.com/aws/aws-sdk-go-v2 v1.32.8/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= -github.com/aws/aws-sdk-go-v2/config v1.28.10 h1:fKODZHfqQu06pCzR69KJ3GuttraRJkhlC8g80RZ0Dfg= -github.com/aws/aws-sdk-go-v2/config v1.28.10/go.mod h1:PvdxRYZ5Um9QMq9PQ0zHHNdtKK+he2NHtFCUFMXWXeg= -github.com/aws/aws-sdk-go-v2/credentials v1.17.51 h1:F/9Sm6Y6k4LqDesZDPJCLxQGXNNHd/ZtJiWd0lCZKRk= -github.com/aws/aws-sdk-go-v2/credentials v1.17.51/go.mod h1:TKbzCHm43AoPyA+iLGGcruXd4AFhF8tOmLex2R9jWNQ= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.23 h1:IBAoD/1d8A8/1aA8g4MBVtTRHhXRiNAgwdbo/xRM2DI= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.23/go.mod h1:vfENuCM7dofkgKpYzuzf1VT1UKkA/YL3qanfBn7HCaA= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.27 h1:jSJjSBzw8VDIbWv+mmvBSP8ezsztMYJGH+eKqi9AmNs= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.27/go.mod h1:/DAhLbFRgwhmvJdOfSm+WwikZrCuUJiA4WgJG0fTNSw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.27 h1:l+X4K77Dui85pIj5foXDhPlnqcNRG2QUyvca300lXh8= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.27/go.mod h1:KvZXSFEXm6x84yE8qffKvT3x8J5clWnVFXphpohhzJ8= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.8 h1:cWno7lefSH6Pp+mSznagKCgfDGeZRin66UvYUqAkyeA= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.8/go.mod h1:tPD+VjU3ABTBoEJ3nctu5Nyg4P4yjqSH5bJGGkY4+XE= -github.com/aws/aws-sdk-go-v2/service/kms v1.37.8 h1:KbLZjYqhQ9hyB4HwXiheiflTlYQa0+Fz0Ms/rh5f3mk= -github.com/aws/aws-sdk-go-v2/service/kms v1.37.8/go.mod h1:ANs9kBhK4Ghj9z1W+bsr3WsNaPF71qkgd6eE6Ekol/Y= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.9 h1:YqtxripbjWb2QLyzRK9pByfEDvgg95gpC2AyDq4hFE8= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.9/go.mod h1:lV8iQpg6OLOfBnqbGMBKYjilBlf633qwHnBEiMSPoHY= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.8 h1:6dBT1Lz8fK11m22R+AqfRsFn8320K0T5DTGxxOQBSMw= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.8/go.mod h1:/kiBvRQXBc6xeJTYzhSdGvJ5vm1tjaDEjH+MSeRJnlY= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.6 h1:VwhTrsTuVn52an4mXx29PqRzs2Dvu921NpGk7y43tAM= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.6/go.mod h1:+8h7PZb3yY5ftmVLD7ocEoE98hdc8PoKS0H3wfx1dlc= -github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= -github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/aws/aws-sdk-go-v2 v1.34.0 h1:9iyL+cjifckRGEVpRKZP3eIxVlL06Qk1Tk13vreaVQU= +github.com/aws/aws-sdk-go-v2 v1.34.0/go.mod h1:JgstGg0JjWU1KpVJjD5H0y0yyAIpSdKEq556EI6yOOM= +github.com/aws/aws-sdk-go-v2/config v1.29.2 h1:JuIxOEPcSKpMB0J+khMjznG9LIhIBdmqNiEcPclnwqc= +github.com/aws/aws-sdk-go-v2/config v1.29.2/go.mod h1:HktTHregOZwNSM/e7WTfVSu9RCX+3eOv+6ij27PtaYs= +github.com/aws/aws-sdk-go-v2/credentials v1.17.55 h1:CDhKnDEaGkLA5ZszV/qw5uwN5M8rbv9Cl0JRN+PRsaM= +github.com/aws/aws-sdk-go-v2/credentials v1.17.55/go.mod h1:kPD/vj+RB5MREDUky376+zdnjZpR+WgdBBvwrmnlmKE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.25 h1:kU7tmXNaJ07LsyN3BUgGqAmVmQtq0w6duVIHAKfp0/w= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.25/go.mod h1:OiC8+OiqrURb1wrwmr/UbOVLFSWEGxjinj5C299VQdo= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.29 h1:Ej0Rf3GMv50Qh4G4852j2djtoDb7AzQ7MuQeFHa3D70= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.29/go.mod h1:oeNTC7PwJNoM5AznVr23wxhLnuJv0ZDe5v7w0wqIs9M= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.29 h1:6e8a71X+9GfghragVevC5bZqvATtc3mAMgxpSNbgzF0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.29/go.mod h1:c4jkZiQ+BWpNqq7VtrxjwISrLrt/VvPq3XiopkUIolI= +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/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/presigned-url v1.12.10 h1:hN4yJBGswmFTOVYqmbz1GBs9ZMtQe8SrYxPwrkrlRv8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.10/go.mod h1:TsxON4fEZXyrKY+D+3d2gSTyJkGORexIYab9PTf56DA= +github.com/aws/aws-sdk-go-v2/service/kms v1.37.14 h1:IvhYu4W4wKMqN6DqtuVD7obkFflgTv1wmnZMjlSeDAA= +github.com/aws/aws-sdk-go-v2/service/kms v1.37.14/go.mod h1:yqUt1GZH4uf7HUNT2Kd7qk6P+Vi5z+C5+NjNSNRO1L4= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.12 h1:kznaW4f81mNMlREkU9w3jUuJvU5g/KsqDV43ab7Rp6s= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.12/go.mod h1:bZy9r8e0/s0P7BSDHgMLXK2KvdyRRBIQ2blKlvLt0IU= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.11 h1:mUwIpAvILeKFnRx4h1dEgGEFGuV8KJ3pEScZWVFYuZA= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.11/go.mod h1:JDJtD+b8HNVv71axz8+S5492KM8wTzHRFpMKQbPlYxw= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.10 h1:g9d+TOsu3ac7SgmY2dUf1qMgu/uJVTlQ4VCbH6hRxSw= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.10/go.mod h1:WZfNmntu92HO44MVZAubQaz3qCuIdeOdog2sADfU6hU= +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/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -134,7 +134,6 @@ github.com/coreos/go-oidc/v3 v3.12.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDh github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.5/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= @@ -209,8 +208,8 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/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/cel-go v0.23.0 h1:knsnzeUOcREUFo0ZFJqZI8Rk6uEVyobAlir7GEbf5v0= -github.com/google/cel-go v0.23.0/go.mod h1:52Pb6QsDbC5kvgxvZhiL9QX1oZEkcUF/ZqaPx1J5Wwo= +github.com/google/cel-go v0.23.2 h1:UdEe3CvQh3Nv+E/j9r1Y//WO0K0cSyD7/y0bzyLIMI4= +github.com/google/cel-go v0.23.2/go.mod h1:52Pb6QsDbC5kvgxvZhiL9QX1oZEkcUF/ZqaPx1J5Wwo= github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/certificate-transparency-go v1.2.2 h1:5TAzjQnCfN1vps2XWUgU6Svt++rgy9a+b8CBYXaKUAo= github.com/google/certificate-transparency-go v1.2.2/go.mod h1:d1o5XNQzK/yz8IXzEce6KXgMxfter/EcMP9vG4dBRNE= @@ -228,10 +227,10 @@ github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus= github.com/google/go-tspi v0.3.0/go.mod h1:xfMGI3G0PhxCdNVcYr1C4C+EizojDg/TXuX5by8CiHI= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0 h1:my2ucqBZmv+cWHIhZNSIYKzgN8EBGyHdC7zD5sASRAg= -github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= -github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= +github.com/google/pprof v0.0.0-20250208200701-d0013a598941 h1:43XjGa6toxLpeksjcxs1jIoIyr+vUfOqY2c6HB4bpoc= +github.com/google/pprof v0.0.0-20250208200701-d0013a598941/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= 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/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= @@ -293,8 +292,8 @@ 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/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= -github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= +github.com/libdns/libdns v0.2.3 h1:ba30K4ObwMGB/QTmqUxf3H4/GmUrCAIkMWejeGl12v8= +github.com/libdns/libdns v0.2.3/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= @@ -423,8 +422,9 @@ github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 h1:kjYv github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935/go.mod h1:vNAduivU014fubg6ewygkAvQC0IQVXqdc8vaGl/0er4= github.com/smallstep/nosql v0.7.0 h1:YiWC9ZAHcrLCrayfaF+QJUv16I2bZ7KdLC3RpJcnAnE= github.com/smallstep/nosql v0.7.0/go.mod h1:H5VnKMCbeq9QA6SRY5iqPylfxLfYcLwvUff3onQ8+HU= -github.com/smallstep/pkcs7 v0.1.1 h1:x+rPdt2W088V9Vkjho4KtoggyktZJlMduZAtRHm68LU= github.com/smallstep/pkcs7 v0.1.1/go.mod h1:dL6j5AIz9GHjVEBTXtW+QliALcgM19RtXaTeyxI+AfA= +github.com/smallstep/pkcs7 v0.2.1 h1:6Kfzr/QizdIuB6LSv8y1LJdZ3aPSfTNhTLqAx9CTLfA= +github.com/smallstep/pkcs7 v0.2.1/go.mod h1:RcXHsMfL+BzH8tRhmrF1NkkpebKpq3JEM66cOFxanf0= github.com/smallstep/scep v0.0.0-20241223071629-a37a330173bc h1:gJ1mkz/iJhKnKUJit5DCFxNRWo9mxIkVm9SI8DiUugI= github.com/smallstep/scep v0.0.0-20241223071629-a37a330173bc/go.mod h1:bENyEPpujhqigQx115AitJTc11LZmGUNk0ftgyhcNus= github.com/smallstep/truststore v0.13.0 h1:90if9htAOblavbMeWlqNLnO9bsjjgVv2hQeQJCi/py4= @@ -443,12 +443,12 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -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/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/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/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= @@ -498,8 +498,8 @@ github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= -go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= -go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= +go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk= +go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= 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= @@ -531,8 +531,8 @@ go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQD go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.step.sm/crypto v0.57.0 h1:YjoRQDaJYAxHLVwjst0Bl0xcnoKzVwuHCJtEo2VSHYU= -go.step.sm/crypto v0.57.0/go.mod h1:+Lwp5gOVPaTa3H/Ul/TzGbxQPXZZcKIUGMS0lG6n9Go= +go.step.sm/crypto v0.57.1 h1:bt7ugfc0m2/nJ9/uhQOtXRW3xQr8zJwL087FLQk9mvc= +go.step.sm/crypto v0.57.1/go.mod h1:wL25/Mh7edmo36AA93hf9agP493Zt3y4QBzB1wzwOjc= go.step.sm/linkedca v0.22.2 h1:zmFIyDC77gFHo6FLQJ8OIXYpLYDIsgDWaYqtYs6A9/Q= go.step.sm/linkedca v0.22.2/go.mod h1:ESY8r5VfhJA8ZVzI6hXIQcEX9LwaY3aoPnT+Hb9jpbw= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= @@ -558,13 +558,13 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/crypto/x509roots/fallback v0.0.0-20250118192723-a8ea4be81f07 h1:Tuk3hxOkRoX4Xwph6/tRU1wGumEsVYM2TZfvAC6MllM= -golang.org/x/crypto/x509roots/fallback v0.0.0-20250118192723-a8ea4be81f07/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/crypto/x509roots/fallback v0.0.0-20250214233241-911360c8a4f4 h1:QDiVWrFJ2lyXzr3pJnIREQWR8S7jkjzuWJPJda8Ic8E= +golang.org/x/crypto/x509roots/fallback v0.0.0-20250214233241-911360c8a4f4/go.mod h1:lxN5T34bK4Z/i6cMaU7frUU57VkDXFD4Kamfl/cp9oU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= -golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= +golang.org/x/exp v0.0.0-20250215185904-eff6e970281f h1:oFMYAjX0867ZD2jcNiLBrI9BdpmEkvPyi5YrBGXbamg= +golang.org/x/exp v0.0.0-20250215185904-eff6e970281f/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 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= @@ -573,8 +573,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= -golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +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= @@ -591,14 +591,14 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= -golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= +golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= 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= @@ -610,8 +610,9 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -634,8 +635,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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= @@ -645,8 +646,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= -golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= -golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= 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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -656,12 +657,13 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= +golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/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-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -672,14 +674,14 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= -golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= +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= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= -google.golang.org/api v0.216.0 h1:xnEHy+xWFrtYInWPy8OdGFsyIfWJjtVnO39g7pz2BFY= -google.golang.org/api v0.216.0/go.mod h1:K9wzQMvWi47Z9IU7OgdOofvZuw75Ge3PPITImZR/UyI= +google.golang.org/api v0.218.0 h1:x6JCjEWeZ9PFCRe9z0FBrNwj7pB7DOAqT35N+IPnAUA= +google.golang.org/api v0.218.0/go.mod h1:5VGHBAkxrA/8EFjLVEYmMUJ8/8+gWWQ3s4cFH0FxG2M= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -691,18 +693,18 @@ google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk= google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc= -google.golang.org/genproto/googleapis/api v0.0.0-20250127172529-29210b9bc287 h1:A2ni10G3UlplFrWdCDJTl7D7mJ7GSRm37S+PDimaKRw= -google.golang.org/genproto/googleapis/api v0.0.0-20250127172529-29210b9bc287/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 h1:J1H9f+LEdWAfHcez/4cvaVBox7cOYT+IU6rgqj5x++8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= +google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b h1:i+d0RZa8Hs2L/MuaOQYI+krthcxdEbEM2N+Tf3kJ4zk= +google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b h1:FQtJ1MxbXoIIrZHZ33M+w5+dAP9o86rgpjoKr/ZmT7k= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 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/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= -google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +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/check.v1 v0.0.0-20161208181325-20d25e280405/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/go.mod b/go.mod index c6aa933c..26040ad2 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module github.com/dunglas/mercure -go 1.22.0 +go 1.23.0 -toolchain go1.23.2 +toolchain go1.24.0 retract ( v0.14.7 // CI problem @@ -18,15 +18,15 @@ require ( github.com/kevburnsjr/skipfilter v0.0.1 github.com/prometheus/client_golang v1.20.5 github.com/prometheus/client_model v0.6.1 - github.com/spf13/cobra v1.8.1 - github.com/spf13/pflag v1.0.5 + github.com/spf13/cobra v1.9.1 + github.com/spf13/pflag v1.0.6 github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.10.0 github.com/unrolled/secure v1.17.0 github.com/yosida95/uritemplate/v3 v3.0.2 - go.etcd.io/bbolt v1.3.11 + go.etcd.io/bbolt v1.4.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.32.0 + golang.org/x/crypto v0.33.0 ) require ( @@ -56,11 +56,11 @@ require ( github.com/spf13/cast v1.7.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect - google.golang.org/protobuf v1.36.4 // indirect + golang.org/x/exp v0.0.0-20250215185904-eff6e970281f // indirect + golang.org/x/net v0.35.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 9dbe3133..0570e408 100644 --- a/go.sum +++ b/go.sum @@ -12,7 +12,7 @@ github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3M github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= 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/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= 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= @@ -67,8 +67,6 @@ github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+ github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= 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.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ= -github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s= 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.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= @@ -76,24 +74,20 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= -github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -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/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -107,30 +101,28 @@ github.com/unrolled/secure v1.17.0 h1:Io7ifFgo99Bnh0J7+Q+qcMzWM6kaDPCA5FroFZEdbW github.com/unrolled/secure v1.17.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4= github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= -go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= -go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= +go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk= +go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk= 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/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= -golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= -google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= -google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/exp v0.0.0-20250215185904-eff6e970281f h1:oFMYAjX0867ZD2jcNiLBrI9BdpmEkvPyi5YrBGXbamg= +golang.org/x/exp v0.0.0-20250215185904-eff6e970281f/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +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/check.v1 v0.0.0-20161208181325-20d25e280405/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= diff --git a/publish_test.go b/publish_test.go index b3b2164e..afec7d16 100644 --- a/publish_test.go +++ b/publish_test.go @@ -313,13 +313,15 @@ func FuzzPublish(f *testing.F) { hub := createDummy() authorizationHeader := bearerPrefix + createDummyAuthorizedJWT(rolePublisher, []string{"*"}) - testCases := [][]interface{}{ + testCases := []struct { + topic1, topic2, id, data, private, retry, typ string + }{ {"https://localhost/foo/bar", "baz", "", "", "", "", ""}, {"https://localhost/foo/baz", "bat", "id", "data", "on", "22", "mytype"}, } for _, tc := range testCases { - f.Add(tc...) //nolint:govet + f.Add(tc.topic1, tc.topic2, tc.id, tc.data, tc.private, tc.retry, tc.typ) } f.Fuzz(func(t *testing.T, topic1, topic2, id, data, private, retry, typ string) { From a2f9831c6d9d40ab73de4ee6b4930304aa7b4684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 17 Feb 2025 11:39:04 +0100 Subject: [PATCH 66/71] test: run tests in parallel (#1009) --- .golangci.yml | 3 - authorization_test.go | 68 +++++++++++++++++++++++ bolt_test.go | 117 +++++++++++++++++++++++---------------- config_test.go | 10 ++++ demo_test.go | 4 ++ event_test.go | 6 ++ hub_test.go | 24 ++++++++ jwtkeyfunc_test.go | 6 ++ local_test.go | 41 +++++++++----- metrics_test.go | 6 ++ publish_test.go | 26 +++++++++ subscribe_test.go | 75 ++++++++++++++++++------- subscriber_test.go | 10 ++++ subscriberlist_test.go | 4 ++ subscription_test.go | 12 ++++ topicselectorlru_test.go | 2 + update_test.go | 4 ++ 17 files changed, 333 insertions(+), 85 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 5085e030..f0a8de04 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -29,9 +29,6 @@ linters: - nolintlint - canonicalheader - # deprecated - - exportloopref - issues: exclude-rules: - path: _test\.go diff --git a/authorization_test.go b/authorization_test.go index de5728b5..cccda314 100644 --- a/authorization_test.go +++ b/authorization_test.go @@ -167,6 +167,8 @@ var AuthTestData = []AuthorizationTestData{ } func TestAuthorizeMultipleAuthorizationHeader(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) r.Header.Add("Authorization", testdata.validEmpty) @@ -181,6 +183,8 @@ func TestAuthorizeMultipleAuthorizationHeader(t *testing.T) { } func TestAuthorizeAuthorizationHeaderTooShort(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) r.Header.Add("Authorization", "Bearer x") @@ -194,6 +198,8 @@ func TestAuthorizeAuthorizationHeaderTooShort(t *testing.T) { } func TestAuthorizeAuthorizationHeaderNoBearer(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) r.Header.Add("Authorization", "Greater "+testdata.validEmpty) @@ -207,6 +213,8 @@ func TestAuthorizeAuthorizationHeaderNoBearer(t *testing.T) { } func TestAuthorizeAuthorizationHeaderInvalidAlg(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) r.Header.Add("Authorization", bearerPrefix+createDummyNoneSignedJWT()) @@ -221,6 +229,8 @@ func TestAuthorizeAuthorizationHeaderInvalidAlg(t *testing.T) { } func TestAuthorizeAuthorizationHeaderInvalidKey(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) r.Header.Add("Authorization", bearerPrefix+testdata.validEmpty) @@ -235,6 +245,8 @@ func TestAuthorizeAuthorizationHeaderInvalidKey(t *testing.T) { } func TestAuthorizeAuthorizationHeaderInvalidSignature(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) r.Header.Add("Authorization", bearerPrefix+testdata.validEmpty[:len(testdata.validEmpty)-8]+"12345678") @@ -249,6 +261,8 @@ func TestAuthorizeAuthorizationHeaderInvalidSignature(t *testing.T) { } func TestAuthorizeAuthorizationHeaderNoContent(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) r.Header.Add("Authorization", bearerPrefix+testdata.validEmpty) @@ -263,6 +277,8 @@ func TestAuthorizeAuthorizationHeaderNoContent(t *testing.T) { } func TestAuthorizeAuthorizationHeader(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) r.Header.Add("Authorization", bearerPrefix+testdata.valid) @@ -277,6 +293,8 @@ func TestAuthorizeAuthorizationHeader(t *testing.T) { } func TestAuthorizeAuthorizationHeaderWithCert(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { if testdata.validForCert != "" { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) @@ -293,6 +311,8 @@ func TestAuthorizeAuthorizationHeaderWithCert(t *testing.T) { } func TestAuthorizeAuthorizationHeaderNamespaced(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { if testdata.validNamespaced != "" { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) @@ -309,6 +329,8 @@ func TestAuthorizeAuthorizationHeaderNamespaced(t *testing.T) { } func TestAuthorizeAuthorizationHeaderWrongAlgorithm(t *testing.T) { + t.Parallel() + for idx, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) r.Header.Add("Authorization", bearerPrefix+testdata.valid) @@ -324,6 +346,8 @@ func TestAuthorizeAuthorizationHeaderWrongAlgorithm(t *testing.T) { } func TestAuthorizeAuthorizationQueryTooShort(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) query := r.URL.Query() @@ -339,6 +363,8 @@ func TestAuthorizeAuthorizationQueryTooShort(t *testing.T) { } func TestAuthorizeAuthorizationQueryInvalidAlg(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) query := r.URL.Query() @@ -355,6 +381,8 @@ func TestAuthorizeAuthorizationQueryInvalidAlg(t *testing.T) { } func TestAuthorizeAuthorizationQueryInvalidKey(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) query := r.URL.Query() @@ -371,6 +399,8 @@ func TestAuthorizeAuthorizationQueryInvalidKey(t *testing.T) { } func TestAuthorizeAuthorizationQueryInvalidSignature(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) query := r.URL.Query() @@ -387,6 +417,8 @@ func TestAuthorizeAuthorizationQueryInvalidSignature(t *testing.T) { } func TestAuthorizeAuthorizationQueryNoContent(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) query := r.URL.Query() @@ -403,6 +435,8 @@ func TestAuthorizeAuthorizationQueryNoContent(t *testing.T) { } func TestAuthorizeAuthorizationQuery(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) query := r.URL.Query() @@ -419,6 +453,8 @@ func TestAuthorizeAuthorizationQuery(t *testing.T) { } func TestAuthorizeAuthorizationQueryNamespaced(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { if testdata.validNamespaced != "" { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) @@ -437,6 +473,8 @@ func TestAuthorizeAuthorizationQueryNamespaced(t *testing.T) { } func TestAuthorizeAuthorizationQueryRsaWithCert(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { if testdata.validForCert != "" { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) @@ -455,6 +493,8 @@ func TestAuthorizeAuthorizationQueryRsaWithCert(t *testing.T) { } func TestAuthorizeAuthorizationQueryWrongAlgorithm(t *testing.T) { + t.Parallel() + for idx, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) query := r.URL.Query() @@ -472,6 +512,8 @@ func TestAuthorizeAuthorizationQueryWrongAlgorithm(t *testing.T) { } func TestAuthorizeCookieInvalidAlg(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: createDummyNoneSignedJWT()}) @@ -485,6 +527,8 @@ func TestAuthorizeCookieInvalidAlg(t *testing.T) { } func TestAuthorizeCookieInvalidKey(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.validEmpty}) @@ -499,6 +543,8 @@ func TestAuthorizeCookieInvalidKey(t *testing.T) { } func TestAuthorizeCookieInvalidSignature(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.validEmpty[:len(testdata.validEmpty)-8] + "12345678"}) @@ -513,6 +559,8 @@ func TestAuthorizeCookieInvalidSignature(t *testing.T) { } func TestAuthorizeCookieNoContent(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.validEmpty}) @@ -527,6 +575,8 @@ func TestAuthorizeCookieNoContent(t *testing.T) { } func TestAuthorizeCookie(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodGet, defaultHubURL, nil) r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.valid}) @@ -541,6 +591,8 @@ func TestAuthorizeCookie(t *testing.T) { } func TestAuthorizeCookieNoOriginNoReferer(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) r.AddCookie(&http.Cookie{Name: defaultCookieName, Value: testdata.valid}) @@ -554,6 +606,8 @@ func TestAuthorizeCookieNoOriginNoReferer(t *testing.T) { } func TestAuthorizeCookieOriginNotAllowed(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) r.Header.Add("Origin", "http://example.com") @@ -568,6 +622,8 @@ func TestAuthorizeCookieOriginNotAllowed(t *testing.T) { } func TestAuthorizeCookieRefererNotAllowed(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) r.Header.Add("Referer", "http://example.com/foo/bar") @@ -582,6 +638,8 @@ func TestAuthorizeCookieRefererNotAllowed(t *testing.T) { } func TestAuthorizeCookieInvalidReferer(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) r.Header.Add("Referer", "http://192.168.0.%31/") @@ -596,6 +654,8 @@ func TestAuthorizeCookieInvalidReferer(t *testing.T) { } func TestAuthorizeCookieOriginHasPriority(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) r.Header.Add("Origin", "http://example.net") @@ -612,6 +672,8 @@ func TestAuthorizeCookieOriginHasPriority(t *testing.T) { } func TestAuthorizeAllOriginsAllowed(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) r.Header.Add("Origin", "http://example.com") @@ -625,6 +687,8 @@ func TestAuthorizeAllOriginsAllowed(t *testing.T) { } func TestAuthorizeCustomCookieName(t *testing.T) { + t.Parallel() + for _, testdata := range AuthTestData { r, _ := http.NewRequest(http.MethodPost, defaultHubURL, nil) r.Header.Add("Origin", "http://example.com") @@ -638,6 +702,8 @@ func TestAuthorizeCustomCookieName(t *testing.T) { } func TestCanReceive(t *testing.T) { + t.Parallel() + tss := &TopicSelectorStore{} assert.True(t, canReceive(tss, []string{"foo", "bar"}, []string{"foo", "bar"})) assert.True(t, canReceive(tss, []string{"foo", "bar"}, []string{"bar"})) @@ -648,6 +714,8 @@ func TestCanReceive(t *testing.T) { } func TestCanDispatch(t *testing.T) { + t.Parallel() + tss := &TopicSelectorStore{} assert.True(t, canDispatch(tss, []string{"foo", "bar"}, []string{"foo", "bar"})) assert.True(t, canDispatch(tss, []string{"foo", "bar"}, []string{"*"})) diff --git a/bolt_test.go b/bolt_test.go index 4d17f6d0..1f00eb96 100644 --- a/bolt_test.go +++ b/bolt_test.go @@ -15,17 +15,28 @@ import ( "go.uber.org/zap" ) -func createBoltTransport(dsn string) *BoltTransport { - u, _ := url.Parse(dsn) - transport, _ := DeprecatedNewBoltTransport(u, zap.NewNop()) +func createBoltTransport(t *testing.T, size uint64, cleanupFrequency float64) (*BoltTransport, func()) { + t.Helper() - return transport.(*BoltTransport) + if cleanupFrequency == 0 { + cleanupFrequency = BoltDefaultCleanupFrequency + } + + path := "test-" + t.Name() + ".db" + transport, err := NewBoltTransport(zap.NewNop(), path, defaultBoltBucketName, size, cleanupFrequency) + require.NoError(t, err) + + return transport, func() { + os.Remove(path) + transport.Close() + } } func TestBoltTransportHistory(t *testing.T) { - transport := createBoltTransport("bolt://test.db") - defer transport.Close() - defer os.Remove("test.db") + t.Parallel() + + transport, cleanup := createBoltTransport(t, 0, 0) + defer cleanup() topics := []string{"https://example.com/foo"} for i := 1; i <= 10; i++ { @@ -53,13 +64,14 @@ func TestBoltTransportHistory(t *testing.T) { } func TestBoltTransportLogsBogusLastEventID(t *testing.T) { + t.Parallel() + sink, logger := newTestLogger(t) defer sink.Reset() - u, _ := url.Parse("bolt://test.db") - transport, _ := DeprecatedNewBoltTransport(u, logger) - defer transport.Close() - defer os.Remove("test.db") + transport, cleanup := createBoltTransport(t, 0, 0) + transport.logger = logger + defer cleanup() // make sure the db is not empty topics := []string{"https://example.com/foo"} @@ -78,9 +90,10 @@ func TestBoltTransportLogsBogusLastEventID(t *testing.T) { } func TestBoltTopicSelectorHistory(t *testing.T) { - transport := createBoltTransport("bolt://test.db") - defer transport.Close() - defer os.Remove("test.db") + t.Parallel() + + transport, cleanup := createBoltTransport(t, 0, 0) + defer cleanup() transport.Dispatch(&Update{Topics: []string{"http://example.com/subscribed"}, Event: Event{ID: "1"}}) transport.Dispatch(&Update{Topics: []string{"http://example.com/not-subscribed"}, Event: Event{ID: "2"}}) @@ -97,9 +110,10 @@ func TestBoltTopicSelectorHistory(t *testing.T) { } func TestBoltTransportRetrieveAllHistory(t *testing.T) { - transport := createBoltTransport("bolt://test.db") - defer transport.Close() - defer os.Remove("test.db") + t.Parallel() + + transport, cleanup := createBoltTransport(t, 0, 0) + defer cleanup() topics := []string{"https://example.com/foo"} for i := 1; i <= 10; i++ { @@ -127,9 +141,10 @@ func TestBoltTransportRetrieveAllHistory(t *testing.T) { } func TestBoltTransportHistoryAndLive(t *testing.T) { - transport := createBoltTransport("bolt://test.db") - defer transport.Close() - defer os.Remove("test.db") + t.Parallel() + + transport, cleanup := createBoltTransport(t, 0, 0) + defer cleanup() topics := []string{"https://example.com/foo"} for i := 1; i <= 10; i++ { @@ -169,9 +184,10 @@ func TestBoltTransportHistoryAndLive(t *testing.T) { } func TestBoltTransportPurgeHistory(t *testing.T) { - transport := createBoltTransport("bolt://test.db?size=5&cleanup_frequency=1") - defer transport.Close() - defer os.Remove("test.db") + t.Parallel() + + transport, cleanup := createBoltTransport(t, 5, 1) + defer cleanup() for i := 0; i < 12; i++ { transport.Dispatch(&Update{ @@ -190,11 +206,14 @@ func TestBoltTransportPurgeHistory(t *testing.T) { } func TestNewBoltTransport(t *testing.T) { - u, _ := url.Parse("bolt://test.db?bucket_name=demo") + t.Parallel() + + u, _ := url.Parse("bolt://test-" + t.Name() + ".db?bucket_name=demo") transport, err := DeprecatedNewBoltTransport(u, zap.NewNop()) require.NoError(t, err) require.NotNil(t, transport) transport.Close() + os.Remove("bolt://test-" + t.Name() + ".db?bucket_name=demo") u, _ = url.Parse("bolt://") _, err = DeprecatedNewBoltTransport(u, zap.NewNop()) @@ -216,9 +235,10 @@ func TestNewBoltTransport(t *testing.T) { } func TestBoltTransportDoNotDispatchUntilListen(t *testing.T) { - transport := createBoltTransport("bolt://test.db") - defer transport.Close() - defer os.Remove("test.db") + t.Parallel() + + transport, cleanup := createBoltTransport(t, 0, 0) + defer cleanup() assert.Implements(t, (*Transport)(nil), transport) s := NewLocalSubscriber("", transport.logger, &TopicSelectorStore{}) @@ -240,9 +260,10 @@ func TestBoltTransportDoNotDispatchUntilListen(t *testing.T) { } func TestBoltTransportDispatch(t *testing.T) { - transport := createBoltTransport("bolt://test.db") - defer transport.Close() - defer os.Remove("test.db") + t.Parallel() + + transport, cleanup := createBoltTransport(t, 0, 0) + defer cleanup() assert.Implements(t, (*Transport)(nil), transport) s := NewLocalSubscriber("", transport.logger, &TopicSelectorStore{}) @@ -268,10 +289,10 @@ func TestBoltTransportDispatch(t *testing.T) { } func TestBoltTransportClosed(t *testing.T) { - transport := createBoltTransport("bolt://test.db") - require.NotNil(t, transport) - defer transport.Close() - defer os.Remove("test.db") + t.Parallel() + + transport, cleanup := createBoltTransport(t, 0, 0) + defer cleanup() assert.Implements(t, (*Transport)(nil), transport) s := NewLocalSubscriber("", transport.logger, &TopicSelectorStore{}) @@ -288,10 +309,10 @@ func TestBoltTransportClosed(t *testing.T) { } func TestBoltCleanDisconnectedSubscribers(t *testing.T) { - transport := createBoltTransport("bolt://test.db") - require.NotNil(t, transport) - defer transport.Close() - defer os.Remove("test.db") + t.Parallel() + + transport, cleanup := createBoltTransport(t, 0, 0) + defer cleanup() s1 := NewLocalSubscriber("", transport.logger, &TopicSelectorStore{}) s1.SetTopics([]string{"foo"}, []string{}) @@ -313,10 +334,10 @@ func TestBoltCleanDisconnectedSubscribers(t *testing.T) { } func TestBoltGetSubscribers(t *testing.T) { - transport := createBoltTransport("bolt://test.db") - require.NotNil(t, transport) - defer transport.Close() - defer os.Remove("test.db") + t.Parallel() + + transport, cleanup := createBoltTransport(t, 0, 0) + defer cleanup() s1 := NewLocalSubscriber("", transport.logger, &TopicSelectorStore{}) require.NoError(t, transport.AddSubscriber(s1)) @@ -334,8 +355,11 @@ func TestBoltGetSubscribers(t *testing.T) { } func TestBoltLastEventID(t *testing.T) { - db, err := bolt.Open("test.db", 0o600, nil) - defer os.Remove("test.db") + t.Parallel() + + path := "test-" + t.Name() + ".db" + db, err := bolt.Open(path, 0o600, nil) + defer os.Remove(path) require.NoError(t, err) db.Update(func(tx *bolt.Tx) error { @@ -358,9 +382,8 @@ func TestBoltLastEventID(t *testing.T) { }) require.NoError(t, db.Close()) - transport := createBoltTransport("bolt://test.db") - require.NotNil(t, transport) - defer transport.Close() + transport, cleanup := createBoltTransport(t, 0, 0) + defer cleanup() lastEventID, _, _ := transport.GetSubscribers() assert.Equal(t, "foo", lastEventID) diff --git a/config_test.go b/config_test.go index 8313b82f..0d89249c 100644 --- a/config_test.go +++ b/config_test.go @@ -11,11 +11,15 @@ import ( ) func TestMissingConfig(t *testing.T) { + t.Parallel() + err := ValidateConfig(viper.New()) require.EqualError(t, err, `invalid config: one of "jwt_key" or "publisher_jwt_key" configuration parameter must be defined`) } func TestMissingKeyFile(t *testing.T) { + t.Parallel() + v := viper.New() v.Set("jwt_key", "abc") v.Set("cert_file", "foo") @@ -25,6 +29,8 @@ func TestMissingKeyFile(t *testing.T) { } func TestMissingCertFile(t *testing.T) { + t.Parallel() + v := viper.New() v.Set("jwt_key", "abc") v.Set("key_file", "foo") @@ -34,6 +40,8 @@ func TestMissingCertFile(t *testing.T) { } func TestSetFlags(t *testing.T) { + t.Parallel() + v := viper.New() fs := pflag.NewFlagSet("test", pflag.PanicOnError) SetFlags(fs, v) @@ -52,6 +60,8 @@ func TestInitConfig(t *testing.T) { } func TestMetricsAreDisabledByDefault(t *testing.T) { + t.Parallel() + v := viper.New() SetConfigDefaults(v) diff --git a/demo_test.go b/demo_test.go index 4e4d6b1e..19ae52ee 100644 --- a/demo_test.go +++ b/demo_test.go @@ -11,6 +11,8 @@ import ( ) func TestEmptyBodyAndJWT(t *testing.T) { + t.Parallel() + req := httptest.NewRequest(http.MethodGet, "http://example.com/demo/foo.jsonld", nil) w := httptest.NewRecorder() @@ -32,6 +34,8 @@ func TestEmptyBodyAndJWT(t *testing.T) { } func TestBodyAndJWT(t *testing.T) { + t.Parallel() + req := httptest.NewRequest(http.MethodGet, "http://example.com/demo/foo/bar.xml?body=&jwt=token", nil) w := httptest.NewRecorder() diff --git a/event_test.go b/event_test.go index f3f05566..b7323036 100644 --- a/event_test.go +++ b/event_test.go @@ -7,18 +7,24 @@ import ( ) func TestEncodeFull(t *testing.T) { + t.Parallel() + e := &Event{"several\nlines\rwith\r\neol", "custom-id", "type", 5} assert.Equal(t, "event: type\nretry: 5\nid: custom-id\ndata: several\ndata: lines\ndata: with\ndata: eol\n\n", e.String()) } func TestEncodeNoType(t *testing.T) { + t.Parallel() + e := &Event{"data", "custom-id", "", 5} assert.Equal(t, "retry: 5\nid: custom-id\ndata: data\n\n", e.String()) } func TestEncodeNoRetry(t *testing.T) { + t.Parallel() + e := &Event{"data", "custom-id", "", 0} assert.Equal(t, "id: custom-id\ndata: data\n\n", e.String()) diff --git a/hub_test.go b/hub_test.go index 45c0774e..9f10983a 100644 --- a/hub_test.go +++ b/hub_test.go @@ -23,6 +23,8 @@ const ( ) func TestNewHub(t *testing.T) { + t.Parallel() + h := createDummy() assert.IsType(t, &viper.Viper{}, h.config) @@ -35,6 +37,8 @@ func TestNewHub(t *testing.T) { } func TestNewHubWithConfig(t *testing.T) { + t.Parallel() + h, err := NewHub( WithPublisherJWT([]byte("foo"), jwt.SigningMethodHS256.Name), WithSubscriberJWT([]byte("bar"), jwt.SigningMethodHS256.Name), @@ -50,6 +54,8 @@ func TestNewHubValidationError(t *testing.T) { } func TestNewHubTransportValidationError(t *testing.T) { + t.Parallel() + v := viper.New() v.Set("publisher_jwt_key", "foo") v.Set("jwt_key", "bar") @@ -61,6 +67,8 @@ func TestNewHubTransportValidationError(t *testing.T) { } func TestStartCrash(t *testing.T) { + t.Parallel() + if os.Getenv("BE_START_CRASH") == "1" { Start() @@ -76,6 +84,8 @@ func TestStartCrash(t *testing.T) { } func TestStop(t *testing.T) { + t.Parallel() + const numberOfSubscribers = 2 hub := createAnonymousDummy() @@ -118,6 +128,8 @@ func TestStop(t *testing.T) { } func TestWithProtocolVersionCompatibility(t *testing.T) { + t.Parallel() + op := &opt{} assert.False(t, op.isBackwardCompatiblyEnabledWith(7)) @@ -131,6 +143,8 @@ func TestWithProtocolVersionCompatibility(t *testing.T) { } func TestWithProtocolVersionCompatibilityVersions(t *testing.T) { + t.Parallel() + op := &opt{} testCases := []struct { @@ -145,6 +159,8 @@ func TestWithProtocolVersionCompatibilityVersions(t *testing.T) { for _, tc := range testCases { t.Run(fmt.Sprintf("version %d", tc.version), func(t *testing.T) { + t.Parallel() + o := WithProtocolVersionCompatibility(tc.version) if tc.ok { @@ -157,6 +173,8 @@ func TestWithProtocolVersionCompatibilityVersions(t *testing.T) { } func TestWithPublisherJWTKeyFunc(t *testing.T) { + t.Parallel() + op := &opt{} o := WithPublisherJWTKeyFunc(func(_ *jwt.Token) (interface{}, error) { return []byte{}, nil }) @@ -165,6 +183,8 @@ func TestWithPublisherJWTKeyFunc(t *testing.T) { } func TestWithSubscriberJWTKeyFunc(t *testing.T) { + t.Parallel() + op := &opt{} o := WithSubscriberJWTKeyFunc(func(_ *jwt.Token) (interface{}, error) { return []byte{}, nil }) @@ -181,6 +201,8 @@ func TestWithDebug(t *testing.T) { } func TestWithUI(t *testing.T) { + t.Parallel() + op := &opt{} o := WithUI() @@ -189,6 +211,8 @@ func TestWithUI(t *testing.T) { } func TestOriginsValidator(t *testing.T) { + t.Parallel() + op := &opt{} validOrigins := [][]string{ diff --git a/jwtkeyfunc_test.go b/jwtkeyfunc_test.go index 02493e86..fb828a51 100644 --- a/jwtkeyfunc_test.go +++ b/jwtkeyfunc_test.go @@ -7,18 +7,24 @@ import ( ) func TestCreateJWTKeyfunc(t *testing.T) { + t.Parallel() + f, err := createJWTKeyfunc([]byte{}, "invalid") require.Error(t, err) require.Nil(t, f) } func TestAuthorizeAuthorizationHeaderEmptyKeyRsa(t *testing.T) { + t.Parallel() + keyfunc, err := createJWTKeyfunc([]byte{}, "RS256") require.EqualError(t, err, "unable to parse RSA public key: invalid key: Key must be a PEM encoded PKCS1 or PKCS8 key") require.Nil(t, keyfunc) } func TestAuthorizeAuthorizationHeaderInvalidKeyRsa(t *testing.T) { + t.Parallel() + keyfunc, err := createJWTKeyfunc([]byte(privateKeyRsa), "RS256") require.EqualError(t, err, "unable to parse RSA public key: asn1: structure error: integer too large") require.Nil(t, keyfunc) diff --git a/local_test.go b/local_test.go index 33e89add..afe879e0 100644 --- a/local_test.go +++ b/local_test.go @@ -1,7 +1,6 @@ package mercure import ( - "net/url" "sync" "testing" @@ -11,16 +10,18 @@ import ( ) func TestLocalTransportDoNotDispatchUntilListen(t *testing.T) { - logger := zap.NewNop() - transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, logger) + t.Parallel() + + transport := NewLocalTransport() defer transport.Close() + assert.Implements(t, (*Transport)(nil), transport) u := &Update{Topics: []string{"http://example.com/books/1"}} err := transport.Dispatch(u) require.NoError(t, err) - s := NewLocalSubscriber("", logger, &TopicSelectorStore{}) + s := NewLocalSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.SetTopics(u.Topics, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -38,12 +39,14 @@ func TestLocalTransportDoNotDispatchUntilListen(t *testing.T) { } func TestLocalTransportDispatch(t *testing.T) { - logger := zap.NewNop() - transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, logger) + t.Parallel() + + transport := NewLocalTransport() defer transport.Close() + assert.Implements(t, (*Transport)(nil), transport) - s := NewLocalSubscriber("", logger, &TopicSelectorStore{}) + s := NewLocalSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.SetTopics([]string{"http://example.com/foo"}, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -53,12 +56,15 @@ func TestLocalTransportDispatch(t *testing.T) { } func TestLocalTransportClosed(t *testing.T) { - logger := zap.NewNop() - transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, logger) + t.Parallel() + + transport := NewLocalTransport() defer transport.Close() + assert.Implements(t, (*Transport)(nil), transport) tss := &TopicSelectorStore{} + logger := zap.NewNop() s := NewLocalSubscriber("", logger, tss) require.NoError(t, transport.AddSubscriber(s)) @@ -71,12 +77,13 @@ func TestLocalTransportClosed(t *testing.T) { } func TestLiveCleanDisconnectedSubscribers(t *testing.T) { - logger := zap.NewNop() - tr, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, logger) - transport := tr.(*LocalTransport) + t.Parallel() + + transport := NewLocalTransport() defer transport.Close() tss := &TopicSelectorStore{} + logger := zap.NewNop() s1 := NewLocalSubscriber("", logger, tss) require.NoError(t, transport.AddSubscriber(s1)) @@ -96,12 +103,13 @@ func TestLiveCleanDisconnectedSubscribers(t *testing.T) { } func TestLiveReading(t *testing.T) { - logger := zap.NewNop() - transport, _ := DeprecatedNewLocalTransport(&url.URL{Scheme: "local"}, logger) + t.Parallel() + + transport := NewLocalTransport() defer transport.Close() assert.Implements(t, (*Transport)(nil), transport) - s := NewLocalSubscriber("", logger, &TopicSelectorStore{}) + s := NewLocalSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.SetTopics([]string{"https://example.com"}, nil) require.NoError(t, transport.AddSubscriber(s)) @@ -113,8 +121,11 @@ func TestLiveReading(t *testing.T) { } func TestLocalTransportGetSubscribers(t *testing.T) { + t.Parallel() + transport := NewLocalTransport() defer transport.Close() + require.NotNil(t, transport) logger := zap.NewNop() diff --git a/metrics_test.go b/metrics_test.go index 5af78744..ef8621d7 100644 --- a/metrics_test.go +++ b/metrics_test.go @@ -10,6 +10,8 @@ import ( ) func TestNumberOfRunningSubscribers(t *testing.T) { + t.Parallel() + m := NewPrometheusMetrics(nil) logger := zap.NewNop() @@ -33,6 +35,8 @@ func TestNumberOfRunningSubscribers(t *testing.T) { } func TestTotalNumberOfHandledSubscribers(t *testing.T) { + t.Parallel() + m := NewPrometheusMetrics(nil) logger := zap.NewNop() @@ -55,6 +59,8 @@ func TestTotalNumberOfHandledSubscribers(t *testing.T) { } func TestTotalOfHandledUpdates(t *testing.T) { + t.Parallel() + m := NewPrometheusMetrics(nil) m.UpdatePublished(&Update{ diff --git a/publish_test.go b/publish_test.go index afec7d16..1a8836dc 100644 --- a/publish_test.go +++ b/publish_test.go @@ -16,6 +16,8 @@ import ( ) func TestPublishNoAuthorizationHeader(t *testing.T) { + t.Parallel() + hub := createDummy() req := httptest.NewRequest(http.MethodPost, defaultHubURL, nil) @@ -30,6 +32,8 @@ func TestPublishNoAuthorizationHeader(t *testing.T) { } func TestPublishUnauthorizedJWT(t *testing.T) { + t.Parallel() + hub := createDummy() req := httptest.NewRequest(http.MethodPost, defaultHubURL, nil) @@ -45,6 +49,8 @@ func TestPublishUnauthorizedJWT(t *testing.T) { } func TestPublishInvalidAlgJWT(t *testing.T) { + t.Parallel() + hub := createDummy() req := httptest.NewRequest(http.MethodPost, defaultHubURL, nil) @@ -60,6 +66,8 @@ func TestPublishInvalidAlgJWT(t *testing.T) { } func TestPublishBadContentType(t *testing.T) { + t.Parallel() + hub := createDummy() req := httptest.NewRequest(http.MethodPost, defaultHubURL, nil) @@ -75,6 +83,8 @@ func TestPublishBadContentType(t *testing.T) { } func TestPublishNoTopic(t *testing.T) { + t.Parallel() + hub := createDummy() req := httptest.NewRequest(http.MethodPost, defaultHubURL, nil) @@ -90,6 +100,8 @@ func TestPublishNoTopic(t *testing.T) { } func TestPublishInvalidRetry(t *testing.T) { + t.Parallel() + hub := createDummy() form := url.Values{} @@ -112,6 +124,8 @@ func TestPublishInvalidRetry(t *testing.T) { } func TestPublishNotAuthorizedTopicSelector(t *testing.T) { + t.Parallel() + hub := createDummy() form := url.Values{} @@ -133,6 +147,8 @@ func TestPublishNotAuthorizedTopicSelector(t *testing.T) { } func TestPublishEmptyTopicSelector(t *testing.T) { + t.Parallel() + hub := createDummy() form := url.Values{} @@ -152,6 +168,8 @@ func TestPublishEmptyTopicSelector(t *testing.T) { } func TestPublishLegacyAuthorization(t *testing.T) { + t.Parallel() + hub := createDummy(WithProtocolVersionCompatibility(7)) form := url.Values{} @@ -171,6 +189,8 @@ func TestPublishLegacyAuthorization(t *testing.T) { } func TestPublishOK(t *testing.T) { + t.Parallel() + hub := createDummy() topics := []string{"http://example.com/books/1"} @@ -217,6 +237,8 @@ func TestPublishOK(t *testing.T) { } func TestPublishNoData(t *testing.T) { + t.Parallel() + hub := createDummy() form := url.Values{} @@ -236,6 +258,8 @@ func TestPublishNoData(t *testing.T) { } func TestPublishGenerateUUID(t *testing.T) { + t.Parallel() + h := createDummy() s := NewLocalSubscriber("", zap.NewNop(), &TopicSelectorStore{}) @@ -279,6 +303,8 @@ func TestPublishGenerateUUID(t *testing.T) { } func TestPublishWithErrorInTransport(t *testing.T) { + t.Parallel() + defer func() { if r := recover(); r == nil { t.Errorf("The code did not panic") diff --git a/subscribe_test.go b/subscribe_test.go index 81f7be21..2547b327 100644 --- a/subscribe_test.go +++ b/subscribe_test.go @@ -126,6 +126,8 @@ func (r *subscribeRecorder) FlushError() error { } func TestSubscribeNotAFlusher(t *testing.T) { + t.Parallel() + hub := createAnonymousDummy() go func() { @@ -153,6 +155,8 @@ func TestSubscribeNotAFlusher(t *testing.T) { } func TestSubscribeNoCookie(t *testing.T) { + t.Parallel() + hub := createDummy() req := httptest.NewRequest(http.MethodGet, defaultHubURL, nil) @@ -168,6 +172,8 @@ func TestSubscribeNoCookie(t *testing.T) { } func TestSubscribeInvalidJWT(t *testing.T) { + t.Parallel() + hub := createDummy() req := httptest.NewRequest(http.MethodGet, defaultHubURL, nil) @@ -184,6 +190,8 @@ func TestSubscribeInvalidJWT(t *testing.T) { } func TestSubscribeUnauthorizedJWT(t *testing.T) { + t.Parallel() + hub := createDummy() req := httptest.NewRequest(http.MethodGet, defaultHubURL, nil) @@ -201,6 +209,8 @@ func TestSubscribeUnauthorizedJWT(t *testing.T) { } func TestSubscribeInvalidAlgJWT(t *testing.T) { + t.Parallel() + hub := createDummy() req := httptest.NewRequest(http.MethodGet, defaultHubURL, nil) @@ -217,6 +227,8 @@ func TestSubscribeInvalidAlgJWT(t *testing.T) { } func TestSubscribeNoTopic(t *testing.T) { + t.Parallel() + hub := createAnonymousDummy() req := httptest.NewRequest(http.MethodGet, defaultHubURL, nil) @@ -255,6 +267,8 @@ func (*addSubscriberErrorTransport) Close() error { } func TestSubscribeAddSubscriberError(t *testing.T) { + t.Parallel() + hub := createAnonymousDummy(WithTransport(&addSubscriberErrorTransport{})) req := httptest.NewRequest(http.MethodGet, defaultHubURL+"?topic=foo", nil) @@ -329,6 +343,8 @@ func testSubscribe(h interface{ Helper() }, numberOfSubscribers int) { } func TestSubscribe(t *testing.T) { + t.Parallel() + testSubscribe(t, 3) } @@ -350,6 +366,8 @@ func testSubscribeLogs(t *testing.T, hub *Hub, payload interface{}) { } func TestSubscribeWithLogLevelDebug(t *testing.T) { + t.Parallel() + core, logs := observer.New(zapcore.DebugLevel) payload := map[string]interface{}{ "bar": "baz", @@ -366,6 +384,8 @@ func TestSubscribeWithLogLevelDebug(t *testing.T) { } func TestSubscribeLogLevelInfo(t *testing.T) { + t.Parallel() + core, logs := observer.New(zapcore.InfoLevel) payload := map[string]interface{}{ "bar": "baz", @@ -379,6 +399,8 @@ func TestSubscribeLogLevelInfo(t *testing.T) { } func TestSubscribeLogAnonymousSubscriber(t *testing.T) { + t.Parallel() + core, logs := observer.New(zapcore.DebugLevel) h := createAnonymousDummy(WithLogger(zap.New(core))) @@ -399,6 +421,8 @@ func TestSubscribeLogAnonymousSubscriber(t *testing.T) { } func TestUnsubscribe(t *testing.T) { + t.Parallel() + hub := createAnonymousDummy() s, _ := hub.transport.(*LocalTransport) @@ -434,6 +458,8 @@ func TestUnsubscribe(t *testing.T) { } func TestSubscribePrivate(t *testing.T) { + t.Parallel() + hub := createDummy() s, _ := hub.transport.(*LocalTransport) @@ -482,6 +508,8 @@ func TestSubscribePrivate(t *testing.T) { } func TestSubscriptionEvents(t *testing.T) { + t.Parallel() + hub := createDummy(WithSubscriptions()) var wg sync.WaitGroup @@ -559,6 +587,8 @@ func TestSubscriptionEvents(t *testing.T) { } func TestSubscribeAll(t *testing.T) { + t.Parallel() + hub := createDummy() s, _ := hub.transport.(*LocalTransport) @@ -602,11 +632,12 @@ func TestSubscribeAll(t *testing.T) { } func TestSendMissedEvents(t *testing.T) { - bt := createBoltTransport("bolt://test.db") - hub := createAnonymousDummy(WithLogger(bt.logger), WithTransport(bt), WithProtocolVersionCompatibility(7)) - transport := hub.transport.(*BoltTransport) - defer transport.Close() - defer os.Remove("test.db") + t.Parallel() + + transport, cleanup := createBoltTransport(t, 0, 0) + defer cleanup() + + hub := createAnonymousDummy(WithLogger(transport.logger), WithTransport(transport), WithProtocolVersionCompatibility(7)) transport.Dispatch(&Update{ Topics: []string{"http://example.com/foos/a"}, @@ -680,11 +711,11 @@ func TestSendMissedEvents(t *testing.T) { } func TestSendAllEvents(t *testing.T) { - bt := createBoltTransport("bolt://test.db") - hub := createAnonymousDummy(WithLogger(bt.logger), WithTransport(bt)) - transport := hub.transport.(*BoltTransport) - defer transport.Close() - defer os.Remove("test.db") + t.Parallel() + + transport, cleanup := createBoltTransport(t, 0, 0) + defer cleanup() + hub := createAnonymousDummy(WithLogger(transport.logger), WithTransport(transport)) transport.Dispatch(&Update{ Topics: []string{"http://example.com/foos/a"}, @@ -743,11 +774,12 @@ func TestSendAllEvents(t *testing.T) { } func TestUnknownLastEventID(t *testing.T) { - bt := createBoltTransport("bolt://test.db") - hub := createAnonymousDummy(WithLogger(bt.logger), WithTransport(bt)) - transport := hub.transport.(*BoltTransport) - defer transport.Close() - defer os.Remove("test.db") + t.Parallel() + + transport, cleanup := createBoltTransport(t, 0, 0) + defer cleanup() + + hub := createAnonymousDummy(WithLogger(transport.logger), WithTransport(transport)) transport.Dispatch(&Update{ Topics: []string{"http://example.com/foos/a"}, @@ -819,11 +851,12 @@ func TestUnknownLastEventID(t *testing.T) { } func TestUnknownLastEventIDEmptyHistory(t *testing.T) { - bt := createBoltTransport("bolt://test.db") - hub := createAnonymousDummy(WithLogger(bt.logger), WithTransport(bt)) - transport := hub.transport.(*BoltTransport) - defer transport.Close() - defer os.Remove("test.db") + t.Parallel() + + transport, cleanup := createBoltTransport(t, 0, 0) + defer cleanup() + + hub := createAnonymousDummy(WithLogger(transport.logger), WithTransport(transport)) var wg sync.WaitGroup wg.Add(2) @@ -923,6 +956,8 @@ func TestSubscribeHeartbeat(t *testing.T) { } func TestSubscribeExpires(t *testing.T) { + t.Parallel() + hub := createAnonymousDummy(WithWriteTimeout(0), WithDispatchTimeout(0), WithHeartbeat(500*time.Millisecond)) token := jwt.New(jwt.SigningMethodHS256) diff --git a/subscriber_test.go b/subscriber_test.go index b3fe3fff..bffd2ac7 100644 --- a/subscriber_test.go +++ b/subscriber_test.go @@ -9,6 +9,8 @@ import ( ) func TestDispatch(t *testing.T) { + t.Parallel() + s := NewLocalSubscriber("1", zap.NewNop(), &TopicSelectorStore{}) s.SubscribedTopics = []string{"http://example.com"} s.SubscribedTopics = []string{"http://example.com"} @@ -32,6 +34,8 @@ func TestDispatch(t *testing.T) { } func TestDisconnect(t *testing.T) { + t.Parallel() + s := NewLocalSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.Disconnect() // can be called two times without crashing @@ -41,6 +45,8 @@ func TestDisconnect(t *testing.T) { } func TestLogSubscriber(t *testing.T) { + t.Parallel() + sink, logger := newTestLogger(t) defer sink.Reset() @@ -59,6 +65,8 @@ func TestLogSubscriber(t *testing.T) { } func TestMatchTopic(t *testing.T) { + t.Parallel() + s := NewLocalSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.SetTopics([]string{"https://example.com/no-match", "https://example.com/books/{id}"}, []string{"https://example.com/users/foo/{?topic}"}) @@ -73,6 +81,8 @@ func TestMatchTopic(t *testing.T) { } func TestSubscriberDoesNotBlockWhenChanIsFull(t *testing.T) { + t.Parallel() + s := NewLocalSubscriber("", zap.NewNop(), &TopicSelectorStore{}) s.Ready() diff --git a/subscriberlist_test.go b/subscriberlist_test.go index 5cd6a255..1bae043c 100644 --- a/subscriberlist_test.go +++ b/subscriberlist_test.go @@ -9,11 +9,15 @@ import ( ) func TestEncode(t *testing.T) { + t.Parallel() + e := encode([]string{"Foo\x00\x01Bar\x00Baz\x01", "\x01bar"}, true) assert.Equal(t, "1\x01\x00\x01bar\x01Foo\x00\x00\x00\x01Bar\x00\x00Baz\x00\x01", e) } func TestDecode(t *testing.T) { + t.Parallel() + topics, private := decode("1\x01\x00\x01bar\x01Foo\x00\x00\x00\x01Bar\x00\x00Baz\x00\x01") assert.Equal(t, []string{"\x01bar", "Foo\x00\x01Bar\x00Baz\x01"}, topics) diff --git a/subscription_test.go b/subscription_test.go index 25334c01..43d545e8 100644 --- a/subscription_test.go +++ b/subscription_test.go @@ -14,6 +14,8 @@ import ( ) func TestSubscriptionsHandlerAccessDenied(t *testing.T) { + t.Parallel() + hub := createDummy() req := httptest.NewRequest(http.MethodGet, subscriptionsURL, nil) @@ -41,6 +43,8 @@ func TestSubscriptionsHandlerAccessDenied(t *testing.T) { } func TestSubscriptionHandlerAccessDenied(t *testing.T) { + t.Parallel() + hub := createDummy() req := httptest.NewRequest(http.MethodGet, defaultHubURL+subscriptionsPath+"/bar/baz", nil) @@ -60,6 +64,8 @@ func TestSubscriptionHandlerAccessDenied(t *testing.T) { } func TestSubscriptionHandlersETag(t *testing.T) { + t.Parallel() + hub := createDummy() req := httptest.NewRequest(http.MethodGet, defaultHubURL+subscriptionsPath, nil) @@ -82,6 +88,8 @@ func TestSubscriptionHandlersETag(t *testing.T) { } func TestSubscriptionsHandler(t *testing.T) { + t.Parallel() + logger := zap.NewNop() hub := createDummy(WithLogger(logger)) @@ -124,6 +132,8 @@ func TestSubscriptionsHandler(t *testing.T) { } func TestSubscriptionsHandlerForTopic(t *testing.T) { + t.Parallel() + logger := zap.NewNop() hub := createDummy(WithLogger(logger)) tss := &TopicSelectorStore{} @@ -171,6 +181,8 @@ func TestSubscriptionsHandlerForTopic(t *testing.T) { } func TestSubscriptionHandler(t *testing.T) { + t.Parallel() + logger := zap.NewNop() hub := createDummy(WithLogger(logger)) tss := &TopicSelectorStore{} diff --git a/topicselectorlru_test.go b/topicselectorlru_test.go index d0cb158a..7a1ddc56 100644 --- a/topicselectorlru_test.go +++ b/topicselectorlru_test.go @@ -8,6 +8,8 @@ import ( ) func TestMatchLRU(t *testing.T) { + t.Parallel() + tss, err := NewTopicSelectorStoreLRU(DefaultTopicSelectorStoreLRUMaxEntriesPerShard, DefaultTopicSelectorStoreLRUMaxEntriesPerShard) require.NoError(t, err) diff --git a/update_test.go b/update_test.go index 65f74cc8..2c1ac1a0 100644 --- a/update_test.go +++ b/update_test.go @@ -11,6 +11,8 @@ import ( ) func TestAssignUUID(t *testing.T) { + t.Parallel() + u := &Update{ Topics: []string{"foo"}, Private: true, @@ -28,6 +30,8 @@ func TestAssignUUID(t *testing.T) { } func TestLogUpdate(t *testing.T) { + t.Parallel() + sink, logger := newTestLogger(t) defer sink.Reset() From 52d3bac73399632d2edcee0e06469452f82d7955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 17 Feb 2025 11:45:11 +0100 Subject: [PATCH 67/71] feat: automatically set GOMEMLIMIT (#1010) --- caddy/go.mod | 4 +++- caddy/go.sum | 4 ++++ caddy/mercure/main.go | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/caddy/go.mod b/caddy/go.mod index 2b6f916f..fb9f98b8 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -12,11 +12,13 @@ retract ( replace github.com/dunglas/mercure => ../ require ( + github.com/KimMachineGun/automemlimit v0.7.0 github.com/MicahParks/keyfunc/v3 v3.3.10 github.com/caddyserver/caddy/v2 v2.9.1 github.com/dunglas/mercure v0.18.2 github.com/stretchr/testify v1.10.0 go.uber.org/zap v1.27.0 + go.uber.org/zap/exp v0.3.0 ) require ( @@ -102,6 +104,7 @@ require ( github.com/mschoch/smat v0.2.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/onsi/ginkgo/v2 v2.22.2 // indirect + github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pires/go-proxyproto v0.8.0 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -162,7 +165,6 @@ require ( go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap/exp v0.3.0 // indirect golang.org/x/crypto v0.33.0 // indirect golang.org/x/crypto/x509roots/fallback v0.0.0-20250214233241-911360c8a4f4 // indirect golang.org/x/exp v0.0.0-20250215185904-eff6e970281f // indirect diff --git a/caddy/go.sum b/caddy/go.sum index 9ed320ea..f1c38023 100644 --- a/caddy/go.sum +++ b/caddy/go.sum @@ -33,6 +33,8 @@ github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOv github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/KimMachineGun/automemlimit v0.7.0 h1:7G06p/dMSf7G8E6oq+f2uOPuVncFyIlDI/pBWK49u88= +github.com/KimMachineGun/automemlimit v0.7.0/go.mod h1:QZxpHaGOQoYvFhv/r4u3U0JTC2ZcOwbSr11UZF46UBM= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= @@ -336,6 +338,8 @@ github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cT github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 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= diff --git a/caddy/mercure/main.go b/caddy/mercure/main.go index 72fa6eac..ff2714a5 100644 --- a/caddy/mercure/main.go +++ b/caddy/mercure/main.go @@ -2,7 +2,13 @@ package main import ( + "log/slog" + + "github.com/caddyserver/caddy/v2" + + "github.com/KimMachineGun/automemlimit/memlimit" caddycmd "github.com/caddyserver/caddy/v2/cmd" + "go.uber.org/zap/exp/zapslog" // plug in Caddy modules here. _ "github.com/caddyserver/caddy/v2/modules/standard" @@ -10,5 +16,19 @@ import ( ) func main() { + // Backport of https://github.com/caddyserver/caddy/pull/6809 + // TODO: remove this block when Caddy 2.10 will be released + _, _ = memlimit.SetGoMemLimitWithOpts( + memlimit.WithLogger( + slog.New(zapslog.NewHandler(caddy.Log().Core())), + ), + memlimit.WithProvider( + memlimit.ApplyFallback( + memlimit.FromCgroup, + memlimit.FromSystem, + ), + ), + ) + caddycmd.Main() } From 4a159441546281b9580a58bf43b0eaf400d3a266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 17 Feb 2025 14:26:13 +0100 Subject: [PATCH 68/71] test: fix race condition in memory sink (#1011) * test: fix race condition in memory sink * cs --- log_test.go | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/log_test.go b/log_test.go index d2d826ba..392bde58 100644 --- a/log_test.go +++ b/log_test.go @@ -5,6 +5,7 @@ import ( "net/url" "testing" + "github.com/stretchr/testify/require" "go.uber.org/zap" ) @@ -19,27 +20,19 @@ type MemorySink struct { func (s *MemorySink) Close() error { return nil } func (s *MemorySink) Sync() error { return nil } -var sink *MemorySink - func newTestLogger(t *testing.T) (*MemorySink, *zap.Logger) { t.Helper() - if sink == nil { - sink = &MemorySink{new(bytes.Buffer)} - if err := zap.RegisterSink("memory", func(*url.URL) (zap.Sink, error) { - return sink, nil - }); err != nil { - t.Fatal(err) - } - } + sink := &MemorySink{new(bytes.Buffer)} + require.NoError(t, zap.RegisterSink(t.Name(), func(*url.URL) (zap.Sink, error) { + return sink, nil + })) conf := zap.NewProductionConfig() - conf.OutputPaths = []string{"memory://"} + conf.OutputPaths = []string{t.Name() + "://"} logger, err := conf.Build() - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) return sink, logger } From bf2555a9a48e914e1ac2efb217be3eeb69b66fa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 17 Feb 2025 15:59:03 +0100 Subject: [PATCH 69/71] chore: prepare release 0.18.3 --- caddy/go.mod | 2 +- charts/mercure/Chart.yaml | 4 ++-- charts/mercure/README.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index fb9f98b8..393a9801 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -15,7 +15,7 @@ require ( github.com/KimMachineGun/automemlimit v0.7.0 github.com/MicahParks/keyfunc/v3 v3.3.10 github.com/caddyserver/caddy/v2 v2.9.1 - github.com/dunglas/mercure v0.18.2 + github.com/dunglas/mercure v0.18.3 github.com/stretchr/testify v1.10.0 go.uber.org/zap v1.27.0 go.uber.org/zap/exp v0.3.0 diff --git a/charts/mercure/Chart.yaml b/charts/mercure/Chart.yaml index de75cbee..ca35dd52 100644 --- a/charts/mercure/Chart.yaml +++ b/charts/mercure/Chart.yaml @@ -12,8 +12,8 @@ keywords: - streaming-api - async-api type: application -version: 0.18.2 -appVersion: "v0.18.2" +version: 0.18.3 +appVersion: "v0.18.3" maintainers: - name: dunglas email: kevin@dunglas.fr diff --git a/charts/mercure/README.md b/charts/mercure/README.md index 7aeaf3ae..fcefabba 100644 --- a/charts/mercure/README.md +++ b/charts/mercure/README.md @@ -1,7 +1,7 @@ # Mercure Chart for Kubernetes -![Version: 0.18.2](https://img.shields.io/badge/Version-0.18.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.18.2](https://img.shields.io/badge/AppVersion-v0.18.2-informational?style=flat-square) +![Version: 0.18.3](https://img.shields.io/badge/Version-0.18.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.18.3](https://img.shields.io/badge/AppVersion-v0.18.3-informational?style=flat-square) A Helm chart to install a Mercure Hub in a Kubernetes cluster. Mercure is a protocol to push data updates to web browsers and other HTTP clients in a convenient, fast, reliable and battery-efficient way. From 7d65b328f0fc62bf35c5ad4387b6b6564da28d42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 19 Feb 2025 01:02:22 +0100 Subject: [PATCH 70/71] fix: duplicate metrics collector registration attempted panic --- caddy/caddy_test.go | 14 +++++++++++++- metrics.go | 17 ++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/caddy/caddy_test.go b/caddy/caddy_test.go index 33ae50df..d352ce5e 100644 --- a/caddy/caddy_test.go +++ b/caddy/caddy_test.go @@ -52,7 +52,19 @@ localhost:9080 { mercure { anonymous publisher_jwt !ChangeMe! - %s + %[1]s + } + + respond 404 + } +} + +example.com:9080 { + route { + mercure { + anonymous + publisher_jwt !ChangeMe! + %[1]s } respond 404 diff --git a/metrics.go b/metrics.go index e5398bfe..70a695d5 100644 --- a/metrics.go +++ b/metrics.go @@ -1,6 +1,7 @@ package mercure import ( + "errors" "net/http" "github.com/dunglas/mercure/common" @@ -62,9 +63,19 @@ func NewPrometheusMetrics(registry prometheus.Registerer) *PrometheusMetrics { ), } - m.registry.MustRegister(m.subscribers) - m.registry.MustRegister(m.subscribersTotal) - m.registry.MustRegister(m.updatesTotal) + // https://github.com/caddyserver/caddy/pull/6820 + if err := m.registry.Register(m.subscribers); err != nil && + !errors.As(err, &prometheus.AlreadyRegisteredError{}) { + panic(err) + } + if err := m.registry.Register(m.subscribersTotal); err != nil && + !errors.As(err, &prometheus.AlreadyRegisteredError{}) { + panic(err) + } + if err := m.registry.Register(m.updatesTotal); err != nil && + !errors.As(err, &prometheus.AlreadyRegisteredError{}) { + panic(err) + } return m } From b508d1ba5afb3c760a108b3a87e906829cf271d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 19 Feb 2025 12:17:52 +0100 Subject: [PATCH 71/71] chore: prepare release 0.18.4 --- caddy/go.mod | 2 +- charts/mercure/Chart.yaml | 4 ++-- charts/mercure/README.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/caddy/go.mod b/caddy/go.mod index 393a9801..2096bc31 100644 --- a/caddy/go.mod +++ b/caddy/go.mod @@ -15,7 +15,7 @@ require ( github.com/KimMachineGun/automemlimit v0.7.0 github.com/MicahParks/keyfunc/v3 v3.3.10 github.com/caddyserver/caddy/v2 v2.9.1 - github.com/dunglas/mercure v0.18.3 + github.com/dunglas/mercure v0.18.4 github.com/stretchr/testify v1.10.0 go.uber.org/zap v1.27.0 go.uber.org/zap/exp v0.3.0 diff --git a/charts/mercure/Chart.yaml b/charts/mercure/Chart.yaml index ca35dd52..2e563df0 100644 --- a/charts/mercure/Chart.yaml +++ b/charts/mercure/Chart.yaml @@ -12,8 +12,8 @@ keywords: - streaming-api - async-api type: application -version: 0.18.3 -appVersion: "v0.18.3" +version: 0.18.4 +appVersion: "v0.18.4" maintainers: - name: dunglas email: kevin@dunglas.fr diff --git a/charts/mercure/README.md b/charts/mercure/README.md index fcefabba..82978ac1 100644 --- a/charts/mercure/README.md +++ b/charts/mercure/README.md @@ -1,7 +1,7 @@ # Mercure Chart for Kubernetes -![Version: 0.18.3](https://img.shields.io/badge/Version-0.18.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.18.3](https://img.shields.io/badge/AppVersion-v0.18.3-informational?style=flat-square) +![Version: 0.18.4](https://img.shields.io/badge/Version-0.18.4-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.18.4](https://img.shields.io/badge/AppVersion-v0.18.4-informational?style=flat-square) A Helm chart to install a Mercure Hub in a Kubernetes cluster. Mercure is a protocol to push data updates to web browsers and other HTTP clients in a convenient, fast, reliable and battery-efficient way.