diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 50336103b..f21dc3bd7 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -5,6 +5,10 @@ on:
branches:
- 'main'
- 'release-*'
+ paths-ignore:
+ - "**.md"
+ - "docs/**"
+ - "hugo/**"
pull_request:
types:
- opened
diff --git a/.gitignore b/.gitignore
index 5fbadf796..e3add1fc0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
build/
**/build/
+build/certs/nginx-repo.key
+build/certs/nginx-repo.crt
bin/
whitesource/
.vscode/
diff --git a/Makefile b/Makefile
index 0eefceef7..8d83c686f 100644
--- a/Makefile
+++ b/Makefile
@@ -23,8 +23,8 @@ DATE = $(shell date +%F_%H-%M-%S)
# | suse | sles12sp5, sle15 | |
# | freebsd | | Not supported |
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-OS_RELEASE ?= ubuntu
-OS_VERSION ?= 22.04
+OS_RELEASE ?= debian
+OS_VERSION ?= bullseye-slim
BASE_IMAGE = "${CONTAINER_REGISTRY}/${OS_RELEASE}:${OS_VERSION}"
IMAGE_TAG = "agent_${OS_RELEASE}_${OS_VERSION}"
@@ -83,7 +83,7 @@ show-env: $(addprefix show-var-, $(SHOW_ENV_VARS)) ## Show environment
all: clean build run ## Compile and run code.
clean: ## Remove build directory
- rm -rf ./build
+ if [ -d "./build" ]; then find ./build -mindepth 1 ! -path '${CERTS_DIR}/nginx-repo.crt' ! -path '${CERTS_DIR}/nginx-repo.key' -delete; fi
run: ## Run code
go run -ldflags=${LDFLAGS} main.go
@@ -105,7 +105,7 @@ deps: ## Update dependencies in vendor folders
go work sync
no-local-changes:
- git diff --quiet || { echo "Depenency changes detected. Please commit these before pushing." >&2; exit 1; }
+ git diff --quiet || { echo "Dependency changes detected. Please commit these before pushing." >&2; exit 1; }
lint: ## Run linter
GOWORK=off go vet ./...
@@ -252,8 +252,8 @@ image: ## Build agent container image for NGINX Plus, need nginx-repo.crt and ng
@echo Building image with $(CONTAINER_CLITOOL); \
$(CONTAINER_BUILDENV) $(CONTAINER_CLITOOL) build -t ${IMAGE_TAG} . \
--no-cache -f ./scripts/docker/nginx-plus/${OS_RELEASE}/Dockerfile \
- --secret id=nginx-crt,src=build/nginx-repo.crt \
- --secret id=nginx-key,src=build/nginx-repo.key \
+ --secret id=nginx-crt,src=${CERTS_DIR}/nginx-repo.crt \
+ --secret id=nginx-key,src=${CERTS_DIR}/nginx-repo.key \
--build-arg BASE_IMAGE=${BASE_IMAGE} \
--build-arg PACKAGES_REPO=${PACKAGES_REPO} \
--build-arg OS_RELEASE=${OS_RELEASE} \
diff --git a/README.md b/README.md
index 1d9f18a45..9aeccb5fa 100644
--- a/README.md
+++ b/README.md
@@ -64,8 +64,8 @@ NGINX Agent allows a gRPC connected control system to register a listener for a
| Event | Description |
| -------------------------------- | -------------------------------------------- |
-| AGENT_START_MESSAGE | NGINX Agent process started |
-| AGENT_STOP_MESSAGE | NGINX Agent process stopped |
+| AGENT_START_MESSAGE | NGINX Agent process started |
+| AGENT_STOP_MESSAGE | NGINX Agent process stopped |
| NGINX_FOUND_MESSAGE | NGINX master process detected on system |
| NGINX_STOP_MESSAGE | NGINX master process stopped |
| NGINX_RELOAD_SUCCESS_MESSAGE | NGINX master process reloaded successfully |
@@ -131,7 +131,7 @@ Follow steps in the [Installation](#installation) section to download, install,
Using your preferred method, clone the NGINX Agent repository into your development directory. See [Cloning a GitHub Repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) for additional help.
## Installing Go
-NGINX Agent and the Mock Control Plane are written in Go. Go 1.19 or higher is required to build and run either application from the source code directory. You can [download Go from the official website](https://go.dev/dl/).
+NGINX Agent and the Mock Control Plane are written in Go. Go 1.19.9 or higher is required to build and run either application from the source code directory. You can [download Go from the official website](https://go.dev/dl/).
## Starting the gRPC Mock Control Plane
Start the mock control plane by running the following command from the `agent` source code root directory:
diff --git a/docs/proto/events.md b/docs/proto/events.md
index 11650ce1c..fc5f48021 100644
--- a/docs/proto/events.md
+++ b/docs/proto/events.md
@@ -43,13 +43,13 @@ Represents an activity event
### ContextData
-
+Represents the context data of each violation
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
-| Name | [string](#string) | | |
-| Value | [string](#string) | | |
+| Name | [string](#string) | | The name within the context data |
+| Value | [string](#string) | | The value within the context data |
@@ -117,45 +117,44 @@ Represents a security violation that is emitted by the agent
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
-| PolicyName | [string](#string) | | |
-| SupportID | [string](#string) | | |
-| Outcome | [string](#string) | | |
-| OutcomeReason | [string](#string) | | |
-| BlockingExceptionReason | [string](#string) | | |
-| Method | [string](#string) | | |
-| Protocol | [string](#string) | | |
-| XForwardedForHeaderValue | [string](#string) | | |
-| URI | [string](#string) | | |
-| Request | [string](#string) | | |
-| IsTruncated | [string](#string) | | |
-| RequestStatus | [string](#string) | | |
-| ResponseCode | [string](#string) | | |
-| ServerAddr | [string](#string) | | |
-| VSName | [string](#string) | | |
-| RemoteAddr | [string](#string) | | |
-| RemotePort | [string](#string) | | |
-| ServerPort | [string](#string) | | |
-| Violations | [string](#string) | | |
-| SubViolations | [string](#string) | | |
-| ViolationRating | [string](#string) | | |
-| SigSetNames | [string](#string) | | |
-| SigCVEs | [string](#string) | | |
-| ClientClass | [string](#string) | | |
-| ClientApplication | [string](#string) | | |
-| ClientApplicationVersion | [string](#string) | | |
-| Severity | [string](#string) | | |
-| ThreatCampaignNames | [string](#string) | | |
-| BotAnomalies | [string](#string) | | |
-| BotCategory | [string](#string) | | |
-| EnforcedBotAnomalies | [string](#string) | | |
-| BotSignatureName | [string](#string) | | |
-| ViolationContexts | [string](#string) | | |
-| ViolationsData | [ViolationData](#f5-nginx-agent-sdk-events-ViolationData) | repeated | |
-| SystemID | [string](#string) | | |
-| InstanceTags | [string](#string) | | |
-| InstanceGroup | [string](#string) | | |
-| DisplayName | [string](#string) | | |
-| ParentHostname | [string](#string) | | |
+| PolicyName | [string](#string) | | The name of the NGINX App Protect policy that triggered the security violation |
+| SupportID | [string](#string) | | The unique NGINX App Protect support ID of the violation, used for tracking purposes |
+| Outcome | [string](#string) | | The outcome that resulted for the security violation |
+| OutcomeReason | [string](#string) | | The reason for the security violation resulting in the outcome |
+| BlockingExceptionReason | [string](#string) | | The blocking exception reason when a configured violation was not blocked |
+| Method | [string](#string) | | The HTTP Method of the request that triggered the security violation |
+| Protocol | [string](#string) | | The HTTP Protocol of the request that triggered the security violation |
+| XForwardedForHeaderValue | [string](#string) | | The HTTP xff_header_value of the request that triggered the security violation |
+| URI | [string](#string) | | The URI of the request that triggered the security violation |
+| Request | [string](#string) | | The full request that triggered the security violation, including the Method, URI and Request Body |
+| IsTruncated | [string](#string) | | If the request is truncated or not |
+| RequestStatus | [string](#string) | | The status of the request that triggered the security violation |
+| ResponseCode | [string](#string) | | The HTTP response status to the request that triggered the security violation |
+| ServerAddr | [string](#string) | | The server address of the instance that caught the security violation |
+| VSName | [string](#string) | | The Virtual Server Name of the instance that caught the security violation |
+| RemoteAddr | [string](#string) | | The targeted address by the request that triggered the security violation |
+| RemotePort | [string](#string) | | The targeted port number by the request that triggered the security violation |
+| ServerPort | [string](#string) | | The server port of the instance that caught the security violation |
+| Violations | [string](#string) | | A comma-separated list of all the violations triggered by the request |
+| SubViolations | [string](#string) | | A comma-separated list of all the sub-violations triggered by the request |
+| ViolationRating | [string](#string) | | The rating of the triggered security violation |
+| SigSetNames | [string](#string) | | A comma-separated list of all the signature names |
+| SigCVEs | [string](#string) | | A comma-separated list of all the signature CVEs |
+| ClientClass | [string](#string) | | The class of the client used to send the request that triggered the security violation |
+| ClientApplication | [string](#string) | | The application used to send the request that triggered the security violation |
+| ClientApplicationVersion | [string](#string) | | The version of the application used to send the request that triggered the security violation |
+| Severity | [string](#string) | | The severity of the triggered security violation |
+| ThreatCampaignNames | [string](#string) | | A comma-separated list of the threat campaign names |
+| BotAnomalies | [string](#string) | | Anomalies of the bot that sent the request that triggered the security violation |
+| BotCategory | [string](#string) | | Category of the bot that sent the request that triggered the security violation |
+| EnforcedBotAnomalies | [string](#string) | | Enforced anomalies of the bot that sent the request that triggered the security violation |
+| BotSignatureName | [string](#string) | | Signature name of the bot that sent the request that triggered the security violation |
+| ViolationsData | [ViolationData](#f5-nginx-agent-sdk-events-ViolationData) | repeated | A list of objects containing descriptive data about all the security violations |
+| SystemID | [string](#string) | | SystemID of the instance where NGINX is running |
+| InstanceTags | [string](#string) | | Instance tags where NGINX is running |
+| InstanceGroup | [string](#string) | | Instance group where NGINX is running |
+| DisplayName | [string](#string) | | Display name of the instance where NGINX is running |
+| ParentHostname | [string](#string) | | The hostname where NGINX is running |
@@ -165,16 +164,16 @@ Represents a security violation that is emitted by the agent
### SignatureData
-
+Represents signature data that's contained within each violation
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
-| ID | [string](#string) | | |
-| BlockingMask | [string](#string) | | |
-| Buffer | [string](#string) | | |
-| Offset | [string](#string) | | |
-| Length | [string](#string) | | |
+| ID | [string](#string) | | ID of the signature data |
+| BlockingMask | [string](#string) | | The blocking mask of the signature data |
+| Buffer | [string](#string) | | The buffer of the signature data |
+| Offset | [string](#string) | | The offset of the signature data |
+| Length | [string](#string) | | The length of the signature data |
@@ -184,15 +183,15 @@ Represents a security violation that is emitted by the agent
### ViolationData
-
+Represents the violation data contained within a security violation event
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
-| Name | [string](#string) | | |
-| Context | [string](#string) | | |
-| ContextData | [ContextData](#f5-nginx-agent-sdk-events-ContextData) | | |
-| Signatures | [SignatureData](#f5-nginx-agent-sdk-events-SignatureData) | repeated | |
+| Name | [string](#string) | | The name of the violation |
+| Context | [string](#string) | | The context of the violation |
+| ContextData | [ContextData](#f5-nginx-agent-sdk-events-ContextData) | | The object representing the context data of the violation |
+| Signatures | [SignatureData](#f5-nginx-agent-sdk-events-SignatureData) | repeated | A list representing the signature data of the violation |
diff --git a/docs/proto/proto.md b/docs/proto/proto.md
index 4f7382cdd..d8fcf6774 100644
--- a/docs/proto/proto.md
+++ b/docs/proto/proto.md
@@ -12,6 +12,8 @@
- [AgentDetails](#f5-nginx-agent-sdk-AgentDetails)
- [AgentLogging](#f5-nginx-agent-sdk-AgentLogging)
- [AgentMeta](#f5-nginx-agent-sdk-AgentMeta)
+ - [Backoff](#f5-nginx-agent-sdk-Backoff)
+ - [Server](#f5-nginx-agent-sdk-Server)
- [AgentConnectStatus.StatusCode](#f5-nginx-agent-sdk-AgentConnectStatus-StatusCode)
- [AgentLogging.Level](#f5-nginx-agent-sdk-AgentLogging-Level)
@@ -204,6 +206,7 @@ Represents agent details. This message is sent from the management server to the
| extensions | [string](#string) | repeated | List of agent extensions that are enabled |
| tags | [string](#string) | repeated | List of tags |
| alias | [string](#string) | | Alias name for the agent |
+| server | [Server](#f5-nginx-agent-sdk-Server) | | Server setting for the agent |
@@ -251,6 +254,45 @@ Represents agent metadata
+
+
+
+### Backoff
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| initial_interval | [int64](#int64) | | First backoff time interval in seconds |
+| randomization_factor | [double](#double) | | Random value used to create range around next backoff interval |
+| multiplier | [double](#double) | | Value to be multiplied with current backoff interval |
+| max_interval | [int64](#int64) | | Max interval in seconds between two retries |
+| max_elapsed_time | [int64](#int64) | | Elapsed time in seconds after which backoff stops. It never stops if max_elapsed_time == 0. |
+
+
+
+
+
+
+
+
+### Server
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| host | [string](#string) | | Host name or IP of the host to connect to |
+| grpc_port | [int32](#int32) | | Grpc port to connect to |
+| token | [string](#string) | | Shared secrect between the server and client |
+| metrics | [string](#string) | | Metrics server name |
+| command | [string](#string) | | Command server name |
+| backoff | [Backoff](#f5-nginx-agent-sdk-Backoff) | | Backoff settings for exponential retry and backoff |
+
+
+
+
+
diff --git a/go.mod b/go.mod
index eb97de389..11155376b 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,7 @@ go 1.19
require (
github.com/alvaroloes/enumer v1.1.2
- github.com/cenkalti/backoff/v4 v4.2.0 // indirect
+ github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/fsnotify/fsnotify v1.6.0
github.com/gogo/protobuf v1.3.2
github.com/golang/mock v1.6.0
@@ -20,7 +20,7 @@ require (
github.com/nxadm/tail v1.4.8
github.com/orcaman/concurrent-map v1.0.0
github.com/shirou/gopsutil v3.21.11+incompatible
- github.com/shirou/gopsutil/v3 v3.22.7
+ github.com/shirou/gopsutil/v3 v3.23.2
github.com/sirupsen/logrus v1.9.0
github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
@@ -28,9 +28,9 @@ require (
github.com/stretchr/testify v1.8.2
github.com/trivago/grok v1.0.0
github.com/vardius/message-bus v1.1.5
- go.uber.org/atomic v1.10.0
- golang.org/x/sync v0.1.0
- google.golang.org/grpc v1.52.0
+ go.uber.org/atomic v1.11.0
+ golang.org/x/sync v0.2.0
+ google.golang.org/grpc v1.55.0
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/mcuadros/go-syslog.v2 v2.3.0
@@ -38,55 +38,87 @@ require (
)
require (
- github.com/bufbuild/buf v1.17.0
- github.com/evilmartians/lefthook v1.3.10
+ github.com/bufbuild/buf v1.18.0
+ github.com/evilmartians/lefthook v1.3.13
github.com/go-resty/resty/v2 v2.7.0
github.com/go-swagger/go-swagger v0.30.4
+ github.com/golangci/golangci-lint v1.52.2
github.com/goreleaser/nfpm/v2 v2.28.0
github.com/nginx/agent/sdk/v2 v2.0.0-00010101000000-000000000000
github.com/prometheus/client_golang v1.13.0
github.com/pseudomuto/protoc-gen-doc v1.5.1
- github.com/rs/cors v1.8.3
- golang.org/x/sys v0.7.0
+ github.com/rs/cors v1.9.0
+ golang.org/x/sys v0.8.0
+ golang.org/x/text v0.9.0
gopkg.in/yaml.v2 v2.4.0
)
require (
+ 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect
+ 4d63.com/gochecknoglobals v0.2.1 // indirect
+ github.com/Abirdcfly/dupword v0.0.11 // indirect
github.com/AlekSi/pointer v1.2.0 // indirect
+ github.com/Antonboom/errname v0.1.9 // indirect
+ github.com/Antonboom/nilnil v0.1.3 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
+ github.com/BurntSushi/toml v1.2.1 // indirect
+ github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
+ github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
- github.com/Microsoft/go-winio v0.6.0 // indirect
+ github.com/Microsoft/go-winio v0.6.1 // indirect
+ github.com/OpenPeeDeeP/depguard v1.1.1 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20210512092938-c05353c2d58c // indirect
+ github.com/alexkohler/prealloc v1.0.0 // indirect
+ github.com/alingse/asasalint v0.0.11 // indirect
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
+ github.com/ashanbrown/forbidigo v1.5.1 // indirect
+ github.com/ashanbrown/makezero v1.1.1 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
+ github.com/bkielbasa/cyclop v1.2.0 // indirect
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb // indirect
+ github.com/blizzy78/varnamelen v0.8.0 // indirect
+ github.com/bombsimon/wsl/v3 v3.4.0 // indirect
+ github.com/breml/bidichk v0.2.4 // indirect
+ github.com/breml/errchkjson v0.3.1 // indirect
github.com/briandowns/spinner v1.23.0 // indirect
- github.com/bufbuild/connect-go v1.6.0 // indirect
+ github.com/bufbuild/connect-go v1.7.0 // indirect
github.com/bufbuild/protocompile v0.5.1 // indirect
+ github.com/butuzov/ireturn v0.1.1 // indirect
github.com/cavaliergopher/cpio v1.0.1 // indirect
- github.com/cespare/xxhash/v2 v2.1.2 // indirect
+ github.com/cespare/xxhash/v2 v2.2.0 // indirect
+ github.com/charithe/durationcheck v0.0.10 // indirect
github.com/charmbracelet/lipgloss v0.7.1 // indirect
+ github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/creack/pty v1.1.18 // indirect
+ github.com/curioswitch/go-reassign v0.2.0 // indirect
+ github.com/daixiang0/gci v0.10.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/docker/cli v23.0.2+incompatible // indirect
+ github.com/denis-tingaikin/go-header v0.4.3 // indirect
+ github.com/docker/cli v23.0.5+incompatible // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
- github.com/docker/docker v23.0.2+incompatible // indirect
+ github.com/docker/docker v23.0.5+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/emirpasic/gods v1.12.0 // indirect
- github.com/envoyproxy/protoc-gen-validate v0.3.0-java // indirect
- github.com/fatih/color v1.14.1 // indirect
+ github.com/envoyproxy/protoc-gen-validate v0.10.0 // indirect
+ github.com/esimonov/ifshort v1.0.4 // indirect
+ github.com/ettle/strcase v0.1.1 // indirect
+ github.com/fatih/color v1.15.0 // indirect
+ github.com/fatih/structtag v1.2.0 // indirect
github.com/felixge/fgprof v0.9.3 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
+ github.com/firefart/nonamedreturns v1.0.4 // indirect
+ github.com/fzipp/gocyclo v0.6.0 // indirect
github.com/go-chi/chi/v5 v5.0.8 // indirect
+ github.com/go-critic/go-critic v0.7.0 // indirect
github.com/go-git/gcfg v1.5.0 // indirect
github.com/go-git/go-billy/v5 v5.3.1 // indirect
github.com/go-git/go-git/v5 v5.2.0 // indirect
@@ -104,16 +136,42 @@ require (
github.com/go-openapi/strfmt v0.21.3 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/go-openapi/validate v0.22.0 // indirect
+ github.com/go-toolsmith/astcast v1.1.0 // indirect
+ github.com/go-toolsmith/astcopy v1.1.0 // indirect
+ github.com/go-toolsmith/astequal v1.1.0 // indirect
+ github.com/go-toolsmith/astfmt v1.1.0 // indirect
+ github.com/go-toolsmith/astp v1.1.0 // indirect
+ github.com/go-toolsmith/strparse v1.1.0 // indirect
+ github.com/go-toolsmith/typep v1.1.0 // indirect
+ github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gofrs/uuid/v5 v5.0.0 // indirect
+ github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect
+ github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect
+ github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect
+ github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 // indirect
+ github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect
+ github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect
+ github.com/golangci/misspell v0.4.0 // indirect
+ github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect
+ github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect
github.com/google/go-containerregistry v0.14.0 // indirect
- github.com/google/pprof v0.0.0-20230323073829-e72429f035bd // indirect
+ github.com/google/pprof v0.0.0-20230502171905-255e3b9b56de // indirect
+ github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 // indirect
github.com/goreleaser/chglog v0.4.2 // indirect
github.com/goreleaser/fileglob v1.3.0 // indirect
github.com/gorilla/handlers v1.5.1 // indirect
- github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
+ github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
+ github.com/gostaticanalysis/comment v1.4.2 // indirect
+ github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect
+ github.com/gostaticanalysis/nilerr v0.1.1 // indirect
+ github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
+ github.com/hashicorp/errwrap v1.1.0 // indirect
+ github.com/hashicorp/go-multierror v1.1.1 // indirect
+ github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
+ github.com/hexops/gotextdiff v1.0.3 // indirect
github.com/huandu/xstrings v1.3.3 // indirect
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 // indirect
github.com/imdario/mergo v0.3.15 // indirect
@@ -122,25 +180,46 @@ require (
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84 // indirect
github.com/jessevdk/go-flags v1.5.0 // indirect
+ github.com/jgautheron/goconst v1.5.1 // indirect
+ github.com/jingyugao/rowserrcheck v1.1.1 // indirect
+ github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/jstemmer/go-junit-report v1.0.0 // indirect
+ github.com/julz/importas v0.1.0 // indirect
+ github.com/junk1tm/musttag v0.5.0 // indirect
github.com/kevinburke/ssh_config v1.1.0 // indirect
- github.com/klauspost/compress v1.16.3 // indirect
- github.com/klauspost/pgzip v1.2.5 // indirect
+ github.com/kisielk/errcheck v1.6.3 // indirect
+ github.com/kisielk/gotool v1.0.0 // indirect
+ github.com/kkHAIKE/contextcheck v1.1.4 // indirect
+ github.com/klauspost/compress v1.16.5 // indirect
+ github.com/klauspost/pgzip v1.2.6 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
+ github.com/kulti/thelper v0.6.3 // indirect
+ github.com/kunwardeep/paralleltest v1.0.6 // indirect
+ github.com/kyoh86/exportloopref v0.1.11 // indirect
+ github.com/ldez/gomoddirectives v0.2.3 // indirect
+ github.com/ldez/tagliatelle v0.4.0 // indirect
+ github.com/leonklingele/grouper v1.1.1 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
+ github.com/lufeee/execinquery v1.2.1 // indirect
github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
+ github.com/maratori/testableexamples v1.0.0 // indirect
+ github.com/maratori/testpackage v1.1.1 // indirect
+ github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
+ github.com/mbilski/exhaustivestruct v1.2.0 // indirect
+ github.com/mgechev/revive v1.3.1 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
- github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
+ github.com/moby/term v0.5.0 // indirect
+ github.com/moricho/tparallel v0.3.1 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/muesli/mango v0.1.0 // indirect
github.com/muesli/mango-cobra v1.2.0 // indirect
@@ -148,59 +227,103 @@ require (
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/roff v0.1.0 // indirect
github.com/muesli/termenv v0.15.1 // indirect
- github.com/nginxinc/nginx-go-crossplane v0.4.15 // indirect
+ github.com/nakabonne/nestif v0.3.1 // indirect
+ github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect
+ github.com/nginxinc/nginx-go-crossplane v0.4.17 // indirect
+ github.com/nishanths/exhaustive v0.9.5 // indirect
+ github.com/nishanths/predeclared v0.2.2 // indirect
+ github.com/nunnatsa/ginkgolinter v0.9.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
+ github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
- github.com/opencontainers/image-spec v1.1.0-rc2 // indirect
+ github.com/opencontainers/image-spec v1.1.0-rc3 // indirect
github.com/pascaldekloe/name v1.0.1 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/profile v1.7.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/polyfloyd/go-errorlint v1.4.0 // indirect
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/pseudomuto/protokit v0.2.0 // indirect
+ github.com/quasilyte/go-ruleguard v0.3.19 // indirect
+ github.com/quasilyte/gogrep v0.5.0 // indirect
+ github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
+ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
+ github.com/ryancurrah/gomodguard v1.3.0 // indirect
+ github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect
+ github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect
+ github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
+ github.com/sashamelentyev/usestdlibvars v1.23.0 // indirect
+ github.com/securego/gosec/v2 v2.15.0 // indirect
github.com/sergi/go-diff v1.2.0 // indirect
+ github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect
github.com/shopspring/decimal v1.2.0 // indirect
+ github.com/sivchari/containedctx v1.0.2 // indirect
+ github.com/sivchari/nosnakecase v1.7.0 // indirect
+ github.com/sivchari/tenv v1.7.1 // indirect
+ github.com/sonatard/noctx v0.0.2 // indirect
+ github.com/sourcegraph/go-diff v0.7.0 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
+ github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
+ github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
- github.com/tetratelabs/wazero v1.0.1 // indirect
- github.com/tklauser/go-sysconf v0.3.10 // indirect
- github.com/tklauser/numcpus v0.5.0 // indirect
+ github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect
+ github.com/tdakkota/asciicheck v0.2.0 // indirect
+ github.com/tetafro/godot v1.4.11 // indirect
+ github.com/tetratelabs/wazero v1.1.0 // indirect
+ github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e // indirect
+ github.com/timonwong/loggercheck v0.9.4 // indirect
+ github.com/tklauser/go-sysconf v0.3.11 // indirect
+ github.com/tklauser/numcpus v0.6.0 // indirect
+ github.com/tomarrell/wrapcheck/v2 v2.8.1 // indirect
+ github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
github.com/toqueteos/webbrowser v1.2.0 // indirect
github.com/trivago/tgo v1.0.7 // indirect
github.com/ulikunitz/xz v0.5.11 // indirect
+ github.com/ultraware/funlen v0.0.3 // indirect
+ github.com/ultraware/whitespace v0.0.5 // indirect
+ github.com/uudashr/gocognit v1.0.6 // indirect
github.com/xanzy/ssh-agent v0.3.1 // indirect
+ github.com/yagipy/maintidx v1.0.0 // indirect
+ github.com/yeya24/promlinter v0.2.0 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
+ gitlab.com/bosi/decorder v0.2.3 // indirect
gitlab.com/digitalxero/go-conventional-commit v1.0.7 // indirect
go.mongodb.org/mongo-driver v1.11.3 // indirect
- go.opentelemetry.io/otel v1.14.0 // indirect
- go.opentelemetry.io/otel/sdk v1.14.0 // indirect
- go.opentelemetry.io/otel/trace v1.14.0 // indirect
+ go.opentelemetry.io/otel v1.15.1 // indirect
+ go.opentelemetry.io/otel/sdk v1.15.1 // indirect
+ go.opentelemetry.io/otel/trace v1.15.1 // indirect
go.uber.org/goleak v1.1.12 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.24.0 // indirect
- golang.org/x/crypto v0.7.0 // indirect
+ golang.org/x/crypto v0.8.0 // indirect
+ golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 // indirect
+ golang.org/x/exp/typeparams v0.0.0-20230224173230-c95f2b4c22f2 // indirect
golang.org/x/mod v0.10.0 // indirect
- golang.org/x/net v0.9.0 // indirect
- golang.org/x/term v0.7.0 // indirect
- golang.org/x/text v0.9.0 // indirect
- golang.org/x/tools v0.8.0 // indirect
- google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2 // indirect
+ golang.org/x/net v0.10.0 // indirect
+ golang.org/x/term v0.8.0 // indirect
+ golang.org/x/tools v0.9.1 // indirect
+ google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
gopkg.in/alessio/shellescape.v1 v1.0.0-20170105083845-52074bc9df61 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gotest.tools/v3 v3.4.0 // indirect
+ honnef.co/go/tools v0.4.3 // indirect
+ mvdan.cc/gofumpt v0.4.0 // indirect
+ mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect
+ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect
+ mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d // indirect
)
replace github.com/nginx/agent/sdk/v2 => ./sdk
diff --git a/go.sum b/go.sum
index c2892468e..0b5b3b112 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,7 @@
+4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA=
+4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs=
+4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc=
+4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
@@ -36,13 +40,25 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+github.com/Abirdcfly/dupword v0.0.11 h1:z6v8rMETchZXUIuHxYNmlUAuKuB21PeaSymTed16wgU=
+github.com/Abirdcfly/dupword v0.0.11/go.mod h1:wH8mVGuf3CP5fsBTkfWwwwKTjDnVVCxtU8d8rgeVYXA=
github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w=
github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0=
+github.com/Antonboom/errname v0.1.9 h1:BZDX4r3l4TBZxZ2o2LNrlGxSHran4d1u4veZdoORTT4=
+github.com/Antonboom/errname v0.1.9/go.mod h1:nLTcJzevREuAsgTbG85UsuiWpMpAqbKD1HNZ29OzE58=
+github.com/Antonboom/nilnil v0.1.3 h1:6RTbx3d2mcEu3Zwq9TowQpQMVpP75zugwOtqY1RTtcE=
+github.com/Antonboom/nilnil v0.1.3/go.mod h1:iOov/7gRcXkeEU+EMGpBu2ORih3iyVEiWjeste1SJm8=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
+github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
+github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM=
+github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
+github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 h1:+r1rSv4gvYn0wmRjC8X7IAzX8QezqtFV9m0MUHFJgts=
+github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
@@ -56,8 +72,10 @@ github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuN
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/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
-github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
-github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
+github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
+github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
+github.com/OpenPeeDeeP/depguard v1.1.1 h1:TSUznLjvp/4IUP+OQ0t/4jF4QUyxIcVX8YnghZdunyA=
+github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc=
github.com/ProtonMail/go-crypto v0.0.0-20210512092938-c05353c2d58c h1:bNpaLLv2Y4kslsdkdCwAYu8Bak1aGVtxwi8Z/wy4Yuo=
github.com/ProtonMail/go-crypto v0.0.0-20210512092938-c05353c2d58c/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/ProtonMail/go-mime v0.0.0-20190923161245-9b5a4261663a h1:W6RrgN/sTxg1msqzFFb+G80MFmpjMw61IU+slm+wln4=
@@ -72,6 +90,10 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0=
+github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw=
+github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
+github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw=
+github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=
github.com/alvaroloes/enumer v1.1.2 h1:5khqHB33TZy1GWCO/lZwcroBFh7u+0j40T83VUbfAMY=
github.com/alvaroloes/enumer v1.1.2/go.mod h1:FxrjvuXoDAx9isTJrv4c+T410zFi0DtXIT0m65DJ+Wo=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
@@ -81,36 +103,58 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
+github.com/ashanbrown/forbidigo v1.5.1 h1:WXhzLjOlnuDYPYQo/eFlcFMi8X/kLfvWLYu6CSoebis=
+github.com/ashanbrown/forbidigo v1.5.1/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU=
+github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s=
+github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
-github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
+github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
+github.com/benbjohnson/clock v1.3.3 h1:g+rSsSaAzhHJYcIQE78hJ3AhyjjtQvleKDjlhdBnIhc=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A=
+github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI=
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
+github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M=
+github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k=
+github.com/bombsimon/wsl/v3 v3.4.0 h1:RkSxjT3tmlptwfgEgTgU+KYKLI35p/tviNXNXiL2aNU=
+github.com/bombsimon/wsl/v3 v3.4.0/go.mod h1:KkIB+TXkqy6MvK9BDZVbZxKNYsE1/oLRJbIFtf14qqo=
+github.com/breml/bidichk v0.2.4 h1:i3yedFWWQ7YzjdZJHnPo9d/xURinSq3OM+gyM43K4/8=
+github.com/breml/bidichk v0.2.4/go.mod h1:7Zk0kRFt1LIZxtQdl9W9JwGAcLTTkOs+tN7wuEYGJ3s=
+github.com/breml/errchkjson v0.3.1 h1:hlIeXuspTyt8Y/UmP5qy1JocGNR00KQHgfaNtRAjoxQ=
+github.com/breml/errchkjson v0.3.1/go.mod h1:XroxrzKjdiutFyW3nWhw34VGg7kiMsDQox73yWCGI2U=
github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A=
github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE=
-github.com/bufbuild/buf v1.17.0 h1:HqfVS5v81r1Q+vWm91V1uqdB77vO48uSjU1LAYC2DyE=
-github.com/bufbuild/buf v1.17.0/go.mod h1:V//7h3wKBA+VVE2cv8CUox57dt9Y6JQ6tCM6cF2ptF8=
-github.com/bufbuild/connect-go v1.6.0 h1:OCEB8JuEuvcY5lEKZCQE95CUscqkDtLnQceNhDgi92k=
-github.com/bufbuild/connect-go v1.6.0/go.mod h1:GmMJYR6orFqD0Y6ZgX8pwQ8j9baizDrIQMm1/a6LnHk=
+github.com/bufbuild/buf v1.18.0 h1:21VUsBACeRLwJ+7XfzCc8z173M4iH8shcKDO7ASwp7A=
+github.com/bufbuild/buf v1.18.0/go.mod h1:Wp6mb9HCLDPI1woVCZux154AA0y8aLiPM+fr7Qufmto=
+github.com/bufbuild/connect-go v1.7.0 h1:MGp82v7SCza+3RhsVhV7aMikwxvI3ZfD72YiGt8FYJo=
+github.com/bufbuild/connect-go v1.7.0/go.mod h1:GmMJYR6orFqD0Y6ZgX8pwQ8j9baizDrIQMm1/a6LnHk=
github.com/bufbuild/protocompile v0.5.1 h1:mixz5lJX4Hiz4FpqFREJHIXLfaLBntfaJv1h+/jS+Qg=
github.com/bufbuild/protocompile v0.5.1/go.mod h1:G5iLmavmF4NsYtpZFvE3B/zFch2GIY8+wjsYLR/lc40=
+github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY=
+github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc=
github.com/caarlos0/go-rpmutils v0.2.1-0.20211112020245-2cd62ff89b11 h1:IRrDwVlWQr6kS1U8/EtyA1+EHcc4yl8pndcqXWrEamg=
github.com/caarlos0/testfs v0.4.4 h1:3PHvzHi5Lt+g332CiShwS8ogTgS3HjrmzZxCm6JCDr8=
github.com/caarlos0/testfs v0.4.4/go.mod h1:bRN55zgG4XCUVVHZCeU+/Tz1Q6AxEJOEJTliBy+1DMk=
github.com/cavaliergopher/cpio v1.0.1 h1:KQFSeKmZhv0cr+kawA3a0xTQCU4QxXF1vhU7P7av2KM=
github.com/cavaliergopher/cpio v1.0.1/go.mod h1:pBdaqQjnvXxdS/6CvNDwIANIFSP0xRKI16PX4xejRQc=
-github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
-github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
+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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
+github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4=
+github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ=
github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E=
github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c=
+github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 h1:W9o46d2kbNL06lq7UNDPV0zYLzkrde/bjIqO02eoll0=
+github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8/go.mod h1:gakxgyXaaPkxvLw1XQxNGK4I37ys9iBRzNUx/B7pUCo=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -124,15 +168,21 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
+github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo=
+github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc=
+github.com/daixiang0/gci v0.10.1 h1:eheNA3ljF6SxnPD/vE4lCBusVHmV3Rs3dkKvFrJ7MR0=
+github.com/daixiang0/gci v0.10.1/go.mod h1:xtHP9N7AHdNvtRNfcx9gwTDfw7FRJx4bZUsiEfiNNAI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/docker/cli v23.0.2+incompatible h1:Yj4wkrNtyCNLCMobKDYzEUIsbtMbfAulkHMH75/ecik=
-github.com/docker/cli v23.0.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU=
+github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c=
+github.com/docker/cli v23.0.5+incompatible h1:ufWmAOuD3Vmr7JP2G5K3cyuNC4YZWiAsuDEvFVVDafE=
+github.com/docker/cli v23.0.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v23.0.2+incompatible h1:q81C2qQ/EhPm8COZMUGOQYh4qLv4Xu6CXELJ3WK/mlU=
-github.com/docker/docker v23.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v23.0.5+incompatible h1:DaxtlTJjFSnLOXVNUBU1+6kXGz2lpDoEAH6QoxaSg8k=
+github.com/docker/docker v23.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
@@ -147,26 +197,38 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/envoyproxy/protoc-gen-validate v0.3.0-java h1:bV5JGEB1ouEzZa0hgVDFFiClrUEuGWRaAc/3mxR2QK0=
-github.com/envoyproxy/protoc-gen-validate v0.3.0-java/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/evilmartians/lefthook v1.3.10 h1:tGnI6JAW74/ZLXIESrdLjWQpPJEfjRmfzY90W3r+rHU=
-github.com/evilmartians/lefthook v1.3.10/go.mod h1:Ybinyhjf5wdloc78pkBV2K0XZRvdnsIova48LAco5HU=
-github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
-github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
+github.com/envoyproxy/protoc-gen-validate v0.10.0 h1:oIfnZFdC0YhpNNEX+SuIqko4cqqVZeN9IGTrhZje83Y=
+github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
+github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA=
+github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0=
+github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw=
+github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY=
+github.com/evilmartians/lefthook v1.3.13 h1:WowytlQPtGLj0ffGJZY2MaLWSfQuqgmVKOjzTzvY46c=
+github.com/evilmartians/lefthook v1.3.13/go.mod h1:Ybinyhjf5wdloc78pkBV2K0XZRvdnsIova48LAco5HU=
+github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
+github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
+github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
+github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y=
+github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
+github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
+github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0=
github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
+github.com/go-critic/go-critic v0.7.0 h1:tqbKzB8pqi0NsRZ+1pyU4aweAF7A7QN0Pi4Q02+rYnQ=
+github.com/go-critic/go-critic v0.7.0/go.mod h1:moYzd7GdVXE2C2hYTwd7h0CPcqlUeclsyBRwMa38v64=
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
@@ -236,6 +298,25 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
github.com/go-swagger/go-swagger v0.30.4 h1:cPrWLSXY6ZdcgfRicOj0lANg72TkTHz6uv/OlUdzO5U=
github.com/go-swagger/go-swagger v0.30.4/go.mod h1:YM5D5kR9c1ft3ynMXvDk2uo/7UZHKFEqKXcAL9f4Phc=
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=
+github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8=
+github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU=
+github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s=
+github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw=
+github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4=
+github.com/go-toolsmith/astequal v1.1.0 h1:kHKm1AWqClYn15R0K1KKE4RG614D46n+nqUQ06E1dTw=
+github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ=
+github.com/go-toolsmith/astfmt v1.1.0 h1:iJVPDPp6/7AaeLJEruMsBUlOYCmvg0MoCfJprsOmcco=
+github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4=
+github.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA=
+github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA=
+github.com/go-toolsmith/pkgload v1.2.2 h1:0CtmHq/02QhxcF7E9N5LIFcYFsMR5rdovfqTtRKkgIk=
+github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
+github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQiyP2Bvw=
+github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ=
+github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus=
+github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig=
+github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U=
+github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
@@ -302,6 +383,26 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0=
+github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4=
+github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM=
+github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
+github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6J5HIP8ZtyMdiDscjMLfRBSPuzVVeo=
+github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ=
+github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY=
+github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs=
+github.com/golangci/golangci-lint v1.52.2 h1:FrPElUUI5rrHXg1mQ7KxI1MXPAw5lBVskiz7U7a8a1A=
+github.com/golangci/golangci-lint v1.52.2/go.mod h1:S5fhC5sHM5kE22/HcATKd1XLWQxX+y7mHj8B5H91Q/0=
+github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA=
+github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg=
+github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA=
+github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o=
+github.com/golangci/misspell v0.4.0 h1:KtVB/hTK4bbL/S6bs64rYyk8adjmh1BygbBiaAiX+a0=
+github.com/golangci/misspell v0.4.0/go.mod h1:W6O/bwV6lGDxUCChm2ykw9NQdd5bYd1Xkjo88UcWyJc=
+github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 h1:DIPQnGy2Gv2FSA4B/hh8Q7xx3B7AIDk3DAMeHclH1vQ=
+github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs=
+github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys=
+github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -335,8 +436,8 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
-github.com/google/pprof v0.0.0-20230323073829-e72429f035bd h1:r8yyd+DJDmsUhGrRBxH5Pj7KeFK5l+Y3FsgT8keqKtk=
-github.com/google/pprof v0.0.0-20230323073829-e72429f035bd/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk=
+github.com/google/pprof v0.0.0-20230502171905-255e3b9b56de h1:6bMcLOeKoNo0+mTOb1ee3McF6CCKGixjLR3EDQY1Jik=
+github.com/google/pprof v0.0.0-20230502171905-255e3b9b56de/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -346,6 +447,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
+github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 h1:9alfqbrhuD+9fLZ4iaAVwhlp5PEhmnBt7yvK2Oy5C1U=
+github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0=
github.com/goreleaser/chglog v0.4.2 h1:afmbT1d7lX/q+GF8wv3a1Dofs2j/Y9YkiCpGemWR6mI=
github.com/goreleaser/chglog v0.4.2/go.mod h1:u/F03un4hMCQrp65qSWCkkC6T+G7YLKZ+AM2mITE47s=
github.com/goreleaser/fileglob v1.3.0 h1:/X6J7U8lbDpQtBvGcwwPS6OpzkNVlVEsFUVRx9+k+7I=
@@ -354,12 +457,33 @@ github.com/goreleaser/nfpm/v2 v2.28.0 h1:BLKOrJpyBrO/LQ7XQP/mICDBqq6K3iX1cqZIMYK
github.com/goreleaser/nfpm/v2 v2.28.0/go.mod h1:cMwzgk+6Irs3+ZKD6Lz/ADJ8qsVmJxYPlE3/wOxAfVA=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
-github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
-github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
+github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk=
+github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc=
+github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado=
+github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q=
+github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM=
+github.com/gostaticanalysis/forcetypeassert v0.1.0 h1:6eUflI3DiGusXGK6X7cCcIgVCpZ2CiZ1Q7jl6ZxNV70=
+github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak=
+github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk=
+github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A=
+github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M=
+github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY=
+github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
+github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
+github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
+github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
+github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
+github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/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 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 h1:i462o439ZjprVSFSZLZxcsoAe592sZB1rci2Z8j4wdk=
@@ -383,7 +507,13 @@ github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84/go.mod h1:Zi/ZFkEqFH
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
+github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM=
+github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
+github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs=
+github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c=
+github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48=
+github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
@@ -399,6 +529,10 @@ github.com/jstemmer/go-junit-report v1.0.0/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
+github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY=
+github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0=
+github.com/junk1tm/musttag v0.5.0 h1:bV1DTdi38Hi4pG4OVWa7Kap0hi0o7EczuK6wQt9zPOM=
+github.com/junk1tm/musttag v0.5.0/go.mod h1:PcR7BA+oREQYvHwgjIDmw3exJeds5JzRcvEJTfjrA0M=
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
@@ -406,14 +540,19 @@ github.com/kevinburke/ssh_config v1.1.0 h1:pH/t1WS9NzT8go394IqZeJTMHVm6Cr6ZJ6AQ+
github.com/kevinburke/ssh_config v1.1.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/errcheck v1.6.3 h1:dEKh+GLHcWm2oN34nMvDzn1sqI0i0WxPvrgiJA5JuM8=
+github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw=
+github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8=
+github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY=
-github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
+github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0=
github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
-github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
-github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
+github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
+github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -426,8 +565,22 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs=
+github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I=
+github.com/kunwardeep/paralleltest v1.0.6 h1:FCKYMF1OF2+RveWlABsdnmsvJrei5aoyZoaGS+Ugg8g=
+github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes=
+github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ=
+github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA=
+github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA=
+github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0=
+github.com/ldez/tagliatelle v0.4.0 h1:sylp7d9kh6AdXN2DpVGHBRb5guTVAgOxqNGhbqc4b1c=
+github.com/ldez/tagliatelle v0.4.0/go.mod h1:mNtTfrHy2haaBAw+VT7IBV6VXBThS7TCreYWbBcJ87I=
+github.com/leonklingele/grouper v1.1.1 h1:suWXRU57D4/Enn6pXR0QVqqWWrnJ9Osrz+5rjt8ivzU=
+github.com/leonklingele/grouper v1.1.1/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
+github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM=
+github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281 h1:aczX6NMOtt6L4YT0fQvKkDK6LZEtdOso9sUH89V1+P0=
github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281/go.mod h1:lc+czkgO/8F7puNki5jk8QyujbfK1LOT7Wl0ON2hxyk=
@@ -438,8 +591,14 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI=
+github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE=
+github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04=
+github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc=
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
+github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 h1:gWg6ZQ4JhDfJPqlo2srm/LN17lpybq15AryXIRcWYLE=
+github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
@@ -447,6 +606,7 @@ 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.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
@@ -455,6 +615,10 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/maxbrunsfeld/counterfeiter/v6 v6.6.1 h1:9XE5ykDiC8eNSqIPkxx0EsV3kMX1oe4kQWRZjIgytUA=
github.com/maxbrunsfeld/counterfeiter/v6 v6.6.1/go.mod h1:qbKwBR+qQODzH2WD/s53mdgp/xVcXMlJb59GRFOp6Z4=
+github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo=
+github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc=
+github.com/mgechev/revive v1.3.1 h1:OlQkcH40IB2cGuprTPcjB0iIUddgVZgGmDX3IAMR8D4=
+github.com/mgechev/revive v1.3.1/go.mod h1:YlD6TTWl2B8A103R9KWJSPVI9DrEf+oqr15q21Ld+5I=
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=
@@ -467,14 +631,16 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
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/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA=
-github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
+github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
+github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
+github.com/moricho/tparallel v0.3.1 h1:fQKD4U1wRMAYNngDonW5XupoB/ZGJHdpzrWqgyg9krA=
+github.com/moricho/tparallel v0.3.1/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/muesli/mango v0.1.0 h1:DZQK45d2gGbql1arsYA4vfg4d7I9Hfx5rX/GCmzsAvI=
@@ -493,25 +659,44 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-proto-validators v0.3.2 h1:qRlmpTzm2pstMKKzTdvwPCF5QfBNURSlAgN/R+qbKos=
github.com/mwitkow/go-proto-validators v0.3.2/go.mod h1:ej0Qp0qMgHN/KtDyUt+Q1/tA7a5VarXUOUxD+oeD30w=
-github.com/nginxinc/nginx-go-crossplane v0.4.15 h1:O+FIyX7L0TnR28G732dLRpeRtOZBEDc2i2veXE4nGD0=
-github.com/nginxinc/nginx-go-crossplane v0.4.15/go.mod h1:UzbZnyFv0vPlt1Urbnp/mrFCzBL4tYCReFuNBpFQEfI=
+github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U=
+github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE=
+github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA=
+github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=
+github.com/nginxinc/nginx-go-crossplane v0.4.17 h1:kBISwQT36Uv4h57ran0bT4MIWUqaoJrMwoTMpryBZcg=
+github.com/nginxinc/nginx-go-crossplane v0.4.17/go.mod h1:UzbZnyFv0vPlt1Urbnp/mrFCzBL4tYCReFuNBpFQEfI=
github.com/nginxinc/nginx-plus-go-client v0.10.0 h1:3zsMMkPvRDo8D7ZSprXtbAEW/SDmezZWzxdyS+6oAlc=
github.com/nginxinc/nginx-plus-go-client v0.10.0/go.mod h1:0v3RsQCvRn/IyrMtW+DK6CNkz+PxEsXDJPjQ3yUMBF0=
github.com/nginxinc/nginx-prometheus-exporter v0.10.0 h1:wFP8mYMtmn8uK1I5tzXb3s4CQq+r3h6Y0Qdc7d+QpyM=
github.com/nginxinc/nginx-prometheus-exporter v0.10.0/go.mod h1:U3BudpuBp/uO++yvnaaI4Dz7oOFJPdM726WEv70k3O4=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
+github.com/nishanths/exhaustive v0.9.5 h1:TzssWan6orBiLYVqewCG8faud9qlFntJE30ACpzmGME=
+github.com/nishanths/exhaustive v0.9.5/go.mod h1:IbwrGdVMizvDcIxPYGVdQn5BqWJaOwpCvg4RGb8r/TA=
+github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=
+github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
+github.com/nunnatsa/ginkgolinter v0.9.0 h1:Sm0zX5QfjJzkeCjEp+t6d3Ha0jwvoDjleP9XCsrEzOA=
+github.com/nunnatsa/ginkgolinter v0.9.0/go.mod h1:FHaMLURXP7qImeH6bvxWJUpyH+2tuqe5j4rW1gxJRmI=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
+github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
+github.com/onsi/ginkgo/v2 v2.8.0 h1:pAM+oBNPrpXRs+E/8spkeGx9QgekbRVyr74EUvRVOUI=
github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
-github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034=
-github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
+github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8=
+github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY=
github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
+github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k=
+github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=
+github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
+github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
+github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
+github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
github.com/pascaldekloe/name v0.0.0-20180628100202-0fd16699aae1/go.mod h1:eD5JxqMiuNYyFNmyY9rkJ/slN8y59oEu4Ei7F8OoKWQ=
github.com/pascaldekloe/name v1.0.1 h1:9lnXOHeqeHHnWLbKfH6X98+4+ETVqFqxN09UXSjcMb0=
github.com/pascaldekloe/name v1.0.1/go.mod h1:Z//MfYJnH4jVpQ9wkclwu2I2MkHmXTlT9wR5UZScttM=
@@ -530,6 +715,8 @@ github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDj
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/polyfloyd/go-errorlint v1.4.0 h1:b+sQ5HibPIAjEZwtuwU8Wz/u0dMZ7YL+bk+9yWyHVJk=
+github.com/polyfloyd/go-errorlint v1.4.0/go.mod h1:qJCkPeBn+0EXkdKTrUCcuFStM2xrDKfxI3MGLXPexUs=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c h1:NRoLoZvkBTKvR5gQLgA3e0hqjkY9u1wm+iOL45VN/qI=
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
@@ -562,6 +749,14 @@ github.com/pseudomuto/protoc-gen-doc v1.5.1 h1:Ah259kcrio7Ix1Rhb6u8FCaOkzf9qRBqX
github.com/pseudomuto/protoc-gen-doc v1.5.1/go.mod h1:XpMKYg6zkcpgfpCfQ8GcWBDRtRxOmMR5w7pz4Xo+dYM=
github.com/pseudomuto/protokit v0.2.0 h1:hlnBDcy3YEDXH7kc9gV+NLaN0cDzhDvD1s7Y6FZ8RpM=
github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q=
+github.com/quasilyte/go-ruleguard v0.3.19 h1:tfMnabXle/HzOb5Xe9CUZYWXKfkS1KwRmZyPmD9nVcc=
+github.com/quasilyte/go-ruleguard v0.3.19/go.mod h1:lHSn69Scl48I7Gt9cX3VrbsZYvYiBYszZOZW4A+oTEw=
+github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo=
+github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng=
+github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl980XxGFEZSS6KlBGIV0diGdySzxATTWoqaU=
+github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=
+github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs=
+github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
@@ -570,20 +765,36 @@ github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
-github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo=
-github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
+github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE=
+github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
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/ryancurrah/gomodguard v1.3.0 h1:q15RT/pd6UggBXVBuLps8BXRvl5GPBcwVA7BJHMLuTw=
+github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50=
+github.com/ryanrolds/sqlclosecheck v0.4.0 h1:i8SX60Rppc1wRuyQjMciLqIzV3xnoHB7/tXbr6RGYNI=
+github.com/ryanrolds/sqlclosecheck v0.4.0/go.mod h1:TBRRjzL31JONc9i4XMinicuo+s+E8yKZ5FN8X3G6CKQ=
+github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc=
+github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI=
+github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw=
+github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ=
+github.com/sashamelentyev/usestdlibvars v1.23.0 h1:01h+/2Kd+NblNItNeux0veSL5cBF1jbEOPrEhDzGYq0=
+github.com/sashamelentyev/usestdlibvars v1.23.0/go.mod h1:YPwr/Y1LATzHI93CqoPUN/2BzGQ/6N/cl/KwgR0B/aU=
github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8=
+github.com/securego/gosec/v2 v2.15.0 h1:v4Ym7FF58/jlykYmmhZ7mTm7FQvN/setNm++0fgIAtw=
+github.com/securego/gosec/v2 v2.15.0/go.mod h1:VOjTrZOkUtSDt2QLSJmQBMWnvwiQPEjg0l+5juIqGk8=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU=
+github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
-github.com/shirou/gopsutil/v3 v3.22.7 h1:flKnuCMfUUrO+oAvwAd6GKZgnPzr098VA/UJ14nhJd4=
-github.com/shirou/gopsutil/v3 v3.22.7/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI=
+github.com/shirou/gopsutil/v3 v3.23.2 h1:PAWSuiAszn7IhPMBtXsbSCafej7PqUOvY6YywlQUExU=
+github.com/shirou/gopsutil/v3 v3.23.2/go.mod h1:gv0aQw33GLo3pG8SiWKiQrbDzbRY1K80RyZJ7V4Th1M=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+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/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
@@ -592,8 +803,18 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYIc1yrHI=
+github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw=
+github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt95do8=
+github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY=
+github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak=
+github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg=
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
+github.com/sonatard/noctx v0.0.2 h1:L7Dz4De2zDQhW8S0t+KUjY0MAQJd6SgVwhzNIc4ok00=
+github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo=
+github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0=
+github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
@@ -609,11 +830,16 @@ 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.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU=
github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA=
+github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0=
+github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
+github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc=
+github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I=
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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
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.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -628,15 +854,32 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
-github.com/tetratelabs/wazero v1.0.1 h1:xyWBoGyMjYekG3mEQ/W7xm9E05S89kJ/at696d/9yuc=
-github.com/tetratelabs/wazero v1.0.1/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ=
+github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8=
+github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk=
+github.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM=
+github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg=
+github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA=
+github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0=
+github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag=
+github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY=
+github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw=
+github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8=
+github.com/tetratelabs/wazero v1.1.0 h1:EByoAhC+QcYpwSZJSs/aV0uokxPwBgKxfiokSUwAknQ=
+github.com/tetratelabs/wazero v1.1.0/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
-github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
-github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
-github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
-github.com/tklauser/numcpus v0.5.0 h1:ooe7gN0fg6myJ0EKoTAf5hebTZrH52px3New/D9iJ+A=
-github.com/tklauser/numcpus v0.5.0/go.mod h1:OGzpTxpcIMNGYQdit2BYL1pvk/dSOaJWjKoflh+RQjo=
+github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e h1:MV6KaVu/hzByHP0UvJ4HcMGE/8a6A4Rggc/0wx2AvJo=
+github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ=
+github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4=
+github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg=
+github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
+github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
+github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
+github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
+github.com/tomarrell/wrapcheck/v2 v2.8.1 h1:HxSqDSN0sAt0yJYsrcYVoEeyM4aI9yAm3KQpIXDJRhQ=
+github.com/tomarrell/wrapcheck/v2 v2.8.1/go.mod h1:/n2Q3NZ4XFT50ho6Hbxg+RV1uyo2Uow/Vdm9NQcl5SE=
+github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw=
+github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
github.com/trivago/grok v1.0.0 h1:oV2ljyZT63tgXkmgEHg2U0jMqiKKuL0hkn49s6aRavQ=
@@ -645,6 +888,12 @@ github.com/trivago/tgo v1.0.7 h1:uaWH/XIy9aWYWpjm2CU3RpcqZXmX2ysQ9/Go+d9gyrM=
github.com/trivago/tgo v1.0.7/go.mod h1:w4dpD+3tzNIIiIfkWWa85w5/B77tlvdZckQ+6PkFnhc=
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
+github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA=
+github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
+github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI=
+github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
+github.com/uudashr/gocognit v1.0.6 h1:2Cgi6MweCsdB6kpcVQp7EW4U23iBFQWfTXiWlyp842Y=
+github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY=
github.com/vardius/message-bus v1.1.5 h1:YSAC2WB4HRlwc4neFPTmT88kzzoiQ+9WRRbej/E/LZc=
github.com/vardius/message-bus v1.1.5/go.mod h1:6xladCV2lMkUAE4bzzS85qKOiB5miV7aBVRafiTJGqw=
github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME=
@@ -657,15 +906,22 @@ github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23n
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
+github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM=
+github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk=
+github.com/yeya24/promlinter v0.2.0 h1:xFKDQ82orCU5jQujdaD8stOHiv8UN68BSdn2a8u8Y3o=
+github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+gitlab.com/bosi/decorder v0.2.3 h1:gX4/RgK16ijY8V+BRQHAySfQAb354T7/xQpDB2n10P0=
+gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE=
gitlab.com/digitalxero/go-conventional-commit v1.0.7 h1:8/dO6WWG+98PMhlZowt/YjuiKhqhGlOCwlIV8SqqGh8=
gitlab.com/digitalxero/go-conventional-commit v1.0.7/go.mod h1:05Xc2BFsSyC5tKhK0y+P3bs0AwUtNuTp+mTpbCU/DZ0=
go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg=
@@ -679,21 +935,22 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
-go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
-go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
-go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY=
-go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM=
-go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
-go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
-go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
-go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
+go.opentelemetry.io/otel v1.15.1 h1:3Iwq3lfRByPaws0f6bU3naAqOR1n5IeDWd9390kWHa8=
+go.opentelemetry.io/otel v1.15.1/go.mod h1:mHHGEHVDLal6YrKMmk9LqC4a3sF5g+fHfrttQIB1NTc=
+go.opentelemetry.io/otel/sdk v1.15.1 h1:5FKR+skgpzvhPQHIEfcwMYjCBr14LWzs3uSqKiQzETI=
+go.opentelemetry.io/otel/sdk v1.15.1/go.mod h1:8rVtxQfrbmbHKfqzpQkT5EzZMcbMBwTzNAggbEAM0KA=
+go.opentelemetry.io/otel/trace v1.15.1 h1:uXLo6iHJEzDfrNC0L0mNjItIp06SyaBQxu5t3xMlngY=
+go.opentelemetry.io/otel/trace v1.15.1/go.mod h1:IWdQG/5N1x7f6YUlmdLeJvH9yxtuJAfc4VW5Agv9r/8=
+go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
+go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
+go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
-go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
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.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -711,9 +968,10 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
-golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
-golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
+golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
+golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -724,6 +982,12 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
+golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o=
+golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
+golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
+golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
+golang.org/x/exp/typeparams v0.0.0-20230224173230-c95f2b4c22f2 h1:J74nGeMgeFnYQJN59eFwh06jX/V8g0lB7LWpjSLxtgU=
+golang.org/x/exp/typeparams v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -748,7 +1012,12 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
+golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
+golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -787,14 +1056,19 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
-golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
+golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
+golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -819,8 +1093,9 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
+golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -880,25 +1155,35 @@ golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/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.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.4.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.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
-golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
-golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
+golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
+golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -909,12 +1194,16 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.6.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 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
+golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -922,6 +1211,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -934,8 +1224,10 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -953,16 +1245,22 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
@@ -970,11 +1268,21 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
+golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
+golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
+golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
-golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
+golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
+golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
+golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
+golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
+golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1042,8 +1350,8 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2 h1:O97sLx/Xmb/KIZHB/2/BzofxBs5QmmR0LcihPtllmbc=
-google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
+google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
+google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -1060,8 +1368,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk=
-google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
+google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
+google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@@ -1119,6 +1427,16 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.4.3 h1:o/n5/K5gXqk8Gozvs2cnL0F2S1/g1vcGCAx2vETjITw=
+honnef.co/go/tools v0.4.3/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA=
+mvdan.cc/gofumpt v0.4.0 h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM=
+mvdan.cc/gofumpt v0.4.0/go.mod h1:PljLOHDeZqgS8opHRKLzp2It2VBuSdteAgqUfzMTxlQ=
+mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I=
+mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
+mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo=
+mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
+mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d h1:3rvTIIM22r9pvXk+q3swxUQAQOxksVMGK7sml4nG57w=
+mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d/go.mod h1:IeHQjmn6TOD+e4Z3RFiZMMsLVL+A96Nvptar8Fj71is=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
diff --git a/go.work.sum b/go.work.sum
index b3bc8c8f0..5a7fbfb66 100644
--- a/go.work.sum
+++ b/go.work.sum
@@ -14,52 +14,103 @@ cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+
cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=
cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM=
cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I=
+cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=
cloud.google.com/go/accessapproval v1.5.0 h1:/nTivgnV/n1CaAeo+ekGexTYUsKEU9jUVkoY5359+3Q=
cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw=
+cloud.google.com/go/accessapproval v1.6.0 h1:x0cEHro/JFPd7eS4BlEWNTMecIj2HdXjOVB5BtvwER0=
+cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E=
cloud.google.com/go/accesscontextmanager v1.4.0 h1:CFhNhU7pcD11cuDkQdrE6PQJgv0EXNKNv06jIzbLlCU=
cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE=
+cloud.google.com/go/accesscontextmanager v1.7.0 h1:MG60JgnEoawHJrbWw0jGdv6HLNSf6gQvYRiXpuzqgEA=
+cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ=
cloud.google.com/go/aiplatform v1.27.0 h1:DBi3Jk9XjCJ4pkkLM4NqKgj3ozUL1wq4l+d3/jTGXAI=
cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg=
+cloud.google.com/go/aiplatform v1.37.0 h1:zTw+suCVchgZyO+k847wjzdVjWmrAuehxdvcZvJwfGg=
+cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw=
cloud.google.com/go/analytics v0.12.0 h1:NKw6PpQi6V1O+KsjuTd+bhip9d0REYu4NevC45vtGp8=
cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4=
+cloud.google.com/go/analytics v0.19.0 h1:LqAo3tAh2FU9+w/r7vc3hBjU23Kv7GhO/PDIW7kIYgM=
+cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE=
cloud.google.com/go/apigateway v1.4.0 h1:IIoXKR7FKrEAQhMTz5hK2wiDz2WNFHS7eVr/L1lE/rM=
cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc=
+cloud.google.com/go/apigateway v1.5.0 h1:ZI9mVO7x3E9RK/BURm2p1aw9YTBSCQe3klmyP1WxWEg=
+cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8=
cloud.google.com/go/apigeeconnect v1.4.0 h1:AONoTYJviyv1vS4IkvWzq69gEVdvHx35wKXc+e6wjZQ=
cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04=
+cloud.google.com/go/apigeeconnect v1.5.0 h1:sWOmgDyAsi1AZ48XRHcATC0tsi9SkPT7DA/+VCfkaeA=
+cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8=
+cloud.google.com/go/apigeeregistry v0.6.0 h1:E43RdhhCxdlV+I161gUY2rI4eOaMzHTA5kNkvRsFXvc=
+cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc=
+cloud.google.com/go/apikeys v0.6.0 h1:B9CdHFZTFjVti89tmyXXrO+7vSNo2jvZuHG8zD5trdQ=
+cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8=
cloud.google.com/go/appengine v1.5.0 h1:lmG+O5oaR9xNwaRBwE2XoMhwQHsHql5IoiGr1ptdDwU=
cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak=
+cloud.google.com/go/appengine v1.7.1 h1:aBGDKmRIaRRoWJ2tAoN0oVSHoWLhtO9aj/NvUyP4aYs=
+cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E=
cloud.google.com/go/area120 v0.6.0 h1:TCMhwWEWhCn8d44/Zs7UCICTWje9j3HuV6nVGMjdpYw=
cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0=
+cloud.google.com/go/area120 v0.7.1 h1:ugckkFh4XkHJMPhTIx0CyvdoBxmOpMe8rNs4Ok8GAag=
+cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k=
cloud.google.com/go/artifactregistry v1.9.0 h1:3d0LRAU1K6vfqCahhl9fx2oGHcq+s5gftdix4v8Ibrc=
cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc=
+cloud.google.com/go/artifactregistry v1.13.0 h1:o1Q80vqEB6Qp8WLEH3b8FBLNUCrGQ4k5RFj0sn/sgO8=
+cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08=
cloud.google.com/go/asset v1.10.0 h1:aCrlaLGJWTODJX4G56ZYzJefITKEWNfbjjtHSzWpxW0=
cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY=
+cloud.google.com/go/asset v1.13.0 h1:YAsssO08BqZ6mncbb6FPlj9h6ACS7bJQUOlzciSfbNk=
+cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw=
cloud.google.com/go/assuredworkloads v1.9.0 h1:hhIdCOowsT1GG5eMCIA0OwK6USRuYTou/1ZeNxCSRtA=
cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0=
+cloud.google.com/go/assuredworkloads v1.10.0 h1:VLGnVFta+N4WM+ASHbhc14ZOItOabDLH1MSoDv+Xuag=
+cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E=
cloud.google.com/go/automl v1.8.0 h1:BMioyXSbg7d7xLibn47cs0elW6RT780IUWr42W8rp2Q=
cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM=
+cloud.google.com/go/automl v1.12.0 h1:50VugllC+U4IGl3tDNcZaWvApHBTrn/TvyHDJ0wM+Uw=
+cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU=
cloud.google.com/go/baremetalsolution v0.4.0 h1:g9KO6SkakcYPcc/XjAzeuUrEOXlYPnMpuiaywYaGrmQ=
cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI=
+cloud.google.com/go/baremetalsolution v0.5.0 h1:2AipdYXL0VxMboelTTw8c1UJ7gYu35LZYUbuRv9Q28s=
+cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss=
cloud.google.com/go/batch v0.4.0 h1:1jvEBY55OH4Sd2FxEXQfxGExFWov1A/IaRe+Z5Z71Fw=
cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE=
+cloud.google.com/go/batch v0.7.0 h1:YbMt0E6BtqeD5FvSv1d56jbVsWEzlGm55lYte+M6Mzs=
+cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g=
cloud.google.com/go/beyondcorp v0.3.0 h1:w+4kThysgl0JiKshi2MKDCg2NZgOyqOI0wq2eBZyrzA=
cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8=
+cloud.google.com/go/beyondcorp v0.5.0 h1:UkY2BTZkEUAVrgqnSdOJ4p3y9ZRBPEe1LkjgC8Bj/Pc=
+cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU=
cloud.google.com/go/bigquery v1.44.0 h1:Wi4dITi+cf9VYp4VH2T9O41w0kCW0uQTELq2Z6tukN0=
cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc=
+cloud.google.com/go/bigquery v1.50.0 h1:RscMV6LbnAmhAzD893Lv9nXXy2WCaJmbxYPWDLbGqNQ=
+cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU=
cloud.google.com/go/billing v1.7.0 h1:Xkii76HWELHwBtkQVZvqmSo9GTr0O+tIbRNnMcGdlg4=
cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y=
+cloud.google.com/go/billing v1.13.0 h1:JYj28UYF5w6VBAh0gQYlgHJ/OD1oA+JgW29YZQU+UHM=
+cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc=
cloud.google.com/go/binaryauthorization v1.4.0 h1:pL70vXWn9TitQYXBWTK2abHl2JHLwkFRjYw6VflRqEA=
cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk=
+cloud.google.com/go/binaryauthorization v1.5.0 h1:d3pMDBCCNivxt5a4eaV7FwL7cSH0H7RrEnFrTb1QKWs=
+cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q=
cloud.google.com/go/certificatemanager v1.4.0 h1:tzbR4UHBbgsewMWUD93JHi8EBi/gHBoSAcY1/sThFGk=
cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590=
+cloud.google.com/go/certificatemanager v1.6.0 h1:5C5UWeSt8Jkgp7OWn2rCkLmYurar/vIWIoSQ2+LaTOc=
+cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8=
cloud.google.com/go/channel v1.9.0 h1:pNuUlZx0Jb0Ts9P312bmNMuH5IiFWIR4RUtLb70Ke5s=
cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk=
+cloud.google.com/go/channel v1.12.0 h1:GpcQY5UJKeOekYgsX3QXbzzAc/kRGtBq43fTmyKe6Uw=
+cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU=
cloud.google.com/go/cloudbuild v1.4.0 h1:TAAmCmAlOJ4uNBu6zwAjwhyl/7fLHHxIEazVhr3QBbQ=
cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA=
+cloud.google.com/go/cloudbuild v1.9.0 h1:GHQCjV4WlPPVU/j3Rlpc8vNIDwThhd1U9qSY/NPZdko=
+cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s=
cloud.google.com/go/clouddms v1.4.0 h1:UhzHIlgFfMr6luVYVNydw/pl9/U5kgtjCMJHnSvoVws=
cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk=
+cloud.google.com/go/clouddms v1.5.0 h1:E7v4TpDGUyEm1C/4KIrpVSOCTm0P6vWdHT0I4mostRA=
+cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA=
cloud.google.com/go/cloudtasks v1.8.0 h1:faUiUgXjW8yVZ7XMnKHKm1WE4OldPBUWWfIRN/3z1dc=
cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI=
+cloud.google.com/go/cloudtasks v1.10.0 h1:uK5k6abf4yligFgYFnG0ni8msai/dSv6mDmiBulU0hU=
+cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs=
cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
@@ -70,207 +121,395 @@ cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOt
cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU=
cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE=
cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo=
+cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs=
+cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU=
cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/contactcenterinsights v1.4.0 h1:tTQLI/ZvguUf9Hv+36BkG2+/PeC8Ol1q4pBW+tgCx0A=
cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck=
+cloud.google.com/go/contactcenterinsights v1.6.0 h1:jXIpfcH/VYSE1SYcPzO0n1VVb+sAamiLOgCw45JbOQk=
+cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w=
cloud.google.com/go/container v1.7.0 h1:nbEK/59GyDRKKlo1SqpohY1TK8LmJ2XNcvS9Gyom2A0=
cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo=
+cloud.google.com/go/container v1.15.0 h1:NKlY/wCDapfVZlbVVaeuu2UZZED5Dy1z4Zx1KhEzm8c=
+cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA=
cloud.google.com/go/containeranalysis v0.6.0 h1:2824iym832ljKdVpCBnpqm5K94YT/uHTVhNF+dRTXPI=
cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4=
+cloud.google.com/go/containeranalysis v0.9.0 h1:EQ4FFxNaEAg8PqQCO7bVQfWz9NVwZCUKaM1b3ycfx3U=
+cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s=
cloud.google.com/go/datacatalog v1.8.0 h1:6kZ4RIOW/uT7QWC5SfPfq/G8sYzr/v+UOmOAxy4Z1TE=
cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM=
+cloud.google.com/go/datacatalog v1.13.0 h1:4H5IJiyUE0X6ShQBqgFFZvGGcrwGVndTwUSLP4c52gw=
+cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8=
cloud.google.com/go/dataflow v0.7.0 h1:CW3541Fm7KPTyZjJdnX6NtaGXYFn5XbFC5UcjgALKvU=
cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ=
+cloud.google.com/go/dataflow v0.8.0 h1:eYyD9o/8Nm6EttsKZaEGD84xC17bNgSKCu0ZxwqUbpg=
+cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE=
cloud.google.com/go/dataform v0.5.0 h1:vLwowLF2ZB5J5gqiZCzv076lDI/Rd7zYQQFu5XO1PSg=
cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0=
+cloud.google.com/go/dataform v0.7.0 h1:Dyk+fufup1FR6cbHjFpMuP4SfPiF3LI3JtoIIALoq48=
+cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE=
cloud.google.com/go/datafusion v1.5.0 h1:j5m2hjWovTZDTQak4MJeXAR9yN7O+zMfULnjGw/OOLg=
cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w=
+cloud.google.com/go/datafusion v1.6.0 h1:sZjRnS3TWkGsu1LjYPFD/fHeMLZNXDK6PDHi2s2s/bk=
+cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8=
cloud.google.com/go/datalabeling v0.6.0 h1:dp8jOF21n/7jwgo/uuA0RN8hvLcKO4q6s/yvwevs2ZM=
cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ=
+cloud.google.com/go/datalabeling v0.7.0 h1:ch4qA2yvddGRUrlfwrNJCr79qLqhS9QBwofPHfFlDIk=
+cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM=
cloud.google.com/go/dataplex v1.4.0 h1:cNxeA2DiWliQGi21kPRqnVeQ5xFhNoEjPRt1400Pm8Y=
cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A=
+cloud.google.com/go/dataplex v1.6.0 h1:RvoZ5T7gySwm1CHzAw7yY1QwwqaGswunmqEssPxU/AM=
+cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs=
cloud.google.com/go/dataproc v1.8.0 h1:gVOqNmElfa6n/ccG/QDlfurMWwrK3ezvy2b2eDoCmS0=
cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI=
+cloud.google.com/go/dataproc v1.12.0 h1:W47qHL3W4BPkAIbk4SWmIERwsWBaNnWm0P2sdx3YgGU=
+cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4=
cloud.google.com/go/dataqna v0.6.0 h1:gx9jr41ytcA3dXkbbd409euEaWtofCVXYBvJz3iYm18=
cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA=
+cloud.google.com/go/dataqna v0.7.0 h1:yFzi/YU4YAdjyo7pXkBE2FeHbgz5OQQBVDdbErEHmVQ=
+cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c=
cloud.google.com/go/datastore v1.10.0 h1:4siQRf4zTiAVt/oeH4GureGkApgb2vtPQAtOmhpqQwE=
cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM=
+cloud.google.com/go/datastore v1.11.0 h1:iF6I/HaLs3Ado8uRKMvZRvF/ZLkWaWE9i8AiHzbC774=
+cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c=
cloud.google.com/go/datastream v1.5.0 h1:PgIgbhedBtYBU6POGXFMn2uSl9vpqubc3ewTNdcU8Mk=
cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4=
+cloud.google.com/go/datastream v1.7.0 h1:BBCBTnWMDwwEzQQmipUXxATa7Cm7CA/gKjKcR2w35T0=
+cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww=
cloud.google.com/go/deploy v1.5.0 h1:kI6dxt8Ml0is/x7YZjLveTvR7YPzXAUD/8wQZ2nH5zA=
cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s=
+cloud.google.com/go/deploy v1.8.0 h1:otshdKEbmsi1ELYeCKNYppwV0UH5xD05drSdBm7ouTk=
+cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ=
cloud.google.com/go/dialogflow v1.19.0 h1:HYHVOkoxQ9bSfNIelSZYNAtUi4CeSrCnROyOsbOqPq8=
cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0=
+cloud.google.com/go/dialogflow v1.32.0 h1:uVlKKzp6G/VtSW0E7IH1Y5o0H48/UOCmqksG2riYCwQ=
+cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE=
cloud.google.com/go/dlp v1.7.0 h1:9I4BYeJSVKoSKgjr70fLdRDumqcUeVmHV4fd5f9LR6Y=
cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q=
+cloud.google.com/go/dlp v1.9.0 h1:1JoJqezlgu6NWCroBxr4rOZnwNFILXr4cB9dMaSKO4A=
+cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4=
cloud.google.com/go/documentai v1.10.0 h1:jfq09Fdjtnpnmt/MLyf6A3DM3ynb8B2na0K+vSXvpFM=
cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4=
+cloud.google.com/go/documentai v1.18.0 h1:KM3Xh0QQyyEdC8Gs2vhZfU+rt6OCPF0dwVwxKgLmWfI=
+cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs=
cloud.google.com/go/domains v0.7.0 h1:pu3JIgC1rswIqi5romW0JgNO6CTUydLYX8zyjiAvO1c=
cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg=
+cloud.google.com/go/domains v0.8.0 h1:2ti/o9tlWL4N+wIuWUNH+LbfgpwxPr8J1sv9RHA4bYQ=
+cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE=
cloud.google.com/go/edgecontainer v0.2.0 h1:hd6J2n5dBBRuAqnNUEsKWrp6XNPKsaxwwIyzOPZTokk=
cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w=
+cloud.google.com/go/edgecontainer v1.0.0 h1:O0YVE5v+O0Q/ODXYsQHmHb+sYM8KNjGZw2pjX2Ws41c=
+cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY=
cloud.google.com/go/errorreporting v0.3.0 h1:kj1XEWMu8P0qlLhm3FwcaFsUvXChV/OraZwA70trRR0=
cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU=
cloud.google.com/go/essentialcontacts v1.4.0 h1:b6csrQXCHKQmfo9h3dG/pHyoEh+fQG1Yg78a53LAviY=
cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8=
+cloud.google.com/go/essentialcontacts v1.5.0 h1:gIzEhCoOT7bi+6QZqZIzX1Erj4SswMPIteNvYVlu+pM=
+cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M=
cloud.google.com/go/eventarc v1.8.0 h1:AgCqrmMMIcel5WWKkzz5EkCUKC3Rl5LNMMYsS+LvsI0=
cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw=
+cloud.google.com/go/eventarc v1.11.0 h1:fsJmNeqvqtk74FsaVDU6cH79lyZNCYP8Rrv7EhaB/PU=
+cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY=
cloud.google.com/go/filestore v1.4.0 h1:yjKOpzvqtDmL5AXbKttLc8j0hL20kuC1qPdy5HPcxp0=
cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI=
+cloud.google.com/go/filestore v1.6.0 h1:ckTEXN5towyTMu4q0uQ1Mde/JwTHur0gXs8oaIZnKfw=
+cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/firestore v1.9.0 h1:IBlRyxgGySXu5VuW0RgGFlTtLukSnNkpDiEOMkQkmpA=
cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE=
cloud.google.com/go/functions v1.9.0 h1:35tgv1fQOtvKqH/uxJMzX3w6usneJ0zXpsFr9KAVhNE=
cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08=
+cloud.google.com/go/functions v1.13.0 h1:pPDqtsXG2g9HeOQLoquLbmvmb82Y4Ezdo1GXuotFoWg=
+cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c=
cloud.google.com/go/gaming v1.8.0 h1:97OAEQtDazAJD7yh/kvQdSCQuTKdR0O+qWAJBZJ4xiA=
cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM=
+cloud.google.com/go/gaming v1.9.0 h1:7vEhFnZmd931Mo7sZ6pJy7uQPDxF7m7v8xtBheG08tc=
+cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0=
cloud.google.com/go/gkebackup v0.3.0 h1:4K+jiv4ocqt1niN8q5Imd8imRoXBHTrdnJVt/uFFxF4=
cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo=
+cloud.google.com/go/gkebackup v0.4.0 h1:za3QZvw6ujR0uyqkhomKKKNoXDyqYGPJies3voUK8DA=
+cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg=
cloud.google.com/go/gkeconnect v0.6.0 h1:zAcvDa04tTnGdu6TEZewaLN2tdMtUOJJ7fEceULjguA=
cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A=
+cloud.google.com/go/gkeconnect v0.7.0 h1:gXYKciHS/Lgq0GJ5Kc9SzPA35NGc3yqu6SkjonpEr2Q=
+cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw=
cloud.google.com/go/gkehub v0.10.0 h1:JTcTaYQRGsVm+qkah7WzHb6e9sf1C0laYdRPn9aN+vg=
cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0=
+cloud.google.com/go/gkehub v0.12.0 h1:TqCSPsEBQ6oZSJgEYZ3XT8x2gUadbvfwI32YB0kuHCs=
+cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw=
cloud.google.com/go/gkemulticloud v0.4.0 h1:8F1NhJj8ucNj7lK51UZMtAjSWTgP1zO18XF6vkfiPPU=
cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI=
+cloud.google.com/go/gkemulticloud v0.5.0 h1:8I84Q4vl02rJRsFiinBxl7WCozfdLlUVBQuSrqr9Wtk=
+cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y=
cloud.google.com/go/grafeas v0.2.0 h1:CYjC+xzdPvbV65gi6Dr4YowKcmLo045pm18L0DhdELM=
cloud.google.com/go/gsuiteaddons v1.4.0 h1:TGT2oGmO5q3VH6SjcrlgPUWI0njhYv4kywLm6jag0to=
cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o=
+cloud.google.com/go/gsuiteaddons v1.5.0 h1:1mvhXqJzV0Vg5Fa95QwckljODJJfDFXV4pn+iL50zzA=
+cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo=
cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=
cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc=
cloud.google.com/go/iam v0.8.0 h1:E2osAkZzxI/+8pZcxVLcDtAQx/u+hZXVryUaYQ5O0Kk=
cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE=
+cloud.google.com/go/iam v0.13.0 h1:+CmB+K0J/33d0zSQ9SlFWUeCCEn5XJA0ZMZ3pHE9u8k=
+cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0=
cloud.google.com/go/iap v1.5.0 h1:BGEXovwejOCt1zDk8hXq0bOhhRu9haXKWXXXp2B4wBM=
cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A=
+cloud.google.com/go/iap v1.7.1 h1:PxVHFuMxmSZyfntKXHXhd8bo82WJ+LcATenq7HLdVnU=
+cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74=
cloud.google.com/go/ids v1.2.0 h1:LncHK4HHucb5Du310X8XH9/ICtMwZ2PCfK0ScjWiJoY=
cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY=
+cloud.google.com/go/ids v1.3.0 h1:fodnCDtOXuMmS8LTC2y3h8t24U8F3eKWfhi+3LY6Qf0=
+cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4=
cloud.google.com/go/iot v1.4.0 h1:Y9+oZT9jD4GUZzORXTU45XsnQrhxmDT+TFbPil6pRVQ=
cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g=
+cloud.google.com/go/iot v1.6.0 h1:39W5BFSarRNZfVG0eXI5LYux+OVQT8GkgpHCnrZL2vM=
+cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE=
cloud.google.com/go/kms v1.6.0 h1:OWRZzrPmOZUzurjI2FBGtgY2mB1WaJkqhw6oIwSj0Yg=
cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0=
+cloud.google.com/go/kms v1.10.1 h1:7hm1bRqGCA1GBRQUrp831TwJ9TWhP+tvLuP497CQS2g=
+cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI=
cloud.google.com/go/language v1.8.0 h1:3Wa+IUMamL4JH3Zd3cDZUHpwyqplTACt6UZKRD2eCL4=
cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8=
+cloud.google.com/go/language v1.9.0 h1:7Ulo2mDk9huBoBi8zCE3ONOoBrL6UXfAI71CLQ9GEIM=
+cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY=
cloud.google.com/go/lifesciences v0.6.0 h1:tIqhivE2LMVYkX0BLgG7xL64oNpDaFFI7teunglt1tI=
cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08=
+cloud.google.com/go/lifesciences v0.8.0 h1:uWrMjWTsGjLZpCTWEAzYvyXj+7fhiZST45u9AgasasI=
+cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo=
cloud.google.com/go/logging v1.6.1 h1:ZBsZK+JG+oCDT+vaxwqF2egKNRjz8soXiS6Xv79benI=
cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw=
+cloud.google.com/go/logging v1.7.0 h1:CJYxlNNNNAMkHp9em/YEXcfJg+rPDg7YfwoRpMU+t5I=
+cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M=
cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs=
cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc=
+cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM=
+cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo=
cloud.google.com/go/managedidentities v1.4.0 h1:3Kdajn6X25yWQFhFCErmKSYTSvkEd3chJROny//F1A0=
cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM=
+cloud.google.com/go/managedidentities v1.5.0 h1:ZRQ4k21/jAhrHBVKl/AY7SjgzeJwG1iZa+mJ82P+VNg=
+cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA=
cloud.google.com/go/maps v0.1.0 h1:kLReRbclTgJefw2fcCbdLPLhPj0U6UUWN10ldG8sdOU=
cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI=
+cloud.google.com/go/maps v0.7.0 h1:mv9YaczD4oZBZkM5XJl6fXQ984IkJNHPwkc8MUsdkBo=
+cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY=
cloud.google.com/go/mediatranslation v0.6.0 h1:qAJzpxmEX+SeND10Y/4868L5wfZpo4Y3BIEnIieP4dk=
cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w=
+cloud.google.com/go/mediatranslation v0.7.0 h1:anPxH+/WWt8Yc3EdoEJhPMBRF7EhIdz426A+tuoA0OU=
+cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I=
cloud.google.com/go/memcache v1.7.0 h1:yLxUzJkZVSH2kPaHut7k+7sbIBFpvSh1LW9qjM2JDjA=
cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY=
+cloud.google.com/go/memcache v1.9.0 h1:8/VEmWCpnETCrBwS3z4MhT+tIdKgR1Z4Tr2tvYH32rg=
+cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM=
cloud.google.com/go/metastore v1.8.0 h1:3KcShzqWdqxrDEXIBWpYJpOOrgpDj+HlBi07Grot49Y=
cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI=
+cloud.google.com/go/metastore v1.10.0 h1:QCFhZVe2289KDBQ7WxaHV2rAmPrmRAdLC6gbjUd3HPo=
+cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo=
cloud.google.com/go/monitoring v1.8.0 h1:c9riaGSPQ4dUKWB+M1Fl0N+iLxstMbCktdEwYSPGDvA=
cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4=
+cloud.google.com/go/monitoring v1.13.0 h1:2qsrgXGVoRXpP7otZ14eE1I568zAa92sJSDPyOJvwjM=
+cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw=
cloud.google.com/go/networkconnectivity v1.7.0 h1:BVdIKaI68bihnXGdCVL89Jsg9kq2kg+II30fjVqo62E=
cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8=
+cloud.google.com/go/networkconnectivity v1.11.0 h1:ZD6b4Pk1jEtp/cx9nx0ZYcL3BKqDa+KixNDZ6Bjs1B8=
+cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM=
cloud.google.com/go/networkmanagement v1.5.0 h1:mDHA3CDW00imTvC5RW6aMGsD1bH+FtKwZm/52BxaiMg=
cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4=
+cloud.google.com/go/networkmanagement v1.6.0 h1:8KWEUNGcpSX9WwZXq7FtciuNGPdPdPN/ruDm769yAEM=
+cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY=
cloud.google.com/go/networksecurity v0.6.0 h1:qDEX/3sipg9dS5JYsAY+YvgTjPR63cozzAWop8oZS94=
cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU=
+cloud.google.com/go/networksecurity v0.8.0 h1:sOc42Ig1K2LiKlzG71GUVloeSJ0J3mffEBYmvu+P0eo=
+cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU=
cloud.google.com/go/notebooks v1.5.0 h1:AC8RPjNvel3ExgXjO1YOAz+teg9+j+89TNxa7pIZfww=
cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0=
+cloud.google.com/go/notebooks v1.8.0 h1:Kg2K3K7CbSXYJHZ1aGQpf1xi5x2GUvQWf2sFVuiZh8M=
+cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ=
cloud.google.com/go/optimization v1.2.0 h1:7PxOq9VTT7TMib/6dMoWpMvWS2E4dJEvtYzjvBreaec=
cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs=
+cloud.google.com/go/optimization v1.3.1 h1:dj8O4VOJRB4CUwZXdmwNViH1OtI0WtWL867/lnYH248=
+cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI=
cloud.google.com/go/orchestration v1.4.0 h1:39d6tqvNjd/wsSub1Bn4cEmrYcet5Ur6xpaN+SxOxtY=
cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk=
+cloud.google.com/go/orchestration v1.6.0 h1:Vw+CEXo8M/FZ1rb4EjcLv0gJqqw89b7+g+C/EmniTb8=
+cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ=
cloud.google.com/go/orgpolicy v1.5.0 h1:erF5PHqDZb6FeFrUHiYj2JK2BMhsk8CyAg4V4amJ3rE=
cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc=
+cloud.google.com/go/orgpolicy v1.10.0 h1:XDriMWug7sd0kYT1QKofRpRHzjad0bK8Q8uA9q+XrU4=
+cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc=
cloud.google.com/go/osconfig v1.10.0 h1:NO0RouqCOM7M2S85Eal6urMSSipWwHU8evzwS+siqUI=
cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw=
+cloud.google.com/go/osconfig v1.11.0 h1:PkSQx4OHit5xz2bNyr11KGcaFccL5oqglFPdTboyqwQ=
+cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw=
cloud.google.com/go/oslogin v1.7.0 h1:pKGDPfeZHDybtw48WsnVLjoIPMi9Kw62kUE5TXCLCN4=
cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo=
+cloud.google.com/go/oslogin v1.9.0 h1:whP7vhpmc+ufZa90eVpkfbgzJRK/Xomjz+XCD4aGwWw=
+cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs=
cloud.google.com/go/phishingprotection v0.6.0 h1:OrwHLSRSZyaiOt3tnY33dsKSedxbMzsXvqB21okItNQ=
cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA=
+cloud.google.com/go/phishingprotection v0.7.0 h1:l6tDkT7qAEV49MNEJkEJTB6vOO/onbSOcNtAT09HPuA=
+cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk=
cloud.google.com/go/policytroubleshooter v1.4.0 h1:NQklJuOUoz1BPP+Epjw81COx7IISWslkZubz/1i0UN8=
cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE=
+cloud.google.com/go/policytroubleshooter v1.6.0 h1:yKAGC4p9O61ttZUswaq9GAn1SZnEzTd0vUYXD7ZBT7Y=
+cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc=
cloud.google.com/go/privatecatalog v0.6.0 h1:Vz86uiHCtNGm1DeC32HeG2VXmOq5JRYA3VRPf8ZEcSg=
cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI=
+cloud.google.com/go/privatecatalog v0.8.0 h1:EPEJ1DpEGXLDnmc7mnCAqFmkwUJbIsaLAiLHVOkkwtc=
+cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs=
cloud.google.com/go/pubsub v1.27.1 h1:q+J/Nfr6Qx4RQeu3rJcnN48SNC0qzlYzSeqkPq93VHs=
cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0=
+cloud.google.com/go/pubsub v1.30.0 h1:vCge8m7aUKBJYOgrZp7EsNDf6QMd2CAlXZqWTn3yq6s=
+cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4=
cloud.google.com/go/pubsublite v1.5.0 h1:iqrD8vp3giTb7hI1q4TQQGj77cj8zzgmMPsTZtLnprM=
cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg=
+cloud.google.com/go/pubsublite v1.7.0 h1:cb9fsrtpINtETHiJ3ECeaVzrfIVhcGjhhJEjybHXHao=
+cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM=
cloud.google.com/go/recaptchaenterprise v1.3.1 h1:u6EznTGzIdsyOsvm+Xkw0aSuKFXQlyjGE9a4exk6iNQ=
cloud.google.com/go/recaptchaenterprise/v2 v2.5.0 h1:UqzFfb/WvhwXGDF1eQtdHLrmni+iByZXY4h3w9Kdyv8=
cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U=
+cloud.google.com/go/recaptchaenterprise/v2 v2.7.0 h1:6iOCujSNJ0YS7oNymI64hXsjGq60T4FK1zdLugxbzvU=
+cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c=
cloud.google.com/go/recommendationengine v0.6.0 h1:6w+WxPf2LmUEqX0YyvfCoYb8aBYOcbIV25Vg6R0FLGw=
cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4=
+cloud.google.com/go/recommendationengine v0.7.0 h1:VibRFCwWXrFebEWKHfZAt2kta6pS7Tlimsnms0fjv7k=
+cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac=
cloud.google.com/go/recommender v1.8.0 h1:9kMZQGeYfcOD/RtZfcNKGKtoex3DdoB4zRgYU/WaIwE=
cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70=
+cloud.google.com/go/recommender v1.9.0 h1:ZnFRY5R6zOVk2IDS1Jbv5Bw+DExCI5rFumsTnMXiu/A=
+cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ=
cloud.google.com/go/redis v1.10.0 h1:/zTwwBKIAD2DEWTrXZp8WD9yD/gntReF/HkPssVYd0U=
cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM=
+cloud.google.com/go/redis v1.11.0 h1:JoAd3SkeDt3rLFAAxEvw6wV4t+8y4ZzfZcZmddqphQ8=
+cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ=
cloud.google.com/go/resourcemanager v1.4.0 h1:NDao6CHMwEZIaNsdWy+tuvHaavNeGP06o1tgrR0kLvU=
cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0=
+cloud.google.com/go/resourcemanager v1.7.0 h1:NRM0p+RJkaQF9Ee9JMnUV9BQ2QBIOq/v8M+Pbv/wmCs=
+cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI=
cloud.google.com/go/resourcesettings v1.4.0 h1:eTzOwB13WrfF0kuzG2ZXCfB3TLunSHBur4s+HFU6uSM=
cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg=
+cloud.google.com/go/resourcesettings v1.5.0 h1:8Dua37kQt27CCWHm4h/Q1XqCF6ByD7Ouu49xg95qJzI=
+cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA=
cloud.google.com/go/retail v1.11.0 h1:N9fa//ecFUOEPsW/6mJHfcapPV0wBSwIUwpVZB7MQ3o=
cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y=
+cloud.google.com/go/retail v1.12.0 h1:1Dda2OpFNzIb4qWgFZjYlpP7sxX3aLeypKG6A3H4Yys=
+cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14=
cloud.google.com/go/run v0.3.0 h1:AWPuzU7Xtaj3Jf+QarDWIs6AJ5hM1VFQ+F6Q+VZ6OT4=
cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo=
+cloud.google.com/go/run v0.9.0 h1:ydJQo+k+MShYnBfhaRHSZYeD/SQKZzZLAROyfpeD9zw=
+cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg=
cloud.google.com/go/scheduler v1.7.0 h1:K/mxOewgHGeKuATUJNGylT75Mhtjmx1TOkKukATqMT8=
cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44=
+cloud.google.com/go/scheduler v1.9.0 h1:NpQAHtx3sulByTLe2dMwWmah8PWgeoieFPpJpArwFV0=
+cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc=
cloud.google.com/go/secretmanager v1.9.0 h1:xE6uXljAC1kCR8iadt9+/blg1fvSbmenlsDN4fT9gqw=
cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4=
+cloud.google.com/go/secretmanager v1.10.0 h1:pu03bha7ukxF8otyPKTFdDz+rr9sE3YauS5PliDXK60=
+cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU=
cloud.google.com/go/security v1.10.0 h1:KSKzzJMyUoMRQzcz7azIgqAUqxo7rmQ5rYvimMhikqg=
cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA=
+cloud.google.com/go/security v1.13.0 h1:PYvDxopRQBfYAXKAuDpFCKBvDOWPWzp9k/H5nB3ud3o=
+cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0=
cloud.google.com/go/securitycenter v1.16.0 h1:QTVtk/Reqnx2bVIZtJKm1+mpfmwRwymmNvlaFez7fQY=
cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk=
+cloud.google.com/go/securitycenter v1.19.0 h1:AF3c2s3awNTMoBtMX3oCUoOMmGlYxGOeuXSYHNBkf14=
+cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag=
cloud.google.com/go/servicecontrol v1.5.0 h1:ImIzbOu6y4jL6ob65I++QzvqgFaoAKgHOG+RU9/c4y8=
cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s=
+cloud.google.com/go/servicecontrol v1.11.1 h1:d0uV7Qegtfaa7Z2ClDzr9HJmnbJW7jn0WhZ7wOX6hLE=
+cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk=
cloud.google.com/go/servicedirectory v1.7.0 h1:f7M8IMcVzO3T425AqlZbP3yLzeipsBHtRza8vVFYMhQ=
cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U=
+cloud.google.com/go/servicedirectory v1.9.0 h1:SJwk0XX2e26o25ObYUORXx6torSFiYgsGkWSkZgkoSU=
+cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s=
cloud.google.com/go/servicemanagement v1.5.0 h1:TpkCO5M7dhKSy1bKUD9o/sSEW/U1Gtx7opA1fsiMx0c=
cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo=
+cloud.google.com/go/servicemanagement v1.8.0 h1:fopAQI/IAzlxnVeiKn/8WiV6zKndjFkvi+gzu+NjywY=
+cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4=
cloud.google.com/go/serviceusage v1.4.0 h1:b0EwJxPJLpavSljMQh0RcdHsUrr5DQ+Nelt/3BAs5ro=
cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU=
+cloud.google.com/go/serviceusage v1.6.0 h1:rXyq+0+RSIm3HFypctp7WoXxIA563rn206CfMWdqXX4=
+cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA=
cloud.google.com/go/shell v1.4.0 h1:b1LFhFBgKsG252inyhtmsUUZwchqSz3WTvAIf3JFo4g=
cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw=
+cloud.google.com/go/shell v1.6.0 h1:wT0Uw7ib7+AgZST9eCDygwTJn4+bHMDtZo5fh7kGWDU=
+cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A=
cloud.google.com/go/spanner v1.41.0 h1:NvdTpRwf7DTegbfFdPjAWyD7bOVu0VeMqcvR9aCQCAc=
cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos=
+cloud.google.com/go/spanner v1.45.0 h1:7VdjZ8zj4sHbDw55atp5dfY6kn1j9sam9DRNpPQhqR4=
+cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M=
cloud.google.com/go/speech v1.9.0 h1:yK0ocnFH4Wsf0cMdUyndJQ/hPv02oTJOxzi6AgpBy4s=
cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco=
+cloud.google.com/go/speech v1.15.0 h1:JEVoWGNnTF128kNty7T4aG4eqv2z86yiMJPT9Zjp+iw=
+cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI=
cloud.google.com/go/storage v1.14.0 h1:6RRlFMv1omScs6iq2hfE3IvgE+l6RfJPampq8UZc5TU=
cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ=
cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s=
+cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y=
+cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4=
cloud.google.com/go/storagetransfer v1.6.0 h1:fUe3OydbbvHcAYp07xY+2UpH4AermGbmnm7qdEj3tGE=
cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I=
+cloud.google.com/go/storagetransfer v1.8.0 h1:5T+PM+3ECU3EY2y9Brv0Sf3oka8pKmsCfpQ07+91G9o=
+cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw=
cloud.google.com/go/talent v1.4.0 h1:MrekAGxLqAeAol4Sc0allOVqUGO8j+Iim8NMvpiD7tM=
cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA=
+cloud.google.com/go/talent v1.5.0 h1:nI9sVZPjMKiO2q3Uu0KhTDVov3Xrlpt63fghP9XjyEM=
+cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c=
cloud.google.com/go/texttospeech v1.5.0 h1:ccPiHgTewxgyAeCWgQWvZvrLmbfQSFABTMAfrSPLPyY=
cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4=
+cloud.google.com/go/texttospeech v1.6.0 h1:H4g1ULStsbVtalbZGktyzXzw6jP26RjVGYx9RaYjBzc=
+cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc=
cloud.google.com/go/tpu v1.4.0 h1:ztIdKoma1Xob2qm6QwNh4Xi9/e7N3IfvtwG5AcNsj1g=
cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg=
+cloud.google.com/go/tpu v1.5.0 h1:/34T6CbSi+kTv5E19Q9zbU/ix8IviInZpzwz3rsFE+A=
+cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM=
cloud.google.com/go/trace v1.4.0 h1:qO9eLn2esajC9sxpqp1YKX37nXC3L4BfGnPS0Cx9dYo=
cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y=
+cloud.google.com/go/trace v1.9.0 h1:olxC0QHC59zgJVALtgqfD9tGk0lfeCP5/AGXL3Px/no=
+cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk=
cloud.google.com/go/translate v1.4.0 h1:AOYOH3MspzJ/bH1YXzB+xTE8fMpn3mwhLjugwGXvMPI=
cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg=
+cloud.google.com/go/translate v1.7.0 h1:GvLP4oQ4uPdChBmBaUSa/SaZxCdyWELtlAaKzpHsXdA=
+cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos=
cloud.google.com/go/video v1.9.0 h1:ttlvO4J5c1VGq6FkHqWPD/aH6PfdxujHt+muTJlW1Zk=
cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw=
+cloud.google.com/go/video v1.15.0 h1:upIbnGI0ZgACm58HPjAeBMleW3sl5cT84AbYQ8PWOgM=
+cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ=
cloud.google.com/go/videointelligence v1.9.0 h1:RPFgVVXbI2b5vnrciZjtsUgpNKVtHO/WIyXUhEfuMhA=
cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU=
+cloud.google.com/go/videointelligence v1.10.0 h1:Uh5BdoET8XXqXX2uXIahGb+wTKbLkGH7s4GXR58RrG8=
+cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU=
cloud.google.com/go/vision v1.2.0 h1:/CsSTkbmO9HC8iQpxbK8ATms3OQaX3YQUeTMGCxlaK4=
cloud.google.com/go/vision/v2 v2.5.0 h1:TQHxRqvLMi19azwm3qYuDbEzZWmiKJNTpGbkNsfRCik=
cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E=
+cloud.google.com/go/vision/v2 v2.7.0 h1:8C8RXUJoflCI4yVdqhTy9tRyygSHmp60aP363z23HKg=
+cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0=
cloud.google.com/go/vmmigration v1.3.0 h1:A2Tl2ZmwMRpvEmhV2ibISY85fmQR+Y5w9a0PlRz5P3s=
cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g=
+cloud.google.com/go/vmmigration v1.6.0 h1:Azs5WKtfOC8pxvkyrDvt7J0/4DYBch0cVbuFfCCFt5k=
+cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY=
cloud.google.com/go/vmwareengine v0.1.0 h1:JMPZaOT/gIUxVlTqSl/QQ32Y2k+r0stNeM1NSqhVP9o=
cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208=
+cloud.google.com/go/vmwareengine v0.3.0 h1:b0NBu7S294l0gmtrT0nOJneMYgZapr5x9tVWvgDoVEM=
+cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY=
cloud.google.com/go/vpcaccess v1.5.0 h1:woHXXtnW8b9gLFdWO9HLPalAddBQ9V4LT+1vjKwR3W8=
cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8=
+cloud.google.com/go/vpcaccess v1.6.0 h1:FOe6CuiQD3BhHJWt7E8QlbBcaIzVRddupwJlp7eqmn4=
+cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes=
cloud.google.com/go/webrisk v1.7.0 h1:ypSnpGlJnZSXbN9a13PDmAYvVekBLnGKxQ3Q9SMwnYY=
cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A=
+cloud.google.com/go/webrisk v1.8.0 h1:IY+L2+UwxcVm2zayMAtBhZleecdIFLiC+QJMzgb0kT0=
+cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg=
cloud.google.com/go/websecurityscanner v1.4.0 h1:y7yIFg/h/mO+5Y5aCOtVAnpGUOgqCH5rXQ2Oc8Oq2+g=
cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ=
+cloud.google.com/go/websecurityscanner v1.5.0 h1:AHC1xmaNMOZtNqxI9Rmm87IJEyPaRkOxeI0gpAacXGk=
+cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng=
cloud.google.com/go/workflows v1.9.0 h1:7Chpin9p50NTU8Tb7qk+I11U/IwVXmDhEoSsdccvInE=
cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA=
+cloud.google.com/go/workflows v1.10.0 h1:FfGp9w0cYnaKZJhUOMqCOJCYT/WlvYBfTQhFWV3sRKI=
+cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8 h1:V8krnnfGj4pV65YLUm3C0/8bl7V5Nry2Pwvy3ru/wLc=
github.com/Azure/azure-sdk-for-go v56.3.0+incompatible h1:DmhwMrUIvpeoTDiWRDtNHqelNUd3Og8JCkrLHQK795c=
@@ -331,6 +570,7 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.16.4 h1:+xtV90n3abQmgzk1pS++FdxZTrPE
github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
+github.com/benbjohnson/clock v1.3.3/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bitly/go-hostpool v0.1.0 h1:XKmsF6k5el6xHG3WPJ8U0Ku/ye7njX7W81Ng7O2ioR0=
@@ -347,6 +587,8 @@ github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1q
github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk=
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
+github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/checkpoint-restore/go-criu/v5 v5.3.0 h1:wpFFOoomK3389ue2lAb0Boag6XPht5QYpipxmSNL4d8=
@@ -361,9 +603,13 @@ github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 h1:hzAQntlaYRkVSFEfj9OTWlVV1H155FMD8BTKktLv0QI=
+github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk=
+github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 h1:zH8ljVhhq7yC0MIeUL/IviMtY8hx2mK8cN9wEYb8ggw=
+github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195 h1:58f1tJ1ra+zFINPlwLWvQsR9CzAKt2e+EWV2yX9oXQ4=
+github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/containerd/aufs v1.0.0 h1:2oeJiwX5HstO7shSrPZjrohJZLzK36wvpdmzDRkL/LY=
github.com/containerd/btrfs v1.0.0 h1:osn1exbzdub9L5SouXO5swW4ea/xVdJZ3wokxN5GrnA=
github.com/containerd/fuse-overlayfs-snapshotter v1.0.2 h1:Xy9Tkx0tk/SsMfLDFc69wzqSrxQHYEFELHBO/Z8XO3M=
@@ -385,6 +631,7 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cristalhq/acmd v0.11.1 h1:DJ4fh2Pv0nPKmqT646IU/0Vh5FNdGblxvF+3/W3NAUI=
github.com/cucumber/gherkin-go/v11 v11.0.0/go.mod h1:CX33k2XU2qog4e+TFjOValoq6mIUq0DmVccZs238R9w=
github.com/cucumber/gherkin-go/v19 v19.0.3 h1:mMSKu1077ffLbTJULUfM5HPokgeBcIGboyeNUof1MdE=
github.com/cucumber/godog v0.11.0 h1:xgaWyJuAD6A+aW4TfVGNDBhuMyKW0jjl0cvY3KNxEak=
@@ -411,6 +658,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 h1:xvqufLtNVwAhN8NMyWklVgxnWohi+wtMGQMhtxexlm0=
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
+github.com/envoyproxy/go-control-plane v0.11.0 h1:jtLewhRR2vMRNnq2ZZUoCjUlgut+Y0+sDDWPOfwOi1o=
+github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
github.com/evilmartians/lefthook v1.3.7/go.mod h1:FTw9v/+5Tg5AlrLPxS2kJeqHhQNqhUA+6/WdGeaf41s=
@@ -449,12 +698,16 @@ github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keL
github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
+github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
+github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
+github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@@ -464,6 +717,7 @@ github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPg
github.com/google/martian/v3 v3.1.0 h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60=
github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ=
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
+github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
@@ -478,6 +732,7 @@ github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbez
github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
github.com/googleapis/enterprise-certificate-proxy v0.2.1 h1:RY7tHKZcRlk788d5WSo/e83gOyyy742E8GSs771ySpg=
github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
+github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
@@ -488,9 +743,11 @@ github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89
github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY=
github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ=
github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8=
+github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA=
github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 h1:tlyzajkF3030q6M8SvmJSemC9DTHL/xaMa18b65+JM4=
+github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/goreleaser/nfpm/v2 v2.27.1/go.mod h1:o5coBBYYdw+tifbB6DJLL/rR42bUmI5mWCKGumJmEt8=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
@@ -499,6 +756,9 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmg
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=
github.com/hanwen/go-fuse/v2 v2.1.1-0.20220112183258-f57e95bda82d h1:ibbzF2InxMOS+lLCphY9PHNKPURDUBNKaG6ErSq8gJQ=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/api v1.15.3 h1:WYONYL2rxTXtlekAqblR2SCdJsizMDIj/uXb5wNy9zU=
@@ -541,7 +801,6 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
-github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
@@ -559,11 +818,14 @@ github.com/hashicorp/serf v0.9.8 h1:JGklO/2Drf1QGa312EieQN3zhxQ+aJg6pG+aC3MFaVo=
github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=
github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
+github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
+github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2 h1:rcanfLhLDA8nozr/K289V1zcntHr3V+SHlXwzz1ZI2g=
github.com/ianlancetaylor/demangle v0.0.0-20220517205856-0058ec4f073c h1:rwmN+hgiyp8QyBqzdEX43lTjKAxaqCrYHaU5op5P9J8=
github.com/intel/goresctrl v0.2.0 h1:JyZjdMQu9Kl/wLXe9xA6s1X+tF6BWsQPFGJMEeCfWzE=
github.com/jinzhu/now v1.1.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
+github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
@@ -574,13 +836,16 @@ github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4d
github.com/karrick/godirwalk v1.10.3 h1:lOpSw2vJP0y5eLBW906QwKsUK/fe/QDyoqM5rnnuPDY=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY=
-github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/klauspost/compress v1.15.13/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f h1:I1iYfgQavGa2tgdgKn+2Qg1yQhHEETvh/mNSxG3x5c0=
+github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
+github.com/lyft/protoc-gen-star/v2 v2.0.1 h1:keaAo8hRuAT0O3DfJ/wM3rufbAjGeJ1lAtWZHDjKGB0=
+github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o=
+github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2 h1:JgVTCPf0uBVcUSWpyXmGpgOc62nK5HWUBKAGc3Qqa5k=
github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI=
@@ -593,6 +858,7 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-sqlite3 v1.6.0 h1:TDwTWbeII+88Qy55nWlof0DclgAtI4LqGujkYMzmQII=
+github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 h1:zpIH83+oKzcpryru8ceC6BxnoG8TBrhgAvRg8obzup0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY=
@@ -602,6 +868,7 @@ github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceT
github.com/mitchellh/cli v1.1.0 h1:tEElEatulEHDeedTxwckzyYMA5c86fbmNIUL1hBIiTg=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
@@ -613,6 +880,7 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/51gbeLHfKGNfgEQQIWrlbdaOsidbQ=
github.com/moby/sys/mount v0.3.0 h1:bXZYMmq7DBQPwHRxH/MG+u9+XF90ZOwoXpHTOznMGp0=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
+github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5 h1:0KqC6/sLy7fDpBdybhVkkv4Yz+PmB7c9Dz9z3dLW804=
github.com/mrunalp/fileutils v0.5.0 h1:NKzVxiH7eSk+OQ4M+ZYW1K6h27RUV3MI6NUTsHhU6Z4=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d h1:7PxY7LVfSZm7PEeBTyK1rj1gABdCO2mbri6GKO1cMDs=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
@@ -623,13 +891,17 @@ github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU=
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ=
+github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI=
+github.com/otiai10/mint v1.3.1 h1:BCmzIS3n71sGfHB5NMNDB3lHYPz8fWSkCAErHed//qc=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
+github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A=
+github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pkg/sftp v1.13.1 h1:I2qBYMChEhIjOgazfJmV3/mZM256btk6wkCDRmW7JYs=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=
@@ -638,16 +910,24 @@ github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
+github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
+github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE=
+github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71 h1:CNooiryw5aisadVfzneSZPswRWvnVW8hF1bS/vo8ReI=
+github.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5 h1:CvqZS4QYHBRvx7AeFdimd16HCbLlYsvQMcKDACpJW/c=
+github.com/remyoudompheng/go-liblzma v0.0.0-20190506200333-81bf2d431b96 h1:J8J/cgLDRuqXJnwIrRDBvtl+LLsdg7De74znW/BRRq4=
+github.com/remyoudompheng/go-misc v0.0.0-20190427085024-2d6ac652a50e h1:eTWZyPUnHcuGRDiryS/l2I7FfKjbU3IBx3IjqHPxuKU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s=
github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
+github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
@@ -657,6 +937,8 @@ github.com/sagikazarmark/crypt v0.9.0/go.mod h1:RnH7sEhxfdnPm1z+XMgSLjWTEIjyK4z2
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646 h1:RpforrEYXWkmGwJHIGnLZ3tTWStkjVVstwzNGqxX2Ds=
+github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e h1:MZM7FHLqUHYI0Y/mQAt3d2aYa0SiNms/hFqC9qJYolM=
+github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041 h1:llrF3Fs4018ePo4+G/HV/uQUqEI1HMDjCeOf2V6puPc=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
@@ -664,6 +946,7 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
@@ -683,6 +966,8 @@ github.com/tonistiigi/go-archvariant v1.0.0 h1:5LC1eDWiBNflnTF1prCiX09yfNHIxDC/a
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA=
+github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
+github.com/valyala/quicktemplate v1.7.0 h1:LUPTJmlVcb46OOUY3IeD9DojFpAVbsG+5WFTcjMJzCM=
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5 h1:+UB2BJA852UkGH42H+Oee69djmxS3ANzl2b/JtT1YiA=
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
@@ -690,6 +975,7 @@ github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=
@@ -718,16 +1004,18 @@ go.opentelemetry.io/otel/exporters/jaeger v1.4.1 h1:VHCK+2yTZDqDaVXj7JH2Z/khptuy
go.opentelemetry.io/otel/internal/metric v0.27.0 h1:9dAVGAfFiiEq5NVB9FUJ5et+btbDQAUIJehJ+ikyryk=
go.opentelemetry.io/otel/sdk v1.11.1/go.mod h1:/l3FE4SupHJ12TduVjUkZtlfFqDCQJlOlithYrdktys=
go.opentelemetry.io/otel/trace v1.11.2/go.mod h1:4N+yC7QEz7TTsG9BSRLNAa63eg5E06ObSbKPmxQ/pKA=
-go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw=
+go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
-go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
+golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20221211140036-ad323defaf05 h1:T8EldfGCcveFMewH5xAYxxoX3PSQMrsechlUGVFlQBU=
golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 h1:BEABXpNXLEz0WxtA+6CQIz2xkg80e+1zrhWyMcq8VzE=
@@ -739,7 +1027,7 @@ golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs=
-golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -758,8 +1046,9 @@ golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
-golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
-golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
@@ -772,10 +1061,12 @@ golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7Lm
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
+golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -800,10 +1091,11 @@ golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
+golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -811,7 +1103,7 @@ golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
@@ -842,10 +1134,14 @@ google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB
google.golang.org/api v0.102.0 h1:JxJl2qQ85fRMPNvlZY/enexbxpCjLwGhZUtgfGeQ51I=
google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo=
google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0=
+google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=
google.golang.org/api v0.107.0 h1:I2SlFjD8ZWabaIFOfeEDg3pf0BHJDh6iYQ1ic3Yu/UU=
google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=
google.golang.org/api v0.108.0 h1:WVBc/faN0DkKtR43Q/7+tPny9ZoLZdIiAyG5Q9vFClg=
google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=
+google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI=
+google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0=
+google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg=
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8 h1:Cpp2P6TPjujNoC5M2KHY6g7wfyLYfIWRZaSdIKfDasA=
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
@@ -891,6 +1187,7 @@ google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP
google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
+google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw=
google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=
google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo=
@@ -898,6 +1195,12 @@ google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZV
google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE=
google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
+google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
+google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
+google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw=
+google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA=
+google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
+google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
@@ -907,18 +1210,25 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
+google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
+google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
+google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
+google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/dancannon/gorethink.v3 v3.0.5 h1:/g7PWP7zUS6vSNmHSDbjCHQh1Rqn8Jy6zSMQxAsBSMQ=
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
gopkg.in/fatih/pool.v2 v2.0.0 h1:xIFeWtxifuQJGk/IEPKsTduEKcKvPmhoiVDGpC40nKg=
diff --git a/hugo/content/changelog.md b/hugo/content/changelog.md
index e5e685110..6430ebd4f 100644
--- a/hugo/content/changelog.md
+++ b/hugo/content/changelog.md
@@ -2,7 +2,7 @@
title: "Changelog"
draft: false
description: "NGINX Agent updates changelog."
-weight: 700
+weight: 900
toc: true
tags: [ "docs" ]
docs: "DOCS-1093"
diff --git a/hugo/content/community.md b/hugo/content/community.md
index 26f7f0677..773e06419 100644
--- a/hugo/content/community.md
+++ b/hugo/content/community.md
@@ -2,7 +2,7 @@
title: "Contributing and Support"
draft: false
description: "Learn about the NGINX Agent community."
-weight: 600
+weight: 800
toc: true
tags: [ "docs" ]
docs: "DOCS-1087"
diff --git a/hugo/content/dev-environment-setup.md b/hugo/content/dev-environment-setup.md
index bca9700eb..a368ac053 100644
--- a/hugo/content/dev-environment-setup.md
+++ b/hugo/content/dev-environment-setup.md
@@ -2,7 +2,7 @@
title: "Development Environment Setup"
draft: false
description: "Learn how to setup a Development Environment for NGINX Agent."
-weight: 400
+weight: 700
toc: true
tags: [ "docs" ]
docs: "DOCS-1088"
@@ -16,7 +16,7 @@ While most Linux or FreeBSD operating systems can be used to contribute to the N
## Install NGINX
-Follow the steps in the [Installation]({{< relref "/installation.md" >}}) section to download, install, and run NGINX and NGINX Agent.
+Follow the steps in the [Installation]({{< relref "/installation-github.md" >}}) section to download, install, and run NGINX and NGINX Agent.
## Clone the NGINX Agent Repository
@@ -56,7 +56,7 @@ make install-tools deps
Run the following commands to build and run NGINX Agent:
-```
+```bash
make build
sudo make run
```
diff --git a/hugo/content/getting-started.md b/hugo/content/getting-started.md
index a6f800e67..2f141b2a3 100644
--- a/hugo/content/getting-started.md
+++ b/hugo/content/getting-started.md
@@ -2,7 +2,7 @@
title: "Getting Started"
draft: false
description: "Learn how to configure and run NGINX Agent."
-weight: 300
+weight: 600
toc: true
tags: [ "docs" ]
docs: "DOCS-1089"
@@ -14,7 +14,7 @@ Follow these steps to configure and run NGINX Agent and a mock interface ("contr
## Install NGINX
-Follow the steps in the [Installation]({{< relref "/installation.md" >}}) section to download, install, and run NGINX.
+Follow the steps in the [Installation]({{< relref "/installation-github.md" >}}) section to download, install, and run NGINX.
## Clone the NGINX Agent Repository
@@ -22,13 +22,13 @@ Using your preferred method, clone the NGINX Agent repository into your developm
## Install Go
-NGINX Agent and the Mock Control Plane are written in Go. Go 1.19 or higher is required to build and run either application from the source code directory. You can [download Go from the official website](https://go.dev/dl/).
+NGINX Agent and the Mock Control Plane are written in Go. Go 1.19.9 or higher is required to build and run either application from the source code directory. You can [download Go from the official website](https://go.dev/dl/).
## Start the gRPC Mock Control Plane
Start the mock control plane by running the following command from the `agent` source code root directory:
-```bash
+```shell
go run sdk/examples/server.go
# Command Output
@@ -37,13 +37,17 @@ INFO[0000] grpc listening at 54789 # grpc control plane port which NGINX Agent w
```
## NGINX Agent Settings
+
If it doesn't already exist, create the `/etc/nginx-agent/` directory and copy the `nginx-agent.conf` file into it from the project root directory.
-```
+
+```shell
sudo mkdir /etc/nginx-agent
sudo cp /nginx-agent.conf /etc/nginx-agent/
```
+
Create the `agent-dynamic.conf` file in the `/var/lib/nginx-agent/` directory, which is required for NGINX Agent to run.
-```
+
+```shell
sudo touch /var/lib/nginx-agent/agent-dynamic.conf
```
@@ -65,6 +69,7 @@ tls:
For more information, see [Agent Protocol Definitions and Documentation](https://github.com/nginx/agent/tree/main/docs/proto/README.md)
### Enable the REST interface
+
The NGINX Agent REST interface can be exposed by validating the following lines in the `/etc/nginx-agent/nginx-agent.conf` file are present:
```yaml
@@ -79,15 +84,17 @@ api:
The mock control plane can use either gRPC or REST protocols to communicate with NGINX Agent.
## Launch Swagger UI
+
Swagger UI requires goswagger be installed. See [instructions for installing goswagger](https://goswagger.io/install.html) for additional help.
To launch the Swagger UI for the REST interface run the following command
-```bash
+```shell
make launch-swagger-ui
```
## Extensions
+
An extension is a piece of code, not critical to the main functionality that the NGINX agent is responsible for. This generally falls outside the remit of managing NGINX Configuration and reporting NGINX metrics.
To enable an extension, it must be added to the extensions list in the `/etc/nginx-agent/nginx-agent.conf`.
@@ -104,7 +111,7 @@ If already running, restart NGINX Agent to apply the new configuration. Alternat
Open another terminal window and start the NGINX Agent. Issue the following command from the `agent` source code root directory.
-```bash
+```shell
sudo make run
# Command Output snippet
@@ -139,3 +146,23 @@ Open a web browser to view the mock control plane at [http://localhost:54790](ht
- **metrics** - shows a buffer of metrics sent to the management plane (similar to what will be sent back in the REST API)
For more NGINX Agent use cases, refer to the [NGINX Agent SDK examples](https://github.com/nginx/agent/tree/main/sdk/examples).
+
+## Start and Enable Start on Boot
+
+To start the NGINX Agent on `systemd` systems, run the following command:
+
+```shell
+sudo systemctl start nginx-agent
+```
+
+To enable the NGINX Agent to start on boot, run the following command:
+
+```shell
+sudo systemctl enable nginx-agent
+```
+
+## Logs
+
+NGINX Agent uses formatted log files to collect metrics. Expanding log formats and instance counts will also increase the size of the NGINX Agent log files. We recommend adding a separate partition for `/var/log/nginx-agent`.
+
+{{< important >}}Without log rotation or storage on a separate partition, log files could use up all the free drive space and cause your system to become unresponsive to certain services.{{< /important >}}
diff --git a/hugo/content/installation.md b/hugo/content/installation-github.md
similarity index 53%
rename from hugo/content/installation.md
rename to hugo/content/installation-github.md
index 40cd08b0f..cba2afe94 100644
--- a/hugo/content/installation.md
+++ b/hugo/content/installation-github.md
@@ -1,7 +1,7 @@
---
-title: "Installation"
+title: "Installation from GitHub Release"
draft: false
-description: "Learn how to install NGINX Agent."
+description: "Learn how to install NGINX Agent from a GitHub Release."
weight: 200
toc: true
tags: [ "docs" ]
@@ -14,58 +14,38 @@ doctypes: ["task"]
NGINX Agent interfaces directly with an NGINX server process installed on the same system. If you don't have it already, follow these steps to install [NGINX Open Source](https://www.nginx.com/resources/wiki/start/topics/tutorials/install/) or [NGINX Plus](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-plus/). Once installed, ensure the NGINX instance is running.
-## Install Agent from Package Files
+## Install NGINX Agent from Package Files
-To install NGINX Agent on your system, go to [Releases](https://github.com/nginx/agent/releases) and download the latest package supported by your OS distribution and CPU architecture.
+To install NGINX Agent on your system, go to [GitHub Releases](https://github.com/nginx/agent/releases) and download the latest package supported by your OS distribution and CPU architecture.
Use your system's package manager to install the package. Some examples:
- Debian, Ubuntu, and other distributions using the `dpkg` package manager.
- ```
+ ```shell
sudo dpkg -i nginx-agent-.deb
```
- RHEL, CentOS RHEL, Amazon Linux, Oracle Linux, and other distributions using the `yum` package manager
- ```
+ ```shell
sudo yum localinstall nginx-agent-.rpm
```
- RHEL and other distributions using the `rpm` package manager
- ```
+ ```shell
sudo rpm -i nginx-agent-.rpm
```
- Alpine Linux
- ```
+ ```shell
sudo apk add nginx-agent-.apk
```
- FreeBSD
- ```
+ ```shell
sudo pkg add nginx-agent-.pkg
```
-
-## Start and Enable Start on Boot
-
-To start the NGINX Agent on `systemd` systems, run the following command:
-
-```
-sudo systemctl start nginx-agent
-```
-
-To enable the NGINX Agent to start on boot, run the following command:
-
-```
-sudo systemctl enable nginx-agent
-```
-
-## Logs
-
-NGINX Agent uses formatted log files to collect metrics. Expanding log formats and instance counts will also increase the size of the NGINX Agent log files. We recommend adding a separate partition for `/var/log/nginx-agent`.
-
-{{< important >}}Without log rotation or storage on a separate partition, log files could use up all the free drive space and cause your system to become unresponsive to certain services.{{< /important >}}
diff --git a/hugo/content/installation-oss.md b/hugo/content/installation-oss.md
new file mode 100644
index 000000000..6ffc41583
--- /dev/null
+++ b/hugo/content/installation-oss.md
@@ -0,0 +1,349 @@
+---
+title: "Installation From NGINX Repository"
+draft: false
+description: "Learn how to install NGINX Agent from OSS Repository."
+weight: 300
+toc: true
+tags: [ "docs" ]
+docs: "DOCS-1216"
+categories: ["configuration"]
+doctypes: ["task"]
+---
+
+
+## Prerequisites
+
+- NGINX installed. Once installed, ensure it is running. If you don't have it installed already, follow these steps to install [NGINX](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/)
+- A [supported operating system and architecture](../technical-specifications/#supported-distributions)
+- `root` privilege
+
+## Configure NGINX OSS Repository for installing NGINX Agent
+
+Before you install NGINX Agent for the first time on your system, you need to set up the `nginx-agent` packages repository. Afterward, you can install and update NGINX Agent from the repository.
+
+- [Installing NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux](#installing-nginx-agent-on-rhel-centos-rocky-linux-almalinux-and-oracle-linux)
+- [Installing NGINX Agent on Ubuntu](#installing-nginx-agent-on-ubuntu)
+- [Installing NGINX Agent on Debian](#installing-nginx-agent-on-debian)
+- [Installing NGINX Agent on SLES](#installing-nginx-agent-on-sles)
+- [Installing NGINX Agent on Alpine Linux](#installing-nginx-agent-on-alpine-linux)
+- [Installing NGINX Agent on Amazon Linux](#installing-nginx-agent-on-amazon-linux)
+- [Installing NGINX Agent on FreeBSD](#installing-nginx-agent-on-freebsd)
+
+### Installing NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux
+
+1. Install the prerequisites:
+
+ ```shell
+ sudo yum install yum-utils
+ ```
+
+1. To set up the yum repository, create the file named `/etc/yum.repos.d/nginx-agent.repo` with the following contents:
+
+ ```
+ [nginx-agent]
+ name=nginx agent repo
+ baseurl=http://packages.nginx.org/nginx-agent/centos/$releasever/$basearch/
+ gpgcheck=1
+ enabled=1
+ gpgkey=https://nginx.org/keys/nginx_signing.key
+ module_hotfixes=true
+ ```
+
+1. To install `nginx-agent`, run the following command:
+
+ ```shell
+ sudo yum install nginx-agent
+ ```
+
+ When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it.
+
+### Installing NGINX Agent on Ubuntu
+
+1. Install the prerequisites:
+
+ ```shell
+ sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
+ ```
+
+1. Import an official nginx signing key so apt could verify the packages authenticity. Fetch the key:
+
+ ```shell
+ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
+ | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
+ ```
+
+1. Verify that the downloaded file contains the proper key:
+
+ ```shell
+ gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
+ ```
+
+ The output should contain the full fingerprint `573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62` as follows:
+
+ ```
+ pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
+ 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
+ uid nginx signing key
+ ```
+
+ {{< important >}}If the fingerprint is different, remove the file.{{< /important >}}
+
+1. Add the nginx agent repository:
+
+ ```shell
+ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
+ http://packages.nginx.org/nginx-agent/ubuntu/ `lsb_release -cs` agent" \
+ | sudo tee /etc/apt/sources.list.d/nginx-agent.list
+ ```
+
+1. To install `nginx-agent`, run the following commands:
+
+ ```shell
+ sudo apt update
+ sudo apt install nginx-agent
+ ```
+
+1. Verify the installation:
+
+ ```shell
+ sudo nginx-agent -v
+ ```
+
+
+### Installing NGINX Agent on Debian
+
+1. Install the prerequisites:
+
+ ```shell
+ sudo apt install curl gnupg2 ca-certificates lsb-release debian-archive-keyring
+ ```
+
+1. Import an official nginx signing key so apt could verify the packages authenticity. Fetch the key:
+
+ ```shell
+ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
+ | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
+ ```
+
+1. Verify that the downloaded file contains the proper key:
+
+ ```shell
+ gpg --dry-run --quiet --no-keyring \
+ --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
+ ```
+
+ The output should contain the full fingerprint `573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62` as follows:
+
+ ```
+ pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
+ 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
+ uid nginx signing key
+ ```
+
+ {{< important >}}If the fingerprint is different, remove the file.{{< /important >}}
+
+1. Add the `nginx-agent` repository:
+
+ ```shell
+ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
+ http://packages.nginx.org/nginx-agent/debian/ `lsb_release -cs` agent" \ | sudo tee /etc/apt/sources.list.d/nginx-agent.list
+ ```
+
+1. To install `nginx-agent`, run the following commands:
+
+ ```shell
+ sudo apt update
+ sudo apt install nginx-agent
+ ```
+
+1. Verify the installation:
+
+ ```shell
+ sudo nginx-agent -v
+ ```
+
+
+### Installing NGINX Agent on SLES
+
+1. Install the prerequisites:
+
+ ```shell
+ sudo zypper install curl ca-certificates gpg2 gawk
+ ```
+
+1. To set up the zypper repository for `nginx-agent` packages, run the following command:
+
+ ```shell
+ sudo zypper addrepo --gpgcheck --refresh --check \
+ 'http://packages.nginx.org/nginx-agent/sles/$releasever_major' nginx-agent
+ ```
+
+1. Next, import an official NGINX signing key so `zypper`/`rpm` can verify the package's authenticity. Fetch the key:
+
+ ```shell
+ curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key
+ ```
+
+1. Verify that the downloaded file contains the proper key:
+
+ ```shell
+ gpg --with-fingerprint --dry-run --quiet --no-keyring --import --import-options import-show /tmp/nginx_signing.key
+ ```
+
+1. The output should contain the full fingerprint `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62` as follows:
+
+ ```
+ pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
+ 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62
+ uid nginx signing key
+ ```
+
+1. Finally, import the key to the rpm database:
+
+ ```shell
+ sudo rpmkeys --import /tmp/nginx_signing.key
+ ```
+
+1. To install `nginx-agent`, run the following command:
+
+ ```shell
+ sudo zypper install nginx-agent
+ ```
+
+1. Verify the installation:
+
+ ```shell
+ sudo nginx-agent -v
+ ```
+
+### Installing NGINX Agent on Alpine Linux
+
+1. Install the prerequisites:
+
+ ```shell
+ sudo apk add openssl curl ca-certificates
+ ```
+
+1. To set up the apk repository for `nginx-agent` packages, run the following command:
+
+ ```shell
+ printf "%s%s%s%s\n" \
+ "@nginx-agent " \
+ "http://packages.nginx.org/nginx-agent/alpine/v" \
+ `grep -o -E '^[0-9]+\.[0-9]+' /etc/alpine-release` \
+ "/main" \
+ | sudo tee -a /etc/apk/repositories
+ ```
+
+1. Next, import an official NGINX signing key so apk can verify the package's authenticity. Fetch the key:
+
+ ```shell
+ curl -o /tmp/nginx_signing.rsa.pub https://nginx.org/keys/nginx_signing.rsa.pub
+ ```
+
+1. Verify that downloaded file contains the proper key:
+
+ ```shell
+ openssl rsa -pubin -in /tmp/nginx_signing.rsa.pub -text -noout
+ ```
+
+ The output should contain the following modulus:
+
+ ```
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:fe:14:f6:0a:1a:b8:86:19:fe:cd:ab:02:9f:58:
+ 2f:37:70:15:74:d6:06:9b:81:55:90:99:96:cc:70:
+ 5c:de:5b:e8:4c:b2:0c:47:5b:a8:a2:98:3d:11:b1:
+ f6:7d:a0:46:df:24:23:c6:d0:24:52:67:ba:69:ab:
+ 9a:4a:6a:66:2c:db:e1:09:f1:0d:b2:b0:e1:47:1f:
+ 0a:46:ac:0d:82:f3:3c:8d:02:ce:08:43:19:d9:64:
+ 86:c4:4e:07:12:c0:5b:43:ba:7d:17:8a:a3:f0:3d:
+ 98:32:b9:75:66:f4:f0:1b:2d:94:5b:7c:1c:e6:f3:
+ 04:7f:dd:25:b2:82:a6:41:04:b7:50:93:94:c4:7c:
+ 34:7e:12:7c:bf:33:54:55:47:8c:42:94:40:8e:34:
+ 5f:54:04:1d:9e:8c:57:48:d4:b0:f8:e4:03:db:3f:
+ 68:6c:37:fa:62:14:1c:94:d6:de:f2:2b:68:29:17:
+ 24:6d:f7:b5:b3:18:79:fd:31:5e:7f:4c:be:c0:99:
+ 13:cc:e2:97:2b:dc:96:9c:9a:d0:a7:c5:77:82:67:
+ c9:cb:a9:e7:68:4a:e1:c5:ba:1c:32:0e:79:40:6e:
+ ef:08:d7:a3:b9:5d:1a:df:ce:1a:c7:44:91:4c:d4:
+ 99:c8:88:69:b3:66:2e:b3:06:f1:f4:22:d7:f2:5f:
+ ab:6d
+ Exponent: 65537 (0x10001)
+ ```
+
+1. Finally, move the key to apk trusted keys storage:
+
+ ```shell
+ sudo mv /tmp/nginx_signing.rsa.pub /etc/apk/keys/
+ ```
+
+1. To install `nginx-agent`, run the following command:
+
+ ```shell
+ sudo apk add nginx-agent@nginx-agent
+ ```
+
+1. Verify the installation:
+
+ ```shell
+ sudo nginx-agent -v
+ ```
+
+### Installing NGINX Agent on Amazon Linux
+
+1. Install the prerequisites:
+
+ ```shell
+ sudo yum install yum-utils procps
+ ```
+
+1. To set up the yum repository for Amazon Linux 2, create the file named `/etc/yum.repos.d/nginx-agent.repo` with the following contents:
+ ```
+ [nginx-agent]
+ name=nginx agent repo
+ baseurl=http://packages.nginx.org/nginx-agent/amzn2/$releasever/$basearch/
+ gpgcheck=1
+ enabled=1
+ gpgkey=https://nginx.org/keys/nginx_signing.key
+ module_hotfixes=true
+ ```
+
+1. To install `nginx-agent`, run the following command:
+
+ ```shell
+ sudo yum install nginx-agent
+ ```
+
+1. When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it.
+
+1. Verify the installation:
+
+ ```shell
+ sudo nginx-agent -v
+ ```
+
+### Installing NGINX Agent on FreeBSD
+
+1. To setup the pkg repository create the file named `/etc/pkg/nginx-agent.conf` with the following content:
+
+ ```
+ nginx-agent: {
+ URL: pkg+http://packages.nginx.org/nginx-agent/freebsd/${ABI}/latest
+ ENABLED: true
+ MIRROR_TYPE: SRV
+ }
+ ```
+
+1. To install `nginx-agent`, run the following command:
+
+ ```shell
+ sudo pkg install nginx-agent
+ ```
+
+1. Verify the installation:
+
+ ```shell
+ sudo nginx-agent -v
+ ```
\ No newline at end of file
diff --git a/hugo/content/installation-plus.md b/hugo/content/installation-plus.md
new file mode 100644
index 000000000..0d4cae191
--- /dev/null
+++ b/hugo/content/installation-plus.md
@@ -0,0 +1,453 @@
+---
+title: "Installation from NGINX Plus Repository"
+draft: false
+description: "Learn how to install NGINX Agent from NGINX Plus repository."
+weight: 400
+toc: true
+tags: [ "docs" ]
+docs: "DOCS-1217"
+categories: ["configuration"]
+doctypes: ["task"]
+---
+
+
+## Prerequisites
+
+- An NGINX Plus subscription (purchased or trial)
+- NGINX Plus installed. Once installed, ensure it is running. If you don't have it installed already, follow these steps to install [NGINX Plus](https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-plus/)
+- A [supported operating system and architecture](../technical-specifications/#supported-distributions)
+- `root` privilege
+- Your credentials to the MyF5 Customer Portal, provided by email from F5, Inc.
+- Your NGINX Plus certificate and public key (`nginx-repo.crt` and `nginx-repo.key` files), provided by email from F5, Inc.
+
+## Configure NGINX Plus Repository for installing NGINX Agent
+
+Before you install NGINX Agent for the first time on your system, you need to set up the `nginx-agent` packages repository. Afterward, you can install and update NGINX Agent from the repository.
+
+- [Installing NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux](#installing-nginx-agent-on-rhel-centos-rocky-linux-almalinux-and-oracle-linux)
+- [Installing NGINX Agent on Ubuntu](#installing-nginx-agent-on-ubuntu)
+- [Installing NGINX Agent on Debian](#installing-nginx-agent-on-debian)
+- [Installing NGINX Agent on SLES](#installing-nginx-agent-on-sles)
+- [Installing NGINX Agent on Alpine Linux](#installing-nginx-agent-on-alpine-linux)
+- [Installing NGINX Agent on Amazon Linux](#installing-nginx-agent-on-amazon-linux)
+- [Installing NGINX Agent on FreeBSD](#installing-nginx-agent-on-freebsd)
+
+### Installing NGINX Agent on RHEL, CentOS, Rocky Linux, AlmaLinux, and Oracle Linux
+
+1. Create the `/etc/ssl/nginx` directory:
+
+ ```shell
+ sudo mkdir -p /etc/ssl/nginx
+ ```
+
+1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files.
+
+1. Copy the files to the `/etc/ssl/nginx/` directory:
+
+ ```shell
+ sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/
+ ```
+
+1. Install the prerequisites:
+
+ ```shell
+ sudo yum install yum-utils procps
+ ```
+
+1. Set up the yum repository by creating the file `nginx-agent.repo` in `/etc/yum.repos.d`, for example using `vi`:
+
+ ```shell
+ sudo vi /etc/yum.repos.d/nginx-agent.repo
+ ```
+
+1. Add the following lines to `nginx-agent.repo`:
+
+ ```
+ [nginx-agent]
+ name=nginx agent repo
+ baseurl=https://pkgs.nginx.com/nginx-agent/centos/$releasever/$basearch/
+ sslclientcert=/etc/ssl/nginx/nginx-repo.crt
+ sslclientkey=/etc/ssl/nginx/nginx-repo.key
+ gpgcheck=0
+ enabled=1
+ ```
+
+1. To install `nginx-agent`, run the following command:
+
+ ```shell
+ sudo yum install nginx-agent
+ ```
+
+ When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it.
+
+1. Verify the installation:
+
+ ```shell
+ sudo nginx-agent -v
+ ```
+
+### Installing NGINX Agent on Ubuntu
+
+1. Create the `/etc/ssl/nginx` directory:
+
+ ```shell
+ sudo mkdir -p /etc/ssl/nginx
+ ```
+
+1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files.
+
+1. Copy the files to the `/etc/ssl/nginx/` directory:
+
+ ```shell
+ sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/
+ ```
+
+1. Install the prerequisites:
+
+ ```shell
+ sudo apt-get install apt-transport-https lsb-release ca-certificates wget gnupg2 ubuntu-keyring
+ ```
+
+1. Download and add [NGINX signing key](https://cs.nginx.com/static/keys/nginx_signing.key):
+
+ ```shell
+ wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
+ ```
+
+1. Create `apt` configuration `/etc/apt/apt.conf.d/90pkgs-nginx`:
+
+ ```
+ Acquire::https::pkgs.nginx.com::Verify-Peer "true";
+ Acquire::https::pkgs.nginx.com::Verify-Host "true";
+ Acquire::https::pkgs.nginx.com::SslCert "/etc/ssl/nginx/nginx-repo.crt";
+ Acquire::https::pkgs.nginx.com::SslKey "/etc/ssl/nginx/nginx-repo.key";
+ ```
+
+1. Add the `nginx-agent` repository:
+
+ ```shell
+ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/nginx-agent/ubuntu/ `lsb_release -cs` agent" \
+ | sudo tee /etc/apt/sources.list.d/nginx-agent.list
+ ```
+
+1. To install `nginx-agent`, run the following commands:
+
+ ```shell
+ sudo apt update
+ sudo apt install nginx-agent
+ ```
+
+1. Verify the installation:
+
+ ```shell
+ sudo nginx-agent -v
+ ```
+
+
+### Installing NGINX Agent on Debian
+
+1. Create the `/etc/ssl/nginx` directory:
+
+ ```shell
+ sudo mkdir -p /etc/ssl/nginx
+ ```
+
+1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files.
+
+1. Copy the files to the `/etc/ssl/nginx/` directory:
+
+ ```shell
+ sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/
+ ```
+
+1. Install the prerequisites:
+
+ ```shell
+ sudo apt install curl gnupg2 ca-certificates lsb-release debian-archive-keyring
+ ```
+
+1. Add the `nginx-agent` repository:
+
+ ```shell
+ echo "deb https://pkgs.nginx.com/nginx-agent/debian/ `lsb_release -cs` agent" \
+ | sudo tee /etc/apt/sources.list.d/nginx-agent.list
+ ```
+
+1. Create apt configuration `/etc/apt/apt.conf.d/90pkgs-nginx`:
+
+ ```
+ Acquire::https::pkgs.nginx.com::Verify-Peer "true";
+ Acquire::https::pkgs.nginx.com::Verify-Host "true";
+ Acquire::https::pkgs.nginx.com::SslCert "/etc/ssl/nginx/nginx-repo.crt";
+ Acquire::https::pkgs.nginx.com::SslKey "/etc/ssl/nginx/nginx-repo.key";
+ ```
+
+1. To install `nginx-agent`, run the following commands:
+
+ ```shell
+ sudo apt update
+ sudo apt install nginx-agent
+ ```
+
+1. Verify the installation:
+
+ ```shell
+ sudo nginx-agent -v
+ ```
+
+### Installing NGINX Agent on SLES
+
+1. Create the `/etc/ssl/nginx` directory:
+
+ ```shell
+ sudo mkdir -p /etc/ssl/nginx
+ ```
+
+1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files.
+
+1. Copy the files to the `/etc/ssl/nginx/` directory:
+
+ ```shell
+ sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/
+ ```
+
+1. Create a file bundle of the certificate and key:
+
+ ```shell
+ cat /etc/ssl/nginx/nginx-repo.crt /etc/ssl/nginx/nginx-repo.key > /etc/ssl/nginx/nginx-repo-bundle.crt
+ ```
+
+1. Install the prerequisites:
+
+ ```shell
+ sudo zypper install curl ca-certificates gpg2 gawk
+ ```
+
+1. To set up the zypper repository for `nginx-agent` packages, run the following command:
+
+ ```shell
+ sudo zypper addrepo --refresh --check \
+ 'https://pkgs.nginx.com/nginx-agent/sles/$releasever_major?ssl_clientcert=/etc/ssl/nginx/nginx-repo-bundle.crt&ssl_verify=peer' nginx-agent
+ ```
+
+1. Next, import an official NGINX signing key so `zypper`/`rpm` can verify the package's authenticity. Fetch the key:
+
+ ```shell
+ curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key
+ ```
+
+1. Verify that the downloaded file contains the proper key:
+
+ ```shell
+ gpg --with-fingerprint --dry-run --quiet --no-keyring --import --import-options import-show /tmp/nginx_signing.key
+ ```
+
+1. The output should contain the full fingerprint `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62` as follows:
+
+ ```
+ pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14]
+ 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62
+ uid nginx signing key
+ ```
+
+1. Finally, import the key to the rpm database:
+
+ ```shell
+ sudo rpmkeys --import /tmp/nginx_signing.key
+ ```
+
+1. To install `nginx-agent`, run the following command:
+
+ ```shell
+ sudo zypper install nginx-agent
+ ```
+
+1. Verify the installation:
+
+ ```shell
+ sudo nginx-agent -v
+ ```
+
+### Installing NGINX Agent on Alpine Linux
+
+1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files.
+
+1. Copy the files to the `/etc/apk/` directory:
+
+ ```shell
+ sudo cp nginx-repo.key /etc/apk/cert.key
+ sudo cp nginx-repo.crt /etc/apk/cert.pem
+ ```
+
+1. Install the prerequisites:
+
+ ```shell
+ sudo apk add openssl curl ca-certificates
+ ```
+
+1. To set up the apk repository for `nginx-agent` packages, run the following command:
+
+ ```shell
+ printf "%s%s%s%s\n" \
+ "@nginx-agent " \
+ "https://pkgs.nginx.com/nginx-agent/alpine/v" \
+ `grep -o -E '^[0-9]+\.[0-9]+' /etc/alpine-release` \
+ "/main" \
+ | sudo tee -a /etc/apk/repositories
+ ```
+
+1. Next, import an official NGINX signing key so apk can verify the package's authenticity. Fetch the key:
+
+ ```shell
+ curl -o /tmp/nginx_signing.rsa.pub https://nginx.org/keys/nginx_signing.rsa.pub
+ ```
+
+1. Verify that downloaded file contains the proper key:
+
+ ```shell
+ openssl rsa -pubin -in /tmp/nginx_signing.rsa.pub -text -noout
+ ```
+
+ The output should contain the following modulus:
+
+ ```
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:fe:14:f6:0a:1a:b8:86:19:fe:cd:ab:02:9f:58:
+ 2f:37:70:15:74:d6:06:9b:81:55:90:99:96:cc:70:
+ 5c:de:5b:e8:4c:b2:0c:47:5b:a8:a2:98:3d:11:b1:
+ f6:7d:a0:46:df:24:23:c6:d0:24:52:67:ba:69:ab:
+ 9a:4a:6a:66:2c:db:e1:09:f1:0d:b2:b0:e1:47:1f:
+ 0a:46:ac:0d:82:f3:3c:8d:02:ce:08:43:19:d9:64:
+ 86:c4:4e:07:12:c0:5b:43:ba:7d:17:8a:a3:f0:3d:
+ 98:32:b9:75:66:f4:f0:1b:2d:94:5b:7c:1c:e6:f3:
+ 04:7f:dd:25:b2:82:a6:41:04:b7:50:93:94:c4:7c:
+ 34:7e:12:7c:bf:33:54:55:47:8c:42:94:40:8e:34:
+ 5f:54:04:1d:9e:8c:57:48:d4:b0:f8:e4:03:db:3f:
+ 68:6c:37:fa:62:14:1c:94:d6:de:f2:2b:68:29:17:
+ 24:6d:f7:b5:b3:18:79:fd:31:5e:7f:4c:be:c0:99:
+ 13:cc:e2:97:2b:dc:96:9c:9a:d0:a7:c5:77:82:67:
+ c9:cb:a9:e7:68:4a:e1:c5:ba:1c:32:0e:79:40:6e:
+ ef:08:d7:a3:b9:5d:1a:df:ce:1a:c7:44:91:4c:d4:
+ 99:c8:88:69:b3:66:2e:b3:06:f1:f4:22:d7:f2:5f:
+ ab:6d
+ Exponent: 65537 (0x10001)
+ ```
+
+1. Finally, move the key to apk trusted keys storage:
+
+ ```shell
+ sudo mv /tmp/nginx_signing.rsa.pub /etc/apk/keys/
+ ```
+
+1. To install `nginx-agent`, run the following command:
+
+ ```shell
+ sudo apk add nginx-agent@nginx-agent
+ ```
+
+1. Verify the installation:
+
+ ```shell
+ sudo nginx-agent -v
+ ```
+
+### Installing NGINX Agent on Amazon Linux
+
+1. Create the `/etc/ssl/nginx` directory:
+
+ ```shell
+ sudo mkdir -p /etc/ssl/nginx
+ ```
+
+1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files.
+
+1. Copy the `nginx-repo.crt` and `nginx-repo.key` files to the `/etc/ssl/nginx/` directory:
+
+ ```shell
+ sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/
+ ```
+
+1. Install the prerequisites:
+
+ ```shell
+ sudo yum install yum-utils procps ca-certificates
+ ```
+
+1. To set up the yum repository for Amazon Linux 2, create the file named `/etc/yum.repos.d/nginx-agent.repo` with the following contents:
+
+ ```
+ [nginx-agent]
+ name=nginx-agent repo
+ baseurl=https://pkgs.nginx.com/nginx-agent/amzn2/$releasever/$basearch
+ sslclientcert=/etc/ssl/nginx/nginx-repo.crt
+ sslclientkey=/etc/ssl/nginx/nginx-repo.key
+ gpgcheck=0
+ enabled=1
+ ```
+
+1. To install `nginx-agent`, run the following command:
+
+ ```shell
+ sudo yum install nginx-agent
+ ```
+
+1. When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it.
+
+1. Verify the installation:
+
+ ```shell
+ sudo nginx-agent -v
+ ```
+
+### Installing NGINX Agent on FreeBSD
+
+1. Create the `/etc/ssl/nginx` directory:
+
+ ```shell
+ sudo mkdir -p /etc/ssl/nginx
+ ```
+
+1. Log in to [MyF5 Customer Portal](https://account.f5.com/myf5/) and download your `nginx-repo.crt` and `nginx-repo.key` files.
+
+1. Copy the files to the `/etc/ssl/nginx/` directory:
+
+ ```shell
+ sudo cp nginx-repo.crt nginx-repo.key /etc/ssl/nginx/
+ ```
+
+1. Install the prerequisite `ca_root_nss` package:
+
+ ```shell
+ sudo pkg install ca_root_nss
+ ```
+
+1. To setup the pkg repository create the file named `/etc/pkg/nginx-agent.conf` with the following content:
+
+ ```
+ nginx-agent: {
+ URL: pkg+https://pkgs.nginx.com/nginx-agent/freebsd/${ABI}/latest
+ ENABLED: yes
+ MIRROR_TYPE: SRV
+ }
+ ```
+
+1. Add the following lines to the `/usr/local/etc/pkg.conf` file:
+
+ ```
+ PKG_ENV: { SSL_NO_VERIFY_PEER: "1",
+ SSL_CLIENT_CERT_FILE: "/etc/ssl/nginx/nginx-repo.crt",
+ SSL_CLIENT_KEY_FILE: "/etc/ssl/nginx/nginx-repo.key" }
+ ```
+
+1. To install `nginx-agent`, run the following command:
+
+ ```shell
+ sudo pkg install nginx-agent
+ ```
+
+1. Verify the installation:
+
+ ```shell
+ sudo nginx-agent -v
+ ```
diff --git a/hugo/content/technical-specifications.md b/hugo/content/technical-specifications.md
index 74d779281..38d3e8ff9 100644
--- a/hugo/content/technical-specifications.md
+++ b/hugo/content/technical-specifications.md
@@ -2,7 +2,7 @@
title: "Technical Specifications"
draft: false
description: "This document describes the requirements for NGINX Agent."
-weight: 500
+weight: 800
toc: true
tags: [ "docs" ]
docs: "DOCS-1092"
@@ -23,6 +23,7 @@ Alpine Linux
- 3.14 (x86_64, aarch64)
- 3.15 (x86_64, aarch64)
- 3.16 (x86_64, aarch64)
+- 3.17 (x86_64, aarch64)
Amazon Linux 2
- LTS (x86_64, aarch64)
@@ -39,12 +40,13 @@ FreeBSD
Oracle Linux
- 7.4+ (x86_64)
-- 8.1+ (x86_64, aarch64)
+- 8.1+ (x86_64)
+- 9 (x86_64)
Red Hat Enterprise Linux (RHEL)
-- 7.4+ (x86_64)
-- 8.1+ (x86_64)
-- 9.0+ (x86_64)
+- 7.4+ (x86_64, aarch64)
+- 8.1+ (x86_64, aarch64)
+- 9.0+ (x86_64, aarch64)
Rocky Linux
- 8 (x86_64, aarch64)
diff --git a/hugo/content/upgrading.md b/hugo/content/upgrading.md
new file mode 100644
index 000000000..54ef81b78
--- /dev/null
+++ b/hugo/content/upgrading.md
@@ -0,0 +1,50 @@
+---
+title: "Upgrade NGINX Agent Package"
+draft: false
+description: "Learn how to upgrade NGINX Agent"
+weight: 500
+toc: true
+tags: [ "docs" ]
+docs: "DOCS-1227"
+categories: ["configuration"]
+doctypes: ["task"]
+---
+
+## Upgrade the NGINX Agent
+
+To upgrade the NGINX Agent, take the following steps:
+
+1. Open an SSH connection to the server where you’ve installed the NGINX Agent and log in.
+
+1. Make a backup copy of the following locations to ensure that you can successfully recover if the upgrade has issues:
+
+ - `/etc/nginx-agent`
+ - `config_dirs` values for any configuration specified in `/etc/nginx-agent/nginx-agent.conf`
+
+1. Stop the NGINX Agent:
+
+ ```shell
+ sudo systemctl stop nginx-agent
+ ```
+
+1. Install the updated version of the NGINX Agent:
+
+ - CentOS, RHEL, RPM-Based
+
+ ```shell
+ sudo yum -y makecache
+ sudo yum update -y nginx-agent
+ ```
+
+ - Debian, Ubuntu, Deb-Based
+
+ ```shell
+ sudo apt-get update
+ sudo apt-get install -y --only-upgrade nginx-agent -o Dpkg::Options::="--force-confold"
+ ```
+
+1. Start the NGINX Agent:
+
+ ```shell
+ sudo systemctl start nginx-agent
+ ```
\ No newline at end of file
diff --git a/main.go b/main.go
index 2c802eb0a..7ab4fbfb3 100644
--- a/main.go
+++ b/main.go
@@ -17,11 +17,7 @@ import (
"syscall"
"time"
- "github.com/google/uuid"
- log "github.com/sirupsen/logrus"
- "github.com/spf13/cobra"
- "google.golang.org/grpc"
-
+ agent_config "github.com/nginx/agent/sdk/v2/agent/config"
"github.com/nginx/agent/sdk/v2/client"
sdkGRPC "github.com/nginx/agent/sdk/v2/grpc"
"github.com/nginx/agent/v2/src/core"
@@ -30,7 +26,10 @@ import (
"github.com/nginx/agent/v2/src/extensions"
"github.com/nginx/agent/v2/src/plugins"
- agent_config "github.com/nginx/agent/sdk/v2/agent/config"
+ "github.com/google/uuid"
+ log "github.com/sirupsen/logrus"
+ "github.com/spf13/cobra"
+ "google.golang.org/grpc"
)
var (
@@ -131,7 +130,9 @@ func handleSignals(
)
log.Debugf("Sending agent stopped event: %v", stopCmd)
- if err := cmder.Send(ctx, client.MessageFromCommand(stopCmd)); err != nil {
+ if cmder == nil {
+ log.Warn("Command channel not configured. Skipping sending AgentStopped event")
+ } else if err := cmder.Send(ctx, client.MessageFromCommand(stopCmd)); err != nil {
log.Errorf("Error sending AgentStopped event to command channel: %v", err)
}
@@ -148,7 +149,7 @@ func handleSignals(
func createGrpcClients(ctx context.Context, loadedConfig *config.Config) (client.Controller, client.Commander, client.MetricReporter) {
if !loadedConfig.IsGrpcServerConfigured() {
- log.Infof("GRPC clients not created")
+ log.Info("GRPC clients not created due to missing server config")
return nil, nil, nil
}
@@ -199,9 +200,14 @@ func loadPlugins(commander client.Commander, binary *core.NginxBinaryType, env *
if commander != nil {
corePlugins = append(corePlugins,
plugins.NewCommander(commander, loadedConfig),
- plugins.NewFileWatcher(loadedConfig, env),
- plugins.NewFileWatchThrottle(),
)
+
+ if loadedConfig.IsFeatureEnabled(agent_config.FeatureFileWatcher) {
+ corePlugins = append(corePlugins,
+ plugins.NewFileWatcher(loadedConfig, env),
+ plugins.NewFileWatchThrottle(),
+ )
+ }
}
if reporter != nil {
@@ -213,22 +219,41 @@ func loadPlugins(commander client.Commander, binary *core.NginxBinaryType, env *
corePlugins = append(corePlugins,
plugins.NewConfigReader(loadedConfig),
plugins.NewNginx(commander, binary, env, loadedConfig),
- plugins.NewOneTimeRegistration(loadedConfig, binary, env, sdkGRPC.NewMessageMeta(uuid.NewString()), version),
- plugins.NewMetrics(loadedConfig, env, binary),
- plugins.NewMetricsThrottle(loadedConfig, env),
- plugins.NewDataPlaneStatus(loadedConfig, sdkGRPC.NewMessageMeta(uuid.NewString()), binary, env, version),
- plugins.NewProcessWatcher(env, binary),
plugins.NewExtensions(loadedConfig, env),
- plugins.NewEvents(loadedConfig, env, sdkGRPC.NewMessageMeta(uuid.NewString()), binary),
+ plugins.NewFeatures(commander, loadedConfig, env, binary, version),
)
- if loadedConfig.AgentAPI.Port != 0 {
+ if loadedConfig.IsFeatureEnabled(agent_config.FeatureRegistration) {
+ corePlugins = append(corePlugins, plugins.NewOneTimeRegistration(loadedConfig, binary, env, sdkGRPC.NewMessageMeta(uuid.NewString()), version))
+ }
+
+ if loadedConfig.IsFeatureEnabled(agent_config.FeatureMetrics) || (len(loadedConfig.Nginx.NginxCountingSocket) > 0 && loadedConfig.IsFeatureEnabled(agent_config.FeatureNginxCounting)) {
+ corePlugins = append(corePlugins, plugins.NewMetrics(loadedConfig, env, binary))
+ }
+
+ if loadedConfig.IsFeatureEnabled(agent_config.FeatureMetricsThrottle) {
+ corePlugins = append(corePlugins, plugins.NewMetricsThrottle(loadedConfig, env))
+ }
+
+ if loadedConfig.IsFeatureEnabled(agent_config.FeatureDataPlaneStatus) {
+ corePlugins = append(corePlugins, plugins.NewDataPlaneStatus(loadedConfig, sdkGRPC.NewMessageMeta(uuid.NewString()), binary, env, version))
+ }
+
+ if loadedConfig.IsFeatureEnabled(agent_config.FeatureProcessWatcher) {
+ corePlugins = append(corePlugins, plugins.NewProcessWatcher(env, binary))
+ }
+
+ if loadedConfig.IsFeatureEnabled(agent_config.FeatureActivityEvents) {
+ corePlugins = append(corePlugins, plugins.NewEvents(loadedConfig, env, sdkGRPC.NewMessageMeta(uuid.NewString()), binary))
+ }
+
+ if loadedConfig.AgentAPI.Port != 0 && loadedConfig.IsFeatureEnabled(agent_config.FeatureAgentAPI) {
corePlugins = append(corePlugins, plugins.NewAgentAPI(loadedConfig, env, binary))
} else {
log.Info("Agent API not configured")
}
- if len(loadedConfig.Nginx.NginxCountingSocket) > 0 {
+ if len(loadedConfig.Nginx.NginxCountingSocket) > 0 && loadedConfig.IsFeatureEnabled(agent_config.FeatureNginxCounting) {
corePlugins = append(corePlugins, plugins.NewNginxCounter(loadedConfig, binary, env))
}
diff --git a/nginx-agent.conf b/nginx-agent.conf
index adee227ab..da4660cb8 100644
--- a/nginx-agent.conf
+++ b/nginx-agent.conf
@@ -3,8 +3,8 @@
#
# Configuration file for NGINX Agent.
#
-# This file is to track agent configuration values that are meant to be statically set. There
-# are additional agent configuration values that are set via the API and agent install script
+# This file is to track NGINX Agent configuration values that are meant to be statically set. There
+# are additional NGINX Agent configuration values that are set via the API and NGINX Agent install script
# which can be found in /var/lib/nginx-agent/agent-dynamic.conf.
log:
@@ -20,7 +20,7 @@ nginx:
dataplane:
status:
- # poll interval for data plane status - the frequency the agent will query the dataplane for changes
+ # poll interval for data plane status - the frequency the NGINX Agent will query the dataplane for changes
poll_interval: 30s
# report interval for data plane status - the maximum duration to wait before syncing dataplane information if no updates have being observed
report_interval: 24h
@@ -36,6 +36,13 @@ metrics:
# path to aux file dirs can also be added
config_dirs: "/etc/nginx:/usr/local/etc/nginx:/usr/share/nginx/modules:/etc/nms"
-api:
- # default port for Agent API, this is for the server configuration of the REST API
- port: 8081
+ # api:
+ # The port at which NGINX Agent accepts remote connections
+ # The API address and port allow for remote management of NGINX and NGINX Agent
+ #
+ # ~~~ WARNING ~~~
+ # Set API address to allow remote management
+ # host: 127.0.0.1
+ #
+ # Set this value to a secure port number to prevent information leaks.
+ # port: 8038
diff --git a/scripts/docker/nginx-plus/almalinux/Dockerfile b/scripts/docker/nginx-plus/almalinux/Dockerfile
new file mode 100644
index 000000000..4afb02b25
--- /dev/null
+++ b/scripts/docker/nginx-plus/almalinux/Dockerfile
@@ -0,0 +1,60 @@
+ARG BASE_IMAGE
+FROM ${BASE_IMAGE} as install
+LABEL maintainer="NGINX Agent Maintainers "
+
+ARG BASE_IMAGE
+ARG PACKAGES_REPO
+ARG OS_RELEASE
+ARG OS_VERSION
+
+WORKDIR /agent
+COPY ./scripts/docker/entrypoint.sh /agent/entrypoint.sh
+COPY ./nginx-agent.conf /agent/nginx-agent.conf
+
+RUN --mount=type=secret,id=nginx-crt,dst=/nginx-repo.crt \
+ --mount=type=secret,id=nginx-key,dst=/nginx-repo.key \
+ set -x \
+ && mkdir -p /etc/ssl/nginx \
+ && cat /nginx-repo.crt > /etc/ssl/nginx/nginx-repo.crt \
+ && cat /nginx-repo.key > /etc/ssl/nginx/nginx-repo.key \
+ && yum install -y --setopt=tsflags=nodocs wget ca-certificates bind-utils wget bind-utils vim-minimal shadow-utils procps \
+ && groupadd --system --gid 101 nginx \
+ && adduser -g nginx --system --no-create-home --home /nonexistent --shell /bin/false --uid 101 nginx \
+ && usermod -s /sbin/nologin nginx \
+ && usermod -L nginx \
+ && printf "[nginx-plus] \n\
+name=nginx-plus repo \n\
+baseurl=https://$PACKAGES_REPO/plus/centos/$OS_VERSION/\$basearch \n\
+sslclientcert=/etc/ssl/nginx/nginx-repo.crt \n\
+sslclientkey=/etc/ssl/nginx/nginx-repo.key \n\
+gpgcheck=1 \n\
+enabled=1 \n\
+sslverify=true \n\
+gpgkey=https://nginx.org/keys/nginx_signing.key" >> /etc/yum.repos.d/nginx-plus.repo \
+ && printf "[nginx-agent] \n\
+name=nginx-agent repo \n\
+baseurl=https://$PACKAGES_REPO/nginx-agent/centos/$OS_VERSION/\$basearch \n\
+sslclientcert=/etc/ssl/nginx/nginx-repo.crt \n\
+sslclientkey=/etc/ssl/nginx/nginx-repo.key \n\
+gpgcheck=1 \n\
+enabled=1 \n\
+sslverify=true \n\
+gpgkey=https://nginx.org/keys/nginx_signing.key">> /etc/yum.repos.d/nginx-agent.repo \
+ && nginxPackages=" \
+ nginx-agent \
+ nginx-plus \
+ " \
+ && yum install -y $nginxPackages \
+ && yum clean all \
+ && rm -rf /var/cache/yum /etc/yum.repos.d/* /etc/ssl/nginx
+
+FROM install as runtime
+
+COPY --from=install /agent/entrypoint.sh /agent/entrypoint.sh
+COPY --from=install /agent/nginx-agent.conf /etc/nginx-agent/nginx-agent.conf
+
+RUN chmod +x /agent/entrypoint.sh
+STOPSIGNAL SIGTERM
+EXPOSE 80 443
+
+ENTRYPOINT ["/agent/entrypoint.sh"]
diff --git a/scripts/docker/nginx-plus/debian/Dockerfile b/scripts/docker/nginx-plus/debian/Dockerfile
index bbf3dc156..3ac100539 100644
--- a/scripts/docker/nginx-plus/debian/Dockerfile
+++ b/scripts/docker/nginx-plus/debian/Dockerfile
@@ -17,7 +17,7 @@ RUN --mount=type=secret,id=nginx-crt,dst=/nginx-repo.crt \
&& apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y \
ca-certificates \
- gnupg1 \
+ gnupg \
lsb-release \
&& \
NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \
@@ -52,7 +52,10 @@ RUN --mount=type=secret,id=nginx-crt,dst=/nginx-repo.crt \
$nginxPackages \
curl \
gettext-base \
- && apt-get remove --purge -y lsb-release \
+ && apt-get autoremove --purge -y \
+ gnupg \
+ lsb-release \
+ && rm -rf /root/.gnupg \
&& apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-plus.list \
&& rm -rf /etc/apt/apt.conf.d/90nginx /etc/ssl/nginx
diff --git a/scripts/docker/nginx-plus/rockylinux/Dockerfile b/scripts/docker/nginx-plus/rockylinux/Dockerfile
new file mode 100644
index 000000000..4afb02b25
--- /dev/null
+++ b/scripts/docker/nginx-plus/rockylinux/Dockerfile
@@ -0,0 +1,60 @@
+ARG BASE_IMAGE
+FROM ${BASE_IMAGE} as install
+LABEL maintainer="NGINX Agent Maintainers "
+
+ARG BASE_IMAGE
+ARG PACKAGES_REPO
+ARG OS_RELEASE
+ARG OS_VERSION
+
+WORKDIR /agent
+COPY ./scripts/docker/entrypoint.sh /agent/entrypoint.sh
+COPY ./nginx-agent.conf /agent/nginx-agent.conf
+
+RUN --mount=type=secret,id=nginx-crt,dst=/nginx-repo.crt \
+ --mount=type=secret,id=nginx-key,dst=/nginx-repo.key \
+ set -x \
+ && mkdir -p /etc/ssl/nginx \
+ && cat /nginx-repo.crt > /etc/ssl/nginx/nginx-repo.crt \
+ && cat /nginx-repo.key > /etc/ssl/nginx/nginx-repo.key \
+ && yum install -y --setopt=tsflags=nodocs wget ca-certificates bind-utils wget bind-utils vim-minimal shadow-utils procps \
+ && groupadd --system --gid 101 nginx \
+ && adduser -g nginx --system --no-create-home --home /nonexistent --shell /bin/false --uid 101 nginx \
+ && usermod -s /sbin/nologin nginx \
+ && usermod -L nginx \
+ && printf "[nginx-plus] \n\
+name=nginx-plus repo \n\
+baseurl=https://$PACKAGES_REPO/plus/centos/$OS_VERSION/\$basearch \n\
+sslclientcert=/etc/ssl/nginx/nginx-repo.crt \n\
+sslclientkey=/etc/ssl/nginx/nginx-repo.key \n\
+gpgcheck=1 \n\
+enabled=1 \n\
+sslverify=true \n\
+gpgkey=https://nginx.org/keys/nginx_signing.key" >> /etc/yum.repos.d/nginx-plus.repo \
+ && printf "[nginx-agent] \n\
+name=nginx-agent repo \n\
+baseurl=https://$PACKAGES_REPO/nginx-agent/centos/$OS_VERSION/\$basearch \n\
+sslclientcert=/etc/ssl/nginx/nginx-repo.crt \n\
+sslclientkey=/etc/ssl/nginx/nginx-repo.key \n\
+gpgcheck=1 \n\
+enabled=1 \n\
+sslverify=true \n\
+gpgkey=https://nginx.org/keys/nginx_signing.key">> /etc/yum.repos.d/nginx-agent.repo \
+ && nginxPackages=" \
+ nginx-agent \
+ nginx-plus \
+ " \
+ && yum install -y $nginxPackages \
+ && yum clean all \
+ && rm -rf /var/cache/yum /etc/yum.repos.d/* /etc/ssl/nginx
+
+FROM install as runtime
+
+COPY --from=install /agent/entrypoint.sh /agent/entrypoint.sh
+COPY --from=install /agent/nginx-agent.conf /etc/nginx-agent/nginx-agent.conf
+
+RUN chmod +x /agent/entrypoint.sh
+STOPSIGNAL SIGTERM
+EXPOSE 80 443
+
+ENTRYPOINT ["/agent/entrypoint.sh"]
diff --git a/scripts/packages/manifest b/scripts/packages/manifest
index 8b5a1e6b7..957c0f6f2 100644
--- a/scripts/packages/manifest
+++ b/scripts/packages/manifest
@@ -2,7 +2,7 @@ name: nginx-agent
version: "${VERSION}"
origin: www/nginx-agent
comment: "Monitors NGINX"
-desc: "Unified agent for various NGINX control plane services."
+desc: "NGINX Agent for various NGINX control plane services."
maintainer: "NGINX Inc. "
www: https://nginx.com
prefix: /
\ No newline at end of file
diff --git a/scripts/packages/packager/local-entrypoint.sh b/scripts/packages/packager/local-entrypoint.sh
index 1a764afab..792cf342d 100644
--- a/scripts/packages/packager/local-entrypoint.sh
+++ b/scripts/packages/packager/local-entrypoint.sh
@@ -13,7 +13,7 @@ mkdir -p /staging/usr/local/etc/rc.d
cp nginx-agent.conf /staging/usr/local/etc/nginx-agent
cp scripts/packages/nginx-agent /staging/usr/local/etc/rc.d
cp scripts/packages/preinstall.sh /staging/+PRE_INSTALL
-cp scripts/packages/postremove.sh /staging/+PRE_DEINSTALL
+cp scripts/packages/postremove.sh /staging/+POST_DEINSTALL
cp scripts/packages/postinstall.sh /staging/+POST_INSTALL
cp scripts/packages/plist /staging
cp build/nginx-agent /staging/usr/local/bin
diff --git a/scripts/packages/packager/signed-entrypoint.sh b/scripts/packages/packager/signed-entrypoint.sh
index cfd90d56b..641ac1619 100644
--- a/scripts/packages/packager/signed-entrypoint.sh
+++ b/scripts/packages/packager/signed-entrypoint.sh
@@ -18,7 +18,7 @@ mkdir -p staging/usr/local/etc/rc.d
cp nginx-agent.conf staging/usr/local/etc/nginx-agent
cp scripts/packages/nginx-agent staging/usr/local/etc/rc.d
cp scripts/packages/preinstall.sh staging/+PRE_INSTALL
-cp scripts/packages/postremove.sh staging/+PRE_DEINSTALL
+cp scripts/packages/postremove.sh staging/+POST_DEINSTALL
cp scripts/packages/postinstall.sh staging/+POST_INSTALL
cp scripts/packages/plist staging
cp build/nginx-agent staging/usr/local/bin
diff --git a/scripts/packages/postinstall.sh b/scripts/packages/postinstall.sh
index b7c92f499..36cadc71e 100755
--- a/scripts/packages/postinstall.sh
+++ b/scripts/packages/postinstall.sh
@@ -183,8 +183,8 @@ add_default_config_file() {
#
# Configuration file for NGINX Agent.
#
-# This file is to track agent configuration values that are meant to be statically set. There
-# are additional agent configuration values that are set via the API and agent install script
+# This file is to track NGINX Agent configuration values that are meant to be statically set. There
+# are additional NGINX Agent configuration values that are set via the API and NGINX Agent install script
# which can be found in /var/lib/nginx-agent/agent-dynamic.conf.
# specify the server grpc port to connect to
@@ -224,7 +224,7 @@ nginx:
dataplane:
status:
- # poll interval for data plane status - the frequency the agent will query the dataplane for changes
+ # poll interval for data plane status - the frequency the NGINX Agent will query the dataplane for changes
poll_interval: 30s
# report interval for data plane status - the maximum duration to wait before syncing dataplane information if no updates have being observed
report_interval: 24h
@@ -241,7 +241,7 @@ metrics:
config_dirs: "/etc/nginx:/usr/local/etc/nginx:/usr/share/nginx/modules:/etc/nms"
api:
- # default port for Agent API, this is for the server configuration of the REST API
+ # default port for NGINX Agent API, this is for the server configuration of the REST API
port: 8081
EOF
printf "PostInstall: Updating file permissions for nginx-agent.conf to 0640\n"
@@ -303,4 +303,3 @@ summary() {
upgrade_config_file
summary
}
-
diff --git a/scripts/packages/postremove.sh b/scripts/packages/postremove.sh
index 75e8379dc..604ea2e67 100755
--- a/scripts/packages/postremove.sh
+++ b/scripts/packages/postremove.sh
@@ -7,23 +7,13 @@ if [ "$ID" = "freebsd" ]; then
echo "Stop and remove nginx-agent service"
service nginx-agent onestop >/dev/null 2>&1 || true
sysrc -x nginx_agent_enable >/dev/null 2>&1 || true
- echo "Removing /usr/local/etc/nginx-agent directory"
- rm -rf "/usr/local/etc/nginx-agent"
- echo "Removing /var/db/nginx-agent directory"
- rm -rf "/var/db/nginx-agent"
elif command -V systemctl >/dev/null 2>&1; then
echo "Stop and disable nginx-agent service"
systemctl stop nginx-agent >/dev/null 2>&1 || true
systemctl disable nginx-agent >/dev/null 2>&1 || true
echo "Running daemon-reload"
systemctl daemon-reload || true
- echo "Removing /etc/nginx-agent directory"
- rm -rf "/etc/nginx-agent"
- echo "Removing /var/lib/nginx-agent directory"
- rm -rf "/var/lib/nginx-agent"
fi
echo "Removing /var/run/nginx-agent directory"
rm -rf "/var/run/nginx-agent"
-echo "Removing /var/log/nginx-agent directory"
-rm -rf "/var/log/nginx-agent"
diff --git a/scripts/packages/preinstall.sh b/scripts/packages/preinstall.sh
index e1238a329..4b0b31d02 100644
--- a/scripts/packages/preinstall.sh
+++ b/scripts/packages/preinstall.sh
@@ -42,15 +42,15 @@ AGENT_DYNAMIC_CONFIG_COMMENT="#
#
# Dynamic configuration file for NGINX Agent.
#
-# The purpose of this file is to track agent configuration
-# values that can be dynamically changed via the API and the agent install script.
+# The purpose of this file is to track NGINX Agent configuration
+# values that can be dynamically changed via the API and the NGINX Agent install script.
# You may edit this file, but API calls that modify the tags on this system will
# overwrite the tag values in this file.
#
-# The agent configuration values that API calls can modify are as follows:
+# The NGINX Agent configuration values that API calls can modify are as follows:
# - tags
#
-# The agent configuration value(s) that the agent install script can modify are as follows:
+# The NGINX Agent configuration value(s) that the NGINX Agent install script can modify are as follows:
# - instance_group
"
@@ -67,8 +67,6 @@ err_exit() {
title() {
printf "\n --- NGINX Agent Package Installer --- \n\n"
- printf " --- Will install the NGINX Agent in 5 seconds ---\n"
- sleep 5
}
ensure_sudo() {
@@ -80,11 +78,13 @@ ensure_sudo() {
}
load_config_values() {
- # If the file doesn't exist attempt to create it
if [ ! -f "$AGENT_DYNAMIC_CONFIG_FILE" ]; then
- if [ -f "$OLD_DYNAMIC_CONFIG_FILE" ]; then
+ if [ -f "$OLD_DYNAMIC_CONFIG_FILE" ]; then
+ printf "Moving %s to %s\n" "$OLD_DYNAMIC_CONFIG_FILE" "$AGENT_DYNAMIC_CONFIG_FILE"
mkdir -p ${AGENT_DYNAMIC_CONFIG_DIR}
- ln "$OLD_DYNAMIC_CONFIG_FILE" "$AGENT_DYNAMIC_CONFIG_FILE"
+ mv "$OLD_DYNAMIC_CONFIG_FILE" "$AGENT_DYNAMIC_CONFIG_FILE"
+ printf "Creating symlink %s at %s\n" "$AGENT_DYNAMIC_CONFIG_FILE" "$OLD_DYNAMIC_CONFIG_FILE"
+ ln -s "$AGENT_DYNAMIC_CONFIG_FILE" "$OLD_DYNAMIC_CONFIG_FILE"
else
printf "Could not find %s ... Creating file\n" ${AGENT_DYNAMIC_CONFIG_FILE}
mkdir -p ${AGENT_DYNAMIC_CONFIG_DIR}
@@ -107,7 +107,7 @@ update_config_file() {
printf "Updating %s ...\n" "${AGENT_DYNAMIC_CONFIG_FILE}"
if [ ! -f "$AGENT_CONFIG_FILE" ]; then
- printf "Agent config file %s does not exist. Could not be updated\n" "$AGENT_CONFIG_FILE"
+ printf "NGINX Agent config file %s does not exist. Could not be updated\n" "$AGENT_CONFIG_FILE"
exit 0
fi
@@ -158,4 +158,4 @@ update_config_file() {
ensure_sudo
load_config_values
update_config_file
-}
+}
\ No newline at end of file
diff --git a/scripts/selinux/README.md b/scripts/selinux/README.md
index 3d98c61bc..f20d4a4e1 100644
--- a/scripts/selinux/README.md
+++ b/scripts/selinux/README.md
@@ -44,8 +44,8 @@ sudo ./nginx_agent.sh --update
## Debugging
* To check for policy violation look at the file `/var/log/audit/audit.log`
-* To check if agent is confined by selinux: `ps -efZ | grep nginx-agent`
+* To check if NGINX Agent is confined by selinux: `ps -efZ | grep nginx-agent`
* For debugging nginx selinux issues refer to this nginx blog: https://www.nginx.com/blog/using-nginx-plus-with-selinux
## References
-* https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/using_selinux/writing-a-custom-selinux-policy_using-selinux
+* https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/using_selinux/writing-a-custom-selinux-policy_using-selinux
\ No newline at end of file
diff --git a/scripts/tools.go b/scripts/tools.go
index bbe13450d..3df4fabba 100644
--- a/scripts/tools.go
+++ b/scripts/tools.go
@@ -16,4 +16,5 @@ import (
_ "github.com/bufbuild/buf/cmd/buf"
_ "github.com/goreleaser/nfpm/v2/cmd/nfpm"
_ "github.com/evilmartians/lefthook"
+ _ "github.com/golangci/golangci-lint/cmd/golangci-lint"
)
diff --git a/sdk/agent/config/config_helpers.go b/sdk/agent/config/config_helpers.go
index 790abe6a9..bbbc79e81 100644
--- a/sdk/agent/config/config_helpers.go
+++ b/sdk/agent/config/config_helpers.go
@@ -15,20 +15,22 @@ const (
DefaultPluginSize = 100
KeyDelimiter = "_"
- // Features
- FeaturesKey = "features"
- FeatureRegistration = FeaturesKey + KeyDelimiter + "registration"
- FeatureNginxConfig = FeaturesKey + KeyDelimiter + "nginx-config"
- FeatureNginxConfigAsync = FeaturesKey + KeyDelimiter + "nginx-config-async"
- FeatureNginxSSLConfig = FeaturesKey + KeyDelimiter + "nginx-ssl-config"
- FeatureNginxCounting = FeaturesKey + KeyDelimiter + "nginx-counting"
- FeatureMetrics = FeaturesKey + KeyDelimiter + "metrics"
- FeatureMetricsThrottle = FeaturesKey + KeyDelimiter + "metrics-throttle"
- FeatureDataPlaneStatus = FeaturesKey + KeyDelimiter + "dataplane-status"
- FeatureProcessWatcher = FeaturesKey + KeyDelimiter + "process-watcher"
- FeatureFileWatcher = FeaturesKey + KeyDelimiter + "file-watcher"
- FeatureActivityEvents = FeaturesKey + KeyDelimiter + "activity-events"
- FeatureAgentAPI = FeaturesKey + KeyDelimiter + "agent-api"
+ // viper keys used in config
+ FeaturesKey = "features"
+ FeatureRegistration = "registration"
+ // Deprecated: use nginx-config-async instead
+ FeatureNginxConfig = "nginx-config"
+ FeatureNginxConfigAsync = "nginx-config-async"
+ FeatureNginxSSLConfig = "nginx-ssl-config"
+ FeatureNginxCounting = "nginx-counting"
+ FeatureMetrics = "metrics"
+ FeatureMetricsThrottle = "metrics-throttle"
+ FeatureDataPlaneStatus = "dataplane-status"
+ FeatureProcessWatcher = "process-watcher"
+ FeatureFileWatcher = "file-watcher"
+ FeatureFileWatcherThrottle = "file-watch-throttle"
+ FeatureActivityEvents = "activity-events"
+ FeatureAgentAPI = "agent-api"
// Extensions
ExtensionsKey = "extensions"
@@ -63,10 +65,9 @@ func IsKnownExtension(extension string) bool {
func GetDefaultFeatures() []string {
return []string{
FeatureRegistration,
- FeatureNginxConfig,
+ FeatureNginxConfigAsync,
FeatureNginxSSLConfig,
FeatureNginxCounting,
- FeatureNginxConfigAsync,
FeatureMetrics,
FeatureMetricsThrottle,
FeatureDataPlaneStatus,
diff --git a/test/integration/vendor/github.com/nginx/agent/sdk/v2/backoff.go b/sdk/backoff/backoff.go
similarity index 54%
rename from test/integration/vendor/github.com/nginx/agent/sdk/v2/backoff.go
rename to sdk/backoff/backoff.go
index 939d8a1c7..f5fa9e3b0 100644
--- a/test/integration/vendor/github.com/nginx/agent/sdk/v2/backoff.go
+++ b/sdk/backoff/backoff.go
@@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
-package sdk
+package backoff
import (
"context"
@@ -19,19 +19,25 @@ const (
BACKOFF_MULTIPLIER = backoff.DefaultMultiplier
)
+type BackoffSettings struct {
+ InitialInterval time.Duration
+ MaxInterval time.Duration
+ MaxElapsedTime time.Duration
+ Multiplier float64
+ Jitter float64
+}
+
func WaitUntil(
ctx context.Context,
- initialInterval time.Duration,
- maxInterval time.Duration,
- maxElapsedTime time.Duration,
+ backoffSettings BackoffSettings,
operation backoff.Operation,
) error {
exponentialBackoff := backoff.NewExponentialBackOff()
- exponentialBackoff.InitialInterval = initialInterval
- exponentialBackoff.MaxInterval = maxInterval
- exponentialBackoff.MaxElapsedTime = maxElapsedTime
- exponentialBackoff.RandomizationFactor = BACKOFF_JITTER
- exponentialBackoff.Multiplier = BACKOFF_MULTIPLIER
+ exponentialBackoff.InitialInterval = backoffSettings.InitialInterval
+ exponentialBackoff.MaxInterval = backoffSettings.MaxInterval
+ exponentialBackoff.MaxElapsedTime = backoffSettings.MaxElapsedTime
+ exponentialBackoff.RandomizationFactor = backoffSettings.Jitter
+ exponentialBackoff.Multiplier = backoffSettings.Multiplier
expoBackoffWithContext := backoff.WithContext(exponentialBackoff, ctx)
diff --git a/sdk/backoff_test.go b/sdk/backoff/backoff_test.go
similarity index 87%
rename from sdk/backoff_test.go
rename to sdk/backoff/backoff_test.go
index b8dae6b30..f036ba60a 100644
--- a/sdk/backoff_test.go
+++ b/sdk/backoff/backoff_test.go
@@ -5,12 +5,11 @@
* LICENSE file in the root directory of this source tree.
*/
-package sdk
+package backoff
import (
"context"
"errors"
-
"testing"
"time"
@@ -88,7 +87,14 @@ func TestBackOff(t *testing.T) {
}
for _, test := range tests {
- result := WaitUntil(test.context, test.initialInterval, test.maxInterval, test.maxElapsedTime, test.operation)
+ backoff := BackoffSettings{
+ InitialInterval: test.initialInterval,
+ MaxInterval: test.maxInterval,
+ MaxElapsedTime: test.maxElapsedTime,
+ Jitter: BACKOFF_JITTER,
+ Multiplier: BACKOFF_MULTIPLIER,
+ }
+ result := WaitUntil(test.context, backoff, test.operation)
if test.expectedError {
assert.Errorf(t, result, test.name)
diff --git a/sdk/certificates.go b/sdk/certificates.go
index 0d13a03c5..34775aa04 100644
--- a/sdk/certificates.go
+++ b/sdk/certificates.go
@@ -12,7 +12,7 @@ import (
"crypto/x509"
"encoding/pem"
"fmt"
- "io/ioutil"
+ "os"
)
func LoadCertificates(certPath, keyPath string) (*tls.Certificate, *x509.CertPool, error) {
@@ -33,7 +33,7 @@ func LoadCertificates(certPath, keyPath string) (*tls.Certificate, *x509.CertPoo
}
func LoadCertificate(certPath string) (*x509.Certificate, error) {
- fileContents, err := ioutil.ReadFile(certPath)
+ fileContents, err := os.ReadFile(certPath)
if err != nil {
return nil, err
}
diff --git a/sdk/client/client.go b/sdk/client/client.go
index 7922328bd..6c79e1309 100644
--- a/sdk/client/client.go
+++ b/sdk/client/client.go
@@ -15,17 +15,11 @@ import (
"google.golang.org/grpc"
+ "github.com/nginx/agent/sdk/v2/backoff"
"github.com/nginx/agent/sdk/v2/interceptors"
"github.com/nginx/agent/sdk/v2/proto"
)
-type BackoffSettings struct {
- initialInterval time.Duration
- maxInterval time.Duration
- maxTimeout time.Duration
- sendMaxTimeout time.Duration
-}
-
type MsgClassification int
const (
@@ -35,11 +29,12 @@ const (
)
var (
- DefaultBackoffSettings = BackoffSettings{
- initialInterval: 10 * time.Second,
- maxInterval: 60 * time.Second,
- maxTimeout: 0,
- sendMaxTimeout: 2 * time.Minute,
+ DefaultBackoffSettings = backoff.BackoffSettings{
+ InitialInterval: 10 * time.Second,
+ MaxInterval: 60 * time.Second,
+ MaxElapsedTime: 2 * time.Minute,
+ Jitter: backoff.BACKOFF_JITTER,
+ Multiplier: backoff.BACKOFF_MULTIPLIER,
}
)
@@ -68,7 +63,7 @@ type (
WithInterceptor(interceptor interceptors.Interceptor) Client
WithClientInterceptor(interceptor interceptors.ClientInterceptor) Client
- WithBackoffSettings(backoffSettings BackoffSettings) Client
+ WithBackoffSettings(backoffSettings backoff.BackoffSettings) Client
}
MetricReporter interface {
Client
diff --git a/sdk/client/commander.go b/sdk/client/commander.go
index 6f8be3f2c..26f6fc11c 100644
--- a/sdk/client/commander.go
+++ b/sdk/client/commander.go
@@ -19,7 +19,7 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/status"
- "github.com/nginx/agent/sdk/v2"
+ "github.com/nginx/agent/sdk/v2/backoff"
"github.com/nginx/agent/sdk/v2/checksum"
sdkGRPC "github.com/nginx/agent/sdk/v2/grpc"
"github.com/nginx/agent/sdk/v2/interceptors"
@@ -49,7 +49,7 @@ type commander struct {
downloadChan chan *proto.DataChunk
ctx context.Context
mu sync.Mutex
- backoffSettings BackoffSettings
+ backoffSettings backoff.BackoffSettings
}
func (c *commander) WithInterceptor(interceptor interceptors.Interceptor) Client {
@@ -71,11 +71,9 @@ func (c *commander) Connect(ctx context.Context) error {
log.Debugf("Commander connecting to %s", c.server)
c.ctx = ctx
- err := sdk.WaitUntil(
+ err := backoff.WaitUntil(
c.ctx,
- c.backoffSettings.initialInterval,
- c.backoffSettings.maxInterval,
- c.backoffSettings.maxTimeout,
+ c.backoffSettings,
c.createClient,
)
if err != nil {
@@ -122,7 +120,7 @@ func (c *commander) ChunksSize() int {
return c.chunkSize
}
-func (c *commander) WithBackoffSettings(backoffSettings BackoffSettings) Client {
+func (c *commander) WithBackoffSettings(backoffSettings backoff.BackoffSettings) Client {
c.backoffSettings = backoffSettings
return c
}
@@ -136,13 +134,13 @@ func (c *commander) Send(ctx context.Context, message Message) error {
switch message.Classification() {
case MsgClassificationCommand:
if cmd, ok = message.Raw().(*proto.Command); !ok {
- return fmt.Errorf("Expected a command message, but received %T", message.Data())
+ return fmt.Errorf("expected a command message, but received %T", message.Data())
}
default:
- return fmt.Errorf("Expected a command message, but received %T", message.Data())
+ return fmt.Errorf("expected a command message, but received %T", message.Data())
}
- err := sdk.WaitUntil(c.ctx, c.backoffSettings.initialInterval, c.backoffSettings.maxInterval, c.backoffSettings.sendMaxTimeout, func() error {
+ err := backoff.WaitUntil(c.ctx, c.backoffSettings, func() error {
if err := c.channel.Send(cmd); err != nil {
return c.handleGrpcError("Commander Channel Send", err)
}
@@ -163,7 +161,7 @@ func (c *commander) Download(ctx context.Context, metadata *proto.Metadata) (*pr
log.Debugf("Downloading config (messageId=%s)", metadata.GetMessageId())
cfg := &proto.NginxConfig{}
- err := sdk.WaitUntil(c.ctx, c.backoffSettings.initialInterval, c.backoffSettings.maxInterval, c.backoffSettings.sendMaxTimeout, func() error {
+ err := backoff.WaitUntil(c.ctx, c.backoffSettings, func() error {
var (
header *proto.DataChunk_Header
body []byte
@@ -228,7 +226,7 @@ func (c *commander) Upload(ctx context.Context, cfg *proto.NginxConfig, messageI
payloadChecksum := checksum.Checksum(payload)
chunks := checksum.Chunk(payload, c.chunkSize)
- return sdk.WaitUntil(c.ctx, c.backoffSettings.initialInterval, c.backoffSettings.maxInterval, c.backoffSettings.sendMaxTimeout, func() error {
+ return backoff.WaitUntil(c.ctx, c.backoffSettings, func() error {
sender, err := c.client.Upload(c.ctx)
if err != nil {
return c.handleGrpcError("Commander Upload", err)
@@ -314,7 +312,7 @@ func (c *commander) createClient() error {
func (c *commander) recvLoop() {
log.Debug("Commander receive loop starting")
for {
- err := sdk.WaitUntil(c.ctx, c.backoffSettings.initialInterval, c.backoffSettings.maxInterval, c.backoffSettings.maxTimeout, func() error {
+ err := backoff.WaitUntil(c.ctx, c.backoffSettings, func() error {
cmd, err := c.channel.Recv()
log.Infof("Commander received %v, %v", cmd, err)
if err != nil {
diff --git a/sdk/client/commander_mock_test.go b/sdk/client/commander_mock_test.go
index c9e649128..26f263199 100644
--- a/sdk/client/commander_mock_test.go
+++ b/sdk/client/commander_mock_test.go
@@ -11,6 +11,7 @@ import (
"context"
"time"
+ "github.com/nginx/agent/sdk/v2/backoff"
"github.com/nginx/agent/sdk/v2/interceptors"
"github.com/nginx/agent/sdk/v2/proto"
"github.com/stretchr/testify/mock"
@@ -93,7 +94,7 @@ func (m *MockCommandClient) WithConnWaitDuration(d time.Duration) Client {
return m
}
-func (m *MockCommandClient) WithBackoffSettings(backoffSettings BackoffSettings) Client {
+func (m *MockCommandClient) WithBackoffSettings(backoffSettings backoff.BackoffSettings) Client {
m.Called(backoffSettings)
return m
diff --git a/sdk/client/commander_test.go b/sdk/client/commander_test.go
index 7da6162c9..6c5d7befd 100644
--- a/sdk/client/commander_test.go
+++ b/sdk/client/commander_test.go
@@ -18,7 +18,7 @@ import (
"testing"
"time"
- "github.com/nginx/agent/sdk/v2"
+ "github.com/nginx/agent/sdk/v2/backoff"
"github.com/nginx/agent/sdk/v2/checksum"
"github.com/nginx/agent/sdk/v2/proto"
"github.com/stretchr/testify/assert"
@@ -206,11 +206,10 @@ func TestCommander_Connect_NoServer(t *testing.T) {
commanderClient := NewCommanderClient()
commanderClient.WithServer("unknown")
commanderClient.WithDialOptions(grpcDialOptions...)
- commanderClient.WithBackoffSettings(BackoffSettings{
- initialInterval: 100 * time.Millisecond,
- maxInterval: 100 * time.Millisecond,
- maxTimeout: 300 * time.Millisecond,
- sendMaxTimeout: 300 * time.Millisecond,
+ commanderClient.WithBackoffSettings(backoff.BackoffSettings{
+ InitialInterval: 100 * time.Millisecond,
+ MaxInterval: 100 * time.Millisecond,
+ MaxElapsedTime: 300 * time.Millisecond,
})
err := commanderClient.Connect(ctx)
@@ -223,11 +222,10 @@ func TestCommander_Recv_Reconnect(t *testing.T) {
ctx := context.TODO()
commanderClient := createTestCommanderClient(dialer)
- commanderClient.WithBackoffSettings(BackoffSettings{
- initialInterval: 100 * time.Millisecond,
- maxInterval: 100 * time.Millisecond,
- maxTimeout: 30 * time.Second,
- sendMaxTimeout: 30 * time.Second,
+ commanderClient.WithBackoffSettings(backoff.BackoffSettings{
+ InitialInterval: 100 * time.Millisecond,
+ MaxInterval: 100 * time.Millisecond,
+ MaxElapsedTime: 30 * time.Second,
})
err := commanderClient.Connect(ctx)
assert.Nil(t, err)
@@ -288,11 +286,10 @@ func TestCommander_Send_Reconnect(t *testing.T) {
ctx := context.TODO()
commanderClient := createTestCommanderClient(dialer)
- commanderClient.WithBackoffSettings(BackoffSettings{
- initialInterval: 100 * time.Millisecond,
- maxInterval: 100 * time.Millisecond,
- maxTimeout: 30 * time.Second,
- sendMaxTimeout: 30 * time.Second,
+ commanderClient.WithBackoffSettings(backoff.BackoffSettings{
+ InitialInterval: 100 * time.Millisecond,
+ MaxInterval: 100 * time.Millisecond,
+ MaxElapsedTime: 30 * time.Second,
})
err := commanderClient.Connect(ctx)
assert.Nil(t, err)
@@ -342,11 +339,10 @@ func TestCommander_Download_Reconnect(t *testing.T) {
ctx := context.TODO()
commanderClient := createTestCommanderClient(dialer)
- commanderClient.WithBackoffSettings(BackoffSettings{
- initialInterval: 100 * time.Millisecond,
- maxInterval: 100 * time.Millisecond,
- maxTimeout: 30 * time.Second,
- sendMaxTimeout: 30 * time.Second,
+ commanderClient.WithBackoffSettings(backoff.BackoffSettings{
+ InitialInterval: 100 * time.Millisecond,
+ MaxInterval: 100 * time.Millisecond,
+ MaxElapsedTime: 30 * time.Second,
})
err := commanderClient.Connect(ctx)
assert.Nil(t, err)
@@ -525,11 +521,10 @@ func TestCommander_Upload_Reconnect(t *testing.T) {
ctx := context.TODO()
commanderClient := createTestCommanderClient(dialer)
- commanderClient.WithBackoffSettings(BackoffSettings{
- initialInterval: 100 * time.Millisecond,
- maxInterval: 100 * time.Millisecond,
- maxTimeout: 30 * time.Second,
- sendMaxTimeout: 30 * time.Second,
+ commanderClient.WithBackoffSettings(backoff.BackoffSettings{
+ InitialInterval: 100 * time.Millisecond,
+ MaxInterval: 100 * time.Millisecond,
+ MaxElapsedTime: 30 * time.Second,
})
err := commanderClient.Connect(ctx)
assert.Nil(t, err)
@@ -725,7 +720,14 @@ func stopMockServer(server *grpc.Server, dialer func(context.Context, string) (n
defer grpcServerMutex.Unlock()
server.Stop()
- err = sdk.WaitUntil(ctx, 100*time.Millisecond, 100*time.Millisecond, 1*time.Second, func() error {
+ backoffSetting := backoff.BackoffSettings{
+ InitialInterval: 100 * time.Millisecond,
+ MaxInterval: 100 * time.Millisecond,
+ MaxElapsedTime: 1 * time.Second,
+ Jitter: backoff.BACKOFF_JITTER,
+ Multiplier: backoff.BACKOFF_MULTIPLIER,
+ }
+ err = backoff.WaitUntil(ctx, backoffSetting, func() error {
state := conn.GetState()
if state.String() != "TRANSIENT_FAILURE" {
return errors.New("Still waiting for server to stop")
@@ -740,11 +742,10 @@ func createTestCommanderClient(dialer func(context.Context, string) (net.Conn, e
commanderClient := NewCommanderClient()
commanderClient.WithServer("bufnet")
commanderClient.WithDialOptions(getDialOptions(dialer)...)
- commanderClient.WithBackoffSettings(BackoffSettings{
- initialInterval: 100 * time.Millisecond,
- maxInterval: 100 * time.Millisecond,
- maxTimeout: 300 * time.Millisecond,
- sendMaxTimeout: 300 * time.Millisecond,
+ commanderClient.WithBackoffSettings(backoff.BackoffSettings{
+ InitialInterval: 100 * time.Millisecond,
+ MaxInterval: 100 * time.Millisecond,
+ MaxElapsedTime: 300 * time.Millisecond,
})
return commanderClient
diff --git a/sdk/client/metric_reporter.go b/sdk/client/metric_reporter.go
index 46e46326b..bc204d392 100644
--- a/sdk/client/metric_reporter.go
+++ b/sdk/client/metric_reporter.go
@@ -17,7 +17,7 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/status"
- "github.com/nginx/agent/sdk/v2"
+ "github.com/nginx/agent/sdk/v2/backoff"
sdkGRPC "github.com/nginx/agent/sdk/v2/grpc"
"github.com/nginx/agent/sdk/v2/interceptors"
"github.com/nginx/agent/sdk/v2/proto"
@@ -38,7 +38,7 @@ type metricReporter struct {
eventsChannel proto.MetricsService_StreamEventsClient
ctx context.Context
mu sync.Mutex
- backoffSettings BackoffSettings
+ backoffSettings backoff.BackoffSettings
}
func (r *metricReporter) WithInterceptor(interceptor interceptors.Interceptor) Client {
@@ -57,11 +57,9 @@ func (r *metricReporter) Connect(ctx context.Context) error {
log.Debugf("Metric Reporter connecting to %s", r.server)
r.ctx = ctx
- err := sdk.WaitUntil(
+ err := backoff.WaitUntil(
r.ctx,
- r.backoffSettings.initialInterval,
- r.backoffSettings.maxInterval,
- r.backoffSettings.maxTimeout,
+ r.backoffSettings,
r.createClient,
)
if err != nil {
@@ -138,7 +136,7 @@ func (r *metricReporter) WithDialOptions(options ...grpc.DialOption) Client {
return r
}
-func (r *metricReporter) WithBackoffSettings(backoffSettings BackoffSettings) Client {
+func (r *metricReporter) WithBackoffSettings(backoffSettings backoff.BackoffSettings) Client {
r.backoffSettings = backoffSettings
return r
}
@@ -152,7 +150,7 @@ func (r *metricReporter) Send(ctx context.Context, message Message) error {
if !ok {
return fmt.Errorf("MetricReporter expected a metrics report message, but received %T", message.Data())
}
- err = sdk.WaitUntil(r.ctx, r.backoffSettings.initialInterval, r.backoffSettings.maxInterval, r.backoffSettings.sendMaxTimeout, func() error {
+ err = backoff.WaitUntil(r.ctx, r.backoffSettings, func() error {
if err := r.channel.Send(report); err != nil {
return r.handleGrpcError("Metric Reporter Channel Send", err)
}
@@ -166,7 +164,7 @@ func (r *metricReporter) Send(ctx context.Context, message Message) error {
if !ok {
return fmt.Errorf("MetricReporter expected an events report message, but received %T", message.Data())
}
- err = sdk.WaitUntil(r.ctx, r.backoffSettings.initialInterval, r.backoffSettings.maxInterval, r.backoffSettings.sendMaxTimeout, func() error {
+ err = backoff.WaitUntil(r.ctx, r.backoffSettings, func() error {
if err := r.eventsChannel.Send(report); err != nil {
return r.handleGrpcError("Metric Reporter Events Channel Send", err)
}
diff --git a/sdk/client/metric_reporter_mock_test.go b/sdk/client/metric_reporter_mock_test.go
index e7759923a..9e5e3c31a 100644
--- a/sdk/client/metric_reporter_mock_test.go
+++ b/sdk/client/metric_reporter_mock_test.go
@@ -11,6 +11,7 @@ import (
"context"
"time"
+ "github.com/nginx/agent/sdk/v2/backoff"
"github.com/nginx/agent/sdk/v2/interceptors"
"github.com/stretchr/testify/mock"
"google.golang.org/grpc"
@@ -68,7 +69,7 @@ func (m *MockMetricsReportClient) WithConnWaitDuration(d time.Duration) Client {
return m
}
-func (m *MockMetricsReportClient) WithBackoffSettings(backoffSettings BackoffSettings) Client {
+func (m *MockMetricsReportClient) WithBackoffSettings(backoffSettings backoff.BackoffSettings) Client {
m.Called(backoffSettings)
return m
diff --git a/sdk/client/metric_reporter_test.go b/sdk/client/metric_reporter_test.go
index 0d1b19303..ab9ba4c9e 100644
--- a/sdk/client/metric_reporter_test.go
+++ b/sdk/client/metric_reporter_test.go
@@ -14,6 +14,7 @@ import (
"testing"
"time"
+ "github.com/nginx/agent/sdk/v2/backoff"
"github.com/nginx/agent/sdk/v2/proto"
f5_nginx_agent_sdk_events "github.com/nginx/agent/sdk/v2/proto/events"
log "github.com/sirupsen/logrus"
@@ -73,11 +74,10 @@ func TestMetricReporter_Connect_NoServer(t *testing.T) {
metricReporterClient := NewMetricReporterClient()
metricReporterClient.WithServer("unknown")
metricReporterClient.WithDialOptions(grpcDialOptions...)
- metricReporterClient.WithBackoffSettings(BackoffSettings{
- initialInterval: 100 * time.Millisecond,
- maxInterval: 100 * time.Millisecond,
- maxTimeout: 300 * time.Millisecond,
- sendMaxTimeout: 300 * time.Millisecond,
+ metricReporterClient.WithBackoffSettings(backoff.BackoffSettings{
+ InitialInterval: 100 * time.Millisecond,
+ MaxInterval: 100 * time.Millisecond,
+ MaxElapsedTime: 300 * time.Millisecond,
})
err := metricReporterClient.Connect(ctx)
@@ -115,11 +115,10 @@ func TestMetricReporter_Send_Reconnect(t *testing.T) {
ctx := context.TODO()
metricReporterClient := createTestMetricReporterClient(dialer)
- metricReporterClient.WithBackoffSettings(BackoffSettings{
- initialInterval: 100 * time.Millisecond,
- maxInterval: 100 * time.Millisecond,
- maxTimeout: 30 * time.Second,
- sendMaxTimeout: 30 * time.Second,
+ metricReporterClient.WithBackoffSettings(backoff.BackoffSettings{
+ InitialInterval: 100 * time.Millisecond,
+ MaxInterval: 100 * time.Millisecond,
+ MaxElapsedTime: 30 * time.Second,
})
err := metricReporterClient.Connect(ctx)
assert.Nil(t, err)
@@ -283,11 +282,10 @@ func createTestMetricReporterClient(dialer func(context.Context, string) (net.Co
metricReporterClient := NewMetricReporterClient()
metricReporterClient.WithServer("bufnet")
metricReporterClient.WithDialOptions(getDialOptions(dialer)...)
- metricReporterClient.WithBackoffSettings(BackoffSettings{
- initialInterval: 100 * time.Millisecond,
- maxInterval: 100 * time.Millisecond,
- maxTimeout: 300 * time.Millisecond,
- sendMaxTimeout: 300 * time.Millisecond,
+ metricReporterClient.WithBackoffSettings(backoff.BackoffSettings{
+ InitialInterval: 100 * time.Millisecond,
+ MaxInterval: 100 * time.Millisecond,
+ MaxElapsedTime: 300 * time.Millisecond,
})
return metricReporterClient
diff --git a/sdk/config_apply.go b/sdk/config_apply.go
index 59a21dd83..00660591b 100644
--- a/sdk/config_apply.go
+++ b/sdk/config_apply.go
@@ -16,10 +16,10 @@ import (
"path/filepath"
"strings"
+ "github.com/nginx/agent/sdk/v2/zip"
+
crossplane "github.com/nginxinc/nginx-go-crossplane"
log "github.com/sirupsen/logrus"
-
- "github.com/nginx/agent/sdk/v2/zip"
)
// ConfigApply facilitates synchronizing the current config against incoming config_apply request. By keeping track
diff --git a/sdk/config_apply_test.go b/sdk/config_apply_test.go
index 5c4a42628..a34e8de2b 100644
--- a/sdk/config_apply_test.go
+++ b/sdk/config_apply_test.go
@@ -10,7 +10,6 @@ package sdk
import (
"errors"
"fmt"
- "io/ioutil"
"os"
"path"
"testing"
@@ -76,24 +75,24 @@ func TestNewConfigApply(t *testing.T) {
require.NoError(t, os.Mkdir(rootDirectory, os.ModePerm))
rootFile1 := path.Join(rootDirectory, "root1.html")
- require.NoError(t, ioutil.WriteFile(rootFile1, []byte{}, 0644))
+ require.NoError(t, os.WriteFile(rootFile1, []byte{}, 0644))
rootFile2 := path.Join(rootDirectory, "root2.html")
- require.NoError(t, ioutil.WriteFile(rootFile2, []byte{}, 0644))
+ require.NoError(t, os.WriteFile(rootFile2, []byte{}, 0644))
rootFile3 := path.Join(rootDirectory, "root3.html")
- require.NoError(t, ioutil.WriteFile(rootFile3, []byte{}, 0644))
+ require.NoError(t, os.WriteFile(rootFile3, []byte{}, 0644))
emptyConfFile := path.Join(tmpDir, "empty_nginx.conf")
- require.NoError(t, ioutil.WriteFile(emptyConfFile, []byte{}, 0644))
+ require.NoError(t, os.WriteFile(emptyConfFile, []byte{}, 0644))
defaultConfFile := path.Join(tmpDir, "default_nginx.conf")
defaultConfFileContent := fmt.Sprintf(defaultConfFileContentsString, rootDirectory, rootDirectory)
- require.NoError(t, ioutil.WriteFile(defaultConfFile, []byte(defaultConfFileContent), 0644))
+ require.NoError(t, os.WriteFile(defaultConfFile, []byte(defaultConfFileContent), 0644))
confFile := path.Join(tmpDir, "nginx.conf")
confFileContent := fmt.Sprintf(confFileContentsString, defaultConfFile)
- require.NoError(t, ioutil.WriteFile(confFile, []byte(confFileContent), 0644))
+ require.NoError(t, os.WriteFile(confFile, []byte(confFileContent), 0644))
testCases := []struct {
name string
@@ -178,7 +177,7 @@ func TestConfigApplyMarkAndSave(t *testing.T) {
unknownFileUnknownDir := path.Join(tmpDir, "/unknown/unknown.conf")
unknownFileUnknownNestedDirs := path.Join(tmpDir, "/unknown/nested/unknown.conf")
- require.NoError(t, ioutil.WriteFile(knownFile, []byte{}, 0644))
+ require.NoError(t, os.WriteFile(knownFile, []byte{}, 0644))
writer, err := zip.NewWriter("/")
require.NoError(t, err)
@@ -250,21 +249,21 @@ func TestConfigApplyCompleteAndRollback(t *testing.T) {
require.NoError(t, os.Mkdir(rootDirectory, os.ModePerm))
rootFile1 := path.Join(rootDirectory, "root1.html")
- require.NoError(t, ioutil.WriteFile(rootFile1, []byte{}, 0644))
+ require.NoError(t, os.WriteFile(rootFile1, []byte{}, 0644))
rootFile2 := path.Join(rootDirectory, "root2.html")
- require.NoError(t, ioutil.WriteFile(rootFile2, []byte{}, 0644))
+ require.NoError(t, os.WriteFile(rootFile2, []byte{}, 0644))
rootFile3 := path.Join(rootDirectory, "root3.html")
- require.NoError(t, ioutil.WriteFile(rootFile3, []byte{}, 0644))
+ require.NoError(t, os.WriteFile(rootFile3, []byte{}, 0644))
defaultConfFile := path.Join(tmpDir, "default_nginx.conf")
defaultConfFileContent := fmt.Sprintf(defaultConfFileContentsString, rootDirectory, rootDirectory)
- require.NoError(t, ioutil.WriteFile(defaultConfFile, []byte(defaultConfFileContent), 0644))
+ require.NoError(t, os.WriteFile(defaultConfFile, []byte(defaultConfFileContent), 0644))
confFile := path.Join(tmpDir, "nginx.conf")
confFileContent := fmt.Sprintf(confFileContentsString, defaultConfFile)
- require.NoError(t, ioutil.WriteFile(confFile, []byte(confFileContent), 0644))
+ require.NoError(t, os.WriteFile(confFile, []byte(confFileContent), 0644))
allowedDirectories := map[string]struct{}{tmpDir: {}}
@@ -279,7 +278,7 @@ func TestConfigApplyCompleteAndRollback(t *testing.T) {
// MarkAndSave an unknown file that does not exist, then create the file afterwards
unknownConfFile := path.Join(tmpDir, "unknown.conf")
assert.NoError(t, configApply.MarkAndSave(unknownConfFile))
- assert.NoError(t, ioutil.WriteFile(unknownConfFile, []byte{}, 0644))
+ assert.NoError(t, os.WriteFile(unknownConfFile, []byte{}, 0644))
// Verify that only root files are deleted
assert.NoError(t, configApply.Complete())
diff --git a/sdk/go.mod b/sdk/go.mod
index b3b715fcc..882ebdc8b 100644
--- a/sdk/go.mod
+++ b/sdk/go.mod
@@ -3,14 +3,14 @@ module github.com/nginx/agent/sdk/v2
go 1.19
require (
- github.com/cenkalti/backoff/v4 v4.2.0
+ github.com/cenkalti/backoff/v4 v4.2.1
github.com/gogo/protobuf v1.3.2
- github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
+ github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/mitchellh/mapstructure v1.5.0
- github.com/nginxinc/nginx-go-crossplane v0.4.15
+ github.com/nginxinc/nginx-go-crossplane v0.4.17
github.com/sirupsen/logrus v1.9.0
github.com/stretchr/testify v1.8.2
- google.golang.org/grpc v1.52.0
+ google.golang.org/grpc v1.55.0
)
require (
@@ -23,11 +23,11 @@ require (
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect
golang.org/x/mod v0.10.0 // indirect
- golang.org/x/net v0.9.0 // indirect
- golang.org/x/sys v0.7.0 // indirect
+ golang.org/x/net v0.10.0 // indirect
+ golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
- golang.org/x/tools v0.8.0 // indirect
- google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2 // indirect
+ golang.org/x/tools v0.9.1 // indirect
+ google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/sdk/go.sum b/sdk/go.sum
index dc17602ea..284ddd05d 100644
--- a/sdk/go.sum
+++ b/sdk/go.sum
@@ -1,7 +1,8 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
-github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
+github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
+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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
@@ -13,8 +14,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
+github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
@@ -29,23 +30,25 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
-github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
-github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
+github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
+github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
github.com/jstemmer/go-junit-report v1.0.0 h1:8X1gzZpR+nVQLAht+L/foqOeX2l9DTZoaIPbEQHxsds=
github.com/jstemmer/go-junit-report v1.0.0/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/maxbrunsfeld/counterfeiter/v6 v6.6.1 h1:9XE5ykDiC8eNSqIPkxx0EsV3kMX1oe4kQWRZjIgytUA=
github.com/maxbrunsfeld/counterfeiter/v6 v6.6.1/go.mod h1:qbKwBR+qQODzH2WD/s53mdgp/xVcXMlJb59GRFOp6Z4=
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/nginxinc/nginx-go-crossplane v0.4.15 h1:O+FIyX7L0TnR28G732dLRpeRtOZBEDc2i2veXE4nGD0=
-github.com/nginxinc/nginx-go-crossplane v0.4.15/go.mod h1:UzbZnyFv0vPlt1Urbnp/mrFCzBL4tYCReFuNBpFQEfI=
+github.com/nginxinc/nginx-go-crossplane v0.4.17 h1:kBISwQT36Uv4h57ran0bT4MIWUqaoJrMwoTMpryBZcg=
+github.com/nginxinc/nginx-go-crossplane v0.4.17/go.mod h1:UzbZnyFv0vPlt1Urbnp/mrFCzBL4tYCReFuNBpFQEfI=
github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -64,6 +67,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -72,9 +76,10 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
-go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
+go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
+go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -82,6 +87,7 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
@@ -94,23 +100,24 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
-golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
+golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
+golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
-golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
@@ -120,11 +127,12 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/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-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
-golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
+golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
+golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -134,23 +142,26 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2 h1:O97sLx/Xmb/KIZHB/2/BzofxBs5QmmR0LcihPtllmbc=
-google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
+google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
+google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
-google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk=
-google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
+google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
+google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/sdk/grpc/grpc.go b/sdk/grpc/grpc.go
index 28529f052..a297ba422 100644
--- a/sdk/grpc/grpc.go
+++ b/sdk/grpc/grpc.go
@@ -12,7 +12,7 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
- "io/ioutil"
+ "os"
"time"
grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
@@ -152,7 +152,7 @@ func appendRootCAs(tlsConfig *tls.Config, caFile string) error {
return nil
}
- ca, err := ioutil.ReadFile(caFile)
+ ca, err := os.ReadFile(caFile)
if err != nil {
return fmt.Errorf("could not read CA file (%s): %w", caFile, err)
}
diff --git a/sdk/proto/agent.pb.go b/sdk/proto/agent.pb.go
index ca50f0ae9..e8ce7b135 100644
--- a/sdk/proto/agent.pb.go
+++ b/sdk/proto/agent.pb.go
@@ -4,6 +4,7 @@
package proto
import (
+ encoding_binary "encoding/binary"
fmt "fmt"
_ "github.com/gogo/protobuf/gogoproto"
proto "github.com/gogo/protobuf/proto"
@@ -97,7 +98,7 @@ func (x AgentLogging_Level) String() string {
}
func (AgentLogging_Level) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_56ede974c0020f77, []int{6, 0}
+ return fileDescriptor_56ede974c0020f77, []int{8, 0}
}
// Represents an agent connect request that is sent from the agent to the management server
@@ -420,7 +421,9 @@ type AgentDetails struct {
// List of tags
Tags []string `protobuf:"bytes,3,rep,name=tags,proto3" json:"tags"`
// Alias name for the agent
- Alias string `protobuf:"bytes,4,opt,name=alias,proto3" json:"alias"`
+ Alias string `protobuf:"bytes,4,opt,name=alias,proto3" json:"alias"`
+ // Server setting for the agent
+ Server *Server `protobuf:"bytes,5,opt,name=server,proto3" json:"server"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -487,6 +490,191 @@ func (m *AgentDetails) GetAlias() string {
return ""
}
+func (m *AgentDetails) GetServer() *Server {
+ if m != nil {
+ return m.Server
+ }
+ return nil
+}
+
+type Server struct {
+ // Host name or IP of the host to connect to
+ Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host"`
+ // Grpc port to connect to
+ GrpcPort int32 `protobuf:"varint,2,opt,name=grpc_port,json=grpcPort,proto3" json:"grpc_port"`
+ // Shared secrect between the server and client
+ Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token"`
+ // Metrics server name
+ Metrics string `protobuf:"bytes,4,opt,name=metrics,proto3" json:"metrics"`
+ // Command server name
+ Command string `protobuf:"bytes,5,opt,name=command,proto3" json:"command"`
+ // Backoff settings for exponential retry and backoff
+ Backoff *Backoff `protobuf:"bytes,6,opt,name=backoff,proto3" json:"backoff"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Server) Reset() { *m = Server{} }
+func (m *Server) String() string { return proto.CompactTextString(m) }
+func (*Server) ProtoMessage() {}
+func (*Server) Descriptor() ([]byte, []int) {
+ return fileDescriptor_56ede974c0020f77, []int{6}
+}
+func (m *Server) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *Server) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_Server.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *Server) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Server.Merge(m, src)
+}
+func (m *Server) XXX_Size() int {
+ return m.Size()
+}
+func (m *Server) XXX_DiscardUnknown() {
+ xxx_messageInfo_Server.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Server proto.InternalMessageInfo
+
+func (m *Server) GetHost() string {
+ if m != nil {
+ return m.Host
+ }
+ return ""
+}
+
+func (m *Server) GetGrpcPort() int32 {
+ if m != nil {
+ return m.GrpcPort
+ }
+ return 0
+}
+
+func (m *Server) GetToken() string {
+ if m != nil {
+ return m.Token
+ }
+ return ""
+}
+
+func (m *Server) GetMetrics() string {
+ if m != nil {
+ return m.Metrics
+ }
+ return ""
+}
+
+func (m *Server) GetCommand() string {
+ if m != nil {
+ return m.Command
+ }
+ return ""
+}
+
+func (m *Server) GetBackoff() *Backoff {
+ if m != nil {
+ return m.Backoff
+ }
+ return nil
+}
+
+type Backoff struct {
+ // First backoff time interval in seconds
+ InitialInterval int64 `protobuf:"varint,1,opt,name=initial_interval,json=initialInterval,proto3" json:"initial_interval"`
+ // Random value used to create range around next backoff interval
+ RandomizationFactor float64 `protobuf:"fixed64,2,opt,name=randomization_factor,json=randomizationFactor,proto3" json:"randomization_factor"`
+ // Value to be multiplied with current backoff interval
+ Multiplier float64 `protobuf:"fixed64,3,opt,name=multiplier,proto3" json:"multiplier"`
+ // Max interval in seconds between two retries
+ MaxInterval int64 `protobuf:"varint,4,opt,name=max_interval,json=maxInterval,proto3" json:"max_interval"`
+ // Elapsed time in seconds after which backoff stops.
+ // It never stops if max_elapsed_time == 0.
+ MaxElapsedTime int64 `protobuf:"varint,5,opt,name=max_elapsed_time,json=maxElapsedTime,proto3" json:"max_elapsed_time"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *Backoff) Reset() { *m = Backoff{} }
+func (m *Backoff) String() string { return proto.CompactTextString(m) }
+func (*Backoff) ProtoMessage() {}
+func (*Backoff) Descriptor() ([]byte, []int) {
+ return fileDescriptor_56ede974c0020f77, []int{7}
+}
+func (m *Backoff) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *Backoff) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_Backoff.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *Backoff) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_Backoff.Merge(m, src)
+}
+func (m *Backoff) XXX_Size() int {
+ return m.Size()
+}
+func (m *Backoff) XXX_DiscardUnknown() {
+ xxx_messageInfo_Backoff.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Backoff proto.InternalMessageInfo
+
+func (m *Backoff) GetInitialInterval() int64 {
+ if m != nil {
+ return m.InitialInterval
+ }
+ return 0
+}
+
+func (m *Backoff) GetRandomizationFactor() float64 {
+ if m != nil {
+ return m.RandomizationFactor
+ }
+ return 0
+}
+
+func (m *Backoff) GetMultiplier() float64 {
+ if m != nil {
+ return m.Multiplier
+ }
+ return 0
+}
+
+func (m *Backoff) GetMaxInterval() int64 {
+ if m != nil {
+ return m.MaxInterval
+ }
+ return 0
+}
+
+func (m *Backoff) GetMaxElapsedTime() int64 {
+ if m != nil {
+ return m.MaxElapsedTime
+ }
+ return 0
+}
+
// Represents agent logging details
type AgentLogging struct {
// Log level
@@ -512,7 +700,7 @@ func (m *AgentLogging) Reset() { *m = AgentLogging{} }
func (m *AgentLogging) String() string { return proto.CompactTextString(m) }
func (*AgentLogging) ProtoMessage() {}
func (*AgentLogging) Descriptor() ([]byte, []int) {
- return fileDescriptor_56ede974c0020f77, []int{6}
+ return fileDescriptor_56ede974c0020f77, []int{8}
}
func (m *AgentLogging) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -615,7 +803,7 @@ func (m *AgentMeta) Reset() { *m = AgentMeta{} }
func (m *AgentMeta) String() string { return proto.CompactTextString(m) }
func (*AgentMeta) ProtoMessage() {}
func (*AgentMeta) Descriptor() ([]byte, []int) {
- return fileDescriptor_56ede974c0020f77, []int{7}
+ return fileDescriptor_56ede974c0020f77, []int{9}
}
func (m *AgentMeta) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -702,6 +890,8 @@ func init() {
proto.RegisterType((*AgentConfigRequest)(nil), "f5.nginx.agent.sdk.AgentConfigRequest")
proto.RegisterType((*AgentConfig)(nil), "f5.nginx.agent.sdk.AgentConfig")
proto.RegisterType((*AgentDetails)(nil), "f5.nginx.agent.sdk.AgentDetails")
+ proto.RegisterType((*Server)(nil), "f5.nginx.agent.sdk.Server")
+ proto.RegisterType((*Backoff)(nil), "f5.nginx.agent.sdk.Backoff")
proto.RegisterType((*AgentLogging)(nil), "f5.nginx.agent.sdk.AgentLogging")
proto.RegisterType((*AgentMeta)(nil), "f5.nginx.agent.sdk.AgentMeta")
}
@@ -709,75 +899,91 @@ func init() {
func init() { proto.RegisterFile("agent.proto", fileDescriptor_56ede974c0020f77) }
var fileDescriptor_56ede974c0020f77 = []byte{
- // 1081 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcd, 0x72, 0x1b, 0x45,
- 0x10, 0xce, 0xea, 0xc7, 0x92, 0x5a, 0xb6, 0xb3, 0x4c, 0x52, 0xa0, 0x88, 0xe0, 0x55, 0xa9, 0x20,
- 0x88, 0x2a, 0x58, 0x81, 0x52, 0x14, 0x05, 0xe1, 0x22, 0x59, 0x8a, 0x63, 0xc7, 0x48, 0xd4, 0x58,
- 0xae, 0x50, 0x5c, 0xb6, 0xc6, 0xda, 0xd1, 0x66, 0xb1, 0x76, 0x57, 0xec, 0x8c, 0x8c, 0x9c, 0x47,
- 0xe0, 0x21, 0xb8, 0x72, 0xe1, 0x01, 0x78, 0x04, 0x8e, 0x3c, 0xc1, 0x16, 0xe5, 0x13, 0xb5, 0x67,
- 0x2e, 0xdc, 0xa8, 0xf9, 0x59, 0x5b, 0xc6, 0x3f, 0xc9, 0x65, 0xa6, 0xfb, 0xdb, 0xee, 0x9e, 0x9e,
- 0x6f, 0xa6, 0x7b, 0x16, 0xaa, 0xc4, 0xa3, 0x21, 0xb7, 0xe7, 0x71, 0xc4, 0x23, 0x84, 0xa6, 0x9f,
- 0xdb, 0xa1, 0xe7, 0x87, 0x4b, 0x5b, 0xa1, 0xcc, 0x3d, 0xae, 0xaf, 0x4f, 0xa2, 0x70, 0xea, 0x7b,
- 0xca, 0xa2, 0xfe, 0xc0, 0x9d, 0x3b, 0x2c, 0x9a, 0xf2, 0x9f, 0x48, 0x4c, 0x1d, 0x97, 0x72, 0xe2,
- 0xcf, 0x98, 0xfe, 0x04, 0x5e, 0xe4, 0x45, 0x5a, 0xb6, 0xbc, 0x28, 0xf2, 0x66, 0xb4, 0x2d, 0xb5,
- 0xa3, 0xc5, 0xb4, 0xcd, 0xfd, 0x80, 0x32, 0x4e, 0x82, 0x79, 0x66, 0xfc, 0x32, 0x62, 0x7a, 0xd5,
- 0x7a, 0x55, 0x2d, 0x29, 0x95, 0xe6, 0x3f, 0x39, 0xb8, 0xd7, 0x15, 0x8b, 0x6f, 0x47, 0x61, 0x48,
- 0x27, 0x1c, 0xd3, 0x1f, 0x17, 0x94, 0x71, 0xf4, 0x04, 0x0a, 0x01, 0xe5, 0xa4, 0x96, 0x6b, 0x18,
- 0xad, 0x6a, 0xe7, 0x3d, 0xfb, 0x6a, 0xa6, 0xb6, 0x74, 0xfb, 0x86, 0x72, 0xd2, 0x2b, 0xa7, 0x89,
- 0x25, 0xcd, 0xb1, 0x1c, 0xd1, 0x0e, 0x94, 0x74, 0xae, 0xb5, 0x7c, 0x23, 0xdf, 0xaa, 0x76, 0x1a,
- 0xd7, 0xf9, 0x0f, 0x85, 0xde, 0x57, 0x76, 0xbd, 0x6a, 0x9a, 0x58, 0x99, 0x13, 0xce, 0x04, 0xf4,
- 0x15, 0x14, 0x44, 0xe2, 0xb5, 0x82, 0xcc, 0xe2, 0xe1, 0x75, 0x51, 0x9e, 0x45, 0x8c, 0xef, 0x86,
- 0xd3, 0x48, 0x25, 0x21, 0xac, 0xb1, 0x1c, 0xd1, 0xcf, 0x06, 0xd4, 0x5d, 0xc2, 0xc9, 0x7c, 0x46,
- 0x42, 0x7a, 0x85, 0xc4, 0x5a, 0x51, 0x26, 0xf6, 0xf1, 0x75, 0x21, 0xfb, 0x99, 0xd7, 0x81, 0x76,
- 0xca, 0x92, 0xdc, 0x4a, 0x13, 0xeb, 0x96, 0x98, 0xb8, 0xe6, 0xde, 0xe0, 0xb9, 0x57, 0x28, 0x1b,
- 0x66, 0x0e, 0x97, 0x7d, 0x97, 0x86, 0xdc, 0xe7, 0xa7, 0xcd, 0xdf, 0x72, 0x80, 0x56, 0x69, 0x3f,
- 0xe0, 0x84, 0x2f, 0x18, 0x3a, 0x02, 0x60, 0x52, 0xda, 0x8e, 0x5c, 0x5a, 0x33, 0x1a, 0x46, 0x6b,
- 0xb3, 0xf3, 0xd9, 0x8d, 0xdc, 0x5f, 0xf2, 0xb5, 0x0f, 0xce, 0x1d, 0x7b, 0x77, 0xd3, 0xc4, 0xaa,
- 0xaa, 0x40, 0xce, 0x24, 0x72, 0x29, 0x5e, 0x89, 0x8a, 0x3e, 0x80, 0x52, 0x40, 0x19, 0x23, 0x1e,
- 0x95, 0x87, 0x5b, 0x51, 0xd4, 0x6b, 0x08, 0x67, 0x02, 0xb2, 0xa0, 0x48, 0xe3, 0x38, 0x8a, 0x6b,
- 0x79, 0x69, 0x54, 0x49, 0x13, 0x4b, 0x01, 0x58, 0x4d, 0xcd, 0x1f, 0x00, 0x2e, 0x96, 0x44, 0xf7,
- 0xe0, 0xee, 0xf6, 0x68, 0x38, 0x1c, 0x6c, 0x8f, 0x9d, 0xc3, 0xe1, 0xf3, 0xe1, 0xe8, 0xc5, 0xd0,
- 0xbc, 0x83, 0x36, 0x01, 0x32, 0x70, 0xf4, 0xdc, 0x34, 0x50, 0x1d, 0xde, 0xce, 0x74, 0x3c, 0xd8,
- 0x1b, 0x6c, 0x8f, 0x07, 0x7d, 0x67, 0x34, 0x7e, 0x36, 0xc0, 0x66, 0x0e, 0xbd, 0x0b, 0xef, 0x5c,
- 0xf9, 0xd6, 0x3f, 0xfc, 0xd6, 0xd9, 0xed, 0x9b, 0xf9, 0xe6, 0xef, 0x06, 0xdc, 0xbf, 0x7c, 0x4b,
- 0xd9, 0x3c, 0x0a, 0x19, 0x45, 0x63, 0x58, 0x97, 0xa4, 0x38, 0xaa, 0x6a, 0x24, 0x65, 0xd5, 0x8e,
- 0x75, 0x1b, 0x65, 0x53, 0xdf, 0xeb, 0x99, 0x69, 0x62, 0x5d, 0x72, 0xc4, 0xaa, 0x2e, 0xd5, 0x67,
- 0xb4, 0x07, 0x6b, 0x8a, 0x30, 0x7d, 0xfd, 0x1f, 0xbd, 0xd9, 0x11, 0xf4, 0x20, 0x4d, 0x2c, 0xed,
- 0x89, 0xf5, 0xdc, 0xbc, 0x7f, 0x71, 0xd0, 0x62, 0x1d, 0x55, 0x5e, 0xcd, 0xbf, 0x0d, 0xa8, 0xae,
- 0xc0, 0xab, 0x15, 0xa3, 0xb6, 0xd0, 0xb8, 0x71, 0xc9, 0xdb, 0x2b, 0x66, 0x07, 0x4a, 0xb3, 0xc8,
- 0xf3, 0x68, 0x9c, 0xe5, 0x7e, 0x73, 0xa0, 0xfd, 0xc8, 0xf3, 0xfc, 0xd0, 0x53, 0x81, 0xb4, 0x13,
- 0xce, 0x04, 0x11, 0x48, 0x51, 0xc3, 0xe4, 0x0d, 0xb8, 0x21, 0x50, 0xb6, 0xab, 0x79, 0x14, 0x73,
- 0x15, 0x48, 0x3b, 0xe1, 0x4c, 0x68, 0xfe, 0x6a, 0xc0, 0xfa, 0x6a, 0xe2, 0xa8, 0x05, 0xe5, 0x29,
- 0x25, 0x7c, 0x11, 0x53, 0xb1, 0xd9, 0x7c, 0xab, 0xd2, 0x5b, 0x4f, 0x13, 0xeb, 0x1c, 0xc3, 0xe7,
- 0x12, 0xb2, 0x01, 0xe8, 0x92, 0xd3, 0x90, 0xf9, 0x51, 0x28, 0xf6, 0x23, 0x6c, 0x37, 0xd3, 0xc4,
- 0x5a, 0x41, 0xf1, 0x8a, 0x8c, 0x1e, 0x42, 0x81, 0x13, 0x4f, 0x35, 0x9d, 0x8a, 0x6a, 0x08, 0x42,
- 0xc7, 0x72, 0x14, 0x37, 0x9a, 0xcc, 0x7c, 0xc2, 0x64, 0x37, 0xd1, 0x37, 0x5a, 0x02, 0x58, 0x4d,
- 0xcd, 0x7f, 0x73, 0x3a, 0x53, 0xcd, 0x0c, 0xda, 0x81, 0xe2, 0x8c, 0x9e, 0xd0, 0x99, 0xae, 0xc4,
- 0x47, 0xaf, 0xa3, 0xd2, 0xde, 0x17, 0xd6, 0x2a, 0xb2, 0x74, 0xc4, 0x6a, 0x42, 0x0f, 0x20, 0xef,
- 0xfa, 0xb1, 0xae, 0xb7, 0x52, 0x9a, 0x58, 0x42, 0xc5, 0x62, 0x10, 0x39, 0x4f, 0xfd, 0x19, 0xd5,
- 0x65, 0x26, 0x73, 0x16, 0x3a, 0x96, 0x23, 0xfa, 0x10, 0xca, 0x01, 0x59, 0x3a, 0xcc, 0x7f, 0x45,
- 0x65, 0xda, 0x1b, 0x8a, 0xab, 0x0c, 0xc3, 0xa5, 0x80, 0x2c, 0x0f, 0xfc, 0x57, 0x14, 0x7d, 0x0a,
- 0x55, 0x01, 0x1e, 0x91, 0xc9, 0xf1, 0x62, 0x2e, 0xba, 0x9b, 0xb0, 0x95, 0x7d, 0x60, 0x05, 0xc6,
- 0x10, 0x90, 0x65, 0x4f, 0xc9, 0xe8, 0x7d, 0x10, 0xce, 0x8e, 0xe8, 0x03, 0x6b, 0xd2, 0x5a, 0xf5,
- 0x01, 0x05, 0xe1, 0xb5, 0x80, 0x2c, 0xbb, 0x1e, 0x15, 0x87, 0x35, 0x89, 0x82, 0x79, 0x4c, 0x19,
- 0xab, 0x95, 0x1a, 0x46, 0xab, 0xac, 0x12, 0xc8, 0x30, 0x7c, 0x2e, 0x35, 0xbf, 0x86, 0xa2, 0xdc,
- 0x3e, 0x2a, 0x43, 0x61, 0x77, 0xf8, 0x74, 0x64, 0xde, 0x41, 0x15, 0x28, 0xf6, 0x07, 0xbd, 0xc3,
- 0x1d, 0xd3, 0x10, 0xe0, 0x8b, 0x2e, 0x1e, 0x9a, 0x39, 0x01, 0x0e, 0x30, 0x1e, 0x61, 0x33, 0x2f,
- 0xc4, 0xa7, 0xdd, 0x71, 0x77, 0xdf, 0x2c, 0x34, 0x7f, 0xc9, 0x43, 0xe5, 0xfc, 0x41, 0x11, 0x3d,
- 0xea, 0x84, 0xc6, 0xe2, 0x50, 0x25, 0xf5, 0xba, 0x47, 0x69, 0x08, 0x67, 0x02, 0x7a, 0x0c, 0xeb,
- 0xae, 0xcf, 0xe6, 0x33, 0x72, 0xea, 0x84, 0x24, 0xc8, 0xfa, 0x99, 0x2c, 0xee, 0x55, 0x1c, 0x57,
- 0xb5, 0x36, 0x24, 0x01, 0x15, 0x67, 0xc1, 0x89, 0xa7, 0xef, 0x88, 0x3c, 0x0b, 0x4e, 0x3c, 0x2c,
- 0x06, 0xf4, 0x25, 0x6c, 0xfa, 0x21, 0xe3, 0x24, 0x9c, 0x50, 0xc7, 0x8b, 0xa3, 0xc5, 0x5c, 0xf2,
- 0x58, 0xe9, 0xa1, 0x34, 0xb1, 0xfe, 0xf7, 0x05, 0x6f, 0x64, 0xfa, 0x8e, 0x50, 0x51, 0x17, 0x4a,
- 0x8b, 0xb9, 0x4b, 0x38, 0x75, 0x25, 0x9b, 0xd5, 0x4e, 0xdd, 0x56, 0x6f, 0xb2, 0x9d, 0xbd, 0xc9,
- 0xf6, 0x38, 0x7b, 0x93, 0xd5, 0x6e, 0xb4, 0x39, 0xce, 0x04, 0xf4, 0x09, 0x00, 0x3b, 0x65, 0x9c,
- 0x06, 0xce, 0xc2, 0x77, 0x25, 0xd9, 0xfa, 0xb6, 0x5f, 0xa0, 0xb8, 0xa2, 0xe4, 0x43, 0xdf, 0x45,
- 0xdf, 0xc1, 0x86, 0xea, 0x60, 0x59, 0xe3, 0x28, 0xbf, 0x61, 0xe3, 0x78, 0x2b, 0x4d, 0xac, 0xcb,
- 0xae, 0x58, 0xf5, 0xc2, 0x8b, 0xc7, 0xaa, 0x60, 0x16, 0x2f, 0x36, 0x28, 0x39, 0xec, 0x7d, 0xf1,
- 0xc7, 0xd9, 0x96, 0xf1, 0xe7, 0xd9, 0x96, 0xf1, 0xd7, 0xd9, 0x96, 0xf1, 0xfd, 0x47, 0x9e, 0xcf,
- 0x5f, 0x2e, 0x8e, 0xec, 0x49, 0x14, 0xb4, 0xe5, 0x62, 0x6d, 0x19, 0xa1, 0xcd, 0xdc, 0xe3, 0xf6,
- 0x49, 0x47, 0xfd, 0x87, 0x3c, 0x51, 0x3b, 0x5f, 0x93, 0xd3, 0xe3, 0xff, 0x02, 0x00, 0x00, 0xff,
- 0xff, 0x01, 0x6e, 0xed, 0x83, 0xfa, 0x08, 0x00, 0x00,
+ // 1342 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcd, 0x6e, 0x1c, 0x45,
+ 0x10, 0xce, 0xec, 0x8f, 0x77, 0xb7, 0xd6, 0x76, 0x86, 0x8e, 0x05, 0x1b, 0x27, 0x78, 0xac, 0x15,
+ 0x04, 0x83, 0x60, 0x0d, 0x8e, 0x10, 0x82, 0xa0, 0x20, 0x8f, 0xbd, 0x71, 0x9c, 0x84, 0x75, 0xd4,
+ 0xb6, 0x15, 0xc4, 0x65, 0xd4, 0xde, 0xe9, 0x9d, 0x34, 0x9e, 0x99, 0x1e, 0x66, 0x7a, 0xcd, 0x26,
+ 0x77, 0x2e, 0x3c, 0x04, 0x4f, 0xc0, 0x03, 0x70, 0xe0, 0x01, 0x38, 0xf2, 0x04, 0x23, 0x94, 0x0b,
+ 0x68, 0xce, 0x5c, 0xb8, 0xa1, 0xfe, 0x19, 0xef, 0x3a, 0xb6, 0x43, 0x2e, 0xdd, 0xd5, 0x5f, 0x57,
+ 0x55, 0x57, 0x55, 0x57, 0x55, 0x37, 0xb4, 0x49, 0x40, 0x63, 0xd1, 0x4b, 0x52, 0x2e, 0x38, 0x42,
+ 0xa3, 0x4f, 0x7b, 0x71, 0xc0, 0xe2, 0x49, 0x4f, 0xa3, 0x99, 0x7f, 0xbc, 0x3c, 0x3f, 0xe4, 0xf1,
+ 0x88, 0x05, 0x9a, 0x63, 0xf9, 0xba, 0x9f, 0x78, 0x19, 0x1f, 0x89, 0x1f, 0x48, 0x4a, 0x3d, 0x9f,
+ 0x0a, 0xc2, 0xc2, 0xcc, 0x6c, 0x41, 0xc0, 0x03, 0x6e, 0x68, 0x27, 0xe0, 0x3c, 0x08, 0xe9, 0xba,
+ 0x5a, 0x1d, 0x8d, 0x47, 0xeb, 0x82, 0x45, 0x34, 0x13, 0x24, 0x4a, 0x4a, 0xe6, 0xa7, 0x3c, 0x33,
+ 0xa7, 0x2e, 0xb7, 0xf5, 0x91, 0x6a, 0xd1, 0xfd, 0xa7, 0x02, 0xd7, 0x36, 0xe5, 0xe1, 0x5b, 0x3c,
+ 0x8e, 0xe9, 0x50, 0x60, 0xfa, 0xfd, 0x98, 0x66, 0x02, 0xdd, 0x81, 0x5a, 0x44, 0x05, 0xe9, 0x54,
+ 0x56, 0xad, 0xb5, 0xf6, 0xc6, 0xdb, 0xbd, 0xf3, 0x96, 0xf6, 0x94, 0xd8, 0xd7, 0x54, 0x10, 0xb7,
+ 0x59, 0xe4, 0x8e, 0x62, 0xc7, 0x6a, 0x44, 0x3b, 0xd0, 0x30, 0xb6, 0x76, 0xaa, 0xab, 0xd5, 0xb5,
+ 0xf6, 0xc6, 0xea, 0x45, 0xf2, 0x03, 0xb9, 0xde, 0xd6, 0x7c, 0x6e, 0xbb, 0xc8, 0x9d, 0x52, 0x08,
+ 0x97, 0x04, 0xfa, 0x02, 0x6a, 0xd2, 0xf0, 0x4e, 0x4d, 0x59, 0x71, 0xf3, 0x22, 0x2d, 0xf7, 0x79,
+ 0x26, 0x76, 0xe3, 0x11, 0xd7, 0x46, 0x48, 0x6e, 0xac, 0x46, 0xf4, 0x93, 0x05, 0xcb, 0x3e, 0x11,
+ 0x24, 0x09, 0x49, 0x4c, 0xcf, 0x05, 0xb1, 0x53, 0x57, 0x86, 0x7d, 0x78, 0x91, 0xca, 0xed, 0x52,
+ 0x6a, 0xdf, 0x08, 0x95, 0x46, 0xae, 0x14, 0xb9, 0xf3, 0x0a, 0x9d, 0xb8, 0xe3, 0x5f, 0x22, 0xf9,
+ 0xa0, 0xd6, 0xb4, 0xec, 0x0a, 0x6e, 0x32, 0x9f, 0xc6, 0x82, 0x89, 0x67, 0xdd, 0x5f, 0x2a, 0x80,
+ 0x66, 0xc3, 0xbe, 0x2f, 0x88, 0x18, 0x67, 0xe8, 0x08, 0x20, 0x53, 0xd4, 0x16, 0xf7, 0x69, 0xc7,
+ 0x5a, 0xb5, 0xd6, 0x16, 0x37, 0x3e, 0xb9, 0x34, 0xf6, 0x67, 0x64, 0x7b, 0xfb, 0xa7, 0x82, 0xee,
+ 0xd5, 0x22, 0x77, 0xda, 0x5a, 0x91, 0x37, 0xe4, 0x3e, 0xc5, 0x33, 0x5a, 0xd1, 0xbb, 0xd0, 0x88,
+ 0x68, 0x96, 0x91, 0x80, 0xaa, 0xcb, 0x6d, 0xe9, 0xd0, 0x1b, 0x08, 0x97, 0x04, 0x72, 0xa0, 0x4e,
+ 0xd3, 0x94, 0xa7, 0x9d, 0xaa, 0x62, 0x6a, 0x15, 0xb9, 0xa3, 0x01, 0xac, 0xa7, 0xee, 0x77, 0x00,
+ 0xd3, 0x23, 0xd1, 0x35, 0xb8, 0xba, 0xb5, 0x37, 0x18, 0xf4, 0xb7, 0x0e, 0xbc, 0xc3, 0xc1, 0xc3,
+ 0xc1, 0xde, 0x93, 0x81, 0x7d, 0x05, 0x2d, 0x02, 0x94, 0xe0, 0xde, 0x43, 0xdb, 0x42, 0xcb, 0xf0,
+ 0x66, 0xb9, 0xc6, 0xfd, 0x07, 0xfd, 0xad, 0x83, 0xfe, 0xb6, 0xb7, 0x77, 0x70, 0xbf, 0x8f, 0xed,
+ 0x0a, 0xba, 0x01, 0x6f, 0x9d, 0xdb, 0xdb, 0x3e, 0x7c, 0xec, 0xed, 0x6e, 0xdb, 0xd5, 0xee, 0xaf,
+ 0x16, 0x2c, 0x9d, 0xcd, 0xd2, 0x2c, 0xe1, 0x71, 0x46, 0xd1, 0x01, 0xcc, 0xab, 0xa0, 0x78, 0xba,
+ 0x6a, 0x54, 0xc8, 0xda, 0x1b, 0xce, 0xab, 0x42, 0x36, 0x62, 0x81, 0x6b, 0x17, 0xb9, 0x73, 0x46,
+ 0x10, 0xeb, 0xba, 0xd4, 0xdb, 0xe8, 0x01, 0xcc, 0xe9, 0x80, 0x99, 0xf4, 0xbf, 0xf5, 0x7a, 0x57,
+ 0xe0, 0x42, 0x91, 0x3b, 0x46, 0x12, 0x9b, 0xb9, 0xbb, 0x34, 0xbd, 0x68, 0x79, 0x8e, 0x2e, 0xaf,
+ 0xee, 0xdf, 0x16, 0xb4, 0x67, 0xe0, 0xd9, 0x8a, 0xd1, 0x2e, 0xac, 0x5e, 0x7a, 0xe4, 0xab, 0x2b,
+ 0x66, 0x07, 0x1a, 0x21, 0x0f, 0x02, 0x9a, 0x96, 0xb6, 0x5f, 0xae, 0xe8, 0x11, 0x0f, 0x02, 0x16,
+ 0x07, 0x5a, 0x91, 0x11, 0xc2, 0x25, 0x21, 0x15, 0xe9, 0xd0, 0x64, 0x2a, 0x03, 0x2e, 0x51, 0x54,
+ 0x7a, 0x95, 0xf0, 0x54, 0x68, 0x45, 0x46, 0x08, 0x97, 0x44, 0xf7, 0x2f, 0x0b, 0xe6, 0x67, 0x0d,
+ 0x47, 0x6b, 0xd0, 0x1c, 0x51, 0x22, 0xc6, 0x29, 0x95, 0xce, 0x56, 0xd7, 0x5a, 0xee, 0x7c, 0x91,
+ 0x3b, 0xa7, 0x18, 0x3e, 0xa5, 0x50, 0x0f, 0x80, 0x4e, 0x04, 0x8d, 0x33, 0xc6, 0x63, 0xe9, 0x8f,
+ 0xe4, 0x5d, 0x2c, 0x72, 0x67, 0x06, 0xc5, 0x33, 0x34, 0xba, 0x09, 0x35, 0x41, 0x02, 0xdd, 0x74,
+ 0x5a, 0xba, 0x21, 0xc8, 0x35, 0x56, 0xa3, 0xcc, 0x68, 0x12, 0x32, 0x92, 0xa9, 0x6e, 0x62, 0x32,
+ 0x5a, 0x01, 0x58, 0x4f, 0xe8, 0x2e, 0xcc, 0x65, 0x34, 0x3d, 0xa1, 0x69, 0xa7, 0xae, 0x3c, 0x5e,
+ 0xbe, 0xc8, 0xe3, 0x7d, 0xc5, 0x61, 0xae, 0x5a, 0xd1, 0xd8, 0xcc, 0xdd, 0x1f, 0x2b, 0x30, 0xa7,
+ 0xb7, 0xa5, 0x25, 0xaa, 0x71, 0x59, 0xea, 0xa8, 0x97, 0x5b, 0xd3, 0x07, 0xd0, 0x0a, 0xd2, 0x64,
+ 0xe8, 0xc9, 0xa8, 0xa9, 0x6b, 0xaa, 0xbb, 0x0b, 0x45, 0xee, 0x4c, 0x41, 0xdc, 0x94, 0xe4, 0x63,
+ 0x9e, 0x0a, 0x69, 0xb5, 0xe0, 0xc7, 0x34, 0x9e, 0xad, 0x43, 0x05, 0x60, 0x3d, 0xe9, 0x7a, 0x16,
+ 0x29, 0x1b, 0x96, 0x8e, 0x99, 0x7a, 0x56, 0x10, 0x2e, 0x09, 0xc9, 0x36, 0xe4, 0x51, 0x44, 0x62,
+ 0x5f, 0x79, 0xd7, 0x2a, 0x6f, 0x4b, 0x41, 0xb8, 0x24, 0x90, 0x0b, 0x8d, 0x23, 0x32, 0x3c, 0xe6,
+ 0xa3, 0x51, 0x67, 0x4e, 0x05, 0xe1, 0xc6, 0x45, 0x41, 0x70, 0x35, 0x8b, 0xd6, 0x61, 0xf8, 0x71,
+ 0x49, 0x74, 0x7f, 0xab, 0x40, 0xc3, 0x70, 0xa0, 0xaf, 0xc0, 0x66, 0x31, 0x13, 0x8c, 0x84, 0x1e,
+ 0x8b, 0x05, 0x4d, 0x4f, 0x48, 0xa8, 0x82, 0x52, 0x75, 0x97, 0x8a, 0xdc, 0x39, 0xb7, 0x87, 0xaf,
+ 0x1a, 0x64, 0xd7, 0x00, 0xe8, 0x21, 0x2c, 0xa5, 0x24, 0xf6, 0x79, 0xc4, 0x9e, 0x13, 0xc1, 0x78,
+ 0xec, 0x8d, 0xc8, 0x50, 0xf0, 0x54, 0x85, 0xcd, 0x72, 0x3b, 0x45, 0xee, 0x5c, 0xb8, 0x8f, 0xaf,
+ 0x9d, 0x41, 0xef, 0x29, 0x50, 0x26, 0x54, 0x34, 0x0e, 0x05, 0x4b, 0x42, 0x46, 0x75, 0x67, 0xb3,
+ 0x74, 0x42, 0x4d, 0x51, 0x3c, 0x43, 0xa3, 0xdb, 0x30, 0x1f, 0x91, 0xc9, 0xd4, 0xf2, 0x9a, 0xb2,
+ 0x5c, 0x75, 0x8f, 0x59, 0x1c, 0xb7, 0x23, 0x32, 0x39, 0xb5, 0xf8, 0x2e, 0xd8, 0x72, 0x93, 0x86,
+ 0x24, 0xc9, 0xa8, 0xef, 0xc9, 0xa7, 0x58, 0x85, 0xdc, 0xb8, 0xfc, 0xf2, 0x1e, 0x5e, 0x8c, 0xc8,
+ 0xa4, 0xaf, 0x81, 0x03, 0x16, 0xd1, 0xee, 0xbf, 0x15, 0x53, 0x30, 0xa6, 0x40, 0xd1, 0x0e, 0xd4,
+ 0x43, 0x7a, 0x42, 0x43, 0xf3, 0x20, 0xdc, 0xfa, 0xbf, 0x8a, 0xee, 0x3d, 0x92, 0xdc, 0x3a, 0x55,
+ 0x94, 0x20, 0xd6, 0x13, 0xba, 0x0e, 0x55, 0x9f, 0xa5, 0xa6, 0xed, 0x37, 0x8a, 0xdc, 0x91, 0x4b,
+ 0x2c, 0x07, 0x99, 0xb0, 0x23, 0x16, 0x52, 0x93, 0x65, 0x2a, 0x61, 0xe5, 0x1a, 0xab, 0x11, 0xbd,
+ 0x07, 0x4d, 0x69, 0x76, 0xc6, 0x9e, 0x53, 0x15, 0x83, 0x05, 0x5d, 0xb2, 0x25, 0x86, 0x1b, 0x11,
+ 0x99, 0xec, 0xb3, 0xe7, 0x14, 0x7d, 0x0c, 0x32, 0x14, 0x9e, 0xcc, 0x84, 0x71, 0x92, 0x29, 0xb7,
+ 0x17, 0xf4, 0x73, 0x34, 0x03, 0x63, 0x88, 0xc8, 0xc4, 0xd5, 0x34, 0x7a, 0x07, 0xa4, 0xb0, 0x27,
+ 0x9f, 0xa3, 0x39, 0xc5, 0xad, 0xd3, 0x57, 0x43, 0x78, 0x2e, 0x22, 0x93, 0xcd, 0x80, 0xca, 0x9e,
+ 0x31, 0xe4, 0x51, 0x92, 0xd2, 0x2c, 0xeb, 0x34, 0x56, 0xad, 0xb5, 0xa6, 0x36, 0xa0, 0xc4, 0xf0,
+ 0x29, 0xd5, 0xfd, 0x12, 0xea, 0xca, 0x7d, 0xd4, 0x84, 0xda, 0xee, 0xe0, 0xde, 0x9e, 0x7d, 0x05,
+ 0xb5, 0xa0, 0xbe, 0xdd, 0x77, 0x0f, 0x77, 0x6c, 0x4b, 0x82, 0x4f, 0x36, 0xf1, 0xc0, 0xae, 0x48,
+ 0xb0, 0x8f, 0xf1, 0x1e, 0xb6, 0xab, 0x92, 0xbc, 0xb7, 0x79, 0xb0, 0xf9, 0xc8, 0xae, 0x75, 0x7f,
+ 0xae, 0x42, 0xeb, 0xf4, 0x5f, 0x23, 0x6b, 0xe6, 0x84, 0xa6, 0xb2, 0xb7, 0x98, 0x42, 0x56, 0xb6,
+ 0x19, 0x08, 0x97, 0x84, 0xcc, 0x12, 0x9f, 0x65, 0x49, 0x48, 0x9e, 0x79, 0x31, 0x89, 0xca, 0x67,
+ 0x55, 0x65, 0xc9, 0x2c, 0x8e, 0xdb, 0x66, 0x35, 0x20, 0x11, 0x95, 0x77, 0x21, 0x48, 0x60, 0x5a,
+ 0x95, 0xba, 0x0b, 0x41, 0x02, 0x2c, 0x07, 0xf4, 0x39, 0x2c, 0xb2, 0x38, 0x13, 0x24, 0x1e, 0x52,
+ 0x2f, 0x48, 0xf9, 0x38, 0x31, 0x15, 0x8b, 0x8a, 0xdc, 0x79, 0x69, 0x07, 0x2f, 0x94, 0xeb, 0x1d,
+ 0xb9, 0x44, 0x9b, 0xd0, 0x18, 0x27, 0x3e, 0x11, 0xd4, 0x37, 0xe5, 0xbb, 0xdc, 0xd3, 0x5f, 0xc3,
+ 0x5e, 0xf9, 0x35, 0xec, 0x1d, 0x94, 0x5f, 0x43, 0xed, 0x8d, 0x61, 0xc7, 0x25, 0x81, 0x3e, 0x02,
+ 0xc8, 0x9e, 0x65, 0x82, 0x46, 0xde, 0x98, 0xf9, 0x2a, 0xd8, 0xa6, 0xe9, 0x4e, 0x51, 0xdc, 0xd2,
+ 0xf4, 0x21, 0xf3, 0xd1, 0x37, 0xb0, 0xa0, 0x1f, 0xd2, 0xf2, 0xfd, 0x6a, 0xbe, 0xe6, 0xfb, 0xf5,
+ 0x46, 0x91, 0x3b, 0x67, 0x45, 0xb1, 0x7e, 0x92, 0xa7, 0x7f, 0xa6, 0x9a, 0x5d, 0x9f, 0x3a, 0xa8,
+ 0x62, 0xe8, 0x7e, 0xf6, 0xfb, 0x8b, 0x15, 0xeb, 0x8f, 0x17, 0x2b, 0xd6, 0x9f, 0x2f, 0x56, 0xac,
+ 0x6f, 0xdf, 0x0f, 0x98, 0x78, 0x3a, 0x3e, 0xea, 0x0d, 0x79, 0xb4, 0xae, 0x0e, 0x5b, 0x57, 0x1a,
+ 0xd6, 0x33, 0xff, 0x78, 0xfd, 0x64, 0x43, 0x7f, 0x87, 0xef, 0x68, 0xcf, 0xe7, 0xd4, 0x74, 0xfb,
+ 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd2, 0x4a, 0x40, 0x6e, 0x81, 0x0b, 0x00, 0x00,
}
func (m *AgentConnectRequest) Marshal() (dAtA []byte, err error) {
@@ -1070,6 +1276,18 @@ func (m *AgentDetails) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
+ if m.Server != nil {
+ {
+ size, err := m.Server.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintAgent(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x2a
+ }
if len(m.Alias) > 0 {
i -= len(m.Alias)
copy(dAtA[i:], m.Alias)
@@ -1107,6 +1325,132 @@ func (m *AgentDetails) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
+func (m *Server) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *Server) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *Server) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.XXX_unrecognized != nil {
+ i -= len(m.XXX_unrecognized)
+ copy(dAtA[i:], m.XXX_unrecognized)
+ }
+ if m.Backoff != nil {
+ {
+ size, err := m.Backoff.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintAgent(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x32
+ }
+ if len(m.Command) > 0 {
+ i -= len(m.Command)
+ copy(dAtA[i:], m.Command)
+ i = encodeVarintAgent(dAtA, i, uint64(len(m.Command)))
+ i--
+ dAtA[i] = 0x2a
+ }
+ if len(m.Metrics) > 0 {
+ i -= len(m.Metrics)
+ copy(dAtA[i:], m.Metrics)
+ i = encodeVarintAgent(dAtA, i, uint64(len(m.Metrics)))
+ i--
+ dAtA[i] = 0x22
+ }
+ if len(m.Token) > 0 {
+ i -= len(m.Token)
+ copy(dAtA[i:], m.Token)
+ i = encodeVarintAgent(dAtA, i, uint64(len(m.Token)))
+ i--
+ dAtA[i] = 0x1a
+ }
+ if m.GrpcPort != 0 {
+ i = encodeVarintAgent(dAtA, i, uint64(m.GrpcPort))
+ i--
+ dAtA[i] = 0x10
+ }
+ if len(m.Host) > 0 {
+ i -= len(m.Host)
+ copy(dAtA[i:], m.Host)
+ i = encodeVarintAgent(dAtA, i, uint64(len(m.Host)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *Backoff) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *Backoff) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *Backoff) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.XXX_unrecognized != nil {
+ i -= len(m.XXX_unrecognized)
+ copy(dAtA[i:], m.XXX_unrecognized)
+ }
+ if m.MaxElapsedTime != 0 {
+ i = encodeVarintAgent(dAtA, i, uint64(m.MaxElapsedTime))
+ i--
+ dAtA[i] = 0x28
+ }
+ if m.MaxInterval != 0 {
+ i = encodeVarintAgent(dAtA, i, uint64(m.MaxInterval))
+ i--
+ dAtA[i] = 0x20
+ }
+ if m.Multiplier != 0 {
+ i -= 8
+ encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.Multiplier))))
+ i--
+ dAtA[i] = 0x19
+ }
+ if m.RandomizationFactor != 0 {
+ i -= 8
+ encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.RandomizationFactor))))
+ i--
+ dAtA[i] = 0x11
+ }
+ if m.InitialInterval != 0 {
+ i = encodeVarintAgent(dAtA, i, uint64(m.InitialInterval))
+ i--
+ dAtA[i] = 0x8
+ }
+ return len(dAtA) - i, nil
+}
+
func (m *AgentLogging) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@@ -1416,6 +1760,72 @@ func (m *AgentDetails) Size() (n int) {
if l > 0 {
n += 1 + l + sovAgent(uint64(l))
}
+ if m.Server != nil {
+ l = m.Server.Size()
+ n += 1 + l + sovAgent(uint64(l))
+ }
+ if m.XXX_unrecognized != nil {
+ n += len(m.XXX_unrecognized)
+ }
+ return n
+}
+
+func (m *Server) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Host)
+ if l > 0 {
+ n += 1 + l + sovAgent(uint64(l))
+ }
+ if m.GrpcPort != 0 {
+ n += 1 + sovAgent(uint64(m.GrpcPort))
+ }
+ l = len(m.Token)
+ if l > 0 {
+ n += 1 + l + sovAgent(uint64(l))
+ }
+ l = len(m.Metrics)
+ if l > 0 {
+ n += 1 + l + sovAgent(uint64(l))
+ }
+ l = len(m.Command)
+ if l > 0 {
+ n += 1 + l + sovAgent(uint64(l))
+ }
+ if m.Backoff != nil {
+ l = m.Backoff.Size()
+ n += 1 + l + sovAgent(uint64(l))
+ }
+ if m.XXX_unrecognized != nil {
+ n += len(m.XXX_unrecognized)
+ }
+ return n
+}
+
+func (m *Backoff) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.InitialInterval != 0 {
+ n += 1 + sovAgent(uint64(m.InitialInterval))
+ }
+ if m.RandomizationFactor != 0 {
+ n += 9
+ }
+ if m.Multiplier != 0 {
+ n += 9
+ }
+ if m.MaxInterval != 0 {
+ n += 1 + sovAgent(uint64(m.MaxInterval))
+ }
+ if m.MaxElapsedTime != 0 {
+ n += 1 + sovAgent(uint64(m.MaxElapsedTime))
+ }
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@@ -2320,6 +2730,406 @@ func (m *AgentDetails) Unmarshal(dAtA []byte) error {
}
m.Alias = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
+ case 5:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Server", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowAgent
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthAgent
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthAgent
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Server == nil {
+ m.Server = &Server{}
+ }
+ if err := m.Server.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipAgent(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthAgent
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *Server) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowAgent
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: Server: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: Server: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Host", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowAgent
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthAgent
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthAgent
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Host = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field GrpcPort", wireType)
+ }
+ m.GrpcPort = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowAgent
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.GrpcPort |= int32(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 3:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Token", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowAgent
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthAgent
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthAgent
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Token = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 4:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Metrics", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowAgent
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthAgent
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthAgent
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Metrics = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 5:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Command", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowAgent
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthAgent
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthAgent
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Command = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 6:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Backoff", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowAgent
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthAgent
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthAgent
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.Backoff == nil {
+ m.Backoff = &Backoff{}
+ }
+ if err := m.Backoff.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipAgent(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthAgent
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *Backoff) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowAgent
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: Backoff: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: Backoff: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field InitialInterval", wireType)
+ }
+ m.InitialInterval = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowAgent
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.InitialInterval |= int64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 2:
+ if wireType != 1 {
+ return fmt.Errorf("proto: wrong wireType = %d for field RandomizationFactor", wireType)
+ }
+ var v uint64
+ if (iNdEx + 8) > l {
+ return io.ErrUnexpectedEOF
+ }
+ v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
+ iNdEx += 8
+ m.RandomizationFactor = float64(math.Float64frombits(v))
+ case 3:
+ if wireType != 1 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Multiplier", wireType)
+ }
+ var v uint64
+ if (iNdEx + 8) > l {
+ return io.ErrUnexpectedEOF
+ }
+ v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:]))
+ iNdEx += 8
+ m.Multiplier = float64(math.Float64frombits(v))
+ case 4:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field MaxInterval", wireType)
+ }
+ m.MaxInterval = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowAgent
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.MaxInterval |= int64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ case 5:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field MaxElapsedTime", wireType)
+ }
+ m.MaxElapsedTime = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowAgent
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.MaxElapsedTime |= int64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
default:
iNdEx = preIndex
skippy, err := skipAgent(dAtA[iNdEx:])
diff --git a/sdk/proto/agent.proto b/sdk/proto/agent.proto
index ef7d6b720..e05aaf335 100644
--- a/sdk/proto/agent.proto
+++ b/sdk/proto/agent.proto
@@ -80,6 +80,37 @@ message AgentDetails {
repeated string tags = 3 [(gogoproto.jsontag) = "tags"];
// Alias name for the agent
string alias = 4 [(gogoproto.jsontag) = "alias"];
+ // Server setting for the agent
+ Server server = 5 [(gogoproto.jsontag) = "server"];
+}
+
+message Server {
+ // Host name or IP of the host to connect to
+ string host = 1 [(gogoproto.jsontag) = "host"];
+ // Grpc port to connect to
+ int32 grpc_port = 2 [(gogoproto.jsontag) = "grpc_port"];
+ // Shared secrect between the server and client
+ string token = 3 [(gogoproto.jsontag) = "token"];
+ // Metrics server name
+ string metrics = 4 [(gogoproto.jsontag) = "metrics"];
+ // Command server name
+ string command = 5 [(gogoproto.jsontag) = "command"];
+ // Backoff settings for exponential retry and backoff
+ Backoff backoff = 6 [(gogoproto.jsontag) = "backoff"];
+}
+
+message Backoff {
+ // First backoff time interval in seconds
+ int64 initial_interval = 1 [(gogoproto.jsontag) = "initial_interval"];
+ // Random value used to create range around next backoff interval
+ double randomization_factor = 2 [(gogoproto.jsontag) = "randomization_factor"];
+ // Value to be multiplied with current backoff interval
+ double multiplier = 3 [(gogoproto.jsontag) = "multiplier"];
+ // Max interval in seconds between two retries
+ int64 max_interval = 4 [(gogoproto.jsontag) = "max_interval"];
+ // Elapsed time in seconds after which backoff stops.
+ // It never stops if max_elapsed_time == 0.
+ int64 max_elapsed_time = 5 [(gogoproto.jsontag) = "max_elapsed_time"];
}
// Represents agent logging details
diff --git a/sdk/proto/events/event.pb.go b/sdk/proto/events/event.pb.go
index a6bba3fd8..e352f827c 100644
--- a/sdk/proto/events/event.pb.go
+++ b/sdk/proto/events/event.pb.go
@@ -336,48 +336,85 @@ func (m *ActivityEvent) GetDimensions() []*common.Dimension {
// Represents a security violation that is emitted by the agent
type SecurityViolationEvent struct {
- PolicyName string `protobuf:"bytes,1,opt,name=PolicyName,proto3" json:"policy_name"`
- SupportID string `protobuf:"bytes,2,opt,name=SupportID,proto3" json:"support_id"`
- Outcome string `protobuf:"bytes,3,opt,name=Outcome,proto3" json:"outcome"`
- OutcomeReason string `protobuf:"bytes,4,opt,name=OutcomeReason,proto3" json:"outcome_reason"`
- BlockingExceptionReason string `protobuf:"bytes,5,opt,name=BlockingExceptionReason,proto3" json:"blocking_exception_reason"`
- Method string `protobuf:"bytes,6,opt,name=Method,proto3" json:"method"`
- Protocol string `protobuf:"bytes,7,opt,name=Protocol,proto3" json:"protocol"`
- XForwardedForHeaderValue string `protobuf:"bytes,8,opt,name=XForwardedForHeaderValue,proto3" json:"xff_header_value"`
- URI string `protobuf:"bytes,9,opt,name=URI,proto3" json:"uri"`
- Request string `protobuf:"bytes,10,opt,name=Request,proto3" json:"request"`
- IsTruncated string `protobuf:"bytes,11,opt,name=IsTruncated,proto3" json:"is_truncated"`
- RequestStatus string `protobuf:"bytes,12,opt,name=RequestStatus,proto3" json:"request_status"`
- ResponseCode string `protobuf:"bytes,13,opt,name=ResponseCode,proto3" json:"response_code"`
- ServerAddr string `protobuf:"bytes,14,opt,name=ServerAddr,proto3" json:"server_addr"`
- VSName string `protobuf:"bytes,15,opt,name=VSName,proto3" json:"vs_name"`
- RemoteAddr string `protobuf:"bytes,16,opt,name=RemoteAddr,proto3" json:"remote_addr"`
- RemotePort string `protobuf:"bytes,17,opt,name=RemotePort,proto3" json:"destination_port"`
- ServerPort string `protobuf:"bytes,18,opt,name=ServerPort,proto3" json:"server_port"`
- Violations string `protobuf:"bytes,19,opt,name=Violations,proto3" json:"violations"`
- SubViolations string `protobuf:"bytes,20,opt,name=SubViolations,proto3" json:"sub_violations"`
- ViolationRating string `protobuf:"bytes,21,opt,name=ViolationRating,proto3" json:"violation_rating"`
- SigSetNames string `protobuf:"bytes,22,opt,name=SigSetNames,proto3" json:"sig_set_names"`
- SigCVEs string `protobuf:"bytes,23,opt,name=SigCVEs,proto3" json:"sig_cves"`
- ClientClass string `protobuf:"bytes,24,opt,name=ClientClass,proto3" json:"client_class"`
- ClientApplication string `protobuf:"bytes,25,opt,name=ClientApplication,proto3" json:"client_application"`
- ClientApplicationVersion string `protobuf:"bytes,26,opt,name=ClientApplicationVersion,proto3" json:"client_application_version"`
- Severity string `protobuf:"bytes,27,opt,name=Severity,proto3" json:"severity"`
- ThreatCampaignNames string `protobuf:"bytes,28,opt,name=ThreatCampaignNames,proto3" json:"threat_campaign_names"`
- BotAnomalies string `protobuf:"bytes,29,opt,name=BotAnomalies,proto3" json:"bot_anomalies"`
- BotCategory string `protobuf:"bytes,30,opt,name=BotCategory,proto3" json:"bot_category"`
- EnforcedBotAnomalies string `protobuf:"bytes,31,opt,name=EnforcedBotAnomalies,proto3" json:"enforced_bot_anomalies"`
- BotSignatureName string `protobuf:"bytes,32,opt,name=BotSignatureName,proto3" json:"bot_signature_name"`
- ViolationContexts string `protobuf:"bytes,33,opt,name=ViolationContexts,proto3" json:"violation_contexts"`
- ViolationsData []*ViolationData `protobuf:"bytes,34,rep,name=ViolationsData,proto3" json:"violations_data"`
- SystemID string `protobuf:"bytes,35,opt,name=SystemID,proto3" json:"system_id"`
- InstanceTags string `protobuf:"bytes,36,opt,name=InstanceTags,proto3" json:"instance_tags"`
- InstanceGroup string `protobuf:"bytes,37,opt,name=InstanceGroup,proto3" json:"instance_group"`
- DisplayName string `protobuf:"bytes,38,opt,name=DisplayName,proto3" json:"display_name"`
- ParentHostname string `protobuf:"bytes,40,opt,name=ParentHostname,proto3" json:"parent_hostname"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ // The name of the NGINX App Protect policy that triggered the security violation
+ PolicyName string `protobuf:"bytes,1,opt,name=PolicyName,proto3" json:"policy_name"`
+ // The unique NGINX App Protect support ID of the violation, used for tracking purposes
+ SupportID string `protobuf:"bytes,2,opt,name=SupportID,proto3" json:"support_id"`
+ // The outcome that resulted for the security violation
+ Outcome string `protobuf:"bytes,3,opt,name=Outcome,proto3" json:"outcome"`
+ // The reason for the security violation resulting in the outcome
+ OutcomeReason string `protobuf:"bytes,4,opt,name=OutcomeReason,proto3" json:"outcome_reason"`
+ // The blocking exception reason when a configured violation was not blocked
+ BlockingExceptionReason string `protobuf:"bytes,5,opt,name=BlockingExceptionReason,proto3" json:"blocking_exception_reason"`
+ // The HTTP Method of the request that triggered the security violation
+ Method string `protobuf:"bytes,6,opt,name=Method,proto3" json:"method"`
+ // The HTTP Protocol of the request that triggered the security violation
+ Protocol string `protobuf:"bytes,7,opt,name=Protocol,proto3" json:"protocol"`
+ // The HTTP xff_header_value of the request that triggered the security violation
+ XForwardedForHeaderValue string `protobuf:"bytes,8,opt,name=XForwardedForHeaderValue,proto3" json:"xff_header_value"`
+ // The URI of the request that triggered the security violation
+ URI string `protobuf:"bytes,9,opt,name=URI,proto3" json:"uri"`
+ // The full request that triggered the security violation, including the Method, URI and Request Body
+ Request string `protobuf:"bytes,10,opt,name=Request,proto3" json:"request"`
+ // If the request is truncated or not
+ IsTruncated string `protobuf:"bytes,11,opt,name=IsTruncated,proto3" json:"is_truncated"`
+ // The status of the request that triggered the security violation
+ RequestStatus string `protobuf:"bytes,12,opt,name=RequestStatus,proto3" json:"request_status"`
+ // The HTTP response status to the request that triggered the security violation
+ ResponseCode string `protobuf:"bytes,13,opt,name=ResponseCode,proto3" json:"response_code"`
+ // The server address of the instance that caught the security violation
+ ServerAddr string `protobuf:"bytes,14,opt,name=ServerAddr,proto3" json:"server_addr"`
+ // The Virtual Server Name of the instance that caught the security violation
+ VSName string `protobuf:"bytes,15,opt,name=VSName,proto3" json:"vs_name"`
+ // The targeted address by the request that triggered the security violation
+ RemoteAddr string `protobuf:"bytes,16,opt,name=RemoteAddr,proto3" json:"remote_addr"`
+ // The targeted port number by the request that triggered the security violation
+ RemotePort string `protobuf:"bytes,17,opt,name=RemotePort,proto3" json:"destination_port"`
+ // The server port of the instance that caught the security violation
+ ServerPort string `protobuf:"bytes,18,opt,name=ServerPort,proto3" json:"server_port"`
+ // A comma-separated list of all the violations triggered by the request
+ Violations string `protobuf:"bytes,19,opt,name=Violations,proto3" json:"violations"`
+ // A comma-separated list of all the sub-violations triggered by the request
+ SubViolations string `protobuf:"bytes,20,opt,name=SubViolations,proto3" json:"sub_violations"`
+ // The rating of the triggered security violation
+ ViolationRating string `protobuf:"bytes,21,opt,name=ViolationRating,proto3" json:"violation_rating"`
+ // A comma-separated list of all the signature names
+ SigSetNames string `protobuf:"bytes,22,opt,name=SigSetNames,proto3" json:"sig_set_names"`
+ // A comma-separated list of all the signature CVEs
+ SigCVEs string `protobuf:"bytes,23,opt,name=SigCVEs,proto3" json:"sig_cves"`
+ // The class of the client used to send the request that triggered the security violation
+ ClientClass string `protobuf:"bytes,24,opt,name=ClientClass,proto3" json:"client_class"`
+ // The application used to send the request that triggered the security violation
+ ClientApplication string `protobuf:"bytes,25,opt,name=ClientApplication,proto3" json:"client_application"`
+ // The version of the application used to send the request that triggered the security violation
+ ClientApplicationVersion string `protobuf:"bytes,26,opt,name=ClientApplicationVersion,proto3" json:"client_application_version"`
+ // The severity of the triggered security violation
+ Severity string `protobuf:"bytes,27,opt,name=Severity,proto3" json:"severity"`
+ // A comma-separated list of the threat campaign names
+ ThreatCampaignNames string `protobuf:"bytes,28,opt,name=ThreatCampaignNames,proto3" json:"threat_campaign_names"`
+ // Anomalies of the bot that sent the request that triggered the security violation
+ BotAnomalies string `protobuf:"bytes,29,opt,name=BotAnomalies,proto3" json:"bot_anomalies"`
+ // Category of the bot that sent the request that triggered the security violation
+ BotCategory string `protobuf:"bytes,30,opt,name=BotCategory,proto3" json:"bot_category"`
+ // Enforced anomalies of the bot that sent the request that triggered the security violation
+ EnforcedBotAnomalies string `protobuf:"bytes,31,opt,name=EnforcedBotAnomalies,proto3" json:"enforced_bot_anomalies"`
+ // Signature name of the bot that sent the request that triggered the security violation
+ BotSignatureName string `protobuf:"bytes,32,opt,name=BotSignatureName,proto3" json:"bot_signature_name"`
+ // A list of objects containing descriptive data about all the security violations
+ ViolationsData []*ViolationData `protobuf:"bytes,34,rep,name=ViolationsData,proto3" json:"violations_data"`
+ // SystemID of the instance where NGINX is running
+ SystemID string `protobuf:"bytes,35,opt,name=SystemID,proto3" json:"system_id"`
+ // Instance tags where NGINX is running
+ InstanceTags string `protobuf:"bytes,36,opt,name=InstanceTags,proto3" json:"instance_tags"`
+ // Instance group where NGINX is running
+ InstanceGroup string `protobuf:"bytes,37,opt,name=InstanceGroup,proto3" json:"instance_group"`
+ // Display name of the instance where NGINX is running
+ DisplayName string `protobuf:"bytes,38,opt,name=DisplayName,proto3" json:"display_name"`
+ // The hostname where NGINX is running
+ ParentHostname string `protobuf:"bytes,40,opt,name=ParentHostname,proto3" json:"parent_hostname"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}
func (m *SecurityViolationEvent) Reset() { *m = SecurityViolationEvent{} }
@@ -637,13 +674,6 @@ func (m *SecurityViolationEvent) GetBotSignatureName() string {
return ""
}
-func (m *SecurityViolationEvent) GetViolationContexts() string {
- if m != nil {
- return m.ViolationContexts
- }
- return ""
-}
-
func (m *SecurityViolationEvent) GetViolationsData() []*ViolationData {
if m != nil {
return m.ViolationsData
@@ -686,11 +716,17 @@ func (m *SecurityViolationEvent) GetParentHostname() string {
return ""
}
+// Represents signature data that's contained within each violation
type SignatureData struct {
- ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"sig_data_id"`
- BlockingMask string `protobuf:"bytes,2,opt,name=BlockingMask,proto3" json:"sig_data_blocking_mask"`
- Buffer string `protobuf:"bytes,3,opt,name=Buffer,proto3" json:"sig_data_buffer"`
- Offset string `protobuf:"bytes,4,opt,name=Offset,proto3" json:"sig_data_offset"`
+ // ID of the signature data
+ ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"sig_data_id"`
+ // The blocking mask of the signature data
+ BlockingMask string `protobuf:"bytes,2,opt,name=BlockingMask,proto3" json:"sig_data_blocking_mask"`
+ // The buffer of the signature data
+ Buffer string `protobuf:"bytes,3,opt,name=Buffer,proto3" json:"sig_data_buffer"`
+ // The offset of the signature data
+ Offset string `protobuf:"bytes,4,opt,name=Offset,proto3" json:"sig_data_offset"`
+ // The length of the signature data
Length string `protobuf:"bytes,5,opt,name=Length,proto3" json:"sig_data_length"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
@@ -765,8 +801,11 @@ func (m *SignatureData) GetLength() string {
return ""
}
+// Represents the context data of each violation
type ContextData struct {
- Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"parameter_data_name"`
+ // The name within the context data
+ Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"parameter_data_name"`
+ // The value within the context data
Value string `protobuf:"bytes,2,opt,name=Value,proto3" json:"parameter_data_value"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
@@ -820,10 +859,15 @@ func (m *ContextData) GetValue() string {
return ""
}
+// Represents the violation data contained within a security violation event
type ViolationData struct {
- Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"violation_data_name"`
- Context string `protobuf:"bytes,2,opt,name=Context,proto3" json:"violation_data_context"`
- ContextData *ContextData `protobuf:"bytes,3,opt,name=ContextData,proto3" json:"violation_data_context_data"`
+ // The name of the violation
+ Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"violation_data_name"`
+ // The context of the violation
+ Context string `protobuf:"bytes,2,opt,name=Context,proto3" json:"violation_data_context"`
+ // The object representing the context data of the violation
+ ContextData *ContextData `protobuf:"bytes,3,opt,name=ContextData,proto3" json:"violation_data_context_data"`
+ // A list representing the signature data of the violation
Signatures []*SignatureData `protobuf:"bytes,4,rep,name=Signatures,proto3" json:"violation_data_signatures"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
@@ -905,110 +949,110 @@ func init() {
func init() { proto.RegisterFile("event.proto", fileDescriptor_2d17a9d3f0ddf27e) }
var fileDescriptor_2d17a9d3f0ddf27e = []byte{
- // 1644 bytes of a gzipped FileDescriptorProto
+ // 1638 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x57, 0xdd, 0x6e, 0xdc, 0xc6,
- 0x15, 0xee, 0x4a, 0xb2, 0x7e, 0x66, 0x25, 0x59, 0x1e, 0x39, 0xf6, 0x48, 0x71, 0x44, 0x75, 0x9d,
- 0xb8, 0x2a, 0x52, 0xac, 0x50, 0x25, 0x01, 0x0a, 0x04, 0x08, 0xe0, 0xd5, 0x3a, 0xc9, 0xb6, 0x91,
- 0x23, 0xcc, 0xca, 0x6a, 0x91, 0x1b, 0x62, 0x44, 0xce, 0x52, 0xac, 0x76, 0x39, 0x2c, 0x67, 0xb8,
- 0xb5, 0x1e, 0xa1, 0x40, 0x9f, 0xaa, 0x17, 0x45, 0x2e, 0xf3, 0x04, 0x44, 0xe1, 0x4b, 0xbe, 0x40,
- 0x6f, 0x8b, 0x39, 0x33, 0xe4, 0x90, 0xfa, 0xeb, 0x95, 0xcd, 0xf3, 0x7d, 0xdf, 0x39, 0x33, 0xe7,
- 0x67, 0xf6, 0x08, 0x75, 0xf9, 0x9c, 0x27, 0xaa, 0x9f, 0x66, 0x42, 0x09, 0xbc, 0x33, 0xf9, 0xaa,
- 0x9f, 0x44, 0x71, 0xf2, 0xbe, 0xcf, 0x22, 0x6d, 0x95, 0xe1, 0x55, 0x1f, 0x70, 0xb9, 0xbb, 0x1d,
- 0x88, 0xd9, 0x4c, 0x24, 0x87, 0xe6, 0x1f, 0xc3, 0xdf, 0x45, 0x91, 0x88, 0x84, 0xfd, 0xbf, 0x17,
- 0x09, 0x11, 0x4d, 0xf9, 0x21, 0x7c, 0x5d, 0xe4, 0x93, 0x43, 0x15, 0xcf, 0xb8, 0x54, 0x6c, 0x96,
- 0x1a, 0x42, 0xef, 0xe7, 0x05, 0xb4, 0x7a, 0xc2, 0x15, 0x0b, 0x99, 0x62, 0xb8, 0x87, 0x96, 0x4f,
- 0x44, 0x98, 0x4f, 0x39, 0xe9, 0xec, 0x77, 0x0e, 0xd6, 0x06, 0xa8, 0x2c, 0xbc, 0xe5, 0x19, 0x58,
- 0xa8, 0x45, 0xf0, 0x0b, 0xb4, 0xf4, 0xee, 0xdd, 0x68, 0x48, 0x16, 0x80, 0xb1, 0x5a, 0x16, 0xde,
- 0x52, 0x9e, 0xc7, 0x21, 0x05, 0x2b, 0xfe, 0x03, 0xda, 0x38, 0x16, 0x59, 0xc6, 0xa7, 0x4c, 0xc5,
- 0x22, 0x19, 0x0d, 0xc9, 0x22, 0xd0, 0x70, 0x59, 0x78, 0x9b, 0x81, 0x03, 0xfc, 0x38, 0xa4, 0x6d,
- 0x22, 0xfe, 0x0e, 0xad, 0x9d, 0x55, 0x67, 0x23, 0x4b, 0xfb, 0x9d, 0x83, 0xee, 0xd1, 0x6e, 0xdf,
- 0x9c, 0xbe, 0x5f, 0x9d, 0xbe, 0x5f, 0x33, 0x06, 0x1b, 0x65, 0xe1, 0xad, 0xd5, 0x97, 0xa1, 0x4e,
- 0x8b, 0x0f, 0x11, 0x7a, 0xa3, 0xb3, 0xf3, 0x03, 0x9f, 0xf3, 0x29, 0x79, 0x04, 0xf1, 0x1f, 0x97,
- 0x85, 0x67, 0x72, 0xea, 0x4f, 0xb5, 0x99, 0x36, 0x28, 0xfa, 0x46, 0x67, 0xd7, 0x29, 0x27, 0xcb,
- 0xee, 0x46, 0xea, 0x3a, 0xe5, 0x14, 0xac, 0xf8, 0x00, 0xad, 0x1e, 0x33, 0xc5, 0x23, 0x91, 0x5d,
- 0x93, 0x15, 0x60, 0xac, 0x97, 0x85, 0xb7, 0x1a, 0x58, 0x1b, 0xad, 0xd1, 0xde, 0x2f, 0x0b, 0xe8,
- 0x11, 0xb8, 0xc5, 0x27, 0x2e, 0xa7, 0x90, 0xc9, 0xee, 0xd1, 0xcb, 0xfe, 0xbd, 0x45, 0xec, 0x57,
- 0x54, 0xe3, 0x78, 0x66, 0xbf, 0xa8, 0x2b, 0x4b, 0x88, 0x36, 0x5e, 0x07, 0x2a, 0x9e, 0xc7, 0xea,
- 0x1a, 0xfc, 0x43, 0xee, 0xbb, 0x47, 0x07, 0x0f, 0xf8, 0x6c, 0xf1, 0x4d, 0xfa, 0x99, 0x35, 0xf9,
- 0x40, 0xf9, 0xfe, 0x57, 0xb4, 0xed, 0x14, 0xff, 0xa3, 0x83, 0x9e, 0x8d, 0x79, 0x90, 0x67, 0xb1,
- 0xba, 0x3e, 0x8f, 0x85, 0x29, 0x8c, 0x89, 0xb7, 0x08, 0xf1, 0x7e, 0xff, 0x40, 0xbc, 0xbb, 0x85,
- 0x83, 0x17, 0x65, 0xe1, 0x11, 0x69, 0x31, 0x7f, 0x5e, 0x81, 0xf5, 0x11, 0xee, 0x09, 0x38, 0x58,
- 0x46, 0x4b, 0xfa, 0xe6, 0xbd, 0x31, 0xea, 0x82, 0x81, 0xf2, 0x54, 0x64, 0x0a, 0x0f, 0xd1, 0x32,
- 0x7c, 0x4a, 0xd2, 0xd9, 0x5f, 0x3c, 0xe8, 0x1e, 0xed, 0x3f, 0x70, 0x22, 0xe3, 0x08, 0x3a, 0xd8,
- 0x58, 0xa8, 0xd5, 0xf6, 0xfe, 0xd9, 0xb9, 0x91, 0x4f, 0xfc, 0x19, 0x5a, 0x39, 0xe1, 0x52, 0xb2,
- 0xa8, 0x6a, 0xfc, 0x6e, 0x59, 0x78, 0x2b, 0x33, 0x63, 0xa2, 0x15, 0x86, 0xcf, 0x10, 0x1a, 0xc6,
- 0x33, 0x9e, 0xc8, 0x58, 0x24, 0x92, 0x2c, 0xc0, 0x11, 0x3e, 0xbd, 0xeb, 0x08, 0x76, 0x1c, 0x6b,
- 0xf2, 0x60, 0xb3, 0x2c, 0x3c, 0x14, 0xd6, 0x5a, 0xda, 0xf0, 0xd3, 0xfb, 0xd7, 0x93, 0xfb, 0xf2,
- 0xae, 0x5b, 0xf9, 0x54, 0x4c, 0xe3, 0xe0, 0xfa, 0x2d, 0x9b, 0x55, 0x47, 0x83, 0x56, 0x4e, 0xc1,
- 0xea, 0x27, 0x6c, 0xc6, 0x69, 0x83, 0x82, 0x7f, 0x87, 0xd6, 0xc6, 0x79, 0xaa, 0x73, 0x55, 0x4f,
- 0x28, 0x84, 0x96, 0xc6, 0xa8, 0xc7, 0xce, 0x11, 0xf4, 0xb5, 0x7f, 0xcc, 0x55, 0x20, 0x66, 0xdc,
- 0x8e, 0x29, 0x5c, 0x5b, 0x18, 0x13, 0xad, 0x30, 0x3d, 0xd3, 0xf6, 0xbf, 0x94, 0x33, 0x29, 0x12,
- 0x98, 0x4e, 0x3b, 0xd3, 0x96, 0xec, 0x67, 0x80, 0xd0, 0x36, 0x11, 0xff, 0x19, 0x3d, 0x1f, 0x4c,
- 0x45, 0x70, 0x15, 0x27, 0xd1, 0x9b, 0xf7, 0x01, 0x4f, 0xf5, 0xcd, 0xac, 0x0f, 0x33, 0x97, 0x9f,
- 0x94, 0x85, 0xb7, 0x73, 0x61, 0x29, 0x3e, 0xaf, 0x38, 0x95, 0xbb, 0xfb, 0xd4, 0xf0, 0x50, 0x71,
- 0x75, 0x29, 0x42, 0x3b, 0xb4, 0xe6, 0xa1, 0x02, 0x0b, 0xb5, 0x88, 0x1e, 0xdc, 0x53, 0xfd, 0x6e,
- 0x04, 0x62, 0xda, 0x1c, 0xdc, 0xd4, 0xda, 0x68, 0x8d, 0xe2, 0x53, 0x44, 0xfe, 0xf2, 0xad, 0xc8,
- 0xfe, 0xce, 0xb2, 0x90, 0x87, 0xdf, 0x8a, 0xec, 0x7b, 0xce, 0x42, 0x9e, 0x9d, 0xb3, 0x69, 0xce,
- 0xc9, 0x2a, 0x28, 0x9f, 0x96, 0x85, 0xb7, 0xf5, 0x7e, 0x32, 0xf1, 0x2f, 0x01, 0xf2, 0xe7, 0x1a,
- 0xa3, 0xf7, 0xaa, 0xf0, 0x0e, 0x5a, 0x7c, 0x47, 0x47, 0x64, 0x0d, 0xc4, 0x2b, 0x65, 0xe1, 0x2d,
- 0xe6, 0x59, 0x4c, 0xb5, 0x4d, 0x27, 0x9d, 0xf2, 0xbf, 0xe5, 0x5c, 0x2a, 0x82, 0x5c, 0xd2, 0x33,
- 0x63, 0xa2, 0x15, 0x86, 0x8f, 0x50, 0x77, 0x24, 0xcf, 0xb2, 0x3c, 0xd1, 0x0f, 0x4d, 0x48, 0xba,
- 0x40, 0xdd, 0x2a, 0x0b, 0x6f, 0x3d, 0x96, 0xbe, 0xaa, 0xec, 0xb4, 0x49, 0xd2, 0x85, 0xb2, 0xf2,
- 0xb1, 0x62, 0x2a, 0x97, 0x64, 0xdd, 0x15, 0xca, 0x06, 0xf0, 0x25, 0x20, 0xb4, 0x4d, 0xc4, 0x5f,
- 0xa1, 0x75, 0xca, 0x65, 0x2a, 0x12, 0xc9, 0x8f, 0x45, 0xc8, 0xc9, 0x06, 0x08, 0x9f, 0x94, 0x85,
- 0xb7, 0x91, 0x59, 0xbb, 0x1f, 0x88, 0x90, 0xd3, 0x16, 0x4d, 0xf7, 0xe7, 0x98, 0x67, 0x73, 0x9e,
- 0xbd, 0x0e, 0xc3, 0x8c, 0x6c, 0xba, 0xfe, 0x94, 0x60, 0xf5, 0x59, 0x18, 0x66, 0xb4, 0x41, 0xc1,
- 0x2f, 0xd1, 0xf2, 0xf9, 0x18, 0x9a, 0xf9, 0xb1, 0xbb, 0xfb, 0x5c, 0x9a, 0x46, 0xb6, 0x90, 0xf6,
- 0x4a, 0xf9, 0x4c, 0x28, 0x0e, 0x5e, 0xb7, 0x9c, 0xd7, 0x0c, 0xac, 0xd6, 0xab, 0xa3, 0xe0, 0x2f,
- 0x2b, 0xc1, 0xa9, 0xc8, 0x14, 0x79, 0xe2, 0x2a, 0x16, 0x72, 0xa9, 0xe2, 0xc4, 0x3c, 0x39, 0xba,
- 0xe7, 0x69, 0x83, 0xe7, 0x0e, 0x0f, 0x2a, 0x7c, 0xeb, 0xf0, 0x46, 0xe0, 0x28, 0xb8, 0x8f, 0x50,
- 0x3d, 0x9f, 0x92, 0x6c, 0xbb, 0xe9, 0xaa, 0xdf, 0x35, 0x49, 0x1b, 0x0c, 0x5d, 0x8e, 0x71, 0x7e,
- 0xd1, 0x90, 0x3c, 0x75, 0xe5, 0x90, 0xf9, 0x85, 0xdf, 0x90, 0xb5, 0x89, 0xf8, 0x1b, 0xf4, 0xb8,
- 0xfe, 0xa2, 0x4c, 0xc5, 0x49, 0x44, 0x3e, 0x72, 0xb7, 0x72, 0xcf, 0x68, 0x06, 0x18, 0xbd, 0x49,
- 0xc6, 0x5f, 0xa0, 0xee, 0x38, 0x8e, 0xc6, 0x5c, 0xe9, 0x7c, 0x4a, 0xf2, 0xcc, 0x55, 0x53, 0xc6,
- 0x91, 0x2f, 0xb9, 0x82, 0x84, 0x4b, 0xda, 0x64, 0xe1, 0x57, 0x68, 0x65, 0x1c, 0x47, 0xc7, 0xe7,
- 0x6f, 0x24, 0x79, 0xee, 0xc6, 0x45, 0x0b, 0x82, 0x39, 0x97, 0xb4, 0x02, 0x75, 0x67, 0x1e, 0x4f,
- 0x63, 0x9e, 0xa8, 0xe3, 0x29, 0x93, 0x92, 0x10, 0xd7, 0x99, 0x01, 0x98, 0xfd, 0x40, 0xdb, 0x69,
- 0x93, 0x84, 0x87, 0xe8, 0x89, 0xf9, 0x7c, 0x9d, 0xa6, 0xd3, 0x38, 0x80, 0xb3, 0x92, 0x1d, 0x50,
- 0x3e, 0x2b, 0x0b, 0x0f, 0x5b, 0x25, 0x73, 0x28, 0xbd, 0x2d, 0xc0, 0x3f, 0x21, 0x72, 0xcb, 0x78,
- 0xce, 0x33, 0xfd, 0x8c, 0x92, 0x5d, 0x70, 0xb6, 0x57, 0x16, 0xde, 0xee, 0x6d, 0x67, 0xfe, 0xdc,
- 0xb0, 0xe8, 0xbd, 0x7a, 0xfd, 0x5a, 0x8c, 0xf9, 0x9c, 0xeb, 0x47, 0x98, 0x7c, 0xdc, 0xb8, 0xbe,
- 0xb5, 0xd1, 0x1a, 0xc5, 0x7f, 0x42, 0xdb, 0x67, 0x97, 0x19, 0x67, 0xea, 0x98, 0xcd, 0x52, 0x16,
- 0x47, 0x89, 0x49, 0xf2, 0x0b, 0x10, 0xed, 0x94, 0x85, 0xf7, 0x91, 0x02, 0xd8, 0x0f, 0x2c, 0x6e,
- 0x93, 0x7d, 0x97, 0x4a, 0x0f, 0xde, 0x40, 0xa8, 0xd7, 0x89, 0x98, 0xb1, 0x69, 0xcc, 0x25, 0xf9,
- 0xc4, 0x95, 0xea, 0x42, 0x28, 0x9f, 0x55, 0x00, 0x6d, 0xd1, 0x74, 0x0d, 0x06, 0x42, 0xd5, 0x7b,
- 0xc9, 0x9e, 0xab, 0x81, 0x56, 0xd5, 0xbb, 0x49, 0x93, 0x84, 0xdf, 0xa2, 0xa7, 0x6f, 0x92, 0x89,
- 0xc8, 0x02, 0x1e, 0xb6, 0x42, 0x7a, 0x20, 0xde, 0x2d, 0x0b, 0xef, 0x19, 0xb7, 0xb8, 0xdf, 0x8e,
- 0x7d, 0xa7, 0x0e, 0x0f, 0xd0, 0xd6, 0x40, 0xa8, 0x71, 0x1c, 0x25, 0x4c, 0xe5, 0x19, 0x87, 0xa9,
- 0xde, 0x77, 0x25, 0xd5, 0x2e, 0x64, 0x05, 0x9a, 0x01, 0xbf, 0xc5, 0xd7, 0x7d, 0x51, 0xf7, 0xee,
- 0xb1, 0x48, 0x14, 0x7f, 0xaf, 0x24, 0xf9, 0xb5, 0x73, 0xe2, 0x5a, 0x3d, 0xb0, 0x28, 0xbd, 0x2d,
- 0xc0, 0x1c, 0x6d, 0xba, 0xe1, 0x19, 0xea, 0xa5, 0xab, 0x07, 0xbf, 0xcd, 0x0f, 0x2d, 0x48, 0xb5,
- 0x40, 0xf3, 0x07, 0xdb, 0x65, 0xe1, 0x3d, 0x76, 0xf3, 0xe8, 0xc3, 0x02, 0x76, 0xc3, 0x29, 0xfe,
- 0x2d, 0x5a, 0x1d, 0x5f, 0x4b, 0xc5, 0x67, 0xa3, 0x21, 0x79, 0x09, 0x67, 0x84, 0x25, 0x54, 0x82,
- 0x4d, 0xff, 0xb4, 0xd6, 0xb0, 0x2e, 0xeb, 0x28, 0x91, 0x8a, 0x25, 0x01, 0x3f, 0x63, 0x91, 0x24,
- 0x9f, 0xba, 0xb2, 0xc6, 0xd6, 0xee, 0x2b, 0x16, 0x49, 0xda, 0xa2, 0xe9, 0x17, 0xa3, 0xfa, 0xfe,
- 0x2e, 0x13, 0x79, 0x4a, 0x3e, 0x73, 0x2f, 0x46, 0xad, 0x8b, 0x34, 0x42, 0xdb, 0x44, 0xdd, 0x10,
- 0xc3, 0x58, 0xa6, 0x53, 0x66, 0x56, 0x85, 0x57, 0xae, 0x21, 0x42, 0x63, 0x36, 0x15, 0x68, 0x92,
- 0xf0, 0xd7, 0x68, 0xf3, 0x94, 0x65, 0x7a, 0x11, 0x13, 0x52, 0x69, 0x98, 0x1c, 0x80, 0x0c, 0x92,
- 0x91, 0x02, 0xe2, 0x5f, 0x5a, 0x88, 0xde, 0xa0, 0xfe, 0x71, 0x69, 0xf5, 0x37, 0x5b, 0x07, 0x74,
- 0xe5, 0xad, 0xce, 0xee, 0x68, 0xd8, 0xfb, 0x6f, 0x07, 0x6d, 0xd4, 0xa5, 0x85, 0x6c, 0x79, 0x68,
- 0x61, 0x34, 0x6c, 0xee, 0x2c, 0xfa, 0x25, 0xd1, 0x79, 0xd5, 0x99, 0x5a, 0x18, 0x0d, 0xf1, 0x37,
- 0x68, 0xbd, 0xfa, 0x79, 0x3f, 0x61, 0xf2, 0xca, 0xae, 0x2b, 0xd0, 0x87, 0x35, 0xb5, 0x5e, 0x0d,
- 0x66, 0x4c, 0x5e, 0xd1, 0x16, 0x1f, 0x7f, 0x8e, 0x96, 0x07, 0xf9, 0x64, 0xc2, 0x33, 0xbb, 0xbc,
- 0xc0, 0xb1, 0x9d, 0x12, 0x20, 0x6a, 0x29, 0x9a, 0xfc, 0xe3, 0x64, 0x22, 0xb9, 0xb2, 0xcb, 0x4b,
- 0x9b, 0x2c, 0x00, 0xa2, 0x96, 0xa2, 0xc9, 0x3f, 0xf0, 0x24, 0x52, 0x97, 0x76, 0x4b, 0x69, 0x93,
- 0xa7, 0x00, 0x51, 0x4b, 0xe9, 0xfd, 0x15, 0x75, 0x6d, 0x23, 0xc2, 0xb5, 0x3f, 0x47, 0x4b, 0x8d,
- 0x65, 0xed, 0x79, 0x59, 0x78, 0xdb, 0x29, 0xcb, 0xd8, 0x8c, 0x2b, 0x9e, 0x19, 0x3d, 0xa4, 0x13,
- 0x48, 0xb8, 0x8f, 0x1e, 0x99, 0x2d, 0xc3, 0xdc, 0x9d, 0x94, 0x85, 0xf7, 0xf4, 0x06, 0xdb, 0x6c,
- 0x1a, 0x86, 0xd6, 0xfb, 0xf7, 0x02, 0xda, 0x68, 0x35, 0xee, 0x5d, 0xe1, 0xdc, 0xcc, 0xdc, 0x0c,
- 0xf7, 0x25, 0x5a, 0xb1, 0x47, 0x6d, 0x26, 0xfb, 0x06, 0xdf, 0x0e, 0x1a, 0xad, 0xa8, 0x38, 0x6e,
- 0x5d, 0xd0, 0xfe, 0x2d, 0xf0, 0xea, 0x81, 0xd1, 0x6a, 0xb0, 0x07, 0x5e, 0x59, 0x78, 0x1f, 0xdf,
- 0x1d, 0xc1, 0x0c, 0x59, 0x2b, 0x79, 0x11, 0x42, 0x75, 0x13, 0x49, 0xb2, 0xf4, 0x7f, 0x87, 0xb8,
- 0xd5, 0x71, 0x66, 0x99, 0xbc, 0x11, 0xab, 0x7e, 0x81, 0x24, 0x6d, 0xb8, 0x1e, 0xd0, 0x9f, 0x3f,
- 0xec, 0x75, 0x7e, 0xf9, 0xb0, 0xd7, 0xf9, 0xcf, 0x87, 0xbd, 0xce, 0x4f, 0xc3, 0x28, 0x56, 0x97,
- 0xf9, 0x85, 0x5e, 0xdb, 0x0f, 0x21, 0xd2, 0x21, 0x44, 0x3a, 0x94, 0xe1, 0xd5, 0xe1, 0xfc, 0xc8,
- 0xfc, 0xed, 0x7c, 0x68, 0x42, 0x7e, 0x7d, 0xef, 0x61, 0x2e, 0x96, 0x81, 0xf7, 0xc5, 0xff, 0x02,
- 0x00, 0x00, 0xff, 0xff, 0x8e, 0xca, 0xe4, 0x62, 0xbc, 0x0f, 0x00, 0x00,
+ 0x15, 0xee, 0x4a, 0xb2, 0x7e, 0x66, 0x25, 0x59, 0x1a, 0x39, 0xf6, 0x48, 0x71, 0x44, 0x75, 0x9d,
+ 0xb8, 0x2a, 0x52, 0xec, 0xa2, 0x4a, 0x02, 0x14, 0x08, 0x10, 0xc0, 0xab, 0x75, 0x92, 0x4d, 0x23,
+ 0x47, 0x98, 0x95, 0xd5, 0x22, 0x37, 0xc4, 0x88, 0x9c, 0xa5, 0x58, 0x2d, 0x39, 0x2c, 0x67, 0xb8,
+ 0xb5, 0x1e, 0xa1, 0x40, 0x6f, 0xfb, 0x4a, 0x45, 0x2e, 0xfd, 0x04, 0x44, 0xe1, 0x4b, 0xbe, 0x40,
+ 0x6f, 0x8b, 0x39, 0x33, 0xfc, 0xd3, 0x5f, 0xae, 0x2c, 0x9e, 0xef, 0xfb, 0xce, 0x99, 0x39, 0x3f,
+ 0xb3, 0xc7, 0xa8, 0xcb, 0xe7, 0x3c, 0x56, 0xfd, 0x24, 0x15, 0x4a, 0xe0, 0xdd, 0xe9, 0x57, 0xfd,
+ 0x38, 0x08, 0xe3, 0x77, 0x7d, 0x16, 0x68, 0xab, 0xf4, 0xaf, 0xfa, 0x80, 0xcb, 0xbd, 0x1d, 0x4f,
+ 0x44, 0x91, 0x88, 0x07, 0xe6, 0x1f, 0xc3, 0xdf, 0x43, 0x81, 0x08, 0x84, 0xfd, 0xdb, 0x09, 0x84,
+ 0x08, 0x66, 0x7c, 0x00, 0x5f, 0x17, 0xd9, 0x74, 0xa0, 0xc2, 0x88, 0x4b, 0xc5, 0xa2, 0xc4, 0x10,
+ 0x7a, 0xbf, 0x2c, 0xa0, 0xd5, 0x13, 0xae, 0x98, 0xcf, 0x14, 0xc3, 0x3d, 0xb4, 0x7c, 0x22, 0xfc,
+ 0x6c, 0xc6, 0x49, 0xe7, 0xa0, 0x73, 0xb8, 0x36, 0x44, 0x45, 0xee, 0x2c, 0x47, 0x60, 0xa1, 0x16,
+ 0xc1, 0xcf, 0xd1, 0xd2, 0xdb, 0xb7, 0xe3, 0x11, 0x59, 0x00, 0xc6, 0x6a, 0x91, 0x3b, 0x4b, 0x59,
+ 0x16, 0xfa, 0x14, 0xac, 0xf8, 0x4f, 0x68, 0xe3, 0x58, 0xa4, 0x29, 0x9f, 0x31, 0x15, 0x8a, 0x78,
+ 0x3c, 0x22, 0x8b, 0x40, 0xc3, 0x45, 0xee, 0x6c, 0x7a, 0x35, 0xe0, 0x86, 0x3e, 0x6d, 0x13, 0xf1,
+ 0x77, 0x68, 0xed, 0xac, 0x3c, 0x1b, 0x59, 0x3a, 0xe8, 0x1c, 0x76, 0x8f, 0xf6, 0xfa, 0xe6, 0xf4,
+ 0xfd, 0xf2, 0xf4, 0xfd, 0x8a, 0x31, 0xdc, 0x28, 0x72, 0x67, 0xad, 0xba, 0x0c, 0xad, 0xb5, 0x78,
+ 0x80, 0xd0, 0x6b, 0x9d, 0x9d, 0x1f, 0xf9, 0x9c, 0xcf, 0xc8, 0x23, 0x88, 0xff, 0xb8, 0xc8, 0x1d,
+ 0x93, 0x53, 0x77, 0xa6, 0xcd, 0xb4, 0x41, 0xd1, 0x37, 0x3a, 0xbb, 0x4e, 0x38, 0x59, 0xae, 0x6f,
+ 0xa4, 0xae, 0x13, 0x4e, 0xc1, 0x8a, 0x0f, 0xd1, 0xea, 0x31, 0x53, 0x3c, 0x10, 0xe9, 0x35, 0x59,
+ 0x01, 0xc6, 0x7a, 0x91, 0x3b, 0xab, 0x9e, 0xb5, 0xd1, 0x0a, 0xed, 0xbd, 0x5f, 0x40, 0x8f, 0xc0,
+ 0x2d, 0x3e, 0xa9, 0x73, 0x0a, 0x99, 0xec, 0x1e, 0xbd, 0xe8, 0xdf, 0x5b, 0xc4, 0x7e, 0x49, 0x35,
+ 0x8e, 0x23, 0xfb, 0x45, 0xeb, 0xb2, 0xf8, 0x68, 0xe3, 0x95, 0xa7, 0xc2, 0x79, 0xa8, 0xae, 0xc1,
+ 0x3f, 0xe4, 0xbe, 0x7b, 0x74, 0xf8, 0x80, 0xcf, 0x16, 0xdf, 0xa4, 0x9f, 0x59, 0x93, 0x0b, 0x94,
+ 0xef, 0x7f, 0x43, 0xdb, 0x4e, 0xf1, 0x3f, 0x3b, 0xe8, 0xe9, 0x84, 0x7b, 0x59, 0x1a, 0xaa, 0xeb,
+ 0xf3, 0x50, 0x98, 0xc2, 0x98, 0x78, 0x8b, 0x10, 0xef, 0x8f, 0x0f, 0xc4, 0xbb, 0x5b, 0x38, 0x7c,
+ 0x5e, 0xe4, 0x0e, 0x91, 0x16, 0x73, 0xe7, 0x25, 0x58, 0x1d, 0xe1, 0x9e, 0x80, 0xc3, 0x65, 0xb4,
+ 0xa4, 0x6f, 0xde, 0x9b, 0xa0, 0x2e, 0x18, 0x28, 0x4f, 0x44, 0xaa, 0xf0, 0x08, 0x2d, 0xc3, 0xa7,
+ 0x24, 0x9d, 0x83, 0xc5, 0xc3, 0xee, 0xd1, 0xc1, 0x03, 0x27, 0x32, 0x8e, 0xa0, 0x83, 0x8d, 0x85,
+ 0x5a, 0x6d, 0xef, 0x5f, 0x9d, 0x1b, 0xf9, 0xc4, 0x9f, 0xa1, 0x95, 0x13, 0x2e, 0x25, 0x0b, 0xca,
+ 0xc6, 0xef, 0x16, 0xb9, 0xb3, 0x12, 0x19, 0x13, 0x2d, 0x31, 0x7c, 0x86, 0xd0, 0x28, 0x8c, 0x78,
+ 0x2c, 0x43, 0x11, 0x4b, 0xb2, 0x00, 0x47, 0xf8, 0xf4, 0xae, 0x23, 0xd8, 0x71, 0xac, 0xc8, 0xc3,
+ 0xcd, 0x22, 0x77, 0x90, 0x5f, 0x69, 0x69, 0xc3, 0x4f, 0xef, 0xdf, 0xdb, 0xf7, 0xe5, 0x5d, 0xb7,
+ 0xf2, 0xa9, 0x98, 0x85, 0xde, 0xf5, 0x1b, 0x16, 0x95, 0x47, 0x83, 0x56, 0x4e, 0xc0, 0xea, 0xc6,
+ 0x2c, 0xe2, 0xb4, 0x41, 0xc1, 0x7f, 0x40, 0x6b, 0x93, 0x2c, 0xd1, 0xb9, 0xaa, 0x26, 0x14, 0x42,
+ 0x4b, 0x63, 0xd4, 0x63, 0x57, 0x13, 0xf4, 0xb5, 0x7f, 0xca, 0x94, 0x27, 0x22, 0x6e, 0xc7, 0x14,
+ 0xae, 0x2d, 0x8c, 0x89, 0x96, 0x98, 0x9e, 0x69, 0xfb, 0x27, 0xe5, 0x4c, 0x8a, 0x18, 0xa6, 0xd3,
+ 0xce, 0xb4, 0x25, 0xbb, 0x29, 0x20, 0xb4, 0x4d, 0xc4, 0x7f, 0x41, 0xcf, 0x86, 0x33, 0xe1, 0x5d,
+ 0x85, 0x71, 0xf0, 0xfa, 0x9d, 0xc7, 0x13, 0x7d, 0x33, 0xeb, 0xc3, 0xcc, 0xe5, 0x27, 0x45, 0xee,
+ 0xec, 0x5e, 0x58, 0x8a, 0xcb, 0x4b, 0x4e, 0xe9, 0xee, 0x3e, 0x35, 0x3c, 0x54, 0x5c, 0x5d, 0x0a,
+ 0xdf, 0x0e, 0xad, 0x79, 0xa8, 0xc0, 0x42, 0x2d, 0xa2, 0x07, 0xf7, 0x54, 0xbf, 0x1b, 0x9e, 0x98,
+ 0x35, 0x07, 0x37, 0xb1, 0x36, 0x5a, 0xa1, 0xf8, 0x14, 0x91, 0xbf, 0x7e, 0x2b, 0xd2, 0x7f, 0xb0,
+ 0xd4, 0xe7, 0xfe, 0xb7, 0x22, 0xfd, 0x9e, 0x33, 0x9f, 0xa7, 0xe7, 0x6c, 0x96, 0x71, 0xb2, 0x0a,
+ 0xca, 0x27, 0x45, 0xee, 0x6c, 0xbd, 0x9b, 0x4e, 0xdd, 0x4b, 0x80, 0xdc, 0xb9, 0xc6, 0xe8, 0xbd,
+ 0x2a, 0xbc, 0x8b, 0x16, 0xdf, 0xd2, 0x31, 0x59, 0x03, 0xf1, 0x4a, 0x91, 0x3b, 0x8b, 0x59, 0x1a,
+ 0x52, 0x6d, 0xd3, 0x49, 0xa7, 0xfc, 0xef, 0x19, 0x97, 0x8a, 0xa0, 0x3a, 0xe9, 0xa9, 0x31, 0xd1,
+ 0x12, 0xc3, 0x47, 0xa8, 0x3b, 0x96, 0x67, 0x69, 0x16, 0xeb, 0x87, 0xc6, 0x27, 0x5d, 0xa0, 0x6e,
+ 0x15, 0xb9, 0xb3, 0x1e, 0x4a, 0x57, 0x95, 0x76, 0xda, 0x24, 0xe9, 0x42, 0x59, 0xf9, 0x44, 0x31,
+ 0x95, 0x49, 0xb2, 0x5e, 0x17, 0xca, 0x06, 0x70, 0x25, 0x20, 0xb4, 0x4d, 0xc4, 0x5f, 0xa1, 0x75,
+ 0xca, 0x65, 0x22, 0x62, 0xc9, 0x8f, 0x85, 0xcf, 0xc9, 0x06, 0x08, 0xb7, 0x8b, 0xdc, 0xd9, 0x48,
+ 0xad, 0xdd, 0xf5, 0x84, 0xcf, 0x69, 0x8b, 0xa6, 0xfb, 0x73, 0xc2, 0xd3, 0x39, 0x4f, 0x5f, 0xf9,
+ 0x7e, 0x4a, 0x36, 0xeb, 0xfe, 0x94, 0x60, 0x75, 0x99, 0xef, 0xa7, 0xb4, 0x41, 0xc1, 0x2f, 0xd0,
+ 0xf2, 0xf9, 0x04, 0x9a, 0xf9, 0x71, 0x7d, 0xf7, 0xb9, 0x34, 0x8d, 0x6c, 0x21, 0xed, 0x95, 0xf2,
+ 0x48, 0x28, 0x0e, 0x5e, 0xb7, 0x6a, 0xaf, 0x29, 0x58, 0xad, 0xd7, 0x9a, 0x82, 0xbf, 0x2c, 0x05,
+ 0xa7, 0x22, 0x55, 0x64, 0xbb, 0xae, 0x98, 0xcf, 0xa5, 0x0a, 0x63, 0xf3, 0xe4, 0xe8, 0x9e, 0xa7,
+ 0x0d, 0x5e, 0x7d, 0x78, 0x50, 0xe1, 0x5b, 0x87, 0x37, 0x82, 0x9a, 0x82, 0xfb, 0x08, 0x55, 0xf3,
+ 0x29, 0xc9, 0x4e, 0x3d, 0x5d, 0xd5, 0xbb, 0x26, 0x69, 0x83, 0xa1, 0xcb, 0x31, 0xc9, 0x2e, 0x1a,
+ 0x92, 0x27, 0x75, 0x39, 0x64, 0x76, 0xe1, 0x36, 0x64, 0x6d, 0x22, 0xfe, 0x06, 0x3d, 0xae, 0xbe,
+ 0x28, 0x53, 0x61, 0x1c, 0x90, 0x8f, 0xea, 0x5b, 0xd5, 0xcf, 0x68, 0x0a, 0x18, 0xbd, 0x49, 0xc6,
+ 0x5f, 0xa0, 0xee, 0x24, 0x0c, 0x26, 0x5c, 0xe9, 0x7c, 0x4a, 0xf2, 0xb4, 0xae, 0xa6, 0x0c, 0x03,
+ 0x57, 0x72, 0x05, 0x09, 0x97, 0xb4, 0xc9, 0xc2, 0x2f, 0xd1, 0xca, 0x24, 0x0c, 0x8e, 0xcf, 0x5f,
+ 0x4b, 0xf2, 0xac, 0x1e, 0x17, 0x2d, 0xf0, 0xe6, 0x5c, 0xd2, 0x12, 0xd4, 0x9d, 0x79, 0x3c, 0x0b,
+ 0x79, 0xac, 0x8e, 0x67, 0x4c, 0x4a, 0x42, 0xea, 0xce, 0xf4, 0xc0, 0xec, 0x7a, 0xda, 0x4e, 0x9b,
+ 0x24, 0x3c, 0x42, 0xdb, 0xe6, 0xf3, 0x55, 0x92, 0xcc, 0x42, 0x0f, 0xce, 0x4a, 0x76, 0x41, 0xf9,
+ 0xb4, 0xc8, 0x1d, 0x6c, 0x95, 0xac, 0x46, 0xe9, 0x6d, 0x01, 0xfe, 0x19, 0x91, 0x5b, 0xc6, 0x73,
+ 0x9e, 0xea, 0x67, 0x94, 0xec, 0x81, 0xb3, 0xfd, 0x22, 0x77, 0xf6, 0x6e, 0x3b, 0x73, 0xe7, 0x86,
+ 0x45, 0xef, 0xd5, 0xeb, 0xd7, 0x62, 0xc2, 0xe7, 0x5c, 0x3f, 0xc2, 0xe4, 0xe3, 0xc6, 0xf5, 0xad,
+ 0x8d, 0x56, 0x28, 0xfe, 0x33, 0xda, 0x39, 0xbb, 0x4c, 0x39, 0x53, 0xc7, 0x2c, 0x4a, 0x58, 0x18,
+ 0xc4, 0x26, 0xc9, 0xcf, 0x41, 0xb4, 0x5b, 0xe4, 0xce, 0x47, 0x0a, 0x60, 0xd7, 0xb3, 0xb8, 0x4d,
+ 0xf6, 0x5d, 0x2a, 0x3d, 0x78, 0x43, 0xa1, 0x5e, 0xc5, 0x22, 0x62, 0xb3, 0x90, 0x4b, 0xf2, 0x49,
+ 0x5d, 0xaa, 0x0b, 0xa1, 0x5c, 0x56, 0x02, 0xb4, 0x45, 0xd3, 0x35, 0x18, 0x0a, 0x55, 0xed, 0x25,
+ 0xfb, 0x75, 0x0d, 0xb4, 0xaa, 0xda, 0x4d, 0x9a, 0x24, 0xfc, 0x06, 0x3d, 0x79, 0x1d, 0x4f, 0x45,
+ 0xea, 0x71, 0xbf, 0x15, 0xd2, 0x01, 0xf1, 0x5e, 0x91, 0x3b, 0x4f, 0xb9, 0xc5, 0xdd, 0x76, 0xec,
+ 0x3b, 0x75, 0x78, 0x88, 0xb6, 0x86, 0x42, 0x4d, 0xc2, 0x20, 0x66, 0x2a, 0x4b, 0x39, 0x4c, 0xf5,
+ 0x41, 0x5d, 0x52, 0xed, 0x42, 0x96, 0xa0, 0x19, 0xf0, 0x5b, 0x7c, 0xcc, 0xd1, 0x66, 0xdd, 0xf6,
+ 0x23, 0xbd, 0x2e, 0xf5, 0xe0, 0x57, 0xf5, 0xa1, 0xd5, 0xa6, 0x12, 0x68, 0xfe, 0x70, 0xa7, 0xc8,
+ 0x9d, 0xc7, 0xf5, 0x24, 0xb9, 0xb0, 0x3a, 0xdd, 0x70, 0x8a, 0x7f, 0x8f, 0x56, 0x27, 0xd7, 0x52,
+ 0xf1, 0x68, 0x3c, 0x22, 0x2f, 0xe0, 0x88, 0xb0, 0x3e, 0x4a, 0xb0, 0xe9, 0x1f, 0xc5, 0x0a, 0xd6,
+ 0x05, 0x19, 0xc7, 0x52, 0xb1, 0xd8, 0xe3, 0x67, 0x2c, 0x90, 0xe4, 0xd3, 0xba, 0x20, 0xa1, 0xb5,
+ 0xbb, 0x8a, 0x05, 0x92, 0xb6, 0x68, 0x7a, 0xd6, 0xcb, 0xef, 0xef, 0x52, 0x91, 0x25, 0xe4, 0xb3,
+ 0x7a, 0xd6, 0x2b, 0x5d, 0xa0, 0x11, 0xda, 0x26, 0xea, 0x52, 0x8e, 0x42, 0x99, 0xcc, 0x98, 0xf9,
+ 0x91, 0x7f, 0x59, 0x97, 0xd2, 0x37, 0x66, 0x93, 0xbb, 0x26, 0x09, 0x7f, 0x8d, 0x36, 0x4f, 0x59,
+ 0xaa, 0x57, 0x28, 0x21, 0x95, 0x86, 0xc9, 0x21, 0xc8, 0x20, 0x19, 0x09, 0x20, 0xee, 0xa5, 0x85,
+ 0xe8, 0x0d, 0xea, 0x0f, 0x4b, 0xab, 0xbf, 0xdb, 0x3a, 0xfc, 0x61, 0x69, 0xf5, 0xb7, 0x5b, 0x3d,
+ 0xba, 0xf2, 0x46, 0xe7, 0x78, 0x3c, 0xa2, 0xdb, 0x55, 0xc6, 0x8e, 0x45, 0xac, 0xf8, 0x3b, 0x25,
+ 0x7b, 0xff, 0xeb, 0xa0, 0x8d, 0xaa, 0x5a, 0x90, 0x46, 0x07, 0x2d, 0x8c, 0x47, 0xcd, 0x35, 0x44,
+ 0x3f, 0x0e, 0x3a, 0xe1, 0x3a, 0x85, 0x0b, 0xe3, 0x11, 0xfe, 0x06, 0xad, 0x97, 0xbf, 0xd8, 0x27,
+ 0x4c, 0x5e, 0xd9, 0x0d, 0x04, 0x5a, 0xab, 0xa2, 0x56, 0xbf, 0xf6, 0x11, 0x93, 0x57, 0xb4, 0xc5,
+ 0xc7, 0x9f, 0xa3, 0xe5, 0x61, 0x36, 0x9d, 0xf2, 0xd4, 0xee, 0x23, 0x70, 0x9f, 0x5a, 0x09, 0x10,
+ 0xb5, 0x14, 0x4d, 0xfe, 0x69, 0x3a, 0x95, 0x5c, 0xd9, 0x7d, 0xa4, 0x4d, 0x16, 0x00, 0x51, 0x4b,
+ 0xd1, 0xe4, 0x1f, 0x79, 0x1c, 0xa8, 0x4b, 0xbb, 0x78, 0xb4, 0xc9, 0x33, 0x80, 0xa8, 0xa5, 0xf4,
+ 0xfe, 0x86, 0xba, 0x36, 0x0b, 0x70, 0xed, 0xcf, 0xd1, 0x52, 0x63, 0xff, 0x7a, 0x56, 0xe4, 0xce,
+ 0x4e, 0xc2, 0x52, 0x16, 0x71, 0xc5, 0x53, 0xa3, 0x87, 0x3c, 0x03, 0x09, 0xf7, 0xd1, 0x23, 0xb3,
+ 0x38, 0x98, 0xbb, 0x93, 0x22, 0x77, 0x9e, 0xdc, 0x60, 0x9b, 0xe5, 0xc1, 0xd0, 0x7a, 0xff, 0x59,
+ 0x40, 0x1b, 0xad, 0x8e, 0xbe, 0x2b, 0x5c, 0xfd, 0xe2, 0xdf, 0x0c, 0xf7, 0x25, 0x5a, 0xb1, 0x47,
+ 0x6d, 0x26, 0xfb, 0x06, 0xdf, 0x33, 0x0c, 0x5a, 0x52, 0x71, 0xd8, 0xba, 0xa0, 0x5d, 0xef, 0x5f,
+ 0x3e, 0x30, 0x73, 0x0d, 0xf6, 0xd0, 0x29, 0x72, 0xe7, 0xe3, 0xbb, 0x23, 0x98, 0xe9, 0x6b, 0x25,
+ 0x2f, 0x40, 0xa8, 0x6a, 0x22, 0x49, 0x96, 0x7e, 0x75, 0xba, 0x5b, 0x1d, 0x67, 0xf6, 0xc3, 0x1b,
+ 0xb1, 0xaa, 0x47, 0x45, 0xd2, 0x86, 0xeb, 0x21, 0xfd, 0xe5, 0xc3, 0x7e, 0xe7, 0xfd, 0x87, 0xfd,
+ 0xce, 0x7f, 0x3f, 0xec, 0x77, 0x7e, 0x1e, 0x05, 0xa1, 0xba, 0xcc, 0x2e, 0xf4, 0x26, 0x3e, 0x80,
+ 0x48, 0x03, 0x88, 0x34, 0x90, 0xfe, 0xd5, 0x60, 0x7e, 0x64, 0xfe, 0x3b, 0x3c, 0x30, 0x21, 0xbf,
+ 0xbe, 0xf7, 0x30, 0x17, 0xcb, 0xc0, 0xfb, 0xe2, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x6a, 0x8a,
+ 0x32, 0xd4, 0x8f, 0x0f, 0x00, 0x00,
}
func (m *Metadata) Marshal() (dAtA []byte, err error) {
@@ -1356,15 +1400,6 @@ func (m *SecurityViolationEvent) MarshalToSizedBuffer(dAtA []byte) (int, error)
dAtA[i] = 0x92
}
}
- if len(m.ViolationContexts) > 0 {
- i -= len(m.ViolationContexts)
- copy(dAtA[i:], m.ViolationContexts)
- i = encodeVarintEvent(dAtA, i, uint64(len(m.ViolationContexts)))
- i--
- dAtA[i] = 0x2
- i--
- dAtA[i] = 0x8a
- }
if len(m.BotSignatureName) > 0 {
i -= len(m.BotSignatureName)
copy(dAtA[i:], m.BotSignatureName)
@@ -2064,10 +2099,6 @@ func (m *SecurityViolationEvent) Size() (n int) {
if l > 0 {
n += 2 + l + sovEvent(uint64(l))
}
- l = len(m.ViolationContexts)
- if l > 0 {
- n += 2 + l + sovEvent(uint64(l))
- }
if len(m.ViolationsData) > 0 {
for _, e := range m.ViolationsData {
l = e.Size()
@@ -3879,38 +3910,6 @@ func (m *SecurityViolationEvent) Unmarshal(dAtA []byte) error {
}
m.BotSignatureName = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
- case 33:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field ViolationContexts", wireType)
- }
- var stringLen uint64
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowEvent
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- stringLen |= uint64(b&0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- intStringLen := int(stringLen)
- if intStringLen < 0 {
- return ErrInvalidLengthEvent
- }
- postIndex := iNdEx + intStringLen
- if postIndex < 0 {
- return ErrInvalidLengthEvent
- }
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- m.ViolationContexts = string(dAtA[iNdEx:postIndex])
- iNdEx = postIndex
case 34:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ViolationsData", wireType)
diff --git a/sdk/proto/events/event.proto b/sdk/proto/events/event.proto
index 61324fc70..e951f87d2 100644
--- a/sdk/proto/events/event.proto
+++ b/sdk/proto/events/event.proto
@@ -69,75 +69,128 @@ message SecurityViolationEvent {
// DEPRECATED
reserved 39;
reserved "NginxID";
+ reserved 33;
+ reserved "ViolationContexts";
+ // The name of the NGINX App Protect policy that triggered the security violation
string PolicyName = 1 [(gogoproto.jsontag) = "policy_name"];
+ // The unique NGINX App Protect support ID of the violation, used for tracking purposes
string SupportID = 2 [(gogoproto.jsontag) = "support_id"];
+ // The outcome that resulted for the security violation
string Outcome = 3 [(gogoproto.jsontag) = "outcome"];
+ // The reason for the security violation resulting in the outcome
string OutcomeReason = 4 [(gogoproto.jsontag) = "outcome_reason"];
+ // The blocking exception reason when a configured violation was not blocked
string BlockingExceptionReason = 5 [(gogoproto.jsontag) = "blocking_exception_reason"];
+ // The HTTP Method of the request that triggered the security violation
string Method = 6 [(gogoproto.jsontag) = "method"];
+ // The HTTP Protocol of the request that triggered the security violation
string Protocol = 7 [(gogoproto.jsontag) = "protocol"];
+ // The HTTP xff_header_value of the request that triggered the security violation
string XForwardedForHeaderValue = 8 [(gogoproto.jsontag) = "xff_header_value"];
+ // The URI of the request that triggered the security violation
string URI = 9 [(gogoproto.jsontag) = "uri"];
+ // The full request that triggered the security violation, including the Method, URI and Request Body
string Request = 10 [(gogoproto.jsontag) = "request"];
+ // If the request is truncated or not
string IsTruncated = 11 [(gogoproto.jsontag) = "is_truncated"];
+ // The status of the request that triggered the security violation
string RequestStatus = 12 [(gogoproto.jsontag) = "request_status"];
+ // The HTTP response status to the request that triggered the security violation
string ResponseCode = 13 [(gogoproto.jsontag) = "response_code"];
+ // The server address of the instance that caught the security violation
string ServerAddr = 14 [(gogoproto.jsontag) = "server_addr"];
+ // The Virtual Server Name of the instance that caught the security violation
string VSName = 15 [(gogoproto.jsontag) = "vs_name"];
+ // The targeted address by the request that triggered the security violation
string RemoteAddr = 16 [(gogoproto.jsontag) = "remote_addr"];
+ // The targeted port number by the request that triggered the security violation
string RemotePort = 17 [(gogoproto.jsontag) = "destination_port"];
+ // The server port of the instance that caught the security violation
string ServerPort = 18 [(gogoproto.jsontag) = "server_port"];
+ // A comma-separated list of all the violations triggered by the request
string Violations = 19 [(gogoproto.jsontag) = "violations"];
+ // A comma-separated list of all the sub-violations triggered by the request
string SubViolations = 20 [(gogoproto.jsontag) = "sub_violations"];
+ // The rating of the triggered security violation
string ViolationRating = 21 [(gogoproto.jsontag) = "violation_rating"];
+ // A comma-separated list of all the signature names
string SigSetNames = 22 [(gogoproto.jsontag) = "sig_set_names"];
+ // A comma-separated list of all the signature CVEs
string SigCVEs = 23 [(gogoproto.jsontag) = "sig_cves"];
+ // The class of the client used to send the request that triggered the security violation
string ClientClass = 24 [(gogoproto.jsontag) = "client_class"];
+ // The application used to send the request that triggered the security violation
string ClientApplication = 25 [(gogoproto.jsontag) = "client_application"];
+ // The version of the application used to send the request that triggered the security violation
string ClientApplicationVersion = 26 [(gogoproto.jsontag) = "client_application_version"];
+ // The severity of the triggered security violation
string Severity = 27 [(gogoproto.jsontag) = "severity"];
+ // A comma-separated list of the threat campaign names
string ThreatCampaignNames = 28 [(gogoproto.jsontag) = "threat_campaign_names"];
+ // Anomalies of the bot that sent the request that triggered the security violation
string BotAnomalies = 29 [(gogoproto.jsontag) = "bot_anomalies"];
+ // Category of the bot that sent the request that triggered the security violation
string BotCategory = 30 [(gogoproto.jsontag) = "bot_category"];
+ // Enforced anomalies of the bot that sent the request that triggered the security violation
string EnforcedBotAnomalies = 31 [(gogoproto.jsontag) = "enforced_bot_anomalies"];
+ // Signature name of the bot that sent the request that triggered the security violation
string BotSignatureName = 32 [(gogoproto.jsontag) = "bot_signature_name"];
- string ViolationContexts = 33 [(gogoproto.jsontag) = "violation_contexts"];
+ // A list of objects containing descriptive data about all the security violations
repeated ViolationData ViolationsData = 34 [(gogoproto.jsontag) = "violations_data"];
+ // SystemID of the instance where NGINX is running
string SystemID = 35 [(gogoproto.jsontag) = "system_id"];
+ // Instance tags where NGINX is running
string InstanceTags = 36 [(gogoproto.jsontag) = "instance_tags"];
+ // Instance group where NGINX is running
string InstanceGroup = 37 [(gogoproto.jsontag) = "instance_group"];
+ // Display name of the instance where NGINX is running
string DisplayName = 38 [(gogoproto.jsontag) = "display_name"];
+ // The hostname where NGINX is running
string ParentHostname = 40 [(gogoproto.jsontag) = "parent_hostname"];
}
+// Represents signature data that's contained within each violation
message SignatureData {
+ // ID of the signature data
string ID = 1 [(gogoproto.jsontag) = "sig_data_id"];
+ // The blocking mask of the signature data
string BlockingMask = 2 [(gogoproto.jsontag) = "sig_data_blocking_mask"];
+ // The buffer of the signature data
string Buffer = 3 [(gogoproto.jsontag) = "sig_data_buffer"];
+ // The offset of the signature data
string Offset = 4 [(gogoproto.jsontag) = "sig_data_offset"];
+ // The length of the signature data
string Length = 5 [(gogoproto.jsontag) = "sig_data_length"];
}
+// Represents the context data of each violation
message ContextData {
+ // The name within the context data
string Name = 1 [(gogoproto.jsontag) = "parameter_data_name"];
+ // The value within the context data
string Value = 2 [(gogoproto.jsontag) = "parameter_data_value"];
}
+// Represents the violation data contained within a security violation event
message ViolationData {
+ // The name of the violation
string Name = 1 [(gogoproto.jsontag) = "violation_data_name"];
+ // The context of the violation
string Context = 2 [(gogoproto.jsontag) = "violation_data_context"];
+ // The object representing the context data of the violation
ContextData ContextData = 3 [(gogoproto.jsontag) = "violation_data_context_data"];
+ // A list representing the signature data of the violation
repeated SignatureData Signatures = 4 [(gogoproto.jsontag) = "violation_data_signatures"];
}
diff --git a/sdk/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/doc.go b/sdk/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/doc.go
index afd924a14..f8ba7198a 100644
--- a/sdk/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/doc.go
+++ b/sdk/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/doc.go
@@ -18,7 +18,7 @@ Other default options are: retry on `ResourceExhausted` and `Unavailable` gRPC c
linear backoff with 10% jitter.
For chained interceptors, the retry interceptor will call every interceptor that follows it
-whenever when a retry happens.
+whenever a retry happens.
Please see examples for more advanced use.
*/
diff --git a/sdk/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/retry.go b/sdk/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/retry.go
index 62d831201..003bbd906 100644
--- a/sdk/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/retry.go
+++ b/sdk/vendor/github.com/grpc-ecosystem/go-grpc-middleware/retry/retry.go
@@ -5,8 +5,8 @@ package grpc_retry
import (
"context"
- "fmt"
"io"
+ "strconv"
"sync"
"time"
@@ -136,7 +136,6 @@ func StreamClientInterceptor(optFuncs ...CallOption) grpc.StreamClientIntercepto
type serverStreamingRetryingStream struct {
grpc.ClientStream
bufferedSends []interface{} // single message that the client can sen
- receivedGood bool // indicates whether any prior receives were successful
wasClosedSend bool // indicates that CloseSend was closed
parentCtx context.Context
callOpts *options
@@ -209,17 +208,8 @@ func (s *serverStreamingRetryingStream) RecvMsg(m interface{}) error {
}
func (s *serverStreamingRetryingStream) receiveMsgAndIndicateRetry(m interface{}) (bool, error) {
- s.mu.RLock()
- wasGood := s.receivedGood
- s.mu.RUnlock()
err := s.getStream().RecvMsg(m)
if err == nil || err == io.EOF {
- s.mu.Lock()
- s.receivedGood = true
- s.mu.Unlock()
- return false, err
- } else if wasGood {
- // previous RecvMsg in the stream succeeded, no retry logic should interfere
return false, err
}
if isContextError(err) {
@@ -303,7 +293,7 @@ func perCallContext(parentCtx context.Context, callOpts *options, attempt uint)
ctx, _ = context.WithTimeout(ctx, callOpts.perCallTimeout)
}
if attempt > 0 && callOpts.includeHeader {
- mdClone := metautils.ExtractOutgoing(ctx).Clone().Set(AttemptMetadataKey, fmt.Sprintf("%d", attempt))
+ mdClone := metautils.ExtractOutgoing(ctx).Clone().Set(AttemptMetadataKey, strconv.FormatUint(uint64(attempt), 10))
ctx = mdClone.ToOutgoing(ctx)
}
return ctx
diff --git a/sdk/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go b/sdk/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go
index 1c60585dd..15225d710 100644
--- a/sdk/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go
+++ b/sdk/vendor/github.com/grpc-ecosystem/go-grpc-middleware/util/metautils/nicemd.go
@@ -10,7 +10,7 @@ import (
"google.golang.org/grpc/metadata"
)
-// NiceMD is a convenience wrapper definiting extra functions on the metadata.
+// NiceMD is a convenience wrapper defining extra functions on the metadata.
type NiceMD metadata.MD
// ExtractIncoming extracts an inbound metadata from the server-side context.
@@ -39,7 +39,7 @@ func ExtractOutgoing(ctx context.Context) NiceMD {
// Clone performs a *deep* copy of the metadata.MD.
//
-// You can specify the lower-case copiedKeys to only copy certain whitelisted keys. If no keys are explicitly whitelisted
+// You can specify the lower-case copiedKeys to only copy certain allow-listed keys. If no keys are explicitly allow-listed
// all keys get copied.
func (m NiceMD) Clone(copiedKeys ...string) NiceMD {
newMd := NiceMD(metadata.Pairs())
@@ -61,7 +61,7 @@ func (m NiceMD) Clone(copiedKeys ...string) NiceMD {
newMd[k] = make([]string, len(vv))
copy(newMd[k], vv)
}
- return NiceMD(newMd)
+ return newMd
}
// ToOutgoing sets the given NiceMD as a client-side context for dispatching.
diff --git a/sdk/vendor/github.com/nginxinc/nginx-go-crossplane/README.md b/sdk/vendor/github.com/nginxinc/nginx-go-crossplane/README.md
index e83ff8aaa..5dc6d482b 100644
--- a/sdk/vendor/github.com/nginxinc/nginx-go-crossplane/README.md
+++ b/sdk/vendor/github.com/nginxinc/nginx-go-crossplane/README.md
@@ -75,7 +75,7 @@ func main() {
## Contributing
-If you'd like to contribute to the project, please read our [Contributing guide](docs/CONTRIBUTING.md).
+If you'd like to contribute to the project, please read our [Contributing guide](CONTRIBUTING.md).
## License
diff --git a/sdk/vendor/github.com/nginxinc/nginx-go-crossplane/analyze.go b/sdk/vendor/github.com/nginxinc/nginx-go-crossplane/analyze.go
index 0e39caba0..8adf1e4ac 100644
--- a/sdk/vendor/github.com/nginxinc/nginx-go-crossplane/analyze.go
+++ b/sdk/vendor/github.com/nginxinc/nginx-go-crossplane/analyze.go
@@ -2120,18 +2120,34 @@ var directives = map[string][]uint{
"js_content": {
ngxHTTPLocConf | ngxHTTPLifConf | ngxHTTPLmtConf | ngxConfTake1,
},
+ "js_fetch_buffer_size": {
+ ngxHTTPMainConf | ngxHTTPSrvConf | ngxHTTPLocConf | ngxConfTake1,
+ ngxStreamMainConf | ngxStreamSrvConf | ngxConfTake1,
+ },
"js_fetch_ciphers": {
ngxHTTPMainConf | ngxHTTPSrvConf | ngxHTTPLocConf | ngxConfTake1,
ngxStreamMainConf | ngxStreamSrvConf | ngxConfTake1,
},
+ "js_fetch_max_response_buffer_size": {
+ ngxHTTPMainConf | ngxHTTPSrvConf | ngxHTTPLocConf | ngxConfTake1,
+ ngxStreamMainConf | ngxStreamSrvConf | ngxConfTake1,
+ },
"js_fetch_protocols": {
ngxHTTPMainConf | ngxHTTPSrvConf | ngxHTTPLocConf | ngxConf1More,
ngxStreamMainConf | ngxStreamSrvConf | ngxConf1More,
},
+ "js_fetch_timeout": {
+ ngxHTTPMainConf | ngxHTTPSrvConf | ngxHTTPLocConf | ngxConfTake1,
+ ngxStreamMainConf | ngxStreamSrvConf | ngxConfTake1,
+ },
"js_fetch_trusted_certificate": {
ngxHTTPMainConf | ngxHTTPSrvConf | ngxHTTPLocConf | ngxConfTake1,
ngxStreamMainConf | ngxStreamSrvConf | ngxConfTake1,
},
+ "js_fetch_verify": {
+ ngxHTTPMainConf | ngxHTTPSrvConf | ngxHTTPLocConf | ngxConfFlag,
+ ngxStreamMainConf | ngxStreamSrvConf | ngxConfFlag,
+ },
"js_fetch_verify_depth": {
ngxHTTPMainConf | ngxHTTPSrvConf | ngxHTTPLocConf | ngxConfTake1,
ngxStreamMainConf | ngxStreamSrvConf | ngxConfTake1,
@@ -2154,6 +2170,10 @@ var directives = map[string][]uint{
ngxHTTPMainConf | ngxHTTPSrvConf | ngxHTTPLocConf | ngxConfTake1,
ngxStreamMainConf | ngxStreamSrvConf | ngxConfTake1,
},
+ "js_preload_object": {
+ ngxHTTPMainConf | ngxHTTPSrvConf | ngxHTTPLocConf | ngxConfTake13,
+ ngxStreamMainConf | ngxStreamSrvConf | ngxConfTake13,
+ },
"js_preread": {
ngxStreamMainConf | ngxStreamSrvConf | ngxConfTake1,
},
diff --git a/sdk/vendor/github.com/nginxinc/nginx-go-crossplane/analyze_map.go b/sdk/vendor/github.com/nginxinc/nginx-go-crossplane/analyze_map.go
index 3f512f406..953a64a62 100644
--- a/sdk/vendor/github.com/nginxinc/nginx-go-crossplane/analyze_map.go
+++ b/sdk/vendor/github.com/nginxinc/nginx-go-crossplane/analyze_map.go
@@ -35,6 +35,9 @@ var mapBodies = map[string]mapParameterMasks{
"types": {
defaultMasks: ngxConf1More,
},
+ "split_clients": {
+ defaultMasks: ngxConfTake1,
+ },
}
// analyzeMapBody validates the body of a map-like directive. Map-like directives are block directives
diff --git a/sdk/vendor/golang.org/x/net/http2/transport.go b/sdk/vendor/golang.org/x/net/http2/transport.go
index f965579f7..ac90a2631 100644
--- a/sdk/vendor/golang.org/x/net/http2/transport.go
+++ b/sdk/vendor/golang.org/x/net/http2/transport.go
@@ -1266,6 +1266,27 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
return res, nil
}
+ cancelRequest := func(cs *clientStream, err error) error {
+ cs.cc.mu.Lock()
+ defer cs.cc.mu.Unlock()
+ cs.abortStreamLocked(err)
+ if cs.ID != 0 {
+ // This request may have failed because of a problem with the connection,
+ // or for some unrelated reason. (For example, the user might have canceled
+ // the request without waiting for a response.) Mark the connection as
+ // not reusable, since trying to reuse a dead connection is worse than
+ // unnecessarily creating a new one.
+ //
+ // If cs.ID is 0, then the request was never allocated a stream ID and
+ // whatever went wrong was unrelated to the connection. We might have
+ // timed out waiting for a stream slot when StrictMaxConcurrentStreams
+ // is set, for example, in which case retrying on a different connection
+ // will not help.
+ cs.cc.doNotReuse = true
+ }
+ return err
+ }
+
for {
select {
case <-cs.respHeaderRecv:
@@ -1280,15 +1301,12 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
return handleResponseHeaders()
default:
waitDone()
- return nil, cs.abortErr
+ return nil, cancelRequest(cs, cs.abortErr)
}
case <-ctx.Done():
- err := ctx.Err()
- cs.abortStream(err)
- return nil, err
+ return nil, cancelRequest(cs, ctx.Err())
case <-cs.reqCancel:
- cs.abortStream(errRequestCanceled)
- return nil, errRequestCanceled
+ return nil, cancelRequest(cs, errRequestCanceled)
}
}
}
diff --git a/sdk/vendor/golang.org/x/sys/unix/mkerrors.sh b/sdk/vendor/golang.org/x/sys/unix/mkerrors.sh
index 2045d3dad..be0423e68 100644
--- a/sdk/vendor/golang.org/x/sys/unix/mkerrors.sh
+++ b/sdk/vendor/golang.org/x/sys/unix/mkerrors.sh
@@ -204,6 +204,7 @@ struct ltchars {
#include
#include
#include
+#include
#include
#include
#include
@@ -518,7 +519,7 @@ ccflags="$@"
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
- $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT)_/ ||
+ $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||
$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
$2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
$2 ~ /^RAW_PAYLOAD_/ ||
diff --git a/sdk/vendor/golang.org/x/sys/unix/zerrors_linux.go b/sdk/vendor/golang.org/x/sys/unix/zerrors_linux.go
index 398c37e52..de936b677 100644
--- a/sdk/vendor/golang.org/x/sys/unix/zerrors_linux.go
+++ b/sdk/vendor/golang.org/x/sys/unix/zerrors_linux.go
@@ -2967,6 +2967,7 @@ const (
SOL_TCP = 0x6
SOL_TIPC = 0x10f
SOL_TLS = 0x11a
+ SOL_UDP = 0x11
SOL_X25 = 0x106
SOL_XDP = 0x11b
SOMAXCONN = 0x1000
@@ -3251,6 +3252,19 @@ const (
TRACEFS_MAGIC = 0x74726163
TS_COMM_LEN = 0x20
UDF_SUPER_MAGIC = 0x15013346
+ UDP_CORK = 0x1
+ UDP_ENCAP = 0x64
+ UDP_ENCAP_ESPINUDP = 0x2
+ UDP_ENCAP_ESPINUDP_NON_IKE = 0x1
+ UDP_ENCAP_GTP0 = 0x4
+ UDP_ENCAP_GTP1U = 0x5
+ UDP_ENCAP_L2TPINUDP = 0x3
+ UDP_GRO = 0x68
+ UDP_NO_CHECK6_RX = 0x66
+ UDP_NO_CHECK6_TX = 0x65
+ UDP_SEGMENT = 0x67
+ UDP_V4_FLOW = 0x2
+ UDP_V6_FLOW = 0x6
UMOUNT_NOFOLLOW = 0x8
USBDEVICE_SUPER_MAGIC = 0x9fa2
UTIME_NOW = 0x3fffffff
diff --git a/sdk/vendor/golang.org/x/sys/windows/env_windows.go b/sdk/vendor/golang.org/x/sys/windows/env_windows.go
index 92ac05ff4..b8ad19250 100644
--- a/sdk/vendor/golang.org/x/sys/windows/env_windows.go
+++ b/sdk/vendor/golang.org/x/sys/windows/env_windows.go
@@ -37,14 +37,14 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) {
return nil, err
}
defer DestroyEnvironmentBlock(block)
- blockp := uintptr(unsafe.Pointer(block))
+ blockp := unsafe.Pointer(block)
for {
- entry := UTF16PtrToString((*uint16)(unsafe.Pointer(blockp)))
+ entry := UTF16PtrToString((*uint16)(blockp))
if len(entry) == 0 {
break
}
env = append(env, entry)
- blockp += 2 * (uintptr(len(entry)) + 1)
+ blockp = unsafe.Add(blockp, 2*(len(entry)+1))
}
return env, nil
}
diff --git a/sdk/vendor/golang.org/x/sys/windows/exec_windows.go b/sdk/vendor/golang.org/x/sys/windows/exec_windows.go
index 75980fd44..a52e0331d 100644
--- a/sdk/vendor/golang.org/x/sys/windows/exec_windows.go
+++ b/sdk/vendor/golang.org/x/sys/windows/exec_windows.go
@@ -95,12 +95,17 @@ func ComposeCommandLine(args []string) string {
// DecomposeCommandLine breaks apart its argument command line into unescaped parts using CommandLineToArgv,
// as gathered from GetCommandLine, QUERY_SERVICE_CONFIG's BinaryPathName argument, or elsewhere that
// command lines are passed around.
+// DecomposeCommandLine returns error if commandLine contains NUL.
func DecomposeCommandLine(commandLine string) ([]string, error) {
if len(commandLine) == 0 {
return []string{}, nil
}
+ utf16CommandLine, err := UTF16FromString(commandLine)
+ if err != nil {
+ return nil, errorspkg.New("string with NUL passed to DecomposeCommandLine")
+ }
var argc int32
- argv, err := CommandLineToArgv(StringToUTF16Ptr(commandLine), &argc)
+ argv, err := CommandLineToArgv(&utf16CommandLine[0], &argc)
if err != nil {
return nil, err
}
diff --git a/sdk/vendor/golang.org/x/sys/windows/service.go b/sdk/vendor/golang.org/x/sys/windows/service.go
index f8deca839..c964b6848 100644
--- a/sdk/vendor/golang.org/x/sys/windows/service.go
+++ b/sdk/vendor/golang.org/x/sys/windows/service.go
@@ -141,6 +141,12 @@ const (
SERVICE_DYNAMIC_INFORMATION_LEVEL_START_REASON = 1
)
+type ENUM_SERVICE_STATUS struct {
+ ServiceName *uint16
+ DisplayName *uint16
+ ServiceStatus SERVICE_STATUS
+}
+
type SERVICE_STATUS struct {
ServiceType uint32
CurrentState uint32
@@ -245,3 +251,4 @@ type QUERY_SERVICE_LOCK_STATUS struct {
//sys UnsubscribeServiceChangeNotifications(subscription uintptr) = sechost.UnsubscribeServiceChangeNotifications?
//sys RegisterServiceCtrlHandlerEx(serviceName *uint16, handlerProc uintptr, context uintptr) (handle Handle, err error) = advapi32.RegisterServiceCtrlHandlerExW
//sys QueryServiceDynamicInformation(service Handle, infoLevel uint32, dynamicInfo unsafe.Pointer) (err error) = advapi32.QueryServiceDynamicInformation?
+//sys EnumDependentServices(service Handle, activityState uint32, services *ENUM_SERVICE_STATUS, buffSize uint32, bytesNeeded *uint32, servicesReturned *uint32) (err error) = advapi32.EnumDependentServicesW
diff --git a/sdk/vendor/golang.org/x/sys/windows/types_windows.go b/sdk/vendor/golang.org/x/sys/windows/types_windows.go
index 0dbb20841..88e62a638 100644
--- a/sdk/vendor/golang.org/x/sys/windows/types_windows.go
+++ b/sdk/vendor/golang.org/x/sys/windows/types_windows.go
@@ -2220,15 +2220,19 @@ type JOBOBJECT_BASIC_UI_RESTRICTIONS struct {
}
const (
- // JobObjectInformationClass
+ // JobObjectInformationClass for QueryInformationJobObject and SetInformationJobObject
JobObjectAssociateCompletionPortInformation = 7
+ JobObjectBasicAccountingInformation = 1
+ JobObjectBasicAndIoAccountingInformation = 8
JobObjectBasicLimitInformation = 2
+ JobObjectBasicProcessIdList = 3
JobObjectBasicUIRestrictions = 4
JobObjectCpuRateControlInformation = 15
JobObjectEndOfJobTimeInformation = 6
JobObjectExtendedLimitInformation = 9
JobObjectGroupInformation = 11
JobObjectGroupInformationEx = 14
+ JobObjectLimitViolationInformation = 13
JobObjectLimitViolationInformation2 = 34
JobObjectNetRateControlInformation = 32
JobObjectNotificationLimitInformation = 12
diff --git a/sdk/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/sdk/vendor/golang.org/x/sys/windows/zsyscall_windows.go
index 6d2a26853..a81ea2c70 100644
--- a/sdk/vendor/golang.org/x/sys/windows/zsyscall_windows.go
+++ b/sdk/vendor/golang.org/x/sys/windows/zsyscall_windows.go
@@ -86,6 +86,7 @@ var (
procDeleteService = modadvapi32.NewProc("DeleteService")
procDeregisterEventSource = modadvapi32.NewProc("DeregisterEventSource")
procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx")
+ procEnumDependentServicesW = modadvapi32.NewProc("EnumDependentServicesW")
procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW")
procEqualSid = modadvapi32.NewProc("EqualSid")
procFreeSid = modadvapi32.NewProc("FreeSid")
@@ -734,6 +735,14 @@ func DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes
return
}
+func EnumDependentServices(service Handle, activityState uint32, services *ENUM_SERVICE_STATUS, buffSize uint32, bytesNeeded *uint32, servicesReturned *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procEnumDependentServicesW.Addr(), 6, uintptr(service), uintptr(activityState), uintptr(unsafe.Pointer(services)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) {
r1, _, e1 := syscall.Syscall12(procEnumServicesStatusExW.Addr(), 10, uintptr(mgr), uintptr(infoLevel), uintptr(serviceType), uintptr(serviceState), uintptr(unsafe.Pointer(services)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), uintptr(unsafe.Pointer(servicesReturned)), uintptr(unsafe.Pointer(resumeHandle)), uintptr(unsafe.Pointer(groupName)), 0, 0)
if r1 == 0 {
diff --git a/sdk/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/sdk/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
index be8f5a867..aa7dfaccf 100644
--- a/sdk/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
+++ b/sdk/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
@@ -113,6 +113,20 @@ const (
opObj = 'O' // .Obj() (Named, TypeParam)
)
+// For is equivalent to new(Encoder).For(obj).
+//
+// It may be more efficient to reuse a single Encoder across several calls.
+func For(obj types.Object) (Path, error) {
+ return new(Encoder).For(obj)
+}
+
+// An Encoder amortizes the cost of encoding the paths of multiple objects.
+// The zero value of an Encoder is ready to use.
+type Encoder struct {
+ scopeNamesMemo map[*types.Scope][]string // memoization of Scope.Names()
+ namedMethodsMemo map[*types.Named][]*types.Func // memoization of namedMethods()
+}
+
// For returns the path to an object relative to its package,
// or an error if the object is not accessible from the package's Scope.
//
@@ -145,24 +159,7 @@ const (
// .Type().Field(0) (field Var X)
//
// where p is the package (*types.Package) to which X belongs.
-func For(obj types.Object) (Path, error) {
- return newEncoderFor()(obj)
-}
-
-// An encoder amortizes the cost of encoding the paths of multiple objects.
-// Nonexported pending approval of proposal 58668.
-type encoder struct {
- scopeNamesMemo map[*types.Scope][]string // memoization of Scope.Names()
- namedMethodsMemo map[*types.Named][]*types.Func // memoization of namedMethods()
-}
-
-// Exposed to gopls via golang.org/x/tools/internal/typesinternal
-// pending approval of proposal 58668.
-//
-//go:linkname newEncoderFor
-func newEncoderFor() func(types.Object) (Path, error) { return new(encoder).For }
-
-func (enc *encoder) For(obj types.Object) (Path, error) {
+func (enc *Encoder) For(obj types.Object) (Path, error) {
pkg := obj.Pkg()
// This table lists the cases of interest.
@@ -341,7 +338,7 @@ func appendOpArg(path []byte, op byte, arg int) []byte {
// This function is just an optimization that avoids the general scope walking
// approach. You are expected to fall back to the general approach if this
// function fails.
-func (enc *encoder) concreteMethod(meth *types.Func) (Path, bool) {
+func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
// Concrete methods can only be declared on package-scoped named types. For
// that reason we can skip the expensive walk over the package scope: the
// path will always be package -> named type -> method. We can trivially get
@@ -421,7 +418,13 @@ func (enc *encoder) concreteMethod(meth *types.Func) (Path, bool) {
}
}
- panic(fmt.Sprintf("couldn't find method %s on type %s", meth, named))
+ // Due to golang/go#59944, go/types fails to associate the receiver with
+ // certain methods on cgo types.
+ //
+ // TODO(rfindley): replace this panic once golang/go#59944 is fixed in all Go
+ // versions gopls supports.
+ return "", false
+ // panic(fmt.Sprintf("couldn't find method %s on type %s; methods: %#v", meth, named, enc.namedMethods(named)))
}
// find finds obj within type T, returning the path to it, or nil if not found.
@@ -730,23 +733,8 @@ func namedMethods(named *types.Named) []*types.Func {
return methods
}
-// scopeNames is a memoization of scope.Names. Callers must not modify the result.
-func (enc *encoder) scopeNames(scope *types.Scope) []string {
- m := enc.scopeNamesMemo
- if m == nil {
- m = make(map[*types.Scope][]string)
- enc.scopeNamesMemo = m
- }
- names, ok := m[scope]
- if !ok {
- names = scope.Names() // allocates and sorts
- m[scope] = names
- }
- return names
-}
-
// namedMethods is a memoization of the namedMethods function. Callers must not modify the result.
-func (enc *encoder) namedMethods(named *types.Named) []*types.Func {
+func (enc *Encoder) namedMethods(named *types.Named) []*types.Func {
m := enc.namedMethodsMemo
if m == nil {
m = make(map[*types.Named][]*types.Func)
@@ -758,5 +746,19 @@ func (enc *encoder) namedMethods(named *types.Named) []*types.Func {
m[named] = methods
}
return methods
+}
+// scopeNames is a memoization of scope.Names. Callers must not modify the result.
+func (enc *Encoder) scopeNames(scope *types.Scope) []string {
+ m := enc.scopeNamesMemo
+ if m == nil {
+ m = make(map[*types.Scope][]string)
+ enc.scopeNamesMemo = m
+ }
+ names, ok := m[scope]
+ if !ok {
+ names = scope.Names() // allocates and sorts
+ m[scope] = names
+ }
+ return names
}
diff --git a/sdk/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/sdk/vendor/golang.org/x/tools/internal/gocommand/invoke.go
index d50551693..3c0afe723 100644
--- a/sdk/vendor/golang.org/x/tools/internal/gocommand/invoke.go
+++ b/sdk/vendor/golang.org/x/tools/internal/gocommand/invoke.go
@@ -8,10 +8,12 @@ package gocommand
import (
"bytes"
"context"
+ "errors"
"fmt"
"io"
"log"
"os"
+ "reflect"
"regexp"
"runtime"
"strconv"
@@ -215,6 +217,18 @@ func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error {
cmd := exec.Command("go", goArgs...)
cmd.Stdout = stdout
cmd.Stderr = stderr
+
+ // cmd.WaitDelay was added only in go1.20 (see #50436).
+ if waitDelay := reflect.ValueOf(cmd).Elem().FieldByName("WaitDelay"); waitDelay.IsValid() {
+ // https://go.dev/issue/59541: don't wait forever copying stderr
+ // after the command has exited.
+ // After CL 484741 we copy stdout manually, so we we'll stop reading that as
+ // soon as ctx is done. However, we also don't want to wait around forever
+ // for stderr. Give a much-longer-than-reasonable delay and then assume that
+ // something has wedged in the kernel or runtime.
+ waitDelay.Set(reflect.ValueOf(30 * time.Second))
+ }
+
// On darwin the cwd gets resolved to the real path, which breaks anything that
// expects the working directory to keep the original path, including the
// go command when dealing with modules.
@@ -229,6 +243,7 @@ func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error {
cmd.Env = append(cmd.Env, "PWD="+i.WorkingDir)
cmd.Dir = i.WorkingDir
}
+
defer func(start time.Time) { log("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now())
return runCmdContext(ctx, cmd)
@@ -242,10 +257,85 @@ var DebugHangingGoCommands = false
// runCmdContext is like exec.CommandContext except it sends os.Interrupt
// before os.Kill.
-func runCmdContext(ctx context.Context, cmd *exec.Cmd) error {
- if err := cmd.Start(); err != nil {
+func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) {
+ // If cmd.Stdout is not an *os.File, the exec package will create a pipe and
+ // copy it to the Writer in a goroutine until the process has finished and
+ // either the pipe reaches EOF or command's WaitDelay expires.
+ //
+ // However, the output from 'go list' can be quite large, and we don't want to
+ // keep reading (and allocating buffers) if we've already decided we don't
+ // care about the output. We don't want to wait for the process to finish, and
+ // we don't wait to wait for the WaitDelay to expire either.
+ //
+ // Instead, if cmd.Stdout requires a copying goroutine we explicitly replace
+ // it with a pipe (which is an *os.File), which we can close in order to stop
+ // copying output as soon as we realize we don't care about it.
+ var stdoutW *os.File
+ if cmd.Stdout != nil {
+ if _, ok := cmd.Stdout.(*os.File); !ok {
+ var stdoutR *os.File
+ stdoutR, stdoutW, err = os.Pipe()
+ if err != nil {
+ return err
+ }
+ prevStdout := cmd.Stdout
+ cmd.Stdout = stdoutW
+
+ stdoutErr := make(chan error, 1)
+ go func() {
+ _, err := io.Copy(prevStdout, stdoutR)
+ if err != nil {
+ err = fmt.Errorf("copying stdout: %w", err)
+ }
+ stdoutErr <- err
+ }()
+ defer func() {
+ // We started a goroutine to copy a stdout pipe.
+ // Wait for it to finish, or terminate it if need be.
+ var err2 error
+ select {
+ case err2 = <-stdoutErr:
+ stdoutR.Close()
+ case <-ctx.Done():
+ stdoutR.Close()
+ // Per https://pkg.go.dev/os#File.Close, the call to stdoutR.Close
+ // should cause the Read call in io.Copy to unblock and return
+ // immediately, but we still need to receive from stdoutErr to confirm
+ // that that has happened.
+ <-stdoutErr
+ err2 = ctx.Err()
+ }
+ if err == nil {
+ err = err2
+ }
+ }()
+
+ // Per https://pkg.go.dev/os/exec#Cmd, “If Stdout and Stderr are the
+ // same writer, and have a type that can be compared with ==, at most
+ // one goroutine at a time will call Write.”
+ //
+ // Since we're starting a goroutine that writes to cmd.Stdout, we must
+ // also update cmd.Stderr so that that still holds.
+ func() {
+ defer func() { recover() }()
+ if cmd.Stderr == prevStdout {
+ cmd.Stderr = cmd.Stdout
+ }
+ }()
+ }
+ }
+
+ err = cmd.Start()
+ if stdoutW != nil {
+ // The child process has inherited the pipe file,
+ // so close the copy held in this process.
+ stdoutW.Close()
+ stdoutW = nil
+ }
+ if err != nil {
return err
}
+
resChan := make(chan error, 1)
go func() {
resChan <- cmd.Wait()
@@ -253,11 +343,14 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) error {
// If we're interested in debugging hanging Go commands, stop waiting after a
// minute and panic with interesting information.
- if DebugHangingGoCommands {
+ debug := DebugHangingGoCommands
+ if debug {
+ timer := time.NewTimer(1 * time.Minute)
+ defer timer.Stop()
select {
case err := <-resChan:
return err
- case <-time.After(1 * time.Minute):
+ case <-timer.C:
HandleHangingGoCommand(cmd.Process)
case <-ctx.Done():
}
@@ -270,30 +363,25 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) error {
}
// Cancelled. Interrupt and see if it ends voluntarily.
- cmd.Process.Signal(os.Interrupt)
- select {
- case err := <-resChan:
- return err
- case <-time.After(time.Second):
+ if err := cmd.Process.Signal(os.Interrupt); err == nil {
+ // (We used to wait only 1s but this proved
+ // fragile on loaded builder machines.)
+ timer := time.NewTimer(5 * time.Second)
+ defer timer.Stop()
+ select {
+ case err := <-resChan:
+ return err
+ case <-timer.C:
+ }
}
// Didn't shut down in response to interrupt. Kill it hard.
// TODO(rfindley): per advice from bcmills@, it may be better to send SIGQUIT
// on certain platforms, such as unix.
- if err := cmd.Process.Kill(); err != nil && DebugHangingGoCommands {
- // Don't panic here as this reliably fails on windows with EINVAL.
+ if err := cmd.Process.Kill(); err != nil && !errors.Is(err, os.ErrProcessDone) && debug {
log.Printf("error killing the Go command: %v", err)
}
- // See above: don't wait indefinitely if we're debugging hanging Go commands.
- if DebugHangingGoCommands {
- select {
- case err := <-resChan:
- return err
- case <-time.After(10 * time.Second): // a shorter wait as resChan should return quickly following Kill
- HandleHangingGoCommand(cmd.Process)
- }
- }
return <-resChan
}
diff --git a/sdk/vendor/golang.org/x/tools/internal/gocommand/version.go b/sdk/vendor/golang.org/x/tools/internal/gocommand/version.go
index 307a76d47..446c5846a 100644
--- a/sdk/vendor/golang.org/x/tools/internal/gocommand/version.go
+++ b/sdk/vendor/golang.org/x/tools/internal/gocommand/version.go
@@ -23,21 +23,11 @@ import (
func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) {
inv.Verb = "list"
inv.Args = []string{"-e", "-f", `{{context.ReleaseTags}}`, `--`, `unsafe`}
- inv.Env = append(append([]string{}, inv.Env...), "GO111MODULE=off")
- // Unset any unneeded flags, and remove them from BuildFlags, if they're
- // present.
- inv.ModFile = ""
+ inv.BuildFlags = nil // This is not a build command.
inv.ModFlag = ""
- var buildFlags []string
- for _, flag := range inv.BuildFlags {
- // Flags can be prefixed by one or two dashes.
- f := strings.TrimPrefix(strings.TrimPrefix(flag, "-"), "-")
- if strings.HasPrefix(f, "mod=") || strings.HasPrefix(f, "modfile=") {
- continue
- }
- buildFlags = append(buildFlags, flag)
- }
- inv.BuildFlags = buildFlags
+ inv.ModFile = ""
+ inv.Env = append(inv.Env[:len(inv.Env):len(inv.Env)], "GO111MODULE=off")
+
stdoutBytes, err := r.Run(ctx, inv)
if err != nil {
return 0, err
diff --git a/sdk/vendor/golang.org/x/tools/internal/imports/fix.go b/sdk/vendor/golang.org/x/tools/internal/imports/fix.go
index 642a5ac2d..6b4935257 100644
--- a/sdk/vendor/golang.org/x/tools/internal/imports/fix.go
+++ b/sdk/vendor/golang.org/x/tools/internal/imports/fix.go
@@ -414,9 +414,16 @@ func (p *pass) fix() ([]*ImportFix, bool) {
})
}
}
-
+ // Collecting fixes involved map iteration, so sort for stability. See
+ // golang/go#59976.
+ sortFixes(fixes)
+
+ // collect selected fixes in a separate slice, so that it can be sorted
+ // separately. Note that these fixes must occur after fixes to existing
+ // imports. TODO(rfindley): figure out why.
+ var selectedFixes []*ImportFix
for _, imp := range selected {
- fixes = append(fixes, &ImportFix{
+ selectedFixes = append(selectedFixes, &ImportFix{
StmtInfo: ImportInfo{
Name: p.importSpecName(imp),
ImportPath: imp.ImportPath,
@@ -425,8 +432,25 @@ func (p *pass) fix() ([]*ImportFix, bool) {
FixType: AddImport,
})
}
+ sortFixes(selectedFixes)
+
+ return append(fixes, selectedFixes...), true
+}
- return fixes, true
+func sortFixes(fixes []*ImportFix) {
+ sort.Slice(fixes, func(i, j int) bool {
+ fi, fj := fixes[i], fixes[j]
+ if fi.StmtInfo.ImportPath != fj.StmtInfo.ImportPath {
+ return fi.StmtInfo.ImportPath < fj.StmtInfo.ImportPath
+ }
+ if fi.StmtInfo.Name != fj.StmtInfo.Name {
+ return fi.StmtInfo.Name < fj.StmtInfo.Name
+ }
+ if fi.IdentName != fj.IdentName {
+ return fi.IdentName < fj.IdentName
+ }
+ return fi.FixType < fj.FixType
+ })
}
// importSpecName gets the import name of imp in the import spec.
diff --git a/sdk/vendor/google.golang.org/grpc/CONTRIBUTING.md b/sdk/vendor/google.golang.org/grpc/CONTRIBUTING.md
index 52338d004..608aa6e1a 100644
--- a/sdk/vendor/google.golang.org/grpc/CONTRIBUTING.md
+++ b/sdk/vendor/google.golang.org/grpc/CONTRIBUTING.md
@@ -20,6 +20,15 @@ How to get your contributions merged smoothly and quickly.
both author's & review's time is wasted. Create more PRs to address different
concerns and everyone will be happy.
+- If you are searching for features to work on, issues labeled [Status: Help
+ Wanted](https://github.com/grpc/grpc-go/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22Status%3A+Help+Wanted%22)
+ is a great place to start. These issues are well-documented and usually can be
+ resolved with a single pull request.
+
+- If you are adding a new file, make sure it has the copyright message template
+ at the top as a comment. You can copy over the message from an existing file
+ and update the year.
+
- The grpc package should only depend on standard Go packages and a small number
of exceptions. If your contribution introduces new dependencies which are NOT
in the [list](https://godoc.org/google.golang.org/grpc?imports), you need a
@@ -32,14 +41,18 @@ How to get your contributions merged smoothly and quickly.
- Provide a good **PR description** as a record of **what** change is being made
and **why** it was made. Link to a github issue if it exists.
-- Don't fix code style and formatting unless you are already changing that line
- to address an issue. PRs with irrelevant changes won't be merged. If you do
- want to fix formatting or style, do that in a separate PR.
+- If you want to fix formatting or style, consider whether your changes are an
+ obvious improvement or might be considered a personal preference. If a style
+ change is based on preference, it likely will not be accepted. If it corrects
+ widely agreed-upon anti-patterns, then please do create a PR and explain the
+ benefits of the change.
- Unless your PR is trivial, you should expect there will be reviewer comments
- that you'll need to address before merging. We expect you to be reasonably
- responsive to those comments, otherwise the PR will be closed after 2-3 weeks
- of inactivity.
+ that you'll need to address before merging. We'll mark it as `Status: Requires
+ Reporter Clarification` if we expect you to respond to these comments in a
+ timely manner. If the PR remains inactive for 6 days, it will be marked as
+ `stale` and automatically close 7 days after that if we don't hear back from
+ you.
- Maintain **clean commit history** and use **meaningful commit messages**. PRs
with messy commit history are difficult to review and won't be merged. Use
diff --git a/sdk/vendor/google.golang.org/grpc/balancer/balancer.go b/sdk/vendor/google.golang.org/grpc/balancer/balancer.go
index 392b21fb2..09d61dd1b 100644
--- a/sdk/vendor/google.golang.org/grpc/balancer/balancer.go
+++ b/sdk/vendor/google.golang.org/grpc/balancer/balancer.go
@@ -279,6 +279,14 @@ type PickResult struct {
// type, Done may not be called. May be nil if the balancer does not wish
// to be notified when the RPC completes.
Done func(DoneInfo)
+
+ // Metadata provides a way for LB policies to inject arbitrary per-call
+ // metadata. Any metadata returned here will be merged with existing
+ // metadata added by the client application.
+ //
+ // LB policies with child policies are responsible for propagating metadata
+ // injected by their children to the ClientConn, as part of Pick().
+ Metatada metadata.MD
}
// TransientFailureError returns e. It exists for backward compatibility and
diff --git a/test/integration/vendor/google.golang.org/grpc/balancer/grpclb/grpclbstate/state.go b/sdk/vendor/google.golang.org/grpc/balancer/grpclb/state/state.go
similarity index 87%
rename from test/integration/vendor/google.golang.org/grpc/balancer/grpclb/grpclbstate/state.go
rename to sdk/vendor/google.golang.org/grpc/balancer/grpclb/state/state.go
index cece046be..4ecfa1c21 100644
--- a/test/integration/vendor/google.golang.org/grpc/balancer/grpclb/grpclbstate/state.go
+++ b/sdk/vendor/google.golang.org/grpc/balancer/grpclb/state/state.go
@@ -16,9 +16,9 @@
*
*/
-// Package grpclbstate declares grpclb types to be set by resolvers wishing to
-// pass information to grpclb via resolver.State Attributes.
-package grpclbstate
+// Package state declares grpclb types to be set by resolvers wishing to pass
+// information to grpclb via resolver.State Attributes.
+package state
import (
"google.golang.org/grpc/resolver"
@@ -27,7 +27,7 @@ import (
// keyType is the key to use for storing State in Attributes.
type keyType string
-const key = keyType("grpc.grpclb.grpclbstate")
+const key = keyType("grpc.grpclb.state")
// State contains gRPCLB-relevant data passed from the name resolver.
type State struct {
diff --git a/sdk/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go b/sdk/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go
index 66d141fce..ec2c2fa14 100644
--- a/sdk/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go
+++ b/sdk/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go
@@ -18,8 +18,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.28.1
-// protoc v3.14.0
+// protoc-gen-go v1.30.0
+// protoc v4.22.0
// source: grpc/binlog/v1/binarylog.proto
package grpc_binarylog_v1
diff --git a/sdk/vendor/google.golang.org/grpc/clientconn.go b/sdk/vendor/google.golang.org/grpc/clientconn.go
index 045668904..3a7614242 100644
--- a/sdk/vendor/google.golang.org/grpc/clientconn.go
+++ b/sdk/vendor/google.golang.org/grpc/clientconn.go
@@ -146,8 +146,18 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{nil})
cc.ctx, cc.cancel = context.WithCancel(context.Background())
- for _, opt := range extraDialOptions {
- opt.apply(&cc.dopts)
+ disableGlobalOpts := false
+ for _, opt := range opts {
+ if _, ok := opt.(*disableGlobalDialOptions); ok {
+ disableGlobalOpts = true
+ break
+ }
+ }
+
+ if !disableGlobalOpts {
+ for _, opt := range globalDialOptions {
+ opt.apply(&cc.dopts)
+ }
}
for _, opt := range opts {
@@ -234,19 +244,6 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
}
}()
- scSet := false
- if cc.dopts.scChan != nil {
- // Try to get an initial service config.
- select {
- case sc, ok := <-cc.dopts.scChan:
- if ok {
- cc.sc = &sc
- cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{&sc})
- scSet = true
- }
- default:
- }
- }
if cc.dopts.bs == nil {
cc.dopts.bs = backoff.DefaultExponential
}
@@ -256,13 +253,13 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
if err != nil {
return nil, err
}
- cc.authority, err = determineAuthority(cc.parsedTarget.Endpoint, cc.target, cc.dopts)
+ cc.authority, err = determineAuthority(cc.parsedTarget.Endpoint(), cc.target, cc.dopts)
if err != nil {
return nil, err
}
channelz.Infof(logger, cc.channelzID, "Channel authority set to %q", cc.authority)
- if cc.dopts.scChan != nil && !scSet {
+ if cc.dopts.scChan != nil {
// Blocking wait for the initial service config.
select {
case sc, ok := <-cc.dopts.scChan:
@@ -934,7 +931,7 @@ func (cc *ClientConn) healthCheckConfig() *healthCheckConfig {
return cc.sc.healthCheckConfig
}
-func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method string) (transport.ClientTransport, func(balancer.DoneInfo), error) {
+func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method string) (transport.ClientTransport, balancer.PickResult, error) {
return cc.blockingpicker.pick(ctx, failfast, balancer.PickInfo{
Ctx: ctx,
FullMethodName: method,
@@ -1103,7 +1100,11 @@ func (ac *addrConn) updateConnectivityState(s connectivity.State, lastErr error)
return
}
ac.state = s
- channelz.Infof(logger, ac.channelzID, "Subchannel Connectivity change to %v", s)
+ if lastErr == nil {
+ channelz.Infof(logger, ac.channelzID, "Subchannel Connectivity change to %v", s)
+ } else {
+ channelz.Infof(logger, ac.channelzID, "Subchannel Connectivity change to %v, last error: %s", s, lastErr)
+ }
ac.cc.handleSubConnStateChange(ac.acbw, s, lastErr)
}
@@ -1237,9 +1238,11 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
addr.ServerName = ac.cc.getServerName(addr)
hctx, hcancel := context.WithCancel(ac.ctx)
- onClose := grpcsync.OnceFunc(func() {
+ onClose := func(r transport.GoAwayReason) {
ac.mu.Lock()
defer ac.mu.Unlock()
+ // adjust params based on GoAwayReason
+ ac.adjustParams(r)
if ac.state == connectivity.Shutdown {
// Already shut down. tearDown() already cleared the transport and
// canceled hctx via ac.ctx, and we expected this connection to be
@@ -1260,19 +1263,13 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
// Always go idle and wait for the LB policy to initiate a new
// connection attempt.
ac.updateConnectivityState(connectivity.Idle, nil)
- })
- onGoAway := func(r transport.GoAwayReason) {
- ac.mu.Lock()
- ac.adjustParams(r)
- ac.mu.Unlock()
- onClose()
}
connectCtx, cancel := context.WithDeadline(ac.ctx, connectDeadline)
defer cancel()
copts.ChannelzParentID = ac.channelzID
- newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, onGoAway, onClose)
+ newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, onClose)
if err != nil {
if logger.V(2) {
logger.Infof("Creating new client transport to %q: %v", addr, err)
@@ -1380,7 +1377,7 @@ func (ac *addrConn) startHealthCheck(ctx context.Context) {
if status.Code(err) == codes.Unimplemented {
channelz.Error(logger, ac.channelzID, "Subchannel health check is unimplemented at server side, thus health check is disabled")
} else {
- channelz.Errorf(logger, ac.channelzID, "HealthCheckFunc exits with unexpected error %v", err)
+ channelz.Errorf(logger, ac.channelzID, "Health checking failed: %v", err)
}
}
}()
@@ -1531,6 +1528,9 @@ func (c *channelzChannel) ChannelzMetric() *channelz.ChannelInternalMetric {
// referenced by users.
var ErrClientConnTimeout = errors.New("grpc: timed out when dialing")
+// getResolver finds the scheme in the cc's resolvers or the global registry.
+// scheme should always be lowercase (typically by virtue of url.Parse()
+// performing proper RFC3986 behavior).
func (cc *ClientConn) getResolver(scheme string) resolver.Builder {
for _, rb := range cc.dopts.resolvers {
if scheme == rb.Scheme() {
@@ -1591,30 +1591,17 @@ func (cc *ClientConn) parseTargetAndFindResolver() (resolver.Builder, error) {
}
// parseTarget uses RFC 3986 semantics to parse the given target into a
-// resolver.Target struct containing scheme, authority and endpoint. Query
+// resolver.Target struct containing scheme, authority and url. Query
// params are stripped from the endpoint.
func parseTarget(target string) (resolver.Target, error) {
u, err := url.Parse(target)
if err != nil {
return resolver.Target{}, err
}
- // For targets of the form "[scheme]://[authority]/endpoint, the endpoint
- // value returned from url.Parse() contains a leading "/". Although this is
- // in accordance with RFC 3986, we do not want to break existing resolver
- // implementations which expect the endpoint without the leading "/". So, we
- // end up stripping the leading "/" here. But this will result in an
- // incorrect parsing for something like "unix:///path/to/socket". Since we
- // own the "unix" resolver, we can workaround in the unix resolver by using
- // the `URL` field instead of the `Endpoint` field.
- endpoint := u.Path
- if endpoint == "" {
- endpoint = u.Opaque
- }
- endpoint = strings.TrimPrefix(endpoint, "/")
+
return resolver.Target{
Scheme: u.Scheme,
Authority: u.Host,
- Endpoint: endpoint,
URL: *u,
}, nil
}
diff --git a/sdk/vendor/google.golang.org/grpc/codes/code_string.go b/sdk/vendor/google.golang.org/grpc/codes/code_string.go
index 0b206a578..934fac2b0 100644
--- a/sdk/vendor/google.golang.org/grpc/codes/code_string.go
+++ b/sdk/vendor/google.golang.org/grpc/codes/code_string.go
@@ -18,7 +18,15 @@
package codes
-import "strconv"
+import (
+ "strconv"
+
+ "google.golang.org/grpc/internal"
+)
+
+func init() {
+ internal.CanonicalString = canonicalString
+}
func (c Code) String() string {
switch c {
@@ -60,3 +68,44 @@ func (c Code) String() string {
return "Code(" + strconv.FormatInt(int64(c), 10) + ")"
}
}
+
+func canonicalString(c Code) string {
+ switch c {
+ case OK:
+ return "OK"
+ case Canceled:
+ return "CANCELLED"
+ case Unknown:
+ return "UNKNOWN"
+ case InvalidArgument:
+ return "INVALID_ARGUMENT"
+ case DeadlineExceeded:
+ return "DEADLINE_EXCEEDED"
+ case NotFound:
+ return "NOT_FOUND"
+ case AlreadyExists:
+ return "ALREADY_EXISTS"
+ case PermissionDenied:
+ return "PERMISSION_DENIED"
+ case ResourceExhausted:
+ return "RESOURCE_EXHAUSTED"
+ case FailedPrecondition:
+ return "FAILED_PRECONDITION"
+ case Aborted:
+ return "ABORTED"
+ case OutOfRange:
+ return "OUT_OF_RANGE"
+ case Unimplemented:
+ return "UNIMPLEMENTED"
+ case Internal:
+ return "INTERNAL"
+ case Unavailable:
+ return "UNAVAILABLE"
+ case DataLoss:
+ return "DATA_LOSS"
+ case Unauthenticated:
+ return "UNAUTHENTICATED"
+ default:
+ return "CODE(" + strconv.FormatInt(int64(c), 10) + ")"
+ }
+}
diff --git a/sdk/vendor/google.golang.org/grpc/credentials/tls.go b/sdk/vendor/google.golang.org/grpc/credentials/tls.go
index ce2bbc10a..877b7cd21 100644
--- a/sdk/vendor/google.golang.org/grpc/credentials/tls.go
+++ b/sdk/vendor/google.golang.org/grpc/credentials/tls.go
@@ -23,9 +23,9 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
- "io/ioutil"
"net"
"net/url"
+ "os"
credinternal "google.golang.org/grpc/internal/credentials"
)
@@ -166,7 +166,7 @@ func NewClientTLSFromCert(cp *x509.CertPool, serverNameOverride string) Transpor
// it will override the virtual host name of authority (e.g. :authority header
// field) in requests.
func NewClientTLSFromFile(certFile, serverNameOverride string) (TransportCredentials, error) {
- b, err := ioutil.ReadFile(certFile)
+ b, err := os.ReadFile(certFile)
if err != nil {
return nil, err
}
diff --git a/sdk/vendor/google.golang.org/grpc/dialoptions.go b/sdk/vendor/google.golang.org/grpc/dialoptions.go
index 8f5b536f1..cdc8263bd 100644
--- a/sdk/vendor/google.golang.org/grpc/dialoptions.go
+++ b/sdk/vendor/google.golang.org/grpc/dialoptions.go
@@ -38,12 +38,14 @@ import (
func init() {
internal.AddGlobalDialOptions = func(opt ...DialOption) {
- extraDialOptions = append(extraDialOptions, opt...)
+ globalDialOptions = append(globalDialOptions, opt...)
}
internal.ClearGlobalDialOptions = func() {
- extraDialOptions = nil
+ globalDialOptions = nil
}
internal.WithBinaryLogger = withBinaryLogger
+ internal.JoinDialOptions = newJoinDialOption
+ internal.DisableGlobalDialOptions = newDisableGlobalDialOptions
}
// dialOptions configure a Dial call. dialOptions are set by the DialOption
@@ -82,7 +84,7 @@ type DialOption interface {
apply(*dialOptions)
}
-var extraDialOptions []DialOption
+var globalDialOptions []DialOption
// EmptyDialOption does not alter the dial configuration. It can be embedded in
// another structure to build custom dial options.
@@ -95,6 +97,16 @@ type EmptyDialOption struct{}
func (EmptyDialOption) apply(*dialOptions) {}
+type disableGlobalDialOptions struct{}
+
+func (disableGlobalDialOptions) apply(*dialOptions) {}
+
+// newDisableGlobalDialOptions returns a DialOption that prevents the ClientConn
+// from applying the global DialOptions (set via AddGlobalDialOptions).
+func newDisableGlobalDialOptions() DialOption {
+ return &disableGlobalDialOptions{}
+}
+
// funcDialOption wraps a function that modifies dialOptions into an
// implementation of the DialOption interface.
type funcDialOption struct {
@@ -111,6 +123,20 @@ func newFuncDialOption(f func(*dialOptions)) *funcDialOption {
}
}
+type joinDialOption struct {
+ opts []DialOption
+}
+
+func (jdo *joinDialOption) apply(do *dialOptions) {
+ for _, opt := range jdo.opts {
+ opt.apply(do)
+ }
+}
+
+func newJoinDialOption(opts ...DialOption) DialOption {
+ return &joinDialOption{opts: opts}
+}
+
// WithWriteBufferSize determines how much data can be batched before doing a
// write on the wire. The corresponding memory allocation for this buffer will
// be twice the size to keep syscalls low. The default value for this buffer is
@@ -269,6 +295,9 @@ func withBackoff(bs internalbackoff.Strategy) DialOption {
// WithBlock returns a DialOption which makes callers of Dial block until the
// underlying connection is up. Without this, Dial returns immediately and
// connecting the server happens in background.
+//
+// Use of this feature is not recommended. For more information, please see:
+// https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md
func WithBlock() DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.block = true
@@ -280,6 +309,9 @@ func WithBlock() DialOption {
// the context.DeadlineExceeded error.
// Implies WithBlock()
//
+// Use of this feature is not recommended. For more information, please see:
+// https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md
+//
// # Experimental
//
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
@@ -422,6 +454,9 @@ func withBinaryLogger(bl binarylog.Logger) DialOption {
// FailOnNonTempDialError only affects the initial dial, and does not do
// anything useful unless you are also using WithBlock().
//
+// Use of this feature is not recommended. For more information, please see:
+// https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md
+//
// # Experimental
//
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
diff --git a/sdk/vendor/google.golang.org/grpc/encoding/encoding.go b/sdk/vendor/google.golang.org/grpc/encoding/encoding.go
index 711763d54..07a586135 100644
--- a/sdk/vendor/google.golang.org/grpc/encoding/encoding.go
+++ b/sdk/vendor/google.golang.org/grpc/encoding/encoding.go
@@ -75,7 +75,9 @@ var registeredCompressor = make(map[string]Compressor)
// registered with the same name, the one registered last will take effect.
func RegisterCompressor(c Compressor) {
registeredCompressor[c.Name()] = c
- grpcutil.RegisteredCompressorNames = append(grpcutil.RegisteredCompressorNames, c.Name())
+ if !grpcutil.IsCompressorNameRegistered(c.Name()) {
+ grpcutil.RegisteredCompressorNames = append(grpcutil.RegisteredCompressorNames, c.Name())
+ }
}
// GetCompressor returns Compressor for the given compressor name.
diff --git a/sdk/vendor/google.golang.org/grpc/grpclog/loggerv2.go b/sdk/vendor/google.golang.org/grpc/grpclog/loggerv2.go
index b5560b47e..5de66e40d 100644
--- a/sdk/vendor/google.golang.org/grpc/grpclog/loggerv2.go
+++ b/sdk/vendor/google.golang.org/grpc/grpclog/loggerv2.go
@@ -22,7 +22,6 @@ import (
"encoding/json"
"fmt"
"io"
- "io/ioutil"
"log"
"os"
"strconv"
@@ -140,9 +139,9 @@ func newLoggerV2WithConfig(infoW, warningW, errorW io.Writer, c loggerV2Config)
// newLoggerV2 creates a loggerV2 to be used as default logger.
// All logs are written to stderr.
func newLoggerV2() LoggerV2 {
- errorW := ioutil.Discard
- warningW := ioutil.Discard
- infoW := ioutil.Discard
+ errorW := io.Discard
+ warningW := io.Discard
+ infoW := io.Discard
logLevel := os.Getenv("GRPC_GO_LOG_SEVERITY_LEVEL")
switch logLevel {
diff --git a/sdk/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go b/sdk/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go
index 809d73cca..af03a40d9 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go
@@ -28,8 +28,10 @@ import (
"google.golang.org/grpc/internal/grpcutil"
)
-// Logger is the global binary logger. It can be used to get binary logger for
-// each method.
+var grpclogLogger = grpclog.Component("binarylog")
+
+// Logger specifies MethodLoggers for method names with a Log call that
+// takes a context.
type Logger interface {
GetMethodLogger(methodName string) MethodLogger
}
@@ -40,8 +42,6 @@ type Logger interface {
// It is used to get a MethodLogger for each individual method.
var binLogger Logger
-var grpclogLogger = grpclog.Component("binarylog")
-
// SetLogger sets the binary logger.
//
// Only call this at init time.
diff --git a/sdk/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go b/sdk/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go
index 85e3ff281..56fcf008d 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go
@@ -19,6 +19,7 @@
package binarylog
import (
+ "context"
"net"
"strings"
"sync/atomic"
@@ -26,7 +27,7 @@ import (
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes"
- pb "google.golang.org/grpc/binarylog/grpc_binarylog_v1"
+ binlogpb "google.golang.org/grpc/binarylog/grpc_binarylog_v1"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)
@@ -49,7 +50,7 @@ var idGen callIDGenerator
// MethodLogger is the sub-logger for each method.
type MethodLogger interface {
- Log(LogEntryConfig)
+ Log(context.Context, LogEntryConfig)
}
// TruncatingMethodLogger is a method logger that truncates headers and messages
@@ -79,7 +80,7 @@ func NewTruncatingMethodLogger(h, m uint64) *TruncatingMethodLogger {
// Build is an internal only method for building the proto message out of the
// input event. It's made public to enable other library to reuse as much logic
// in TruncatingMethodLogger as possible.
-func (ml *TruncatingMethodLogger) Build(c LogEntryConfig) *pb.GrpcLogEntry {
+func (ml *TruncatingMethodLogger) Build(c LogEntryConfig) *binlogpb.GrpcLogEntry {
m := c.toProto()
timestamp, _ := ptypes.TimestampProto(time.Now())
m.Timestamp = timestamp
@@ -87,22 +88,22 @@ func (ml *TruncatingMethodLogger) Build(c LogEntryConfig) *pb.GrpcLogEntry {
m.SequenceIdWithinCall = ml.idWithinCallGen.next()
switch pay := m.Payload.(type) {
- case *pb.GrpcLogEntry_ClientHeader:
+ case *binlogpb.GrpcLogEntry_ClientHeader:
m.PayloadTruncated = ml.truncateMetadata(pay.ClientHeader.GetMetadata())
- case *pb.GrpcLogEntry_ServerHeader:
+ case *binlogpb.GrpcLogEntry_ServerHeader:
m.PayloadTruncated = ml.truncateMetadata(pay.ServerHeader.GetMetadata())
- case *pb.GrpcLogEntry_Message:
+ case *binlogpb.GrpcLogEntry_Message:
m.PayloadTruncated = ml.truncateMessage(pay.Message)
}
return m
}
// Log creates a proto binary log entry, and logs it to the sink.
-func (ml *TruncatingMethodLogger) Log(c LogEntryConfig) {
+func (ml *TruncatingMethodLogger) Log(ctx context.Context, c LogEntryConfig) {
ml.sink.Write(ml.Build(c))
}
-func (ml *TruncatingMethodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated bool) {
+func (ml *TruncatingMethodLogger) truncateMetadata(mdPb *binlogpb.Metadata) (truncated bool) {
if ml.headerMaxLen == maxUInt {
return false
}
@@ -132,7 +133,7 @@ func (ml *TruncatingMethodLogger) truncateMetadata(mdPb *pb.Metadata) (truncated
return truncated
}
-func (ml *TruncatingMethodLogger) truncateMessage(msgPb *pb.Message) (truncated bool) {
+func (ml *TruncatingMethodLogger) truncateMessage(msgPb *binlogpb.Message) (truncated bool) {
if ml.messageMaxLen == maxUInt {
return false
}
@@ -145,7 +146,7 @@ func (ml *TruncatingMethodLogger) truncateMessage(msgPb *pb.Message) (truncated
// LogEntryConfig represents the configuration for binary log entry.
type LogEntryConfig interface {
- toProto() *pb.GrpcLogEntry
+ toProto() *binlogpb.GrpcLogEntry
}
// ClientHeader configs the binary log entry to be a ClientHeader entry.
@@ -159,10 +160,10 @@ type ClientHeader struct {
PeerAddr net.Addr
}
-func (c *ClientHeader) toProto() *pb.GrpcLogEntry {
+func (c *ClientHeader) toProto() *binlogpb.GrpcLogEntry {
// This function doesn't need to set all the fields (e.g. seq ID). The Log
// function will set the fields when necessary.
- clientHeader := &pb.ClientHeader{
+ clientHeader := &binlogpb.ClientHeader{
Metadata: mdToMetadataProto(c.Header),
MethodName: c.MethodName,
Authority: c.Authority,
@@ -170,16 +171,16 @@ func (c *ClientHeader) toProto() *pb.GrpcLogEntry {
if c.Timeout > 0 {
clientHeader.Timeout = ptypes.DurationProto(c.Timeout)
}
- ret := &pb.GrpcLogEntry{
- Type: pb.GrpcLogEntry_EVENT_TYPE_CLIENT_HEADER,
- Payload: &pb.GrpcLogEntry_ClientHeader{
+ ret := &binlogpb.GrpcLogEntry{
+ Type: binlogpb.GrpcLogEntry_EVENT_TYPE_CLIENT_HEADER,
+ Payload: &binlogpb.GrpcLogEntry_ClientHeader{
ClientHeader: clientHeader,
},
}
if c.OnClientSide {
- ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT
+ ret.Logger = binlogpb.GrpcLogEntry_LOGGER_CLIENT
} else {
- ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER
+ ret.Logger = binlogpb.GrpcLogEntry_LOGGER_SERVER
}
if c.PeerAddr != nil {
ret.Peer = addrToProto(c.PeerAddr)
@@ -195,19 +196,19 @@ type ServerHeader struct {
PeerAddr net.Addr
}
-func (c *ServerHeader) toProto() *pb.GrpcLogEntry {
- ret := &pb.GrpcLogEntry{
- Type: pb.GrpcLogEntry_EVENT_TYPE_SERVER_HEADER,
- Payload: &pb.GrpcLogEntry_ServerHeader{
- ServerHeader: &pb.ServerHeader{
+func (c *ServerHeader) toProto() *binlogpb.GrpcLogEntry {
+ ret := &binlogpb.GrpcLogEntry{
+ Type: binlogpb.GrpcLogEntry_EVENT_TYPE_SERVER_HEADER,
+ Payload: &binlogpb.GrpcLogEntry_ServerHeader{
+ ServerHeader: &binlogpb.ServerHeader{
Metadata: mdToMetadataProto(c.Header),
},
},
}
if c.OnClientSide {
- ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT
+ ret.Logger = binlogpb.GrpcLogEntry_LOGGER_CLIENT
} else {
- ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER
+ ret.Logger = binlogpb.GrpcLogEntry_LOGGER_SERVER
}
if c.PeerAddr != nil {
ret.Peer = addrToProto(c.PeerAddr)
@@ -223,7 +224,7 @@ type ClientMessage struct {
Message interface{}
}
-func (c *ClientMessage) toProto() *pb.GrpcLogEntry {
+func (c *ClientMessage) toProto() *binlogpb.GrpcLogEntry {
var (
data []byte
err error
@@ -238,19 +239,19 @@ func (c *ClientMessage) toProto() *pb.GrpcLogEntry {
} else {
grpclogLogger.Infof("binarylogging: message to log is neither proto.message nor []byte")
}
- ret := &pb.GrpcLogEntry{
- Type: pb.GrpcLogEntry_EVENT_TYPE_CLIENT_MESSAGE,
- Payload: &pb.GrpcLogEntry_Message{
- Message: &pb.Message{
+ ret := &binlogpb.GrpcLogEntry{
+ Type: binlogpb.GrpcLogEntry_EVENT_TYPE_CLIENT_MESSAGE,
+ Payload: &binlogpb.GrpcLogEntry_Message{
+ Message: &binlogpb.Message{
Length: uint32(len(data)),
Data: data,
},
},
}
if c.OnClientSide {
- ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT
+ ret.Logger = binlogpb.GrpcLogEntry_LOGGER_CLIENT
} else {
- ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER
+ ret.Logger = binlogpb.GrpcLogEntry_LOGGER_SERVER
}
return ret
}
@@ -263,7 +264,7 @@ type ServerMessage struct {
Message interface{}
}
-func (c *ServerMessage) toProto() *pb.GrpcLogEntry {
+func (c *ServerMessage) toProto() *binlogpb.GrpcLogEntry {
var (
data []byte
err error
@@ -278,19 +279,19 @@ func (c *ServerMessage) toProto() *pb.GrpcLogEntry {
} else {
grpclogLogger.Infof("binarylogging: message to log is neither proto.message nor []byte")
}
- ret := &pb.GrpcLogEntry{
- Type: pb.GrpcLogEntry_EVENT_TYPE_SERVER_MESSAGE,
- Payload: &pb.GrpcLogEntry_Message{
- Message: &pb.Message{
+ ret := &binlogpb.GrpcLogEntry{
+ Type: binlogpb.GrpcLogEntry_EVENT_TYPE_SERVER_MESSAGE,
+ Payload: &binlogpb.GrpcLogEntry_Message{
+ Message: &binlogpb.Message{
Length: uint32(len(data)),
Data: data,
},
},
}
if c.OnClientSide {
- ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT
+ ret.Logger = binlogpb.GrpcLogEntry_LOGGER_CLIENT
} else {
- ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER
+ ret.Logger = binlogpb.GrpcLogEntry_LOGGER_SERVER
}
return ret
}
@@ -300,15 +301,15 @@ type ClientHalfClose struct {
OnClientSide bool
}
-func (c *ClientHalfClose) toProto() *pb.GrpcLogEntry {
- ret := &pb.GrpcLogEntry{
- Type: pb.GrpcLogEntry_EVENT_TYPE_CLIENT_HALF_CLOSE,
+func (c *ClientHalfClose) toProto() *binlogpb.GrpcLogEntry {
+ ret := &binlogpb.GrpcLogEntry{
+ Type: binlogpb.GrpcLogEntry_EVENT_TYPE_CLIENT_HALF_CLOSE,
Payload: nil, // No payload here.
}
if c.OnClientSide {
- ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT
+ ret.Logger = binlogpb.GrpcLogEntry_LOGGER_CLIENT
} else {
- ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER
+ ret.Logger = binlogpb.GrpcLogEntry_LOGGER_SERVER
}
return ret
}
@@ -324,7 +325,7 @@ type ServerTrailer struct {
PeerAddr net.Addr
}
-func (c *ServerTrailer) toProto() *pb.GrpcLogEntry {
+func (c *ServerTrailer) toProto() *binlogpb.GrpcLogEntry {
st, ok := status.FromError(c.Err)
if !ok {
grpclogLogger.Info("binarylogging: error in trailer is not a status error")
@@ -340,10 +341,10 @@ func (c *ServerTrailer) toProto() *pb.GrpcLogEntry {
grpclogLogger.Infof("binarylogging: failed to marshal status proto: %v", err)
}
}
- ret := &pb.GrpcLogEntry{
- Type: pb.GrpcLogEntry_EVENT_TYPE_SERVER_TRAILER,
- Payload: &pb.GrpcLogEntry_Trailer{
- Trailer: &pb.Trailer{
+ ret := &binlogpb.GrpcLogEntry{
+ Type: binlogpb.GrpcLogEntry_EVENT_TYPE_SERVER_TRAILER,
+ Payload: &binlogpb.GrpcLogEntry_Trailer{
+ Trailer: &binlogpb.Trailer{
Metadata: mdToMetadataProto(c.Trailer),
StatusCode: uint32(st.Code()),
StatusMessage: st.Message(),
@@ -352,9 +353,9 @@ func (c *ServerTrailer) toProto() *pb.GrpcLogEntry {
},
}
if c.OnClientSide {
- ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT
+ ret.Logger = binlogpb.GrpcLogEntry_LOGGER_CLIENT
} else {
- ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER
+ ret.Logger = binlogpb.GrpcLogEntry_LOGGER_SERVER
}
if c.PeerAddr != nil {
ret.Peer = addrToProto(c.PeerAddr)
@@ -367,15 +368,15 @@ type Cancel struct {
OnClientSide bool
}
-func (c *Cancel) toProto() *pb.GrpcLogEntry {
- ret := &pb.GrpcLogEntry{
- Type: pb.GrpcLogEntry_EVENT_TYPE_CANCEL,
+func (c *Cancel) toProto() *binlogpb.GrpcLogEntry {
+ ret := &binlogpb.GrpcLogEntry{
+ Type: binlogpb.GrpcLogEntry_EVENT_TYPE_CANCEL,
Payload: nil,
}
if c.OnClientSide {
- ret.Logger = pb.GrpcLogEntry_LOGGER_CLIENT
+ ret.Logger = binlogpb.GrpcLogEntry_LOGGER_CLIENT
} else {
- ret.Logger = pb.GrpcLogEntry_LOGGER_SERVER
+ ret.Logger = binlogpb.GrpcLogEntry_LOGGER_SERVER
}
return ret
}
@@ -392,15 +393,15 @@ func metadataKeyOmit(key string) bool {
return strings.HasPrefix(key, "grpc-")
}
-func mdToMetadataProto(md metadata.MD) *pb.Metadata {
- ret := &pb.Metadata{}
+func mdToMetadataProto(md metadata.MD) *binlogpb.Metadata {
+ ret := &binlogpb.Metadata{}
for k, vv := range md {
if metadataKeyOmit(k) {
continue
}
for _, v := range vv {
ret.Entry = append(ret.Entry,
- &pb.MetadataEntry{
+ &binlogpb.MetadataEntry{
Key: k,
Value: []byte(v),
},
@@ -410,26 +411,26 @@ func mdToMetadataProto(md metadata.MD) *pb.Metadata {
return ret
}
-func addrToProto(addr net.Addr) *pb.Address {
- ret := &pb.Address{}
+func addrToProto(addr net.Addr) *binlogpb.Address {
+ ret := &binlogpb.Address{}
switch a := addr.(type) {
case *net.TCPAddr:
if a.IP.To4() != nil {
- ret.Type = pb.Address_TYPE_IPV4
+ ret.Type = binlogpb.Address_TYPE_IPV4
} else if a.IP.To16() != nil {
- ret.Type = pb.Address_TYPE_IPV6
+ ret.Type = binlogpb.Address_TYPE_IPV6
} else {
- ret.Type = pb.Address_TYPE_UNKNOWN
+ ret.Type = binlogpb.Address_TYPE_UNKNOWN
// Do not set address and port fields.
break
}
ret.Address = a.IP.String()
ret.IpPort = uint32(a.Port)
case *net.UnixAddr:
- ret.Type = pb.Address_TYPE_UNIX
+ ret.Type = binlogpb.Address_TYPE_UNIX
ret.Address = a.String()
default:
- ret.Type = pb.Address_TYPE_UNKNOWN
+ ret.Type = binlogpb.Address_TYPE_UNKNOWN
}
return ret
}
diff --git a/sdk/vendor/google.golang.org/grpc/internal/binarylog/sink.go b/sdk/vendor/google.golang.org/grpc/internal/binarylog/sink.go
index c2fdd58b3..264de387c 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/binarylog/sink.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/binarylog/sink.go
@@ -26,7 +26,7 @@ import (
"time"
"github.com/golang/protobuf/proto"
- pb "google.golang.org/grpc/binarylog/grpc_binarylog_v1"
+ binlogpb "google.golang.org/grpc/binarylog/grpc_binarylog_v1"
)
var (
@@ -42,15 +42,15 @@ type Sink interface {
// Write will be called to write the log entry into the sink.
//
// It should be thread-safe so it can be called in parallel.
- Write(*pb.GrpcLogEntry) error
+ Write(*binlogpb.GrpcLogEntry) error
// Close will be called when the Sink is replaced by a new Sink.
Close() error
}
type noopSink struct{}
-func (ns *noopSink) Write(*pb.GrpcLogEntry) error { return nil }
-func (ns *noopSink) Close() error { return nil }
+func (ns *noopSink) Write(*binlogpb.GrpcLogEntry) error { return nil }
+func (ns *noopSink) Close() error { return nil }
// newWriterSink creates a binary log sink with the given writer.
//
@@ -66,7 +66,7 @@ type writerSink struct {
out io.Writer
}
-func (ws *writerSink) Write(e *pb.GrpcLogEntry) error {
+func (ws *writerSink) Write(e *binlogpb.GrpcLogEntry) error {
b, err := proto.Marshal(e)
if err != nil {
grpclogLogger.Errorf("binary logging: failed to marshal proto message: %v", err)
@@ -96,7 +96,7 @@ type bufferedSink struct {
done chan struct{}
}
-func (fs *bufferedSink) Write(e *pb.GrpcLogEntry) error {
+func (fs *bufferedSink) Write(e *binlogpb.GrpcLogEntry) error {
fs.mu.Lock()
defer fs.mu.Unlock()
if !fs.flusherStarted {
diff --git a/sdk/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/sdk/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
index 7edd196bd..5ba9d94d4 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
@@ -21,19 +21,42 @@ package envconfig
import (
"os"
+ "strconv"
"strings"
)
-const (
- prefix = "GRPC_GO_"
- txtErrIgnoreStr = prefix + "IGNORE_TXT_ERRORS"
- advertiseCompressorsStr = prefix + "ADVERTISE_COMPRESSORS"
-)
-
var (
// TXTErrIgnore is set if TXT errors should be ignored ("GRPC_GO_IGNORE_TXT_ERRORS" is not "false").
- TXTErrIgnore = !strings.EqualFold(os.Getenv(txtErrIgnoreStr), "false")
+ TXTErrIgnore = boolFromEnv("GRPC_GO_IGNORE_TXT_ERRORS", true)
// AdvertiseCompressors is set if registered compressor should be advertised
// ("GRPC_GO_ADVERTISE_COMPRESSORS" is not "false").
- AdvertiseCompressors = !strings.EqualFold(os.Getenv(advertiseCompressorsStr), "false")
+ AdvertiseCompressors = boolFromEnv("GRPC_GO_ADVERTISE_COMPRESSORS", true)
+ // RingHashCap indicates the maximum ring size which defaults to 4096
+ // entries but may be overridden by setting the environment variable
+ // "GRPC_RING_HASH_CAP". This does not override the default bounds
+ // checking which NACKs configs specifying ring sizes > 8*1024*1024 (~8M).
+ RingHashCap = uint64FromEnv("GRPC_RING_HASH_CAP", 4096, 1, 8*1024*1024)
)
+
+func boolFromEnv(envVar string, def bool) bool {
+ if def {
+ // The default is true; return true unless the variable is "false".
+ return !strings.EqualFold(os.Getenv(envVar), "false")
+ }
+ // The default is false; return false unless the variable is "true".
+ return strings.EqualFold(os.Getenv(envVar), "true")
+}
+
+func uint64FromEnv(envVar string, def, min, max uint64) uint64 {
+ v, err := strconv.ParseUint(os.Getenv(envVar), 10, 64)
+ if err != nil {
+ return def
+ }
+ if v < min {
+ return min
+ }
+ if v > max {
+ return max
+ }
+ return v
+}
diff --git a/sdk/vendor/google.golang.org/grpc/internal/envconfig/xds.go b/sdk/vendor/google.golang.org/grpc/internal/envconfig/xds.go
index af09711a3..3b17705ba 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/envconfig/xds.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/envconfig/xds.go
@@ -20,7 +20,6 @@ package envconfig
import (
"os"
- "strings"
)
const (
@@ -36,16 +35,6 @@ const (
//
// When both bootstrap FileName and FileContent are set, FileName is used.
XDSBootstrapFileContentEnv = "GRPC_XDS_BOOTSTRAP_CONFIG"
-
- ringHashSupportEnv = "GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH"
- clientSideSecuritySupportEnv = "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT"
- aggregateAndDNSSupportEnv = "GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER"
- rbacSupportEnv = "GRPC_XDS_EXPERIMENTAL_RBAC"
- outlierDetectionSupportEnv = "GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION"
- federationEnv = "GRPC_EXPERIMENTAL_XDS_FEDERATION"
- rlsInXDSEnv = "GRPC_EXPERIMENTAL_XDS_RLS_LB"
-
- c2pResolverTestOnlyTrafficDirectorURIEnv = "GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI"
)
var (
@@ -64,38 +53,40 @@ var (
// XDSRingHash indicates whether ring hash support is enabled, which can be
// disabled by setting the environment variable
// "GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH" to "false".
- XDSRingHash = !strings.EqualFold(os.Getenv(ringHashSupportEnv), "false")
+ XDSRingHash = boolFromEnv("GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH", true)
// XDSClientSideSecurity is used to control processing of security
// configuration on the client-side.
//
// Note that there is no env var protection for the server-side because we
// have a brand new API on the server-side and users explicitly need to use
// the new API to get security integration on the server.
- XDSClientSideSecurity = !strings.EqualFold(os.Getenv(clientSideSecuritySupportEnv), "false")
+ XDSClientSideSecurity = boolFromEnv("GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT", true)
// XDSAggregateAndDNS indicates whether processing of aggregated cluster
// and DNS cluster is enabled, which can be enabled by setting the
// environment variable
// "GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER" to
// "true".
- XDSAggregateAndDNS = !strings.EqualFold(os.Getenv(aggregateAndDNSSupportEnv), "false")
+ XDSAggregateAndDNS = boolFromEnv("GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER", true)
// XDSRBAC indicates whether xDS configured RBAC HTTP Filter is enabled,
// which can be disabled by setting the environment variable
// "GRPC_XDS_EXPERIMENTAL_RBAC" to "false".
- XDSRBAC = !strings.EqualFold(os.Getenv(rbacSupportEnv), "false")
+ XDSRBAC = boolFromEnv("GRPC_XDS_EXPERIMENTAL_RBAC", true)
// XDSOutlierDetection indicates whether outlier detection support is
// enabled, which can be disabled by setting the environment variable
// "GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION" to "false".
- XDSOutlierDetection = !strings.EqualFold(os.Getenv(outlierDetectionSupportEnv), "false")
- // XDSFederation indicates whether federation support is enabled.
- XDSFederation = strings.EqualFold(os.Getenv(federationEnv), "true")
+ XDSOutlierDetection = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION", true)
+ // XDSFederation indicates whether federation support is enabled, which can
+ // be enabled by setting the environment variable
+ // "GRPC_EXPERIMENTAL_XDS_FEDERATION" to "true".
+ XDSFederation = boolFromEnv("GRPC_EXPERIMENTAL_XDS_FEDERATION", true)
// XDSRLS indicates whether processing of Cluster Specifier plugins and
// support for the RLS CLuster Specifier is enabled, which can be enabled by
// setting the environment variable "GRPC_EXPERIMENTAL_XDS_RLS_LB" to
// "true".
- XDSRLS = strings.EqualFold(os.Getenv(rlsInXDSEnv), "true")
+ XDSRLS = boolFromEnv("GRPC_EXPERIMENTAL_XDS_RLS_LB", false)
// C2PResolverTestOnlyTrafficDirectorURI is the TD URI for testing.
- C2PResolverTestOnlyTrafficDirectorURI = os.Getenv(c2pResolverTestOnlyTrafficDirectorURIEnv)
+ C2PResolverTestOnlyTrafficDirectorURI = os.Getenv("GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI")
)
diff --git a/sdk/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go b/sdk/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go
index 82af70e96..02224b42c 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/grpclog/prefixLogger.go
@@ -63,6 +63,9 @@ func (pl *PrefixLogger) Errorf(format string, args ...interface{}) {
// Debugf does info logging at verbose level 2.
func (pl *PrefixLogger) Debugf(format string, args ...interface{}) {
+ // TODO(6044): Refactor interfaces LoggerV2 and DepthLogger, and maybe
+ // rewrite PrefixLogger a little to ensure that we don't use the global
+ // `Logger` here, and instead use the `logger` field.
if !Logger.V(2) {
return
}
@@ -73,6 +76,15 @@ func (pl *PrefixLogger) Debugf(format string, args ...interface{}) {
return
}
InfoDepth(1, fmt.Sprintf(format, args...))
+
+}
+
+// V reports whether verbosity level l is at least the requested verbose level.
+func (pl *PrefixLogger) V(l int) bool {
+ // TODO(6044): Refactor interfaces LoggerV2 and DepthLogger, and maybe
+ // rewrite PrefixLogger a little to ensure that we don't use the global
+ // `Logger` here, and instead use the `logger` field.
+ return Logger.V(l)
}
// NewPrefixLogger creates a prefix logger with the given prefix.
diff --git a/sdk/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go b/sdk/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go
new file mode 100644
index 000000000..79993d343
--- /dev/null
+++ b/sdk/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go
@@ -0,0 +1,65 @@
+/*
+ *
+ * Copyright 2022 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package grpcsync
+
+import (
+ "context"
+
+ "google.golang.org/grpc/internal/buffer"
+)
+
+// CallbackSerializer provides a mechanism to schedule callbacks in a
+// synchronized manner. It provides a FIFO guarantee on the order of execution
+// of scheduled callbacks. New callbacks can be scheduled by invoking the
+// Schedule() method.
+//
+// This type is safe for concurrent access.
+type CallbackSerializer struct {
+ callbacks *buffer.Unbounded
+}
+
+// NewCallbackSerializer returns a new CallbackSerializer instance. The provided
+// context will be passed to the scheduled callbacks. Users should cancel the
+// provided context to shutdown the CallbackSerializer. It is guaranteed that no
+// callbacks will be executed once this context is canceled.
+func NewCallbackSerializer(ctx context.Context) *CallbackSerializer {
+ t := &CallbackSerializer{callbacks: buffer.NewUnbounded()}
+ go t.run(ctx)
+ return t
+}
+
+// Schedule adds a callback to be scheduled after existing callbacks are run.
+//
+// Callbacks are expected to honor the context when performing any blocking
+// operations, and should return early when the context is canceled.
+func (t *CallbackSerializer) Schedule(f func(ctx context.Context)) {
+ t.callbacks.Put(f)
+}
+
+func (t *CallbackSerializer) run(ctx context.Context) {
+ for ctx.Err() == nil {
+ select {
+ case <-ctx.Done():
+ return
+ case callback := <-t.callbacks.Get():
+ t.callbacks.Load()
+ callback.(func(ctx context.Context))(ctx)
+ }
+ }
+}
diff --git a/sdk/vendor/google.golang.org/grpc/internal/internal.go b/sdk/vendor/google.golang.org/grpc/internal/internal.go
index fd0ee3dca..836b6a3b3 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/internal.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/internal.go
@@ -58,6 +58,9 @@ var (
// gRPC server. An xDS-enabled server needs to know what type of credentials
// is configured on the underlying gRPC server. This is set by server.go.
GetServerCredentials interface{} // func (*grpc.Server) credentials.TransportCredentials
+ // CanonicalString returns the canonical string of the code defined here:
+ // https://github.com/grpc/grpc/blob/master/doc/statuscodes.md.
+ CanonicalString interface{} // func (codes.Code) string
// DrainServerTransports initiates a graceful close of existing connections
// on a gRPC server accepted on the provided listener address. An
// xDS-enabled server invokes this method on a grpc.Server when a particular
@@ -74,9 +77,16 @@ var (
// globally for newly created client channels. The priority will be: 1.
// user-provided; 2. this method; 3. default values.
AddGlobalDialOptions interface{} // func(opt ...DialOption)
+ // DisableGlobalDialOptions returns a DialOption that prevents the
+ // ClientConn from applying the global DialOptions (set via
+ // AddGlobalDialOptions).
+ DisableGlobalDialOptions interface{} // func() grpc.DialOption
// ClearGlobalDialOptions clears the array of extra DialOption. This
// method is useful in testing and benchmarking.
ClearGlobalDialOptions func()
+ // JoinDialOptions combines the dial options passed as arguments into a
+ // single dial option.
+ JoinDialOptions interface{} // func(...grpc.DialOption) grpc.DialOption
// JoinServerOptions combines the server options passed as arguments into a
// single server option.
JoinServerOptions interface{} // func(...grpc.ServerOption) grpc.ServerOption
@@ -127,6 +137,9 @@ var (
//
// TODO: Remove this function once the RBAC env var is removed.
UnregisterRBACHTTPFilterForTesting func()
+
+ // ORCAAllowAnyMinReportingInterval is for examples/orca use ONLY.
+ ORCAAllowAnyMinReportingInterval interface{} // func(so *orca.ServiceOptions)
)
// HealthChecker defines the signature of the client-side LB channel health checking function.
diff --git a/sdk/vendor/google.golang.org/grpc/internal/metadata/metadata.go b/sdk/vendor/google.golang.org/grpc/internal/metadata/metadata.go
index b2980f8ac..c82e608e0 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/metadata/metadata.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/metadata/metadata.go
@@ -76,33 +76,11 @@ func Set(addr resolver.Address, md metadata.MD) resolver.Address {
return addr
}
-// Validate returns an error if the input md contains invalid keys or values.
-//
-// If the header is not a pseudo-header, the following items are checked:
-// - header names must contain one or more characters from this set [0-9 a-z _ - .].
-// - if the header-name ends with a "-bin" suffix, no validation of the header value is performed.
-// - otherwise, the header value must contain one or more characters from the set [%x20-%x7E].
+// Validate validates every pair in md with ValidatePair.
func Validate(md metadata.MD) error {
for k, vals := range md {
- // pseudo-header will be ignored
- if k[0] == ':' {
- continue
- }
- // check key, for i that saving a conversion if not using for range
- for i := 0; i < len(k); i++ {
- r := k[i]
- if !(r >= 'a' && r <= 'z') && !(r >= '0' && r <= '9') && r != '.' && r != '-' && r != '_' {
- return fmt.Errorf("header key %q contains illegal characters not in [0-9a-z-_.]", k)
- }
- }
- if strings.HasSuffix(k, "-bin") {
- continue
- }
- // check value
- for _, val := range vals {
- if hasNotPrintable(val) {
- return fmt.Errorf("header key %q contains value with non-printable ASCII characters", k)
- }
+ if err := ValidatePair(k, vals...); err != nil {
+ return err
}
}
return nil
@@ -118,3 +96,37 @@ func hasNotPrintable(msg string) bool {
}
return false
}
+
+// ValidatePair validate a key-value pair with the following rules (the pseudo-header will be skipped) :
+//
+// - key must contain one or more characters.
+// - the characters in the key must be contained in [0-9 a-z _ - .].
+// - if the key ends with a "-bin" suffix, no validation of the corresponding value is performed.
+// - the characters in the every value must be printable (in [%x20-%x7E]).
+func ValidatePair(key string, vals ...string) error {
+ // key should not be empty
+ if key == "" {
+ return fmt.Errorf("there is an empty key in the header")
+ }
+ // pseudo-header will be ignored
+ if key[0] == ':' {
+ return nil
+ }
+ // check key, for i that saving a conversion if not using for range
+ for i := 0; i < len(key); i++ {
+ r := key[i]
+ if !(r >= 'a' && r <= 'z') && !(r >= '0' && r <= '9') && r != '.' && r != '-' && r != '_' {
+ return fmt.Errorf("header key %q contains illegal characters not in [0-9a-z-_.]", key)
+ }
+ }
+ if strings.HasSuffix(key, "-bin") {
+ return nil
+ }
+ // check value
+ for _, val := range vals {
+ if hasNotPrintable(val) {
+ return fmt.Errorf("header key %q contains value with non-printable ASCII characters", key)
+ }
+ }
+ return nil
+}
diff --git a/sdk/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go b/sdk/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go
index d51302e65..09a667f33 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go
@@ -32,7 +32,7 @@ import (
"sync"
"time"
- grpclbstate "google.golang.org/grpc/balancer/grpclb/grpclbstate"
+ grpclbstate "google.golang.org/grpc/balancer/grpclb/state"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/backoff"
"google.golang.org/grpc/internal/envconfig"
@@ -116,7 +116,7 @@ type dnsBuilder struct{}
// Build creates and starts a DNS resolver that watches the name resolution of the target.
func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
- host, port, err := parseTarget(target.Endpoint, defaultPort)
+ host, port, err := parseTarget(target.Endpoint(), defaultPort)
if err != nil {
return nil, err
}
diff --git a/sdk/vendor/google.golang.org/grpc/internal/resolver/passthrough/passthrough.go b/sdk/vendor/google.golang.org/grpc/internal/resolver/passthrough/passthrough.go
index c6e08221f..afac56572 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/resolver/passthrough/passthrough.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/resolver/passthrough/passthrough.go
@@ -31,7 +31,7 @@ const scheme = "passthrough"
type passthroughBuilder struct{}
func (*passthroughBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
- if target.Endpoint == "" && opts.Dialer == nil {
+ if target.Endpoint() == "" && opts.Dialer == nil {
return nil, errors.New("passthrough: received empty target in Build()")
}
r := &passthroughResolver{
@@ -52,7 +52,7 @@ type passthroughResolver struct {
}
func (r *passthroughResolver) start() {
- r.cc.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: r.target.Endpoint}}})
+ r.cc.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: r.target.Endpoint()}}})
}
func (*passthroughResolver) ResolveNow(o resolver.ResolveNowOptions) {}
diff --git a/sdk/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/sdk/vendor/google.golang.org/grpc/internal/transport/controlbuf.go
index aaa9c859a..be5a9c81e 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/transport/controlbuf.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/transport/controlbuf.go
@@ -22,6 +22,7 @@ import (
"bytes"
"errors"
"fmt"
+ "net"
"runtime"
"strconv"
"sync"
@@ -29,6 +30,7 @@ import (
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
+ "google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcutil"
"google.golang.org/grpc/status"
)
@@ -486,12 +488,14 @@ type loopyWriter struct {
hEnc *hpack.Encoder // HPACK encoder.
bdpEst *bdpEstimator
draining bool
+ conn net.Conn
+ logger *grpclog.PrefixLogger
// Side-specific handlers
ssGoAwayHandler func(*goAway) (bool, error)
}
-func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimator) *loopyWriter {
+func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimator, conn net.Conn, logger *grpclog.PrefixLogger) *loopyWriter {
var buf bytes.Buffer
l := &loopyWriter{
side: s,
@@ -504,6 +508,8 @@ func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimato
hBuf: &buf,
hEnc: hpack.NewEncoder(&buf),
bdpEst: bdpEst,
+ conn: conn,
+ logger: logger,
}
return l
}
@@ -521,12 +527,27 @@ const minBatchSize = 1000
// 2. Stream level flow control quota available.
//
// In each iteration of run loop, other than processing the incoming control
-// frame, loopy calls processData, which processes one node from the activeStreams linked-list.
-// This results in writing of HTTP2 frames into an underlying write buffer.
-// When there's no more control frames to read from controlBuf, loopy flushes the write buffer.
-// As an optimization, to increase the batch size for each flush, loopy yields the processor, once
-// if the batch size is too low to give stream goroutines a chance to fill it up.
+// frame, loopy calls processData, which processes one node from the
+// activeStreams linked-list. This results in writing of HTTP2 frames into an
+// underlying write buffer. When there's no more control frames to read from
+// controlBuf, loopy flushes the write buffer. As an optimization, to increase
+// the batch size for each flush, loopy yields the processor, once if the batch
+// size is too low to give stream goroutines a chance to fill it up.
+//
+// Upon exiting, if the error causing the exit is not an I/O error, run()
+// flushes and closes the underlying connection. Otherwise, the connection is
+// left open to allow the I/O error to be encountered by the reader instead.
func (l *loopyWriter) run() (err error) {
+ defer func() {
+ if l.logger.V(logLevel) {
+ l.logger.Infof("loopyWriter exiting with error: %v", err)
+ }
+ if !isIOError(err) {
+ l.framer.writer.Flush()
+ l.conn.Close()
+ }
+ l.cbuf.finish()
+ }()
for {
it, err := l.cbuf.get(true)
if err != nil {
@@ -578,11 +599,11 @@ func (l *loopyWriter) outgoingWindowUpdateHandler(w *outgoingWindowUpdate) error
return l.framer.fr.WriteWindowUpdate(w.streamID, w.increment)
}
-func (l *loopyWriter) incomingWindowUpdateHandler(w *incomingWindowUpdate) error {
+func (l *loopyWriter) incomingWindowUpdateHandler(w *incomingWindowUpdate) {
// Otherwise update the quota.
if w.streamID == 0 {
l.sendQuota += w.increment
- return nil
+ return
}
// Find the stream and update it.
if str, ok := l.estdStreams[w.streamID]; ok {
@@ -590,10 +611,9 @@ func (l *loopyWriter) incomingWindowUpdateHandler(w *incomingWindowUpdate) error
if strQuota := int(l.oiws) - str.bytesOutStanding; strQuota > 0 && str.state == waitingOnStreamQuota {
str.state = active
l.activeStreams.enqueue(str)
- return nil
+ return
}
}
- return nil
}
func (l *loopyWriter) outgoingSettingsHandler(s *outgoingSettings) error {
@@ -601,13 +621,11 @@ func (l *loopyWriter) outgoingSettingsHandler(s *outgoingSettings) error {
}
func (l *loopyWriter) incomingSettingsHandler(s *incomingSettings) error {
- if err := l.applySettings(s.ss); err != nil {
- return err
- }
+ l.applySettings(s.ss)
return l.framer.fr.WriteSettingsAck()
}
-func (l *loopyWriter) registerStreamHandler(h *registerStream) error {
+func (l *loopyWriter) registerStreamHandler(h *registerStream) {
str := &outStream{
id: h.streamID,
state: empty,
@@ -615,15 +633,14 @@ func (l *loopyWriter) registerStreamHandler(h *registerStream) error {
wq: h.wq,
}
l.estdStreams[h.streamID] = str
- return nil
}
func (l *loopyWriter) headerHandler(h *headerFrame) error {
if l.side == serverSide {
str, ok := l.estdStreams[h.streamID]
if !ok {
- if logger.V(logLevel) {
- logger.Warningf("transport: loopy doesn't recognize the stream: %d", h.streamID)
+ if l.logger.V(logLevel) {
+ l.logger.Infof("Unrecognized streamID %d in loopyWriter", h.streamID)
}
return nil
}
@@ -650,16 +667,18 @@ func (l *loopyWriter) headerHandler(h *headerFrame) error {
itl: &itemList{},
wq: h.wq,
}
- str.itl.enqueue(h)
- return l.originateStream(str)
+ return l.originateStream(str, h)
}
-func (l *loopyWriter) originateStream(str *outStream) error {
- hdr := str.itl.dequeue().(*headerFrame)
+func (l *loopyWriter) originateStream(str *outStream, hdr *headerFrame) error {
+ // l.draining is set when handling GoAway. In which case, we want to avoid
+ // creating new streams.
+ if l.draining {
+ // TODO: provide a better error with the reason we are in draining.
+ hdr.onOrphaned(errStreamDrain)
+ return nil
+ }
if err := hdr.initStream(str.id); err != nil {
- if err == errStreamDrain { // errStreamDrain need not close transport
- return nil
- }
return err
}
if err := l.writeHeader(str.id, hdr.endStream, hdr.hf, hdr.onWrite); err != nil {
@@ -676,8 +695,8 @@ func (l *loopyWriter) writeHeader(streamID uint32, endStream bool, hf []hpack.He
l.hBuf.Reset()
for _, f := range hf {
if err := l.hEnc.WriteField(f); err != nil {
- if logger.V(logLevel) {
- logger.Warningf("transport: loopyWriter.writeHeader encountered error while encoding headers: %v", err)
+ if l.logger.V(logLevel) {
+ l.logger.Warningf("Encountered error while encoding headers: %v", err)
}
}
}
@@ -715,10 +734,10 @@ func (l *loopyWriter) writeHeader(streamID uint32, endStream bool, hf []hpack.He
return nil
}
-func (l *loopyWriter) preprocessData(df *dataFrame) error {
+func (l *loopyWriter) preprocessData(df *dataFrame) {
str, ok := l.estdStreams[df.streamID]
if !ok {
- return nil
+ return
}
// If we got data for a stream it means that
// stream was originated and the headers were sent out.
@@ -727,7 +746,6 @@ func (l *loopyWriter) preprocessData(df *dataFrame) error {
str.state = active
l.activeStreams.enqueue(str)
}
- return nil
}
func (l *loopyWriter) pingHandler(p *ping) error {
@@ -738,9 +756,8 @@ func (l *loopyWriter) pingHandler(p *ping) error {
}
-func (l *loopyWriter) outFlowControlSizeRequestHandler(o *outFlowControlSizeRequest) error {
+func (l *loopyWriter) outFlowControlSizeRequestHandler(o *outFlowControlSizeRequest) {
o.resp <- l.sendQuota
- return nil
}
func (l *loopyWriter) cleanupStreamHandler(c *cleanupStream) error {
@@ -757,7 +774,8 @@ func (l *loopyWriter) cleanupStreamHandler(c *cleanupStream) error {
return err
}
}
- if l.side == clientSide && l.draining && len(l.estdStreams) == 0 {
+ if l.draining && len(l.estdStreams) == 0 {
+ // Flush and close the connection; we are done with it.
return errors.New("finished processing active streams while in draining mode")
}
return nil
@@ -793,6 +811,7 @@ func (l *loopyWriter) incomingGoAwayHandler(*incomingGoAway) error {
if l.side == clientSide {
l.draining = true
if len(l.estdStreams) == 0 {
+ // Flush and close the connection; we are done with it.
return errors.New("received GOAWAY with no active streams")
}
}
@@ -811,18 +830,10 @@ func (l *loopyWriter) goAwayHandler(g *goAway) error {
return nil
}
-func (l *loopyWriter) closeConnectionHandler() error {
- l.framer.writer.Flush()
- // Exit loopyWriter entirely by returning an error here. This will lead to
- // the transport closing the connection, and, ultimately, transport
- // closure.
- return ErrConnClosing
-}
-
func (l *loopyWriter) handle(i interface{}) error {
switch i := i.(type) {
case *incomingWindowUpdate:
- return l.incomingWindowUpdateHandler(i)
+ l.incomingWindowUpdateHandler(i)
case *outgoingWindowUpdate:
return l.outgoingWindowUpdateHandler(i)
case *incomingSettings:
@@ -832,7 +843,7 @@ func (l *loopyWriter) handle(i interface{}) error {
case *headerFrame:
return l.headerHandler(i)
case *registerStream:
- return l.registerStreamHandler(i)
+ l.registerStreamHandler(i)
case *cleanupStream:
return l.cleanupStreamHandler(i)
case *earlyAbortStream:
@@ -840,21 +851,24 @@ func (l *loopyWriter) handle(i interface{}) error {
case *incomingGoAway:
return l.incomingGoAwayHandler(i)
case *dataFrame:
- return l.preprocessData(i)
+ l.preprocessData(i)
case *ping:
return l.pingHandler(i)
case *goAway:
return l.goAwayHandler(i)
case *outFlowControlSizeRequest:
- return l.outFlowControlSizeRequestHandler(i)
+ l.outFlowControlSizeRequestHandler(i)
case closeConnection:
- return l.closeConnectionHandler()
+ // Just return a non-I/O error and run() will flush and close the
+ // connection.
+ return ErrConnClosing
default:
return fmt.Errorf("transport: unknown control message type %T", i)
}
+ return nil
}
-func (l *loopyWriter) applySettings(ss []http2.Setting) error {
+func (l *loopyWriter) applySettings(ss []http2.Setting) {
for _, s := range ss {
switch s.ID {
case http2.SettingInitialWindowSize:
@@ -873,7 +887,6 @@ func (l *loopyWriter) applySettings(ss []http2.Setting) error {
updateHeaderTblSize(l.hEnc, s.Val)
}
}
- return nil
}
// processData removes the first stream from active streams, writes out at most 16KB
@@ -907,7 +920,7 @@ func (l *loopyWriter) processData() (bool, error) {
return false, err
}
if err := l.cleanupStreamHandler(trailer.cleanup); err != nil {
- return false, nil
+ return false, err
}
} else {
l.activeStreams.enqueue(str)
diff --git a/sdk/vendor/google.golang.org/grpc/internal/transport/defaults.go b/sdk/vendor/google.golang.org/grpc/internal/transport/defaults.go
index 9fa306b2e..bc8ee0747 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/transport/defaults.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/transport/defaults.go
@@ -47,3 +47,9 @@ const (
defaultClientMaxHeaderListSize = uint32(16 << 20)
defaultServerMaxHeaderListSize = uint32(16 << 20)
)
+
+// MaxStreamID is the upper bound for the stream ID before the current
+// transport gracefully closes and new transport is created for subsequent RPCs.
+// This is set to 75% of 2^31-1. Streams are identified with an unsigned 31-bit
+// integer. It's exported so that tests can override it.
+var MaxStreamID = uint32(math.MaxInt32 * 3 / 4)
diff --git a/sdk/vendor/google.golang.org/grpc/internal/transport/handler_server.go b/sdk/vendor/google.golang.org/grpc/internal/transport/handler_server.go
index ebe8bfe33..fbee581b8 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/transport/handler_server.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/transport/handler_server.go
@@ -39,6 +39,7 @@ import (
"golang.org/x/net/http2"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
+ "google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcutil"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/peer"
@@ -65,7 +66,7 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []s
contentSubtype, validContentType := grpcutil.ContentSubtype(contentType)
if !validContentType {
msg := fmt.Sprintf("invalid gRPC request content-type %q", contentType)
- http.Error(w, msg, http.StatusBadRequest)
+ http.Error(w, msg, http.StatusUnsupportedMediaType)
return nil, errors.New(msg)
}
if _, ok := w.(http.Flusher); !ok {
@@ -83,11 +84,12 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []s
contentSubtype: contentSubtype,
stats: stats,
}
+ st.logger = prefixLoggerForServerHandlerTransport(st)
if v := r.Header.Get("grpc-timeout"); v != "" {
to, err := decodeTimeout(v)
if err != nil {
- msg := fmt.Sprintf("malformed time-out: %v", err)
+ msg := fmt.Sprintf("malformed grpc-timeout: %v", err)
http.Error(w, msg, http.StatusBadRequest)
return nil, status.Error(codes.Internal, msg)
}
@@ -150,13 +152,14 @@ type serverHandlerTransport struct {
// TODO make sure this is consistent across handler_server and http2_server
contentSubtype string
- stats []stats.Handler
+ stats []stats.Handler
+ logger *grpclog.PrefixLogger
}
func (ht *serverHandlerTransport) Close(err error) {
ht.closeOnce.Do(func() {
- if logger.V(logLevel) {
- logger.Infof("Closing serverHandlerTransport: %v", err)
+ if ht.logger.V(logLevel) {
+ ht.logger.Infof("Closing: %v", err)
}
close(ht.closedCh)
})
diff --git a/sdk/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/sdk/vendor/google.golang.org/grpc/internal/transport/http2_client.go
index 3e582a285..5216998a8 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/transport/http2_client.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/transport/http2_client.go
@@ -38,6 +38,7 @@ import (
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/internal/channelz"
icredentials "google.golang.org/grpc/internal/credentials"
+ "google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/internal/grpcutil"
imetadata "google.golang.org/grpc/internal/metadata"
@@ -140,12 +141,12 @@ type http2Client struct {
channelzID *channelz.Identifier
czData *channelzData
- onGoAway func(GoAwayReason)
- onClose func()
+ onClose func(GoAwayReason)
bufferPool *bufferPool
connectionID uint64
+ logger *grpclog.PrefixLogger
}
func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error), addr resolver.Address, useProxy bool, grpcUA string) (net.Conn, error) {
@@ -197,7 +198,7 @@ func isTemporary(err error) bool {
// newHTTP2Client constructs a connected ClientTransport to addr based on HTTP2
// and starts to receive messages on it. Non-nil error returns if construction
// fails.
-func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onGoAway func(GoAwayReason), onClose func()) (_ *http2Client, err error) {
+func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onClose func(GoAwayReason)) (_ *http2Client, err error) {
scheme := "http"
ctx, cancel := context.WithCancel(ctx)
defer func() {
@@ -217,7 +218,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
if opts.FailOnNonTempDialError {
return nil, connectionErrorf(isTemporary(err), err, "transport: error while dialing: %v", err)
}
- return nil, connectionErrorf(true, err, "transport: Error while dialing %v", err)
+ return nil, connectionErrorf(true, err, "transport: Error while dialing: %v", err)
}
// Any further errors will close the underlying connection
@@ -245,7 +246,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
if err := connectCtx.Err(); err != nil {
// connectCtx expired before exiting the function. Hard close the connection.
if logger.V(logLevel) {
- logger.Infof("newClientTransport: aborting due to connectCtx: %v", err)
+ logger.Infof("Aborting due to connect deadline expiring: %v", err)
}
conn.Close()
}
@@ -343,11 +344,11 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
streamQuota: defaultMaxStreamsClient,
streamsQuotaAvailable: make(chan struct{}, 1),
czData: new(channelzData),
- onGoAway: onGoAway,
keepaliveEnabled: keepaliveEnabled,
bufferPool: newBufferPool(),
onClose: onClose,
}
+ t.logger = prefixLoggerForClientTransport(t)
// Add peer information to the http2client context.
t.ctx = peer.NewContext(t.ctx, t.getPeer())
@@ -446,15 +447,8 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
return nil, err
}
go func() {
- t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst)
- err := t.loopy.run()
- if logger.V(logLevel) {
- logger.Infof("transport: loopyWriter exited. Closing connection. Err: %v", err)
- }
- // Do not close the transport. Let reader goroutine handle it since
- // there might be data in the buffers.
- t.conn.Close()
- t.controlBuf.finish()
+ t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger)
+ t.loopy.run()
close(t.writerDone)
}()
return t, nil
@@ -744,15 +738,12 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream,
endStream: false,
initStream: func(id uint32) error {
t.mu.Lock()
- if state := t.state; state != reachable {
+ // TODO: handle transport closure in loopy instead and remove this
+ // initStream is never called when transport is draining.
+ if t.state == closing {
t.mu.Unlock()
- // Do a quick cleanup.
- err := error(errStreamDrain)
- if state == closing {
- err = ErrConnClosing
- }
- cleanup(err)
- return err
+ cleanup(ErrConnClosing)
+ return ErrConnClosing
}
if channelz.IsOn() {
atomic.AddInt64(&t.czData.streamsStarted, 1)
@@ -770,6 +761,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream,
}
firstTry := true
var ch chan struct{}
+ transportDrainRequired := false
checkForStreamQuota := func(it interface{}) bool {
if t.streamQuota <= 0 { // Can go negative if server decreases it.
if firstTry {
@@ -785,10 +777,15 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream,
h := it.(*headerFrame)
h.streamID = t.nextID
t.nextID += 2
+
+ // Drain client transport if nextID > MaxStreamID which signals gRPC that
+ // the connection is closed and a new one must be created for subsequent RPCs.
+ transportDrainRequired = t.nextID > MaxStreamID
+
s.id = h.streamID
s.fc = &inFlow{limit: uint32(t.initialWindowSize)}
t.mu.Lock()
- if t.activeStreams == nil { // Can be niled from Close().
+ if t.state == draining || t.activeStreams == nil { // Can be niled from Close().
t.mu.Unlock()
return false // Don't create a stream if the transport is already closed.
}
@@ -864,6 +861,12 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream,
sh.HandleRPC(s.ctx, outHeader)
}
}
+ if transportDrainRequired {
+ if t.logger.V(logLevel) {
+ t.logger.Infof("Draining transport: t.nextID > MaxStreamID")
+ }
+ t.GracefulClose()
+ }
return s, nil
}
@@ -952,12 +955,14 @@ func (t *http2Client) Close(err error) {
t.mu.Unlock()
return
}
- if logger.V(logLevel) {
- logger.Infof("transport: closing: %v", err)
+ if t.logger.V(logLevel) {
+ t.logger.Infof("Closing: %v", err)
}
// Call t.onClose ASAP to prevent the client from attempting to create new
// streams.
- t.onClose()
+ if t.state != draining {
+ t.onClose(GoAwayInvalid)
+ }
t.state = closing
streams := t.activeStreams
t.activeStreams = nil
@@ -1007,9 +1012,10 @@ func (t *http2Client) GracefulClose() {
t.mu.Unlock()
return
}
- if logger.V(logLevel) {
- logger.Infof("transport: GracefulClose called")
+ if t.logger.V(logLevel) {
+ t.logger.Infof("GracefulClose called")
}
+ t.onClose(GoAwayInvalid)
t.state = draining
active := len(t.activeStreams)
t.mu.Unlock()
@@ -1171,8 +1177,8 @@ func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) {
}
statusCode, ok := http2ErrConvTab[f.ErrCode]
if !ok {
- if logger.V(logLevel) {
- logger.Warningf("transport: http2Client.handleRSTStream found no mapped gRPC status for the received http2 error %v", f.ErrCode)
+ if t.logger.V(logLevel) {
+ t.logger.Infof("Received a RST_STREAM frame with code %q, but found no mapped gRPC status", f.ErrCode)
}
statusCode = codes.Unknown
}
@@ -1254,10 +1260,12 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
t.mu.Unlock()
return
}
- if f.ErrCode == http2.ErrCodeEnhanceYourCalm {
- if logger.V(logLevel) {
- logger.Infof("Client received GoAway with http2.ErrCodeEnhanceYourCalm.")
- }
+ if f.ErrCode == http2.ErrCodeEnhanceYourCalm && string(f.DebugData()) == "too_many_pings" {
+ // When a client receives a GOAWAY with error code ENHANCE_YOUR_CALM and debug
+ // data equal to ASCII "too_many_pings", it should log the occurrence at a log level that is
+ // enabled by default and double the configure KEEPALIVE_TIME used for new connections
+ // on that channel.
+ logger.Errorf("Client received GoAway with error code ENHANCE_YOUR_CALM and debug data equal to ASCII \"too_many_pings\".")
}
id := f.LastStreamID
if id > 0 && id%2 == 0 {
@@ -1290,8 +1298,10 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
// Notify the clientconn about the GOAWAY before we set the state to
// draining, to allow the client to stop attempting to create streams
// before disallowing new streams on this connection.
- t.onGoAway(t.goAwayReason)
- t.state = draining
+ if t.state != draining {
+ t.onClose(t.goAwayReason)
+ t.state = draining
+ }
}
// All streams with IDs greater than the GoAwayId
// and smaller than the previous GoAway ID should be killed.
@@ -1780,3 +1790,9 @@ func (t *http2Client) getOutFlowWindow() int64 {
return -2
}
}
+
+func (t *http2Client) stateForTesting() transportState {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ return t.state
+}
diff --git a/sdk/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/sdk/vendor/google.golang.org/grpc/internal/transport/http2_server.go
index 37e089bc8..4b406b8cb 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/transport/http2_server.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/transport/http2_server.go
@@ -35,7 +35,9 @@ import (
"github.com/golang/protobuf/proto"
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
+ "google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcutil"
+ "google.golang.org/grpc/internal/pretty"
"google.golang.org/grpc/internal/syscall"
"google.golang.org/grpc/codes"
@@ -129,6 +131,8 @@ type http2Server struct {
// This lock may not be taken if mu is already held.
maxStreamMu sync.Mutex
maxStreamID uint32 // max stream ID ever seen
+
+ logger *grpclog.PrefixLogger
}
// NewServerTransport creates a http2 transport with conn and configuration
@@ -267,6 +271,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
czData: new(channelzData),
bufferPool: newBufferPool(),
}
+ t.logger = prefixLoggerForServerTransport(t)
// Add peer information to the http2server context.
t.ctx = peer.NewContext(t.ctx, t.getPeer())
@@ -331,14 +336,9 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
t.handleSettings(sf)
go func() {
- t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst)
+ t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger)
t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler
- err := t.loopy.run()
- if logger.V(logLevel) {
- logger.Infof("transport: loopyWriter exited. Closing connection. Err: %v", err)
- }
- t.conn.Close()
- t.controlBuf.finish()
+ t.loopy.run()
close(t.writerDone)
}()
go t.keepalive()
@@ -380,13 +380,14 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
fc: &inFlow{limit: uint32(t.initialWindowSize)},
}
var (
- // If a gRPC Response-Headers has already been received, then it means
- // that the peer is speaking gRPC and we are in gRPC mode.
- isGRPC = false
- mdata = make(map[string][]string)
- httpMethod string
- // headerError is set if an error is encountered while parsing the headers
- headerError bool
+ // if false, content-type was missing or invalid
+ isGRPC = false
+ contentType = ""
+ mdata = make(metadata.MD, len(frame.Fields))
+ httpMethod string
+ // these are set if an error is encountered while parsing the headers
+ protocolError bool
+ headerError *status.Status
timeoutSet bool
timeout time.Duration
@@ -397,11 +398,23 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
case "content-type":
contentSubtype, validContentType := grpcutil.ContentSubtype(hf.Value)
if !validContentType {
+ contentType = hf.Value
break
}
mdata[hf.Name] = append(mdata[hf.Name], hf.Value)
s.contentSubtype = contentSubtype
isGRPC = true
+
+ case "grpc-accept-encoding":
+ mdata[hf.Name] = append(mdata[hf.Name], hf.Value)
+ if hf.Value == "" {
+ continue
+ }
+ compressors := hf.Value
+ if s.clientAdvertisedCompressors != "" {
+ compressors = s.clientAdvertisedCompressors + "," + compressors
+ }
+ s.clientAdvertisedCompressors = compressors
case "grpc-encoding":
s.recvCompress = hf.Value
case ":method":
@@ -412,23 +425,23 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
timeoutSet = true
var err error
if timeout, err = decodeTimeout(hf.Value); err != nil {
- headerError = true
+ headerError = status.Newf(codes.Internal, "malformed grpc-timeout: %v", err)
}
// "Transports must consider requests containing the Connection header
// as malformed." - A41
case "connection":
- if logger.V(logLevel) {
- logger.Errorf("transport: http2Server.operateHeaders parsed a :connection header which makes a request malformed as per the HTTP/2 spec")
+ if t.logger.V(logLevel) {
+ t.logger.Infof("Received a HEADERS frame with a :connection header which makes the request malformed, as per the HTTP/2 spec")
}
- headerError = true
+ protocolError = true
default:
if isReservedHeader(hf.Name) && !isWhitelistedHeader(hf.Name) {
break
}
v, err := decodeMetadataHeader(hf.Name, hf.Value)
if err != nil {
- headerError = true
- logger.Warningf("Failed to decode metadata header (%q, %q): %v", hf.Name, hf.Value, err)
+ headerError = status.Newf(codes.Internal, "malformed binary metadata %q in header %q: %v", hf.Value, hf.Name, err)
+ t.logger.Warningf("Failed to decode metadata header (%q, %q): %v", hf.Name, hf.Value, err)
break
}
mdata[hf.Name] = append(mdata[hf.Name], v)
@@ -442,11 +455,11 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
// error, this takes precedence over a client not speaking gRPC.
if len(mdata[":authority"]) > 1 || len(mdata["host"]) > 1 {
errMsg := fmt.Sprintf("num values of :authority: %v, num values of host: %v, both must only have 1 value as per HTTP/2 spec", len(mdata[":authority"]), len(mdata["host"]))
- if logger.V(logLevel) {
- logger.Errorf("transport: %v", errMsg)
+ if t.logger.V(logLevel) {
+ t.logger.Infof("Aborting the stream early: %v", errMsg)
}
t.controlBuf.put(&earlyAbortStream{
- httpStatus: 400,
+ httpStatus: http.StatusBadRequest,
streamID: streamID,
contentSubtype: s.contentSubtype,
status: status.New(codes.Internal, errMsg),
@@ -455,7 +468,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
return nil
}
- if !isGRPC || headerError {
+ if protocolError {
t.controlBuf.put(&cleanupStream{
streamID: streamID,
rst: true,
@@ -464,6 +477,26 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
})
return nil
}
+ if !isGRPC {
+ t.controlBuf.put(&earlyAbortStream{
+ httpStatus: http.StatusUnsupportedMediaType,
+ streamID: streamID,
+ contentSubtype: s.contentSubtype,
+ status: status.Newf(codes.InvalidArgument, "invalid gRPC request content-type %q", contentType),
+ rst: !frame.StreamEnded(),
+ })
+ return nil
+ }
+ if headerError != nil {
+ t.controlBuf.put(&earlyAbortStream{
+ httpStatus: http.StatusBadRequest,
+ streamID: streamID,
+ contentSubtype: s.contentSubtype,
+ status: headerError,
+ rst: !frame.StreamEnded(),
+ })
+ return nil
+ }
// "If :authority is missing, Host must be renamed to :authority." - A41
if len(mdata[":authority"]) == 0 {
@@ -517,9 +550,9 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
}
if httpMethod != http.MethodPost {
t.mu.Unlock()
- errMsg := fmt.Sprintf("http2Server.operateHeaders parsed a :method field: %v which should be POST", httpMethod)
- if logger.V(logLevel) {
- logger.Infof("transport: %v", errMsg)
+ errMsg := fmt.Sprintf("Received a HEADERS frame with :method %q which should be POST", httpMethod)
+ if t.logger.V(logLevel) {
+ t.logger.Infof("Aborting the stream early: %v", errMsg)
}
t.controlBuf.put(&earlyAbortStream{
httpStatus: 405,
@@ -535,8 +568,8 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
var err error
if s.ctx, err = t.inTapHandle(s.ctx, &tap.Info{FullMethodName: s.method}); err != nil {
t.mu.Unlock()
- if logger.V(logLevel) {
- logger.Infof("transport: http2Server.operateHeaders got an error from InTapHandle: %v", err)
+ if t.logger.V(logLevel) {
+ t.logger.Infof("Aborting the stream early due to InTapHandle failure: %v", err)
}
stat, ok := status.FromError(err)
if !ok {
@@ -573,7 +606,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
LocalAddr: t.localAddr,
Compression: s.recvCompress,
WireLength: int(frame.Header().Length),
- Header: metadata.MD(mdata).Copy(),
+ Header: mdata.Copy(),
}
sh.HandleRPC(s.ctx, inHeader)
}
@@ -610,8 +643,8 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.
atomic.StoreInt64(&t.lastRead, time.Now().UnixNano())
if err != nil {
if se, ok := err.(http2.StreamError); ok {
- if logger.V(logLevel) {
- logger.Warningf("transport: http2Server.HandleStreams encountered http2.StreamError: %v", se)
+ if t.logger.V(logLevel) {
+ t.logger.Warningf("Encountered http2.StreamError: %v", se)
}
t.mu.Lock()
s := t.activeStreams[se.StreamID]
@@ -654,8 +687,8 @@ func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.
case *http2.GoAwayFrame:
// TODO: Handle GoAway from the client appropriately.
default:
- if logger.V(logLevel) {
- logger.Errorf("transport: http2Server.HandleStreams found unhandled frame type %v.", frame)
+ if t.logger.V(logLevel) {
+ t.logger.Infof("Received unsupported frame type %T", frame)
}
}
}
@@ -914,8 +947,8 @@ func (t *http2Server) checkForHeaderListSize(it interface{}) bool {
var sz int64
for _, f := range hdrFrame.hf {
if sz += int64(f.Size()); sz > int64(*t.maxSendHeaderListSize) {
- if logger.V(logLevel) {
- logger.Errorf("header list size to send violates the maximum size (%d bytes) set by client", *t.maxSendHeaderListSize)
+ if t.logger.V(logLevel) {
+ t.logger.Infof("Header list size to send violates the maximum size (%d bytes) set by client", *t.maxSendHeaderListSize)
}
return false
}
@@ -1028,7 +1061,7 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error {
stBytes, err := proto.Marshal(p)
if err != nil {
// TODO: return error instead, when callers are able to handle it.
- logger.Errorf("transport: failed to marshal rpc status: %v, error: %v", p, err)
+ t.logger.Errorf("Failed to marshal rpc status: %s, error: %v", pretty.ToJSON(p), err)
} else {
headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-status-details-bin", Value: encodeBinHeader(stBytes)})
}
@@ -1143,8 +1176,8 @@ func (t *http2Server) keepalive() {
select {
case <-ageTimer.C:
// Close the connection after grace period.
- if logger.V(logLevel) {
- logger.Infof("transport: closing server transport due to maximum connection age.")
+ if t.logger.V(logLevel) {
+ t.logger.Infof("Closing server transport due to maximum connection age")
}
t.controlBuf.put(closeConnection{})
case <-t.done:
@@ -1195,8 +1228,8 @@ func (t *http2Server) Close(err error) {
t.mu.Unlock()
return
}
- if logger.V(logLevel) {
- logger.Infof("transport: closing: %v", err)
+ if t.logger.V(logLevel) {
+ t.logger.Infof("Closing: %v", err)
}
t.state = closing
streams := t.activeStreams
@@ -1204,8 +1237,8 @@ func (t *http2Server) Close(err error) {
t.mu.Unlock()
t.controlBuf.finish()
close(t.done)
- if err := t.conn.Close(); err != nil && logger.V(logLevel) {
- logger.Infof("transport: error closing conn during Close: %v", err)
+ if err := t.conn.Close(); err != nil && t.logger.V(logLevel) {
+ t.logger.Infof("Error closing underlying net.Conn during Close: %v", err)
}
channelz.RemoveEntry(t.channelzID)
// Cancel all active streams.
@@ -1322,9 +1355,6 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) {
return false, err
}
if retErr != nil {
- // Abruptly close the connection following the GoAway (via
- // loopywriter). But flush out what's inside the buffer first.
- t.framer.writer.Flush()
return false, retErr
}
return true, nil
diff --git a/sdk/vendor/google.golang.org/grpc/internal/transport/http_util.go b/sdk/vendor/google.golang.org/grpc/internal/transport/http_util.go
index 2c601a864..19cbb18f5 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/transport/http_util.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/transport/http_util.go
@@ -21,6 +21,7 @@ package transport
import (
"bufio"
"encoding/base64"
+ "errors"
"fmt"
"io"
"math"
@@ -37,7 +38,6 @@ import (
"golang.org/x/net/http2/hpack"
spb "google.golang.org/genproto/googleapis/rpc/status"
"google.golang.org/grpc/codes"
- "google.golang.org/grpc/grpclog"
"google.golang.org/grpc/status"
)
@@ -85,7 +85,6 @@ var (
// 504 Gateway timeout - UNAVAILABLE.
http.StatusGatewayTimeout: codes.Unavailable,
}
- logger = grpclog.Component("transport")
)
// isReservedHeader checks whether hdr belongs to HTTP2 headers
@@ -330,7 +329,8 @@ func (w *bufWriter) Write(b []byte) (n int, err error) {
return 0, w.err
}
if w.batchSize == 0 { // Buffer has been disabled.
- return w.conn.Write(b)
+ n, err = w.conn.Write(b)
+ return n, toIOError(err)
}
for len(b) > 0 {
nn := copy(w.buf[w.offset:], b)
@@ -352,10 +352,30 @@ func (w *bufWriter) Flush() error {
return nil
}
_, w.err = w.conn.Write(w.buf[:w.offset])
+ w.err = toIOError(w.err)
w.offset = 0
return w.err
}
+type ioError struct {
+ error
+}
+
+func (i ioError) Unwrap() error {
+ return i.error
+}
+
+func isIOError(err error) bool {
+ return errors.As(err, &ioError{})
+}
+
+func toIOError(err error) error {
+ if err == nil {
+ return nil
+ }
+ return ioError{error: err}
+}
+
type framer struct {
writer *bufWriter
fr *http2.Framer
diff --git a/sdk/vendor/google.golang.org/grpc/internal/transport/logging.go b/sdk/vendor/google.golang.org/grpc/internal/transport/logging.go
new file mode 100644
index 000000000..42ed2b07a
--- /dev/null
+++ b/sdk/vendor/google.golang.org/grpc/internal/transport/logging.go
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright 2023 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package transport
+
+import (
+ "fmt"
+
+ "google.golang.org/grpc/grpclog"
+ internalgrpclog "google.golang.org/grpc/internal/grpclog"
+)
+
+var logger = grpclog.Component("transport")
+
+func prefixLoggerForServerTransport(p *http2Server) *internalgrpclog.PrefixLogger {
+ return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[server-transport %p] ", p))
+}
+
+func prefixLoggerForServerHandlerTransport(p *serverHandlerTransport) *internalgrpclog.PrefixLogger {
+ return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[server-handler-transport %p] ", p))
+}
+
+func prefixLoggerForClientTransport(p *http2Client) *internalgrpclog.PrefixLogger {
+ return internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf("[client-transport %p] ", p))
+}
diff --git a/sdk/vendor/google.golang.org/grpc/internal/transport/transport.go b/sdk/vendor/google.golang.org/grpc/internal/transport/transport.go
index 6cff20c8e..1b7d7fabc 100644
--- a/sdk/vendor/google.golang.org/grpc/internal/transport/transport.go
+++ b/sdk/vendor/google.golang.org/grpc/internal/transport/transport.go
@@ -257,6 +257,9 @@ type Stream struct {
fc *inFlow
wq *writeQuota
+ // Holds compressor names passed in grpc-accept-encoding metadata from the
+ // client. This is empty for the client side stream.
+ clientAdvertisedCompressors string
// Callback to state application's intentions to read data. This
// is used to adjust flow control, if needed.
requestRead func(int)
@@ -345,8 +348,24 @@ func (s *Stream) RecvCompress() string {
}
// SetSendCompress sets the compression algorithm to the stream.
-func (s *Stream) SetSendCompress(str string) {
- s.sendCompress = str
+func (s *Stream) SetSendCompress(name string) error {
+ if s.isHeaderSent() || s.getState() == streamDone {
+ return errors.New("transport: set send compressor called after headers sent or stream done")
+ }
+
+ s.sendCompress = name
+ return nil
+}
+
+// SendCompress returns the send compressor name.
+func (s *Stream) SendCompress() string {
+ return s.sendCompress
+}
+
+// ClientAdvertisedCompressors returns the compressor names advertised by the
+// client via grpc-accept-encoding header.
+func (s *Stream) ClientAdvertisedCompressors() string {
+ return s.clientAdvertisedCompressors
}
// Done returns a channel which is closed when it receives the final status
@@ -583,8 +602,8 @@ type ConnectOptions struct {
// NewClientTransport establishes the transport with the required ConnectOptions
// and returns it to the caller.
-func NewClientTransport(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onGoAway func(GoAwayReason), onClose func()) (ClientTransport, error) {
- return newHTTP2Client(connectCtx, ctx, addr, opts, onGoAway, onClose)
+func NewClientTransport(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onClose func(GoAwayReason)) (ClientTransport, error) {
+ return newHTTP2Client(connectCtx, ctx, addr, opts, onClose)
}
// Options provides additional hints and information for message
diff --git a/sdk/vendor/google.golang.org/grpc/metadata/metadata.go b/sdk/vendor/google.golang.org/grpc/metadata/metadata.go
index fb4a88f59..a2cdcaf12 100644
--- a/sdk/vendor/google.golang.org/grpc/metadata/metadata.go
+++ b/sdk/vendor/google.golang.org/grpc/metadata/metadata.go
@@ -91,7 +91,11 @@ func (md MD) Len() int {
// Copy returns a copy of md.
func (md MD) Copy() MD {
- return Join(md)
+ out := make(MD, len(md))
+ for k, v := range md {
+ out[k] = copyOf(v)
+ }
+ return out
}
// Get obtains the values for a given key.
@@ -171,8 +175,11 @@ func AppendToOutgoingContext(ctx context.Context, kv ...string) context.Context
md, _ := ctx.Value(mdOutgoingKey{}).(rawMD)
added := make([][]string, len(md.added)+1)
copy(added, md.added)
- added[len(added)-1] = make([]string, len(kv))
- copy(added[len(added)-1], kv)
+ kvCopy := make([]string, 0, len(kv))
+ for i := 0; i < len(kv); i += 2 {
+ kvCopy = append(kvCopy, strings.ToLower(kv[i]), kv[i+1])
+ }
+ added[len(added)-1] = kvCopy
return context.WithValue(ctx, mdOutgoingKey{}, rawMD{md: md.md, added: added})
}
diff --git a/sdk/vendor/google.golang.org/grpc/picker_wrapper.go b/sdk/vendor/google.golang.org/grpc/picker_wrapper.go
index a5d5516ee..c525dc070 100644
--- a/sdk/vendor/google.golang.org/grpc/picker_wrapper.go
+++ b/sdk/vendor/google.golang.org/grpc/picker_wrapper.go
@@ -58,12 +58,18 @@ func (pw *pickerWrapper) updatePicker(p balancer.Picker) {
pw.mu.Unlock()
}
-func doneChannelzWrapper(acw *acBalancerWrapper, done func(balancer.DoneInfo)) func(balancer.DoneInfo) {
+// doneChannelzWrapper performs the following:
+// - increments the calls started channelz counter
+// - wraps the done function in the passed in result to increment the calls
+// failed or calls succeeded channelz counter before invoking the actual
+// done function.
+func doneChannelzWrapper(acw *acBalancerWrapper, result *balancer.PickResult) {
acw.mu.Lock()
ac := acw.ac
acw.mu.Unlock()
ac.incrCallsStarted()
- return func(b balancer.DoneInfo) {
+ done := result.Done
+ result.Done = func(b balancer.DoneInfo) {
if b.Err != nil && b.Err != io.EOF {
ac.incrCallsFailed()
} else {
@@ -82,7 +88,7 @@ func doneChannelzWrapper(acw *acBalancerWrapper, done func(balancer.DoneInfo)) f
// - the current picker returns other errors and failfast is false.
// - the subConn returned by the current picker is not READY
// When one of these situations happens, pick blocks until the picker gets updated.
-func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.PickInfo) (transport.ClientTransport, func(balancer.DoneInfo), error) {
+func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.PickInfo) (transport.ClientTransport, balancer.PickResult, error) {
var ch chan struct{}
var lastPickErr error
@@ -90,7 +96,7 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
pw.mu.Lock()
if pw.done {
pw.mu.Unlock()
- return nil, nil, ErrClientConnClosing
+ return nil, balancer.PickResult{}, ErrClientConnClosing
}
if pw.picker == nil {
@@ -111,9 +117,9 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
}
switch ctx.Err() {
case context.DeadlineExceeded:
- return nil, nil, status.Error(codes.DeadlineExceeded, errStr)
+ return nil, balancer.PickResult{}, status.Error(codes.DeadlineExceeded, errStr)
case context.Canceled:
- return nil, nil, status.Error(codes.Canceled, errStr)
+ return nil, balancer.PickResult{}, status.Error(codes.Canceled, errStr)
}
case <-ch:
}
@@ -125,7 +131,6 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
pw.mu.Unlock()
pickResult, err := p.Pick(info)
-
if err != nil {
if err == balancer.ErrNoSubConnAvailable {
continue
@@ -136,7 +141,7 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
if istatus.IsRestrictedControlPlaneCode(st) {
err = status.Errorf(codes.Internal, "received picker error with illegal status: %v", err)
}
- return nil, nil, dropError{error: err}
+ return nil, balancer.PickResult{}, dropError{error: err}
}
// For all other errors, wait for ready RPCs should block and other
// RPCs should fail with unavailable.
@@ -144,7 +149,7 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
lastPickErr = err
continue
}
- return nil, nil, status.Error(codes.Unavailable, err.Error())
+ return nil, balancer.PickResult{}, status.Error(codes.Unavailable, err.Error())
}
acw, ok := pickResult.SubConn.(*acBalancerWrapper)
@@ -154,9 +159,10 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
}
if t := acw.getAddrConn().getReadyTransport(); t != nil {
if channelz.IsOn() {
- return t, doneChannelzWrapper(acw, pickResult.Done), nil
+ doneChannelzWrapper(acw, &pickResult)
+ return t, pickResult, nil
}
- return t, pickResult.Done, nil
+ return t, pickResult, nil
}
if pickResult.Done != nil {
// Calling done with nil error, no bytes sent and no bytes received.
diff --git a/sdk/vendor/google.golang.org/grpc/pickfirst.go b/sdk/vendor/google.golang.org/grpc/pickfirst.go
index b3a55481b..fc91b4d26 100644
--- a/sdk/vendor/google.golang.org/grpc/pickfirst.go
+++ b/sdk/vendor/google.golang.org/grpc/pickfirst.go
@@ -51,7 +51,7 @@ type pickfirstBalancer struct {
func (b *pickfirstBalancer) ResolverError(err error) {
if logger.V(2) {
- logger.Infof("pickfirstBalancer: ResolverError called with error %v", err)
+ logger.Infof("pickfirstBalancer: ResolverError called with error: %v", err)
}
if b.subConn == nil {
b.state = connectivity.TransientFailure
diff --git a/sdk/vendor/google.golang.org/grpc/resolver/resolver.go b/sdk/vendor/google.golang.org/grpc/resolver/resolver.go
index 967cbc737..6215e5ef2 100644
--- a/sdk/vendor/google.golang.org/grpc/resolver/resolver.go
+++ b/sdk/vendor/google.golang.org/grpc/resolver/resolver.go
@@ -24,6 +24,7 @@ import (
"context"
"net"
"net/url"
+ "strings"
"google.golang.org/grpc/attributes"
"google.golang.org/grpc/credentials"
@@ -40,8 +41,9 @@ var (
// TODO(bar) install dns resolver in init(){}.
-// Register registers the resolver builder to the resolver map. b.Scheme will be
-// used as the scheme registered with this builder.
+// Register registers the resolver builder to the resolver map. b.Scheme will
+// be used as the scheme registered with this builder. The registry is case
+// sensitive, and schemes should not contain any uppercase characters.
//
// NOTE: this function must only be called during initialization time (i.e. in
// an init() function), and is not thread-safe. If multiple Resolvers are
@@ -202,6 +204,15 @@ type State struct {
// gRPC to add new methods to this interface.
type ClientConn interface {
// UpdateState updates the state of the ClientConn appropriately.
+ //
+ // If an error is returned, the resolver should try to resolve the
+ // target again. The resolver should use a backoff timer to prevent
+ // overloading the server with requests. If a resolver is certain that
+ // reresolving will not change the result, e.g. because it is
+ // a watch-based resolver, returned errors can be ignored.
+ //
+ // If the resolved State is the same as the last reported one, calling
+ // UpdateState can be omitted.
UpdateState(State) error
// ReportError notifies the ClientConn that the Resolver encountered an
// error. The ClientConn will notify the load balancer and begin calling
@@ -247,9 +258,6 @@ type Target struct {
Scheme string
// Deprecated: use URL.Host instead.
Authority string
- // Deprecated: use URL.Path or URL.Opaque instead. The latter is set when
- // the former is empty.
- Endpoint string
// URL contains the parsed dial target with an optional default scheme added
// to it if the original dial target contained no scheme or contained an
// unregistered scheme. Any query params specified in the original dial
@@ -257,6 +265,24 @@ type Target struct {
URL url.URL
}
+// Endpoint retrieves endpoint without leading "/" from either `URL.Path`
+// or `URL.Opaque`. The latter is used when the former is empty.
+func (t Target) Endpoint() string {
+ endpoint := t.URL.Path
+ if endpoint == "" {
+ endpoint = t.URL.Opaque
+ }
+ // For targets of the form "[scheme]://[authority]/endpoint, the endpoint
+ // value returned from url.Parse() contains a leading "/". Although this is
+ // in accordance with RFC 3986, we do not want to break existing resolver
+ // implementations which expect the endpoint without the leading "/". So, we
+ // end up stripping the leading "/" here. But this will result in an
+ // incorrect parsing for something like "unix:///path/to/socket". Since we
+ // own the "unix" resolver, we can workaround in the unix resolver by using
+ // the `URL` field.
+ return strings.TrimPrefix(endpoint, "/")
+}
+
// Builder creates a resolver that will be used to watch name resolution updates.
type Builder interface {
// Build creates a new resolver for the given target.
@@ -264,8 +290,10 @@ type Builder interface {
// gRPC dial calls Build synchronously, and fails if the returned error is
// not nil.
Build(target Target, cc ClientConn, opts BuildOptions) (Resolver, error)
- // Scheme returns the scheme supported by this resolver.
- // Scheme is defined at https://github.com/grpc/grpc/blob/master/doc/naming.md.
+ // Scheme returns the scheme supported by this resolver. Scheme is defined
+ // at https://github.com/grpc/grpc/blob/master/doc/naming.md. The returned
+ // string should not contain uppercase characters, as they will not match
+ // the parsed target's scheme as defined in RFC 3986.
Scheme() string
}
diff --git a/sdk/vendor/google.golang.org/grpc/rpc_util.go b/sdk/vendor/google.golang.org/grpc/rpc_util.go
index 934fc1aa0..2030736a3 100644
--- a/sdk/vendor/google.golang.org/grpc/rpc_util.go
+++ b/sdk/vendor/google.golang.org/grpc/rpc_util.go
@@ -25,7 +25,6 @@ import (
"encoding/binary"
"fmt"
"io"
- "io/ioutil"
"math"
"strings"
"sync"
@@ -77,7 +76,7 @@ func NewGZIPCompressorWithLevel(level int) (Compressor, error) {
return &gzipCompressor{
pool: sync.Pool{
New: func() interface{} {
- w, err := gzip.NewWriterLevel(ioutil.Discard, level)
+ w, err := gzip.NewWriterLevel(io.Discard, level)
if err != nil {
panic(err)
}
@@ -143,7 +142,7 @@ func (d *gzipDecompressor) Do(r io.Reader) ([]byte, error) {
z.Close()
d.pool.Put(z)
}()
- return ioutil.ReadAll(z)
+ return io.ReadAll(z)
}
func (d *gzipDecompressor) Type() string {
@@ -160,6 +159,7 @@ type callInfo struct {
contentSubtype string
codec baseCodec
maxRetryRPCBufferSize int
+ onFinish []func(err error)
}
func defaultCallInfo() *callInfo {
@@ -296,8 +296,44 @@ func (o FailFastCallOption) before(c *callInfo) error {
}
func (o FailFastCallOption) after(c *callInfo, attempt *csAttempt) {}
+// OnFinish returns a CallOption that configures a callback to be called when
+// the call completes. The error passed to the callback is the status of the
+// RPC, and may be nil. The onFinish callback provided will only be called once
+// by gRPC. This is mainly used to be used by streaming interceptors, to be
+// notified when the RPC completes along with information about the status of
+// the RPC.
+//
+// # Experimental
+//
+// Notice: This API is EXPERIMENTAL and may be changed or removed in a
+// later release.
+func OnFinish(onFinish func(err error)) CallOption {
+ return OnFinishCallOption{
+ OnFinish: onFinish,
+ }
+}
+
+// OnFinishCallOption is CallOption that indicates a callback to be called when
+// the call completes.
+//
+// # Experimental
+//
+// Notice: This type is EXPERIMENTAL and may be changed or removed in a
+// later release.
+type OnFinishCallOption struct {
+ OnFinish func(error)
+}
+
+func (o OnFinishCallOption) before(c *callInfo) error {
+ c.onFinish = append(c.onFinish, o.OnFinish)
+ return nil
+}
+
+func (o OnFinishCallOption) after(c *callInfo, attempt *csAttempt) {}
+
// MaxCallRecvMsgSize returns a CallOption which sets the maximum message size
-// in bytes the client can receive.
+// in bytes the client can receive. If this is not set, gRPC uses the default
+// 4MB.
func MaxCallRecvMsgSize(bytes int) CallOption {
return MaxRecvMsgSizeCallOption{MaxRecvMsgSize: bytes}
}
@@ -320,7 +356,8 @@ func (o MaxRecvMsgSizeCallOption) before(c *callInfo) error {
func (o MaxRecvMsgSizeCallOption) after(c *callInfo, attempt *csAttempt) {}
// MaxCallSendMsgSize returns a CallOption which sets the maximum message size
-// in bytes the client can send.
+// in bytes the client can send. If this is not set, gRPC uses the default
+// `math.MaxInt32`.
func MaxCallSendMsgSize(bytes int) CallOption {
return MaxSendMsgSizeCallOption{MaxSendMsgSize: bytes}
}
@@ -657,12 +694,13 @@ func msgHeader(data, compData []byte) (hdr []byte, payload []byte) {
func outPayload(client bool, msg interface{}, data, payload []byte, t time.Time) *stats.OutPayload {
return &stats.OutPayload{
- Client: client,
- Payload: msg,
- Data: data,
- Length: len(data),
- WireLength: len(payload) + headerLen,
- SentTime: t,
+ Client: client,
+ Payload: msg,
+ Data: data,
+ Length: len(data),
+ WireLength: len(payload) + headerLen,
+ CompressedLength: len(payload),
+ SentTime: t,
}
}
@@ -683,7 +721,7 @@ func checkRecvPayload(pf payloadFormat, recvCompress string, haveCompressor bool
}
type payloadInfo struct {
- wireLength int // The compressed length got from wire.
+ compressedLength int // The compressed length got from wire.
uncompressedBytes []byte
}
@@ -693,7 +731,7 @@ func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxRecei
return nil, err
}
if payInfo != nil {
- payInfo.wireLength = len(d)
+ payInfo.compressedLength = len(d)
}
if st := checkRecvPayload(pf, s.RecvCompress(), compressor != nil || dc != nil); st != nil {
@@ -711,7 +749,7 @@ func recvAndDecompress(p *parser, s *transport.Stream, dc Decompressor, maxRecei
d, size, err = decompress(compressor, d, maxReceiveMessageSize)
}
if err != nil {
- return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message %v", err)
+ return nil, status.Errorf(codes.Internal, "grpc: failed to decompress the received message: %v", err)
}
if size > maxReceiveMessageSize {
// TODO: Revisit the error code. Currently keep it consistent with java
@@ -746,7 +784,7 @@ func decompress(compressor encoding.Compressor, d []byte, maxReceiveMessageSize
}
// Read from LimitReader with limit max+1. So if the underlying
// reader is over limit, the result will be bigger than max.
- d, err = ioutil.ReadAll(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1))
+ d, err = io.ReadAll(io.LimitReader(dcReader, int64(maxReceiveMessageSize)+1))
return d, len(d), err
}
@@ -759,7 +797,7 @@ func recv(p *parser, c baseCodec, s *transport.Stream, dc Decompressor, m interf
return err
}
if err := c.Unmarshal(d, m); err != nil {
- return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message %v", err)
+ return status.Errorf(codes.Internal, "grpc: failed to unmarshal the received message: %v", err)
}
if payInfo != nil {
payInfo.uncompressedBytes = d
diff --git a/sdk/vendor/google.golang.org/grpc/server.go b/sdk/vendor/google.golang.org/grpc/server.go
index 2808b7c83..76d152a69 100644
--- a/sdk/vendor/google.golang.org/grpc/server.go
+++ b/sdk/vendor/google.golang.org/grpc/server.go
@@ -43,8 +43,8 @@ import (
"google.golang.org/grpc/internal"
"google.golang.org/grpc/internal/binarylog"
"google.golang.org/grpc/internal/channelz"
- "google.golang.org/grpc/internal/grpcrand"
"google.golang.org/grpc/internal/grpcsync"
+ "google.golang.org/grpc/internal/grpcutil"
"google.golang.org/grpc/internal/transport"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/metadata"
@@ -74,10 +74,10 @@ func init() {
srv.drainServerTransports(addr)
}
internal.AddGlobalServerOptions = func(opt ...ServerOption) {
- extraServerOptions = append(extraServerOptions, opt...)
+ globalServerOptions = append(globalServerOptions, opt...)
}
internal.ClearGlobalServerOptions = func() {
- extraServerOptions = nil
+ globalServerOptions = nil
}
internal.BinaryLogger = binaryLogger
internal.JoinServerOptions = newJoinServerOption
@@ -145,7 +145,7 @@ type Server struct {
channelzID *channelz.Identifier
czData *channelzData
- serverWorkerChannels []chan *serverWorkerData
+ serverWorkerChannel chan *serverWorkerData
}
type serverOptions struct {
@@ -183,7 +183,7 @@ var defaultServerOptions = serverOptions{
writeBufferSize: defaultWriteBufSize,
readBufferSize: defaultReadBufSize,
}
-var extraServerOptions []ServerOption
+var globalServerOptions []ServerOption
// A ServerOption sets options such as credentials, codec and keepalive parameters, etc.
type ServerOption interface {
@@ -560,47 +560,45 @@ func NumStreamWorkers(numServerWorkers uint32) ServerOption {
const serverWorkerResetThreshold = 1 << 16
// serverWorkers blocks on a *transport.Stream channel forever and waits for
-// data to be fed by serveStreams. This allows different requests to be
+// data to be fed by serveStreams. This allows multiple requests to be
// processed by the same goroutine, removing the need for expensive stack
// re-allocations (see the runtime.morestack problem [1]).
//
// [1] https://github.com/golang/go/issues/18138
-func (s *Server) serverWorker(ch chan *serverWorkerData) {
- // To make sure all server workers don't reset at the same time, choose a
- // random number of iterations before resetting.
- threshold := serverWorkerResetThreshold + grpcrand.Intn(serverWorkerResetThreshold)
- for completed := 0; completed < threshold; completed++ {
- data, ok := <-ch
+func (s *Server) serverWorker() {
+ for completed := 0; completed < serverWorkerResetThreshold; completed++ {
+ data, ok := <-s.serverWorkerChannel
if !ok {
return
}
- s.handleStream(data.st, data.stream, s.traceInfo(data.st, data.stream))
- data.wg.Done()
+ s.handleSingleStream(data)
}
- go s.serverWorker(ch)
+ go s.serverWorker()
}
-// initServerWorkers creates worker goroutines and channels to process incoming
+func (s *Server) handleSingleStream(data *serverWorkerData) {
+ defer data.wg.Done()
+ s.handleStream(data.st, data.stream, s.traceInfo(data.st, data.stream))
+}
+
+// initServerWorkers creates worker goroutines and a channel to process incoming
// connections to reduce the time spent overall on runtime.morestack.
func (s *Server) initServerWorkers() {
- s.serverWorkerChannels = make([]chan *serverWorkerData, s.opts.numServerWorkers)
+ s.serverWorkerChannel = make(chan *serverWorkerData)
for i := uint32(0); i < s.opts.numServerWorkers; i++ {
- s.serverWorkerChannels[i] = make(chan *serverWorkerData)
- go s.serverWorker(s.serverWorkerChannels[i])
+ go s.serverWorker()
}
}
func (s *Server) stopServerWorkers() {
- for i := uint32(0); i < s.opts.numServerWorkers; i++ {
- close(s.serverWorkerChannels[i])
- }
+ close(s.serverWorkerChannel)
}
// NewServer creates a gRPC server which has no service registered and has not
// started to accept requests yet.
func NewServer(opt ...ServerOption) *Server {
opts := defaultServerOptions
- for _, o := range extraServerOptions {
+ for _, o := range globalServerOptions {
o.apply(&opts)
}
for _, o := range opt {
@@ -945,26 +943,21 @@ func (s *Server) serveStreams(st transport.ServerTransport) {
defer st.Close(errors.New("finished serving streams for the server transport"))
var wg sync.WaitGroup
- var roundRobinCounter uint32
st.HandleStreams(func(stream *transport.Stream) {
wg.Add(1)
if s.opts.numServerWorkers > 0 {
data := &serverWorkerData{st: st, wg: &wg, stream: stream}
select {
- case s.serverWorkerChannels[atomic.AddUint32(&roundRobinCounter, 1)%s.opts.numServerWorkers] <- data:
+ case s.serverWorkerChannel <- data:
+ return
default:
// If all stream workers are busy, fallback to the default code path.
- go func() {
- s.handleStream(st, stream, s.traceInfo(st, stream))
- wg.Done()
- }()
}
- } else {
- go func() {
- defer wg.Done()
- s.handleStream(st, stream, s.traceInfo(st, stream))
- }()
}
+ go func() {
+ defer wg.Done()
+ s.handleStream(st, stream, s.traceInfo(st, stream))
+ }()
}, func(ctx context.Context, method string) context.Context {
if !EnableTracing {
return ctx
@@ -1252,7 +1245,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
logEntry.PeerAddr = peer.Addr
}
for _, binlog := range binlogs {
- binlog.Log(logEntry)
+ binlog.Log(ctx, logEntry)
}
}
@@ -1263,6 +1256,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
var comp, decomp encoding.Compressor
var cp Compressor
var dc Decompressor
+ var sendCompressorName string
// If dc is set and matches the stream's compression, use it. Otherwise, try
// to find a matching registered compressor for decomp.
@@ -1283,12 +1277,18 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
// NOTE: this needs to be ahead of all handling, https://github.com/grpc/grpc-go/issues/686.
if s.opts.cp != nil {
cp = s.opts.cp
- stream.SetSendCompress(cp.Type())
+ sendCompressorName = cp.Type()
} else if rc := stream.RecvCompress(); rc != "" && rc != encoding.Identity {
// Legacy compressor not specified; attempt to respond with same encoding.
comp = encoding.GetCompressor(rc)
if comp != nil {
- stream.SetSendCompress(rc)
+ sendCompressorName = comp.Name()
+ }
+ }
+
+ if sendCompressorName != "" {
+ if err := stream.SetSendCompress(sendCompressorName); err != nil {
+ return status.Errorf(codes.Internal, "grpc: failed to set send compressor: %v", err)
}
}
@@ -1299,7 +1299,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
d, err := recvAndDecompress(&parser{r: stream}, stream, dc, s.opts.maxReceiveMessageSize, payInfo, decomp)
if err != nil {
if e := t.WriteStatus(stream, status.Convert(err)); e != nil {
- channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status %v", e)
+ channelz.Warningf(logger, s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e)
}
return err
}
@@ -1312,11 +1312,12 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
}
for _, sh := range shs {
sh.HandleRPC(stream.Context(), &stats.InPayload{
- RecvTime: time.Now(),
- Payload: v,
- WireLength: payInfo.wireLength + headerLen,
- Data: d,
- Length: len(d),
+ RecvTime: time.Now(),
+ Payload: v,
+ Length: len(d),
+ WireLength: payInfo.compressedLength + headerLen,
+ CompressedLength: payInfo.compressedLength,
+ Data: d,
})
}
if len(binlogs) != 0 {
@@ -1324,7 +1325,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
Message: d,
}
for _, binlog := range binlogs {
- binlog.Log(cm)
+ binlog.Log(stream.Context(), cm)
}
}
if trInfo != nil {
@@ -1357,7 +1358,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
Header: h,
}
for _, binlog := range binlogs {
- binlog.Log(sh)
+ binlog.Log(stream.Context(), sh)
}
}
st := &binarylog.ServerTrailer{
@@ -1365,7 +1366,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
Err: appErr,
}
for _, binlog := range binlogs {
- binlog.Log(st)
+ binlog.Log(stream.Context(), st)
}
}
return appErr
@@ -1375,6 +1376,11 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
}
opts := &transport.Options{Last: true}
+ // Server handler could have set new compressor by calling SetSendCompressor.
+ // In case it is set, we need to use it for compressing outbound message.
+ if stream.SendCompress() != sendCompressorName {
+ comp = encoding.GetCompressor(stream.SendCompress())
+ }
if err := s.sendResponse(t, stream, reply, cp, opts, comp); err != nil {
if err == io.EOF {
// The entire stream is done (for unary RPC only).
@@ -1402,8 +1408,8 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
Err: appErr,
}
for _, binlog := range binlogs {
- binlog.Log(sh)
- binlog.Log(st)
+ binlog.Log(stream.Context(), sh)
+ binlog.Log(stream.Context(), st)
}
}
return err
@@ -1417,8 +1423,8 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
Message: reply,
}
for _, binlog := range binlogs {
- binlog.Log(sh)
- binlog.Log(sm)
+ binlog.Log(stream.Context(), sh)
+ binlog.Log(stream.Context(), sm)
}
}
if channelz.IsOn() {
@@ -1430,17 +1436,16 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
// TODO: Should we be logging if writing status failed here, like above?
// Should the logging be in WriteStatus? Should we ignore the WriteStatus
// error or allow the stats handler to see it?
- err = t.WriteStatus(stream, statusOK)
if len(binlogs) != 0 {
st := &binarylog.ServerTrailer{
Trailer: stream.Trailer(),
Err: appErr,
}
for _, binlog := range binlogs {
- binlog.Log(st)
+ binlog.Log(stream.Context(), st)
}
}
- return err
+ return t.WriteStatus(stream, statusOK)
}
// chainStreamServerInterceptors chains all stream server interceptors into one.
@@ -1574,7 +1579,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
logEntry.PeerAddr = peer.Addr
}
for _, binlog := range ss.binlogs {
- binlog.Log(logEntry)
+ binlog.Log(stream.Context(), logEntry)
}
}
@@ -1597,12 +1602,18 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
// NOTE: this needs to be ahead of all handling, https://github.com/grpc/grpc-go/issues/686.
if s.opts.cp != nil {
ss.cp = s.opts.cp
- stream.SetSendCompress(s.opts.cp.Type())
+ ss.sendCompressorName = s.opts.cp.Type()
} else if rc := stream.RecvCompress(); rc != "" && rc != encoding.Identity {
// Legacy compressor not specified; attempt to respond with same encoding.
ss.comp = encoding.GetCompressor(rc)
if ss.comp != nil {
- stream.SetSendCompress(rc)
+ ss.sendCompressorName = rc
+ }
+ }
+
+ if ss.sendCompressorName != "" {
+ if err := stream.SetSendCompress(ss.sendCompressorName); err != nil {
+ return status.Errorf(codes.Internal, "grpc: failed to set send compressor: %v", err)
}
}
@@ -1640,16 +1651,16 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
ss.trInfo.tr.SetError()
ss.mu.Unlock()
}
- t.WriteStatus(ss.s, appStatus)
if len(ss.binlogs) != 0 {
st := &binarylog.ServerTrailer{
Trailer: ss.s.Trailer(),
Err: appErr,
}
for _, binlog := range ss.binlogs {
- binlog.Log(st)
+ binlog.Log(stream.Context(), st)
}
}
+ t.WriteStatus(ss.s, appStatus)
// TODO: Should we log an error from WriteStatus here and below?
return appErr
}
@@ -1658,17 +1669,16 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
ss.trInfo.tr.LazyLog(stringer("OK"), false)
ss.mu.Unlock()
}
- err = t.WriteStatus(ss.s, statusOK)
if len(ss.binlogs) != 0 {
st := &binarylog.ServerTrailer{
Trailer: ss.s.Trailer(),
Err: appErr,
}
for _, binlog := range ss.binlogs {
- binlog.Log(st)
+ binlog.Log(stream.Context(), st)
}
}
- return err
+ return t.WriteStatus(ss.s, statusOK)
}
func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream, trInfo *traceInfo) {
@@ -1935,6 +1945,60 @@ func SendHeader(ctx context.Context, md metadata.MD) error {
return nil
}
+// SetSendCompressor sets a compressor for outbound messages from the server.
+// It must not be called after any event that causes headers to be sent
+// (see ServerStream.SetHeader for the complete list). Provided compressor is
+// used when below conditions are met:
+//
+// - compressor is registered via encoding.RegisterCompressor
+// - compressor name must exist in the client advertised compressor names
+// sent in grpc-accept-encoding header. Use ClientSupportedCompressors to
+// get client supported compressor names.
+//
+// The context provided must be the context passed to the server's handler.
+// It must be noted that compressor name encoding.Identity disables the
+// outbound compression.
+// By default, server messages will be sent using the same compressor with
+// which request messages were sent.
+//
+// It is not safe to call SetSendCompressor concurrently with SendHeader and
+// SendMsg.
+//
+// # Experimental
+//
+// Notice: This function is EXPERIMENTAL and may be changed or removed in a
+// later release.
+func SetSendCompressor(ctx context.Context, name string) error {
+ stream, ok := ServerTransportStreamFromContext(ctx).(*transport.Stream)
+ if !ok || stream == nil {
+ return fmt.Errorf("failed to fetch the stream from the given context")
+ }
+
+ if err := validateSendCompressor(name, stream.ClientAdvertisedCompressors()); err != nil {
+ return fmt.Errorf("unable to set send compressor: %w", err)
+ }
+
+ return stream.SetSendCompress(name)
+}
+
+// ClientSupportedCompressors returns compressor names advertised by the client
+// via grpc-accept-encoding header.
+//
+// The context provided must be the context passed to the server's handler.
+//
+// # Experimental
+//
+// Notice: This function is EXPERIMENTAL and may be changed or removed in a
+// later release.
+func ClientSupportedCompressors(ctx context.Context) ([]string, error) {
+ stream, ok := ServerTransportStreamFromContext(ctx).(*transport.Stream)
+ if !ok || stream == nil {
+ return nil, fmt.Errorf("failed to fetch the stream from the given context %v", ctx)
+ }
+
+ return strings.Split(stream.ClientAdvertisedCompressors(), ","), nil
+}
+
// SetTrailer sets the trailer metadata that will be sent when an RPC returns.
// When called more than once, all the provided metadata will be merged.
//
@@ -1969,3 +2033,22 @@ type channelzServer struct {
func (c *channelzServer) ChannelzMetric() *channelz.ServerInternalMetric {
return c.s.channelzMetric()
}
+
+// validateSendCompressor returns an error when given compressor name cannot be
+// handled by the server or the client based on the advertised compressors.
+func validateSendCompressor(name, clientCompressors string) error {
+ if name == encoding.Identity {
+ return nil
+ }
+
+ if !grpcutil.IsCompressorNameRegistered(name) {
+ return fmt.Errorf("compressor not registered %q", name)
+ }
+
+ for _, c := range strings.Split(clientCompressors, ",") {
+ if c == name {
+ return nil // found match
+ }
+ }
+ return fmt.Errorf("client does not support compressor %q", name)
+}
diff --git a/sdk/vendor/google.golang.org/grpc/service_config.go b/sdk/vendor/google.golang.org/grpc/service_config.go
index 01bbb2025..f22acace4 100644
--- a/sdk/vendor/google.golang.org/grpc/service_config.go
+++ b/sdk/vendor/google.golang.org/grpc/service_config.go
@@ -226,7 +226,7 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult {
var rsc jsonSC
err := json.Unmarshal([]byte(js), &rsc)
if err != nil {
- logger.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err)
+ logger.Warningf("grpc: unmarshaling service config %s: %v", js, err)
return &serviceconfig.ParseResult{Err: err}
}
sc := ServiceConfig{
@@ -254,7 +254,7 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult {
}
d, err := parseDuration(m.Timeout)
if err != nil {
- logger.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err)
+ logger.Warningf("grpc: unmarshaling service config %s: %v", js, err)
return &serviceconfig.ParseResult{Err: err}
}
@@ -263,7 +263,7 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult {
Timeout: d,
}
if mc.RetryPolicy, err = convertRetryPolicy(m.RetryPolicy); err != nil {
- logger.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err)
+ logger.Warningf("grpc: unmarshaling service config %s: %v", js, err)
return &serviceconfig.ParseResult{Err: err}
}
if m.MaxRequestMessageBytes != nil {
@@ -283,13 +283,13 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult {
for i, n := range *m.Name {
path, err := n.generatePath()
if err != nil {
- logger.Warningf("grpc: parseServiceConfig error unmarshaling %s due to methodConfig[%d]: %v", js, i, err)
+ logger.Warningf("grpc: error unmarshaling service config %s due to methodConfig[%d]: %v", js, i, err)
return &serviceconfig.ParseResult{Err: err}
}
if _, ok := paths[path]; ok {
err = errDuplicatedName
- logger.Warningf("grpc: parseServiceConfig error unmarshaling %s due to methodConfig[%d]: %v", js, i, err)
+ logger.Warningf("grpc: error unmarshaling service config %s due to methodConfig[%d]: %v", js, i, err)
return &serviceconfig.ParseResult{Err: err}
}
paths[path] = struct{}{}
diff --git a/sdk/vendor/google.golang.org/grpc/stats/stats.go b/sdk/vendor/google.golang.org/grpc/stats/stats.go
index 0285dcc6a..7a552a9b7 100644
--- a/sdk/vendor/google.golang.org/grpc/stats/stats.go
+++ b/sdk/vendor/google.golang.org/grpc/stats/stats.go
@@ -67,10 +67,18 @@ type InPayload struct {
Payload interface{}
// Data is the serialized message payload.
Data []byte
- // Length is the length of uncompressed data.
+
+ // Length is the size of the uncompressed payload data. Does not include any
+ // framing (gRPC or HTTP/2).
Length int
- // WireLength is the length of data on wire (compressed, signed, encrypted).
+ // CompressedLength is the size of the compressed payload data. Does not
+ // include any framing (gRPC or HTTP/2). Same as Length if compression not
+ // enabled.
+ CompressedLength int
+ // WireLength is the size of the compressed payload data plus gRPC framing.
+ // Does not include HTTP/2 framing.
WireLength int
+
// RecvTime is the time when the payload is received.
RecvTime time.Time
}
@@ -129,9 +137,15 @@ type OutPayload struct {
Payload interface{}
// Data is the serialized message payload.
Data []byte
- // Length is the length of uncompressed data.
+ // Length is the size of the uncompressed payload data. Does not include any
+ // framing (gRPC or HTTP/2).
Length int
- // WireLength is the length of data on wire (compressed, signed, encrypted).
+ // CompressedLength is the size of the compressed payload data. Does not
+ // include any framing (gRPC or HTTP/2). Same as Length if compression not
+ // enabled.
+ CompressedLength int
+ // WireLength is the size of the compressed payload data plus gRPC framing.
+ // Does not include HTTP/2 framing.
WireLength int
// SentTime is the time when the payload is sent.
SentTime time.Time
diff --git a/sdk/vendor/google.golang.org/grpc/status/status.go b/sdk/vendor/google.golang.org/grpc/status/status.go
index 623be39f2..53910fb7c 100644
--- a/sdk/vendor/google.golang.org/grpc/status/status.go
+++ b/sdk/vendor/google.golang.org/grpc/status/status.go
@@ -77,7 +77,9 @@ func FromProto(s *spb.Status) *Status {
// FromError returns a Status representation of err.
//
// - If err was produced by this package or implements the method `GRPCStatus()
-// *Status`, the appropriate Status is returned.
+// *Status`, or if err wraps a type satisfying this, the appropriate Status is
+// returned. For wrapped errors, the message returned contains the entire
+// err.Error() text and not just the wrapped status.
//
// - If err is nil, a Status is returned with codes.OK and no message.
//
@@ -88,10 +90,15 @@ func FromError(err error) (s *Status, ok bool) {
if err == nil {
return nil, true
}
- if se, ok := err.(interface {
- GRPCStatus() *Status
- }); ok {
- return se.GRPCStatus(), true
+ type grpcstatus interface{ GRPCStatus() *Status }
+ if gs, ok := err.(grpcstatus); ok {
+ return gs.GRPCStatus(), true
+ }
+ var gs grpcstatus
+ if errors.As(err, &gs) {
+ p := gs.GRPCStatus().Proto()
+ p.Message = err.Error()
+ return status.FromProto(p), true
}
return New(codes.Unknown, err.Error()), false
}
@@ -103,19 +110,16 @@ func Convert(err error) *Status {
return s
}
-// Code returns the Code of the error if it is a Status error, codes.OK if err
-// is nil, or codes.Unknown otherwise.
+// Code returns the Code of the error if it is a Status error or if it wraps a
+// Status error. If that is not the case, it returns codes.OK if err is nil, or
+// codes.Unknown otherwise.
func Code(err error) codes.Code {
// Don't use FromError to avoid allocation of OK status.
if err == nil {
return codes.OK
}
- if se, ok := err.(interface {
- GRPCStatus() *Status
- }); ok {
- return se.GRPCStatus().Code()
- }
- return codes.Unknown
+
+ return Convert(err).Code()
}
// FromContextError converts a context error or wrapped context error into a
diff --git a/sdk/vendor/google.golang.org/grpc/stream.go b/sdk/vendor/google.golang.org/grpc/stream.go
index 0f8e6c014..d1226a412 100644
--- a/sdk/vendor/google.golang.org/grpc/stream.go
+++ b/sdk/vendor/google.golang.org/grpc/stream.go
@@ -168,10 +168,19 @@ func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
}
func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (_ ClientStream, err error) {
- if md, _, ok := metadata.FromOutgoingContextRaw(ctx); ok {
+ if md, added, ok := metadata.FromOutgoingContextRaw(ctx); ok {
+ // validate md
if err := imetadata.Validate(md); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
+ // validate added
+ for _, kvs := range added {
+ for i := 0; i < len(kvs); i += 2 {
+ if err := imetadata.ValidatePair(kvs[i], kvs[i+1]); err != nil {
+ return nil, status.Error(codes.Internal, err.Error())
+ }
+ }
+ }
}
if channelz.IsOn() {
cc.incrCallsStarted()
@@ -352,7 +361,7 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client
}
}
for _, binlog := range cs.binlogs {
- binlog.Log(logEntry)
+ binlog.Log(cs.ctx, logEntry)
}
}
@@ -438,7 +447,7 @@ func (a *csAttempt) getTransport() error {
cs := a.cs
var err error
- a.t, a.done, err = cs.cc.getTransport(a.ctx, cs.callInfo.failFast, cs.callHdr.Method)
+ a.t, a.pickResult, err = cs.cc.getTransport(a.ctx, cs.callInfo.failFast, cs.callHdr.Method)
if err != nil {
if de, ok := err.(dropError); ok {
err = de.error
@@ -455,6 +464,25 @@ func (a *csAttempt) getTransport() error {
func (a *csAttempt) newStream() error {
cs := a.cs
cs.callHdr.PreviousAttempts = cs.numRetries
+
+ // Merge metadata stored in PickResult, if any, with existing call metadata.
+ // It is safe to overwrite the csAttempt's context here, since all state
+ // maintained in it are local to the attempt. When the attempt has to be
+ // retried, a new instance of csAttempt will be created.
+ if a.pickResult.Metatada != nil {
+ // We currently do not have a function it the metadata package which
+ // merges given metadata with existing metadata in a context. Existing
+ // function `AppendToOutgoingContext()` takes a variadic argument of key
+ // value pairs.
+ //
+ // TODO: Make it possible to retrieve key value pairs from metadata.MD
+ // in a form passable to AppendToOutgoingContext(), or create a version
+ // of AppendToOutgoingContext() that accepts a metadata.MD.
+ md, _ := metadata.FromOutgoingContext(a.ctx)
+ md = metadata.Join(md, a.pickResult.Metatada)
+ a.ctx = metadata.NewOutgoingContext(a.ctx, md)
+ }
+
s, err := a.t.NewStream(a.ctx, cs.callHdr)
if err != nil {
nse, ok := err.(*transport.NewStreamError)
@@ -529,12 +557,12 @@ type clientStream struct {
// csAttempt implements a single transport stream attempt within a
// clientStream.
type csAttempt struct {
- ctx context.Context
- cs *clientStream
- t transport.ClientTransport
- s *transport.Stream
- p *parser
- done func(balancer.DoneInfo)
+ ctx context.Context
+ cs *clientStream
+ t transport.ClientTransport
+ s *transport.Stream
+ p *parser
+ pickResult balancer.PickResult
finished bool
dc Decompressor
@@ -781,7 +809,7 @@ func (cs *clientStream) Header() (metadata.MD, error) {
}
cs.serverHeaderBinlogged = true
for _, binlog := range cs.binlogs {
- binlog.Log(logEntry)
+ binlog.Log(cs.ctx, logEntry)
}
}
return m, nil
@@ -862,7 +890,7 @@ func (cs *clientStream) SendMsg(m interface{}) (err error) {
Message: data,
}
for _, binlog := range cs.binlogs {
- binlog.Log(cm)
+ binlog.Log(cs.ctx, cm)
}
}
return err
@@ -886,7 +914,7 @@ func (cs *clientStream) RecvMsg(m interface{}) error {
Message: recvInfo.uncompressedBytes,
}
for _, binlog := range cs.binlogs {
- binlog.Log(sm)
+ binlog.Log(cs.ctx, sm)
}
}
if err != nil || !cs.desc.ServerStreams {
@@ -907,7 +935,7 @@ func (cs *clientStream) RecvMsg(m interface{}) error {
logEntry.PeerAddr = peer.Addr
}
for _, binlog := range cs.binlogs {
- binlog.Log(logEntry)
+ binlog.Log(cs.ctx, logEntry)
}
}
}
@@ -934,7 +962,7 @@ func (cs *clientStream) CloseSend() error {
OnClientSide: true,
}
for _, binlog := range cs.binlogs {
- binlog.Log(chc)
+ binlog.Log(cs.ctx, chc)
}
}
// We never returned an error here for reasons.
@@ -952,6 +980,9 @@ func (cs *clientStream) finish(err error) {
return
}
cs.finished = true
+ for _, onFinish := range cs.callInfo.onFinish {
+ onFinish(err)
+ }
cs.commitAttemptLocked()
if cs.attempt != nil {
cs.attempt.finish(err)
@@ -973,7 +1004,7 @@ func (cs *clientStream) finish(err error) {
OnClientSide: true,
}
for _, binlog := range cs.binlogs {
- binlog.Log(c)
+ binlog.Log(cs.ctx, c)
}
}
if err == nil {
@@ -1062,9 +1093,10 @@ func (a *csAttempt) recvMsg(m interface{}, payInfo *payloadInfo) (err error) {
RecvTime: time.Now(),
Payload: m,
// TODO truncate large payload.
- Data: payInfo.uncompressedBytes,
- WireLength: payInfo.wireLength + headerLen,
- Length: len(payInfo.uncompressedBytes),
+ Data: payInfo.uncompressedBytes,
+ WireLength: payInfo.compressedLength + headerLen,
+ CompressedLength: payInfo.compressedLength,
+ Length: len(payInfo.uncompressedBytes),
})
}
if channelz.IsOn() {
@@ -1103,12 +1135,12 @@ func (a *csAttempt) finish(err error) {
tr = a.s.Trailer()
}
- if a.done != nil {
+ if a.pickResult.Done != nil {
br := false
if a.s != nil {
br = a.s.BytesReceived()
}
- a.done(balancer.DoneInfo{
+ a.pickResult.Done(balancer.DoneInfo{
Err: err,
Trailer: tr,
BytesSent: a.s != nil,
@@ -1464,6 +1496,9 @@ type ServerStream interface {
// It is safe to have a goroutine calling SendMsg and another goroutine
// calling RecvMsg on the same stream at the same time, but it is not safe
// to call SendMsg on the same stream in different goroutines.
+ //
+ // It is not safe to modify the message after calling SendMsg. Tracing
+ // libraries and stats handlers may use the message lazily.
SendMsg(m interface{}) error
// RecvMsg blocks until it receives a message into m or the stream is
// done. It returns io.EOF when the client has performed a CloseSend. On
@@ -1489,6 +1524,8 @@ type serverStream struct {
comp encoding.Compressor
decomp encoding.Compressor
+ sendCompressorName string
+
maxReceiveMessageSize int
maxSendMessageSize int
trInfo *traceInfo
@@ -1536,7 +1573,7 @@ func (ss *serverStream) SendHeader(md metadata.MD) error {
}
ss.serverHeaderBinlogged = true
for _, binlog := range ss.binlogs {
- binlog.Log(sh)
+ binlog.Log(ss.ctx, sh)
}
}
return err
@@ -1581,6 +1618,13 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) {
}
}()
+ // Server handler could have set new compressor by calling SetSendCompressor.
+ // In case it is set, we need to use it for compressing outbound message.
+ if sendCompressorsName := ss.s.SendCompress(); sendCompressorsName != ss.sendCompressorName {
+ ss.comp = encoding.GetCompressor(sendCompressorsName)
+ ss.sendCompressorName = sendCompressorsName
+ }
+
// load hdr, payload, data
hdr, payload, data, err := prepareMsg(m, ss.codec, ss.cp, ss.comp)
if err != nil {
@@ -1602,14 +1646,14 @@ func (ss *serverStream) SendMsg(m interface{}) (err error) {
}
ss.serverHeaderBinlogged = true
for _, binlog := range ss.binlogs {
- binlog.Log(sh)
+ binlog.Log(ss.ctx, sh)
}
}
sm := &binarylog.ServerMessage{
Message: data,
}
for _, binlog := range ss.binlogs {
- binlog.Log(sm)
+ binlog.Log(ss.ctx, sm)
}
}
if len(ss.statsHandler) != 0 {
@@ -1657,7 +1701,7 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) {
if len(ss.binlogs) != 0 {
chc := &binarylog.ClientHalfClose{}
for _, binlog := range ss.binlogs {
- binlog.Log(chc)
+ binlog.Log(ss.ctx, chc)
}
}
return err
@@ -1673,9 +1717,10 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) {
RecvTime: time.Now(),
Payload: m,
// TODO truncate large payload.
- Data: payInfo.uncompressedBytes,
- WireLength: payInfo.wireLength + headerLen,
- Length: len(payInfo.uncompressedBytes),
+ Data: payInfo.uncompressedBytes,
+ Length: len(payInfo.uncompressedBytes),
+ WireLength: payInfo.compressedLength + headerLen,
+ CompressedLength: payInfo.compressedLength,
})
}
}
@@ -1684,7 +1729,7 @@ func (ss *serverStream) RecvMsg(m interface{}) (err error) {
Message: payInfo.uncompressedBytes,
}
for _, binlog := range ss.binlogs {
- binlog.Log(cm)
+ binlog.Log(ss.ctx, cm)
}
}
return nil
diff --git a/sdk/vendor/google.golang.org/grpc/version.go b/sdk/vendor/google.golang.org/grpc/version.go
index 243e06e8d..853ce0e30 100644
--- a/sdk/vendor/google.golang.org/grpc/version.go
+++ b/sdk/vendor/google.golang.org/grpc/version.go
@@ -19,4 +19,4 @@
package grpc
// Version is the current grpc version.
-const Version = "1.52.0"
+const Version = "1.55.0"
diff --git a/sdk/vendor/google.golang.org/grpc/vet.sh b/sdk/vendor/google.golang.org/grpc/vet.sh
index 1d03c0914..a8e4732b3 100644
--- a/sdk/vendor/google.golang.org/grpc/vet.sh
+++ b/sdk/vendor/google.golang.org/grpc/vet.sh
@@ -41,16 +41,8 @@ if [[ "$1" = "-install" ]]; then
github.com/client9/misspell/cmd/misspell
popd
if [[ -z "${VET_SKIP_PROTO}" ]]; then
- if [[ "${TRAVIS}" = "true" ]]; then
- PROTOBUF_VERSION=3.14.0
- PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip
- pushd /home/travis
- wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME}
- unzip ${PROTOC_FILENAME}
- bin/protoc --version
- popd
- elif [[ "${GITHUB_ACTIONS}" = "true" ]]; then
- PROTOBUF_VERSION=3.14.0
+ if [[ "${GITHUB_ACTIONS}" = "true" ]]; then
+ PROTOBUF_VERSION=22.0 # a.k.a v4.22.0 in pb.go files.
PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip
pushd /home/runner/go
wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME}
@@ -66,6 +58,16 @@ elif [[ "$#" -ne 0 ]]; then
die "Unknown argument(s): $*"
fi
+# - Check that generated proto files are up to date.
+if [[ -z "${VET_SKIP_PROTO}" ]]; then
+ make proto && git status --porcelain 2>&1 | fail_on_output || \
+ (git status; git --no-pager diff; exit 1)
+fi
+
+if [[ -n "${VET_ONLY_PROTO}" ]]; then
+ exit 0
+fi
+
# - Ensure all source files contain a copyright message.
# (Done in two parts because Darwin "git grep" has broken support for compound
# exclusion matches.)
@@ -93,13 +95,6 @@ git grep '"github.com/envoyproxy/go-control-plane/envoy' -- '*.go' ':(exclude)*.
misspell -error .
-# - Check that generated proto files are up to date.
-if [[ -z "${VET_SKIP_PROTO}" ]]; then
- PATH="/home/travis/bin:${PATH}" make proto && \
- git status --porcelain 2>&1 | fail_on_output || \
- (git status; git --no-pager diff; exit 1)
-fi
-
# - gofmt, goimports, golint (with exceptions for generated code), go vet,
# go mod tidy.
# Perform these checks on each module inside gRPC.
@@ -111,7 +106,7 @@ for MOD_FILE in $(find . -name 'go.mod'); do
goimports -l . 2>&1 | not grep -vE "\.pb\.go"
golint ./... 2>&1 | not grep -vE "/grpc_testing_not_regenerate/.*\.pb\.go:"
- go mod tidy
+ go mod tidy -compat=1.17
git status --porcelain 2>&1 | fail_on_output || \
(git status; git --no-pager diff; exit 1)
popd
diff --git a/sdk/vendor/modules.txt b/sdk/vendor/modules.txt
index b76392785..6310c331b 100644
--- a/sdk/vendor/modules.txt
+++ b/sdk/vendor/modules.txt
@@ -1,4 +1,4 @@
-# github.com/cenkalti/backoff/v4 v4.2.0
+# github.com/cenkalti/backoff/v4 v4.2.1
## explicit; go 1.18
github.com/cenkalti/backoff/v4
# github.com/davecgh/go-spew v1.1.1
@@ -19,7 +19,7 @@ github.com/golang/protobuf/ptypes
github.com/golang/protobuf/ptypes/any
github.com/golang/protobuf/ptypes/duration
github.com/golang/protobuf/ptypes/timestamp
-# github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
+# github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
## explicit; go 1.14
github.com/grpc-ecosystem/go-grpc-middleware/retry
github.com/grpc-ecosystem/go-grpc-middleware/util/backoffutils
@@ -41,7 +41,7 @@ github.com/maxbrunsfeld/counterfeiter/v6/generator
# github.com/mitchellh/mapstructure v1.5.0
## explicit; go 1.14
github.com/mitchellh/mapstructure
-# github.com/nginxinc/nginx-go-crossplane v0.4.15
+# github.com/nginxinc/nginx-go-crossplane v0.4.17
## explicit; go 1.19
github.com/nginxinc/nginx-go-crossplane
# github.com/pmezard/go-difflib v1.0.0
@@ -65,7 +65,7 @@ github.com/stretchr/testify/require
golang.org/x/mod/internal/lazyregexp
golang.org/x/mod/module
golang.org/x/mod/semver
-# golang.org/x/net v0.9.0
+# golang.org/x/net v0.10.0
## explicit; go 1.17
golang.org/x/net/http/httpguts
golang.org/x/net/http2
@@ -73,7 +73,7 @@ golang.org/x/net/http2/hpack
golang.org/x/net/idna
golang.org/x/net/internal/timeseries
golang.org/x/net/trace
-# golang.org/x/sys v0.7.0
+# golang.org/x/sys v0.8.0
## explicit; go 1.17
golang.org/x/sys/execabs
golang.org/x/sys/internal/unsafeheader
@@ -85,7 +85,7 @@ golang.org/x/text/secure/bidirule
golang.org/x/text/transform
golang.org/x/text/unicode/bidi
golang.org/x/text/unicode/norm
-# golang.org/x/tools v0.8.0
+# golang.org/x/tools v0.9.1
## explicit; go 1.18
golang.org/x/tools/cmd/goimports
golang.org/x/tools/go/ast/astutil
@@ -109,17 +109,17 @@ golang.org/x/tools/internal/pkgbits
golang.org/x/tools/internal/tokeninternal
golang.org/x/tools/internal/typeparams
golang.org/x/tools/internal/typesinternal
-# google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2
+# google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1
## explicit; go 1.19
google.golang.org/genproto/googleapis/rpc/status
-# google.golang.org/grpc v1.52.0
+# google.golang.org/grpc v1.55.0
## explicit; go 1.17
google.golang.org/grpc
google.golang.org/grpc/attributes
google.golang.org/grpc/backoff
google.golang.org/grpc/balancer
google.golang.org/grpc/balancer/base
-google.golang.org/grpc/balancer/grpclb/grpclbstate
+google.golang.org/grpc/balancer/grpclb/state
google.golang.org/grpc/balancer/roundrobin
google.golang.org/grpc/binarylog/grpc_binarylog_v1
google.golang.org/grpc/channelz
diff --git a/src/core/config/commands.go b/src/core/config/commands.go
index 8321b83c3..e78f45615 100644
--- a/src/core/config/commands.go
+++ b/src/core/config/commands.go
@@ -55,7 +55,7 @@ $ nginx-agent completion fish > ~/.config/fish/completions/nginx-agent.fish
`,
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "zsh", "fish"},
- Args: cobra.ExactValidArgs(1),
+ Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
Run: func(cmd *cobra.Command, args []string) {
var err error
diff --git a/src/core/config/config.go b/src/core/config/config.go
index 508bce77d..a5c5d5531 100644
--- a/src/core/config/config.go
+++ b/src/core/config/config.go
@@ -8,8 +8,12 @@
package config
import (
+ "bufio"
+ "bytes"
+ "errors"
"fmt"
- "io/ioutil"
+ "io"
+ "io/fs"
"os"
"path/filepath"
"reflect"
@@ -20,12 +24,11 @@ import (
agent_config "github.com/nginx/agent/sdk/v2/agent/config"
+ log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
+ flag "github.com/spf13/pflag"
"github.com/spf13/viper"
"gopkg.in/yaml.v3"
-
- log "github.com/sirupsen/logrus"
- flag "github.com/spf13/pflag"
)
const (
@@ -219,6 +222,12 @@ func UpdateAgentConfig(systemId string, updateTags []string, updateFeatures []st
Viper.Set(TagsKey, updateTags)
config.Tags = Viper.GetStringSlice(TagsKey)
+ // Needed for legacy reasons.
+ // Remove Features_ prefix from the feature strings.
+ // This is needed for management servers that are sending features before sdk version v2.23.0
+ for index, feature := range updateFeatures {
+ updateFeatures[index] = strings.Replace(feature, "features_", "", 1)
+ }
sort.Strings(updateFeatures)
sort.Strings(config.Features)
synchronizedFeatures := reflect.DeepEqual(updateFeatures, config.Features)
@@ -251,7 +260,7 @@ func UpdateAgentConfig(systemId string, updateTags []string, updateFeatures []st
updatedConfBytes = append([]byte(dynamicConfigUsageComment), updatedConfBytes...)
- err = ioutil.WriteFile(dynamicCfgPath, updatedConfBytes, 0)
+ err = os.WriteFile(dynamicCfgPath, updatedConfBytes, 0)
if err != nil {
return false, err
}
@@ -306,11 +315,23 @@ func getServer() Server {
Token: Viper.GetString(ServerToken),
Metrics: Viper.GetString(ServerMetrics),
Command: Viper.GetString(ServerCommand),
+ Backoff: getBackOff(),
+ }
+}
+
+func getBackOff() Backoff {
+ return Backoff{
+ InitialInterval: Viper.GetDuration(BackoffInitialInterval),
+ RandomizationFactor: Viper.GetFloat64(BackoffRandomizationFactor),
+ Multiplier: Viper.GetFloat64(BackoffMultiplier),
+ MaxInterval: Viper.GetDuration(BackoffMaxInterval),
+ MaxElapsedTime: Viper.GetDuration(BackoffMaxElapsedTime),
}
}
func getAgentAPI() AgentAPI {
return AgentAPI{
+ Host: Viper.GetString(AgentAPIHost),
Port: Viper.GetInt(AgentAPIPort),
Cert: Viper.GetString(AgentAPICert),
Key: Viper.GetString(AgentAPIKey),
@@ -345,25 +366,46 @@ func LoadPropertiesFromFile(cfg string) error {
dynamicCfgPath = DynamicConfigFileAbsPath
}
}
+
dynamicCfgDir, dynamicCfgFile := filepath.Split(dynamicCfgPath)
// Get dynamic file, if it doesn't exist create it.
- file, err := os.Stat(dynamicCfgPath)
- if err != nil {
- log.Warnf("Unable to read dynamic config (%s), got the following error: %v", dynamicCfgPath, err)
- }
+ _, err = os.Stat(dynamicCfgPath)
+ if err == nil {
+ log.Debugf("Checking if features need to be purged from dynamic config: %s", dynamicCfgPath)
+
+ dynCfg, err := os.Open(dynamicCfgPath)
+ if err != nil {
+ return fmt.Errorf("error attempting to open dynamic config (%s): %v", dynamicCfgPath, err)
+ }
- if file == nil {
+ featuresAreSet, cleanDynCfgContent, err := removeFeatures(dynCfg)
+ if err != nil {
+ return fmt.Errorf("error updating dynamic config with features removed (%s): %v", dynamicCfgPath, err)
+ }
+ dynCfg.Close()
+
+ if featuresAreSet {
+ err = os.WriteFile(dynamicCfgPath, cleanDynCfgContent, 0644)
+ if err != nil {
+ return fmt.Errorf("error attempting to update dynamic config (%s): %v", dynamicCfgPath, err)
+ }
+
+ log.Info("Dynamic config purged successfully. Previously enabled features have been removed")
+ }
+ } else if errors.Is(err, fs.ErrNotExist) {
log.Infof("Writing the following file to disk: %s", dynamicCfgPath)
err = os.MkdirAll(dynamicCfgDir, 0755)
if err != nil {
- return fmt.Errorf("error attempting to create directory for dynamic config (%s), got the following error: %v", dynamicCfgDir, err)
+ return fmt.Errorf("error attempting to create directory for dynamic config (%s): %v", dynamicCfgDir, err)
}
err = os.WriteFile(dynamicCfgPath, []byte(dynamicConfigUsageComment), 0644)
if err != nil {
- return fmt.Errorf("error attempting to create dynamic config (%s), got the following error: %v", dynamicCfgPath, err)
+ return fmt.Errorf("error attempting to create dynamic config (%s): %v", dynamicCfgPath, err)
}
+ } else if err != nil {
+ log.Warnf("Unable to read dynamic config (%s): %v", dynamicCfgPath, err)
}
// Load properties from existing file
@@ -378,6 +420,45 @@ func LoadPropertiesFromFile(cfg string) error {
return nil
}
+// removeFeatures removes enabled features from dynamic config content
+func removeFeatures(readFile io.Reader) (bool, []byte, error) {
+ fileScanner := bufio.NewScanner(readFile)
+
+ fileScanner.Split(bufio.ScanLines)
+
+ var bs []byte
+ buf := bytes.NewBuffer(bs)
+
+ var featuresSet bool
+
+ for fileScanner.Scan() {
+ if strings.HasPrefix(fileScanner.Text(), "features") {
+ featuresSet = true
+ for fileScanner.Scan() {
+ if !strings.HasPrefix(strings.TrimSpace(fileScanner.Text()), "-") {
+ _, err := buf.Write(fileScanner.Bytes())
+ if err != nil {
+ return featuresSet, nil, err
+ }
+ break
+ }
+ }
+ } else {
+ _, err := buf.Write(fileScanner.Bytes())
+ if err != nil {
+ return featuresSet, nil, err
+ }
+ }
+
+ _, err := buf.WriteString("\n")
+ if err != nil {
+ return featuresSet, nil, err
+ }
+ }
+
+ return featuresSet, buf.Bytes(), nil
+}
+
func SetDynamicConfigFileAbsPath(dynamicCfgPath string) {
Viper.Set(DynamicConfigPathKey, dynamicCfgPath)
log.Debugf("Set dynamic agent config file: %s", dynamicCfgPath)
diff --git a/src/core/config/config_test.go b/src/core/config/config_test.go
index a7306f591..008e99d30 100644
--- a/src/core/config/config_test.go
+++ b/src/core/config/config_test.go
@@ -8,6 +8,7 @@
package config
import (
+ "bytes"
"fmt"
"os"
"reflect"
@@ -15,12 +16,11 @@ import (
"strings"
"testing"
+ agent_config "github.com/nginx/agent/sdk/v2/agent/config"
+ sysutils "github.com/nginx/agent/v2/test/utils/system"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
-
- agent_config "github.com/nginx/agent/sdk/v2/agent/config"
- sysutils "github.com/nginx/agent/v2/test/utils/system"
)
const (
@@ -87,10 +87,9 @@ func TestSeekConfigFileInPathsFail(t *testing.T) {
func TestDefaultConfig(t *testing.T) {
configPath := "../../../nginx-agent.conf"
- tmpDir := t.TempDir()
t.Run("parsing of default config with dynamic config dir and file creation", func(t *testing.T) {
- tmpDynConfigDir := tmpDir + "/defaultConfigTest"
+ tmpDynConfigDir := t.TempDir() + "/defaultConfigTest"
defer os.RemoveAll(tmpDynConfigDir)
dynConfigPath := fmt.Sprintf("%s/%s", tmpDynConfigDir, DynamicConfigFileName)
SetDynamicConfigFileAbsPath(dynConfigPath)
@@ -148,6 +147,8 @@ func TestGetConfig(t *testing.T) {
assert.Equal(t, Defaults.Server.Metrics, config.Server.Metrics)
assert.Equal(t, Defaults.AgentAPI.Port, config.AgentAPI.Port)
+ assert.Equal(t, Defaults.AgentAPI.Host, config.AgentAPI.Host)
+
assert.Equal(t, Defaults.Nginx.ConfigReloadMonitoringPeriod, config.Nginx.ConfigReloadMonitoringPeriod)
assert.True(t, len(config.AllowedDirectoriesMap) > 0)
@@ -161,6 +162,7 @@ func TestGetConfig(t *testing.T) {
assert.Equal(t, Defaults.AgentMetrics.CollectionInterval, config.AgentMetrics.CollectionInterval)
assert.Equal(t, []string{}, config.Tags)
+ assert.Equal(t, Defaults.Features, config.Features)
assert.Equal(t, []string{}, config.Extensions)
})
@@ -271,14 +273,16 @@ func TestGetConfig(t *testing.T) {
assert.Equal(t, updatedLogLevel, config.Log.Level)
assert.Equal(t, updatedLogPath, config.Log.Path)
- // Everything else should still be default
- assert.Equal(t, Defaults.AgentMetrics.Mode, config.AgentMetrics.Mode)
-
// Check TLS defaults
assert.Equal(t, false, config.TLS.Enable)
assert.Equal(t, "", config.TLS.Ca)
assert.Equal(t, "", config.TLS.Cert)
assert.Equal(t, "", config.TLS.Key)
+
+ // Everything else should still be default
+ assert.Equal(t, Defaults.AgentMetrics.Mode, config.AgentMetrics.Mode)
+ assert.Equal(t, Defaults.Features, config.Features)
+ assert.Equal(t, []string{}, config.Extensions)
})
t.Run("test override config values with ENV variables", func(t *testing.T) {
@@ -393,7 +397,7 @@ extensions:
require.NoError(t, err)
// Check extensions value
- assert.Equal(t, 1, len(config.Extensions))
+ assert.Equal(t, []string{"advanced-metrics"}, config.Extensions)
assert.Equal(t, agent_config.AdvancedMetricsExtensionPlugin, config.Extensions[0])
})
}
@@ -522,3 +526,136 @@ func cleanEnv(t *testing.T, confFileName, dynamicConfFileAbsPath string) {
Viper.Set(ConfigPathKey, cfg)
}
+
+func TestRemoveFeatures(t *testing.T) {
+ tests := []struct {
+ name string
+ input string
+ want string
+ wantFeaturesAreSet bool
+ }{
+ {
+ name: "default dyn config. unchanged",
+ input: `#
+# /etc/nginx-agent/dynamic-agent.conf
+#
+# Dynamic configuration file for NGINX Agent.
+#
+# The purpose of this file is to track agent configuration
+# values that can be dynamically changed via the API and the agent install script.
+# You may edit this file, but API calls that modify the tags on this system will
+# overwrite the tag values in this file.
+#
+# The agent configuration values that API calls can modify are as follows:
+# - tags
+#
+# The agent configuration values that the agent install script can modify are as follows:
+# - instance_group`,
+ want: `#
+# /etc/nginx-agent/dynamic-agent.conf
+#
+# Dynamic configuration file for NGINX Agent.
+#
+# The purpose of this file is to track agent configuration
+# values that can be dynamically changed via the API and the agent install script.
+# You may edit this file, but API calls that modify the tags on this system will
+# overwrite the tag values in this file.
+#
+# The agent configuration values that API calls can modify are as follows:
+# - tags
+#
+# The agent configuration values that the agent install script can modify are as follows:
+# - instance_group
+`,
+ wantFeaturesAreSet: false,
+ },
+ {
+ name: "dyn conf with features enabled",
+ input: `#
+# /etc/nginx-agent/dynamic-agent.conf
+#
+# Dynamic configuration file for NGINX Agent.
+#
+# The purpose of this file is to track agent configuration
+# values that can be dynamically changed via the API and the agent install script.
+# You may edit this file, but API calls that modify the tags on this system will
+# overwrite the tag values in this file.
+#
+# The agent configuration values that API calls can modify are as follows:
+# - tags
+#
+# The agent configuration values that the agent install script can modify are as follows:
+# - instance_group
+
+features:
+ - features_activity-events
+ - features_agent-api
+ - features_dataplane-status
+ - features_file-watcher
+ - features_metrics-throttle
+ - features_nginx-config-async
+ - features_nginx-counting
+ - features_nginx-ssl-config
+ - features_process-watcher
+ - features_registration
+`,
+ want: `#
+# /etc/nginx-agent/dynamic-agent.conf
+#
+# Dynamic configuration file for NGINX Agent.
+#
+# The purpose of this file is to track agent configuration
+# values that can be dynamically changed via the API and the agent install script.
+# You may edit this file, but API calls that modify the tags on this system will
+# overwrite the tag values in this file.
+#
+# The agent configuration values that API calls can modify are as follows:
+# - tags
+#
+# The agent configuration values that the agent install script can modify are as follows:
+# - instance_group
+
+
+`,
+ wantFeaturesAreSet: true,
+ },
+ {
+ name: "dyn conf with features enabled and tags after",
+ input: `#
+# /etc/nginx-agent/dynamic-agent.conf
+#
+# Dynamic configuration file for NGINX Agent.
+
+features:
+ - features_activity-events
+ - features_process-watcher
+ - features_registration
+
+tags:
+ - tag1
+ - tag2
+`,
+ want: `#
+# /etc/nginx-agent/dynamic-agent.conf
+#
+# Dynamic configuration file for NGINX Agent.
+
+
+tags:
+ - tag1
+ - tag2
+`,
+ wantFeaturesAreSet: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ inputBuf := bytes.NewBufferString(tt.input)
+
+ featuresAreSet, got, err := removeFeatures(inputBuf)
+ assert.Equal(t, tt.want, string(got))
+ assert.Equal(t, tt.wantFeaturesAreSet, featuresAreSet)
+ assert.NoError(t, err)
+ })
+ }
+}
diff --git a/src/core/config/defaults.go b/src/core/config/defaults.go
index a89563bbf..32104583d 100644
--- a/src/core/config/defaults.go
+++ b/src/core/config/defaults.go
@@ -49,6 +49,13 @@ var (
// token needs to be validated on the server side - can be overridden by the config value or the cli / environment variable
// so setting to random uuid at the moment, tls connection won't work without the auth header
Token: uuid.New().String(),
+ Backoff: Backoff{
+ InitialInterval: 500 * time.Millisecond,
+ RandomizationFactor: 0.5,
+ Multiplier: 1.5,
+ MaxInterval: 60 * time.Second,
+ MaxElapsedTime: 15 * time.Second,
+ },
},
Nginx: Nginx{
Debug: false,
@@ -75,6 +82,9 @@ var (
CollectionInterval: 15 * time.Second,
Mode: "aggregated",
},
+ AgentAPI: AgentAPI{
+ Host: "127.0.0.1",
+ },
Features: agent_config.GetDefaultFeatures(),
}
AllowedDirectoriesMap map[string]struct{}
@@ -111,10 +121,20 @@ const (
ServerToken = ServerKey + agent_config.KeyDelimiter + "token"
ServerMetrics = ServerKey + agent_config.KeyDelimiter + "metrics"
ServerCommand = ServerKey + agent_config.KeyDelimiter + "command"
+ ServerBackoff = ServerKey + agent_config.KeyDelimiter + "backoff"
+
+ // viper keys used in config
+ BackoffKey = "backoff"
+ BackoffInitialInterval = BackoffKey + agent_config.KeyDelimiter + "initialinterval"
+ BackoffRandomizationFactor = BackoffKey + agent_config.KeyDelimiter + "randomizationfactor"
+ BackoffMultiplier = BackoffKey + agent_config.KeyDelimiter + "multiplier"
+ BackoffMaxInterval = BackoffKey + agent_config.KeyDelimiter + "maxinterval"
+ BackoffMaxElapsedTime = BackoffKey + agent_config.KeyDelimiter + "maxelapsedtime"
// viper keys used in config
APIKey = "api"
+ AgentAPIHost = APIKey + agent_config.KeyDelimiter + "host"
AgentAPIPort = APIKey + agent_config.KeyDelimiter + "port"
AgentAPICert = APIKey + agent_config.KeyDelimiter + "cert"
AgentAPIKey = APIKey + agent_config.KeyDelimiter + "key"
@@ -214,6 +234,11 @@ var (
DefaultValue: Defaults.Server.Command,
},
// API Config
+ &StringFlag{
+ Name: AgentAPIHost,
+ Usage: "The host used by the Agent API.",
+ DefaultValue: Defaults.AgentAPI.Host,
+ },
&IntFlag{
Name: AgentAPIPort,
Usage: "The desired port to use for nginx-agent to expose for HTTP traffic.",
diff --git a/src/core/config/types.go b/src/core/config/types.go
index a0a4bda35..234a2b90c 100644
--- a/src/core/config/types.go
+++ b/src/core/config/types.go
@@ -61,11 +61,21 @@ type Server struct {
Token string `mapstructure:"token" yaml:"-"`
Metrics string `mapstructure:"metrics" yaml:"-"`
Command string `mapstructure:"command" yaml:"-"`
- // This is internal and shouldnt be exposed as a flag
- Target string `mapstructure:"target" yaml:"-"`
+ // This is internal and shouldn't be exposed as a flag
+ Target string `mapstructure:"target" yaml:"-"`
+ Backoff Backoff `mapstructure:"backoff" yaml:"-"`
+}
+
+type Backoff struct {
+ InitialInterval time.Duration `mapstructure:"initial_interval" yaml:"-"`
+ RandomizationFactor float64 `mapstructure:"randomization_factor" yaml:"-"`
+ Multiplier float64 `mapstructure:"multiplier" yaml:"-"`
+ MaxInterval time.Duration `mapstructure:"max_interval" yaml:"-"`
+ MaxElapsedTime time.Duration `mapstructure:"max_elapsed_time" yaml:"-"`
}
type AgentAPI struct {
+ Host string `mapstructure:"host" yaml:"-"`
Port int `mapstructure:"port" yaml:"-"`
Cert string `mapstructure:"cert" yaml:"-"`
Key string `mapstructure:"key" yaml:"-"`
diff --git a/src/core/environment_test.go b/src/core/environment_test.go
index ce55abb43..780eccdd3 100644
--- a/src/core/environment_test.go
+++ b/src/core/environment_test.go
@@ -10,7 +10,6 @@ package core
import (
"errors"
"fmt"
- "io/ioutil"
"os"
"strings"
"testing"
@@ -926,7 +925,7 @@ func TestGetContainerID(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- mountInfoFile, err := ioutil.TempFile(os.TempDir(), "mountInfo-")
+ mountInfoFile, err := os.CreateTemp(os.TempDir(), "mountInfo-")
if err != nil {
t.Fatalf("Cannot create temporary file: %v", err)
}
@@ -1012,7 +1011,7 @@ func TestCGroupV1Check(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- mountInfoFile, err := ioutil.TempFile(os.TempDir(), "cGroupV1Check-")
+ mountInfoFile, err := os.CreateTemp(os.TempDir(), "cGroupV1Check-")
if err != nil {
t.Fatalf("Cannot create temporary file: %v", err)
}
diff --git a/src/core/metrics/collectors/nginx.go b/src/core/metrics/collectors/nginx.go
index 93a3539ab..0fb6522c6 100644
--- a/src/core/metrics/collectors/nginx.go
+++ b/src/core/metrics/collectors/nginx.go
@@ -16,10 +16,8 @@ import (
"github.com/nginx/agent/v2/src/core/metrics"
"github.com/nginx/agent/v2/src/core/metrics/sources"
log "github.com/sirupsen/logrus"
-)
-var (
- _ metrics.Collector = (*NginxCollector)(nil)
+ agent_config "github.com/nginx/agent/sdk/v2/agent/config"
)
type NginxCollector struct {
@@ -38,7 +36,7 @@ func NewNginxCollector(conf *config.Config, env core.Environment, collectorConf
dimensions.NginxAccessLogPaths = collectorConf.AccessLogs
return &NginxCollector{
- sources: buildSources(dimensions, binary, collectorConf),
+ sources: buildSources(dimensions, binary, collectorConf, conf),
buf: make(chan *metrics.StatsEntityWrapper, 65535),
dimensions: dimensions,
collectorConf: collectorConf,
@@ -47,24 +45,29 @@ func NewNginxCollector(conf *config.Config, env core.Environment, collectorConf
}
}
-func buildSources(dimensions *metrics.CommonDim, binary core.NginxBinary, collectorConf *metrics.NginxCollectorConfig) []metrics.NginxSource {
+func buildSources(dimensions *metrics.CommonDim, binary core.NginxBinary, collectorConf *metrics.NginxCollectorConfig, conf *config.Config) []metrics.NginxSource {
var nginxSources []metrics.NginxSource
// worker metrics
- nginxSources = append(nginxSources, sources.NewNginxProcess(dimensions, sources.OSSNamespace, binary))
- nginxSources = append(nginxSources, sources.NewNginxWorker(dimensions, sources.OSSNamespace, binary, sources.NewNginxWorkerClient()))
-
- if collectorConf.StubStatus != "" {
- nginxSources = append(nginxSources, sources.NewNginxOSS(dimensions, sources.OSSNamespace, collectorConf.StubStatus))
- nginxSources = append(nginxSources, sources.NewNginxAccessLog(dimensions, sources.OSSNamespace, binary, sources.OSSNginxType, collectorConf.CollectionInterval))
- nginxSources = append(nginxSources, sources.NewNginxErrorLog(dimensions, sources.OSSNamespace, binary, sources.OSSNginxType, collectorConf.CollectionInterval))
- } else if collectorConf.PlusAPI != "" {
- nginxSources = append(nginxSources, sources.NewNginxPlus(dimensions, sources.OSSNamespace, sources.PlusNamespace, collectorConf.PlusAPI, collectorConf.ClientVersion))
- nginxSources = append(nginxSources, sources.NewNginxAccessLog(dimensions, sources.OSSNamespace, binary, sources.PlusNginxType, collectorConf.CollectionInterval))
- nginxSources = append(nginxSources, sources.NewNginxErrorLog(dimensions, sources.OSSNamespace, binary, sources.PlusNginxType, collectorConf.CollectionInterval))
- } else {
- // if Plus API or stub_status are not setup, run the NGINX static collector and return nginx.status = 0
- log.Warnf("The NGINX API is not configured. Please configure it to collect NGINX metrics.")
- nginxSources = append(nginxSources, sources.NewNginxStatic(dimensions, sources.OSSNamespace))
+ if len(conf.Nginx.NginxCountingSocket) > 0 && conf.IsFeatureEnabled(agent_config.FeatureNginxCounting) {
+ nginxSources = append(nginxSources, sources.NewNginxProcess(dimensions, sources.OSSNamespace, binary))
+ }
+
+ if conf.IsFeatureEnabled(agent_config.FeatureMetrics) {
+ nginxSources = append(nginxSources, sources.NewNginxWorker(dimensions, sources.OSSNamespace, binary, sources.NewNginxWorkerClient()))
+
+ if collectorConf.StubStatus != "" {
+ nginxSources = append(nginxSources, sources.NewNginxOSS(dimensions, sources.OSSNamespace, collectorConf.StubStatus))
+ nginxSources = append(nginxSources, sources.NewNginxAccessLog(dimensions, sources.OSSNamespace, binary, sources.OSSNginxType, collectorConf.CollectionInterval))
+ nginxSources = append(nginxSources, sources.NewNginxErrorLog(dimensions, sources.OSSNamespace, binary, sources.OSSNginxType, collectorConf.CollectionInterval))
+ } else if collectorConf.PlusAPI != "" {
+ nginxSources = append(nginxSources, sources.NewNginxPlus(dimensions, sources.OSSNamespace, sources.PlusNamespace, collectorConf.PlusAPI, collectorConf.ClientVersion))
+ nginxSources = append(nginxSources, sources.NewNginxAccessLog(dimensions, sources.OSSNamespace, binary, sources.PlusNginxType, collectorConf.CollectionInterval))
+ nginxSources = append(nginxSources, sources.NewNginxErrorLog(dimensions, sources.OSSNamespace, binary, sources.PlusNginxType, collectorConf.CollectionInterval))
+ } else {
+ // if Plus API or stub_status are not setup, run the NGINX static collector and return nginx.status = 0
+ log.Warnf("The NGINX API is not configured. Please configure it to collect NGINX metrics.")
+ nginxSources = append(nginxSources, sources.NewNginxStatic(dimensions, sources.OSSNamespace))
+ }
}
return nginxSources
}
@@ -110,11 +113,11 @@ func (c *NginxCollector) UpdateConfig(config *config.Config) {
}
}
-func (c *NginxCollector) UpdateCollectorConfig(collectorConfig *metrics.NginxCollectorConfig) {
+func (c *NginxCollector) UpdateCollectorConfig(collectorConfig *metrics.NginxCollectorConfig, conf *config.Config) {
// If the metrics API has being enabled or disabled then we need to stop all nginx sources and rebuild them again
if c.collectorConf.StubStatus != collectorConfig.StubStatus || c.collectorConf.PlusAPI != collectorConfig.PlusAPI {
c.Stop()
- c.sources = buildSources(c.dimensions, c.binary, collectorConfig)
+ c.sources = buildSources(c.dimensions, c.binary, collectorConfig, conf)
}
c.collectorConf = collectorConfig
@@ -130,3 +133,9 @@ func (c *NginxCollector) Stop() {
func (c *NginxCollector) GetNginxId() string {
return c.dimensions.NginxId
}
+
+func (c *NginxCollector) UpdateSources() {
+ for _, nginxSource := range c.sources {
+ nginxSource.Update(c.dimensions, c.collectorConf)
+ }
+}
diff --git a/src/core/metrics/collectors/nginx_test.go b/src/core/metrics/collectors/nginx_test.go
index 72372fc31..805e0963e 100644
--- a/src/core/metrics/collectors/nginx_test.go
+++ b/src/core/metrics/collectors/nginx_test.go
@@ -47,8 +47,12 @@ var (
CollectionInterval: 1,
Mode: "aggregated",
},
+ Features: config.Defaults.Features,
+ Nginx: config.Nginx{
+ Debug: false,
+ NginxCountingSocket: "unix:/var/run/nginx-agent/nginx.sock",
+ },
}
-
collectorConfigNoApi = &metrics.NginxCollectorConfig{
BinPath: "/path/to/nginx",
NginxId: nginxId,
@@ -231,7 +235,7 @@ func TestNginxCollector_UpdateCollectorConfig(t *testing.T) {
dimensions: metrics.NewCommonDim(host, &config.Config{}, "123"),
}
- nginxCollector.UpdateCollectorConfig(&metrics.NginxCollectorConfig{StubStatus: "http://localhost:80/api"})
+ nginxCollector.UpdateCollectorConfig(&metrics.NginxCollectorConfig{StubStatus: "http://localhost:80/api"}, configuration)
// Verify that sources are stopped
mockNginxSource1.AssertExpectations(t)
diff --git a/src/core/metrics/metrics_util.go b/src/core/metrics/metrics_util.go
index 2cae8caf0..fef2ecd38 100644
--- a/src/core/metrics/metrics_util.go
+++ b/src/core/metrics/metrics_util.go
@@ -25,9 +25,11 @@ type Collector interface {
Collect(ctx context.Context, wg *sync.WaitGroup, m chan<- *StatsEntityWrapper)
UpdateConfig(config *config.Config)
}
+
type Source interface {
Collect(ctx context.Context, wg *sync.WaitGroup, m chan<- *StatsEntityWrapper)
}
+
type NginxSource interface {
Collect(ctx context.Context, wg *sync.WaitGroup, m chan<- *StatsEntityWrapper)
Update(dimensions *CommonDim, collectorConf *NginxCollectorConfig)
diff --git a/src/core/metrics/sources/disk.go b/src/core/metrics/sources/disk.go
index 909ee4a85..8880b75bf 100644
--- a/src/core/metrics/sources/disk.go
+++ b/src/core/metrics/sources/disk.go
@@ -39,7 +39,7 @@ func (c *Disk) Collect(ctx context.Context, wg *sync.WaitGroup, m chan<- *metric
usage, err := disk.Usage(part.Mountpoint)
if err != nil {
- c.logger.Log(fmt.Sprintf("Failed to get disk metrics, %v", err))
+ c.logger.Log(fmt.Sprintf("Failed to get disk metrics for mount point %s, %v", part.Mountpoint, err))
continue
}
diff --git a/src/core/metrics/sources/nginx_access_log.go b/src/core/metrics/sources/nginx_access_log.go
index 2e0627e91..27a6f0ff1 100644
--- a/src/core/metrics/sources/nginx_access_log.go
+++ b/src/core/metrics/sources/nginx_access_log.go
@@ -101,7 +101,6 @@ func NewNginxAccessLog(
nginxAccessLog.logFormats[logFile] = logFormat
go nginxAccessLog.logStats(logCTX, logFile, logFormat)
}
-
return nginxAccessLog
}
@@ -118,26 +117,61 @@ func (c *NginxAccessLog) Update(dimensions *metrics.CommonDim, collectorConf *me
if c.collectionInterval != collectorConf.CollectionInterval {
c.collectionInterval = collectorConf.CollectionInterval
+ // remove old access logs
+ // add new access logs
+ c.recreateLogs()
+ } else {
+ // add, remove or update existing log trailers
+ c.syncLogs()
+ }
- for f, fn := range c.logs {
- log.Infof("Removing access log tailer: %s", f)
- fn()
- delete(c.logs, f)
- delete(c.logFormats, f)
- }
+}
- logs := c.binary.GetAccessLogs()
+func (c *NginxAccessLog) recreateLogs() {
+ for f, fn := range c.logs {
+ c.stopTailer(f, fn)
+ }
- for logFile, logFormat := range logs {
- if _, ok := c.logs[logFile]; !ok {
- log.Infof("Adding access log tailer: %s", logFile)
- logCTX, fn := context.WithCancel(context.Background())
- c.logs[logFile] = fn
- c.logFormats[logFile] = logFormat
- go c.logStats(logCTX, logFile, logFormat)
- }
+ logs := c.binary.GetAccessLogs()
+
+ for logFile, logFormat := range logs {
+ c.startTailer(logFile, logFormat)
+ }
+}
+
+func (c *NginxAccessLog) syncLogs() {
+ logs := c.binary.GetAccessLogs()
+
+ for f, fn := range c.logs {
+ if _, ok := logs[f]; !ok {
+ c.stopTailer(f, fn)
}
}
+
+ for logFile, logFormat := range logs {
+ if _, ok := c.logs[logFile]; !ok {
+ c.startTailer(logFile, logFormat)
+ } else if c.logFormats[logFile] != logFormat {
+ // cancel tailer with old log format
+ c.logs[logFile]()
+ c.startTailer(logFile, logFormat)
+ }
+ }
+}
+
+func (c *NginxAccessLog) startTailer(logFile string, logFormat string) {
+ log.Infof("Adding access log tailer: %s", logFile)
+ logCTX, fn := context.WithCancel(context.Background())
+ c.logs[logFile] = fn
+ c.logFormats[logFile] = logFormat
+ go c.logStats(logCTX, logFile, logFormat)
+}
+
+func (c *NginxAccessLog) stopTailer(logFile string, cancelFunction context.CancelFunc) {
+ log.Infof("Removing access log tailer: %s", logFile)
+ cancelFunction()
+ delete(c.logs, logFile)
+ delete(c.logFormats, logFile)
}
func (c *NginxAccessLog) Stop() {
@@ -152,28 +186,6 @@ func (c *NginxAccessLog) Stop() {
func (c *NginxAccessLog) collectLogStats(ctx context.Context, m chan<- *metrics.StatsEntityWrapper) {
c.mu.Lock()
defer c.mu.Unlock()
- logs := c.binary.GetAccessLogs()
-
- if c.binary.UpdateLogs(c.logFormats, logs) {
- log.Info("Access logs updated")
- // cancel any removed access logs
- for f, fn := range c.logs {
- if _, ok := logs[f]; !ok {
- log.Infof("Removing access log tailer: %s", f)
- fn()
- delete(c.logs, f)
- }
- }
- // add any new ones
- for logFile, logFormat := range logs {
- if _, ok := c.logs[logFile]; !ok {
- log.Infof("Adding access log tailer: %s", logFile)
- logCTX, fn := context.WithCancel(context.Background())
- c.logs[logFile] = fn
- go c.logStats(logCTX, logFile, logFormat)
- }
- }
- }
for _, stat := range c.buf {
m <- stat
@@ -206,7 +218,6 @@ func (c *NginxAccessLog) logStats(ctx context.Context, logFile, logFormat string
tick := time.NewTicker(c.collectionInterval)
defer tick.Stop()
-
for {
select {
case d := <-data:
@@ -344,7 +355,7 @@ func (c *NginxAccessLog) logStats(ctx context.Context, logFile, logFormat string
case <-ctx.Done():
err := ctx.Err()
if err != nil {
- log.Errorf("NginxAccessLog: error in done context logStats %v", err)
+ log.Tracef("NginxAccessLog: error in done context logStats %v", err)
}
log.Info("NginxAccessLog: logStats are done")
return
diff --git a/src/core/metrics/sources/nginx_error_log.go b/src/core/metrics/sources/nginx_error_log.go
index ec336b4a3..ecd43e13e 100644
--- a/src/core/metrics/sources/nginx_error_log.go
+++ b/src/core/metrics/sources/nginx_error_log.go
@@ -121,55 +121,68 @@ func (c *NginxErrorLog) Update(dimensions *metrics.CommonDim, collectorConf *met
defer c.mu.Unlock()
c.baseDimensions = dimensions
+
if c.collectionInterval != collectorConf.CollectionInterval {
c.collectionInterval = collectorConf.CollectionInterval
+ // remove old error logs
+ // add new error logs
+ c.recreateLogs()
+ } else {
+ // add, remove or update existing log trailers
+ c.syncLogs()
+ }
+}
- for f, fn := range c.logs {
- log.Infof("Removing error log tailer: %s", f)
- fn()
- delete(c.logs, f)
- }
+func (c *NginxErrorLog) recreateLogs() {
+ for f, fn := range c.logs {
+ c.stopTailer(f, fn)
+ }
- logs := c.binary.GetErrorLogs()
+ logs := c.binary.GetErrorLogs()
- // add any new ones
- for logFile, logFormat := range logs {
- if _, ok := c.logs[logFile]; !ok {
- log.Infof("Adding error log tailer: %s", logFile)
- logCTX, fn := context.WithCancel(context.Background())
- c.logs[logFile] = fn
- c.logFormats[logFile] = logFormat
- go c.logStats(logCTX, logFile)
- }
- }
+ for logFile, logFormat := range logs {
+ c.startTailer(logFile, logFormat)
}
}
-func (c *NginxErrorLog) collectLogStats(ctx context.Context, m chan<- *metrics.StatsEntityWrapper) {
- c.mu.Lock()
- defer c.mu.Unlock()
+func (c *NginxErrorLog) syncLogs() {
logs := c.binary.GetErrorLogs()
- if c.binary.UpdateLogs(c.logFormats, logs) {
- log.Info("Error logs updated")
- // cancel any removed error logs
- for f, fn := range c.logs {
- if _, ok := logs[f]; !ok {
- log.Infof("Removing error log tailer: %s", f)
- fn()
- delete(c.logs, f)
- }
+ for f, fn := range c.logs {
+ if _, ok := logs[f]; !ok {
+ c.stopTailer(f, fn)
}
- // add any new ones
- for logFile := range logs {
- if _, ok := c.logs[logFile]; !ok {
- log.Infof("Adding error log tailer: %s", logFile)
- logCTX, fn := context.WithCancel(context.Background())
- c.logs[logFile] = fn
- go c.logStats(logCTX, logFile)
- }
+ }
+
+ for logFile, logFormat := range logs {
+ if _, ok := c.logs[logFile]; !ok {
+ c.startTailer(logFile, logFormat)
+ } else if c.logFormats[logFile] != logFormat {
+ // cancel tailer with old log format
+ c.logs[logFile]()
+ c.startTailer(logFile, logFormat)
}
}
+}
+
+func (c *NginxErrorLog) startTailer(logFile string, logFormat string) {
+ log.Infof("Adding error log tailer: %s", logFile)
+ logCTX, fn := context.WithCancel(context.Background())
+ c.logs[logFile] = fn
+ c.logFormats[logFile] = logFormat
+ go c.logStats(logCTX, logFile)
+}
+
+func (c *NginxErrorLog) stopTailer(logFile string, cancelFunction context.CancelFunc) {
+ log.Infof("Removing error log tailer: %s", logFile)
+ cancelFunction()
+ delete(c.logs, logFile)
+ delete(c.logFormats, logFile)
+}
+
+func (c *NginxErrorLog) collectLogStats(ctx context.Context, m chan<- *metrics.StatsEntityWrapper) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
for _, stat := range c.buf {
m <- stat
diff --git a/src/core/mock_pipe.go b/src/core/mock_pipe.go
index 18086511e..62501de7a 100644
--- a/src/core/mock_pipe.go
+++ b/src/core/mock_pipe.go
@@ -58,6 +58,10 @@ func (p *MockMessagePipe) Register(size int, plugins []Plugin, extensionPlugins
return nil
}
+func (p *MockMessagePipe) DeRegister(plugins []string) error {
+ return nil
+}
+
func (p *MockMessagePipe) Context() context.Context {
return p.ctx
}
@@ -112,3 +116,13 @@ func (p *MockMessagePipe) GetPlugins() []Plugin {
func (p *MockMessagePipe) GetExtensionPlugins() []ExtensionPlugin {
return p.extensionPlugins
}
+
+func (p *MockMessagePipe) IsPluginAlreadyRegistered(pluginName string) bool {
+ pluginAlreadyRegistered := false
+ for _, plugin := range p.GetPlugins() {
+ if plugin.Info().Name() == pluginName {
+ pluginAlreadyRegistered = true
+ }
+ }
+ return pluginAlreadyRegistered
+}
diff --git a/src/core/network/network.go b/src/core/network/network.go
index 9e4bb88e6..3915ef867 100644
--- a/src/core/network/network.go
+++ b/src/core/network/network.go
@@ -12,7 +12,7 @@ import (
"bytes"
"errors"
"fmt"
- "io/ioutil"
+ "io"
"net"
"os"
"os/exec"
@@ -37,8 +37,9 @@ const (
)
var (
- reOverflow = regexp.MustCompile(`\s*(\d+)\s*`)
- reTimesOverflowed = regexp.MustCompile("times the listen queue of a socket overflowed")
+ reOverflow = regexp.MustCompile(`\s*(\d+)\s*`)
+ reTimesOverflowed = regexp.MustCompile("times the listen queue of a socket overflowed")
+ reTimesOverflowedWithNstat = regexp.MustCompile("TcpExtListenOverflows")
)
type routeStruct struct {
@@ -57,31 +58,25 @@ type routeStruct struct {
// Get net overflow. The command (netstat) to get net overflow may not be available on all platforms
func GetNetOverflow() (float64, error) {
- const (
- Netstat = "netstat"
- NetstatFlags = "-s"
- )
overflows := 0.0
switch runtime.GOOS {
- case FREEBSD:
- return freeBsdSolaris(Netstat, NetstatFlags, overflows)
- case SOLARIS:
- return freeBsdSolaris(Netstat, NetstatFlags, overflows)
+ case FREEBSD, SOLARIS:
+ return getNetOverflowCmd("netstat", "-s", reTimesOverflowed, overflows)
case DARWIN:
return overflows, errors.New("this operating system is not implemented")
case LINUX:
- return overflows, errors.New("this operating system is not implemented")
+ return getNetOverflowCmd("nstat", "-az", reTimesOverflowedWithNstat, overflows)
default:
return overflows, errors.New("this operating system is not implemented")
}
}
-func freeBsdSolaris(netstat string, flags string, overflows float64) (float64, error) {
- netstatCmd := exec.Command(netstat, flags)
+func getNetOverflowCmd(cmd string, flags string, pattern *regexp.Regexp, overflows float64) (float64, error) {
+ netstatCmd := exec.Command(cmd, flags)
outbuf, err := netstatCmd.CombinedOutput()
if err != nil {
- errMsg := fmt.Sprintf("netstat not available: %v", err)
+ errMsg := fmt.Sprintf("%s not available: %v", cmd, err)
log.Debug(errMsg)
return overflows, errors.New(errMsg)
}
@@ -90,8 +85,9 @@ func freeBsdSolaris(netstat string, flags string, overflows float64) (float64, e
matches := []string{}
for scanner.Scan() {
line := scanner.Text()
- if reTimesOverflowed.MatchString(line) {
+ if pattern.MatchString(line) {
matches = append(matches, line)
+
}
}
so := strings.Join(matches, "\n")
@@ -195,7 +191,7 @@ func getDefaultNetworkInterfaceCrossPlatform() (string, error) {
}
defer f.Close()
- output, err := ioutil.ReadAll(f)
+ output, err := io.ReadAll(f)
if err != nil {
return "", fmt.Errorf("Can't read contents of %s", linuxFile)
}
@@ -296,20 +292,21 @@ func parseToLinuxRouteStruct(output []byte) (routeStruct, error) {
const (
destinationField = 1 // field containing hex destination address
)
- lineNumber := 0
scanner := bufio.NewScanner(bytes.NewReader(output))
// Skip header line
if !scanner.Scan() {
- return routeStruct{}, errors.New("Invalid linux route file")
+ if scanner.Err() == nil {
+ return routeStruct{}, errors.New("invalid linux route file: no header line")
+ } else {
+ return routeStruct{}, fmt.Errorf("invalid linux route file: %w", scanner.Err())
+ }
}
+ lineNumber := 0
+
for scanner.Scan() {
lineNumber++
- if lineNumber == 1 {
- // Skip header line.
- continue
- }
row := scanner.Text()
tokens := strings.Fields(strings.TrimSpace(row))
if len(tokens) < 11 {
@@ -329,25 +326,28 @@ func parseToLinuxRouteStruct(output []byte) (routeStruct, error) {
}
// The default interface is the one that's 0
- if destination != 0 {
- continue
+ if destination == 0 {
+ return routeStruct{
+ Iface: tokens[0],
+ Destination: tokens[1],
+ Gateway: tokens[2],
+ Flags: tokens[3],
+ RefCnt: tokens[4],
+ Use: tokens[5],
+ Metric: tokens[6],
+ Mask: tokens[7],
+ MTU: tokens[8],
+ Window: tokens[9],
+ IRTT: tokens[10],
+ }, nil
}
+ }
- return routeStruct{
- Iface: tokens[0],
- Destination: tokens[1],
- Gateway: tokens[2],
- Flags: tokens[3],
- RefCnt: tokens[4],
- Use: tokens[5],
- Metric: tokens[6],
- Mask: tokens[7],
- MTU: tokens[8],
- Window: tokens[9],
- IRTT: tokens[10],
- }, nil
+ if scanner.Err() == nil {
+ return routeStruct{}, errors.New("interface with default destination not found")
+ } else {
+ return routeStruct{}, fmt.Errorf("invalid linux route file: %w", scanner.Err())
}
- return routeStruct{}, errors.New("interface with default destination not found")
}
func ipv6ToStr(ip []byte) string {
diff --git a/src/core/network/network_test.go b/src/core/network/network_test.go
index 92aae6727..640cd23fa 100644
--- a/src/core/network/network_test.go
+++ b/src/core/network/network_test.go
@@ -21,8 +21,7 @@ func TestParseToLinuxRouteStruct(t *testing.T) {
err error
}{
{
- input: []byte(`
- Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
+ input: []byte(`Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
enp0s3 0002000A 00000000 0001 0 0 0 00FFFFFF 0 0 0
enp0s3 0202000A 00000000 0005 0 0 100 FFFFFFFF 0 0 0
enp0s3 00000000 0202000A 0003 0 0 100 00000000 0 0 0
@@ -44,15 +43,14 @@ func TestParseToLinuxRouteStruct(t *testing.T) {
err: nil,
},
{
- input: []byte(`
- Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT`),
+ input: []byte(`Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT`),
expected: routeStruct{},
err: errors.New("interface with default destination not found"),
},
{
input: []byte(``),
expected: routeStruct{},
- err: errors.New("Invalid linux route file"),
+ err: errors.New("invalid linux route file: no header line"),
},
}
for _, test := range tests {
diff --git a/src/core/nginx_test.go b/src/core/nginx_test.go
index 581f0d09c..d98f98406 100644
--- a/src/core/nginx_test.go
+++ b/src/core/nginx_test.go
@@ -18,12 +18,11 @@ import (
"strings"
"testing"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-
"github.com/nginx/agent/sdk/v2/proto"
"github.com/nginx/agent/sdk/v2/zip"
"github.com/nginx/agent/v2/src/core/config"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
const CONF_TEMPLATE = `
diff --git a/src/core/pipe.go b/src/core/pipe.go
index ab4f5c141..8f143f0f8 100644
--- a/src/core/pipe.go
+++ b/src/core/pipe.go
@@ -23,11 +23,13 @@ const (
type MessagePipeInterface interface {
Register(int, []Plugin, []ExtensionPlugin) error
+ DeRegister(plugins []string) error
Process(...*Message)
Run()
Context() context.Context
GetPlugins() []Plugin
GetExtensionPlugins() []ExtensionPlugin
+ IsPluginAlreadyRegistered(string) bool
}
type MessagePipe struct {
@@ -36,7 +38,7 @@ type MessagePipe struct {
extensionPlugins []ExtensionPlugin
ctx context.Context
cancel context.CancelFunc
- mu sync.Mutex
+ mu sync.RWMutex
bus messagebus.MessageBus
}
@@ -48,7 +50,7 @@ func NewMessagePipe(ctx context.Context) *MessagePipe {
extensionPlugins: make([]ExtensionPlugin, 0, MaxExtensionPlugins),
ctx: pipeContext,
cancel: pipeCancel,
- mu: sync.Mutex{},
+ mu: sync.RWMutex{},
}
}
@@ -81,14 +83,55 @@ func (p *MessagePipe) Register(size int, plugins []Plugin, extensionPlugins []Ex
}
extensionPluginsRegistered = append(extensionPluginsRegistered, *plugin.Info().name)
}
+ log.Debugf("The following core plugins have being registered: %q", pluginsRegistered)
+ log.Debugf("The following extension plugins have being registered: %q", extensionPluginsRegistered)
+ p.mu.Unlock()
+ return nil
+}
+
+func (p *MessagePipe) DeRegister(pluginNames []string) error {
+ p.mu.Lock()
+
+ var plugins []Plugin
+ for _, name := range pluginNames {
+ for _, plugin := range p.plugins {
+ if plugin.Info().Name() == name {
+ plugins = append(plugins, plugin)
+ }
+ }
+ }
+
+ for _, plugin := range plugins {
+ index := getIndex(plugin.Info().Name(), p.plugins)
+
+ if index != -1 {
+ p.plugins = append(p.plugins[:index], p.plugins[index+1:]...)
+
+ plugin.Close()
- log.Infof("The following core plugins have being registered: %q", pluginsRegistered)
- log.Infof("The following extension plugins have being registered: %q", extensionPluginsRegistered)
+ for _, subscription := range plugin.Subscriptions() {
+ err := p.bus.Unsubscribe(subscription, plugin.Process)
+ if err != nil {
+ return err
+ }
+ }
+ }
+
+ }
p.mu.Unlock()
return nil
}
+func getIndex(pluginName string, plugins []Plugin) int {
+ for index, plugin := range plugins {
+ if pluginName == plugin.Info().Name() {
+ return index
+ }
+ }
+ return -1
+}
+
func (p *MessagePipe) Process(messages ...*Message) {
for _, m := range messages {
select {
@@ -149,3 +192,15 @@ func (p *MessagePipe) initPlugins() {
r.Init(p)
}
}
+
+func (p *MessagePipe) IsPluginAlreadyRegistered(pluginName string) bool {
+ pluginAlreadyRegistered := false
+ for _, plugin := range p.GetPlugins() {
+ if plugin.Info().Name() == pluginName {
+ pluginAlreadyRegistered = true
+ }
+ }
+ log.Infof("pluginName: %v", pluginName)
+ log.Infof("pluginAlreadyRegistred: %v", pluginAlreadyRegistered)
+ return pluginAlreadyRegistered
+}
diff --git a/src/core/topics.go b/src/core/topics.go
index b0e095550..3c9f2fdb0 100644
--- a/src/core/topics.go
+++ b/src/core/topics.go
@@ -51,5 +51,6 @@ const (
ConfigRollbackResponse = "config.rollback.response"
DataplaneSoftwareDetailsUpdated = "dataplane.software.details.updated"
EnableExtension = "enable.extension"
+ EnableFeature = "enable.feature"
AgentAPIConfigApplyResponse = "agent.api.config.apply.response"
)
diff --git a/src/extensions/nginx-app-protect/monitoring/processor/nap.go b/src/extensions/nginx-app-protect/monitoring/processor/nap.go
index 28a8d7ec6..05fb6cf95 100644
--- a/src/extensions/nginx-app-protect/monitoring/processor/nap.go
+++ b/src/extensions/nginx-app-protect/monitoring/processor/nap.go
@@ -12,12 +12,14 @@ import (
"encoding/xml"
"errors"
"fmt"
+ "golang.org/x/text/language"
"regexp"
"strings"
"time"
"github.com/gogo/protobuf/types"
"github.com/sirupsen/logrus"
+ "golang.org/x/text/cases"
models "github.com/nginx/agent/sdk/v2/proto/events"
)
@@ -32,6 +34,7 @@ const (
encodedComma = "%2C"
violationNameSeparator = '_'
+ violationNamePrefix = "viol"
violationContextRequest = "request"
violationContextHeader = "header"
violationContextParameter = "parameter"
@@ -134,6 +137,8 @@ type Header struct {
Text string `xml:",chardata"`
Name string `xml:"header_name"`
Value string `xml:"header_value"`
+ ActualValue string `xml:"header_actual_value"`
+ MatchedValue string `xml:"header_matched_value"`
IsBase64Decoded bool `xml:"is_base64_decoded"`
}
@@ -169,26 +174,31 @@ type BADMSG struct {
// ParameterData and ParamData are both received when context == "parameter" | ""
// We receive either ParameterData or ParamData separately and not in the same XML message
// ParameterData and ParamData semantically represent the same thing (with ParameterData having more fields).
- ParameterData ParameterData `xml:"parameter_data"`
- ParamData ParamData `xml:"param_data"`
- ParamName string `xml:"param_name"`
- IsBase64Decoded bool `xml:"is_base64_decoded"`
- Header Header `xml:"header"`
- HeaderData Header `xml:"header_data"`
- Cookie Cookie `xml:"cookie"`
- CookieName string `xml:"cookie_name"`
- Buffer string `xml:"buffer"`
- SpecificDesc string `xml:"specific_desc"`
- Uri string `xml:"uri"`
- UriObjectData UriObjectData `xml:"object_data"`
- UriLength string `xml:"uri_len"`
- UriLengthLimit string `xml:"uri_len_limit"`
- DefinedLength string `xml:"defined_length"`
- DetectedLength string `xml:"detected_length"`
- TotalLen string `xml:"total_len"`
- TotalLenLimit string `xml:"total_len_limit"`
- Staging string `xml:"staging"`
- SigData []struct {
+ ParameterData ParameterData `xml:"parameter_data"`
+ ParamData ParamData `xml:"param_data"`
+ ParamName string `xml:"param_name"`
+ IsBase64Decoded bool `xml:"is_base64_decoded"`
+ Header Header `xml:"header"`
+ HeaderData Header `xml:"header_data"`
+ HeaderName string `xml:"header_name"`
+ HeaderLength string `xml:"header_len"`
+ HeaderLengthLimit string `xml:"header_len_limit"`
+ Cookie Cookie `xml:"cookie"`
+ CookieName string `xml:"cookie_name"`
+ CookieLength string `xml:"cookie_len"`
+ CookieLengthLimit string `xml:"cookie_len_limit"`
+ Buffer string `xml:"buffer"`
+ SpecificDesc string `xml:"specific_desc"`
+ Uri string `xml:"uri"`
+ UriObjectData UriObjectData `xml:"object_data"`
+ UriLength string `xml:"uri_len"`
+ UriLengthLimit string `xml:"uri_len_limit"`
+ DefinedLength string `xml:"defined_length"`
+ DetectedLength string `xml:"detected_length"`
+ TotalLen string `xml:"total_len"`
+ TotalLenLimit string `xml:"total_len_limit"`
+ Staging string `xml:"staging"`
+ SigData []struct {
Text string `xml:",chardata"`
SigID string `xml:"sig_id"`
BlockingMask string `xml:"blocking_mask"`
@@ -307,7 +317,6 @@ func (f *NAPConfig) getSecurityViolation(logger *logrus.Entry) *models.SecurityV
BotCategory: f.BotCategory,
BotSignatureName: f.BotSignatureName,
EnforcedBotAnomalies: f.EnforcedBotAnomalies,
- ViolationContexts: f.getViolationContext(),
Outcome: f.RequestOutcome,
OutcomeReason: f.RequestOutcomeReason,
URI: f.HTTPURI,
@@ -329,38 +338,37 @@ func (f *NAPConfig) getMetadata() (*models.Metadata, error) {
return NewMetadata(t, f.SupportID)
}
-func (f *NAPConfig) getViolationContext() string {
- contexts := []string{}
+func (f *NAPConfig) extractViolationContext() {
if f.ViolationDetailsXML != nil {
for i, v := range f.ViolationDetailsXML.RequestViolations.Violations {
+ if strings.ToLower(v.Context) == violationContextUrl {
+ f.ViolationDetailsXML.RequestViolations.Violations[i].Context = violationContextUri
+ }
if v.Context != "" {
- contexts = append(contexts, strings.ToLower(v.Context))
continue
}
if v.ViolName != "" {
f.ViolationDetailsXML.RequestViolations.Violations[i].Context = extractContextFromViolationName(v.ViolName)
- contexts = append(contexts, f.ViolationDetailsXML.RequestViolations.Violations[i].Context)
}
}
}
- return strings.Join(contexts, ",")
}
func extractContextFromViolationName(violationName string) string {
- if strings.Contains(violationName, strings.ToUpper(violationContextParameter)) {
+ if strings.Contains(strings.ToLower(violationName), violationContextParameter) {
return violationContextParameter
}
- if strings.Contains(violationName, strings.ToUpper(violationContextHeader)) {
+ if strings.Contains(strings.ToLower(violationName), violationContextHeader) {
return violationContextHeader
}
- if strings.Contains(violationName, strings.ToUpper(violationContextCookie)) {
+ if strings.Contains(strings.ToLower(violationName), violationContextCookie) {
return violationContextCookie
}
- if strings.Contains(violationName, strings.ToUpper(violationContextRequest)) {
+ if strings.Contains(strings.ToLower(violationName), violationContextRequest) {
return violationContextRequest
}
- if strings.Contains(violationName, strings.ToUpper(violationContextUri)) ||
- strings.Contains(violationName, strings.ToUpper(violationContextUrl)) {
+ if strings.Contains(strings.ToLower(violationName), violationContextUri) ||
+ strings.Contains(strings.ToLower(violationName), violationContextUrl) {
return violationContextUri
}
@@ -374,17 +382,19 @@ func (f *NAPConfig) getViolations(logger *logrus.Entry) []*models.ViolationData
return violations
}
+ f.extractViolationContext()
+
for _, v := range f.ViolationDetailsXML.RequestViolations.Violations {
violation := models.ViolationData{
Name: v.ViolName,
Context: strings.ToLower(v.Context),
}
+ contextualized := true
+ var name, value string
+ var isB64Decoded bool
switch strings.ToLower(v.Context) {
case violationContextParameter:
- var isB64Decoded bool
- var name, value string
-
if v.ParameterData != (ParameterData{}) {
isB64Decoded = v.ParameterData.IsBase64Decoded
name = v.ParameterData.Name
@@ -399,74 +409,31 @@ func (f *NAPConfig) getViolations(logger *logrus.Entry) []*models.ViolationData
} else {
logger.Warn("context is parameter but no Parameter data received")
}
-
- if isB64Decoded {
- violation.ContextData = &models.ContextData{
- Name: name,
- Value: value,
- }
- break
- }
-
- decodedName, err := base64.StdEncoding.DecodeString(name)
- if err != nil {
- logger.Errorf("could not decode the Paramater Name %s for %v", name, f.SupportID)
- break
- }
-
- decodedValue, err := base64.StdEncoding.DecodeString(value)
- if err != nil {
- logger.Errorf("could not decode the Paramater Value %s for %v", value, f.SupportID)
- break
- }
-
- violation.ContextData = &models.ContextData{
- Name: string(decodedName),
- Value: string(decodedValue),
- }
case violationContextHeader:
- var isB64Decoded bool
- var name, value string
-
if v.Header != (Header{}) {
isB64Decoded = v.Header.IsBase64Decoded
- name = v.Header.Name
- value = v.Header.Value
+ if v.Header.Name != "" || v.Header.Value != "" {
+ name = v.Header.Name
+ value = v.Header.Value
+ } else {
+ value = v.Header.Text
+ }
} else if v.HeaderData != (Header{}) {
isB64Decoded = v.HeaderData.IsBase64Decoded
name = v.HeaderData.Name
value = v.HeaderData.Value
- }
-
- if isB64Decoded {
- violation.ContextData = &models.ContextData{
- Name: name,
- Value: value,
+ } else if v.HeaderLength != "" {
+ isB64Decoded = true
+ decodedName, err := base64.StdEncoding.DecodeString(v.HeaderName)
+ if err != nil {
+ logger.Errorf("could not decode the Header %s for %v", v.HeaderName, f.SupportID)
+ break
}
- break
- }
-
- decodedName, err := base64.StdEncoding.DecodeString(name)
- if err != nil {
- logger.Errorf("could not decode the Header Name %s for %v", name, f.SupportID)
- break
- }
-
- decodedValue, err := base64.StdEncoding.DecodeString(value)
- if err != nil {
- logger.Errorf("could not decode the Header Value %s for %v", value, f.SupportID)
- break
- }
-
- violation.ContextData = &models.ContextData{
- Name: string(decodedName),
- Value: string(decodedValue),
+ name = string(decodedName)
+ value = fmt.Sprintf("Header length: %s, exceeds Header length limit: %s", v.HeaderLength, v.HeaderLengthLimit)
}
case violationContextCookie:
- var isB64Decoded bool
- var name, value string
-
- if v.Cookie != (Cookie{}) {
+ if v.Cookie != (Cookie{}) && v.CookieLength == "" {
isB64Decoded = v.Cookie.IsBase64Decoded
name = v.Cookie.Name
value = v.Cookie.Value
@@ -483,64 +450,49 @@ func (f *NAPConfig) getViolations(logger *logrus.Entry) []*models.ViolationData
}
name = v.SpecificDesc
value = string(decodedBuffer)
- }
-
- if isB64Decoded {
- violation.ContextData = &models.ContextData{
- Name: name,
- Value: value,
+ } else if v.CookieLength != "" {
+ isB64Decoded = true
+ decodedValue, err := base64.StdEncoding.DecodeString(v.Cookie.Text)
+ if err != nil {
+ logger.Errorf("could not decode the Cookie %s for %v", v.Cookie.Text, f.SupportID)
+ break
}
- break
+ name = fmt.Sprintf("Cookie length: %s, exceeds Cookie length limit: %s", v.CookieLength, v.CookieLengthLimit)
+ value = string(decodedValue)
}
-
- decodedName, err := base64.StdEncoding.DecodeString(name)
- if err != nil {
- logger.Errorf("could not decode the Cookie Name %s for %v", name, f.SupportID)
- break
- }
-
- decodedValue, err := base64.StdEncoding.DecodeString(value)
- if err != nil {
- logger.Errorf("could not decode the Cookie Value %s for %v", value, f.SupportID)
- break
- }
-
- violation.ContextData = &models.ContextData{
- Name: string(decodedName),
- Value: string(decodedValue),
- }
- case violationContextUrl, violationContextUri:
- var (
- name, value string
- isB64Decoded bool
- )
+ case violationContextUri:
if v.Uri != "" {
+ name = base64.StdEncoding.EncodeToString([]byte(violationContextUri))
value = v.Uri
} else if v.UriObjectData != (UriObjectData{}) {
+ name = base64.StdEncoding.EncodeToString([]byte(violationContextUri))
value = v.UriObjectData.Object
} else if v.UriLength != "" {
isB64Decoded = true
name = fmt.Sprintf("URI length: %s", v.UriLength)
value = fmt.Sprintf("URI length limit: %s", v.UriLengthLimit)
- }
-
- if isB64Decoded {
- violation.ContextData = &models.ContextData{
- Name: name,
- Value: value,
+ } else if v.HeaderData != (Header{}) {
+ isB64Decoded = true
+ decodedName, err := base64.StdEncoding.DecodeString(v.HeaderData.Name)
+ if err != nil {
+ logger.Errorf("uri context could not decode the Header name %s for %v", v.HeaderData.Name, f.SupportID)
+ break
}
- break
- }
-
- decodedValue, err := base64.StdEncoding.DecodeString(value)
- if err != nil {
- logger.Errorf("could not decode the URL Value %s for %v", value, f.SupportID)
- break
+ decodedActualValue, err := base64.StdEncoding.DecodeString(v.HeaderData.ActualValue)
+ if err != nil {
+ logger.Errorf("uri context could not decode the Actual Header value %s for %v", v.HeaderData.ActualValue, f.SupportID)
+ break
+ }
+ decodedMatchedValue, err := base64.StdEncoding.DecodeString(v.HeaderData.MatchedValue)
+ if err != nil {
+ logger.Errorf("uri context could not decode the Matched Header value %s for %v", v.HeaderData.MatchedValue, f.SupportID)
+ break
+ }
+ name = string(decodedName)
+ value = fmt.Sprintf("actual header value: %s. matched header value: %s", string(decodedActualValue), string(decodedMatchedValue))
}
-
- violation.ContextData = &models.ContextData{Name: name, Value: string(decodedValue)}
case violationContextRequest:
- var name, value string
+ isB64Decoded = true
if v.DefinedLength != "" {
name = fmt.Sprintf("Defined length: %s", v.DefinedLength)
value = fmt.Sprintf("Detected length: %s", v.DetectedLength)
@@ -548,8 +500,31 @@ func (f *NAPConfig) getViolations(logger *logrus.Entry) []*models.ViolationData
name = fmt.Sprintf("Total length: %s", v.TotalLen)
value = fmt.Sprintf("Total length limit: %s", v.TotalLenLimit)
}
+ default:
+ contextualized = false
+ }
- violation.ContextData = &models.ContextData{Name: name, Value: value}
+ if contextualized {
+ if isB64Decoded {
+ name, value = populateNameValue(violation.Name, name, value)
+ violation.ContextData = &models.ContextData{
+ Name: name,
+ Value: value,
+ }
+ } else {
+ decodedName, err := base64.StdEncoding.DecodeString(name)
+ if err != nil {
+ logger.Errorf("could not decode the %s Name %s for %v", v.Context, name, f.SupportID)
+ } else {
+ decodedValue, err := base64.StdEncoding.DecodeString(value)
+ if err != nil {
+ logger.Errorf("could not decode the %s Value %s for %v", v.Context, value, f.SupportID)
+ } else {
+ name, value = populateNameValue(violation.Name, string(decodedName), string(decodedValue))
+ violation.ContextData = &models.ContextData{Name: name, Value: value}
+ }
+ }
+ }
}
for _, s := range v.SigData {
@@ -574,6 +549,33 @@ func (f *NAPConfig) getViolations(logger *logrus.Entry) []*models.ViolationData
return violations
}
+func populateNameValue(violationName, dataName, dataValue string) (name string, value string) {
+ if dataName != "" && dataValue != "" {
+ name = dataName
+ value = dataValue
+ return
+ }
+ name = violationNameToDataName(violationName)
+ if dataName == "" && dataValue != "" {
+ value = dataValue
+ return
+ }
+ if dataName != "" && dataValue == "" {
+ value = dataName
+ return
+ }
+ return
+}
+
+func violationNameToDataName(violationName string) string {
+ c := cases.Title(language.English)
+ parts := strings.Split(strings.ToLower(violationName), string(violationNameSeparator))
+ if parts[0] != violationNamePrefix {
+ return c.String(strings.Join(parts, " "))
+ }
+ return c.String(strings.Join(parts[1:], " "))
+}
+
// Parse the NAP date time string into a Proto Time type.
func parseNAPDateTime(raw string) (*types.Timestamp, error) {
t, err := time.Parse(napDateTimeLayout, raw)
@@ -591,6 +593,12 @@ func parseNAP(logEntry string, logger *logrus.Entry) (*NAPConfig, error) {
values := strings.Split(logEntry, ",")
+ lenV := len(values)
+ lenFK := len(logFormatKeys)
+ if lenV != lenFK {
+ return nil, fmt.Errorf("log line values does not match expected values. expecting %d values got %d values", lenFK, lenV)
+ }
+
for idx, key := range logFormatKeys {
err := setValue(&waf, key, values[idx], logger)
if err != nil {
diff --git a/src/extensions/nginx-app-protect/monitoring/processor/nap_test.go b/src/extensions/nginx-app-protect/monitoring/processor/nap_test.go
index ecb915af7..dfe69c47c 100644
--- a/src/extensions/nginx-app-protect/monitoring/processor/nap_test.go
+++ b/src/extensions/nginx-app-protect/monitoring/processor/nap_test.go
@@ -10,6 +10,7 @@ package processor
import (
"fmt"
"os"
+ "regexp"
"testing"
"github.com/sirupsen/logrus"
@@ -82,3 +83,87 @@ func TestParseNAPCommaEncoding(t *testing.T) {
})
}
}
+
+func TestPopulateNameValue(t *testing.T) {
+ testCases := []struct {
+ testName string
+ violationName string
+ dataName string
+ dataValue string
+ expName string
+ expValue string
+ }{
+ {
+ testName: "empty data name, empty data value",
+ violationName: "VIOL_TEST1",
+ dataName: "",
+ dataValue: "",
+ expName: "Test1",
+ expValue: "",
+ },
+ {
+ testName: "empty data name, provided data value",
+ violationName: "VIOL_TEST2",
+ dataName: "",
+ dataValue: "some_value",
+ expName: "Test2",
+ expValue: "some_value",
+ },
+ {
+ testName: "provided data name, empty data value",
+ violationName: "TEST_3",
+ dataName: "some_name",
+ dataValue: "",
+ expName: "Test 3",
+ expValue: "some_name",
+ },
+ {
+ testName: "provided data name, provided data value",
+ violationName: "VIOL_TEST_3",
+ dataName: "some_name",
+ dataValue: "some_value",
+ expName: "some_name",
+ expValue: "some_value",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.testName, func(t *testing.T) {
+ name, value := populateNameValue(testCase.violationName, testCase.dataName, testCase.dataValue)
+ assert.Equal(t, testCase.expName, name)
+ assert.Equal(t, testCase.expValue, value)
+ })
+ }
+}
+
+func TestGetEvent(t *testing.T) {
+ testCases := []struct {
+ testName string
+ hostPattern *regexp.Regexp
+ logger *logrus.Entry
+ }{
+ {
+ testName: "nil host pattern, valid logger",
+ hostPattern: nil,
+ logger: logrus.New().WithFields(nil),
+ },
+ {
+ testName: "valid host pattern, nil logger",
+ hostPattern: regexp.MustCompile("ˆhost"),
+ logger: nil,
+ },
+ {
+ testName: "nil host pattern, nil logger",
+ hostPattern: nil,
+ logger: nil,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.testName, func(t *testing.T) {
+ napCfg := &NAPConfig{}
+ _, err := napCfg.GetEvent(testCase.hostPattern, testCase.logger)
+ assert.NoError(t, err)
+ })
+ }
+}
diff --git a/src/extensions/nginx-app-protect/monitoring/processor/processor_test.go b/src/extensions/nginx-app-protect/monitoring/processor/processor_test.go
index b980860b3..ef09de170 100644
--- a/src/extensions/nginx-app-protect/monitoring/processor/processor_test.go
+++ b/src/extensions/nginx-app-protect/monitoring/processor/processor_test.go
@@ -8,8 +8,10 @@
package processor
import (
+ "bytes"
"context"
"os"
+ "strings"
"sync"
"testing"
"time"
@@ -29,11 +31,12 @@ const (
func TestNAPProcess(t *testing.T) {
testCases := []struct {
- testName string
- testFile string
- expected *pb.SecurityViolationEvent
- isNegative bool
- fileExists bool
+ testName string
+ testFile string
+ expected *pb.SecurityViolationEvent
+ isNegative bool
+ fileExists bool
+ errorLogged string
}{
{
testName: "PassedEvent",
@@ -71,7 +74,6 @@ func TestNAPProcess(t *testing.T) {
BotCategory: "HTTP Library",
EnforcedBotAnomalies: "N/A",
BotSignatureName: "curl",
- ViolationContexts: "parameter,,parameter",
ViolationsData: []*pb.ViolationData{
{
Name: "VIOL_ATTACK_SIGNATURE",
@@ -153,34 +155,37 @@ func TestNAPProcess(t *testing.T) {
BotCategory: "HTTP Library",
EnforcedBotAnomalies: "N/A",
BotSignatureName: "curl",
- ViolationContexts: "cookie,cookie,cookie,cookie",
ViolationsData: []*pb.ViolationData{
{
Name: "VIOL_ASM_COOKIE_MODIFIED",
Context: "cookie",
ContextData: &pb.ContextData{
- Name: "TS0144e914_1",
+ Name: "Asm Cookie Modified",
+ Value: "TS0144e914_1",
},
},
{
Name: "VIOL_ASM_COOKIE_MODIFIED",
Context: "cookie",
ContextData: &pb.ContextData{
- Name: "TS0144e914_31",
+ Name: "Asm Cookie Modified",
+ Value: "TS0144e914_31",
},
},
{
Name: "VIOL_ASM_COOKIE_MODIFIED",
Context: "cookie",
ContextData: &pb.ContextData{
- Name: "TS0144e914_1",
+ Name: "Asm Cookie Modified",
+ Value: "TS0144e914_1",
},
},
{
Name: "VIOL_ASM_COOKIE_MODIFIED",
Context: "cookie",
ContextData: &pb.ContextData{
- Name: "TS0144e914_31",
+ Name: "Asm Cookie Modified",
+ Value: "TS0144e914_31",
},
},
},
@@ -227,12 +232,12 @@ func TestNAPProcess(t *testing.T) {
BotCategory: "HTTP Library",
EnforcedBotAnomalies: "N/A",
BotSignatureName: "curl",
- ViolationContexts: "parameter",
ViolationsData: []*pb.ViolationData{
{
Name: "VIOL_ATTACK_SIGNATURE",
Context: "parameter",
ContextData: &pb.ContextData{
+ Name: "Attack Signature",
Value: "f5paramautotest>",
},
Signatures: []*pb.SignatureData{
@@ -245,6 +250,94 @@ func TestNAPProcess(t *testing.T) {
},
},
},
+ {
+ Name: "VIOL_PARAMETER_REPEATED",
+ Context: "parameter",
+ ContextData: &pb.ContextData{
+ Name: "a",
+ Value: "2",
+ },
+ },
+ {
+ Name: "VIOL_PARAMETER_MULTIPART_NULL_VALUE",
+ Context: "parameter",
+ ContextData: &pb.ContextData{
+ Name: "parameter",
+ Value: "\x00",
+ },
+ },
+ {
+ Name: "VIOL_PARAMETER_EMPTY_VALUE",
+ Context: "parameter",
+ ContextData: &pb.ContextData{
+ Name: "Parameter Empty Value",
+ Value: "a",
+ },
+ },
+ {
+ Name: "VIOL_PARAMETER_VALUE_REGEXP",
+ Context: "parameter",
+ ContextData: &pb.ContextData{
+ Name: "r",
+ Value: "2",
+ },
+ },
+ {
+ Name: "VIOL_PARAMETER_NUMERIC_VALUE",
+ Context: "parameter",
+ ContextData: &pb.ContextData{
+ Name: "a",
+ Value: "2",
+ },
+ },
+ {
+ Name: "VIOL_PARAMETER_DATA_TYPE",
+ Context: "parameter",
+ ContextData: &pb.ContextData{
+ Name: "a",
+ Value: "f",
+ },
+ },
+ {
+ Name: "VIOL_PARAMETER_VALUE_LENGTH",
+ Context: "parameter",
+ ContextData: &pb.ContextData{
+ Name: "r",
+ Value: "3948394839489898",
+ },
+ },
+ {
+ Name: "VIOL_PARAMETER_DYNAMIC_VALUE",
+ Context: "parameter",
+ ContextData: &pb.ContextData{
+ Name: "r",
+ Value: "2",
+ },
+ },
+ {
+ Name: "VIOL_PARAMETER_STATIC_VALUE",
+ Context: "parameter",
+ ContextData: &pb.ContextData{
+ Name: "a",
+ Value: "f",
+ },
+ },
+ {
+ Name: "VIOL_PARAMETER_ARRAY_VALUE",
+ Context: "parameter",
+ ContextData: &pb.ContextData{
+ Name: "r",
+ Value: "1m\b",
+ },
+ },
+ {
+ Name: "VIOL_PARAMETER_LOCATION",
+ Context: "parameter",
+ ContextData: &pb.ContextData{
+ Name: "a",
+ Value: "12",
+ },
+ },
},
SystemID: "",
InstanceTags: "",
@@ -289,7 +382,6 @@ func TestNAPProcess(t *testing.T) {
BotCategory: "HTTP Library",
EnforcedBotAnomalies: "N/A",
BotSignatureName: "curl",
- ViolationContexts: "parameter,parameter",
ViolationsData: []*pb.ViolationData{
{
Name: "VIOL_PARAMETER",
@@ -351,7 +443,6 @@ func TestNAPProcess(t *testing.T) {
BotCategory: "HTTP Library",
EnforcedBotAnomalies: "N/A",
BotSignatureName: "curl",
- ViolationContexts: "parameter",
ViolationsData: []*pb.ViolationData{
{
Name: "VIOL_JSON_MALFORMED",
@@ -405,7 +496,6 @@ func TestNAPProcess(t *testing.T) {
BotCategory: "HTTP Library",
EnforcedBotAnomalies: "N/A",
BotSignatureName: "curl",
- ViolationContexts: "header",
ViolationsData: []*pb.ViolationData{
{
Name: "VIOL_ATTACK_SIGNATURE",
@@ -459,7 +549,6 @@ func TestNAPProcess(t *testing.T) {
BotCategory: "HTTP Library",
EnforcedBotAnomalies: "N/A",
BotSignatureName: "curl",
- ViolationContexts: "",
ViolationsData: []*pb.ViolationData{
{
Name: "VIOL_ATTACK_SIGNATURE",
@@ -538,7 +627,6 @@ func TestNAPProcess(t *testing.T) {
BotCategory: "HTTP Library",
EnforcedBotAnomalies: "N/A",
BotSignatureName: "curl",
- ViolationContexts: "cookie,cookie",
ViolationsData: []*pb.ViolationData{
{
Name: "VIOL_COOKIE_MALFORMED",
@@ -556,6 +644,14 @@ func TestNAPProcess(t *testing.T) {
Value: "choco",
},
},
+ {
+ Name: "VIOL_COOKIE_EXPIRED",
+ Context: "cookie",
+ ContextData: &pb.ContextData{
+ Name: "Cookie Expired",
+ Value: "TS0142ff11",
+ },
+ },
},
SystemID: "",
InstanceTags: "",
@@ -600,7 +696,6 @@ func TestNAPProcess(t *testing.T) {
BotCategory: "HTTP Library",
EnforcedBotAnomalies: "N/A",
BotSignatureName: "curl",
- ViolationContexts: "parameter,parameter,parameter,header",
ViolationsData: []*pb.ViolationData{
{
Name: "VIOL_PARAMETER_VALUE_METACHAR",
@@ -614,8 +709,8 @@ func TestNAPProcess(t *testing.T) {
Name: "VIOL_PARAMETER_NAME_METACHAR",
Context: "parameter",
ContextData: &pb.ContextData{
- Name: "x@",
- Value: "",
+ Name: "Parameter Name Metachar",
+ Value: "x@",
},
},
{
@@ -678,7 +773,6 @@ func TestNAPProcess(t *testing.T) {
BotCategory: "HTTP Library",
EnforcedBotAnomalies: "N/A",
BotSignatureName: "curl",
- ViolationContexts: "request,request",
ViolationsData: []*pb.ViolationData{
{
Name: "VIOL_REQUEST_MAX_LENGTH",
@@ -740,13 +834,12 @@ func TestNAPProcess(t *testing.T) {
BotCategory: "HTTP Library",
EnforcedBotAnomalies: "N/A",
BotSignatureName: "curl",
- ViolationContexts: "uri,uri,url",
ViolationsData: []*pb.ViolationData{
{
Name: "VIOL_URL_METACHAR",
Context: "uri",
ContextData: &pb.ContextData{
- Name: "",
+ Name: "uri",
Value: "/;shutdown",
},
},
@@ -760,12 +853,179 @@ func TestNAPProcess(t *testing.T) {
},
{
Name: "VIOL_JSON_MALFORMED",
- Context: "url",
+ Context: "uri",
ContextData: &pb.ContextData{
- Name: "",
+ Name: "uri",
Value: "/",
},
},
+ {
+ Name: "VIOL_URL",
+ Context: "uri",
+ ContextData: &pb.ContextData{
+ Name: "Url",
+ Value: "",
+ },
+ },
+ },
+ SystemID: "",
+ InstanceTags: "",
+ InstanceGroup: "",
+ DisplayName: "",
+ ParentHostname: "",
+ },
+ },
+ {
+ testName: "violation: cookie length",
+ testFile: "./testdata/xml_cookie_length.log.txt",
+ expected: &pb.SecurityViolationEvent{
+ PolicyName: "app_protect_default_policy",
+ SupportID: "3255056874564592514",
+ Outcome: "REJECTED",
+ OutcomeReason: "SECURITY_WAF_VIOLATION",
+ BlockingExceptionReason: "N/A",
+ Method: "GET",
+ Protocol: "HTTP",
+ XForwardedForHeaderValue: "N/A",
+ URI: "/",
+ Request: "GET /?a=
+
+
+
+
+
+
+
+
+
+
+