From ecf98ee5dd115ff27edae5ffc6710138553b3ac9 Mon Sep 17 00:00:00 2001 From: Shivaprasad Date: Thu, 2 Mar 2023 11:53:18 +0530 Subject: [PATCH 01/72] fix: kube deployment char limit --- .gitignore | 5 +++-- modules/firehose/config.go | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 38bb345a..4cd243d3 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ tmp/ expt/ -entropy.dev.yaml +entropy*.dev.yaml +entropy*.dev.yml -requests.http \ No newline at end of file +requests.http diff --git a/modules/firehose/config.go b/modules/firehose/config.go index de380e98..29d57d5d 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -1,6 +1,7 @@ package firehose import ( + "crypto/sha256" _ "embed" "encoding/json" "fmt" @@ -99,5 +100,17 @@ func (mc *moduleConfig) JSON() []byte { } func generateFirehoseName(r resource.Resource) string { - return fmt.Sprintf("%s-%s-firehose", r.Project, r.Name) + const ( + suffix = "-firehose" + kubeNameMaxLen = 63 + ) + + name := fmt.Sprintf("%s-%s", r.Project, r.Name) + if len(name)+len(suffix) >= kubeNameMaxLen { + val := sha256.Sum256([]byte(name)) + hash := fmt.Sprintf("%x", val) + name = fmt.Sprintf("%s-%s", name[:48], hash[:5]) + } + + return name + suffix } From d48ba77e1f0c83e9a6692893047de15aba5400b1 Mon Sep 17 00:00:00 2001 From: Shivaprasad Date: Fri, 3 Mar 2023 17:07:10 +0530 Subject: [PATCH 02/72] feat: add deployment_id feature --- modules/firehose/config.go | 43 +++++++++++++++++------- modules/kubernetes/config_schema.json | 4 +-- modules/kubernetes/config_schema_test.go | 2 +- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index 29d57d5d..55a2166b 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -12,7 +12,10 @@ import ( "github.com/odpf/entropy/pkg/helm" ) -const firehoseConsumerIDStartingSequence = "0001" +const ( + firehoseConsumerIDStartingSequence = "0001" + kubeDeploymentNameLengthLimit = 63 +) var ( //go:embed schema/config.json @@ -35,6 +38,7 @@ type moduleConfig struct { KafkaTopic string `json:"kafka_topic"` KafkaConsumerID string `json:"kafka_consumer_id"` EnvVariables map[string]string `json:"env_variables"` + DeploymentID string `json:"deployment_id,omitempty"` } `json:"firehose"` } @@ -45,7 +49,8 @@ func (mc *moduleConfig) validateAndSanitize(r resource.Resource) error { } if mc.Firehose.KafkaConsumerID == "" { - mc.Firehose.KafkaConsumerID = fmt.Sprintf("%s-%s", generateFirehoseName(r), firehoseConsumerIDStartingSequence) + mc.Firehose.KafkaConsumerID = fmt.Sprintf("%s-%s-%s-%s", + r.Project, r.Name, "-firehose-", firehoseConsumerIDStartingSequence) } return nil @@ -59,8 +64,13 @@ func (mc *moduleConfig) GetHelmReleaseConfig(r resource.Resource) (*helm.Release } defaults := output.Defaults + relName, err := sanitiseDeploymentID(r, *mc) + if err != nil { + return nil, err + } + rc := helm.DefaultReleaseConfig() - rc.Name = generateFirehoseName(r) + rc.Name = relName rc.Repository = defaults.ChartRepository rc.Chart = defaults.ChartName rc.Namespace = defaults.Namespace @@ -99,18 +109,25 @@ func (mc *moduleConfig) JSON() []byte { return b } -func generateFirehoseName(r resource.Resource) string { - const ( - suffix = "-firehose" - kubeNameMaxLen = 63 - ) +func sanitiseDeploymentID(r resource.Resource, mc moduleConfig) (string, error) { + releaseName := mc.Firehose.DeploymentID + if len(releaseName) == 0 { + releaseName = generateSafeReleaseName(r.Project, r.Name) + } else if len(releaseName) >= kubeDeploymentNameLengthLimit { + return "", errors.ErrInvalid.WithMsgf("deployment_id must be shorter than 63 chars") + } + return releaseName, nil +} + +func generateSafeReleaseName(project, name string) string { + const suffix = "-firehose" - name := fmt.Sprintf("%s-%s", r.Project, r.Name) - if len(name)+len(suffix) >= kubeNameMaxLen { - val := sha256.Sum256([]byte(name)) + releaseName := fmt.Sprintf("%s-%s", project, name) + if len(releaseName)+len(suffix) >= kubeDeploymentNameLengthLimit { + val := sha256.Sum256([]byte(releaseName)) hash := fmt.Sprintf("%x", val) - name = fmt.Sprintf("%s-%s", name[:48], hash[:5]) + releaseName = fmt.Sprintf("%s-%s", releaseName[:48], hash[:5]) } - return name + suffix + return releaseName + suffix } diff --git a/modules/kubernetes/config_schema.json b/modules/kubernetes/config_schema.json index 89e55ed5..dc315cf2 100644 --- a/modules/kubernetes/config_schema.json +++ b/modules/kubernetes/config_schema.json @@ -19,7 +19,7 @@ "client_certificate": { "type": "string" }, - "client_ca_certificate": { + "cluster_ca_certificate": { "type": "string" } }, @@ -48,7 +48,7 @@ }, "then": { "required": [ - "client_ca_certificate" + "cluster_ca_certificate" ] } } diff --git a/modules/kubernetes/config_schema_test.go b/modules/kubernetes/config_schema_test.go index ab3e8a58..0128a370 100644 --- a/modules/kubernetes/config_schema_test.go +++ b/modules/kubernetes/config_schema_test.go @@ -70,7 +70,7 @@ func TestModule_KubernetesJSONSchema(t *testing.T) { "insecure": false, "client_key": "c_key", "client_certificate": "c_cert", - "client_ca_certificate": "ca_cert" + "cluster_ca_certificate": "ca_cert" }`, shouldBeValid: true, }, From 4867aa2de14b62516ba6f4ebe026274ba5cb2f20 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Tue, 14 Mar 2023 15:46:08 +0530 Subject: [PATCH 03/72] refactor: rename to goto (#2) chore: change odpf references to goto --- .golangci.yml | 4 +- .goreleaser.yml | 14 +- Makefile | 26 +- README.md | 14 +- buf.gen.yaml | 25 + cli/action.go | 6 +- cli/cli.go | 2 +- cli/client.go | 2 +- cli/config.go | 8 +- cli/logs.go | 6 +- cli/migrate.go | 2 +- cli/resource.go | 6 +- cli/serve.go | 22 +- cli/version.go | 2 +- core/core.go | 8 +- core/core_test.go | 6 +- core/mocks/async_worker.go | 19 +- core/mocks/driver.go | 21 +- core/mocks/loggable_module.go | 21 +- core/mocks/module_registry.go | 19 +- core/mocks/module_service.go | 21 +- core/mocks/module_store.go | 19 +- core/mocks/resource_store.go | 19 +- core/module/action.go | 2 +- core/module/driver.go | 2 +- core/module/module.go | 2 +- core/module/service.go | 4 +- core/read.go | 6 +- core/read_test.go | 8 +- core/resource/resource.go | 2 +- core/resource/resource_test.go | 4 +- core/resource/state_test.go | 2 +- core/sync.go | 8 +- core/write.go | 6 +- core/write_test.go | 12 +- docs/concepts/resource-life-cycle.md | 2 +- docs/installation.md | 6 +- docs/modules/firehose.md | 2 +- docs/modules/kubernetes.md | 2 +- go.mod | 117 +- go.sum | 296 +- internal/server/server.go | 22 +- internal/server/serverutils/grpcerror.go | 2 +- internal/server/v1/mocks/module_service.go | 19 +- internal/server/v1/mocks/resource_service.go | 21 +- internal/server/v1/modules/mappers.go | 6 +- internal/server/v1/modules/server.go | 6 +- internal/server/v1/modules/server_test.go | 4 +- internal/server/v1/resources/mappers.go | 6 +- internal/server/v1/resources/server.go | 8 +- internal/server/v1/resources/server_test.go | 8 +- internal/store/postgres/module_model.go | 4 +- internal/store/postgres/module_store.go | 4 +- internal/store/postgres/resource_model.go | 2 +- internal/store/postgres/resource_store.go | 4 +- internal/store/postgres/revision_model.go | 2 +- internal/store/postgres/revision_store.go | 4 +- internal/store/postgres/utils.go | 4 +- main.go | 2 +- modules/firehose/config.go | 6 +- modules/firehose/kafka/consumer.go | 2 +- modules/firehose/log.go | 8 +- modules/firehose/module.go | 4 +- modules/firehose/output.go | 8 +- modules/firehose/plan.go | 6 +- modules/firehose/plan_test.go | 6 +- modules/firehose/sync.go | 16 +- modules/kubernetes/kubernetes.go | 8 +- modules/registry.go | 4 +- modules/registry_test.go | 8 +- pkg/common/common.go | 24 + pkg/errors/errors_test.go | 2 +- pkg/helm/client.go | 2 +- pkg/helm/release.go | 2 +- pkg/kube/client.go | 2 +- pkg/kube/client_test.go | 2 +- pkg/version/version.go | 3 +- pkg/worker/example/main.go | 6 +- pkg/worker/job_test.go | 4 +- pkg/worker/mocks/job_queue.go | 19 +- pkg/worker/pgq/pgq.go | 4 +- pkg/worker/pgq/pgq_utils.go | 2 +- pkg/worker/worker.go | 2 +- pkg/worker/worker_test.go | 6 +- proto/entropy.swagger.yaml | 564 +++ proto/gotocompany/common/v1/service.pb.go | 357 ++ proto/gotocompany/common/v1/service.pb.gw.go | 171 + .../common/v1/service.pb.validate.go | 432 +++ .../gotocompany/common/v1/service_grpc.pb.go | 101 + .../gotocompany/entropy/v1beta1/module.pb.go | 922 +++++ .../entropy/v1beta1/module.pb.gw.go | 583 +++ .../entropy/v1beta1/module.pb.validate.go | 1421 ++++++++ .../entropy/v1beta1/module_grpc.pb.go | 245 ++ .../entropy/v1beta1/resource.pb.go | 2151 +++++++++++ .../entropy/v1beta1/resource.pb.gw.go | 921 +++++ .../entropy/v1beta1/resource.pb.validate.go | 3134 +++++++++++++++++ .../entropy/v1beta1/resource_grpc.pb.go | 381 ++ 97 files changed, 12081 insertions(+), 361 deletions(-) create mode 100644 buf.gen.yaml create mode 100644 pkg/common/common.go create mode 100644 proto/entropy.swagger.yaml create mode 100644 proto/gotocompany/common/v1/service.pb.go create mode 100644 proto/gotocompany/common/v1/service.pb.gw.go create mode 100644 proto/gotocompany/common/v1/service.pb.validate.go create mode 100644 proto/gotocompany/common/v1/service_grpc.pb.go create mode 100644 proto/gotocompany/entropy/v1beta1/module.pb.go create mode 100644 proto/gotocompany/entropy/v1beta1/module.pb.gw.go create mode 100644 proto/gotocompany/entropy/v1beta1/module.pb.validate.go create mode 100644 proto/gotocompany/entropy/v1beta1/module_grpc.pb.go create mode 100644 proto/gotocompany/entropy/v1beta1/resource.pb.go create mode 100644 proto/gotocompany/entropy/v1beta1/resource.pb.gw.go create mode 100644 proto/gotocompany/entropy/v1beta1/resource.pb.validate.go create mode 100644 proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go diff --git a/.golangci.yml b/.golangci.yml index de8a79e7..5b10261e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -112,12 +112,12 @@ linters-settings: checks: - "all" goimports: - local-prefixes: github.com/odpf/entropy + local-prefixes: github.com/goto/entropy gci: sections: - standard # Captures all standard packages if they do not match another section. - default # Contains all imports that could not be matched to another section type. - - prefix(github.com/odpf/entropy) # Groups all imports with the specified Prefix. + - prefix(github.com/goto/entropy) # Groups all imports with the specified Prefix. gocritic: disabled-checks: - ifElseChain diff --git a/.goreleaser.yml b/.goreleaser.yml index ab95a0cd..dc3767c5 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -10,9 +10,9 @@ builds: binary: entropy flags: [-a] ldflags: - - -X github.com/odpf/entropy/pkg/version.Version={{.Tag}} - - -X github.com/odpf/entropy/pkg/version.Commit={{.FullCommit}} - - -X github.com/odpf/entropy/pkg/version.BuildTime={{.Date}} + - -X github.com/goto/entropy/pkg/version.Version={{.Tag}} + - -X github.com/goto/entropy/pkg/version.Commit={{.FullCommit}} + - -X github.com/goto/entropy/pkg/version.BuildTime={{.Date}} goos: - darwin - linux @@ -58,13 +58,13 @@ dockers: - entropy dockerfile: Dockerfile image_templates: - - 'docker.io/odpf/{{.ProjectName}}:latest' - - 'docker.io/odpf/{{.ProjectName}}:{{ .Version }}' - - 'docker.io/odpf/{{.ProjectName}}:{{ .Version }}-amd64' + - 'docker.io/gotocompany/{{.ProjectName}}:latest' + - 'docker.io/gotocompany/{{.ProjectName}}:{{ .Version }}' + - 'docker.io/gotocompany/{{.ProjectName}}:{{ .Version }}-amd64' brews: - name: entropy - homepage: "https://github.com/odpf/entropy" + homepage: "https://github.com/goto/entropy" description: "Infrastructure orchestration tool." tap: owner: odpf diff --git a/Makefile b/Makefile index afaf4975..7e32c416 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,13 @@ -NAME=github.com/odpf/entropy +NAME=github.com/goto/entropy VERSION=$(shell git describe --tags --always --first-parent 2>/dev/null) COMMIT=$(shell git rev-parse --short HEAD) +PROTON_COMMIT="5b5dc727b525925bcec025b355983ca61d7ccf68" BUILD_TIME=$(shell date) COVERAGE_DIR=coverage BUILD_DIR=dist EXE=entropy -.PHONY: all build clean tidy format test test-coverage +.PHONY: all build clean tidy format test test-coverage proto all: clean test build format lint @@ -14,9 +15,17 @@ tidy: @echo "Tidy up go.mod..." @go mod tidy -v -install: - @echo "Installing Entropy to ${GOBIN}..." - @go install +install: ## install required dependencies + @echo "> installing dependencies" + go get -d github.com/vektra/mockery/v2@v2.13.1 + go get -d google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1 + go get google.golang.org/protobuf/proto@v1.28.1 + go get google.golang.org/grpc@v1.49.0 + go get -d google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2.0 + go get -d github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@v2.11.3 + go get -d github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@v2.11.3 + go get -d github.com/bufbuild/buf/cmd/buf@v1.7.0 + go get github.com/envoyproxy/protoc-gen-validate@v0.6.7 format: @echo "Running gofumpt..." @@ -46,6 +55,13 @@ build: clean @echo "Running build for '${VERSION}' in '${BUILD_DIR}/'..." @CGO_ENABLED=0 go build -ldflags '-X "${NAME}/pkg/version.Version=${VERSION}" -X "${NAME}/pkg/version.Commit=${COMMIT}" -X "${NAME}/pkg/version.BuildTime=${BUILD_TIME}"' -o ${BUILD_DIR}/${EXE} +proto: ## Generate the protobuf files + @echo " > generating protobuf from goto/proton" + @echo " > [info] make sure correct version of dependencies are installed using 'make install'" + @rm -rf ./proto + @buf generate https://github.com/goto/proton/archive/${PROTON_COMMIT}.zip#strip_components=1 --template buf.gen.yaml --path gotocompany/entropy --path gotocompany/common + @echo " > protobuf compilation finished" + download: @go mod download diff --git a/README.md b/README.md index 335f03f6..d27622ab 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Entropy -![test workflow](https://github.com/odpf/entropy/actions/workflows/test.yml/badge.svg) -[![Go Report Card](https://goreportcard.com/badge/github.com/odpf/entropy)](https://goreportcard.com/report/github.com/odpf/entropy) -[![Version](https://img.shields.io/github/v/release/odpf/entropy?logo=semantic-release)](Version) +![test workflow](https://github.com/goto/entropy/actions/workflows/test.yml/badge.svg) +[![Go Report Card](https://goreportcard.com/badge/github.com/goto/entropy)](https://goreportcard.com/report/github.com/goto/entropy) +[![Version](https://img.shields.io/github/v/release/goto/entropy?logo=semantic-release)](Version) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg?logo=apache)](LICENSE) Entropy is an extensible infrastructure orchestration and application deployment tool. Entropy provides features @@ -23,7 +23,7 @@ Install Entropy on macOS, Windows, Linux, OpenBSD, FreeBSD, and on any machine. #### Binary (Cross-platform) -Download the appropriate version for your platform from [releases](https://github.com/odpf/entropy/releases) page. Once +Download the appropriate version for your platform from [releases](https://github.com/goto/entropy/releases) page. Once downloaded, the binary can be run from anywhere. You don’t need to install it into a global location. This works well for shared hosts and other systems where you don’t have a privileged account. Ideally, you should install it somewhere in your PATH for easy use. `/usr/local/bin` is the most probable location. @@ -58,7 +58,7 @@ $ entropy serve --config ./my_config.yaml ```sh # Clone the repo -$ git clone https://github.com/odpf/entropy.git +$ git clone https://github.com/goto/entropy.git # Build entropy binary file $ make build @@ -87,10 +87,10 @@ Read our [contributing guide](https://odpf.github.io/entropy/docs/contribute/con development process, how to propose bugfixes and improvements, and how to build and test your changes to Entropy. To help you get your feet wet and get you familiar with our contribution process, we have a list -of [good first issues](https://github.com/odpf/entropy/labels/good%20first%20issue) that contain bugs which have a +of [good first issues](https://github.com/goto/entropy/labels/good%20first%20issue) that contain bugs which have a relatively limited scope. This is a great place to get started. -This project exists thanks to all the [contributors](https://github.com/odpf/entropy/graphs/contributors). +This project exists thanks to all the [contributors](https://github.com/goto/entropy/graphs/contributors). ## License diff --git a/buf.gen.yaml b/buf.gen.yaml new file mode 100644 index 00000000..e50d1450 --- /dev/null +++ b/buf.gen.yaml @@ -0,0 +1,25 @@ +version: v1 +plugins: + - remote: "buf.build/library/plugins/go:v1.27.1-1" + out: proto + opt: paths=source_relative + - remote: "buf.build/library/plugins/go-grpc:v1.1.0-2" + out: proto + opt: paths=source_relative,require_unimplemented_servers=true + - remote: buf.build/odpf/plugins/validate + out: "proto" + opt: "paths=source_relative,lang=go" + - remote: "buf.build/grpc-ecosystem/plugins/grpc-gateway:v2.11.3-1" + out: proto + opt: + - paths=source_relative + - allow_repeated_fields_in_body=true + - remote: "buf.build/grpc-ecosystem/plugins/openapiv2:v2.11.3-1" + out: proto + opt: + - allow_repeated_fields_in_body=true + - output_format=yaml + - allow_merge=true + - merge_file_name=entropy + - openapi_naming_strategy=simple + - json_names_for_fields=false \ No newline at end of file diff --git a/cli/action.go b/cli/action.go index 434f559a..d36dbb13 100644 --- a/cli/action.go +++ b/cli/action.go @@ -4,10 +4,10 @@ import ( "fmt" "github.com/MakeNowJust/heredoc" - "github.com/odpf/salt/printer" - "github.com/odpf/salt/term" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" + "github.com/goto/salt/printer" + "github.com/goto/salt/term" "github.com/spf13/cobra" - entropyv1beta1 "go.buf.build/odpf/gwv/odpf/proton/odpf/entropy/v1beta1" "google.golang.org/protobuf/types/known/structpb" ) diff --git a/cli/cli.go b/cli/cli.go index 2894e01a..d40fa51f 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -3,7 +3,7 @@ package cli import ( "context" - "github.com/odpf/salt/cmdx" + "github.com/goto/salt/cmdx" "github.com/spf13/cobra" ) diff --git a/cli/client.go b/cli/client.go index 565971e1..1fc0d4e8 100644 --- a/cli/client.go +++ b/cli/client.go @@ -5,8 +5,8 @@ import ( "strconv" "time" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" "github.com/spf13/cobra" - entropyv1beta1 "go.buf.build/odpf/gwv/odpf/proton/odpf/entropy/v1beta1" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) diff --git a/cli/config.go b/cli/config.go index 034db2b2..17e32dd0 100644 --- a/cli/config.go +++ b/cli/config.go @@ -6,13 +6,13 @@ import ( "os" "time" - "github.com/odpf/salt/config" + "github.com/goto/salt/config" "github.com/spf13/cobra" "gopkg.in/yaml.v2" - "github.com/odpf/entropy/pkg/errors" - "github.com/odpf/entropy/pkg/logger" - "github.com/odpf/entropy/pkg/telemetry" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/logger" + "github.com/goto/entropy/pkg/telemetry" ) const configFlag = "config" diff --git a/cli/logs.go b/cli/logs.go index e2710985..f89e8beb 100644 --- a/cli/logs.go +++ b/cli/logs.go @@ -7,11 +7,11 @@ import ( "log" "strings" - "github.com/odpf/salt/term" // nolint - entropyv1beta1 "go.buf.build/odpf/gwv/odpf/proton/odpf/entropy/v1beta1" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" + "github.com/goto/salt/term" // nolint "github.com/MakeNowJust/heredoc" - "github.com/odpf/salt/printer" + "github.com/goto/salt/printer" "github.com/spf13/cobra" ) diff --git a/cli/migrate.go b/cli/migrate.go index 60b120e1..ee0393e0 100644 --- a/cli/migrate.go +++ b/cli/migrate.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/cobra" "go.uber.org/zap" - "github.com/odpf/entropy/pkg/logger" + "github.com/goto/entropy/pkg/logger" ) func cmdMigrate() *cobra.Command { diff --git a/cli/resource.go b/cli/resource.go index 8669201b..c2eb8b14 100644 --- a/cli/resource.go +++ b/cli/resource.go @@ -4,11 +4,11 @@ import ( "fmt" "os" - "github.com/odpf/salt/term" // nolint - entropyv1beta1 "go.buf.build/odpf/gwv/odpf/proton/odpf/entropy/v1beta1" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" + "github.com/goto/salt/term" // nolint "github.com/MakeNowJust/heredoc" - "github.com/odpf/salt/printer" + "github.com/goto/salt/printer" "github.com/spf13/cobra" ) diff --git a/cli/serve.go b/cli/serve.go index aed4529f..1516be3b 100644 --- a/cli/serve.go +++ b/cli/serve.go @@ -8,17 +8,17 @@ import ( "github.com/spf13/cobra" "go.uber.org/zap" - "github.com/odpf/entropy/core" - "github.com/odpf/entropy/core/module" - entropyserver "github.com/odpf/entropy/internal/server" - "github.com/odpf/entropy/internal/store/postgres" - "github.com/odpf/entropy/modules" - "github.com/odpf/entropy/modules/firehose" - "github.com/odpf/entropy/modules/kubernetes" - "github.com/odpf/entropy/pkg/logger" - "github.com/odpf/entropy/pkg/telemetry" - "github.com/odpf/entropy/pkg/worker" - "github.com/odpf/entropy/pkg/worker/pgq" + "github.com/goto/entropy/core" + "github.com/goto/entropy/core/module" + entropyserver "github.com/goto/entropy/internal/server" + "github.com/goto/entropy/internal/store/postgres" + "github.com/goto/entropy/modules" + "github.com/goto/entropy/modules/firehose" + "github.com/goto/entropy/modules/kubernetes" + "github.com/goto/entropy/pkg/logger" + "github.com/goto/entropy/pkg/telemetry" + "github.com/goto/entropy/pkg/worker" + "github.com/goto/entropy/pkg/worker/pgq" ) func cmdServe() *cobra.Command { diff --git a/cli/version.go b/cli/version.go index 2fcbd04b..61922444 100644 --- a/cli/version.go +++ b/cli/version.go @@ -3,7 +3,7 @@ package cli import ( "github.com/spf13/cobra" - v "github.com/odpf/entropy/pkg/version" + v "github.com/goto/entropy/pkg/version" ) func cmdVersion() *cobra.Command { diff --git a/core/core.go b/core/core.go index a4bdf02f..125b94e5 100644 --- a/core/core.go +++ b/core/core.go @@ -10,10 +10,10 @@ import ( "go.uber.org/zap" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" - "github.com/odpf/entropy/pkg/worker" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/worker" ) type Service struct { diff --git a/core/core_test.go b/core/core_test.go index 825504e9..b891a661 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -6,9 +6,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/odpf/entropy/core" - "github.com/odpf/entropy/core/mocks" - "github.com/odpf/entropy/core/resource" + "github.com/goto/entropy/core" + "github.com/goto/entropy/core/mocks" + "github.com/goto/entropy/core/resource" ) var ( diff --git a/core/mocks/async_worker.go b/core/mocks/async_worker.go index d5c53398..5910d8ed 100644 --- a/core/mocks/async_worker.go +++ b/core/mocks/async_worker.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.10.4. DO NOT EDIT. +// Code generated by mockery v2.14.0. DO NOT EDIT. package mocks @@ -7,7 +7,7 @@ import ( mock "github.com/stretchr/testify/mock" - worker "github.com/odpf/entropy/pkg/worker" + worker "github.com/goto/entropy/pkg/worker" ) // AsyncWorker is an autogenerated mock type for the AsyncWorker type @@ -74,3 +74,18 @@ func (_c *AsyncWorker_Enqueue_Call) Return(_a0 error) *AsyncWorker_Enqueue_Call _c.Call.Return(_a0) return _c } + +type mockConstructorTestingTNewAsyncWorker interface { + mock.TestingT + Cleanup(func()) +} + +// NewAsyncWorker creates a new instance of AsyncWorker. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewAsyncWorker(t mockConstructorTestingTNewAsyncWorker) *AsyncWorker { + mock := &AsyncWorker{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/mocks/driver.go b/core/mocks/driver.go index 243bc872..23c4c8a2 100644 --- a/core/mocks/driver.go +++ b/core/mocks/driver.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.10.4. DO NOT EDIT. +// Code generated by mockery v2.14.0. DO NOT EDIT. package mocks @@ -8,9 +8,9 @@ import ( mock "github.com/stretchr/testify/mock" - module "github.com/odpf/entropy/core/module" + module "github.com/goto/entropy/core/module" - resource "github.com/odpf/entropy/core/resource" + resource "github.com/goto/entropy/core/resource" ) // ModuleDriver is an autogenerated mock type for the Driver type @@ -167,3 +167,18 @@ func (_c *ModuleDriver_Sync_Call) Return(_a0 *resource.State, _a1 error) *Module _c.Call.Return(_a0, _a1) return _c } + +type mockConstructorTestingTNewModuleDriver interface { + mock.TestingT + Cleanup(func()) +} + +// NewModuleDriver creates a new instance of ModuleDriver. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewModuleDriver(t mockConstructorTestingTNewModuleDriver) *ModuleDriver { + mock := &ModuleDriver{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/mocks/loggable_module.go b/core/mocks/loggable_module.go index edd56d97..c6a61752 100644 --- a/core/mocks/loggable_module.go +++ b/core/mocks/loggable_module.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.10.4. DO NOT EDIT. +// Code generated by mockery v2.14.0. DO NOT EDIT. package mocks @@ -8,9 +8,9 @@ import ( mock "github.com/stretchr/testify/mock" - module "github.com/odpf/entropy/core/module" + module "github.com/goto/entropy/core/module" - resource "github.com/odpf/entropy/core/resource" + resource "github.com/goto/entropy/core/resource" ) // LoggableModule is an autogenerated mock type for the Loggable type @@ -215,3 +215,18 @@ func (_c *LoggableModule_Sync_Call) Return(_a0 *resource.State, _a1 error) *Logg _c.Call.Return(_a0, _a1) return _c } + +type mockConstructorTestingTNewLoggableModule interface { + mock.TestingT + Cleanup(func()) +} + +// NewLoggableModule creates a new instance of LoggableModule. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewLoggableModule(t mockConstructorTestingTNewLoggableModule) *LoggableModule { + mock := &LoggableModule{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/mocks/module_registry.go b/core/mocks/module_registry.go index a2a17f10..68563c20 100644 --- a/core/mocks/module_registry.go +++ b/core/mocks/module_registry.go @@ -1,11 +1,11 @@ -// Code generated by mockery v2.10.4. DO NOT EDIT. +// Code generated by mockery v2.14.0. DO NOT EDIT. package mocks import ( context "context" - module "github.com/odpf/entropy/core/module" + module "github.com/goto/entropy/core/module" mock "github.com/stretchr/testify/mock" ) @@ -75,3 +75,18 @@ func (_c *ModuleRegistry_GetDriver_Call) Return(_a0 module.Driver, _a1 module.De _c.Call.Return(_a0, _a1, _a2) return _c } + +type mockConstructorTestingTNewModuleRegistry interface { + mock.TestingT + Cleanup(func()) +} + +// NewModuleRegistry creates a new instance of ModuleRegistry. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewModuleRegistry(t mockConstructorTestingTNewModuleRegistry) *ModuleRegistry { + mock := &ModuleRegistry{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/mocks/module_service.go b/core/mocks/module_service.go index 2e5462e3..d3f9876d 100644 --- a/core/mocks/module_service.go +++ b/core/mocks/module_service.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.10.4. DO NOT EDIT. +// Code generated by mockery v2.14.0. DO NOT EDIT. package mocks @@ -9,9 +9,9 @@ import ( mock "github.com/stretchr/testify/mock" - module "github.com/odpf/entropy/core/module" + module "github.com/goto/entropy/core/module" - resource "github.com/odpf/entropy/core/resource" + resource "github.com/goto/entropy/core/resource" ) // ModuleService is an autogenerated mock type for the ModuleService type @@ -216,3 +216,18 @@ func (_c *ModuleService_SyncState_Call) Return(_a0 *resource.State, _a1 error) * _c.Call.Return(_a0, _a1) return _c } + +type mockConstructorTestingTNewModuleService interface { + mock.TestingT + Cleanup(func()) +} + +// NewModuleService creates a new instance of ModuleService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewModuleService(t mockConstructorTestingTNewModuleService) *ModuleService { + mock := &ModuleService{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/mocks/module_store.go b/core/mocks/module_store.go index 3b1cbbf5..f8e50a5a 100644 --- a/core/mocks/module_store.go +++ b/core/mocks/module_store.go @@ -1,11 +1,11 @@ -// Code generated by mockery v2.10.4. DO NOT EDIT. +// Code generated by mockery v2.14.0. DO NOT EDIT. package mocks import ( context "context" - module "github.com/odpf/entropy/core/module" + module "github.com/goto/entropy/core/module" mock "github.com/stretchr/testify/mock" ) @@ -229,3 +229,18 @@ func (_c *ModuleStore_UpdateModule_Call) Return(_a0 error) *ModuleStore_UpdateMo _c.Call.Return(_a0) return _c } + +type mockConstructorTestingTNewModuleStore interface { + mock.TestingT + Cleanup(func()) +} + +// NewModuleStore creates a new instance of ModuleStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewModuleStore(t mockConstructorTestingTNewModuleStore) *ModuleStore { + mock := &ModuleStore{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/mocks/resource_store.go b/core/mocks/resource_store.go index b8d88731..ac7dd6ea 100644 --- a/core/mocks/resource_store.go +++ b/core/mocks/resource_store.go @@ -1,11 +1,11 @@ -// Code generated by mockery v2.10.4. DO NOT EDIT. +// Code generated by mockery v2.14.0. DO NOT EDIT. package mocks import ( context "context" - resource "github.com/odpf/entropy/core/resource" + resource "github.com/goto/entropy/core/resource" mock "github.com/stretchr/testify/mock" ) @@ -323,3 +323,18 @@ func (_c *ResourceStore_Update_Call) Return(_a0 error) *ResourceStore_Update_Cal _c.Call.Return(_a0) return _c } + +type mockConstructorTestingTNewResourceStore interface { + mock.TestingT + Cleanup(func()) +} + +// NewResourceStore creates a new instance of ResourceStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewResourceStore(t mockConstructorTestingTNewResourceStore) *ResourceStore { + mock := &ResourceStore{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/module/action.go b/core/module/action.go index a2fc611a..ea2ed58a 100644 --- a/core/module/action.go +++ b/core/module/action.go @@ -6,7 +6,7 @@ import ( "github.com/xeipuuv/gojsonschema" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/pkg/errors" ) const ( diff --git a/core/module/driver.go b/core/module/driver.go index f52be7e7..dd7e416c 100644 --- a/core/module/driver.go +++ b/core/module/driver.go @@ -8,7 +8,7 @@ import ( "encoding/json" "time" - "github.com/odpf/entropy/core/resource" + "github.com/goto/entropy/core/resource" ) // Driver is responsible for achieving desired external system states based diff --git a/core/module/module.go b/core/module/module.go index f5fa1e93..a5611be9 100644 --- a/core/module/module.go +++ b/core/module/module.go @@ -9,7 +9,7 @@ import ( "strings" "time" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/pkg/errors" ) // Module represents all the data needed to initialize a particular module. diff --git a/core/module/service.go b/core/module/service.go index da9257e0..e3d07405 100644 --- a/core/module/service.go +++ b/core/module/service.go @@ -5,8 +5,8 @@ import ( "encoding/json" "fmt" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" ) type Service struct { diff --git a/core/read.go b/core/read.go index 0ab96e08..7c1769aa 100644 --- a/core/read.go +++ b/core/read.go @@ -3,9 +3,9 @@ package core import ( "context" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" ) func (s *Service) GetResource(ctx context.Context, urn string) (*resource.Resource, error) { diff --git a/core/read_test.go b/core/read_test.go index 0c79bd16..9a501005 100644 --- a/core/read_test.go +++ b/core/read_test.go @@ -7,10 +7,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/odpf/entropy/core" - "github.com/odpf/entropy/core/mocks" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core" + "github.com/goto/entropy/core/mocks" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" ) func TestService_GetResource(t *testing.T) { diff --git a/core/resource/resource.go b/core/resource/resource.go index fc2b0a3a..e080623b 100644 --- a/core/resource/resource.go +++ b/core/resource/resource.go @@ -9,7 +9,7 @@ import ( "strings" "time" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/pkg/errors" ) const urnSeparator = ":" diff --git a/core/resource/resource_test.go b/core/resource/resource_test.go index f29fd367..36473a9b 100644 --- a/core/resource/resource_test.go +++ b/core/resource/resource_test.go @@ -5,8 +5,8 @@ import ( "github.com/stretchr/testify/assert" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" ) func TestResource_Validate(t *testing.T) { diff --git a/core/resource/state_test.go b/core/resource/state_test.go index e245bf1b..112f477f 100644 --- a/core/resource/state_test.go +++ b/core/resource/state_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/odpf/entropy/core/resource" + "github.com/goto/entropy/core/resource" ) func TestState_IsTerminal(t *testing.T) { diff --git a/core/sync.go b/core/sync.go index b1f4ee27..44abb31f 100644 --- a/core/sync.go +++ b/core/sync.go @@ -6,10 +6,10 @@ import ( "fmt" "time" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" - "github.com/odpf/entropy/pkg/worker" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/worker" ) const ( diff --git a/core/write.go b/core/write.go index 7ed57253..7509daec 100644 --- a/core/write.go +++ b/core/write.go @@ -3,9 +3,9 @@ package core import ( "context" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" ) func (s *Service) CreateResource(ctx context.Context, res resource.Resource) (*resource.Resource, error) { diff --git a/core/write_test.go b/core/write_test.go index 5ab387cf..f6233519 100644 --- a/core/write_test.go +++ b/core/write_test.go @@ -8,12 +8,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "github.com/odpf/entropy/core" - "github.com/odpf/entropy/core/mocks" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" - "github.com/odpf/entropy/pkg/worker" + "github.com/goto/entropy/core" + "github.com/goto/entropy/core/mocks" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/worker" ) func TestService_CreateResource(t *testing.T) { diff --git a/docs/concepts/resource-life-cycle.md b/docs/concepts/resource-life-cycle.md index 3f19bb20..656ff732 100644 --- a/docs/concepts/resource-life-cycle.md +++ b/docs/concepts/resource-life-cycle.md @@ -37,7 +37,7 @@ type Output map[string]interface{} The `Resource` definition is self explanatory. It has the `Spec` field which holds the `Configs` and `Dependencies` of a resource. The `State` field has three parts, `Status` holds the current status of a resource, `Output` holds the outcome of the latest action performed while `Data` holds the transactory information which might be used to perform actions on the reosurce. -For instance, a [firehose](https://github.com/odpf/firehose) resource looks like: +For instance, a [firehose](https://github.com/goto/firehose) resource looks like: ``` { diff --git a/docs/installation.md b/docs/installation.md index 16c1acc4..f7551238 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -9,7 +9,7 @@ Entropy installation is simple. You can install Entropy on macOS, Windows, Linux #### Binary (Cross-platform) -Download the appropriate version for your platform from [releases](https://github.com/odpf/entropy/releases) page. Once +Download the appropriate version for your platform from [releases](https://github.com/goto/entropy/releases) page. Once downloaded, the binary can be run from anywhere. You don’t need to install it into a global location. This works well for shared hosts and other systems where you don’t have a privileged account. Ideally, you should install it somewhere in your PATH for easy use. `/usr/local/bin` is the most probable location. @@ -33,7 +33,7 @@ To compile from source, you will need [Go](https://golang.org/) installed in you ```bash # Clone the repo -$ https://github.com/odpf/entropy.git +$ https://github.com/goto/entropy.git # Build entropy binary file $ make build @@ -44,7 +44,7 @@ $ ./entropy version ### Using Docker image -Entropy ships a Docker image [odpf/entropy](https://hub.docker.com/r/odpf/entropy) that enables you to use `entropy` as part of your Docker workflow. +Entropy ships a Docker image [odpf/entropy](https://hub.docker.com/r/goto/entropy) that enables you to use `entropy` as part of your Docker workflow. For example, you can run `entropy version` with this command: diff --git a/docs/modules/firehose.md b/docs/modules/firehose.md index 4e981e8a..93d36f77 100644 --- a/docs/modules/firehose.md +++ b/docs/modules/firehose.md @@ -34,4 +34,4 @@ type moduleConfig struct { | `ChartVersion` | `string` Chart version you want to use. | | `Firehose` | `struct` Holds firehose configuration. | -Detailed JSONSchema for config can be referenced [here](https://github.com/odpf/entropy/blob/main/modules/firehose/schema/config.json). \ No newline at end of file +Detailed JSONSchema for config can be referenced [here](https://github.com/goto/entropy/blob/main/modules/firehose/schema/config.json). \ No newline at end of file diff --git a/docs/modules/kubernetes.md b/docs/modules/kubernetes.md index 54fee8b7..8df4cbd6 100644 --- a/docs/modules/kubernetes.md +++ b/docs/modules/kubernetes.md @@ -43,7 +43,7 @@ type Config struct { | `ClientCertificate` | `string` PEM-encoded client certificate for TLS authentication. | Note: User shall either enable Insecure or set ClusterCACertificate. Also, user can either use Token to aunthenate a service account or they can use ClientKey & ClientCertificate for TLS authentication. -Detailed JSONSchema for config can be referenced [here](https://github.com/odpf/entropy/blob/main/modules/kubernetes/config_schema.json). +Detailed JSONSchema for config can be referenced [here](https://github.com/goto/entropy/blob/main/modules/kubernetes/config_schema.json). ## Supported actions diff --git a/go.mod b/go.mod index f9c597da..6c3770d5 100644 --- a/go.mod +++ b/go.mod @@ -1,30 +1,35 @@ -module github.com/odpf/entropy +module github.com/goto/entropy go 1.18 require ( contrib.go.opencensus.io/exporter/ocagent v0.7.0 contrib.go.opencensus.io/exporter/prometheus v0.4.1 + github.com/MakeNowJust/heredoc v1.0.0 github.com/Masterminds/squirrel v1.5.2 - github.com/google/go-cmp v0.5.8 + github.com/ghodss/yaml v1.0.0 + github.com/google/go-cmp v0.5.9 + github.com/gorilla/mux v1.8.0 + github.com/goto/salt v0.3.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 + github.com/jmoiron/sqlx v1.3.5 github.com/lib/pq v1.10.4 github.com/mcuadros/go-defaults v1.2.0 + github.com/mitchellh/mapstructure v1.5.0 github.com/newrelic/go-agent/v3 v3.17.0 github.com/newrelic/go-agent/v3/integrations/nrgorilla v1.1.1 github.com/newrelic/go-agent/v3/integrations/nrgrpc v1.3.1 github.com/newrelic/newrelic-opencensus-exporter-go v0.4.0 - github.com/odpf/salt v0.2.1 - github.com/rs/xid v1.2.1 - github.com/spf13/cobra v1.4.0 - github.com/stretchr/testify v1.7.1 + github.com/rs/xid v1.3.0 + github.com/spf13/cobra v1.5.0 + github.com/stretchr/testify v1.8.1 github.com/xeipuuv/gojsonschema v1.2.0 - go.buf.build/odpf/gw/odpf/proton v1.1.122 - go.buf.build/odpf/gwv/odpf/proton v1.1.172 - go.opencensus.io v0.23.0 + go.opencensus.io v0.24.0 go.uber.org/zap v1.21.0 - google.golang.org/grpc v1.46.2 - google.golang.org/protobuf v1.28.0 + google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc + google.golang.org/grpc v1.49.0 + google.golang.org/protobuf v1.28.1 gopkg.in/yaml.v2 v2.4.0 helm.sh/helm/v3 v3.9.0 k8s.io/api v0.24.0 @@ -32,22 +37,9 @@ require ( k8s.io/client-go v0.24.0 ) -require ( - github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect - github.com/cli/safeexec v1.0.0 // indirect - github.com/go-kit/log v0.1.0 // indirect - github.com/go-logfmt/logfmt v0.5.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect - github.com/newrelic/newrelic-telemetry-sdk-go v0.2.0 // indirect - github.com/prometheus/statsd_exporter v0.21.0 // indirect - google.golang.org/api v0.62.0 // indirect -) - require ( github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/BurntSushi/toml v1.0.0 // indirect - github.com/MakeNowJust/heredoc v1.0.0 github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.1.1 // indirect github.com/Masterminds/sprig/v3 v3.2.2 // indirect @@ -56,19 +48,21 @@ require ( github.com/alecthomas/chroma v0.8.2 // indirect github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect github.com/aymerick/douceur v0.2.0 // indirect + github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/briandowns/spinner v1.18.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect github.com/charmbracelet/glamour v0.3.0 // indirect - github.com/containerd/containerd v1.6.3 // indirect + github.com/containerd/containerd v1.6.6 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dlclark/regexp2 v1.2.0 // indirect - github.com/docker/cli v20.10.11+incompatible // indirect + github.com/docker/cli v20.10.14+incompatible // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v20.10.14+incompatible // indirect + github.com/docker/docker v20.10.17+incompatible // indirect github.com/docker/docker-credential-helpers v0.6.4 // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-metrics v0.0.1 // indirect @@ -77,11 +71,11 @@ require ( github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/fatih/color v1.13.0 // indirect - github.com/fsnotify/fsnotify v1.5.1 // indirect - github.com/ghodss/yaml v1.0.0 + github.com/felixge/httpsnoop v1.0.2 // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/go-errors/errors v1.0.1 // indirect github.com/go-gorp/gorp/v3 v3.0.2 // indirect - github.com/go-logr/logr v1.2.2 // indirect + github.com/go-logr/logr v1.2.3 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.19.5 // indirect github.com/go-openapi/swag v0.19.14 // indirect @@ -94,24 +88,21 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/css v1.0.0 // indirect - github.com/gorilla/mux v1.8.0 github.com/gosuri/uitable v0.0.4 // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.0 github.com/hashicorp/hcl v1.0.0 // indirect github.com/huandu/xstrings v1.3.2 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jeremywohl/flatten v1.0.1 // indirect - github.com/jmoiron/sqlx v1.3.5 github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.13.6 // indirect + github.com/klauspost/compress v1.15.9 // indirect github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/magiconair/properties v1.8.5 // indirect + github.com/magiconair/properties v1.8.6 // indirect github.com/mailru/easyjson v0.7.6 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect @@ -121,10 +112,10 @@ require ( github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect - github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/spdystream v0.2.0 // indirect + github.com/moby/sys/mountinfo v0.6.0 // indirect github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -133,10 +124,12 @@ require ( github.com/muesli/reflow v0.2.0 // indirect github.com/muesli/termenv v0.9.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/oklog/run v1.1.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect - github.com/pelletier/go-toml v1.9.4 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.0.2 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -147,38 +140,37 @@ require ( github.com/rivo/uniseg v0.2.0 // indirect github.com/rubenv/sql-migrate v1.1.1 // indirect github.com/russross/blackfriday v1.5.2 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/schollz/progressbar/v3 v3.8.5 // indirect github.com/shopspring/decimal v1.2.0 // indirect - github.com/sirupsen/logrus v1.8.1 // indirect - github.com/spf13/afero v1.6.0 // indirect - github.com/spf13/cast v1.4.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spf13/afero v1.9.2 // indirect + github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.8.1 // indirect - github.com/stretchr/objx v0.2.0 // indirect - github.com/subosito/gotenv v1.2.0 // indirect + github.com/spf13/viper v1.12.0 // indirect + github.com/stretchr/objx v0.5.0 // indirect + github.com/subosito/gotenv v1.4.0 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect - github.com/yuin/goldmark v1.4.1 // indirect + github.com/yuin/goldmark v1.4.13 // indirect github.com/yuin/goldmark-emoji v1.0.1 // indirect - go.buf.build/odpf/gw/grpc-ecosystem/grpc-gateway v1.1.44 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect - go.uber.org/atomic v1.7.0 // indirect - go.uber.org/multierr v1.6.0 // indirect - golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect - golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect - golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect - golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect - golang.org/x/text v0.3.7 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect + golang.org/x/net v0.5.0 // indirect + golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.4.0 // indirect + golang.org/x/term v0.4.0 // indirect + golang.org/x/text v0.6.0 // indirect golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/ini.v1 v1.62.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + gopkg.in/ini.v1 v1.66.6 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiextensions-apiserver v0.24.0 // indirect k8s.io/apiserver v0.24.0 // indirect k8s.io/cli-runtime v0.24.0 // indirect @@ -194,3 +186,14 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) + +require ( + github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect + github.com/cli/safeexec v1.0.0 // indirect + github.com/go-kit/log v0.1.0 // indirect + github.com/go-logfmt/logfmt v0.5.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/newrelic/newrelic-telemetry-sdk-go v0.2.0 // indirect + github.com/prometheus/statsd_exporter v0.21.0 // indirect + google.golang.org/api v0.98.0 // indirect +) diff --git a/go.sum b/go.sum index ee01b518..9531f60a 100644 --- a/go.sum +++ b/go.sum @@ -5,6 +5,7 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -17,6 +18,7 @@ cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOY cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= @@ -29,15 +31,24 @@ cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/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= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -48,6 +59,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= contrib.go.opencensus.io/exporter/ocagent v0.7.0 h1:BEfdCTXfMV30tLZD8c9n64V/tIZX5+9sXiuFLnrr1k8= contrib.go.opencensus.io/exporter/ocagent v0.7.0/go.mod h1:IshRmMJBhDfFj5Y67nVhMYTTIze91RUeT73ipWKs/GY= contrib.go.opencensus.io/exporter/prometheus v0.4.1 h1:oObVeKo2NxpdF/fIfrPsNj6K0Prg0R0mHM+uANlYMiM= @@ -83,7 +96,6 @@ github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ClickHouse/clickhouse-go v1.4.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= @@ -119,8 +131,8 @@ github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+V github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= -github.com/Microsoft/hcsshim v0.9.2 h1:wB06W5aYFfUB3IvootYAY2WnOmIdgPGfqSI6tufQNnY= github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= +github.com/Microsoft/hcsshim v0.9.3 h1:k371PzBuRrz2b+ebGuI2nVgVhgsVX60jMfSw80NECxo= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -166,6 +178,9 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/authzed/authzed-go v0.7.0/go.mod h1:bmjzzIQ34M0+z8NO9SLjf4oA0A9Ka9gUWVzeSbD0E7c= +github.com/authzed/grpcutil v0.0.0-20210913124023-cad23ae5a9e8/go.mod h1:HwO/KbRU3fWXEYHE96kvXnwxzi97tkXD1hfi5UaZ71Y= +github.com/authzed/grpcutil v0.0.0-20220104222419-f813f77722e5/go.mod h1:rqjY3zyK/YP7NID9+B2BdIRRkvnK+cdf9/qya/zaFZE= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0= @@ -197,8 +212,9 @@ github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAm github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -228,14 +244,16 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembj github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -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/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= @@ -315,8 +333,8 @@ github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTV github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s= github.com/containerd/containerd v1.6.1/go.mod h1:1nJz5xCZPusx6jJU8Frfct988y0NpumIq9ODB0kLtoE= -github.com/containerd/containerd v1.6.3 h1:JfgUEIAH07xDWk6kqz0P3ArZt+KJ9YeihSC9uyFtSKg= -github.com/containerd/containerd v1.6.3/go.mod h1:gCVGrYRYFm2E8GmuUIbj/NGD7DLZQLzSJQazjVKDOig= +github.com/containerd/containerd v1.6.6 h1:xJNPhbrmz8xAMDNoVjHy9YHtWwEQNS+CDkcIRh7t8Y0= +github.com/containerd/containerd v1.6.6/go.mod h1:ZoP1geJldzCVY3Tonoz7b1IXk8rIX0Nltt5QE4OMNk0= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -325,6 +343,7 @@ github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= +github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= @@ -396,6 +415,8 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -416,7 +437,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs 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/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= -github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= @@ -429,17 +449,18 @@ github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v20.10.11+incompatible h1:tXU1ezXcruZQRrMP8RN2z9N91h+6egZTS1gsPsKantc= -github.com/docker/cli v20.10.11+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v20.10.14+incompatible h1:dSBKJOVesDgHo7rbxlYjYsXe7gPzrTT+/cKQgpDAazg= +github.com/docker/cli v20.10.14+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= 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 v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.13+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.14+incompatible h1:+T9/PRYWNDo5SZl5qS1r9Mo/0Q8AwxKKPtu9S1yxM0w= -github.com/docker/docker v20.10.14+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.17+incompatible h1:JYCuMrWaVNophQTOrMMoSwudOVEfcegoZZrleKc1xwE= +github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o= github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c= @@ -477,6 +498,7 @@ github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPO github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= +github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= @@ -487,18 +509,20 @@ github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwo github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= +github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.5+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsouza/fake-gcs-server v1.17.0/go.mod h1:D1rTE4YCyHFNa99oyJJ5HyclvN/0uQR+pM/VdlL83bw= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= @@ -536,8 +560,9 @@ github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= @@ -688,8 +713,10 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-github/v39 v39.2.0/go.mod h1:C1s8C5aCC9L+JXIYpJM5GYytdX52vC1bLvHEF1IhBrE= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -711,6 +738,7 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= @@ -725,14 +753,20 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +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/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= @@ -750,7 +784,8 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= -github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= +github.com/goto/salt v0.3.0 h1:7bFVqh6/zHfyImkrl2mYJHsFuGd2OBM/8rKs+giDpbc= +github.com/goto/salt v0.3.0/go.mod h1:L8PtSbpUFFo/Yh5YZ0FTgV9FIAvtqGdNa2BkA5M3jWo= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -761,11 +796,9 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.6.0/go.mod h1:qrJPVzv9YlhsrxJc3P/Q85nr0w1lIRikTl4JlhdDH5w= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.0 h1:ESEyqQqXXFIcImj/BE8oKEX37Zsuceb2cZI+EL/zNCY= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.0/go.mod h1:XnLCLFp3tjoZJszVKjfpyAK6J8sYIcQXWQxmqLWF21I= +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/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= @@ -821,7 +854,6 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= -github.com/jackc/pgconn v1.7.0/go.mod h1:sF/lPpNEMEOp+IYhyQGdAvrG20gWf6A1tKlr0v7JMeA= github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgerrcode v0.0.0-20201024163028-a0d42d470451/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= @@ -833,7 +865,6 @@ github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.0.5/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.0.7/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= @@ -844,7 +875,6 @@ github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrU github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= -github.com/jackc/pgtype v1.5.0/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig= github.com/jackc/pgtype v1.6.2/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= @@ -852,13 +882,11 @@ github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQ github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= -github.com/jackc/pgx/v4 v4.9.0/go.mod h1:MNGWmViCgqbZck9ujOOBN63gK9XVGILXWCvKLGKmnms= github.com/jackc/pgx/v4 v4.10.1/go.mod h1:QlrWebbs3kqEZPHCTGyxecvzG6tvIsYu+A5b1raylkA= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jackc/puddle v1.1.2/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jeremywohl/flatten v1.0.1 h1:LrsxmB3hfwJuE+ptGOijix1PIfOoKLJ3Uee/mzbgtrs= github.com/jeremywohl/flatten v1.0.1/go.mod h1:4AmD/VxjWcI5SRB0n6szE2A6s2fsNHDLO0nAlMHgfLQ= @@ -888,12 +916,12 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 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/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jzelinskie/stringz v0.0.0-20210414224931-d6a8ce844a70/go.mod h1:hHYbgxJuNLRw91CmpuFsYEOyQqpDVFg8pvEh23vy4P0= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= github.com/k0kubun/pp v2.3.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= @@ -912,8 +940,9 @@ github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= 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= @@ -922,8 +951,8 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= @@ -935,6 +964,7 @@ github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= +github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -950,10 +980,13 @@ github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z 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/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= +github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= +github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -999,7 +1032,6 @@ github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vq github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.10 h1:MLn+5bFRlWMGoSRmJour3CL1w/qL96mvipqpwQW/Sfk= github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= @@ -1045,12 +1077,14 @@ github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8 github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9ObI= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/sys/mountinfo v0.6.0 h1:gUDhXQx58YNrpHlK4nSL+7y2pxFZkUcXqzFDKWdC0Oo= +github.com/moby/sys/mountinfo v0.6.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= @@ -1098,8 +1132,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/odpf/salt v0.2.1 h1:91TRXZ85XKeKUwq6jotcAD5eo40kP1GS3xZMvXK9xR0= -github.com/odpf/salt v0.2.1/go.mod h1:ZmDaHPtlwvOlluzv+qiC3qZj99hmfxlFRMqfqZx5IP8= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= @@ -1147,6 +1181,7 @@ github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rm github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= +github.com/opencontainers/runc v1.1.2/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -1159,14 +1194,16 @@ github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3 github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/ory/dockertest/v3 v3.9.1/go.mod h1:42Ir9hmvaAPm0Mgibk6mBPi7SFvTXxEcnztDYOJ//uM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= +github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= @@ -1183,6 +1220,7 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -1242,9 +1280,11 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/xid v1.3.0 h1:6NjYksEUlhurdVehpc7S7dk6DAmcKv8V9gG0FsVN2U4= +github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/rubenv/sql-migrate v1.1.1 h1:haR5Hn8hbW9/SpAICrXoZqXnywS7Q5WijwkQENPeNWY= @@ -1252,6 +1292,7 @@ github.com/rubenv/sql-migrate v1.1.1/go.mod h1:/7TZymwxN8VWumcIxw1jjHEcR1djpdkMH github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +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/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -1281,12 +1322,11 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/snowflakedb/gosnowflake v1.6.3/go.mod h1:6hLajn6yxuJ4xUHZegMekpq9rnQbGJ7TMwXjgTmA6lg= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1295,19 +1335,21 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= +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/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= -github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= +github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -1319,15 +1361,18 @@ 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.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= +github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/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= @@ -1335,10 +1380,14 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= +github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -1386,8 +1435,9 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.3/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1 h1:/vn0k+RBvwlxEmP5E7SZMqNxPhfMVFEJiykr15/0XKM= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18Wa1os= github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI= @@ -1400,17 +1450,6 @@ github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxt github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= -go.buf.build/odpf/gw/envoyproxy/protoc-gen-validate v1.1.6/go.mod h1:Z+auCoGBL8lg1aQQgGe7R3HLnYKf6nbtTawTt0WmFCo= -go.buf.build/odpf/gw/grpc-ecosystem/grpc-gateway v1.1.35/go.mod h1:/LuddrGPi0fwj7ay6Orutt8oFfPz8Y3c8qdBkacJq1A= -go.buf.build/odpf/gw/grpc-ecosystem/grpc-gateway v1.1.44 h1:ya+Pdx7IBc+Uf+UImPPecJbdI7gpMz9gJI6/LUNjsbE= -go.buf.build/odpf/gw/grpc-ecosystem/grpc-gateway v1.1.44/go.mod h1:/LuddrGPi0fwj7ay6Orutt8oFfPz8Y3c8qdBkacJq1A= -go.buf.build/odpf/gw/odpf/proton v1.1.9/go.mod h1:I9E8CF7w/690vRNWqBU6qDcUbi3Pi2THdn1yycBVTDQ= -go.buf.build/odpf/gw/odpf/proton v1.1.122 h1:6NM4D8VwKIdq6F0A5nXnmxPp7LnzuwsGCeVxi3E1HOI= -go.buf.build/odpf/gw/odpf/proton v1.1.122/go.mod h1:FySqyI0YPPldpzXULKDcIC/bMJIdGaO6j36i1ZKJSvE= -go.buf.build/odpf/gwv/envoyproxy/protoc-gen-validate v1.1.7/go.mod h1:2Tg6rYIoDhpl39Zd2+WBOF9uG4XxAOs0bK2Z2/bwTOc= -go.buf.build/odpf/gwv/grpc-ecosystem/grpc-gateway v1.1.46/go.mod h1:UrBCdmHgaY/pLapYUMOq01c1yuzwT8AEBTsgpmzq2zo= -go.buf.build/odpf/gwv/odpf/proton v1.1.172 h1:cGk4ctsVhBK4d6mV+QVrJD0rWkXtDO+ogCA8l3BCkhk= -go.buf.build/odpf/gwv/odpf/proton v1.1.172/go.mod h1:V6NNZKrRPHjMkIPiSXvwUHks0D8bUGPXAjXUaujG/90= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= @@ -1435,8 +1474,9 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w= @@ -1463,16 +1503,18 @@ go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0H go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= 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.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= -go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -1504,12 +1546,14 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38= -golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1558,6 +1602,7 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1630,8 +1675,17 @@ golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220111093109-d55c255bac03/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-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220919232410-f2f64ebce3c1/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1651,8 +1705,13 @@ golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1664,8 +1723,11 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/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/sys v0.0.0-20180224232135-f6cff0780e54/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1754,6 +1816,7 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1787,21 +1850,36 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220111092808-5a964db01320/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-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220405210540-1e041c57c461/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/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-20220610221304-9f5ed59c137d/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-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220818161305-2296e01440c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= 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= @@ -1810,8 +1888,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1895,6 +1974,7 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1903,12 +1983,16 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= @@ -1948,8 +2032,18 @@ google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqiv google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.62.0 h1:PhGymJMXfGBzc4lBRmrx9+1w4w2wEzURHNGF/sD/xGc= google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.98.0 h1:yxZrcxXESimy6r6mdL5Q6EnZwmewDJK2dVg3g75s5Dg= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/appengine v1.0.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2003,10 +2097,13 @@ google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= @@ -2030,11 +2127,30 @@ google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3 h1:q1kiSVscqoDeqTF27eQ2NnLLDmqF0I373qQNXYMy0fo= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +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 h1:Nf+EdcTLHR8qDNN/KfkQL0u0ssxt9OhbaWCl5C0ucEI= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -2067,11 +2183,16 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.44.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 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ= 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 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -2085,8 +2206,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -2104,8 +2226,9 @@ gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:a gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= +gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= @@ -2126,26 +2249,19 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/datatypes v1.0.0/go.mod h1:aKpJ+RNhLXWeF5OAdxfzBwT1UPw1wseSchF0AY3/lSw= -gorm.io/driver/mysql v1.0.3/go.mod h1:twGxftLBlFgNVNakL7F+P/x9oYqoymG3YYT8cAfI9oI= -gorm.io/driver/postgres v1.0.5/go.mod h1:qrD92UurYzNctBMVCJ8C3VQEjffEuphycXtxOudXNCA= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/postgres v1.0.8/go.mod h1:4eOzrI1MUfm6ObJU/UcmbXyiHSs8jSwH95G5P5dxcAg= -gorm.io/driver/sqlite v1.1.3/go.mod h1:AKDgRWk8lcSQSw+9kxCJnX/yySj8G3rdwYlU57cB45c= -gorm.io/driver/sqlserver v1.0.5/go.mod h1:WI/bfZ+s9TigYXe3hb3XjNaUP0TqmTdXl11pECyLATs= -gorm.io/gorm v1.20.1/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.20.2/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.20.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.20.5/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.21.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= -gotest.tools/v3 v3.1.0 h1:rVV8Tcg/8jHUkPUorwjaMTtemIMVXfIPKiOqnhEhakk= gotest.tools/v3 v3.1.0/go.mod h1:fHy7eyTmJFO5bQbUsEGQ1v4m2J3Jz9eWL54TP2/ZuYQ= +gotest.tools/v3 v3.2.0 h1:I0DwBVMGAx26dttAj1BtJLAkVGncrkkUXfJLC4Flt/I= +gotest.tools/v3 v3.2.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= helm.sh/helm/v3 v3.9.0 h1:qDSWViuF6SzZX5s5AB/NVRGWmdao7T5j4S4ebIkMGag= helm.sh/helm/v3 v3.9.0/go.mod h1:fzZfyslcPAWwSdkXrXlpKexFeE2Dei8N27FFQWt+PN0= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/server/server.go b/internal/server/server.go index 90e70373..b3f44474 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -7,6 +7,9 @@ import ( "time" gorillamux "github.com/gorilla/mux" + commonv1 "github.com/goto/entropy/proto/gotocompany/common/v1" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" + "github.com/goto/salt/mux" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery" @@ -15,19 +18,16 @@ import ( "github.com/newrelic/go-agent/v3/integrations/nrgorilla" "github.com/newrelic/go-agent/v3/integrations/nrgrpc" "github.com/newrelic/go-agent/v3/newrelic" - "github.com/odpf/salt/common" - "github.com/odpf/salt/mux" - commonv1 "go.buf.build/odpf/gw/odpf/proton/odpf/common/v1" - entropyv1beta1 "go.buf.build/odpf/gwv/odpf/proton/odpf/entropy/v1beta1" "go.opencensus.io/plugin/ocgrpc" "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/reflection" "google.golang.org/protobuf/encoding/protojson" - modulesv1 "github.com/odpf/entropy/internal/server/v1/modules" - resourcesv1 "github.com/odpf/entropy/internal/server/v1/resources" - "github.com/odpf/entropy/pkg/version" + modulesv1 "github.com/goto/entropy/internal/server/v1/modules" + resourcesv1 "github.com/goto/entropy/internal/server/v1/resources" + "github.com/goto/entropy/pkg/common" + "github.com/goto/entropy/pkg/version" ) const defaultGracePeriod = 5 * time.Second @@ -91,9 +91,11 @@ func Serve(ctx context.Context, addr string, nrApp *newrelic.Application, logger ) logger.Info("starting server", zap.String("addr", addr)) - return mux.Serve(ctx, addr, - mux.WithHTTP(httpRouter), - mux.WithGRPC(grpcServer), + return mux.Serve(ctx, + mux.WithHTTPTarget(":8081", &http.Server{ + Handler: httpRouter, + }), + mux.WithGRPCTarget(addr, grpcServer), mux.WithGracePeriod(defaultGracePeriod), ) } diff --git a/internal/server/serverutils/grpcerror.go b/internal/server/serverutils/grpcerror.go index 4eed22b6..334abe39 100644 --- a/internal/server/serverutils/grpcerror.go +++ b/internal/server/serverutils/grpcerror.go @@ -4,7 +4,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/pkg/errors" ) // ToRPCError returns an instance of gRPC Error Status equivalent to the diff --git a/internal/server/v1/mocks/module_service.go b/internal/server/v1/mocks/module_service.go index cd41e869..49545818 100644 --- a/internal/server/v1/mocks/module_service.go +++ b/internal/server/v1/mocks/module_service.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.10.4. DO NOT EDIT. +// Code generated by mockery v2.14.0. DO NOT EDIT. package mocks @@ -8,7 +8,7 @@ import ( mock "github.com/stretchr/testify/mock" - module "github.com/odpf/entropy/core/module" + module "github.com/goto/entropy/core/module" ) // ModuleService is an autogenerated mock type for the ModuleService type @@ -250,3 +250,18 @@ func (_c *ModuleService_UpdateModule_Call) Return(_a0 *module.Module, _a1 error) _c.Call.Return(_a0, _a1) return _c } + +type mockConstructorTestingTNewModuleService interface { + mock.TestingT + Cleanup(func()) +} + +// NewModuleService creates a new instance of ModuleService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewModuleService(t mockConstructorTestingTNewModuleService) *ModuleService { + mock := &ModuleService{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/internal/server/v1/mocks/resource_service.go b/internal/server/v1/mocks/resource_service.go index b6ebfb14..9f3a8185 100644 --- a/internal/server/v1/mocks/resource_service.go +++ b/internal/server/v1/mocks/resource_service.go @@ -1,14 +1,14 @@ -// Code generated by mockery v2.10.4. DO NOT EDIT. +// Code generated by mockery v2.14.0. DO NOT EDIT. package mocks import ( context "context" - module "github.com/odpf/entropy/core/module" + module "github.com/goto/entropy/core/module" mock "github.com/stretchr/testify/mock" - resource "github.com/odpf/entropy/core/resource" + resource "github.com/goto/entropy/core/resource" ) // ResourceService is an autogenerated mock type for the ResourceService type @@ -393,3 +393,18 @@ func (_c *ResourceService_UpdateResource_Call) Return(_a0 *resource.Resource, _a _c.Call.Return(_a0, _a1) return _c } + +type mockConstructorTestingTNewResourceService interface { + mock.TestingT + Cleanup(func()) +} + +// NewResourceService creates a new instance of ResourceService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewResourceService(t mockConstructorTestingTNewResourceService) *ResourceService { + mock := &ResourceService{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/internal/server/v1/modules/mappers.go b/internal/server/v1/modules/mappers.go index 5816959b..cf9fdb96 100644 --- a/internal/server/v1/modules/mappers.go +++ b/internal/server/v1/modules/mappers.go @@ -3,12 +3,12 @@ package modules import ( "encoding/json" - entropyv1beta1 "go.buf.build/odpf/gwv/odpf/proton/odpf/entropy/v1beta1" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/pkg/errors" ) func moduleToProto(mod module.Module) (*entropyv1beta1.Module, error) { diff --git a/internal/server/v1/modules/server.go b/internal/server/v1/modules/server.go index 7704aa45..cd3be997 100644 --- a/internal/server/v1/modules/server.go +++ b/internal/server/v1/modules/server.go @@ -6,10 +6,10 @@ import ( "context" "encoding/json" - entropyv1beta1 "go.buf.build/odpf/gwv/odpf/proton/odpf/entropy/v1beta1" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/internal/server/serverutils" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/internal/server/serverutils" ) type ModuleService interface { diff --git a/internal/server/v1/modules/server_test.go b/internal/server/v1/modules/server_test.go index 40b571b7..3a263c84 100644 --- a/internal/server/v1/modules/server_test.go +++ b/internal/server/v1/modules/server_test.go @@ -5,11 +5,11 @@ import ( "testing" "github.com/google/go-cmp/cmp" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" "github.com/stretchr/testify/assert" - entropyv1beta1 "go.buf.build/odpf/gwv/odpf/proton/odpf/entropy/v1beta1" "google.golang.org/protobuf/testing/protocmp" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/pkg/errors" ) func TestAPIServer_ListModules(t *testing.T) { diff --git a/internal/server/v1/resources/mappers.go b/internal/server/v1/resources/mappers.go index 8bbcccd9..eb6e9166 100644 --- a/internal/server/v1/resources/mappers.go +++ b/internal/server/v1/resources/mappers.go @@ -4,12 +4,12 @@ import ( "encoding/json" "strconv" - entropyv1beta1 "go.buf.build/odpf/gwv/odpf/proton/odpf/entropy/v1beta1" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" ) const decimalBase = 10 diff --git a/internal/server/v1/resources/server.go b/internal/server/v1/resources/server.go index 5fbe0452..02851777 100644 --- a/internal/server/v1/resources/server.go +++ b/internal/server/v1/resources/server.go @@ -5,11 +5,11 @@ package resources import ( "context" - entropyv1beta1 "go.buf.build/odpf/gwv/odpf/proton/odpf/entropy/v1beta1" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/internal/server/serverutils" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/internal/server/serverutils" ) type ResourceService interface { diff --git a/internal/server/v1/resources/server_test.go b/internal/server/v1/resources/server_test.go index c9d4de55..ea46516a 100644 --- a/internal/server/v1/resources/server_test.go +++ b/internal/server/v1/resources/server_test.go @@ -7,19 +7,19 @@ import ( "time" "github.com/google/go-cmp/cmp" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - entropyv1beta1 "go.buf.build/odpf/gwv/odpf/proton/odpf/entropy/v1beta1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/internal/server/v1/mocks" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/internal/server/v1/mocks" + "github.com/goto/entropy/pkg/errors" ) func TestAPIServer_CreateResource(t *testing.T) { diff --git a/internal/store/postgres/module_model.go b/internal/store/postgres/module_model.go index 664e29ee..44460574 100644 --- a/internal/store/postgres/module_model.go +++ b/internal/store/postgres/module_model.go @@ -8,8 +8,8 @@ import ( sq "github.com/Masterminds/squirrel" "github.com/jmoiron/sqlx" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/pkg/errors" ) const tableModules = "modules" diff --git a/internal/store/postgres/module_store.go b/internal/store/postgres/module_store.go index 32edbaba..84119150 100644 --- a/internal/store/postgres/module_store.go +++ b/internal/store/postgres/module_store.go @@ -6,8 +6,8 @@ import ( sq "github.com/Masterminds/squirrel" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/pkg/errors" ) func (st *Store) GetModule(ctx context.Context, urn string) (*module.Module, error) { diff --git a/internal/store/postgres/resource_model.go b/internal/store/postgres/resource_model.go index e1c7facf..543396bf 100644 --- a/internal/store/postgres/resource_model.go +++ b/internal/store/postgres/resource_model.go @@ -8,7 +8,7 @@ import ( sq "github.com/Masterminds/squirrel" "github.com/jmoiron/sqlx" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/pkg/errors" ) type resourceModel struct { diff --git a/internal/store/postgres/resource_store.go b/internal/store/postgres/resource_store.go index 04bb6e2f..a2aa6b8d 100644 --- a/internal/store/postgres/resource_store.go +++ b/internal/store/postgres/resource_store.go @@ -7,8 +7,8 @@ import ( sq "github.com/Masterminds/squirrel" "github.com/jmoiron/sqlx" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" ) func (st *Store) GetByURN(ctx context.Context, urn string) (*resource.Resource, error) { diff --git a/internal/store/postgres/revision_model.go b/internal/store/postgres/revision_model.go index 785727ae..fd222576 100644 --- a/internal/store/postgres/revision_model.go +++ b/internal/store/postgres/revision_model.go @@ -8,7 +8,7 @@ import ( sq "github.com/Masterminds/squirrel" "github.com/jmoiron/sqlx" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/pkg/errors" ) type revisionModel struct { diff --git a/internal/store/postgres/revision_store.go b/internal/store/postgres/revision_store.go index 7b08ba1e..116e9d1d 100644 --- a/internal/store/postgres/revision_store.go +++ b/internal/store/postgres/revision_store.go @@ -7,8 +7,8 @@ import ( sq "github.com/Masterminds/squirrel" "github.com/jmoiron/sqlx" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" ) func (st *Store) Revisions(ctx context.Context, selector resource.RevisionsSelector) ([]resource.Revision, error) { diff --git a/internal/store/postgres/utils.go b/internal/store/postgres/utils.go index c6c33c9a..caa003af 100644 --- a/internal/store/postgres/utils.go +++ b/internal/store/postgres/utils.go @@ -7,8 +7,8 @@ import ( "github.com/jmoiron/sqlx" "github.com/lib/pq" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" ) type TxFunc func(ctx context.Context, tx *sqlx.Tx) error diff --git a/main.go b/main.go index 0861d5cf..d2565722 100644 --- a/main.go +++ b/main.go @@ -5,7 +5,7 @@ import ( "os/signal" "syscall" - "github.com/odpf/entropy/cli" + "github.com/goto/entropy/cli" ) func main() { diff --git a/modules/firehose/config.go b/modules/firehose/config.go index 55a2166b..fc19e8ab 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -7,9 +7,9 @@ import ( "fmt" "time" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" - "github.com/odpf/entropy/pkg/helm" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/helm" ) const ( diff --git a/modules/firehose/kafka/consumer.go b/modules/firehose/kafka/consumer.go index 4a6a0520..ef35377c 100644 --- a/modules/firehose/kafka/consumer.go +++ b/modules/firehose/kafka/consumer.go @@ -3,7 +3,7 @@ package kafka import ( "context" - "github.com/odpf/entropy/pkg/kube" + "github.com/goto/entropy/pkg/kube" ) const ( diff --git a/modules/firehose/log.go b/modules/firehose/log.go index 921158ae..a0c01aab 100644 --- a/modules/firehose/log.go +++ b/modules/firehose/log.go @@ -4,10 +4,10 @@ import ( "context" "encoding/json" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/modules/kubernetes" - "github.com/odpf/entropy/pkg/errors" - "github.com/odpf/entropy/pkg/kube" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/modules/kubernetes" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/kube" ) func (*firehoseModule) Log(ctx context.Context, res module.ExpandedResource, filter map[string]string) (<-chan module.LogChunk, error) { diff --git a/modules/firehose/module.go b/modules/firehose/module.go index 7c9a8385..6de46e2f 100644 --- a/modules/firehose/module.go +++ b/modules/firehose/module.go @@ -4,8 +4,8 @@ import ( _ "embed" "encoding/json" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/modules/kubernetes" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/modules/kubernetes" ) const ( diff --git a/modules/firehose/output.go b/modules/firehose/output.go index 2dcb5f37..8e82d8df 100644 --- a/modules/firehose/output.go +++ b/modules/firehose/output.go @@ -4,10 +4,10 @@ import ( "context" "encoding/json" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/modules/kubernetes" - "github.com/odpf/entropy/pkg/errors" - "github.com/odpf/entropy/pkg/kube" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/modules/kubernetes" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/kube" ) type Output struct { diff --git a/modules/firehose/plan.go b/modules/firehose/plan.go index 66707f13..7328945e 100644 --- a/modules/firehose/plan.go +++ b/modules/firehose/plan.go @@ -4,9 +4,9 @@ import ( "context" "encoding/json" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" ) func (m *firehoseModule) Plan(_ context.Context, res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { diff --git a/modules/firehose/plan_test.go b/modules/firehose/plan_test.go index 0f215ac1..0d9e8023 100644 --- a/modules/firehose/plan_test.go +++ b/modules/firehose/plan_test.go @@ -8,9 +8,9 @@ import ( "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" ) func TestFirehoseModule_Plan(t *testing.T) { diff --git a/modules/firehose/sync.go b/modules/firehose/sync.go index dd2178e7..1b58347e 100644 --- a/modules/firehose/sync.go +++ b/modules/firehose/sync.go @@ -5,14 +5,14 @@ import ( "encoding/json" "time" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/modules/firehose/kafka" - "github.com/odpf/entropy/modules/kubernetes" - "github.com/odpf/entropy/pkg/errors" - "github.com/odpf/entropy/pkg/helm" - "github.com/odpf/entropy/pkg/kube" - "github.com/odpf/entropy/pkg/worker" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/modules/firehose/kafka" + "github.com/goto/entropy/modules/kubernetes" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/helm" + "github.com/goto/entropy/pkg/kube" + "github.com/goto/entropy/pkg/worker" ) const ( diff --git a/modules/kubernetes/kubernetes.go b/modules/kubernetes/kubernetes.go index 733899b9..bbddc9d6 100644 --- a/modules/kubernetes/kubernetes.go +++ b/modules/kubernetes/kubernetes.go @@ -8,10 +8,10 @@ import ( "k8s.io/apimachinery/pkg/version" "k8s.io/client-go/kubernetes" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/core/resource" - "github.com/odpf/entropy/pkg/errors" - "github.com/odpf/entropy/pkg/kube" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/kube" ) //go:embed config_schema.json diff --git a/modules/registry.go b/modules/registry.go index d507850c..6853399c 100644 --- a/modules/registry.go +++ b/modules/registry.go @@ -5,8 +5,8 @@ import ( "reflect" "sync" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/pkg/errors" ) // Registry maintains a list of supported/enabled modules. diff --git a/modules/registry_test.go b/modules/registry_test.go index 7e4b388a..bf1bc7c2 100644 --- a/modules/registry_test.go +++ b/modules/registry_test.go @@ -9,10 +9,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/odpf/entropy/core/mocks" - "github.com/odpf/entropy/core/module" - "github.com/odpf/entropy/modules" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/core/mocks" + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/modules" + "github.com/goto/entropy/pkg/errors" ) func TestRegistry_GetDriver(t *testing.T) { diff --git a/pkg/common/common.go b/pkg/common/common.go new file mode 100644 index 00000000..44c66ee7 --- /dev/null +++ b/pkg/common/common.go @@ -0,0 +1,24 @@ +package common + +import ( + "context" + + commonv1 "github.com/goto/entropy/proto/gotocompany/common/v1" +) + +type CommonService struct { + commonv1.UnimplementedCommonServiceServer + version *commonv1.Version +} + +func New(version *commonv1.Version) *CommonService { + return &CommonService{ + version: version, + } +} + +func (c *CommonService) GetVersion(context.Context, *commonv1.GetVersionRequest) (*commonv1.GetVersionResponse, error) { + return &commonv1.GetVersionResponse{ + Server: c.version, + }, nil +} diff --git a/pkg/errors/errors_test.go b/pkg/errors/errors_test.go index 8665e046..e83981a2 100644 --- a/pkg/errors/errors_test.go +++ b/pkg/errors/errors_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/pkg/errors" ) func Test_E(t *testing.T) { diff --git a/pkg/helm/client.go b/pkg/helm/client.go index d8101976..5059b00e 100644 --- a/pkg/helm/client.go +++ b/pkg/helm/client.go @@ -9,7 +9,7 @@ import ( "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd/api" - "github.com/odpf/entropy/pkg/kube" + "github.com/goto/entropy/pkg/kube" ) type Config struct { diff --git a/pkg/helm/release.go b/pkg/helm/release.go index 94b20612..fdcb575b 100644 --- a/pkg/helm/release.go +++ b/pkg/helm/release.go @@ -13,7 +13,7 @@ import ( "helm.sh/helm/v3/pkg/chart/loader" "helm.sh/helm/v3/pkg/release" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/pkg/errors" ) var ( diff --git a/pkg/kube/client.go b/pkg/kube/client.go index a41fd01c..bd933e35 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -22,7 +22,7 @@ import ( typedbatchv1 "k8s.io/client-go/kubernetes/typed/batch/v1" "k8s.io/client-go/rest" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/pkg/errors" ) const ( diff --git a/pkg/kube/client_test.go b/pkg/kube/client_test.go index 104c32cf..6cb4339d 100644 --- a/pkg/kube/client_test.go +++ b/pkg/kube/client_test.go @@ -8,7 +8,7 @@ import ( "os" "testing" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/pkg/errors" "github.com/stretchr/testify/assert" ) diff --git a/pkg/version/version.go b/pkg/version/version.go index 5ae42c77..2d34cca3 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -5,7 +5,8 @@ import ( "runtime" "time" - commonv1 "go.buf.build/odpf/gw/odpf/proton/odpf/common/v1" + commonv1 "github.com/goto/entropy/proto/gotocompany/common/v1" + "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/pkg/worker/example/main.go b/pkg/worker/example/main.go index ec3c97e9..fada2325 100644 --- a/pkg/worker/example/main.go +++ b/pkg/worker/example/main.go @@ -9,9 +9,9 @@ import ( "go.uber.org/zap" - "github.com/odpf/entropy/pkg/errors" - "github.com/odpf/entropy/pkg/worker" - "github.com/odpf/entropy/pkg/worker/pgq" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/worker" + "github.com/goto/entropy/pkg/worker/pgq" ) var ( diff --git a/pkg/worker/job_test.go b/pkg/worker/job_test.go index 70ecf616..f47e36d2 100644 --- a/pkg/worker/job_test.go +++ b/pkg/worker/job_test.go @@ -8,8 +8,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" - "github.com/odpf/entropy/pkg/errors" - "github.com/odpf/entropy/pkg/worker" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/worker" ) func TestJob_Attempt(t *testing.T) { diff --git a/pkg/worker/mocks/job_queue.go b/pkg/worker/mocks/job_queue.go index 19e4bb79..7ca410fd 100644 --- a/pkg/worker/mocks/job_queue.go +++ b/pkg/worker/mocks/job_queue.go @@ -1,11 +1,11 @@ -// Code generated by mockery v2.10.4. DO NOT EDIT. +// Code generated by mockery v2.14.0. DO NOT EDIT. package mocks import ( context "context" - worker "github.com/odpf/entropy/pkg/worker" + worker "github.com/goto/entropy/pkg/worker" mock "github.com/stretchr/testify/mock" ) @@ -112,3 +112,18 @@ func (_c *JobQueue_Enqueue_Call) Return(_a0 error) *JobQueue_Enqueue_Call { _c.Call.Return(_a0) return _c } + +type mockConstructorTestingTNewJobQueue interface { + mock.TestingT + Cleanup(func()) +} + +// NewJobQueue creates a new instance of JobQueue. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewJobQueue(t mockConstructorTestingTNewJobQueue) *JobQueue { + mock := &JobQueue{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/worker/pgq/pgq.go b/pkg/worker/pgq/pgq.go index 6113b184..754ef1a6 100644 --- a/pkg/worker/pgq/pgq.go +++ b/pkg/worker/pgq/pgq.go @@ -12,8 +12,8 @@ import ( sq "github.com/Masterminds/squirrel" "github.com/lib/pq" - "github.com/odpf/entropy/pkg/errors" - "github.com/odpf/entropy/pkg/worker" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/worker" ) const ( diff --git a/pkg/worker/pgq/pgq_utils.go b/pkg/worker/pgq/pgq_utils.go index 224ec817..fdd48ae4 100644 --- a/pkg/worker/pgq/pgq_utils.go +++ b/pkg/worker/pgq/pgq_utils.go @@ -7,7 +7,7 @@ import ( sq "github.com/Masterminds/squirrel" - "github.com/odpf/entropy/pkg/worker" + "github.com/goto/entropy/pkg/worker" ) type txnFn func(ctx context.Context, tx *sql.Tx) error diff --git a/pkg/worker/worker.go b/pkg/worker/worker.go index c5822957..70bcf8d1 100644 --- a/pkg/worker/worker.go +++ b/pkg/worker/worker.go @@ -8,7 +8,7 @@ import ( "go.uber.org/zap" - "github.com/odpf/entropy/pkg/errors" + "github.com/goto/entropy/pkg/errors" ) // Worker provides asynchronous job processing using a job-queue. diff --git a/pkg/worker/worker_test.go b/pkg/worker/worker_test.go index 3dcd4bbe..6392a0fa 100644 --- a/pkg/worker/worker_test.go +++ b/pkg/worker/worker_test.go @@ -9,9 +9,9 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/odpf/entropy/pkg/errors" - "github.com/odpf/entropy/pkg/worker" - "github.com/odpf/entropy/pkg/worker/mocks" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/worker" + "github.com/goto/entropy/pkg/worker/mocks" ) func Test_New(t *testing.T) { diff --git a/proto/entropy.swagger.yaml b/proto/entropy.swagger.yaml new file mode 100644 index 00000000..0559c476 --- /dev/null +++ b/proto/entropy.swagger.yaml @@ -0,0 +1,564 @@ +swagger: "2.0" +info: + title: gotocompany/common/v1/service.proto + version: 0.1.0 +tags: + - name: CommonService + - name: ModuleService + - name: ResourceService +schemes: + - http +consumes: + - application/json +produces: + - application/json +paths: + /v1beta1/modules: + get: + operationId: ModuleService_ListModules + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/ListModulesResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpc.Status' + parameters: + - name: project + in: query + required: false + type: string + tags: + - ModuleService + post: + operationId: ModuleService_CreateModule + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/CreateModuleResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpc.Status' + parameters: + - name: module + in: body + required: true + schema: + $ref: '#/definitions/Module' + tags: + - ModuleService + /v1beta1/modules/{urn}: + get: + operationId: ModuleService_GetModule + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/GetModuleResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpc.Status' + parameters: + - name: urn + in: path + required: true + type: string + tags: + - ModuleService + delete: + operationId: ModuleService_DeleteModule + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/DeleteModuleResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpc.Status' + parameters: + - name: urn + in: path + required: true + type: string + tags: + - ModuleService + patch: + operationId: ModuleService_UpdateModule + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/UpdateModuleResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpc.Status' + parameters: + - name: urn + in: path + required: true + type: string + - name: body + in: body + required: true + schema: + type: object + properties: + configs: {} + tags: + - ModuleService + /v1beta1/resources: + get: + operationId: ResourceService_ListResources + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/ListResourcesResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpc.Status' + parameters: + - name: project + in: query + required: false + type: string + - name: kind + in: query + required: false + type: string + tags: + - ResourceService + post: + operationId: ResourceService_CreateResource + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/CreateResourceResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpc.Status' + parameters: + - name: resource + in: body + required: true + schema: + $ref: '#/definitions/Resource' + tags: + - ResourceService + /v1beta1/resources/{urn}: + get: + operationId: ResourceService_GetResource + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/GetResourceResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpc.Status' + parameters: + - name: urn + in: path + required: true + type: string + tags: + - ResourceService + delete: + operationId: ResourceService_DeleteResource + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/DeleteResourceResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpc.Status' + parameters: + - name: urn + in: path + required: true + type: string + tags: + - ResourceService + patch: + operationId: ResourceService_UpdateResource + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/UpdateResourceResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpc.Status' + parameters: + - name: urn + in: path + required: true + type: string + - name: body + in: body + required: true + schema: + type: object + properties: + labels: + type: object + additionalProperties: + type: string + new_spec: + $ref: '#/definitions/ResourceSpec' + tags: + - ResourceService + /v1beta1/resources/{urn}/actions/{action}: + post: + operationId: ResourceService_ApplyAction + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/ApplyActionResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpc.Status' + parameters: + - name: urn + in: path + required: true + type: string + - name: action + in: path + required: true + type: string + - name: params + in: body + required: true + schema: {} + tags: + - ResourceService + /v1beta1/resources/{urn}/logs: + get: + operationId: ResourceService_GetLog + responses: + "200": + description: A successful response.(streaming responses) + schema: + type: object + properties: + error: + $ref: '#/definitions/rpc.Status' + result: + $ref: '#/definitions/GetLogResponse' + title: Stream result of GetLogResponse + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpc.Status' + parameters: + - name: urn + in: path + required: true + type: string + tags: + - ResourceService + /v1beta1/resources/{urn}/revisions: + get: + operationId: ResourceService_GetResourceRevisions + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/GetResourceRevisionsResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpc.Status' + parameters: + - name: urn + in: path + required: true + type: string + tags: + - ResourceService + /v1/version: + post: + operationId: CommonService_GetVersion + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/GetVersionResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpc.Status' + parameters: + - name: body + in: body + required: true + schema: + $ref: '#/definitions/GetVersionRequest' + tags: + - CommonService +definitions: + Any: + type: object + properties: + '@type': + type: string + additionalProperties: {} + ApplyActionResponse: + type: object + properties: + resource: + $ref: '#/definitions/Resource' + CreateModuleResponse: + type: object + properties: + module: + $ref: '#/definitions/Module' + CreateResourceResponse: + type: object + properties: + resource: + $ref: '#/definitions/Resource' + DeleteModuleResponse: + type: object + DeleteResourceResponse: + type: object + GetLogResponse: + type: object + properties: + chunk: + $ref: '#/definitions/LogChunk' + GetModuleResponse: + type: object + properties: + module: + $ref: '#/definitions/Module' + GetResourceResponse: + type: object + properties: + resource: + $ref: '#/definitions/Resource' + GetResourceRevisionsResponse: + type: object + properties: + revisions: + type: array + items: + $ref: '#/definitions/ResourceRevision' + GetVersionRequest: + type: object + properties: + client: + $ref: '#/definitions/Version' + GetVersionResponse: + type: object + properties: + server: + $ref: '#/definitions/Version' + ListModulesResponse: + type: object + properties: + modules: + type: array + items: + $ref: '#/definitions/Module' + ListResourcesResponse: + type: object + properties: + resources: + type: array + items: + $ref: '#/definitions/Resource' + ListString: + type: object + properties: + values: + type: array + items: + type: string + LogChunk: + type: object + properties: + data: + type: string + format: byte + labels: + type: object + additionalProperties: + type: string + LogOptions: + type: object + properties: + filters: + type: object + additionalProperties: + $ref: '#/definitions/ListString' + Module: + type: object + properties: + configs: {} + created_at: + type: string + format: date-time + name: + type: string + project: + type: string + updated_at: + type: string + format: date-time + urn: + type: string + NullValue: + type: string + enum: + - NULL_VALUE + default: NULL_VALUE + description: |- + `NullValue` is a singleton enumeration to represent the null value for the + `Value` type union. + + The JSON representation for `NullValue` is JSON `null`. + + - NULL_VALUE: Null value. + Resource: + type: object + properties: + created_at: + type: string + format: date-time + kind: + type: string + labels: + type: object + additionalProperties: + type: string + name: + type: string + project: + type: string + spec: + $ref: '#/definitions/ResourceSpec' + state: + $ref: '#/definitions/ResourceState' + updated_at: + type: string + format: date-time + urn: + type: string + ResourceDependency: + type: object + properties: + key: + type: string + description: |- + Key should be as defined by the module being used for + the resource. + value: + type: string + description: Value should refer to an existing resource via URN. + ResourceRevision: + type: object + properties: + created_at: + type: string + format: date-time + id: + type: string + labels: + type: object + additionalProperties: + type: string + reason: + type: string + spec: + $ref: '#/definitions/ResourceSpec' + urn: + type: string + ResourceSpec: + type: object + properties: + configs: {} + dependencies: + type: array + items: + $ref: '#/definitions/ResourceDependency' + description: |- + dependencies can be used to refer to other existing resources + as dependency of this resource. + ResourceState: + type: object + properties: + log_options: + $ref: '#/definitions/LogOptions' + module_data: + type: string + format: byte + output: {} + status: + $ref: '#/definitions/ResourceState.Status' + ResourceState.Status: + type: string + enum: + - STATUS_UNSPECIFIED + - STATUS_PENDING + - STATUS_ERROR + - STATUS_DELETED + - STATUS_COMPLETED + default: STATUS_UNSPECIFIED + UpdateModuleResponse: + type: object + properties: + module: + $ref: '#/definitions/Module' + UpdateResourceResponse: + type: object + properties: + resource: + $ref: '#/definitions/Resource' + Version: + type: object + properties: + architecture: + type: string + build_time: + type: string + format: date-time + commit: + type: string + lang_version: + type: string + os: + type: string + version: + type: string + rpc.Status: + type: object + properties: + code: + type: integer + format: int32 + details: + type: array + items: + $ref: '#/definitions/Any' + message: + type: string +externalDocs: + description: Common endpoints for all services diff --git a/proto/gotocompany/common/v1/service.pb.go b/proto/gotocompany/common/v1/service.pb.go new file mode 100644 index 00000000..5de1cb00 --- /dev/null +++ b/proto/gotocompany/common/v1/service.pb.go @@ -0,0 +1,357 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc (unknown) +// source: gotocompany/common/v1/service.proto + +package v1 + +import ( + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type GetVersionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Client *Version `protobuf:"bytes,1,opt,name=client,proto3" json:"client,omitempty"` +} + +func (x *GetVersionRequest) Reset() { + *x = GetVersionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_common_v1_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetVersionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetVersionRequest) ProtoMessage() {} + +func (x *GetVersionRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_common_v1_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetVersionRequest.ProtoReflect.Descriptor instead. +func (*GetVersionRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_common_v1_service_proto_rawDescGZIP(), []int{0} +} + +func (x *GetVersionRequest) GetClient() *Version { + if x != nil { + return x.Client + } + return nil +} + +type GetVersionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Server *Version `protobuf:"bytes,1,opt,name=server,proto3" json:"server,omitempty"` +} + +func (x *GetVersionResponse) Reset() { + *x = GetVersionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_common_v1_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetVersionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetVersionResponse) ProtoMessage() {} + +func (x *GetVersionResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_common_v1_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetVersionResponse.ProtoReflect.Descriptor instead. +func (*GetVersionResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_common_v1_service_proto_rawDescGZIP(), []int{1} +} + +func (x *GetVersionResponse) GetServer() *Version { + if x != nil { + return x.Server + } + return nil +} + +type Version struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + Commit string `protobuf:"bytes,2,opt,name=commit,proto3" json:"commit,omitempty"` + BuildTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=build_time,json=buildTime,proto3" json:"build_time,omitempty"` + LangVersion string `protobuf:"bytes,4,opt,name=lang_version,json=langVersion,proto3" json:"lang_version,omitempty"` + Os string `protobuf:"bytes,5,opt,name=os,proto3" json:"os,omitempty"` + Architecture string `protobuf:"bytes,6,opt,name=architecture,proto3" json:"architecture,omitempty"` +} + +func (x *Version) Reset() { + *x = Version{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_common_v1_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Version) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Version) ProtoMessage() {} + +func (x *Version) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_common_v1_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Version.ProtoReflect.Descriptor instead. +func (*Version) Descriptor() ([]byte, []int) { + return file_gotocompany_common_v1_service_proto_rawDescGZIP(), []int{2} +} + +func (x *Version) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *Version) GetCommit() string { + if x != nil { + return x.Commit + } + return "" +} + +func (x *Version) GetBuildTime() *timestamppb.Timestamp { + if x != nil { + return x.BuildTime + } + return nil +} + +func (x *Version) GetLangVersion() string { + if x != nil { + return x.LangVersion + } + return "" +} + +func (x *Version) GetOs() string { + if x != nil { + return x.Os + } + return "" +} + +func (x *Version) GetArchitecture() string { + if x != nil { + return x.Architecture + } + return "" +} + +var File_gotocompany_common_v1_service_proto protoreflect.FileDescriptor + +var file_gotocompany_common_v1_service_proto_rawDesc = []byte{ + 0x0a, 0x23, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2f, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x6e, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, + 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4b, 0x0a, 0x11, 0x47, + 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x36, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0x4c, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, + 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, + 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x06, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0xcd, 0x01, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x21, 0x0a, 0x0c, 0x6c, 0x61, 0x6e, 0x67, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6c, 0x61, 0x6e, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x6f, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, + 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, + 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x32, 0x8a, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x79, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x29, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x42, 0x8b, 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2e, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x42, 0x12, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x20, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x92, 0x41, 0x31, + 0x12, 0x07, 0x32, 0x05, 0x30, 0x2e, 0x31, 0x2e, 0x30, 0x2a, 0x01, 0x01, 0x72, 0x23, 0x0a, 0x21, + 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_gotocompany_common_v1_service_proto_rawDescOnce sync.Once + file_gotocompany_common_v1_service_proto_rawDescData = file_gotocompany_common_v1_service_proto_rawDesc +) + +func file_gotocompany_common_v1_service_proto_rawDescGZIP() []byte { + file_gotocompany_common_v1_service_proto_rawDescOnce.Do(func() { + file_gotocompany_common_v1_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_gotocompany_common_v1_service_proto_rawDescData) + }) + return file_gotocompany_common_v1_service_proto_rawDescData +} + +var file_gotocompany_common_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_gotocompany_common_v1_service_proto_goTypes = []interface{}{ + (*GetVersionRequest)(nil), // 0: gotocompany.common.v1.GetVersionRequest + (*GetVersionResponse)(nil), // 1: gotocompany.common.v1.GetVersionResponse + (*Version)(nil), // 2: gotocompany.common.v1.Version + (*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp +} +var file_gotocompany_common_v1_service_proto_depIdxs = []int32{ + 2, // 0: gotocompany.common.v1.GetVersionRequest.client:type_name -> gotocompany.common.v1.Version + 2, // 1: gotocompany.common.v1.GetVersionResponse.server:type_name -> gotocompany.common.v1.Version + 3, // 2: gotocompany.common.v1.Version.build_time:type_name -> google.protobuf.Timestamp + 0, // 3: gotocompany.common.v1.CommonService.GetVersion:input_type -> gotocompany.common.v1.GetVersionRequest + 1, // 4: gotocompany.common.v1.CommonService.GetVersion:output_type -> gotocompany.common.v1.GetVersionResponse + 4, // [4:5] is the sub-list for method output_type + 3, // [3:4] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_gotocompany_common_v1_service_proto_init() } +func file_gotocompany_common_v1_service_proto_init() { + if File_gotocompany_common_v1_service_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_gotocompany_common_v1_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetVersionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_common_v1_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetVersionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_common_v1_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Version); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_gotocompany_common_v1_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_gotocompany_common_v1_service_proto_goTypes, + DependencyIndexes: file_gotocompany_common_v1_service_proto_depIdxs, + MessageInfos: file_gotocompany_common_v1_service_proto_msgTypes, + }.Build() + File_gotocompany_common_v1_service_proto = out.File + file_gotocompany_common_v1_service_proto_rawDesc = nil + file_gotocompany_common_v1_service_proto_goTypes = nil + file_gotocompany_common_v1_service_proto_depIdxs = nil +} diff --git a/proto/gotocompany/common/v1/service.pb.gw.go b/proto/gotocompany/common/v1/service.pb.gw.go new file mode 100644 index 00000000..457b50f9 --- /dev/null +++ b/proto/gotocompany/common/v1/service.pb.gw.go @@ -0,0 +1,171 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: gotocompany/common/v1/service.proto + +/* +Package v1 is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package v1 + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +func request_CommonService_GetVersion_0(ctx context.Context, marshaler runtime.Marshaler, client CommonServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetVersionRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetVersion(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_CommonService_GetVersion_0(ctx context.Context, marshaler runtime.Marshaler, server CommonServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetVersionRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetVersion(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterCommonServiceHandlerServer registers the http handlers for service CommonService to "mux". +// UnaryRPC :call CommonServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterCommonServiceHandlerFromEndpoint instead. +func RegisterCommonServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server CommonServiceServer) error { + + mux.Handle("POST", pattern_CommonService_GetVersion_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/gotocompany.common.v1.CommonService/GetVersion", runtime.WithHTTPPathPattern("/v1/version")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_CommonService_GetVersion_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_CommonService_GetVersion_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterCommonServiceHandlerFromEndpoint is same as RegisterCommonServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterCommonServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterCommonServiceHandler(ctx, mux, conn) +} + +// RegisterCommonServiceHandler registers the http handlers for service CommonService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterCommonServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterCommonServiceHandlerClient(ctx, mux, NewCommonServiceClient(conn)) +} + +// RegisterCommonServiceHandlerClient registers the http handlers for service CommonService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "CommonServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "CommonServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "CommonServiceClient" to call the correct interceptors. +func RegisterCommonServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client CommonServiceClient) error { + + mux.Handle("POST", pattern_CommonService_GetVersion_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/gotocompany.common.v1.CommonService/GetVersion", runtime.WithHTTPPathPattern("/v1/version")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_CommonService_GetVersion_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_CommonService_GetVersion_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_CommonService_GetVersion_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "version"}, "")) +) + +var ( + forward_CommonService_GetVersion_0 = runtime.ForwardResponseMessage +) diff --git a/proto/gotocompany/common/v1/service.pb.validate.go b/proto/gotocompany/common/v1/service.pb.validate.go new file mode 100644 index 00000000..0588dd5f --- /dev/null +++ b/proto/gotocompany/common/v1/service.pb.validate.go @@ -0,0 +1,432 @@ +// Code generated by protoc-gen-validate. DO NOT EDIT. +// source: gotocompany/common/v1/service.proto + +package v1 + +import ( + "bytes" + "errors" + "fmt" + "net" + "net/mail" + "net/url" + "regexp" + "sort" + "strings" + "time" + "unicode/utf8" + + "google.golang.org/protobuf/types/known/anypb" +) + +// ensure the imports are used +var ( + _ = bytes.MinRead + _ = errors.New("") + _ = fmt.Print + _ = utf8.UTFMax + _ = (*regexp.Regexp)(nil) + _ = (*strings.Reader)(nil) + _ = net.IPv4len + _ = time.Duration(0) + _ = (*url.URL)(nil) + _ = (*mail.Address)(nil) + _ = anypb.Any{} + _ = sort.Sort +) + +// Validate checks the field values on GetVersionRequest with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *GetVersionRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetVersionRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GetVersionRequestMultiError, or nil if none found. +func (m *GetVersionRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *GetVersionRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetClient()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GetVersionRequestValidationError{ + field: "Client", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GetVersionRequestValidationError{ + field: "Client", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetClient()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GetVersionRequestValidationError{ + field: "Client", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return GetVersionRequestMultiError(errors) + } + return nil +} + +// GetVersionRequestMultiError is an error wrapping multiple validation errors +// returned by GetVersionRequest.ValidateAll() if the designated constraints +// aren't met. +type GetVersionRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetVersionRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetVersionRequestMultiError) AllErrors() []error { return m } + +// GetVersionRequestValidationError is the validation error returned by +// GetVersionRequest.Validate if the designated constraints aren't met. +type GetVersionRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetVersionRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetVersionRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetVersionRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetVersionRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetVersionRequestValidationError) ErrorName() string { + return "GetVersionRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e GetVersionRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetVersionRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetVersionRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetVersionRequestValidationError{} + +// Validate checks the field values on GetVersionResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GetVersionResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetVersionResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GetVersionResponseMultiError, or nil if none found. +func (m *GetVersionResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *GetVersionResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetServer()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GetVersionResponseValidationError{ + field: "Server", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GetVersionResponseValidationError{ + field: "Server", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetServer()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GetVersionResponseValidationError{ + field: "Server", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return GetVersionResponseMultiError(errors) + } + return nil +} + +// GetVersionResponseMultiError is an error wrapping multiple validation errors +// returned by GetVersionResponse.ValidateAll() if the designated constraints +// aren't met. +type GetVersionResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetVersionResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetVersionResponseMultiError) AllErrors() []error { return m } + +// GetVersionResponseValidationError is the validation error returned by +// GetVersionResponse.Validate if the designated constraints aren't met. +type GetVersionResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetVersionResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetVersionResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetVersionResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetVersionResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetVersionResponseValidationError) ErrorName() string { + return "GetVersionResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e GetVersionResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetVersionResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetVersionResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetVersionResponseValidationError{} + +// Validate checks the field values on Version with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *Version) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on Version with the rules defined in the +// proto definition for this message. If any rules are violated, the result is +// a list of violation errors wrapped in VersionMultiError, or nil if none found. +func (m *Version) ValidateAll() error { + return m.validate(true) +} + +func (m *Version) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Version + + // no validation rules for Commit + + if all { + switch v := interface{}(m.GetBuildTime()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, VersionValidationError{ + field: "BuildTime", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, VersionValidationError{ + field: "BuildTime", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetBuildTime()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return VersionValidationError{ + field: "BuildTime", + reason: "embedded message failed validation", + cause: err, + } + } + } + + // no validation rules for LangVersion + + // no validation rules for Os + + // no validation rules for Architecture + + if len(errors) > 0 { + return VersionMultiError(errors) + } + return nil +} + +// VersionMultiError is an error wrapping multiple validation errors returned +// by Version.ValidateAll() if the designated constraints aren't met. +type VersionMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m VersionMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m VersionMultiError) AllErrors() []error { return m } + +// VersionValidationError is the validation error returned by Version.Validate +// if the designated constraints aren't met. +type VersionValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e VersionValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e VersionValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e VersionValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e VersionValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e VersionValidationError) ErrorName() string { return "VersionValidationError" } + +// Error satisfies the builtin error interface +func (e VersionValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sVersion.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = VersionValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = VersionValidationError{} diff --git a/proto/gotocompany/common/v1/service_grpc.pb.go b/proto/gotocompany/common/v1/service_grpc.pb.go new file mode 100644 index 00000000..13c31ab3 --- /dev/null +++ b/proto/gotocompany/common/v1/service_grpc.pb.go @@ -0,0 +1,101 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// CommonServiceClient is the client API for CommonService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type CommonServiceClient interface { + GetVersion(ctx context.Context, in *GetVersionRequest, opts ...grpc.CallOption) (*GetVersionResponse, error) +} + +type commonServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewCommonServiceClient(cc grpc.ClientConnInterface) CommonServiceClient { + return &commonServiceClient{cc} +} + +func (c *commonServiceClient) GetVersion(ctx context.Context, in *GetVersionRequest, opts ...grpc.CallOption) (*GetVersionResponse, error) { + out := new(GetVersionResponse) + err := c.cc.Invoke(ctx, "/gotocompany.common.v1.CommonService/GetVersion", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// CommonServiceServer is the server API for CommonService service. +// All implementations must embed UnimplementedCommonServiceServer +// for forward compatibility +type CommonServiceServer interface { + GetVersion(context.Context, *GetVersionRequest) (*GetVersionResponse, error) + mustEmbedUnimplementedCommonServiceServer() +} + +// UnimplementedCommonServiceServer must be embedded to have forward compatible implementations. +type UnimplementedCommonServiceServer struct { +} + +func (UnimplementedCommonServiceServer) GetVersion(context.Context, *GetVersionRequest) (*GetVersionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetVersion not implemented") +} +func (UnimplementedCommonServiceServer) mustEmbedUnimplementedCommonServiceServer() {} + +// UnsafeCommonServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to CommonServiceServer will +// result in compilation errors. +type UnsafeCommonServiceServer interface { + mustEmbedUnimplementedCommonServiceServer() +} + +func RegisterCommonServiceServer(s grpc.ServiceRegistrar, srv CommonServiceServer) { + s.RegisterService(&CommonService_ServiceDesc, srv) +} + +func _CommonService_GetVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetVersionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CommonServiceServer).GetVersion(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gotocompany.common.v1.CommonService/GetVersion", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CommonServiceServer).GetVersion(ctx, req.(*GetVersionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// CommonService_ServiceDesc is the grpc.ServiceDesc for CommonService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var CommonService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "gotocompany.common.v1.CommonService", + HandlerType: (*CommonServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetVersion", + Handler: _CommonService_GetVersion_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "gotocompany/common/v1/service.proto", +} diff --git a/proto/gotocompany/entropy/v1beta1/module.pb.go b/proto/gotocompany/entropy/v1beta1/module.pb.go new file mode 100644 index 00000000..e4c447b2 --- /dev/null +++ b/proto/gotocompany/entropy/v1beta1/module.pb.go @@ -0,0 +1,922 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc (unknown) +// source: gotocompany/entropy/v1beta1/module.proto + +package entropyv1beta1 + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + structpb "google.golang.org/protobuf/types/known/structpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Module struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Urn string `protobuf:"bytes,1,opt,name=urn,proto3" json:"urn,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Project string `protobuf:"bytes,3,opt,name=project,proto3" json:"project,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + Configs *structpb.Value `protobuf:"bytes,7,opt,name=configs,proto3" json:"configs,omitempty"` +} + +func (x *Module) Reset() { + *x = Module{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Module) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Module) ProtoMessage() {} + +func (x *Module) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Module.ProtoReflect.Descriptor instead. +func (*Module) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_module_proto_rawDescGZIP(), []int{0} +} + +func (x *Module) GetUrn() string { + if x != nil { + return x.Urn + } + return "" +} + +func (x *Module) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Module) GetProject() string { + if x != nil { + return x.Project + } + return "" +} + +func (x *Module) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Module) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *Module) GetConfigs() *structpb.Value { + if x != nil { + return x.Configs + } + return nil +} + +type ListModulesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"` +} + +func (x *ListModulesRequest) Reset() { + *x = ListModulesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListModulesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListModulesRequest) ProtoMessage() {} + +func (x *ListModulesRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListModulesRequest.ProtoReflect.Descriptor instead. +func (*ListModulesRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_module_proto_rawDescGZIP(), []int{1} +} + +func (x *ListModulesRequest) GetProject() string { + if x != nil { + return x.Project + } + return "" +} + +type ListModulesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Modules []*Module `protobuf:"bytes,1,rep,name=modules,proto3" json:"modules,omitempty"` +} + +func (x *ListModulesResponse) Reset() { + *x = ListModulesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListModulesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListModulesResponse) ProtoMessage() {} + +func (x *ListModulesResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListModulesResponse.ProtoReflect.Descriptor instead. +func (*ListModulesResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_module_proto_rawDescGZIP(), []int{2} +} + +func (x *ListModulesResponse) GetModules() []*Module { + if x != nil { + return x.Modules + } + return nil +} + +type GetModuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Urn string `protobuf:"bytes,1,opt,name=urn,proto3" json:"urn,omitempty"` +} + +func (x *GetModuleRequest) Reset() { + *x = GetModuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetModuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetModuleRequest) ProtoMessage() {} + +func (x *GetModuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetModuleRequest.ProtoReflect.Descriptor instead. +func (*GetModuleRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_module_proto_rawDescGZIP(), []int{3} +} + +func (x *GetModuleRequest) GetUrn() string { + if x != nil { + return x.Urn + } + return "" +} + +type GetModuleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Module *Module `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"` +} + +func (x *GetModuleResponse) Reset() { + *x = GetModuleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetModuleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetModuleResponse) ProtoMessage() {} + +func (x *GetModuleResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetModuleResponse.ProtoReflect.Descriptor instead. +func (*GetModuleResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_module_proto_rawDescGZIP(), []int{4} +} + +func (x *GetModuleResponse) GetModule() *Module { + if x != nil { + return x.Module + } + return nil +} + +type CreateModuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Module *Module `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"` +} + +func (x *CreateModuleRequest) Reset() { + *x = CreateModuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateModuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateModuleRequest) ProtoMessage() {} + +func (x *CreateModuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateModuleRequest.ProtoReflect.Descriptor instead. +func (*CreateModuleRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_module_proto_rawDescGZIP(), []int{5} +} + +func (x *CreateModuleRequest) GetModule() *Module { + if x != nil { + return x.Module + } + return nil +} + +type CreateModuleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Module *Module `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"` +} + +func (x *CreateModuleResponse) Reset() { + *x = CreateModuleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateModuleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateModuleResponse) ProtoMessage() {} + +func (x *CreateModuleResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateModuleResponse.ProtoReflect.Descriptor instead. +func (*CreateModuleResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_module_proto_rawDescGZIP(), []int{6} +} + +func (x *CreateModuleResponse) GetModule() *Module { + if x != nil { + return x.Module + } + return nil +} + +type UpdateModuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Urn string `protobuf:"bytes,1,opt,name=urn,proto3" json:"urn,omitempty"` + Configs *structpb.Value `protobuf:"bytes,3,opt,name=configs,proto3" json:"configs,omitempty"` +} + +func (x *UpdateModuleRequest) Reset() { + *x = UpdateModuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateModuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateModuleRequest) ProtoMessage() {} + +func (x *UpdateModuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateModuleRequest.ProtoReflect.Descriptor instead. +func (*UpdateModuleRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_module_proto_rawDescGZIP(), []int{7} +} + +func (x *UpdateModuleRequest) GetUrn() string { + if x != nil { + return x.Urn + } + return "" +} + +func (x *UpdateModuleRequest) GetConfigs() *structpb.Value { + if x != nil { + return x.Configs + } + return nil +} + +type UpdateModuleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Module *Module `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"` +} + +func (x *UpdateModuleResponse) Reset() { + *x = UpdateModuleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateModuleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateModuleResponse) ProtoMessage() {} + +func (x *UpdateModuleResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateModuleResponse.ProtoReflect.Descriptor instead. +func (*UpdateModuleResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_module_proto_rawDescGZIP(), []int{8} +} + +func (x *UpdateModuleResponse) GetModule() *Module { + if x != nil { + return x.Module + } + return nil +} + +type DeleteModuleRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Urn string `protobuf:"bytes,1,opt,name=urn,proto3" json:"urn,omitempty"` +} + +func (x *DeleteModuleRequest) Reset() { + *x = DeleteModuleRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteModuleRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteModuleRequest) ProtoMessage() {} + +func (x *DeleteModuleRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteModuleRequest.ProtoReflect.Descriptor instead. +func (*DeleteModuleRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_module_proto_rawDescGZIP(), []int{9} +} + +func (x *DeleteModuleRequest) GetUrn() string { + if x != nil { + return x.Urn + } + return "" +} + +type DeleteModuleResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteModuleResponse) Reset() { + *x = DeleteModuleResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteModuleResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteModuleResponse) ProtoMessage() {} + +func (x *DeleteModuleResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_module_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteModuleResponse.ProtoReflect.Descriptor instead. +func (*DeleteModuleResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_module_proto_rawDescGZIP(), []int{10} +} + +var File_gotocompany_entropy_v1beta1_module_proto protoreflect.FileDescriptor + +var file_gotocompany_entropy_v1beta1_module_proto_rawDesc = []byte{ + 0x0a, 0x28, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2f, 0x65, 0x6e, + 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x67, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf6, 0x01, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, + 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, + 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, + 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x30, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x22, 0x2e, 0x0a, + 0x12, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x54, 0x0a, + 0x13, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, + 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x73, 0x22, 0x24, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x22, 0x50, 0x0a, 0x11, 0x47, 0x65, 0x74, + 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, + 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, + 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, + 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x22, 0x52, 0x0a, 0x13, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, + 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x22, + 0x53, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x06, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x22, 0x5f, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, + 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x30, 0x0a, + 0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x4a, + 0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0x53, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, + 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, + 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, + 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x22, 0x27, 0x0a, 0x13, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x75, 0x72, 0x6e, 0x22, 0x16, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xf0, 0x05, 0x0a, 0x0d, + 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x8a, 0x01, + 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x2f, 0x2e, + 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, + 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, + 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, + 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x8a, 0x01, 0x0a, 0x09, 0x47, + 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x2d, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, + 0x16, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x12, 0x95, 0x01, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x30, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x67, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x3a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x22, 0x10, 0x2f, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, + 0x96, 0x01, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x12, 0x30, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, + 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, + 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x01, 0x2a, + 0x32, 0x16, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x12, 0x93, 0x01, 0x0a, 0x0c, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x30, 0x2e, 0x67, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x67, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, + 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x2a, 0x16, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x42, 0x75, + 0x0a, 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, + 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x12, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x35, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x74, 0x6f, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2f, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_gotocompany_entropy_v1beta1_module_proto_rawDescOnce sync.Once + file_gotocompany_entropy_v1beta1_module_proto_rawDescData = file_gotocompany_entropy_v1beta1_module_proto_rawDesc +) + +func file_gotocompany_entropy_v1beta1_module_proto_rawDescGZIP() []byte { + file_gotocompany_entropy_v1beta1_module_proto_rawDescOnce.Do(func() { + file_gotocompany_entropy_v1beta1_module_proto_rawDescData = protoimpl.X.CompressGZIP(file_gotocompany_entropy_v1beta1_module_proto_rawDescData) + }) + return file_gotocompany_entropy_v1beta1_module_proto_rawDescData +} + +var file_gotocompany_entropy_v1beta1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_gotocompany_entropy_v1beta1_module_proto_goTypes = []interface{}{ + (*Module)(nil), // 0: gotocompany.entropy.v1beta1.Module + (*ListModulesRequest)(nil), // 1: gotocompany.entropy.v1beta1.ListModulesRequest + (*ListModulesResponse)(nil), // 2: gotocompany.entropy.v1beta1.ListModulesResponse + (*GetModuleRequest)(nil), // 3: gotocompany.entropy.v1beta1.GetModuleRequest + (*GetModuleResponse)(nil), // 4: gotocompany.entropy.v1beta1.GetModuleResponse + (*CreateModuleRequest)(nil), // 5: gotocompany.entropy.v1beta1.CreateModuleRequest + (*CreateModuleResponse)(nil), // 6: gotocompany.entropy.v1beta1.CreateModuleResponse + (*UpdateModuleRequest)(nil), // 7: gotocompany.entropy.v1beta1.UpdateModuleRequest + (*UpdateModuleResponse)(nil), // 8: gotocompany.entropy.v1beta1.UpdateModuleResponse + (*DeleteModuleRequest)(nil), // 9: gotocompany.entropy.v1beta1.DeleteModuleRequest + (*DeleteModuleResponse)(nil), // 10: gotocompany.entropy.v1beta1.DeleteModuleResponse + (*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp + (*structpb.Value)(nil), // 12: google.protobuf.Value +} +var file_gotocompany_entropy_v1beta1_module_proto_depIdxs = []int32{ + 11, // 0: gotocompany.entropy.v1beta1.Module.created_at:type_name -> google.protobuf.Timestamp + 11, // 1: gotocompany.entropy.v1beta1.Module.updated_at:type_name -> google.protobuf.Timestamp + 12, // 2: gotocompany.entropy.v1beta1.Module.configs:type_name -> google.protobuf.Value + 0, // 3: gotocompany.entropy.v1beta1.ListModulesResponse.modules:type_name -> gotocompany.entropy.v1beta1.Module + 0, // 4: gotocompany.entropy.v1beta1.GetModuleResponse.module:type_name -> gotocompany.entropy.v1beta1.Module + 0, // 5: gotocompany.entropy.v1beta1.CreateModuleRequest.module:type_name -> gotocompany.entropy.v1beta1.Module + 0, // 6: gotocompany.entropy.v1beta1.CreateModuleResponse.module:type_name -> gotocompany.entropy.v1beta1.Module + 12, // 7: gotocompany.entropy.v1beta1.UpdateModuleRequest.configs:type_name -> google.protobuf.Value + 0, // 8: gotocompany.entropy.v1beta1.UpdateModuleResponse.module:type_name -> gotocompany.entropy.v1beta1.Module + 1, // 9: gotocompany.entropy.v1beta1.ModuleService.ListModules:input_type -> gotocompany.entropy.v1beta1.ListModulesRequest + 3, // 10: gotocompany.entropy.v1beta1.ModuleService.GetModule:input_type -> gotocompany.entropy.v1beta1.GetModuleRequest + 5, // 11: gotocompany.entropy.v1beta1.ModuleService.CreateModule:input_type -> gotocompany.entropy.v1beta1.CreateModuleRequest + 7, // 12: gotocompany.entropy.v1beta1.ModuleService.UpdateModule:input_type -> gotocompany.entropy.v1beta1.UpdateModuleRequest + 9, // 13: gotocompany.entropy.v1beta1.ModuleService.DeleteModule:input_type -> gotocompany.entropy.v1beta1.DeleteModuleRequest + 2, // 14: gotocompany.entropy.v1beta1.ModuleService.ListModules:output_type -> gotocompany.entropy.v1beta1.ListModulesResponse + 4, // 15: gotocompany.entropy.v1beta1.ModuleService.GetModule:output_type -> gotocompany.entropy.v1beta1.GetModuleResponse + 6, // 16: gotocompany.entropy.v1beta1.ModuleService.CreateModule:output_type -> gotocompany.entropy.v1beta1.CreateModuleResponse + 8, // 17: gotocompany.entropy.v1beta1.ModuleService.UpdateModule:output_type -> gotocompany.entropy.v1beta1.UpdateModuleResponse + 10, // 18: gotocompany.entropy.v1beta1.ModuleService.DeleteModule:output_type -> gotocompany.entropy.v1beta1.DeleteModuleResponse + 14, // [14:19] is the sub-list for method output_type + 9, // [9:14] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name +} + +func init() { file_gotocompany_entropy_v1beta1_module_proto_init() } +func file_gotocompany_entropy_v1beta1_module_proto_init() { + if File_gotocompany_entropy_v1beta1_module_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_gotocompany_entropy_v1beta1_module_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Module); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_module_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListModulesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_module_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListModulesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_module_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetModuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_module_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetModuleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_module_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateModuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_module_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateModuleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_module_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateModuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_module_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateModuleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_module_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteModuleRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_module_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteModuleResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_gotocompany_entropy_v1beta1_module_proto_rawDesc, + NumEnums: 0, + NumMessages: 11, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_gotocompany_entropy_v1beta1_module_proto_goTypes, + DependencyIndexes: file_gotocompany_entropy_v1beta1_module_proto_depIdxs, + MessageInfos: file_gotocompany_entropy_v1beta1_module_proto_msgTypes, + }.Build() + File_gotocompany_entropy_v1beta1_module_proto = out.File + file_gotocompany_entropy_v1beta1_module_proto_rawDesc = nil + file_gotocompany_entropy_v1beta1_module_proto_goTypes = nil + file_gotocompany_entropy_v1beta1_module_proto_depIdxs = nil +} diff --git a/proto/gotocompany/entropy/v1beta1/module.pb.gw.go b/proto/gotocompany/entropy/v1beta1/module.pb.gw.go new file mode 100644 index 00000000..16655f87 --- /dev/null +++ b/proto/gotocompany/entropy/v1beta1/module.pb.gw.go @@ -0,0 +1,583 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: gotocompany/entropy/v1beta1/module.proto + +/* +Package entropyv1beta1 is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package entropyv1beta1 + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +var ( + filter_ModuleService_ListModules_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_ModuleService_ListModules_0(ctx context.Context, marshaler runtime.Marshaler, client ModuleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListModulesRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ModuleService_ListModules_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListModules(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ModuleService_ListModules_0(ctx context.Context, marshaler runtime.Marshaler, server ModuleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListModulesRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ModuleService_ListModules_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListModules(ctx, &protoReq) + return msg, metadata, err + +} + +func request_ModuleService_GetModule_0(ctx context.Context, marshaler runtime.Marshaler, client ModuleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetModuleRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + msg, err := client.GetModule(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ModuleService_GetModule_0(ctx context.Context, marshaler runtime.Marshaler, server ModuleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetModuleRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + msg, err := server.GetModule(ctx, &protoReq) + return msg, metadata, err + +} + +func request_ModuleService_CreateModule_0(ctx context.Context, marshaler runtime.Marshaler, client ModuleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateModuleRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Module); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.CreateModule(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ModuleService_CreateModule_0(ctx context.Context, marshaler runtime.Marshaler, server ModuleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateModuleRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Module); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.CreateModule(ctx, &protoReq) + return msg, metadata, err + +} + +func request_ModuleService_UpdateModule_0(ctx context.Context, marshaler runtime.Marshaler, client ModuleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateModuleRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + msg, err := client.UpdateModule(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ModuleService_UpdateModule_0(ctx context.Context, marshaler runtime.Marshaler, server ModuleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateModuleRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + msg, err := server.UpdateModule(ctx, &protoReq) + return msg, metadata, err + +} + +func request_ModuleService_DeleteModule_0(ctx context.Context, marshaler runtime.Marshaler, client ModuleServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteModuleRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + msg, err := client.DeleteModule(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ModuleService_DeleteModule_0(ctx context.Context, marshaler runtime.Marshaler, server ModuleServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteModuleRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + msg, err := server.DeleteModule(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterModuleServiceHandlerServer registers the http handlers for service ModuleService to "mux". +// UnaryRPC :call ModuleServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterModuleServiceHandlerFromEndpoint instead. +func RegisterModuleServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ModuleServiceServer) error { + + mux.Handle("GET", pattern_ModuleService_ListModules_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ModuleService/ListModules", runtime.WithHTTPPathPattern("/v1beta1/modules")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ModuleService_ListModules_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ModuleService_ListModules_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_ModuleService_GetModule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ModuleService/GetModule", runtime.WithHTTPPathPattern("/v1beta1/modules/{urn}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ModuleService_GetModule_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ModuleService_GetModule_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ModuleService_CreateModule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ModuleService/CreateModule", runtime.WithHTTPPathPattern("/v1beta1/modules")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ModuleService_CreateModule_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ModuleService_CreateModule_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PATCH", pattern_ModuleService_UpdateModule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ModuleService/UpdateModule", runtime.WithHTTPPathPattern("/v1beta1/modules/{urn}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ModuleService_UpdateModule_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ModuleService_UpdateModule_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_ModuleService_DeleteModule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ModuleService/DeleteModule", runtime.WithHTTPPathPattern("/v1beta1/modules/{urn}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ModuleService_DeleteModule_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ModuleService_DeleteModule_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterModuleServiceHandlerFromEndpoint is same as RegisterModuleServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterModuleServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterModuleServiceHandler(ctx, mux, conn) +} + +// RegisterModuleServiceHandler registers the http handlers for service ModuleService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterModuleServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterModuleServiceHandlerClient(ctx, mux, NewModuleServiceClient(conn)) +} + +// RegisterModuleServiceHandlerClient registers the http handlers for service ModuleService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ModuleServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ModuleServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "ModuleServiceClient" to call the correct interceptors. +func RegisterModuleServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ModuleServiceClient) error { + + mux.Handle("GET", pattern_ModuleService_ListModules_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ModuleService/ListModules", runtime.WithHTTPPathPattern("/v1beta1/modules")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ModuleService_ListModules_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ModuleService_ListModules_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_ModuleService_GetModule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ModuleService/GetModule", runtime.WithHTTPPathPattern("/v1beta1/modules/{urn}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ModuleService_GetModule_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ModuleService_GetModule_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ModuleService_CreateModule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ModuleService/CreateModule", runtime.WithHTTPPathPattern("/v1beta1/modules")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ModuleService_CreateModule_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ModuleService_CreateModule_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PATCH", pattern_ModuleService_UpdateModule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ModuleService/UpdateModule", runtime.WithHTTPPathPattern("/v1beta1/modules/{urn}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ModuleService_UpdateModule_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ModuleService_UpdateModule_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_ModuleService_DeleteModule_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ModuleService/DeleteModule", runtime.WithHTTPPathPattern("/v1beta1/modules/{urn}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ModuleService_DeleteModule_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ModuleService_DeleteModule_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_ModuleService_ListModules_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1beta1", "modules"}, "")) + + pattern_ModuleService_GetModule_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1beta1", "modules", "urn"}, "")) + + pattern_ModuleService_CreateModule_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1beta1", "modules"}, "")) + + pattern_ModuleService_UpdateModule_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1beta1", "modules", "urn"}, "")) + + pattern_ModuleService_DeleteModule_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1beta1", "modules", "urn"}, "")) +) + +var ( + forward_ModuleService_ListModules_0 = runtime.ForwardResponseMessage + + forward_ModuleService_GetModule_0 = runtime.ForwardResponseMessage + + forward_ModuleService_CreateModule_0 = runtime.ForwardResponseMessage + + forward_ModuleService_UpdateModule_0 = runtime.ForwardResponseMessage + + forward_ModuleService_DeleteModule_0 = runtime.ForwardResponseMessage +) diff --git a/proto/gotocompany/entropy/v1beta1/module.pb.validate.go b/proto/gotocompany/entropy/v1beta1/module.pb.validate.go new file mode 100644 index 00000000..52f2cb00 --- /dev/null +++ b/proto/gotocompany/entropy/v1beta1/module.pb.validate.go @@ -0,0 +1,1421 @@ +// Code generated by protoc-gen-validate. DO NOT EDIT. +// source: gotocompany/entropy/v1beta1/module.proto + +package entropyv1beta1 + +import ( + "bytes" + "errors" + "fmt" + "net" + "net/mail" + "net/url" + "regexp" + "sort" + "strings" + "time" + "unicode/utf8" + + "google.golang.org/protobuf/types/known/anypb" +) + +// ensure the imports are used +var ( + _ = bytes.MinRead + _ = errors.New("") + _ = fmt.Print + _ = utf8.UTFMax + _ = (*regexp.Regexp)(nil) + _ = (*strings.Reader)(nil) + _ = net.IPv4len + _ = time.Duration(0) + _ = (*url.URL)(nil) + _ = (*mail.Address)(nil) + _ = anypb.Any{} + _ = sort.Sort +) + +// Validate checks the field values on Module with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *Module) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on Module with the rules defined in the +// proto definition for this message. If any rules are violated, the result is +// a list of violation errors wrapped in ModuleMultiError, or nil if none found. +func (m *Module) ValidateAll() error { + return m.validate(true) +} + +func (m *Module) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Urn + + // no validation rules for Name + + // no validation rules for Project + + if all { + switch v := interface{}(m.GetCreatedAt()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ModuleValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ModuleValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetCreatedAt()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ModuleValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetUpdatedAt()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ModuleValidationError{ + field: "UpdatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ModuleValidationError{ + field: "UpdatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetUpdatedAt()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ModuleValidationError{ + field: "UpdatedAt", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetConfigs()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ModuleValidationError{ + field: "Configs", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ModuleValidationError{ + field: "Configs", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetConfigs()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ModuleValidationError{ + field: "Configs", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return ModuleMultiError(errors) + } + return nil +} + +// ModuleMultiError is an error wrapping multiple validation errors returned by +// Module.ValidateAll() if the designated constraints aren't met. +type ModuleMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ModuleMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ModuleMultiError) AllErrors() []error { return m } + +// ModuleValidationError is the validation error returned by Module.Validate if +// the designated constraints aren't met. +type ModuleValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ModuleValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ModuleValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ModuleValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ModuleValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ModuleValidationError) ErrorName() string { return "ModuleValidationError" } + +// Error satisfies the builtin error interface +func (e ModuleValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sModule.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ModuleValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ModuleValidationError{} + +// Validate checks the field values on ListModulesRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ListModulesRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListModulesRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListModulesRequestMultiError, or nil if none found. +func (m *ListModulesRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *ListModulesRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Project + + if len(errors) > 0 { + return ListModulesRequestMultiError(errors) + } + return nil +} + +// ListModulesRequestMultiError is an error wrapping multiple validation errors +// returned by ListModulesRequest.ValidateAll() if the designated constraints +// aren't met. +type ListModulesRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListModulesRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListModulesRequestMultiError) AllErrors() []error { return m } + +// ListModulesRequestValidationError is the validation error returned by +// ListModulesRequest.Validate if the designated constraints aren't met. +type ListModulesRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListModulesRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListModulesRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListModulesRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListModulesRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListModulesRequestValidationError) ErrorName() string { + return "ListModulesRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e ListModulesRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListModulesRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListModulesRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListModulesRequestValidationError{} + +// Validate checks the field values on ListModulesResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ListModulesResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListModulesResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListModulesResponseMultiError, or nil if none found. +func (m *ListModulesResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *ListModulesResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + for idx, item := range m.GetModules() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ListModulesResponseValidationError{ + field: fmt.Sprintf("Modules[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ListModulesResponseValidationError{ + field: fmt.Sprintf("Modules[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ListModulesResponseValidationError{ + field: fmt.Sprintf("Modules[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return ListModulesResponseMultiError(errors) + } + return nil +} + +// ListModulesResponseMultiError is an error wrapping multiple validation +// errors returned by ListModulesResponse.ValidateAll() if the designated +// constraints aren't met. +type ListModulesResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListModulesResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListModulesResponseMultiError) AllErrors() []error { return m } + +// ListModulesResponseValidationError is the validation error returned by +// ListModulesResponse.Validate if the designated constraints aren't met. +type ListModulesResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListModulesResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListModulesResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListModulesResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListModulesResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListModulesResponseValidationError) ErrorName() string { + return "ListModulesResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e ListModulesResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListModulesResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListModulesResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListModulesResponseValidationError{} + +// Validate checks the field values on GetModuleRequest with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *GetModuleRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetModuleRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GetModuleRequestMultiError, or nil if none found. +func (m *GetModuleRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *GetModuleRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Urn + + if len(errors) > 0 { + return GetModuleRequestMultiError(errors) + } + return nil +} + +// GetModuleRequestMultiError is an error wrapping multiple validation errors +// returned by GetModuleRequest.ValidateAll() if the designated constraints +// aren't met. +type GetModuleRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetModuleRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetModuleRequestMultiError) AllErrors() []error { return m } + +// GetModuleRequestValidationError is the validation error returned by +// GetModuleRequest.Validate if the designated constraints aren't met. +type GetModuleRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetModuleRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetModuleRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetModuleRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetModuleRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetModuleRequestValidationError) ErrorName() string { return "GetModuleRequestValidationError" } + +// Error satisfies the builtin error interface +func (e GetModuleRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetModuleRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetModuleRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetModuleRequestValidationError{} + +// Validate checks the field values on GetModuleResponse with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *GetModuleResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetModuleResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GetModuleResponseMultiError, or nil if none found. +func (m *GetModuleResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *GetModuleResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetModule()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GetModuleResponseValidationError{ + field: "Module", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GetModuleResponseValidationError{ + field: "Module", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetModule()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GetModuleResponseValidationError{ + field: "Module", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return GetModuleResponseMultiError(errors) + } + return nil +} + +// GetModuleResponseMultiError is an error wrapping multiple validation errors +// returned by GetModuleResponse.ValidateAll() if the designated constraints +// aren't met. +type GetModuleResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetModuleResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetModuleResponseMultiError) AllErrors() []error { return m } + +// GetModuleResponseValidationError is the validation error returned by +// GetModuleResponse.Validate if the designated constraints aren't met. +type GetModuleResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetModuleResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetModuleResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetModuleResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetModuleResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetModuleResponseValidationError) ErrorName() string { + return "GetModuleResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e GetModuleResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetModuleResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetModuleResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetModuleResponseValidationError{} + +// Validate checks the field values on CreateModuleRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *CreateModuleRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on CreateModuleRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// CreateModuleRequestMultiError, or nil if none found. +func (m *CreateModuleRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *CreateModuleRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetModule()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, CreateModuleRequestValidationError{ + field: "Module", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, CreateModuleRequestValidationError{ + field: "Module", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetModule()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return CreateModuleRequestValidationError{ + field: "Module", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return CreateModuleRequestMultiError(errors) + } + return nil +} + +// CreateModuleRequestMultiError is an error wrapping multiple validation +// errors returned by CreateModuleRequest.ValidateAll() if the designated +// constraints aren't met. +type CreateModuleRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m CreateModuleRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m CreateModuleRequestMultiError) AllErrors() []error { return m } + +// CreateModuleRequestValidationError is the validation error returned by +// CreateModuleRequest.Validate if the designated constraints aren't met. +type CreateModuleRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e CreateModuleRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e CreateModuleRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e CreateModuleRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e CreateModuleRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e CreateModuleRequestValidationError) ErrorName() string { + return "CreateModuleRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e CreateModuleRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sCreateModuleRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = CreateModuleRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = CreateModuleRequestValidationError{} + +// Validate checks the field values on CreateModuleResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *CreateModuleResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on CreateModuleResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// CreateModuleResponseMultiError, or nil if none found. +func (m *CreateModuleResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *CreateModuleResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetModule()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, CreateModuleResponseValidationError{ + field: "Module", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, CreateModuleResponseValidationError{ + field: "Module", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetModule()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return CreateModuleResponseValidationError{ + field: "Module", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return CreateModuleResponseMultiError(errors) + } + return nil +} + +// CreateModuleResponseMultiError is an error wrapping multiple validation +// errors returned by CreateModuleResponse.ValidateAll() if the designated +// constraints aren't met. +type CreateModuleResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m CreateModuleResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m CreateModuleResponseMultiError) AllErrors() []error { return m } + +// CreateModuleResponseValidationError is the validation error returned by +// CreateModuleResponse.Validate if the designated constraints aren't met. +type CreateModuleResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e CreateModuleResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e CreateModuleResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e CreateModuleResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e CreateModuleResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e CreateModuleResponseValidationError) ErrorName() string { + return "CreateModuleResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e CreateModuleResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sCreateModuleResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = CreateModuleResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = CreateModuleResponseValidationError{} + +// Validate checks the field values on UpdateModuleRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *UpdateModuleRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UpdateModuleRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// UpdateModuleRequestMultiError, or nil if none found. +func (m *UpdateModuleRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *UpdateModuleRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Urn + + if all { + switch v := interface{}(m.GetConfigs()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, UpdateModuleRequestValidationError{ + field: "Configs", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, UpdateModuleRequestValidationError{ + field: "Configs", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetConfigs()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return UpdateModuleRequestValidationError{ + field: "Configs", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return UpdateModuleRequestMultiError(errors) + } + return nil +} + +// UpdateModuleRequestMultiError is an error wrapping multiple validation +// errors returned by UpdateModuleRequest.ValidateAll() if the designated +// constraints aren't met. +type UpdateModuleRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UpdateModuleRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m UpdateModuleRequestMultiError) AllErrors() []error { return m } + +// UpdateModuleRequestValidationError is the validation error returned by +// UpdateModuleRequest.Validate if the designated constraints aren't met. +type UpdateModuleRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UpdateModuleRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UpdateModuleRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UpdateModuleRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UpdateModuleRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UpdateModuleRequestValidationError) ErrorName() string { + return "UpdateModuleRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e UpdateModuleRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sUpdateModuleRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UpdateModuleRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UpdateModuleRequestValidationError{} + +// Validate checks the field values on UpdateModuleResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *UpdateModuleResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UpdateModuleResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// UpdateModuleResponseMultiError, or nil if none found. +func (m *UpdateModuleResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *UpdateModuleResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetModule()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, UpdateModuleResponseValidationError{ + field: "Module", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, UpdateModuleResponseValidationError{ + field: "Module", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetModule()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return UpdateModuleResponseValidationError{ + field: "Module", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return UpdateModuleResponseMultiError(errors) + } + return nil +} + +// UpdateModuleResponseMultiError is an error wrapping multiple validation +// errors returned by UpdateModuleResponse.ValidateAll() if the designated +// constraints aren't met. +type UpdateModuleResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UpdateModuleResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m UpdateModuleResponseMultiError) AllErrors() []error { return m } + +// UpdateModuleResponseValidationError is the validation error returned by +// UpdateModuleResponse.Validate if the designated constraints aren't met. +type UpdateModuleResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UpdateModuleResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UpdateModuleResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UpdateModuleResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UpdateModuleResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UpdateModuleResponseValidationError) ErrorName() string { + return "UpdateModuleResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e UpdateModuleResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sUpdateModuleResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UpdateModuleResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UpdateModuleResponseValidationError{} + +// Validate checks the field values on DeleteModuleRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *DeleteModuleRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on DeleteModuleRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// DeleteModuleRequestMultiError, or nil if none found. +func (m *DeleteModuleRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *DeleteModuleRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Urn + + if len(errors) > 0 { + return DeleteModuleRequestMultiError(errors) + } + return nil +} + +// DeleteModuleRequestMultiError is an error wrapping multiple validation +// errors returned by DeleteModuleRequest.ValidateAll() if the designated +// constraints aren't met. +type DeleteModuleRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m DeleteModuleRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m DeleteModuleRequestMultiError) AllErrors() []error { return m } + +// DeleteModuleRequestValidationError is the validation error returned by +// DeleteModuleRequest.Validate if the designated constraints aren't met. +type DeleteModuleRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e DeleteModuleRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e DeleteModuleRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e DeleteModuleRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e DeleteModuleRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e DeleteModuleRequestValidationError) ErrorName() string { + return "DeleteModuleRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e DeleteModuleRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sDeleteModuleRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = DeleteModuleRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = DeleteModuleRequestValidationError{} + +// Validate checks the field values on DeleteModuleResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *DeleteModuleResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on DeleteModuleResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// DeleteModuleResponseMultiError, or nil if none found. +func (m *DeleteModuleResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *DeleteModuleResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return DeleteModuleResponseMultiError(errors) + } + return nil +} + +// DeleteModuleResponseMultiError is an error wrapping multiple validation +// errors returned by DeleteModuleResponse.ValidateAll() if the designated +// constraints aren't met. +type DeleteModuleResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m DeleteModuleResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m DeleteModuleResponseMultiError) AllErrors() []error { return m } + +// DeleteModuleResponseValidationError is the validation error returned by +// DeleteModuleResponse.Validate if the designated constraints aren't met. +type DeleteModuleResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e DeleteModuleResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e DeleteModuleResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e DeleteModuleResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e DeleteModuleResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e DeleteModuleResponseValidationError) ErrorName() string { + return "DeleteModuleResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e DeleteModuleResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sDeleteModuleResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = DeleteModuleResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = DeleteModuleResponseValidationError{} diff --git a/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go b/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go new file mode 100644 index 00000000..c469596d --- /dev/null +++ b/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go @@ -0,0 +1,245 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package entropyv1beta1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// ModuleServiceClient is the client API for ModuleService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ModuleServiceClient interface { + ListModules(ctx context.Context, in *ListModulesRequest, opts ...grpc.CallOption) (*ListModulesResponse, error) + GetModule(ctx context.Context, in *GetModuleRequest, opts ...grpc.CallOption) (*GetModuleResponse, error) + CreateModule(ctx context.Context, in *CreateModuleRequest, opts ...grpc.CallOption) (*CreateModuleResponse, error) + UpdateModule(ctx context.Context, in *UpdateModuleRequest, opts ...grpc.CallOption) (*UpdateModuleResponse, error) + DeleteModule(ctx context.Context, in *DeleteModuleRequest, opts ...grpc.CallOption) (*DeleteModuleResponse, error) +} + +type moduleServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewModuleServiceClient(cc grpc.ClientConnInterface) ModuleServiceClient { + return &moduleServiceClient{cc} +} + +func (c *moduleServiceClient) ListModules(ctx context.Context, in *ListModulesRequest, opts ...grpc.CallOption) (*ListModulesResponse, error) { + out := new(ListModulesResponse) + err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ModuleService/ListModules", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *moduleServiceClient) GetModule(ctx context.Context, in *GetModuleRequest, opts ...grpc.CallOption) (*GetModuleResponse, error) { + out := new(GetModuleResponse) + err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ModuleService/GetModule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *moduleServiceClient) CreateModule(ctx context.Context, in *CreateModuleRequest, opts ...grpc.CallOption) (*CreateModuleResponse, error) { + out := new(CreateModuleResponse) + err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ModuleService/CreateModule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *moduleServiceClient) UpdateModule(ctx context.Context, in *UpdateModuleRequest, opts ...grpc.CallOption) (*UpdateModuleResponse, error) { + out := new(UpdateModuleResponse) + err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ModuleService/UpdateModule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *moduleServiceClient) DeleteModule(ctx context.Context, in *DeleteModuleRequest, opts ...grpc.CallOption) (*DeleteModuleResponse, error) { + out := new(DeleteModuleResponse) + err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ModuleService/DeleteModule", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ModuleServiceServer is the server API for ModuleService service. +// All implementations must embed UnimplementedModuleServiceServer +// for forward compatibility +type ModuleServiceServer interface { + ListModules(context.Context, *ListModulesRequest) (*ListModulesResponse, error) + GetModule(context.Context, *GetModuleRequest) (*GetModuleResponse, error) + CreateModule(context.Context, *CreateModuleRequest) (*CreateModuleResponse, error) + UpdateModule(context.Context, *UpdateModuleRequest) (*UpdateModuleResponse, error) + DeleteModule(context.Context, *DeleteModuleRequest) (*DeleteModuleResponse, error) + mustEmbedUnimplementedModuleServiceServer() +} + +// UnimplementedModuleServiceServer must be embedded to have forward compatible implementations. +type UnimplementedModuleServiceServer struct { +} + +func (UnimplementedModuleServiceServer) ListModules(context.Context, *ListModulesRequest) (*ListModulesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListModules not implemented") +} +func (UnimplementedModuleServiceServer) GetModule(context.Context, *GetModuleRequest) (*GetModuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetModule not implemented") +} +func (UnimplementedModuleServiceServer) CreateModule(context.Context, *CreateModuleRequest) (*CreateModuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateModule not implemented") +} +func (UnimplementedModuleServiceServer) UpdateModule(context.Context, *UpdateModuleRequest) (*UpdateModuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateModule not implemented") +} +func (UnimplementedModuleServiceServer) DeleteModule(context.Context, *DeleteModuleRequest) (*DeleteModuleResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteModule not implemented") +} +func (UnimplementedModuleServiceServer) mustEmbedUnimplementedModuleServiceServer() {} + +// UnsafeModuleServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ModuleServiceServer will +// result in compilation errors. +type UnsafeModuleServiceServer interface { + mustEmbedUnimplementedModuleServiceServer() +} + +func RegisterModuleServiceServer(s grpc.ServiceRegistrar, srv ModuleServiceServer) { + s.RegisterService(&ModuleService_ServiceDesc, srv) +} + +func _ModuleService_ListModules_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListModulesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ModuleServiceServer).ListModules(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gotocompany.entropy.v1beta1.ModuleService/ListModules", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ModuleServiceServer).ListModules(ctx, req.(*ListModulesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ModuleService_GetModule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetModuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ModuleServiceServer).GetModule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gotocompany.entropy.v1beta1.ModuleService/GetModule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ModuleServiceServer).GetModule(ctx, req.(*GetModuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ModuleService_CreateModule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateModuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ModuleServiceServer).CreateModule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gotocompany.entropy.v1beta1.ModuleService/CreateModule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ModuleServiceServer).CreateModule(ctx, req.(*CreateModuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ModuleService_UpdateModule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateModuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ModuleServiceServer).UpdateModule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gotocompany.entropy.v1beta1.ModuleService/UpdateModule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ModuleServiceServer).UpdateModule(ctx, req.(*UpdateModuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ModuleService_DeleteModule_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteModuleRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ModuleServiceServer).DeleteModule(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gotocompany.entropy.v1beta1.ModuleService/DeleteModule", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ModuleServiceServer).DeleteModule(ctx, req.(*DeleteModuleRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// ModuleService_ServiceDesc is the grpc.ServiceDesc for ModuleService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ModuleService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "gotocompany.entropy.v1beta1.ModuleService", + HandlerType: (*ModuleServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ListModules", + Handler: _ModuleService_ListModules_Handler, + }, + { + MethodName: "GetModule", + Handler: _ModuleService_GetModule_Handler, + }, + { + MethodName: "CreateModule", + Handler: _ModuleService_CreateModule_Handler, + }, + { + MethodName: "UpdateModule", + Handler: _ModuleService_UpdateModule_Handler, + }, + { + MethodName: "DeleteModule", + Handler: _ModuleService_DeleteModule_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "gotocompany/entropy/v1beta1/module.proto", +} diff --git a/proto/gotocompany/entropy/v1beta1/resource.pb.go b/proto/gotocompany/entropy/v1beta1/resource.pb.go new file mode 100644 index 00000000..a7efff50 --- /dev/null +++ b/proto/gotocompany/entropy/v1beta1/resource.pb.go @@ -0,0 +1,2151 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc (unknown) +// source: gotocompany/entropy/v1beta1/resource.proto + +package entropyv1beta1 + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + structpb "google.golang.org/protobuf/types/known/structpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ResourceState_Status int32 + +const ( + ResourceState_STATUS_UNSPECIFIED ResourceState_Status = 0 + ResourceState_STATUS_PENDING ResourceState_Status = 1 + ResourceState_STATUS_ERROR ResourceState_Status = 2 + ResourceState_STATUS_DELETED ResourceState_Status = 3 + ResourceState_STATUS_COMPLETED ResourceState_Status = 4 +) + +// Enum value maps for ResourceState_Status. +var ( + ResourceState_Status_name = map[int32]string{ + 0: "STATUS_UNSPECIFIED", + 1: "STATUS_PENDING", + 2: "STATUS_ERROR", + 3: "STATUS_DELETED", + 4: "STATUS_COMPLETED", + } + ResourceState_Status_value = map[string]int32{ + "STATUS_UNSPECIFIED": 0, + "STATUS_PENDING": 1, + "STATUS_ERROR": 2, + "STATUS_DELETED": 3, + "STATUS_COMPLETED": 4, + } +) + +func (x ResourceState_Status) Enum() *ResourceState_Status { + p := new(ResourceState_Status) + *p = x + return p +} + +func (x ResourceState_Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ResourceState_Status) Descriptor() protoreflect.EnumDescriptor { + return file_gotocompany_entropy_v1beta1_resource_proto_enumTypes[0].Descriptor() +} + +func (ResourceState_Status) Type() protoreflect.EnumType { + return &file_gotocompany_entropy_v1beta1_resource_proto_enumTypes[0] +} + +func (x ResourceState_Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ResourceState_Status.Descriptor instead. +func (ResourceState_Status) EnumDescriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{4, 0} +} + +type ResourceDependency struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Key should be as defined by the module being used for + // the resource. + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // Value should refer to an existing resource via URN. + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *ResourceDependency) Reset() { + *x = ResourceDependency{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResourceDependency) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResourceDependency) ProtoMessage() {} + +func (x *ResourceDependency) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResourceDependency.ProtoReflect.Descriptor instead. +func (*ResourceDependency) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{0} +} + +func (x *ResourceDependency) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *ResourceDependency) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +type ResourceSpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Configs *structpb.Value `protobuf:"bytes,1,opt,name=configs,proto3" json:"configs,omitempty"` + // dependencies can be used to refer to other existing resources + // as dependency of this resource. + Dependencies []*ResourceDependency `protobuf:"bytes,2,rep,name=dependencies,proto3" json:"dependencies,omitempty"` +} + +func (x *ResourceSpec) Reset() { + *x = ResourceSpec{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResourceSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResourceSpec) ProtoMessage() {} + +func (x *ResourceSpec) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResourceSpec.ProtoReflect.Descriptor instead. +func (*ResourceSpec) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{1} +} + +func (x *ResourceSpec) GetConfigs() *structpb.Value { + if x != nil { + return x.Configs + } + return nil +} + +func (x *ResourceSpec) GetDependencies() []*ResourceDependency { + if x != nil { + return x.Dependencies + } + return nil +} + +type ListString struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Values []string `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` +} + +func (x *ListString) Reset() { + *x = ListString{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListString) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListString) ProtoMessage() {} + +func (x *ListString) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListString.ProtoReflect.Descriptor instead. +func (*ListString) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{2} +} + +func (x *ListString) GetValues() []string { + if x != nil { + return x.Values + } + return nil +} + +type LogOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Filters map[string]*ListString `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *LogOptions) Reset() { + *x = LogOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LogOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogOptions) ProtoMessage() {} + +func (x *LogOptions) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogOptions.ProtoReflect.Descriptor instead. +func (*LogOptions) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{3} +} + +func (x *LogOptions) GetFilters() map[string]*ListString { + if x != nil { + return x.Filters + } + return nil +} + +type ResourceState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status ResourceState_Status `protobuf:"varint,1,opt,name=status,proto3,enum=gotocompany.entropy.v1beta1.ResourceState_Status" json:"status,omitempty"` + Output *structpb.Value `protobuf:"bytes,2,opt,name=output,proto3" json:"output,omitempty"` + ModuleData []byte `protobuf:"bytes,3,opt,name=module_data,json=moduleData,proto3" json:"module_data,omitempty"` + LogOptions *LogOptions `protobuf:"bytes,4,opt,name=log_options,json=logOptions,proto3" json:"log_options,omitempty"` +} + +func (x *ResourceState) Reset() { + *x = ResourceState{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResourceState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResourceState) ProtoMessage() {} + +func (x *ResourceState) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResourceState.ProtoReflect.Descriptor instead. +func (*ResourceState) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{4} +} + +func (x *ResourceState) GetStatus() ResourceState_Status { + if x != nil { + return x.Status + } + return ResourceState_STATUS_UNSPECIFIED +} + +func (x *ResourceState) GetOutput() *structpb.Value { + if x != nil { + return x.Output + } + return nil +} + +func (x *ResourceState) GetModuleData() []byte { + if x != nil { + return x.ModuleData + } + return nil +} + +func (x *ResourceState) GetLogOptions() *LogOptions { + if x != nil { + return x.LogOptions + } + return nil +} + +type Resource struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Urn string `protobuf:"bytes,1,opt,name=urn,proto3" json:"urn,omitempty"` + Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Project string `protobuf:"bytes,4,opt,name=project,proto3" json:"project,omitempty"` + Labels map[string]string `protobuf:"bytes,5,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + Spec *ResourceSpec `protobuf:"bytes,8,opt,name=spec,proto3" json:"spec,omitempty"` + State *ResourceState `protobuf:"bytes,9,opt,name=state,proto3" json:"state,omitempty"` +} + +func (x *Resource) Reset() { + *x = Resource{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Resource) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Resource) ProtoMessage() {} + +func (x *Resource) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Resource.ProtoReflect.Descriptor instead. +func (*Resource) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{5} +} + +func (x *Resource) GetUrn() string { + if x != nil { + return x.Urn + } + return "" +} + +func (x *Resource) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *Resource) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Resource) GetProject() string { + if x != nil { + return x.Project + } + return "" +} + +func (x *Resource) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *Resource) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Resource) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *Resource) GetSpec() *ResourceSpec { + if x != nil { + return x.Spec + } + return nil +} + +func (x *Resource) GetState() *ResourceState { + if x != nil { + return x.State + } + return nil +} + +type ListResourcesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"` + Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` +} + +func (x *ListResourcesRequest) Reset() { + *x = ListResourcesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListResourcesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListResourcesRequest) ProtoMessage() {} + +func (x *ListResourcesRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListResourcesRequest.ProtoReflect.Descriptor instead. +func (*ListResourcesRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{6} +} + +func (x *ListResourcesRequest) GetProject() string { + if x != nil { + return x.Project + } + return "" +} + +func (x *ListResourcesRequest) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +type ListResourcesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Resources []*Resource `protobuf:"bytes,1,rep,name=resources,proto3" json:"resources,omitempty"` +} + +func (x *ListResourcesResponse) Reset() { + *x = ListResourcesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListResourcesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListResourcesResponse) ProtoMessage() {} + +func (x *ListResourcesResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListResourcesResponse.ProtoReflect.Descriptor instead. +func (*ListResourcesResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{7} +} + +func (x *ListResourcesResponse) GetResources() []*Resource { + if x != nil { + return x.Resources + } + return nil +} + +type GetResourceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Urn string `protobuf:"bytes,1,opt,name=urn,proto3" json:"urn,omitempty"` +} + +func (x *GetResourceRequest) Reset() { + *x = GetResourceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetResourceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetResourceRequest) ProtoMessage() {} + +func (x *GetResourceRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetResourceRequest.ProtoReflect.Descriptor instead. +func (*GetResourceRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{8} +} + +func (x *GetResourceRequest) GetUrn() string { + if x != nil { + return x.Urn + } + return "" +} + +type GetResourceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Resource *Resource `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` +} + +func (x *GetResourceResponse) Reset() { + *x = GetResourceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetResourceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetResourceResponse) ProtoMessage() {} + +func (x *GetResourceResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetResourceResponse.ProtoReflect.Descriptor instead. +func (*GetResourceResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{9} +} + +func (x *GetResourceResponse) GetResource() *Resource { + if x != nil { + return x.Resource + } + return nil +} + +type CreateResourceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Resource *Resource `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` +} + +func (x *CreateResourceRequest) Reset() { + *x = CreateResourceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateResourceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateResourceRequest) ProtoMessage() {} + +func (x *CreateResourceRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateResourceRequest.ProtoReflect.Descriptor instead. +func (*CreateResourceRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{10} +} + +func (x *CreateResourceRequest) GetResource() *Resource { + if x != nil { + return x.Resource + } + return nil +} + +type CreateResourceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Resource *Resource `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` +} + +func (x *CreateResourceResponse) Reset() { + *x = CreateResourceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateResourceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateResourceResponse) ProtoMessage() {} + +func (x *CreateResourceResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateResourceResponse.ProtoReflect.Descriptor instead. +func (*CreateResourceResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{11} +} + +func (x *CreateResourceResponse) GetResource() *Resource { + if x != nil { + return x.Resource + } + return nil +} + +type UpdateResourceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Urn string `protobuf:"bytes,1,opt,name=urn,proto3" json:"urn,omitempty"` + NewSpec *ResourceSpec `protobuf:"bytes,2,opt,name=new_spec,json=newSpec,proto3" json:"new_spec,omitempty"` + Labels map[string]string `protobuf:"bytes,3,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *UpdateResourceRequest) Reset() { + *x = UpdateResourceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateResourceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateResourceRequest) ProtoMessage() {} + +func (x *UpdateResourceRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateResourceRequest.ProtoReflect.Descriptor instead. +func (*UpdateResourceRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{12} +} + +func (x *UpdateResourceRequest) GetUrn() string { + if x != nil { + return x.Urn + } + return "" +} + +func (x *UpdateResourceRequest) GetNewSpec() *ResourceSpec { + if x != nil { + return x.NewSpec + } + return nil +} + +func (x *UpdateResourceRequest) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +type UpdateResourceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Resource *Resource `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` +} + +func (x *UpdateResourceResponse) Reset() { + *x = UpdateResourceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateResourceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateResourceResponse) ProtoMessage() {} + +func (x *UpdateResourceResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateResourceResponse.ProtoReflect.Descriptor instead. +func (*UpdateResourceResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{13} +} + +func (x *UpdateResourceResponse) GetResource() *Resource { + if x != nil { + return x.Resource + } + return nil +} + +type DeleteResourceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Urn string `protobuf:"bytes,1,opt,name=urn,proto3" json:"urn,omitempty"` +} + +func (x *DeleteResourceRequest) Reset() { + *x = DeleteResourceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteResourceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteResourceRequest) ProtoMessage() {} + +func (x *DeleteResourceRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteResourceRequest.ProtoReflect.Descriptor instead. +func (*DeleteResourceRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{14} +} + +func (x *DeleteResourceRequest) GetUrn() string { + if x != nil { + return x.Urn + } + return "" +} + +type DeleteResourceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteResourceResponse) Reset() { + *x = DeleteResourceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteResourceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteResourceResponse) ProtoMessage() {} + +func (x *DeleteResourceResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteResourceResponse.ProtoReflect.Descriptor instead. +func (*DeleteResourceResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{15} +} + +type ApplyActionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Urn string `protobuf:"bytes,1,opt,name=urn,proto3" json:"urn,omitempty"` + Action string `protobuf:"bytes,2,opt,name=action,proto3" json:"action,omitempty"` + Params *structpb.Value `protobuf:"bytes,3,opt,name=params,proto3" json:"params,omitempty"` + Labels map[string]string `protobuf:"bytes,4,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *ApplyActionRequest) Reset() { + *x = ApplyActionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApplyActionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApplyActionRequest) ProtoMessage() {} + +func (x *ApplyActionRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApplyActionRequest.ProtoReflect.Descriptor instead. +func (*ApplyActionRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{16} +} + +func (x *ApplyActionRequest) GetUrn() string { + if x != nil { + return x.Urn + } + return "" +} + +func (x *ApplyActionRequest) GetAction() string { + if x != nil { + return x.Action + } + return "" +} + +func (x *ApplyActionRequest) GetParams() *structpb.Value { + if x != nil { + return x.Params + } + return nil +} + +func (x *ApplyActionRequest) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +type ApplyActionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Resource *Resource `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` +} + +func (x *ApplyActionResponse) Reset() { + *x = ApplyActionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ApplyActionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ApplyActionResponse) ProtoMessage() {} + +func (x *ApplyActionResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ApplyActionResponse.ProtoReflect.Descriptor instead. +func (*ApplyActionResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{17} +} + +func (x *ApplyActionResponse) GetResource() *Resource { + if x != nil { + return x.Resource + } + return nil +} + +type LogChunk struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + Labels map[string]string `protobuf:"bytes,2,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *LogChunk) Reset() { + *x = LogChunk{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LogChunk) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogChunk) ProtoMessage() {} + +func (x *LogChunk) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogChunk.ProtoReflect.Descriptor instead. +func (*LogChunk) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{18} +} + +func (x *LogChunk) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *LogChunk) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +type GetLogRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Urn string `protobuf:"bytes,1,opt,name=urn,proto3" json:"urn,omitempty"` + Filter map[string]string `protobuf:"bytes,6,rep,name=filter,proto3" json:"filter,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GetLogRequest) Reset() { + *x = GetLogRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetLogRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLogRequest) ProtoMessage() {} + +func (x *GetLogRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLogRequest.ProtoReflect.Descriptor instead. +func (*GetLogRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{19} +} + +func (x *GetLogRequest) GetUrn() string { + if x != nil { + return x.Urn + } + return "" +} + +func (x *GetLogRequest) GetFilter() map[string]string { + if x != nil { + return x.Filter + } + return nil +} + +type GetLogResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Chunk *LogChunk `protobuf:"bytes,1,opt,name=chunk,proto3" json:"chunk,omitempty"` +} + +func (x *GetLogResponse) Reset() { + *x = GetLogResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetLogResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLogResponse) ProtoMessage() {} + +func (x *GetLogResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLogResponse.ProtoReflect.Descriptor instead. +func (*GetLogResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{20} +} + +func (x *GetLogResponse) GetChunk() *LogChunk { + if x != nil { + return x.Chunk + } + return nil +} + +type ResourceRevision struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Urn string `protobuf:"bytes,2,opt,name=urn,proto3" json:"urn,omitempty"` + Labels map[string]string `protobuf:"bytes,3,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + Spec *ResourceSpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` + Reason string `protobuf:"bytes,6,opt,name=reason,proto3" json:"reason,omitempty"` +} + +func (x *ResourceRevision) Reset() { + *x = ResourceRevision{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResourceRevision) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResourceRevision) ProtoMessage() {} + +func (x *ResourceRevision) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResourceRevision.ProtoReflect.Descriptor instead. +func (*ResourceRevision) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{21} +} + +func (x *ResourceRevision) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ResourceRevision) GetUrn() string { + if x != nil { + return x.Urn + } + return "" +} + +func (x *ResourceRevision) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *ResourceRevision) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *ResourceRevision) GetSpec() *ResourceSpec { + if x != nil { + return x.Spec + } + return nil +} + +func (x *ResourceRevision) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +type GetResourceRevisionsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Urn string `protobuf:"bytes,1,opt,name=urn,proto3" json:"urn,omitempty"` +} + +func (x *GetResourceRevisionsRequest) Reset() { + *x = GetResourceRevisionsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetResourceRevisionsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetResourceRevisionsRequest) ProtoMessage() {} + +func (x *GetResourceRevisionsRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetResourceRevisionsRequest.ProtoReflect.Descriptor instead. +func (*GetResourceRevisionsRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{22} +} + +func (x *GetResourceRevisionsRequest) GetUrn() string { + if x != nil { + return x.Urn + } + return "" +} + +type GetResourceRevisionsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Revisions []*ResourceRevision `protobuf:"bytes,1,rep,name=revisions,proto3" json:"revisions,omitempty"` +} + +func (x *GetResourceRevisionsResponse) Reset() { + *x = GetResourceRevisionsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetResourceRevisionsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetResourceRevisionsResponse) ProtoMessage() {} + +func (x *GetResourceRevisionsResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetResourceRevisionsResponse.ProtoReflect.Descriptor instead. +func (*GetResourceRevisionsResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP(), []int{23} +} + +func (x *GetResourceRevisionsResponse) GetRevisions() []*ResourceRevision { + if x != nil { + return x.Revisions + } + return nil +} + +var File_gotocompany_entropy_v1beta1_resource_proto protoreflect.FileDescriptor + +var file_gotocompany_entropy_v1beta1_resource_proto_rawDesc = []byte{ + 0x0a, 0x2a, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2f, 0x65, 0x6e, + 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x67, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, + 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3c, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x22, 0x95, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x30, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x53, 0x0a, 0x0c, 0x64, 0x65, 0x70, 0x65, 0x6e, + 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, + 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, + 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x0c, + 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x22, 0x24, 0x0a, 0x0a, + 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x22, 0xc1, 0x01, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x4e, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, + 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x4c, 0x6f, 0x67, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x73, 0x1a, 0x63, 0x0a, 0x0c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, + 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xe7, 0x02, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x49, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x2e, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x48, 0x0a, 0x0b, 0x6c, 0x6f, 0x67, 0x5f, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x0a, 0x6c, 0x6f, 0x67, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x70, + 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, + 0x4e, 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x04, + 0x22, 0xdb, 0x03, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, + 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, + 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x12, 0x49, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, + 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, + 0x41, 0x74, 0x12, 0x3d, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, + 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, + 0x63, 0x12, 0x40, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2a, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, + 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x44, + 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6b, 0x69, 0x6e, 0x64, 0x22, 0x5c, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, + 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, + 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x22, 0x26, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x22, 0x58, 0x0a, 0x13, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, + 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x22, 0x5a, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, + 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x22, 0x5b, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, + 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x82, 0x02, + 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x44, 0x0a, 0x08, 0x6e, 0x65, 0x77, + 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, + 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x53, 0x70, 0x65, 0x63, 0x12, + 0x56, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x3e, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, + 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0x5b, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, + 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, + 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, + 0x29, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfe, 0x01, 0x0a, 0x12, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, + 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x16, 0x0a, + 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x53, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, + 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x58, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, + 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, + 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, + 0xa4, 0x01, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x49, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, + 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, + 0x6f, 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xac, 0x01, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x6f, + 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x4e, 0x0a, 0x06, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x67, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x39, 0x0a, 0x0b, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4d, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x05, 0x63, + 0x68, 0x75, 0x6e, 0x6b, 0x22, 0xd4, 0x02, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x51, 0x0a, 0x06, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x67, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, + 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, + 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3d, 0x0a, 0x04, 0x73, 0x70, 0x65, + 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, + 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, + 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, + 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2f, 0x0a, 0x1b, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x22, 0x6b, 0x0a, 0x1c, + 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x09, + 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2d, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, + 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x09, + 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x32, 0x91, 0x0a, 0x0a, 0x0f, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x92, 0x01, + 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, + 0x31, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, + 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, + 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, + 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x12, 0x92, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x2f, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, + 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, + 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x12, 0x9f, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x67, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, + 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, + 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x08, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x9e, 0x01, 0x0a, 0x0e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x67, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, + 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x33, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, + 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, + 0x32, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x12, 0x9b, 0x01, 0x0a, 0x0e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x2e, + 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, + 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x33, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, + 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, 0x18, + 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x12, 0xab, 0x01, 0x0a, 0x0b, 0x41, 0x70, 0x70, + 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x67, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x33, 0x3a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x29, 0x2f, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, + 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x8a, 0x01, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4c, 0x6f, + 0x67, 0x12, 0x2a, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, + 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, + 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, + 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, + 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x2f, 0x6c, 0x6f, 0x67, + 0x73, 0x30, 0x01, 0x12, 0xb7, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x2e, 0x67, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, + 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, + 0x72, 0x6e, 0x7d, 0x2f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x77, 0x0a, + 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x74, 0x6f, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2f, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2f, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_gotocompany_entropy_v1beta1_resource_proto_rawDescOnce sync.Once + file_gotocompany_entropy_v1beta1_resource_proto_rawDescData = file_gotocompany_entropy_v1beta1_resource_proto_rawDesc +) + +func file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP() []byte { + file_gotocompany_entropy_v1beta1_resource_proto_rawDescOnce.Do(func() { + file_gotocompany_entropy_v1beta1_resource_proto_rawDescData = protoimpl.X.CompressGZIP(file_gotocompany_entropy_v1beta1_resource_proto_rawDescData) + }) + return file_gotocompany_entropy_v1beta1_resource_proto_rawDescData +} + +var file_gotocompany_entropy_v1beta1_resource_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_gotocompany_entropy_v1beta1_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 31) +var file_gotocompany_entropy_v1beta1_resource_proto_goTypes = []interface{}{ + (ResourceState_Status)(0), // 0: gotocompany.entropy.v1beta1.ResourceState.Status + (*ResourceDependency)(nil), // 1: gotocompany.entropy.v1beta1.ResourceDependency + (*ResourceSpec)(nil), // 2: gotocompany.entropy.v1beta1.ResourceSpec + (*ListString)(nil), // 3: gotocompany.entropy.v1beta1.ListString + (*LogOptions)(nil), // 4: gotocompany.entropy.v1beta1.LogOptions + (*ResourceState)(nil), // 5: gotocompany.entropy.v1beta1.ResourceState + (*Resource)(nil), // 6: gotocompany.entropy.v1beta1.Resource + (*ListResourcesRequest)(nil), // 7: gotocompany.entropy.v1beta1.ListResourcesRequest + (*ListResourcesResponse)(nil), // 8: gotocompany.entropy.v1beta1.ListResourcesResponse + (*GetResourceRequest)(nil), // 9: gotocompany.entropy.v1beta1.GetResourceRequest + (*GetResourceResponse)(nil), // 10: gotocompany.entropy.v1beta1.GetResourceResponse + (*CreateResourceRequest)(nil), // 11: gotocompany.entropy.v1beta1.CreateResourceRequest + (*CreateResourceResponse)(nil), // 12: gotocompany.entropy.v1beta1.CreateResourceResponse + (*UpdateResourceRequest)(nil), // 13: gotocompany.entropy.v1beta1.UpdateResourceRequest + (*UpdateResourceResponse)(nil), // 14: gotocompany.entropy.v1beta1.UpdateResourceResponse + (*DeleteResourceRequest)(nil), // 15: gotocompany.entropy.v1beta1.DeleteResourceRequest + (*DeleteResourceResponse)(nil), // 16: gotocompany.entropy.v1beta1.DeleteResourceResponse + (*ApplyActionRequest)(nil), // 17: gotocompany.entropy.v1beta1.ApplyActionRequest + (*ApplyActionResponse)(nil), // 18: gotocompany.entropy.v1beta1.ApplyActionResponse + (*LogChunk)(nil), // 19: gotocompany.entropy.v1beta1.LogChunk + (*GetLogRequest)(nil), // 20: gotocompany.entropy.v1beta1.GetLogRequest + (*GetLogResponse)(nil), // 21: gotocompany.entropy.v1beta1.GetLogResponse + (*ResourceRevision)(nil), // 22: gotocompany.entropy.v1beta1.ResourceRevision + (*GetResourceRevisionsRequest)(nil), // 23: gotocompany.entropy.v1beta1.GetResourceRevisionsRequest + (*GetResourceRevisionsResponse)(nil), // 24: gotocompany.entropy.v1beta1.GetResourceRevisionsResponse + nil, // 25: gotocompany.entropy.v1beta1.LogOptions.FiltersEntry + nil, // 26: gotocompany.entropy.v1beta1.Resource.LabelsEntry + nil, // 27: gotocompany.entropy.v1beta1.UpdateResourceRequest.LabelsEntry + nil, // 28: gotocompany.entropy.v1beta1.ApplyActionRequest.LabelsEntry + nil, // 29: gotocompany.entropy.v1beta1.LogChunk.LabelsEntry + nil, // 30: gotocompany.entropy.v1beta1.GetLogRequest.FilterEntry + nil, // 31: gotocompany.entropy.v1beta1.ResourceRevision.LabelsEntry + (*structpb.Value)(nil), // 32: google.protobuf.Value + (*timestamppb.Timestamp)(nil), // 33: google.protobuf.Timestamp +} +var file_gotocompany_entropy_v1beta1_resource_proto_depIdxs = []int32{ + 32, // 0: gotocompany.entropy.v1beta1.ResourceSpec.configs:type_name -> google.protobuf.Value + 1, // 1: gotocompany.entropy.v1beta1.ResourceSpec.dependencies:type_name -> gotocompany.entropy.v1beta1.ResourceDependency + 25, // 2: gotocompany.entropy.v1beta1.LogOptions.filters:type_name -> gotocompany.entropy.v1beta1.LogOptions.FiltersEntry + 0, // 3: gotocompany.entropy.v1beta1.ResourceState.status:type_name -> gotocompany.entropy.v1beta1.ResourceState.Status + 32, // 4: gotocompany.entropy.v1beta1.ResourceState.output:type_name -> google.protobuf.Value + 4, // 5: gotocompany.entropy.v1beta1.ResourceState.log_options:type_name -> gotocompany.entropy.v1beta1.LogOptions + 26, // 6: gotocompany.entropy.v1beta1.Resource.labels:type_name -> gotocompany.entropy.v1beta1.Resource.LabelsEntry + 33, // 7: gotocompany.entropy.v1beta1.Resource.created_at:type_name -> google.protobuf.Timestamp + 33, // 8: gotocompany.entropy.v1beta1.Resource.updated_at:type_name -> google.protobuf.Timestamp + 2, // 9: gotocompany.entropy.v1beta1.Resource.spec:type_name -> gotocompany.entropy.v1beta1.ResourceSpec + 5, // 10: gotocompany.entropy.v1beta1.Resource.state:type_name -> gotocompany.entropy.v1beta1.ResourceState + 6, // 11: gotocompany.entropy.v1beta1.ListResourcesResponse.resources:type_name -> gotocompany.entropy.v1beta1.Resource + 6, // 12: gotocompany.entropy.v1beta1.GetResourceResponse.resource:type_name -> gotocompany.entropy.v1beta1.Resource + 6, // 13: gotocompany.entropy.v1beta1.CreateResourceRequest.resource:type_name -> gotocompany.entropy.v1beta1.Resource + 6, // 14: gotocompany.entropy.v1beta1.CreateResourceResponse.resource:type_name -> gotocompany.entropy.v1beta1.Resource + 2, // 15: gotocompany.entropy.v1beta1.UpdateResourceRequest.new_spec:type_name -> gotocompany.entropy.v1beta1.ResourceSpec + 27, // 16: gotocompany.entropy.v1beta1.UpdateResourceRequest.labels:type_name -> gotocompany.entropy.v1beta1.UpdateResourceRequest.LabelsEntry + 6, // 17: gotocompany.entropy.v1beta1.UpdateResourceResponse.resource:type_name -> gotocompany.entropy.v1beta1.Resource + 32, // 18: gotocompany.entropy.v1beta1.ApplyActionRequest.params:type_name -> google.protobuf.Value + 28, // 19: gotocompany.entropy.v1beta1.ApplyActionRequest.labels:type_name -> gotocompany.entropy.v1beta1.ApplyActionRequest.LabelsEntry + 6, // 20: gotocompany.entropy.v1beta1.ApplyActionResponse.resource:type_name -> gotocompany.entropy.v1beta1.Resource + 29, // 21: gotocompany.entropy.v1beta1.LogChunk.labels:type_name -> gotocompany.entropy.v1beta1.LogChunk.LabelsEntry + 30, // 22: gotocompany.entropy.v1beta1.GetLogRequest.filter:type_name -> gotocompany.entropy.v1beta1.GetLogRequest.FilterEntry + 19, // 23: gotocompany.entropy.v1beta1.GetLogResponse.chunk:type_name -> gotocompany.entropy.v1beta1.LogChunk + 31, // 24: gotocompany.entropy.v1beta1.ResourceRevision.labels:type_name -> gotocompany.entropy.v1beta1.ResourceRevision.LabelsEntry + 33, // 25: gotocompany.entropy.v1beta1.ResourceRevision.created_at:type_name -> google.protobuf.Timestamp + 2, // 26: gotocompany.entropy.v1beta1.ResourceRevision.spec:type_name -> gotocompany.entropy.v1beta1.ResourceSpec + 22, // 27: gotocompany.entropy.v1beta1.GetResourceRevisionsResponse.revisions:type_name -> gotocompany.entropy.v1beta1.ResourceRevision + 3, // 28: gotocompany.entropy.v1beta1.LogOptions.FiltersEntry.value:type_name -> gotocompany.entropy.v1beta1.ListString + 7, // 29: gotocompany.entropy.v1beta1.ResourceService.ListResources:input_type -> gotocompany.entropy.v1beta1.ListResourcesRequest + 9, // 30: gotocompany.entropy.v1beta1.ResourceService.GetResource:input_type -> gotocompany.entropy.v1beta1.GetResourceRequest + 11, // 31: gotocompany.entropy.v1beta1.ResourceService.CreateResource:input_type -> gotocompany.entropy.v1beta1.CreateResourceRequest + 13, // 32: gotocompany.entropy.v1beta1.ResourceService.UpdateResource:input_type -> gotocompany.entropy.v1beta1.UpdateResourceRequest + 15, // 33: gotocompany.entropy.v1beta1.ResourceService.DeleteResource:input_type -> gotocompany.entropy.v1beta1.DeleteResourceRequest + 17, // 34: gotocompany.entropy.v1beta1.ResourceService.ApplyAction:input_type -> gotocompany.entropy.v1beta1.ApplyActionRequest + 20, // 35: gotocompany.entropy.v1beta1.ResourceService.GetLog:input_type -> gotocompany.entropy.v1beta1.GetLogRequest + 23, // 36: gotocompany.entropy.v1beta1.ResourceService.GetResourceRevisions:input_type -> gotocompany.entropy.v1beta1.GetResourceRevisionsRequest + 8, // 37: gotocompany.entropy.v1beta1.ResourceService.ListResources:output_type -> gotocompany.entropy.v1beta1.ListResourcesResponse + 10, // 38: gotocompany.entropy.v1beta1.ResourceService.GetResource:output_type -> gotocompany.entropy.v1beta1.GetResourceResponse + 12, // 39: gotocompany.entropy.v1beta1.ResourceService.CreateResource:output_type -> gotocompany.entropy.v1beta1.CreateResourceResponse + 14, // 40: gotocompany.entropy.v1beta1.ResourceService.UpdateResource:output_type -> gotocompany.entropy.v1beta1.UpdateResourceResponse + 16, // 41: gotocompany.entropy.v1beta1.ResourceService.DeleteResource:output_type -> gotocompany.entropy.v1beta1.DeleteResourceResponse + 18, // 42: gotocompany.entropy.v1beta1.ResourceService.ApplyAction:output_type -> gotocompany.entropy.v1beta1.ApplyActionResponse + 21, // 43: gotocompany.entropy.v1beta1.ResourceService.GetLog:output_type -> gotocompany.entropy.v1beta1.GetLogResponse + 24, // 44: gotocompany.entropy.v1beta1.ResourceService.GetResourceRevisions:output_type -> gotocompany.entropy.v1beta1.GetResourceRevisionsResponse + 37, // [37:45] is the sub-list for method output_type + 29, // [29:37] is the sub-list for method input_type + 29, // [29:29] is the sub-list for extension type_name + 29, // [29:29] is the sub-list for extension extendee + 0, // [0:29] is the sub-list for field type_name +} + +func init() { file_gotocompany_entropy_v1beta1_resource_proto_init() } +func file_gotocompany_entropy_v1beta1_resource_proto_init() { + if File_gotocompany_entropy_v1beta1_resource_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResourceDependency); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResourceSpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListString); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LogOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResourceState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Resource); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListResourcesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListResourcesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetResourceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetResourceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateResourceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateResourceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateResourceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateResourceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteResourceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteResourceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplyActionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplyActionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LogChunk); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetLogRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetLogResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResourceRevision); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetResourceRevisionsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_entropy_v1beta1_resource_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetResourceRevisionsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_gotocompany_entropy_v1beta1_resource_proto_rawDesc, + NumEnums: 1, + NumMessages: 31, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_gotocompany_entropy_v1beta1_resource_proto_goTypes, + DependencyIndexes: file_gotocompany_entropy_v1beta1_resource_proto_depIdxs, + EnumInfos: file_gotocompany_entropy_v1beta1_resource_proto_enumTypes, + MessageInfos: file_gotocompany_entropy_v1beta1_resource_proto_msgTypes, + }.Build() + File_gotocompany_entropy_v1beta1_resource_proto = out.File + file_gotocompany_entropy_v1beta1_resource_proto_rawDesc = nil + file_gotocompany_entropy_v1beta1_resource_proto_goTypes = nil + file_gotocompany_entropy_v1beta1_resource_proto_depIdxs = nil +} diff --git a/proto/gotocompany/entropy/v1beta1/resource.pb.gw.go b/proto/gotocompany/entropy/v1beta1/resource.pb.gw.go new file mode 100644 index 00000000..99e32e79 --- /dev/null +++ b/proto/gotocompany/entropy/v1beta1/resource.pb.gw.go @@ -0,0 +1,921 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: gotocompany/entropy/v1beta1/resource.proto + +/* +Package entropyv1beta1 is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package entropyv1beta1 + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +var ( + filter_ResourceService_ListResources_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_ResourceService_ListResources_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListResourcesRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ResourceService_ListResources_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListResources(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ResourceService_ListResources_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListResourcesRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ResourceService_ListResources_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListResources(ctx, &protoReq) + return msg, metadata, err + +} + +func request_ResourceService_GetResource_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetResourceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + msg, err := client.GetResource(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ResourceService_GetResource_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetResourceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + msg, err := server.GetResource(ctx, &protoReq) + return msg, metadata, err + +} + +func request_ResourceService_CreateResource_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateResourceRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Resource); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.CreateResource(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ResourceService_CreateResource_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateResourceRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Resource); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.CreateResource(ctx, &protoReq) + return msg, metadata, err + +} + +func request_ResourceService_UpdateResource_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateResourceRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + msg, err := client.UpdateResource(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ResourceService_UpdateResource_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateResourceRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + msg, err := server.UpdateResource(ctx, &protoReq) + return msg, metadata, err + +} + +func request_ResourceService_DeleteResource_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteResourceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + msg, err := client.DeleteResource(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ResourceService_DeleteResource_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteResourceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + msg, err := server.DeleteResource(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_ResourceService_ApplyAction_0 = &utilities.DoubleArray{Encoding: map[string]int{"params": 0, "urn": 1, "action": 2}, Base: []int{1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 2, 3, 4}} +) + +func request_ResourceService_ApplyAction_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ApplyActionRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Params); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + val, ok = pathParams["action"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "action") + } + + protoReq.Action, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "action", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ResourceService_ApplyAction_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ApplyAction(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ResourceService_ApplyAction_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ApplyActionRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Params); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + val, ok = pathParams["action"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "action") + } + + protoReq.Action, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "action", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ResourceService_ApplyAction_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ApplyAction(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_ResourceService_GetLog_0 = &utilities.DoubleArray{Encoding: map[string]int{"urn": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_ResourceService_GetLog_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (ResourceService_GetLogClient, runtime.ServerMetadata, error) { + var protoReq GetLogRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ResourceService_GetLog_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + stream, err := client.GetLog(ctx, &protoReq) + if err != nil { + return nil, metadata, err + } + header, err := stream.Header() + if err != nil { + return nil, metadata, err + } + metadata.HeaderMD = header + return stream, metadata, nil + +} + +func request_ResourceService_GetResourceRevisions_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetResourceRevisionsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + msg, err := client.GetResourceRevisions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ResourceService_GetResourceRevisions_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetResourceRevisionsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["urn"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "urn") + } + + protoReq.Urn, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "urn", err) + } + + msg, err := server.GetResourceRevisions(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterResourceServiceHandlerServer registers the http handlers for service ResourceService to "mux". +// UnaryRPC :call ResourceServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterResourceServiceHandlerFromEndpoint instead. +func RegisterResourceServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ResourceServiceServer) error { + + mux.Handle("GET", pattern_ResourceService_ListResources_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/ListResources", runtime.WithHTTPPathPattern("/v1beta1/resources")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ResourceService_ListResources_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_ListResources_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_ResourceService_GetResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/GetResource", runtime.WithHTTPPathPattern("/v1beta1/resources/{urn}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ResourceService_GetResource_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_GetResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ResourceService_CreateResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/CreateResource", runtime.WithHTTPPathPattern("/v1beta1/resources")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ResourceService_CreateResource_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_CreateResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PATCH", pattern_ResourceService_UpdateResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/UpdateResource", runtime.WithHTTPPathPattern("/v1beta1/resources/{urn}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ResourceService_UpdateResource_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_UpdateResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_ResourceService_DeleteResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/DeleteResource", runtime.WithHTTPPathPattern("/v1beta1/resources/{urn}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ResourceService_DeleteResource_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_DeleteResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ResourceService_ApplyAction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/ApplyAction", runtime.WithHTTPPathPattern("/v1beta1/resources/{urn}/actions/{action}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ResourceService_ApplyAction_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_ApplyAction_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_ResourceService_GetLog_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + err := status.Error(codes.Unimplemented, "streaming calls are not yet supported in the in-process transport") + _, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + }) + + mux.Handle("GET", pattern_ResourceService_GetResourceRevisions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/GetResourceRevisions", runtime.WithHTTPPathPattern("/v1beta1/resources/{urn}/revisions")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ResourceService_GetResourceRevisions_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_GetResourceRevisions_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterResourceServiceHandlerFromEndpoint is same as RegisterResourceServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterResourceServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterResourceServiceHandler(ctx, mux, conn) +} + +// RegisterResourceServiceHandler registers the http handlers for service ResourceService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterResourceServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterResourceServiceHandlerClient(ctx, mux, NewResourceServiceClient(conn)) +} + +// RegisterResourceServiceHandlerClient registers the http handlers for service ResourceService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ResourceServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ResourceServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "ResourceServiceClient" to call the correct interceptors. +func RegisterResourceServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ResourceServiceClient) error { + + mux.Handle("GET", pattern_ResourceService_ListResources_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/ListResources", runtime.WithHTTPPathPattern("/v1beta1/resources")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ResourceService_ListResources_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_ListResources_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_ResourceService_GetResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/GetResource", runtime.WithHTTPPathPattern("/v1beta1/resources/{urn}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ResourceService_GetResource_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_GetResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ResourceService_CreateResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/CreateResource", runtime.WithHTTPPathPattern("/v1beta1/resources")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ResourceService_CreateResource_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_CreateResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PATCH", pattern_ResourceService_UpdateResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/UpdateResource", runtime.WithHTTPPathPattern("/v1beta1/resources/{urn}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ResourceService_UpdateResource_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_UpdateResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_ResourceService_DeleteResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/DeleteResource", runtime.WithHTTPPathPattern("/v1beta1/resources/{urn}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ResourceService_DeleteResource_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_DeleteResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ResourceService_ApplyAction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/ApplyAction", runtime.WithHTTPPathPattern("/v1beta1/resources/{urn}/actions/{action}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ResourceService_ApplyAction_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_ApplyAction_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_ResourceService_GetLog_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/GetLog", runtime.WithHTTPPathPattern("/v1beta1/resources/{urn}/logs")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ResourceService_GetLog_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_GetLog_0(annotatedContext, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_ResourceService_GetResourceRevisions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/gotocompany.entropy.v1beta1.ResourceService/GetResourceRevisions", runtime.WithHTTPPathPattern("/v1beta1/resources/{urn}/revisions")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ResourceService_GetResourceRevisions_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_GetResourceRevisions_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_ResourceService_ListResources_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1beta1", "resources"}, "")) + + pattern_ResourceService_GetResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1beta1", "resources", "urn"}, "")) + + pattern_ResourceService_CreateResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1beta1", "resources"}, "")) + + pattern_ResourceService_UpdateResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1beta1", "resources", "urn"}, "")) + + pattern_ResourceService_DeleteResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1beta1", "resources", "urn"}, "")) + + pattern_ResourceService_ApplyAction_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"v1beta1", "resources", "urn", "actions", "action"}, "")) + + pattern_ResourceService_GetLog_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3}, []string{"v1beta1", "resources", "urn", "logs"}, "")) + + pattern_ResourceService_GetResourceRevisions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3}, []string{"v1beta1", "resources", "urn", "revisions"}, "")) +) + +var ( + forward_ResourceService_ListResources_0 = runtime.ForwardResponseMessage + + forward_ResourceService_GetResource_0 = runtime.ForwardResponseMessage + + forward_ResourceService_CreateResource_0 = runtime.ForwardResponseMessage + + forward_ResourceService_UpdateResource_0 = runtime.ForwardResponseMessage + + forward_ResourceService_DeleteResource_0 = runtime.ForwardResponseMessage + + forward_ResourceService_ApplyAction_0 = runtime.ForwardResponseMessage + + forward_ResourceService_GetLog_0 = runtime.ForwardResponseStream + + forward_ResourceService_GetResourceRevisions_0 = runtime.ForwardResponseMessage +) diff --git a/proto/gotocompany/entropy/v1beta1/resource.pb.validate.go b/proto/gotocompany/entropy/v1beta1/resource.pb.validate.go new file mode 100644 index 00000000..46600873 --- /dev/null +++ b/proto/gotocompany/entropy/v1beta1/resource.pb.validate.go @@ -0,0 +1,3134 @@ +// Code generated by protoc-gen-validate. DO NOT EDIT. +// source: gotocompany/entropy/v1beta1/resource.proto + +package entropyv1beta1 + +import ( + "bytes" + "errors" + "fmt" + "net" + "net/mail" + "net/url" + "regexp" + "sort" + "strings" + "time" + "unicode/utf8" + + "google.golang.org/protobuf/types/known/anypb" +) + +// ensure the imports are used +var ( + _ = bytes.MinRead + _ = errors.New("") + _ = fmt.Print + _ = utf8.UTFMax + _ = (*regexp.Regexp)(nil) + _ = (*strings.Reader)(nil) + _ = net.IPv4len + _ = time.Duration(0) + _ = (*url.URL)(nil) + _ = (*mail.Address)(nil) + _ = anypb.Any{} + _ = sort.Sort +) + +// Validate checks the field values on ResourceDependency with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ResourceDependency) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ResourceDependency with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ResourceDependencyMultiError, or nil if none found. +func (m *ResourceDependency) ValidateAll() error { + return m.validate(true) +} + +func (m *ResourceDependency) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Key + + // no validation rules for Value + + if len(errors) > 0 { + return ResourceDependencyMultiError(errors) + } + return nil +} + +// ResourceDependencyMultiError is an error wrapping multiple validation errors +// returned by ResourceDependency.ValidateAll() if the designated constraints +// aren't met. +type ResourceDependencyMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ResourceDependencyMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ResourceDependencyMultiError) AllErrors() []error { return m } + +// ResourceDependencyValidationError is the validation error returned by +// ResourceDependency.Validate if the designated constraints aren't met. +type ResourceDependencyValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ResourceDependencyValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ResourceDependencyValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ResourceDependencyValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ResourceDependencyValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ResourceDependencyValidationError) ErrorName() string { + return "ResourceDependencyValidationError" +} + +// Error satisfies the builtin error interface +func (e ResourceDependencyValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sResourceDependency.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ResourceDependencyValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ResourceDependencyValidationError{} + +// Validate checks the field values on ResourceSpec with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *ResourceSpec) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ResourceSpec with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in ResourceSpecMultiError, or +// nil if none found. +func (m *ResourceSpec) ValidateAll() error { + return m.validate(true) +} + +func (m *ResourceSpec) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetConfigs()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ResourceSpecValidationError{ + field: "Configs", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ResourceSpecValidationError{ + field: "Configs", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetConfigs()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResourceSpecValidationError{ + field: "Configs", + reason: "embedded message failed validation", + cause: err, + } + } + } + + for idx, item := range m.GetDependencies() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ResourceSpecValidationError{ + field: fmt.Sprintf("Dependencies[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ResourceSpecValidationError{ + field: fmt.Sprintf("Dependencies[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResourceSpecValidationError{ + field: fmt.Sprintf("Dependencies[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return ResourceSpecMultiError(errors) + } + return nil +} + +// ResourceSpecMultiError is an error wrapping multiple validation errors +// returned by ResourceSpec.ValidateAll() if the designated constraints aren't met. +type ResourceSpecMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ResourceSpecMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ResourceSpecMultiError) AllErrors() []error { return m } + +// ResourceSpecValidationError is the validation error returned by +// ResourceSpec.Validate if the designated constraints aren't met. +type ResourceSpecValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ResourceSpecValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ResourceSpecValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ResourceSpecValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ResourceSpecValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ResourceSpecValidationError) ErrorName() string { return "ResourceSpecValidationError" } + +// Error satisfies the builtin error interface +func (e ResourceSpecValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sResourceSpec.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ResourceSpecValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ResourceSpecValidationError{} + +// Validate checks the field values on ListString with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *ListString) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListString with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in ListStringMultiError, or +// nil if none found. +func (m *ListString) ValidateAll() error { + return m.validate(true) +} + +func (m *ListString) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return ListStringMultiError(errors) + } + return nil +} + +// ListStringMultiError is an error wrapping multiple validation errors +// returned by ListString.ValidateAll() if the designated constraints aren't met. +type ListStringMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListStringMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListStringMultiError) AllErrors() []error { return m } + +// ListStringValidationError is the validation error returned by +// ListString.Validate if the designated constraints aren't met. +type ListStringValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListStringValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListStringValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListStringValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListStringValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListStringValidationError) ErrorName() string { return "ListStringValidationError" } + +// Error satisfies the builtin error interface +func (e ListStringValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListString.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListStringValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListStringValidationError{} + +// Validate checks the field values on LogOptions with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *LogOptions) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on LogOptions with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in LogOptionsMultiError, or +// nil if none found. +func (m *LogOptions) ValidateAll() error { + return m.validate(true) +} + +func (m *LogOptions) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + { + sorted_keys := make([]string, len(m.GetFilters())) + i := 0 + for key := range m.GetFilters() { + sorted_keys[i] = key + i++ + } + sort.Slice(sorted_keys, func(i, j int) bool { return sorted_keys[i] < sorted_keys[j] }) + for _, key := range sorted_keys { + val := m.GetFilters()[key] + _ = val + + // no validation rules for Filters[key] + + if all { + switch v := interface{}(val).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, LogOptionsValidationError{ + field: fmt.Sprintf("Filters[%v]", key), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, LogOptionsValidationError{ + field: fmt.Sprintf("Filters[%v]", key), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(val).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return LogOptionsValidationError{ + field: fmt.Sprintf("Filters[%v]", key), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + } + + if len(errors) > 0 { + return LogOptionsMultiError(errors) + } + return nil +} + +// LogOptionsMultiError is an error wrapping multiple validation errors +// returned by LogOptions.ValidateAll() if the designated constraints aren't met. +type LogOptionsMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m LogOptionsMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m LogOptionsMultiError) AllErrors() []error { return m } + +// LogOptionsValidationError is the validation error returned by +// LogOptions.Validate if the designated constraints aren't met. +type LogOptionsValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e LogOptionsValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e LogOptionsValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e LogOptionsValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e LogOptionsValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e LogOptionsValidationError) ErrorName() string { return "LogOptionsValidationError" } + +// Error satisfies the builtin error interface +func (e LogOptionsValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sLogOptions.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = LogOptionsValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = LogOptionsValidationError{} + +// Validate checks the field values on ResourceState with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *ResourceState) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ResourceState with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in ResourceStateMultiError, or +// nil if none found. +func (m *ResourceState) ValidateAll() error { + return m.validate(true) +} + +func (m *ResourceState) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Status + + if all { + switch v := interface{}(m.GetOutput()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ResourceStateValidationError{ + field: "Output", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ResourceStateValidationError{ + field: "Output", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetOutput()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResourceStateValidationError{ + field: "Output", + reason: "embedded message failed validation", + cause: err, + } + } + } + + // no validation rules for ModuleData + + if all { + switch v := interface{}(m.GetLogOptions()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ResourceStateValidationError{ + field: "LogOptions", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ResourceStateValidationError{ + field: "LogOptions", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetLogOptions()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResourceStateValidationError{ + field: "LogOptions", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return ResourceStateMultiError(errors) + } + return nil +} + +// ResourceStateMultiError is an error wrapping multiple validation errors +// returned by ResourceState.ValidateAll() if the designated constraints +// aren't met. +type ResourceStateMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ResourceStateMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ResourceStateMultiError) AllErrors() []error { return m } + +// ResourceStateValidationError is the validation error returned by +// ResourceState.Validate if the designated constraints aren't met. +type ResourceStateValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ResourceStateValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ResourceStateValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ResourceStateValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ResourceStateValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ResourceStateValidationError) ErrorName() string { return "ResourceStateValidationError" } + +// Error satisfies the builtin error interface +func (e ResourceStateValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sResourceState.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ResourceStateValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ResourceStateValidationError{} + +// Validate checks the field values on Resource with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *Resource) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on Resource with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in ResourceMultiError, or nil +// if none found. +func (m *Resource) ValidateAll() error { + return m.validate(true) +} + +func (m *Resource) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Urn + + // no validation rules for Kind + + // no validation rules for Name + + // no validation rules for Project + + // no validation rules for Labels + + if all { + switch v := interface{}(m.GetCreatedAt()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ResourceValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ResourceValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetCreatedAt()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResourceValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetUpdatedAt()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ResourceValidationError{ + field: "UpdatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ResourceValidationError{ + field: "UpdatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetUpdatedAt()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResourceValidationError{ + field: "UpdatedAt", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetSpec()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ResourceValidationError{ + field: "Spec", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ResourceValidationError{ + field: "Spec", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetSpec()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResourceValidationError{ + field: "Spec", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetState()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ResourceValidationError{ + field: "State", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ResourceValidationError{ + field: "State", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetState()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResourceValidationError{ + field: "State", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return ResourceMultiError(errors) + } + return nil +} + +// ResourceMultiError is an error wrapping multiple validation errors returned +// by Resource.ValidateAll() if the designated constraints aren't met. +type ResourceMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ResourceMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ResourceMultiError) AllErrors() []error { return m } + +// ResourceValidationError is the validation error returned by +// Resource.Validate if the designated constraints aren't met. +type ResourceValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ResourceValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ResourceValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ResourceValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ResourceValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ResourceValidationError) ErrorName() string { return "ResourceValidationError" } + +// Error satisfies the builtin error interface +func (e ResourceValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sResource.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ResourceValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ResourceValidationError{} + +// Validate checks the field values on ListResourcesRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ListResourcesRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListResourcesRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListResourcesRequestMultiError, or nil if none found. +func (m *ListResourcesRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *ListResourcesRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Project + + // no validation rules for Kind + + if len(errors) > 0 { + return ListResourcesRequestMultiError(errors) + } + return nil +} + +// ListResourcesRequestMultiError is an error wrapping multiple validation +// errors returned by ListResourcesRequest.ValidateAll() if the designated +// constraints aren't met. +type ListResourcesRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListResourcesRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListResourcesRequestMultiError) AllErrors() []error { return m } + +// ListResourcesRequestValidationError is the validation error returned by +// ListResourcesRequest.Validate if the designated constraints aren't met. +type ListResourcesRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListResourcesRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListResourcesRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListResourcesRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListResourcesRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListResourcesRequestValidationError) ErrorName() string { + return "ListResourcesRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e ListResourcesRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListResourcesRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListResourcesRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListResourcesRequestValidationError{} + +// Validate checks the field values on ListResourcesResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ListResourcesResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListResourcesResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListResourcesResponseMultiError, or nil if none found. +func (m *ListResourcesResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *ListResourcesResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + for idx, item := range m.GetResources() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ListResourcesResponseValidationError{ + field: fmt.Sprintf("Resources[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ListResourcesResponseValidationError{ + field: fmt.Sprintf("Resources[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ListResourcesResponseValidationError{ + field: fmt.Sprintf("Resources[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return ListResourcesResponseMultiError(errors) + } + return nil +} + +// ListResourcesResponseMultiError is an error wrapping multiple validation +// errors returned by ListResourcesResponse.ValidateAll() if the designated +// constraints aren't met. +type ListResourcesResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListResourcesResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListResourcesResponseMultiError) AllErrors() []error { return m } + +// ListResourcesResponseValidationError is the validation error returned by +// ListResourcesResponse.Validate if the designated constraints aren't met. +type ListResourcesResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListResourcesResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListResourcesResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListResourcesResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListResourcesResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListResourcesResponseValidationError) ErrorName() string { + return "ListResourcesResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e ListResourcesResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sListResourcesResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListResourcesResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListResourcesResponseValidationError{} + +// Validate checks the field values on GetResourceRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GetResourceRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetResourceRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GetResourceRequestMultiError, or nil if none found. +func (m *GetResourceRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *GetResourceRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Urn + + if len(errors) > 0 { + return GetResourceRequestMultiError(errors) + } + return nil +} + +// GetResourceRequestMultiError is an error wrapping multiple validation errors +// returned by GetResourceRequest.ValidateAll() if the designated constraints +// aren't met. +type GetResourceRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetResourceRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetResourceRequestMultiError) AllErrors() []error { return m } + +// GetResourceRequestValidationError is the validation error returned by +// GetResourceRequest.Validate if the designated constraints aren't met. +type GetResourceRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetResourceRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetResourceRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetResourceRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetResourceRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetResourceRequestValidationError) ErrorName() string { + return "GetResourceRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e GetResourceRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetResourceRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetResourceRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetResourceRequestValidationError{} + +// Validate checks the field values on GetResourceResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GetResourceResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetResourceResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GetResourceResponseMultiError, or nil if none found. +func (m *GetResourceResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *GetResourceResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetResource()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GetResourceResponseValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GetResourceResponseValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetResource()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GetResourceResponseValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return GetResourceResponseMultiError(errors) + } + return nil +} + +// GetResourceResponseMultiError is an error wrapping multiple validation +// errors returned by GetResourceResponse.ValidateAll() if the designated +// constraints aren't met. +type GetResourceResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetResourceResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetResourceResponseMultiError) AllErrors() []error { return m } + +// GetResourceResponseValidationError is the validation error returned by +// GetResourceResponse.Validate if the designated constraints aren't met. +type GetResourceResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetResourceResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetResourceResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetResourceResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetResourceResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetResourceResponseValidationError) ErrorName() string { + return "GetResourceResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e GetResourceResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetResourceResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetResourceResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetResourceResponseValidationError{} + +// Validate checks the field values on CreateResourceRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *CreateResourceRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on CreateResourceRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// CreateResourceRequestMultiError, or nil if none found. +func (m *CreateResourceRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *CreateResourceRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetResource()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, CreateResourceRequestValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, CreateResourceRequestValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetResource()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return CreateResourceRequestValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return CreateResourceRequestMultiError(errors) + } + return nil +} + +// CreateResourceRequestMultiError is an error wrapping multiple validation +// errors returned by CreateResourceRequest.ValidateAll() if the designated +// constraints aren't met. +type CreateResourceRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m CreateResourceRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m CreateResourceRequestMultiError) AllErrors() []error { return m } + +// CreateResourceRequestValidationError is the validation error returned by +// CreateResourceRequest.Validate if the designated constraints aren't met. +type CreateResourceRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e CreateResourceRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e CreateResourceRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e CreateResourceRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e CreateResourceRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e CreateResourceRequestValidationError) ErrorName() string { + return "CreateResourceRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e CreateResourceRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sCreateResourceRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = CreateResourceRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = CreateResourceRequestValidationError{} + +// Validate checks the field values on CreateResourceResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *CreateResourceResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on CreateResourceResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// CreateResourceResponseMultiError, or nil if none found. +func (m *CreateResourceResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *CreateResourceResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetResource()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, CreateResourceResponseValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, CreateResourceResponseValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetResource()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return CreateResourceResponseValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return CreateResourceResponseMultiError(errors) + } + return nil +} + +// CreateResourceResponseMultiError is an error wrapping multiple validation +// errors returned by CreateResourceResponse.ValidateAll() if the designated +// constraints aren't met. +type CreateResourceResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m CreateResourceResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m CreateResourceResponseMultiError) AllErrors() []error { return m } + +// CreateResourceResponseValidationError is the validation error returned by +// CreateResourceResponse.Validate if the designated constraints aren't met. +type CreateResourceResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e CreateResourceResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e CreateResourceResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e CreateResourceResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e CreateResourceResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e CreateResourceResponseValidationError) ErrorName() string { + return "CreateResourceResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e CreateResourceResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sCreateResourceResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = CreateResourceResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = CreateResourceResponseValidationError{} + +// Validate checks the field values on UpdateResourceRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *UpdateResourceRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UpdateResourceRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// UpdateResourceRequestMultiError, or nil if none found. +func (m *UpdateResourceRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *UpdateResourceRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Urn + + if all { + switch v := interface{}(m.GetNewSpec()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, UpdateResourceRequestValidationError{ + field: "NewSpec", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, UpdateResourceRequestValidationError{ + field: "NewSpec", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetNewSpec()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return UpdateResourceRequestValidationError{ + field: "NewSpec", + reason: "embedded message failed validation", + cause: err, + } + } + } + + // no validation rules for Labels + + if len(errors) > 0 { + return UpdateResourceRequestMultiError(errors) + } + return nil +} + +// UpdateResourceRequestMultiError is an error wrapping multiple validation +// errors returned by UpdateResourceRequest.ValidateAll() if the designated +// constraints aren't met. +type UpdateResourceRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UpdateResourceRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m UpdateResourceRequestMultiError) AllErrors() []error { return m } + +// UpdateResourceRequestValidationError is the validation error returned by +// UpdateResourceRequest.Validate if the designated constraints aren't met. +type UpdateResourceRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UpdateResourceRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UpdateResourceRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UpdateResourceRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UpdateResourceRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UpdateResourceRequestValidationError) ErrorName() string { + return "UpdateResourceRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e UpdateResourceRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sUpdateResourceRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UpdateResourceRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UpdateResourceRequestValidationError{} + +// Validate checks the field values on UpdateResourceResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *UpdateResourceResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on UpdateResourceResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// UpdateResourceResponseMultiError, or nil if none found. +func (m *UpdateResourceResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *UpdateResourceResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetResource()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, UpdateResourceResponseValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, UpdateResourceResponseValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetResource()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return UpdateResourceResponseValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return UpdateResourceResponseMultiError(errors) + } + return nil +} + +// UpdateResourceResponseMultiError is an error wrapping multiple validation +// errors returned by UpdateResourceResponse.ValidateAll() if the designated +// constraints aren't met. +type UpdateResourceResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m UpdateResourceResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m UpdateResourceResponseMultiError) AllErrors() []error { return m } + +// UpdateResourceResponseValidationError is the validation error returned by +// UpdateResourceResponse.Validate if the designated constraints aren't met. +type UpdateResourceResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e UpdateResourceResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e UpdateResourceResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e UpdateResourceResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e UpdateResourceResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e UpdateResourceResponseValidationError) ErrorName() string { + return "UpdateResourceResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e UpdateResourceResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sUpdateResourceResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = UpdateResourceResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = UpdateResourceResponseValidationError{} + +// Validate checks the field values on DeleteResourceRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *DeleteResourceRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on DeleteResourceRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// DeleteResourceRequestMultiError, or nil if none found. +func (m *DeleteResourceRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *DeleteResourceRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Urn + + if len(errors) > 0 { + return DeleteResourceRequestMultiError(errors) + } + return nil +} + +// DeleteResourceRequestMultiError is an error wrapping multiple validation +// errors returned by DeleteResourceRequest.ValidateAll() if the designated +// constraints aren't met. +type DeleteResourceRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m DeleteResourceRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m DeleteResourceRequestMultiError) AllErrors() []error { return m } + +// DeleteResourceRequestValidationError is the validation error returned by +// DeleteResourceRequest.Validate if the designated constraints aren't met. +type DeleteResourceRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e DeleteResourceRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e DeleteResourceRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e DeleteResourceRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e DeleteResourceRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e DeleteResourceRequestValidationError) ErrorName() string { + return "DeleteResourceRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e DeleteResourceRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sDeleteResourceRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = DeleteResourceRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = DeleteResourceRequestValidationError{} + +// Validate checks the field values on DeleteResourceResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *DeleteResourceResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on DeleteResourceResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// DeleteResourceResponseMultiError, or nil if none found. +func (m *DeleteResourceResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *DeleteResourceResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return DeleteResourceResponseMultiError(errors) + } + return nil +} + +// DeleteResourceResponseMultiError is an error wrapping multiple validation +// errors returned by DeleteResourceResponse.ValidateAll() if the designated +// constraints aren't met. +type DeleteResourceResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m DeleteResourceResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m DeleteResourceResponseMultiError) AllErrors() []error { return m } + +// DeleteResourceResponseValidationError is the validation error returned by +// DeleteResourceResponse.Validate if the designated constraints aren't met. +type DeleteResourceResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e DeleteResourceResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e DeleteResourceResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e DeleteResourceResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e DeleteResourceResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e DeleteResourceResponseValidationError) ErrorName() string { + return "DeleteResourceResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e DeleteResourceResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sDeleteResourceResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = DeleteResourceResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = DeleteResourceResponseValidationError{} + +// Validate checks the field values on ApplyActionRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ApplyActionRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ApplyActionRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ApplyActionRequestMultiError, or nil if none found. +func (m *ApplyActionRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *ApplyActionRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Urn + + // no validation rules for Action + + if all { + switch v := interface{}(m.GetParams()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ApplyActionRequestValidationError{ + field: "Params", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ApplyActionRequestValidationError{ + field: "Params", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetParams()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ApplyActionRequestValidationError{ + field: "Params", + reason: "embedded message failed validation", + cause: err, + } + } + } + + // no validation rules for Labels + + if len(errors) > 0 { + return ApplyActionRequestMultiError(errors) + } + return nil +} + +// ApplyActionRequestMultiError is an error wrapping multiple validation errors +// returned by ApplyActionRequest.ValidateAll() if the designated constraints +// aren't met. +type ApplyActionRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ApplyActionRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ApplyActionRequestMultiError) AllErrors() []error { return m } + +// ApplyActionRequestValidationError is the validation error returned by +// ApplyActionRequest.Validate if the designated constraints aren't met. +type ApplyActionRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ApplyActionRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ApplyActionRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ApplyActionRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ApplyActionRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ApplyActionRequestValidationError) ErrorName() string { + return "ApplyActionRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e ApplyActionRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sApplyActionRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ApplyActionRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ApplyActionRequestValidationError{} + +// Validate checks the field values on ApplyActionResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ApplyActionResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ApplyActionResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ApplyActionResponseMultiError, or nil if none found. +func (m *ApplyActionResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *ApplyActionResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetResource()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ApplyActionResponseValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ApplyActionResponseValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetResource()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ApplyActionResponseValidationError{ + field: "Resource", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return ApplyActionResponseMultiError(errors) + } + return nil +} + +// ApplyActionResponseMultiError is an error wrapping multiple validation +// errors returned by ApplyActionResponse.ValidateAll() if the designated +// constraints aren't met. +type ApplyActionResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ApplyActionResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ApplyActionResponseMultiError) AllErrors() []error { return m } + +// ApplyActionResponseValidationError is the validation error returned by +// ApplyActionResponse.Validate if the designated constraints aren't met. +type ApplyActionResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ApplyActionResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ApplyActionResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ApplyActionResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ApplyActionResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ApplyActionResponseValidationError) ErrorName() string { + return "ApplyActionResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e ApplyActionResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sApplyActionResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ApplyActionResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ApplyActionResponseValidationError{} + +// Validate checks the field values on LogChunk with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *LogChunk) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on LogChunk with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in LogChunkMultiError, or nil +// if none found. +func (m *LogChunk) ValidateAll() error { + return m.validate(true) +} + +func (m *LogChunk) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Data + + // no validation rules for Labels + + if len(errors) > 0 { + return LogChunkMultiError(errors) + } + return nil +} + +// LogChunkMultiError is an error wrapping multiple validation errors returned +// by LogChunk.ValidateAll() if the designated constraints aren't met. +type LogChunkMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m LogChunkMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m LogChunkMultiError) AllErrors() []error { return m } + +// LogChunkValidationError is the validation error returned by +// LogChunk.Validate if the designated constraints aren't met. +type LogChunkValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e LogChunkValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e LogChunkValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e LogChunkValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e LogChunkValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e LogChunkValidationError) ErrorName() string { return "LogChunkValidationError" } + +// Error satisfies the builtin error interface +func (e LogChunkValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sLogChunk.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = LogChunkValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = LogChunkValidationError{} + +// Validate checks the field values on GetLogRequest with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *GetLogRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetLogRequest with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in GetLogRequestMultiError, or +// nil if none found. +func (m *GetLogRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *GetLogRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Urn + + // no validation rules for Filter + + if len(errors) > 0 { + return GetLogRequestMultiError(errors) + } + return nil +} + +// GetLogRequestMultiError is an error wrapping multiple validation errors +// returned by GetLogRequest.ValidateAll() if the designated constraints +// aren't met. +type GetLogRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetLogRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetLogRequestMultiError) AllErrors() []error { return m } + +// GetLogRequestValidationError is the validation error returned by +// GetLogRequest.Validate if the designated constraints aren't met. +type GetLogRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetLogRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetLogRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetLogRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetLogRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetLogRequestValidationError) ErrorName() string { return "GetLogRequestValidationError" } + +// Error satisfies the builtin error interface +func (e GetLogRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetLogRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetLogRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetLogRequestValidationError{} + +// Validate checks the field values on GetLogResponse with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *GetLogResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetLogResponse with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in GetLogResponseMultiError, +// or nil if none found. +func (m *GetLogResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *GetLogResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetChunk()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GetLogResponseValidationError{ + field: "Chunk", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GetLogResponseValidationError{ + field: "Chunk", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetChunk()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GetLogResponseValidationError{ + field: "Chunk", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if len(errors) > 0 { + return GetLogResponseMultiError(errors) + } + return nil +} + +// GetLogResponseMultiError is an error wrapping multiple validation errors +// returned by GetLogResponse.ValidateAll() if the designated constraints +// aren't met. +type GetLogResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetLogResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetLogResponseMultiError) AllErrors() []error { return m } + +// GetLogResponseValidationError is the validation error returned by +// GetLogResponse.Validate if the designated constraints aren't met. +type GetLogResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetLogResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetLogResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetLogResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetLogResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetLogResponseValidationError) ErrorName() string { return "GetLogResponseValidationError" } + +// Error satisfies the builtin error interface +func (e GetLogResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetLogResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetLogResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetLogResponseValidationError{} + +// Validate checks the field values on ResourceRevision with the rules defined +// in the proto definition for this message. If any rules are violated, the +// first error encountered is returned, or nil if there are no violations. +func (m *ResourceRevision) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ResourceRevision with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ResourceRevisionMultiError, or nil if none found. +func (m *ResourceRevision) ValidateAll() error { + return m.validate(true) +} + +func (m *ResourceRevision) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Id + + // no validation rules for Urn + + // no validation rules for Labels + + if all { + switch v := interface{}(m.GetCreatedAt()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ResourceRevisionValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ResourceRevisionValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetCreatedAt()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResourceRevisionValidationError{ + field: "CreatedAt", + reason: "embedded message failed validation", + cause: err, + } + } + } + + if all { + switch v := interface{}(m.GetSpec()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ResourceRevisionValidationError{ + field: "Spec", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ResourceRevisionValidationError{ + field: "Spec", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetSpec()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResourceRevisionValidationError{ + field: "Spec", + reason: "embedded message failed validation", + cause: err, + } + } + } + + // no validation rules for Reason + + if len(errors) > 0 { + return ResourceRevisionMultiError(errors) + } + return nil +} + +// ResourceRevisionMultiError is an error wrapping multiple validation errors +// returned by ResourceRevision.ValidateAll() if the designated constraints +// aren't met. +type ResourceRevisionMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ResourceRevisionMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ResourceRevisionMultiError) AllErrors() []error { return m } + +// ResourceRevisionValidationError is the validation error returned by +// ResourceRevision.Validate if the designated constraints aren't met. +type ResourceRevisionValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ResourceRevisionValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ResourceRevisionValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ResourceRevisionValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ResourceRevisionValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ResourceRevisionValidationError) ErrorName() string { return "ResourceRevisionValidationError" } + +// Error satisfies the builtin error interface +func (e ResourceRevisionValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sResourceRevision.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ResourceRevisionValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ResourceRevisionValidationError{} + +// Validate checks the field values on GetResourceRevisionsRequest with the +// rules defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GetResourceRevisionsRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetResourceRevisionsRequest with the +// rules defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GetResourceRevisionsRequestMultiError, or nil if none found. +func (m *GetResourceRevisionsRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *GetResourceRevisionsRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Urn + + if len(errors) > 0 { + return GetResourceRevisionsRequestMultiError(errors) + } + return nil +} + +// GetResourceRevisionsRequestMultiError is an error wrapping multiple +// validation errors returned by GetResourceRevisionsRequest.ValidateAll() if +// the designated constraints aren't met. +type GetResourceRevisionsRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetResourceRevisionsRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetResourceRevisionsRequestMultiError) AllErrors() []error { return m } + +// GetResourceRevisionsRequestValidationError is the validation error returned +// by GetResourceRevisionsRequest.Validate if the designated constraints +// aren't met. +type GetResourceRevisionsRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetResourceRevisionsRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetResourceRevisionsRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetResourceRevisionsRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetResourceRevisionsRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetResourceRevisionsRequestValidationError) ErrorName() string { + return "GetResourceRevisionsRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e GetResourceRevisionsRequestValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetResourceRevisionsRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetResourceRevisionsRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetResourceRevisionsRequestValidationError{} + +// Validate checks the field values on GetResourceRevisionsResponse with the +// rules defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GetResourceRevisionsResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GetResourceRevisionsResponse with the +// rules defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GetResourceRevisionsResponseMultiError, or nil if none found. +func (m *GetResourceRevisionsResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *GetResourceRevisionsResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + for idx, item := range m.GetRevisions() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GetResourceRevisionsResponseValidationError{ + field: fmt.Sprintf("Revisions[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GetResourceRevisionsResponseValidationError{ + field: fmt.Sprintf("Revisions[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GetResourceRevisionsResponseValidationError{ + field: fmt.Sprintf("Revisions[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return GetResourceRevisionsResponseMultiError(errors) + } + return nil +} + +// GetResourceRevisionsResponseMultiError is an error wrapping multiple +// validation errors returned by GetResourceRevisionsResponse.ValidateAll() if +// the designated constraints aren't met. +type GetResourceRevisionsResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GetResourceRevisionsResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GetResourceRevisionsResponseMultiError) AllErrors() []error { return m } + +// GetResourceRevisionsResponseValidationError is the validation error returned +// by GetResourceRevisionsResponse.Validate if the designated constraints +// aren't met. +type GetResourceRevisionsResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GetResourceRevisionsResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GetResourceRevisionsResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GetResourceRevisionsResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GetResourceRevisionsResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GetResourceRevisionsResponseValidationError) ErrorName() string { + return "GetResourceRevisionsResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e GetResourceRevisionsResponseValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGetResourceRevisionsResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GetResourceRevisionsResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GetResourceRevisionsResponseValidationError{} diff --git a/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go b/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go new file mode 100644 index 00000000..4bb55330 --- /dev/null +++ b/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go @@ -0,0 +1,381 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package entropyv1beta1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// ResourceServiceClient is the client API for ResourceService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ResourceServiceClient interface { + ListResources(ctx context.Context, in *ListResourcesRequest, opts ...grpc.CallOption) (*ListResourcesResponse, error) + GetResource(ctx context.Context, in *GetResourceRequest, opts ...grpc.CallOption) (*GetResourceResponse, error) + CreateResource(ctx context.Context, in *CreateResourceRequest, opts ...grpc.CallOption) (*CreateResourceResponse, error) + UpdateResource(ctx context.Context, in *UpdateResourceRequest, opts ...grpc.CallOption) (*UpdateResourceResponse, error) + DeleteResource(ctx context.Context, in *DeleteResourceRequest, opts ...grpc.CallOption) (*DeleteResourceResponse, error) + ApplyAction(ctx context.Context, in *ApplyActionRequest, opts ...grpc.CallOption) (*ApplyActionResponse, error) + GetLog(ctx context.Context, in *GetLogRequest, opts ...grpc.CallOption) (ResourceService_GetLogClient, error) + GetResourceRevisions(ctx context.Context, in *GetResourceRevisionsRequest, opts ...grpc.CallOption) (*GetResourceRevisionsResponse, error) +} + +type resourceServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewResourceServiceClient(cc grpc.ClientConnInterface) ResourceServiceClient { + return &resourceServiceClient{cc} +} + +func (c *resourceServiceClient) ListResources(ctx context.Context, in *ListResourcesRequest, opts ...grpc.CallOption) (*ListResourcesResponse, error) { + out := new(ListResourcesResponse) + err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ResourceService/ListResources", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceServiceClient) GetResource(ctx context.Context, in *GetResourceRequest, opts ...grpc.CallOption) (*GetResourceResponse, error) { + out := new(GetResourceResponse) + err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ResourceService/GetResource", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceServiceClient) CreateResource(ctx context.Context, in *CreateResourceRequest, opts ...grpc.CallOption) (*CreateResourceResponse, error) { + out := new(CreateResourceResponse) + err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ResourceService/CreateResource", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceServiceClient) UpdateResource(ctx context.Context, in *UpdateResourceRequest, opts ...grpc.CallOption) (*UpdateResourceResponse, error) { + out := new(UpdateResourceResponse) + err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ResourceService/UpdateResource", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceServiceClient) DeleteResource(ctx context.Context, in *DeleteResourceRequest, opts ...grpc.CallOption) (*DeleteResourceResponse, error) { + out := new(DeleteResourceResponse) + err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ResourceService/DeleteResource", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceServiceClient) ApplyAction(ctx context.Context, in *ApplyActionRequest, opts ...grpc.CallOption) (*ApplyActionResponse, error) { + out := new(ApplyActionResponse) + err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ResourceService/ApplyAction", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceServiceClient) GetLog(ctx context.Context, in *GetLogRequest, opts ...grpc.CallOption) (ResourceService_GetLogClient, error) { + stream, err := c.cc.NewStream(ctx, &ResourceService_ServiceDesc.Streams[0], "/gotocompany.entropy.v1beta1.ResourceService/GetLog", opts...) + if err != nil { + return nil, err + } + x := &resourceServiceGetLogClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type ResourceService_GetLogClient interface { + Recv() (*GetLogResponse, error) + grpc.ClientStream +} + +type resourceServiceGetLogClient struct { + grpc.ClientStream +} + +func (x *resourceServiceGetLogClient) Recv() (*GetLogResponse, error) { + m := new(GetLogResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *resourceServiceClient) GetResourceRevisions(ctx context.Context, in *GetResourceRevisionsRequest, opts ...grpc.CallOption) (*GetResourceRevisionsResponse, error) { + out := new(GetResourceRevisionsResponse) + err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ResourceService/GetResourceRevisions", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ResourceServiceServer is the server API for ResourceService service. +// All implementations must embed UnimplementedResourceServiceServer +// for forward compatibility +type ResourceServiceServer interface { + ListResources(context.Context, *ListResourcesRequest) (*ListResourcesResponse, error) + GetResource(context.Context, *GetResourceRequest) (*GetResourceResponse, error) + CreateResource(context.Context, *CreateResourceRequest) (*CreateResourceResponse, error) + UpdateResource(context.Context, *UpdateResourceRequest) (*UpdateResourceResponse, error) + DeleteResource(context.Context, *DeleteResourceRequest) (*DeleteResourceResponse, error) + ApplyAction(context.Context, *ApplyActionRequest) (*ApplyActionResponse, error) + GetLog(*GetLogRequest, ResourceService_GetLogServer) error + GetResourceRevisions(context.Context, *GetResourceRevisionsRequest) (*GetResourceRevisionsResponse, error) + mustEmbedUnimplementedResourceServiceServer() +} + +// UnimplementedResourceServiceServer must be embedded to have forward compatible implementations. +type UnimplementedResourceServiceServer struct { +} + +func (UnimplementedResourceServiceServer) ListResources(context.Context, *ListResourcesRequest) (*ListResourcesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListResources not implemented") +} +func (UnimplementedResourceServiceServer) GetResource(context.Context, *GetResourceRequest) (*GetResourceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetResource not implemented") +} +func (UnimplementedResourceServiceServer) CreateResource(context.Context, *CreateResourceRequest) (*CreateResourceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateResource not implemented") +} +func (UnimplementedResourceServiceServer) UpdateResource(context.Context, *UpdateResourceRequest) (*UpdateResourceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateResource not implemented") +} +func (UnimplementedResourceServiceServer) DeleteResource(context.Context, *DeleteResourceRequest) (*DeleteResourceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteResource not implemented") +} +func (UnimplementedResourceServiceServer) ApplyAction(context.Context, *ApplyActionRequest) (*ApplyActionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ApplyAction not implemented") +} +func (UnimplementedResourceServiceServer) GetLog(*GetLogRequest, ResourceService_GetLogServer) error { + return status.Errorf(codes.Unimplemented, "method GetLog not implemented") +} +func (UnimplementedResourceServiceServer) GetResourceRevisions(context.Context, *GetResourceRevisionsRequest) (*GetResourceRevisionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetResourceRevisions not implemented") +} +func (UnimplementedResourceServiceServer) mustEmbedUnimplementedResourceServiceServer() {} + +// UnsafeResourceServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ResourceServiceServer will +// result in compilation errors. +type UnsafeResourceServiceServer interface { + mustEmbedUnimplementedResourceServiceServer() +} + +func RegisterResourceServiceServer(s grpc.ServiceRegistrar, srv ResourceServiceServer) { + s.RegisterService(&ResourceService_ServiceDesc, srv) +} + +func _ResourceService_ListResources_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListResourcesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceServiceServer).ListResources(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gotocompany.entropy.v1beta1.ResourceService/ListResources", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceServiceServer).ListResources(ctx, req.(*ListResourcesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceService_GetResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetResourceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceServiceServer).GetResource(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gotocompany.entropy.v1beta1.ResourceService/GetResource", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceServiceServer).GetResource(ctx, req.(*GetResourceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceService_CreateResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateResourceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceServiceServer).CreateResource(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gotocompany.entropy.v1beta1.ResourceService/CreateResource", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceServiceServer).CreateResource(ctx, req.(*CreateResourceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceService_UpdateResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateResourceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceServiceServer).UpdateResource(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gotocompany.entropy.v1beta1.ResourceService/UpdateResource", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceServiceServer).UpdateResource(ctx, req.(*UpdateResourceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceService_DeleteResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteResourceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceServiceServer).DeleteResource(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gotocompany.entropy.v1beta1.ResourceService/DeleteResource", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceServiceServer).DeleteResource(ctx, req.(*DeleteResourceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceService_ApplyAction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ApplyActionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceServiceServer).ApplyAction(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gotocompany.entropy.v1beta1.ResourceService/ApplyAction", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceServiceServer).ApplyAction(ctx, req.(*ApplyActionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceService_GetLog_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(GetLogRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(ResourceServiceServer).GetLog(m, &resourceServiceGetLogServer{stream}) +} + +type ResourceService_GetLogServer interface { + Send(*GetLogResponse) error + grpc.ServerStream +} + +type resourceServiceGetLogServer struct { + grpc.ServerStream +} + +func (x *resourceServiceGetLogServer) Send(m *GetLogResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _ResourceService_GetResourceRevisions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetResourceRevisionsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceServiceServer).GetResourceRevisions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gotocompany.entropy.v1beta1.ResourceService/GetResourceRevisions", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceServiceServer).GetResourceRevisions(ctx, req.(*GetResourceRevisionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// ResourceService_ServiceDesc is the grpc.ServiceDesc for ResourceService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ResourceService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "gotocompany.entropy.v1beta1.ResourceService", + HandlerType: (*ResourceServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "ListResources", + Handler: _ResourceService_ListResources_Handler, + }, + { + MethodName: "GetResource", + Handler: _ResourceService_GetResource_Handler, + }, + { + MethodName: "CreateResource", + Handler: _ResourceService_CreateResource_Handler, + }, + { + MethodName: "UpdateResource", + Handler: _ResourceService_UpdateResource_Handler, + }, + { + MethodName: "DeleteResource", + Handler: _ResourceService_DeleteResource_Handler, + }, + { + MethodName: "ApplyAction", + Handler: _ResourceService_ApplyAction_Handler, + }, + { + MethodName: "GetResourceRevisions", + Handler: _ResourceService_GetResourceRevisions_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "GetLog", + Handler: _ResourceService_GetLog_Handler, + ServerStreams: true, + }, + }, + Metadata: "gotocompany/entropy/v1beta1/resource.proto", +} From 3b338aaa28b7d12dbe719a4d6337db0a513e2ab3 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Tue, 14 Mar 2023 17:08:37 +0530 Subject: [PATCH 04/72] fix: golanci config (#3) * fix: golanci config * fix: gci lint issues * fix: lint issues * fix: remove nosnakecase lint from disable list --- .golangci.yml | 2 +- cli/action.go | 3 +- cli/client.go | 3 +- cli/logs.go | 6 +-- cli/resource.go | 6 +-- core/mocks/async_worker.go | 4 +- core/mocks/driver.go | 14 +++---- core/mocks/loggable_module.go | 20 ++++----- core/mocks/module_registry.go | 7 ++-- core/mocks/module_service.go | 20 ++++----- core/mocks/module_store.go | 23 ++++++----- core/mocks/resource_store.go | 37 +++++++++-------- internal/server/server.go | 18 +++++--- internal/server/v1/mocks/module_service.go | 22 +++++----- internal/server/v1/mocks/resource_service.go | 41 ++++++++++--------- internal/server/v1/modules/mappers.go | 2 +- internal/server/v1/modules/server.go | 3 +- internal/server/v1/modules/server_test.go | 2 +- internal/server/v1/resources/mappers.go | 2 +- internal/server/v1/resources/server.go | 3 +- internal/server/v1/resources/server_test.go | 2 +- internal/store/postgres/postgres.go | 1 + pkg/common/common.go | 1 + pkg/helm/status.go | 4 +- pkg/kube/client_test.go | 3 +- pkg/telemetry/telemetry.go | 1 + pkg/version/version.go | 4 +- pkg/worker/mocks/job_queue.go | 13 +++--- proto/gotocompany/common/v1/service.pb.go | 5 ++- .../gotocompany/common/v1/service_grpc.pb.go | 1 + .../gotocompany/entropy/v1beta1/module.pb.go | 5 ++- .../entropy/v1beta1/module_grpc.pb.go | 1 + .../entropy/v1beta1/resource.pb.go | 5 ++- .../entropy/v1beta1/resource_grpc.pb.go | 1 + 34 files changed, 154 insertions(+), 131 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 5b10261e..53ffc774 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -43,9 +43,9 @@ linters: linters-settings: decorder: dec-order: - - type - const - var + - type - func disable-dec-order-check: false disable-init-func-first-check: false diff --git a/cli/action.go b/cli/action.go index d36dbb13..470e1d4d 100644 --- a/cli/action.go +++ b/cli/action.go @@ -4,11 +4,12 @@ import ( "fmt" "github.com/MakeNowJust/heredoc" - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" "github.com/goto/salt/printer" "github.com/goto/salt/term" "github.com/spf13/cobra" "google.golang.org/protobuf/types/known/structpb" + + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" ) func cmdAction() *cobra.Command { diff --git a/cli/client.go b/cli/client.go index 1fc0d4e8..221185aa 100644 --- a/cli/client.go +++ b/cli/client.go @@ -5,10 +5,11 @@ import ( "strconv" "time" - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" "github.com/spf13/cobra" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" + + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" ) const timeout = 2 diff --git a/cli/logs.go b/cli/logs.go index f89e8beb..ad77d513 100644 --- a/cli/logs.go +++ b/cli/logs.go @@ -7,12 +7,12 @@ import ( "log" "strings" - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" - "github.com/goto/salt/term" // nolint - "github.com/MakeNowJust/heredoc" "github.com/goto/salt/printer" + "github.com/goto/salt/term" // nolint "github.com/spf13/cobra" + + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" ) func cmdLogs() *cobra.Command { diff --git a/cli/resource.go b/cli/resource.go index c2eb8b14..4ded7d16 100644 --- a/cli/resource.go +++ b/cli/resource.go @@ -4,12 +4,12 @@ import ( "fmt" "os" - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" - "github.com/goto/salt/term" // nolint - "github.com/MakeNowJust/heredoc" "github.com/goto/salt/printer" + "github.com/goto/salt/term" // nolint "github.com/spf13/cobra" + + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" ) func cmdResource() *cobra.Command { diff --git a/core/mocks/async_worker.go b/core/mocks/async_worker.go index 5910d8ed..2223efda 100644 --- a/core/mocks/async_worker.go +++ b/core/mocks/async_worker.go @@ -50,8 +50,8 @@ type AsyncWorker_Enqueue_Call struct { } // Enqueue is a helper method to define mock.On call -// - ctx context.Context -// - jobs ...worker.Job +// - ctx context.Context +// - jobs ...worker.Job func (_e *AsyncWorker_Expecter) Enqueue(ctx interface{}, jobs ...interface{}) *AsyncWorker_Enqueue_Call { return &AsyncWorker_Enqueue_Call{Call: _e.mock.On("Enqueue", append([]interface{}{ctx}, jobs...)...)} diff --git a/core/mocks/driver.go b/core/mocks/driver.go index 23c4c8a2..bd8e990d 100644 --- a/core/mocks/driver.go +++ b/core/mocks/driver.go @@ -55,8 +55,8 @@ type ModuleDriver_Output_Call struct { } // Output is a helper method to define mock.On call -// - ctx context.Context -// - res module.ExpandedResource +// - ctx context.Context +// - res module.ExpandedResource func (_e *ModuleDriver_Expecter) Output(ctx interface{}, res interface{}) *ModuleDriver_Output_Call { return &ModuleDriver_Output_Call{Call: _e.mock.On("Output", ctx, res)} } @@ -102,9 +102,9 @@ type ModuleDriver_Plan_Call struct { } // Plan is a helper method to define mock.On call -// - ctx context.Context -// - res module.ExpandedResource -// - act module.ActionRequest +// - ctx context.Context +// - res module.ExpandedResource +// - act module.ActionRequest func (_e *ModuleDriver_Expecter) Plan(ctx interface{}, res interface{}, act interface{}) *ModuleDriver_Plan_Call { return &ModuleDriver_Plan_Call{Call: _e.mock.On("Plan", ctx, res, act)} } @@ -150,8 +150,8 @@ type ModuleDriver_Sync_Call struct { } // Sync is a helper method to define mock.On call -// - ctx context.Context -// - res module.ExpandedResource +// - ctx context.Context +// - res module.ExpandedResource func (_e *ModuleDriver_Expecter) Sync(ctx interface{}, res interface{}) *ModuleDriver_Sync_Call { return &ModuleDriver_Sync_Call{Call: _e.mock.On("Sync", ctx, res)} } diff --git a/core/mocks/loggable_module.go b/core/mocks/loggable_module.go index c6a61752..888df706 100644 --- a/core/mocks/loggable_module.go +++ b/core/mocks/loggable_module.go @@ -55,9 +55,9 @@ type LoggableModule_Log_Call struct { } // Log is a helper method to define mock.On call -// - ctx context.Context -// - res module.ExpandedResource -// - filter map[string]string +// - ctx context.Context +// - res module.ExpandedResource +// - filter map[string]string func (_e *LoggableModule_Expecter) Log(ctx interface{}, res interface{}, filter interface{}) *LoggableModule_Log_Call { return &LoggableModule_Log_Call{Call: _e.mock.On("Log", ctx, res, filter)} } @@ -103,8 +103,8 @@ type LoggableModule_Output_Call struct { } // Output is a helper method to define mock.On call -// - ctx context.Context -// - res module.ExpandedResource +// - ctx context.Context +// - res module.ExpandedResource func (_e *LoggableModule_Expecter) Output(ctx interface{}, res interface{}) *LoggableModule_Output_Call { return &LoggableModule_Output_Call{Call: _e.mock.On("Output", ctx, res)} } @@ -150,9 +150,9 @@ type LoggableModule_Plan_Call struct { } // Plan is a helper method to define mock.On call -// - ctx context.Context -// - res module.ExpandedResource -// - act module.ActionRequest +// - ctx context.Context +// - res module.ExpandedResource +// - act module.ActionRequest func (_e *LoggableModule_Expecter) Plan(ctx interface{}, res interface{}, act interface{}) *LoggableModule_Plan_Call { return &LoggableModule_Plan_Call{Call: _e.mock.On("Plan", ctx, res, act)} } @@ -198,8 +198,8 @@ type LoggableModule_Sync_Call struct { } // Sync is a helper method to define mock.On call -// - ctx context.Context -// - res module.ExpandedResource +// - ctx context.Context +// - res module.ExpandedResource func (_e *LoggableModule_Expecter) Sync(ctx interface{}, res interface{}) *LoggableModule_Sync_Call { return &LoggableModule_Sync_Call{Call: _e.mock.On("Sync", ctx, res)} } diff --git a/core/mocks/module_registry.go b/core/mocks/module_registry.go index 68563c20..f5d95bef 100644 --- a/core/mocks/module_registry.go +++ b/core/mocks/module_registry.go @@ -5,8 +5,9 @@ package mocks import ( context "context" - module "github.com/goto/entropy/core/module" mock "github.com/stretchr/testify/mock" + + module "github.com/goto/entropy/core/module" ) // ModuleRegistry is an autogenerated mock type for the Registry type @@ -58,8 +59,8 @@ type ModuleRegistry_GetDriver_Call struct { } // GetDriver is a helper method to define mock.On call -// - ctx context.Context -// - mod module.Module +// - ctx context.Context +// - mod module.Module func (_e *ModuleRegistry_Expecter) GetDriver(ctx interface{}, mod interface{}) *ModuleRegistry_GetDriver_Call { return &ModuleRegistry_GetDriver_Call{Call: _e.mock.On("GetDriver", ctx, mod)} } diff --git a/core/mocks/module_service.go b/core/mocks/module_service.go index d3f9876d..03a6a29c 100644 --- a/core/mocks/module_service.go +++ b/core/mocks/module_service.go @@ -56,8 +56,8 @@ type ModuleService_GetOutput_Call struct { } // GetOutput is a helper method to define mock.On call -// - ctx context.Context -// - res module.ExpandedResource +// - ctx context.Context +// - res module.ExpandedResource func (_e *ModuleService_Expecter) GetOutput(ctx interface{}, res interface{}) *ModuleService_GetOutput_Call { return &ModuleService_GetOutput_Call{Call: _e.mock.On("GetOutput", ctx, res)} } @@ -103,9 +103,9 @@ type ModuleService_PlanAction_Call struct { } // PlanAction is a helper method to define mock.On call -// - ctx context.Context -// - res module.ExpandedResource -// - act module.ActionRequest +// - ctx context.Context +// - res module.ExpandedResource +// - act module.ActionRequest func (_e *ModuleService_Expecter) PlanAction(ctx interface{}, res interface{}, act interface{}) *ModuleService_PlanAction_Call { return &ModuleService_PlanAction_Call{Call: _e.mock.On("PlanAction", ctx, res, act)} } @@ -151,9 +151,9 @@ type ModuleService_StreamLogs_Call struct { } // StreamLogs is a helper method to define mock.On call -// - ctx context.Context -// - res module.ExpandedResource -// - filter map[string]string +// - ctx context.Context +// - res module.ExpandedResource +// - filter map[string]string func (_e *ModuleService_Expecter) StreamLogs(ctx interface{}, res interface{}, filter interface{}) *ModuleService_StreamLogs_Call { return &ModuleService_StreamLogs_Call{Call: _e.mock.On("StreamLogs", ctx, res, filter)} } @@ -199,8 +199,8 @@ type ModuleService_SyncState_Call struct { } // SyncState is a helper method to define mock.On call -// - ctx context.Context -// - res module.ExpandedResource +// - ctx context.Context +// - res module.ExpandedResource func (_e *ModuleService_Expecter) SyncState(ctx interface{}, res interface{}) *ModuleService_SyncState_Call { return &ModuleService_SyncState_Call{Call: _e.mock.On("SyncState", ctx, res)} } diff --git a/core/mocks/module_store.go b/core/mocks/module_store.go index f8e50a5a..873d6a0e 100644 --- a/core/mocks/module_store.go +++ b/core/mocks/module_store.go @@ -5,8 +5,9 @@ package mocks import ( context "context" - module "github.com/goto/entropy/core/module" mock "github.com/stretchr/testify/mock" + + module "github.com/goto/entropy/core/module" ) // ModuleStore is an autogenerated mock type for the Store type @@ -42,8 +43,8 @@ type ModuleStore_CreateModule_Call struct { } // CreateModule is a helper method to define mock.On call -// - ctx context.Context -// - m module.Module +// - ctx context.Context +// - m module.Module func (_e *ModuleStore_Expecter) CreateModule(ctx interface{}, m interface{}) *ModuleStore_CreateModule_Call { return &ModuleStore_CreateModule_Call{Call: _e.mock.On("CreateModule", ctx, m)} } @@ -80,8 +81,8 @@ type ModuleStore_DeleteModule_Call struct { } // DeleteModule is a helper method to define mock.On call -// - ctx context.Context -// - urn string +// - ctx context.Context +// - urn string func (_e *ModuleStore_Expecter) DeleteModule(ctx interface{}, urn interface{}) *ModuleStore_DeleteModule_Call { return &ModuleStore_DeleteModule_Call{Call: _e.mock.On("DeleteModule", ctx, urn)} } @@ -127,8 +128,8 @@ type ModuleStore_GetModule_Call struct { } // GetModule is a helper method to define mock.On call -// - ctx context.Context -// - urn string +// - ctx context.Context +// - urn string func (_e *ModuleStore_Expecter) GetModule(ctx interface{}, urn interface{}) *ModuleStore_GetModule_Call { return &ModuleStore_GetModule_Call{Call: _e.mock.On("GetModule", ctx, urn)} } @@ -174,8 +175,8 @@ type ModuleStore_ListModules_Call struct { } // ListModules is a helper method to define mock.On call -// - ctx context.Context -// - project string +// - ctx context.Context +// - project string func (_e *ModuleStore_Expecter) ListModules(ctx interface{}, project interface{}) *ModuleStore_ListModules_Call { return &ModuleStore_ListModules_Call{Call: _e.mock.On("ListModules", ctx, project)} } @@ -212,8 +213,8 @@ type ModuleStore_UpdateModule_Call struct { } // UpdateModule is a helper method to define mock.On call -// - ctx context.Context -// - m module.Module +// - ctx context.Context +// - m module.Module func (_e *ModuleStore_Expecter) UpdateModule(ctx interface{}, m interface{}) *ModuleStore_UpdateModule_Call { return &ModuleStore_UpdateModule_Call{Call: _e.mock.On("UpdateModule", ctx, m)} } diff --git a/core/mocks/resource_store.go b/core/mocks/resource_store.go index ac7dd6ea..96087d48 100644 --- a/core/mocks/resource_store.go +++ b/core/mocks/resource_store.go @@ -5,8 +5,9 @@ package mocks import ( context "context" - resource "github.com/goto/entropy/core/resource" mock "github.com/stretchr/testify/mock" + + resource "github.com/goto/entropy/core/resource" ) // ResourceStore is an autogenerated mock type for the Store type @@ -49,9 +50,9 @@ type ResourceStore_Create_Call struct { } // Create is a helper method to define mock.On call -// - ctx context.Context -// - r resource.Resource -// - hooks ...resource.MutationHook +// - ctx context.Context +// - r resource.Resource +// - hooks ...resource.MutationHook func (_e *ResourceStore_Expecter) Create(ctx interface{}, r interface{}, hooks ...interface{}) *ResourceStore_Create_Call { return &ResourceStore_Create_Call{Call: _e.mock.On("Create", append([]interface{}{ctx, r}, hooks...)...)} @@ -102,9 +103,9 @@ type ResourceStore_Delete_Call struct { } // Delete is a helper method to define mock.On call -// - ctx context.Context -// - urn string -// - hooks ...resource.MutationHook +// - ctx context.Context +// - urn string +// - hooks ...resource.MutationHook func (_e *ResourceStore_Expecter) Delete(ctx interface{}, urn interface{}, hooks ...interface{}) *ResourceStore_Delete_Call { return &ResourceStore_Delete_Call{Call: _e.mock.On("Delete", append([]interface{}{ctx, urn}, hooks...)...)} @@ -157,8 +158,8 @@ type ResourceStore_GetByURN_Call struct { } // GetByURN is a helper method to define mock.On call -// - ctx context.Context -// - urn string +// - ctx context.Context +// - urn string func (_e *ResourceStore_Expecter) GetByURN(ctx interface{}, urn interface{}) *ResourceStore_GetByURN_Call { return &ResourceStore_GetByURN_Call{Call: _e.mock.On("GetByURN", ctx, urn)} } @@ -204,8 +205,8 @@ type ResourceStore_List_Call struct { } // List is a helper method to define mock.On call -// - ctx context.Context -// - filter resource.Filter +// - ctx context.Context +// - filter resource.Filter func (_e *ResourceStore_Expecter) List(ctx interface{}, filter interface{}) *ResourceStore_List_Call { return &ResourceStore_List_Call{Call: _e.mock.On("List", ctx, filter)} } @@ -251,8 +252,8 @@ type ResourceStore_Revisions_Call struct { } // Revisions is a helper method to define mock.On call -// - ctx context.Context -// - selector resource.RevisionsSelector +// - ctx context.Context +// - selector resource.RevisionsSelector func (_e *ResourceStore_Expecter) Revisions(ctx interface{}, selector interface{}) *ResourceStore_Revisions_Call { return &ResourceStore_Revisions_Call{Call: _e.mock.On("Revisions", ctx, selector)} } @@ -296,11 +297,11 @@ type ResourceStore_Update_Call struct { } // Update is a helper method to define mock.On call -// - ctx context.Context -// - r resource.Resource -// - saveRevision bool -// - reason string -// - hooks ...resource.MutationHook +// - ctx context.Context +// - r resource.Resource +// - saveRevision bool +// - reason string +// - hooks ...resource.MutationHook func (_e *ResourceStore_Expecter) Update(ctx interface{}, r interface{}, saveRevision interface{}, reason interface{}, hooks ...interface{}) *ResourceStore_Update_Call { return &ResourceStore_Update_Call{Call: _e.mock.On("Update", append([]interface{}{ctx, r, saveRevision, reason}, hooks...)...)} diff --git a/internal/server/server.go b/internal/server/server.go index b3f44474..8e0e382c 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -7,8 +7,6 @@ import ( "time" gorillamux "github.com/gorilla/mux" - commonv1 "github.com/goto/entropy/proto/gotocompany/common/v1" - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" "github.com/goto/salt/mux" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_zap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" @@ -28,9 +26,16 @@ import ( resourcesv1 "github.com/goto/entropy/internal/server/v1/resources" "github.com/goto/entropy/pkg/common" "github.com/goto/entropy/pkg/version" + commonv1 "github.com/goto/entropy/proto/gotocompany/common/v1" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" ) -const defaultGracePeriod = 5 * time.Second +const ( + gracePeriod = 5 * time.Second + readTimeout = 120 * time.Second + writeTimeout = 120 * time.Second + maxHeaderBytes = 1 << 20 +) // Serve initialises all the gRPC+HTTP API routes, starts listening for requests at addr, and blocks until server exits. // Server exits gracefully when context is cancelled. @@ -93,9 +98,12 @@ func Serve(ctx context.Context, addr string, nrApp *newrelic.Application, logger logger.Info("starting server", zap.String("addr", addr)) return mux.Serve(ctx, mux.WithHTTPTarget(":8081", &http.Server{ - Handler: httpRouter, + Handler: httpRouter, + ReadTimeout: readTimeout, + WriteTimeout: writeTimeout, + MaxHeaderBytes: maxHeaderBytes, }), mux.WithGRPCTarget(addr, grpcServer), - mux.WithGracePeriod(defaultGracePeriod), + mux.WithGracePeriod(gracePeriod), ) } diff --git a/internal/server/v1/mocks/module_service.go b/internal/server/v1/mocks/module_service.go index 49545818..a486135c 100644 --- a/internal/server/v1/mocks/module_service.go +++ b/internal/server/v1/mocks/module_service.go @@ -53,8 +53,8 @@ type ModuleService_CreateModule_Call struct { } // CreateModule is a helper method to define mock.On call -// - ctx context.Context -// - mod module.Module +// - ctx context.Context +// - mod module.Module func (_e *ModuleService_Expecter) CreateModule(ctx interface{}, mod interface{}) *ModuleService_CreateModule_Call { return &ModuleService_CreateModule_Call{Call: _e.mock.On("CreateModule", ctx, mod)} } @@ -91,8 +91,8 @@ type ModuleService_DeleteModule_Call struct { } // DeleteModule is a helper method to define mock.On call -// - ctx context.Context -// - urn string +// - ctx context.Context +// - urn string func (_e *ModuleService_Expecter) DeleteModule(ctx interface{}, urn interface{}) *ModuleService_DeleteModule_Call { return &ModuleService_DeleteModule_Call{Call: _e.mock.On("DeleteModule", ctx, urn)} } @@ -138,8 +138,8 @@ type ModuleService_GetModule_Call struct { } // GetModule is a helper method to define mock.On call -// - ctx context.Context -// - urn string +// - ctx context.Context +// - urn string func (_e *ModuleService_Expecter) GetModule(ctx interface{}, urn interface{}) *ModuleService_GetModule_Call { return &ModuleService_GetModule_Call{Call: _e.mock.On("GetModule", ctx, urn)} } @@ -185,8 +185,8 @@ type ModuleService_ListModules_Call struct { } // ListModules is a helper method to define mock.On call -// - ctx context.Context -// - project string +// - ctx context.Context +// - project string func (_e *ModuleService_Expecter) ListModules(ctx interface{}, project interface{}) *ModuleService_ListModules_Call { return &ModuleService_ListModules_Call{Call: _e.mock.On("ListModules", ctx, project)} } @@ -232,9 +232,9 @@ type ModuleService_UpdateModule_Call struct { } // UpdateModule is a helper method to define mock.On call -// - ctx context.Context -// - urn string -// - newConfigs json.RawMessage +// - ctx context.Context +// - urn string +// - newConfigs json.RawMessage func (_e *ModuleService_Expecter) UpdateModule(ctx interface{}, urn interface{}, newConfigs interface{}) *ModuleService_UpdateModule_Call { return &ModuleService_UpdateModule_Call{Call: _e.mock.On("UpdateModule", ctx, urn, newConfigs)} } diff --git a/internal/server/v1/mocks/resource_service.go b/internal/server/v1/mocks/resource_service.go index 9f3a8185..d0f09d0f 100644 --- a/internal/server/v1/mocks/resource_service.go +++ b/internal/server/v1/mocks/resource_service.go @@ -5,9 +5,10 @@ package mocks import ( context "context" - module "github.com/goto/entropy/core/module" mock "github.com/stretchr/testify/mock" + module "github.com/goto/entropy/core/module" + resource "github.com/goto/entropy/core/resource" ) @@ -53,9 +54,9 @@ type ResourceService_ApplyAction_Call struct { } // ApplyAction is a helper method to define mock.On call -// - ctx context.Context -// - urn string -// - action module.ActionRequest +// - ctx context.Context +// - urn string +// - action module.ActionRequest func (_e *ResourceService_Expecter) ApplyAction(ctx interface{}, urn interface{}, action interface{}) *ResourceService_ApplyAction_Call { return &ResourceService_ApplyAction_Call{Call: _e.mock.On("ApplyAction", ctx, urn, action)} } @@ -101,8 +102,8 @@ type ResourceService_CreateResource_Call struct { } // CreateResource is a helper method to define mock.On call -// - ctx context.Context -// - res resource.Resource +// - ctx context.Context +// - res resource.Resource func (_e *ResourceService_Expecter) CreateResource(ctx interface{}, res interface{}) *ResourceService_CreateResource_Call { return &ResourceService_CreateResource_Call{Call: _e.mock.On("CreateResource", ctx, res)} } @@ -139,8 +140,8 @@ type ResourceService_DeleteResource_Call struct { } // DeleteResource is a helper method to define mock.On call -// - ctx context.Context -// - urn string +// - ctx context.Context +// - urn string func (_e *ResourceService_Expecter) DeleteResource(ctx interface{}, urn interface{}) *ResourceService_DeleteResource_Call { return &ResourceService_DeleteResource_Call{Call: _e.mock.On("DeleteResource", ctx, urn)} } @@ -186,9 +187,9 @@ type ResourceService_GetLog_Call struct { } // GetLog is a helper method to define mock.On call -// - ctx context.Context -// - urn string -// - filter map[string]string +// - ctx context.Context +// - urn string +// - filter map[string]string func (_e *ResourceService_Expecter) GetLog(ctx interface{}, urn interface{}, filter interface{}) *ResourceService_GetLog_Call { return &ResourceService_GetLog_Call{Call: _e.mock.On("GetLog", ctx, urn, filter)} } @@ -234,8 +235,8 @@ type ResourceService_GetResource_Call struct { } // GetResource is a helper method to define mock.On call -// - ctx context.Context -// - urn string +// - ctx context.Context +// - urn string func (_e *ResourceService_Expecter) GetResource(ctx interface{}, urn interface{}) *ResourceService_GetResource_Call { return &ResourceService_GetResource_Call{Call: _e.mock.On("GetResource", ctx, urn)} } @@ -281,8 +282,8 @@ type ResourceService_GetRevisions_Call struct { } // GetRevisions is a helper method to define mock.On call -// - ctx context.Context -// - selector resource.RevisionsSelector +// - ctx context.Context +// - selector resource.RevisionsSelector func (_e *ResourceService_Expecter) GetRevisions(ctx interface{}, selector interface{}) *ResourceService_GetRevisions_Call { return &ResourceService_GetRevisions_Call{Call: _e.mock.On("GetRevisions", ctx, selector)} } @@ -328,8 +329,8 @@ type ResourceService_ListResources_Call struct { } // ListResources is a helper method to define mock.On call -// - ctx context.Context -// - filter resource.Filter +// - ctx context.Context +// - filter resource.Filter func (_e *ResourceService_Expecter) ListResources(ctx interface{}, filter interface{}) *ResourceService_ListResources_Call { return &ResourceService_ListResources_Call{Call: _e.mock.On("ListResources", ctx, filter)} } @@ -375,9 +376,9 @@ type ResourceService_UpdateResource_Call struct { } // UpdateResource is a helper method to define mock.On call -// - ctx context.Context -// - urn string -// - req resource.UpdateRequest +// - ctx context.Context +// - urn string +// - req resource.UpdateRequest func (_e *ResourceService_Expecter) UpdateResource(ctx interface{}, urn interface{}, req interface{}) *ResourceService_UpdateResource_Call { return &ResourceService_UpdateResource_Call{Call: _e.mock.On("UpdateResource", ctx, urn, req)} } diff --git a/internal/server/v1/modules/mappers.go b/internal/server/v1/modules/mappers.go index cf9fdb96..3ace9b1f 100644 --- a/internal/server/v1/modules/mappers.go +++ b/internal/server/v1/modules/mappers.go @@ -3,12 +3,12 @@ package modules import ( "encoding/json" - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" "github.com/goto/entropy/core/module" "github.com/goto/entropy/pkg/errors" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" ) func moduleToProto(mod module.Module) (*entropyv1beta1.Module, error) { diff --git a/internal/server/v1/modules/server.go b/internal/server/v1/modules/server.go index cd3be997..7ba1612c 100644 --- a/internal/server/v1/modules/server.go +++ b/internal/server/v1/modules/server.go @@ -6,10 +6,9 @@ import ( "context" "encoding/json" - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" - "github.com/goto/entropy/core/module" "github.com/goto/entropy/internal/server/serverutils" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" ) type ModuleService interface { diff --git a/internal/server/v1/modules/server_test.go b/internal/server/v1/modules/server_test.go index 3a263c84..4b4a9d13 100644 --- a/internal/server/v1/modules/server_test.go +++ b/internal/server/v1/modules/server_test.go @@ -5,11 +5,11 @@ import ( "testing" "github.com/google/go-cmp/cmp" - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" "github.com/stretchr/testify/assert" "google.golang.org/protobuf/testing/protocmp" "github.com/goto/entropy/pkg/errors" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" ) func TestAPIServer_ListModules(t *testing.T) { diff --git a/internal/server/v1/resources/mappers.go b/internal/server/v1/resources/mappers.go index eb6e9166..67a4bacb 100644 --- a/internal/server/v1/resources/mappers.go +++ b/internal/server/v1/resources/mappers.go @@ -4,12 +4,12 @@ import ( "encoding/json" "strconv" - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" "github.com/goto/entropy/core/resource" "github.com/goto/entropy/pkg/errors" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" ) const decimalBase = 10 diff --git a/internal/server/v1/resources/server.go b/internal/server/v1/resources/server.go index 02851777..ab908b50 100644 --- a/internal/server/v1/resources/server.go +++ b/internal/server/v1/resources/server.go @@ -5,11 +5,10 @@ package resources import ( "context" - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" - "github.com/goto/entropy/core/module" "github.com/goto/entropy/core/resource" "github.com/goto/entropy/internal/server/serverutils" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" ) type ResourceService interface { diff --git a/internal/server/v1/resources/server_test.go b/internal/server/v1/resources/server_test.go index ea46516a..a0b78dfb 100644 --- a/internal/server/v1/resources/server_test.go +++ b/internal/server/v1/resources/server_test.go @@ -7,7 +7,6 @@ import ( "time" "github.com/google/go-cmp/cmp" - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -20,6 +19,7 @@ import ( "github.com/goto/entropy/core/resource" "github.com/goto/entropy/internal/server/v1/mocks" "github.com/goto/entropy/pkg/errors" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" ) func TestAPIServer_CreateResource(t *testing.T) { diff --git a/internal/store/postgres/postgres.go b/internal/store/postgres/postgres.go index 9b09170e..0110071b 100644 --- a/internal/store/postgres/postgres.go +++ b/internal/store/postgres/postgres.go @@ -20,6 +20,7 @@ const ( // schema represents the storage schema. // Note: Update the constants above if the table name is changed. +// //go:embed schema.sql var schema string diff --git a/pkg/common/common.go b/pkg/common/common.go index 44c66ee7..18ba7be6 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -17,6 +17,7 @@ func New(version *commonv1.Version) *CommonService { } } +// nolint func (c *CommonService) GetVersion(context.Context, *commonv1.GetVersionRequest) (*commonv1.GetVersionResponse, error) { return &commonv1.GetVersionResponse{ Server: c.version, diff --git a/pkg/helm/status.go b/pkg/helm/status.go index d980e451..4db8b81c 100644 --- a/pkg/helm/status.go +++ b/pkg/helm/status.go @@ -1,11 +1,11 @@ package helm -type Status string - const ( StatusUnknown Status = "unknown" StatusSuccess Status = "success" StatusFailed Status = "failed" ) +type Status string + func (x Status) String() string { return string(x) } diff --git a/pkg/kube/client_test.go b/pkg/kube/client_test.go index 6cb4339d..362cf731 100644 --- a/pkg/kube/client_test.go +++ b/pkg/kube/client_test.go @@ -8,8 +8,9 @@ import ( "os" "testing" - "github.com/goto/entropy/pkg/errors" "github.com/stretchr/testify/assert" + + "github.com/goto/entropy/pkg/errors" ) var ( diff --git a/pkg/telemetry/telemetry.go b/pkg/telemetry/telemetry.go index e0ed24e2..cba5244e 100644 --- a/pkg/telemetry/telemetry.go +++ b/pkg/telemetry/telemetry.go @@ -44,6 +44,7 @@ func Init(ctx context.Context, cfg Config, lg *zap.Logger) { if cfg.Debug != "" { go func() { + // nolint if err := http.ListenAndServe(cfg.Debug, mux); err != nil { lg.Error("debug server exited due to error", zap.Error(err)) } diff --git a/pkg/version/version.go b/pkg/version/version.go index 2d34cca3..e1d4342e 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -5,10 +5,10 @@ import ( "runtime" "time" - commonv1 "github.com/goto/entropy/proto/gotocompany/common/v1" - "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/types/known/timestamppb" + + commonv1 "github.com/goto/entropy/proto/gotocompany/common/v1" ) var ( diff --git a/pkg/worker/mocks/job_queue.go b/pkg/worker/mocks/job_queue.go index 7ca410fd..4b9a685f 100644 --- a/pkg/worker/mocks/job_queue.go +++ b/pkg/worker/mocks/job_queue.go @@ -5,8 +5,9 @@ package mocks import ( context "context" - worker "github.com/goto/entropy/pkg/worker" mock "github.com/stretchr/testify/mock" + + worker "github.com/goto/entropy/pkg/worker" ) // JobQueue is an autogenerated mock type for the JobQueue type @@ -42,9 +43,9 @@ type JobQueue_Dequeue_Call struct { } // Dequeue is a helper method to define mock.On call -// - ctx context.Context -// - kinds []string -// - fn worker.DequeueFn +// - ctx context.Context +// - kinds []string +// - fn worker.DequeueFn func (_e *JobQueue_Expecter) Dequeue(ctx interface{}, kinds interface{}, fn interface{}) *JobQueue_Dequeue_Call { return &JobQueue_Dequeue_Call{Call: _e.mock.On("Dequeue", ctx, kinds, fn)} } @@ -88,8 +89,8 @@ type JobQueue_Enqueue_Call struct { } // Enqueue is a helper method to define mock.On call -// - ctx context.Context -// - jobs ...worker.Job +// - ctx context.Context +// - jobs ...worker.Job func (_e *JobQueue_Expecter) Enqueue(ctx interface{}, jobs ...interface{}) *JobQueue_Enqueue_Call { return &JobQueue_Enqueue_Call{Call: _e.mock.On("Enqueue", append([]interface{}{ctx}, jobs...)...)} diff --git a/proto/gotocompany/common/v1/service.pb.go b/proto/gotocompany/common/v1/service.pb.go index 5de1cb00..551e9aac 100644 --- a/proto/gotocompany/common/v1/service.pb.go +++ b/proto/gotocompany/common/v1/service.pb.go @@ -7,13 +7,14 @@ package v1 import ( + reflect "reflect" + sync "sync" + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" ) const ( diff --git a/proto/gotocompany/common/v1/service_grpc.pb.go b/proto/gotocompany/common/v1/service_grpc.pb.go index 13c31ab3..5823bcca 100644 --- a/proto/gotocompany/common/v1/service_grpc.pb.go +++ b/proto/gotocompany/common/v1/service_grpc.pb.go @@ -4,6 +4,7 @@ package v1 import ( context "context" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" diff --git a/proto/gotocompany/entropy/v1beta1/module.pb.go b/proto/gotocompany/entropy/v1beta1/module.pb.go index e4c447b2..665a4a5a 100644 --- a/proto/gotocompany/entropy/v1beta1/module.pb.go +++ b/proto/gotocompany/entropy/v1beta1/module.pb.go @@ -7,13 +7,14 @@ package entropyv1beta1 import ( + reflect "reflect" + sync "sync" + _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" structpb "google.golang.org/protobuf/types/known/structpb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" ) const ( diff --git a/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go b/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go index c469596d..45f627b3 100644 --- a/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go +++ b/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go @@ -4,6 +4,7 @@ package entropyv1beta1 import ( context "context" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" diff --git a/proto/gotocompany/entropy/v1beta1/resource.pb.go b/proto/gotocompany/entropy/v1beta1/resource.pb.go index a7efff50..8d68acb8 100644 --- a/proto/gotocompany/entropy/v1beta1/resource.pb.go +++ b/proto/gotocompany/entropy/v1beta1/resource.pb.go @@ -7,13 +7,14 @@ package entropyv1beta1 import ( + reflect "reflect" + sync "sync" + _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" structpb "google.golang.org/protobuf/types/known/structpb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" ) const ( diff --git a/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go b/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go index 4bb55330..aa4696be 100644 --- a/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go +++ b/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go @@ -4,6 +4,7 @@ package entropyv1beta1 import ( context "context" + grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" From 4d909e6d16d95d8bb17f632b89fc449496e60651 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Wed, 15 Mar 2023 16:28:00 +0530 Subject: [PATCH 05/72] fix: kube config handling (#4) --- Makefile | 20 +-- cli/config.go | 6 +- cli/serve.go | 5 +- core/core.go | 2 +- core/mocks/module_registry.go | 3 +- core/mocks/module_store.go | 3 +- core/mocks/resource_store.go | 3 +- core/sync.go | 5 +- internal/server/middlewares.go | 5 +- internal/server/server.go | 16 ++- internal/server/v1/mocks/resource_service.go | 3 +- internal/server/v1/resources/logwrapper.go | 87 +++++++++++++ internal/server/v1/resources/server.go | 21 ++- internal/server/v1/resources/server_test.go | 16 +-- modules/kubernetes/config_schema.json | 56 -------- modules/kubernetes/config_schema_test.go | 120 ------------------ .../kubernetes/{kubernetes.go => driver.go} | 46 +------ modules/kubernetes/module.go | 23 ++++ modules/kubernetes/output.go | 22 ++++ pkg/errors/errors.go | 28 ++-- pkg/errors/errors_test.go | 34 +---- pkg/kube/config.go | 30 ++++- pkg/telemetry/telemetry.go | 2 +- pkg/worker/mocks/job_queue.go | 3 +- 24 files changed, 247 insertions(+), 312 deletions(-) create mode 100644 internal/server/v1/resources/logwrapper.go delete mode 100644 modules/kubernetes/config_schema.json delete mode 100644 modules/kubernetes/config_schema_test.go rename modules/kubernetes/{kubernetes.go => driver.go} (62%) create mode 100644 modules/kubernetes/module.go create mode 100644 modules/kubernetes/output.go diff --git a/Makefile b/Makefile index 7e32c416..a7c51863 100644 --- a/Makefile +++ b/Makefile @@ -17,15 +17,15 @@ tidy: install: ## install required dependencies @echo "> installing dependencies" - go get -d github.com/vektra/mockery/v2@v2.13.1 - go get -d google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1 - go get google.golang.org/protobuf/proto@v1.28.1 - go get google.golang.org/grpc@v1.49.0 - go get -d google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2.0 - go get -d github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@v2.11.3 - go get -d github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@v2.11.3 - go get -d github.com/bufbuild/buf/cmd/buf@v1.7.0 - go get github.com/envoyproxy/protoc-gen-validate@v0.6.7 + go install github.com/vektra/mockery/v2@v2.14.0 + go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1 + go get -d google.golang.org/protobuf/proto@v1.28.1 + go get -d google.golang.org/grpc@v1.49.0 + go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2.0 + go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@v2.11.3 + go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@v2.11.3 + go install github.com/bufbuild/buf/cmd/buf@v1.7.0 + go install github.com/envoyproxy/protoc-gen-validate@v0.6.7 format: @echo "Running gofumpt..." @@ -38,6 +38,8 @@ lint: clean: tidy @echo "Cleaning up build directories..." @rm -rf ${COVERAGE_DIR} ${BUILD_DIR} + +generate: @echo "Running go-generate..." @go generate ./... diff --git a/cli/config.go b/cli/config.go index 17e32dd0..f44c8802 100644 --- a/cli/config.go +++ b/cli/config.go @@ -29,6 +29,8 @@ type Config struct { type serveConfig struct { Host string `mapstructure:"host" default:""` Port int `mapstructure:"port" default:"8080"` + + HTTPAddr string `mapstructure:"http_addr" default:":8081"` } type workerConf struct { @@ -39,7 +41,9 @@ type workerConf struct { PollInterval time.Duration `mapstructure:"poll_interval" default:"100ms"` } -func (serveCfg serveConfig) addr() string { +func (serveCfg serveConfig) httpAddr() string { return serveCfg.HTTPAddr } + +func (serveCfg serveConfig) grpcAddr() string { return fmt.Sprintf("%s:%d", serveCfg.Host, serveCfg.Port) } diff --git a/cli/serve.go b/cli/serve.go index 1516be3b..855430ef 100644 --- a/cli/serve.go +++ b/cli/serve.go @@ -89,7 +89,10 @@ func runServer(baseCtx context.Context, nrApp *newrelic.Application, zapLog *zap return err } - return entropyserver.Serve(ctx, cfg.Service.addr(), nrApp, zapLog, resourceService, moduleService) + return entropyserver.Serve(ctx, + cfg.Service.httpAddr(), cfg.Service.grpcAddr(), + nrApp, zapLog, resourceService, moduleService, + ) } func setupRegistry(logger *zap.Logger) module.Registry { diff --git a/core/core.go b/core/core.go index 125b94e5..e5b4c0b9 100644 --- a/core/core.go +++ b/core/core.go @@ -4,7 +4,7 @@ package core //go:generate mockery --name=ModuleService -r --case underscore --with-expecter --structname ModuleService --filename=module_service.go --output=./mocks import ( - context "context" + "context" "encoding/json" "time" diff --git a/core/mocks/module_registry.go b/core/mocks/module_registry.go index f5d95bef..5dd6d1fc 100644 --- a/core/mocks/module_registry.go +++ b/core/mocks/module_registry.go @@ -5,9 +5,8 @@ package mocks import ( context "context" - mock "github.com/stretchr/testify/mock" - module "github.com/goto/entropy/core/module" + mock "github.com/stretchr/testify/mock" ) // ModuleRegistry is an autogenerated mock type for the Registry type diff --git a/core/mocks/module_store.go b/core/mocks/module_store.go index 873d6a0e..95fe96c9 100644 --- a/core/mocks/module_store.go +++ b/core/mocks/module_store.go @@ -5,9 +5,8 @@ package mocks import ( context "context" - mock "github.com/stretchr/testify/mock" - module "github.com/goto/entropy/core/module" + mock "github.com/stretchr/testify/mock" ) // ModuleStore is an autogenerated mock type for the Store type diff --git a/core/mocks/resource_store.go b/core/mocks/resource_store.go index 96087d48..79ac941e 100644 --- a/core/mocks/resource_store.go +++ b/core/mocks/resource_store.go @@ -5,9 +5,8 @@ package mocks import ( context "context" - mock "github.com/stretchr/testify/mock" - resource "github.com/goto/entropy/core/resource" + mock "github.com/stretchr/testify/mock" ) // ResourceStore is an autogenerated mock type for the Store type diff --git a/core/sync.go b/core/sync.go index 44abb31f..80a9319d 100644 --- a/core/sync.go +++ b/core/sync.go @@ -61,12 +61,11 @@ func (s *Service) HandleSyncJob(ctx context.Context, job worker.Job) ([]byte, er if err != nil { if errors.Is(err, errors.ErrInternal) { return nil, &worker.RetryableError{ - Cause: errors.Verbose(err), + Cause: err, RetryAfter: retryBackoff, } } - - return nil, errors.Verbose(err) + return nil, err } return json.Marshal(map[string]interface{}{ diff --git a/internal/server/middlewares.go b/internal/server/middlewares.go index f356c5af..b65015e4 100644 --- a/internal/server/middlewares.go +++ b/internal/server/middlewares.go @@ -93,7 +93,10 @@ func requestLogger(lg *zap.Logger) gorillamux.MiddlewareFunc { zap.String("trace_id", span.SpanContext().TraceID.String()), } - wrapped := &wrappedWriter{ResponseWriter: wr} + wrapped := &wrappedWriter{ + Status: http.StatusOK, + ResponseWriter: wr, + } next.ServeHTTP(wrapped, req) fields = append(fields, zap.Duration("response_time", time.Since(t)), diff --git a/internal/server/server.go b/internal/server/server.go index 8e0e382c..039d7dbc 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -39,7 +39,7 @@ const ( // Serve initialises all the gRPC+HTTP API routes, starts listening for requests at addr, and blocks until server exits. // Server exits gracefully when context is cancelled. -func Serve(ctx context.Context, addr string, nrApp *newrelic.Application, logger *zap.Logger, +func Serve(ctx context.Context, httpAddr, grpcAddr string, nrApp *newrelic.Application, logger *zap.Logger, resourceSvc resourcesv1.ResourceService, moduleSvc modulesv1.ModuleService, ) error { grpcOpts := []grpc.ServerOption{ @@ -70,7 +70,10 @@ func Serve(ctx context.Context, addr string, nrApp *newrelic.Application, logger return err } - resourceServiceRPC := resourcesv1.NewAPIServer(resourceSvc) + resourceServiceRPC := &resourcesv1.LogWrapper{ + Logger: logger, + ResourceServiceServer: resourcesv1.NewAPIServer(resourceSvc), + } grpcServer.RegisterService(&entropyv1beta1.ResourceService_ServiceDesc, resourceServiceRPC) if err := entropyv1beta1.RegisterResourceServiceHandlerServer(ctx, rpcHTTPGateway, resourceServiceRPC); err != nil { return err @@ -95,15 +98,18 @@ func Serve(ctx context.Context, addr string, nrApp *newrelic.Application, logger requestLogger(logger), // nolint ) - logger.Info("starting server", zap.String("addr", addr)) + logger.Info("starting http & grpc servers", + zap.String("http_addr", httpAddr), + zap.String("grpc_addr", grpcAddr), + ) return mux.Serve(ctx, - mux.WithHTTPTarget(":8081", &http.Server{ + mux.WithHTTPTarget(httpAddr, &http.Server{ Handler: httpRouter, ReadTimeout: readTimeout, WriteTimeout: writeTimeout, MaxHeaderBytes: maxHeaderBytes, }), - mux.WithGRPCTarget(addr, grpcServer), + mux.WithGRPCTarget(grpcAddr, grpcServer), mux.WithGracePeriod(gracePeriod), ) } diff --git a/internal/server/v1/mocks/resource_service.go b/internal/server/v1/mocks/resource_service.go index d0f09d0f..637f48be 100644 --- a/internal/server/v1/mocks/resource_service.go +++ b/internal/server/v1/mocks/resource_service.go @@ -5,9 +5,8 @@ package mocks import ( context "context" - mock "github.com/stretchr/testify/mock" - module "github.com/goto/entropy/core/module" + mock "github.com/stretchr/testify/mock" resource "github.com/goto/entropy/core/resource" ) diff --git a/internal/server/v1/resources/logwrapper.go b/internal/server/v1/resources/logwrapper.go new file mode 100644 index 00000000..5f64cf3d --- /dev/null +++ b/internal/server/v1/resources/logwrapper.go @@ -0,0 +1,87 @@ +package resources + +import ( + "context" + + "go.uber.org/zap" + + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" +) + +type LogWrapper struct { + entropyv1beta1.ResourceServiceServer + + Logger *zap.Logger +} + +func (lw *LogWrapper) ListResources(ctx context.Context, request *entropyv1beta1.ListResourcesRequest) (*entropyv1beta1.ListResourcesResponse, error) { + resp, err := lw.ResourceServiceServer.ListResources(ctx, request) + if err != nil { + lw.Logger.Error("ListResources() failed", zap.Error(err)) + return nil, err + } + return resp, nil +} + +func (lw *LogWrapper) GetResource(ctx context.Context, request *entropyv1beta1.GetResourceRequest) (*entropyv1beta1.GetResourceResponse, error) { + resp, err := lw.ResourceServiceServer.GetResource(ctx, request) + if err != nil { + lw.Logger.Error("GetResource() failed", zap.Error(err)) + return nil, err + } + return resp, nil +} + +func (lw *LogWrapper) CreateResource(ctx context.Context, request *entropyv1beta1.CreateResourceRequest) (*entropyv1beta1.CreateResourceResponse, error) { + resp, err := lw.ResourceServiceServer.CreateResource(ctx, request) + if err != nil { + lw.Logger.Error("CreateResource() failed", zap.Error(err)) + return nil, err + } + return resp, nil +} + +func (lw *LogWrapper) UpdateResource(ctx context.Context, request *entropyv1beta1.UpdateResourceRequest) (*entropyv1beta1.UpdateResourceResponse, error) { + resp, err := lw.ResourceServiceServer.UpdateResource(ctx, request) + if err != nil { + lw.Logger.Error("UpdateResource() failed", zap.Error(err)) + return nil, err + } + return resp, nil +} + +func (lw *LogWrapper) DeleteResource(ctx context.Context, request *entropyv1beta1.DeleteResourceRequest) (*entropyv1beta1.DeleteResourceResponse, error) { + resp, err := lw.ResourceServiceServer.DeleteResource(ctx, request) + if err != nil { + lw.Logger.Error("DeleteResource() failed", zap.Error(err)) + return nil, err + } + return resp, nil +} + +func (lw *LogWrapper) ApplyAction(ctx context.Context, request *entropyv1beta1.ApplyActionRequest) (*entropyv1beta1.ApplyActionResponse, error) { + resp, err := lw.ResourceServiceServer.ApplyAction(ctx, request) + if err != nil { + lw.Logger.Error("ApplyAction() failed", zap.Error(err)) + return nil, err + } + return resp, nil +} + +func (lw *LogWrapper) GetLog(request *entropyv1beta1.GetLogRequest, server entropyv1beta1.ResourceService_GetLogServer) error { + err := lw.ResourceServiceServer.GetLog(request, server) + if err != nil { + lw.Logger.Error("GetLog() failed", zap.Error(err)) + return err + } + return nil +} + +func (lw *LogWrapper) GetResourceRevisions(ctx context.Context, request *entropyv1beta1.GetResourceRevisionsRequest) (*entropyv1beta1.GetResourceRevisionsResponse, error) { + resp, err := lw.ResourceServiceServer.GetResourceRevisions(ctx, request) + if err != nil { + lw.Logger.Error("GetResourceRevisions() failed", zap.Error(err)) + return nil, err + } + return resp, nil +} diff --git a/internal/server/v1/resources/server.go b/internal/server/v1/resources/server.go index ab908b50..e2b3eaae 100644 --- a/internal/server/v1/resources/server.go +++ b/internal/server/v1/resources/server.go @@ -26,13 +26,12 @@ type ResourceService interface { type APIServer struct { entropyv1beta1.UnimplementedResourceServiceServer - - resourceService ResourceService + resourceSvc ResourceService } func NewAPIServer(resourceService ResourceService) *APIServer { return &APIServer{ - resourceService: resourceService, + resourceSvc: resourceService, } } @@ -42,7 +41,7 @@ func (server APIServer) CreateResource(ctx context.Context, request *entropyv1be return nil, serverutils.ToRPCError(err) } - result, err := server.resourceService.CreateResource(ctx, *res) + result, err := server.resourceSvc.CreateResource(ctx, *res) if err != nil { return nil, serverutils.ToRPCError(err) } @@ -68,7 +67,7 @@ func (server APIServer) UpdateResource(ctx context.Context, request *entropyv1be Labels: request.Labels, } - res, err := server.resourceService.UpdateResource(ctx, request.GetUrn(), updateRequest) + res, err := server.resourceSvc.UpdateResource(ctx, request.GetUrn(), updateRequest) if err != nil { return nil, serverutils.ToRPCError(err) } @@ -84,7 +83,7 @@ func (server APIServer) UpdateResource(ctx context.Context, request *entropyv1be } func (server APIServer) GetResource(ctx context.Context, request *entropyv1beta1.GetResourceRequest) (*entropyv1beta1.GetResourceResponse, error) { - res, err := server.resourceService.GetResource(ctx, request.GetUrn()) + res, err := server.resourceSvc.GetResource(ctx, request.GetUrn()) if err != nil { return nil, serverutils.ToRPCError(err) } @@ -106,7 +105,7 @@ func (server APIServer) ListResources(ctx context.Context, request *entropyv1bet Labels: nil, } - resources, err := server.resourceService.ListResources(ctx, filter) + resources, err := server.resourceSvc.ListResources(ctx, filter) if err != nil { return nil, serverutils.ToRPCError(err) } @@ -126,7 +125,7 @@ func (server APIServer) ListResources(ctx context.Context, request *entropyv1bet } func (server APIServer) DeleteResource(ctx context.Context, request *entropyv1beta1.DeleteResourceRequest) (*entropyv1beta1.DeleteResourceResponse, error) { - err := server.resourceService.DeleteResource(ctx, request.GetUrn()) + err := server.resourceSvc.DeleteResource(ctx, request.GetUrn()) if err != nil { return nil, serverutils.ToRPCError(err) } @@ -146,7 +145,7 @@ func (server APIServer) ApplyAction(ctx context.Context, request *entropyv1beta1 Labels: request.Labels, } - updatedRes, err := server.resourceService.ApplyAction(ctx, request.GetUrn(), action) + updatedRes, err := server.resourceSvc.ApplyAction(ctx, request.GetUrn(), action) if err != nil { return nil, serverutils.ToRPCError(err) } @@ -164,7 +163,7 @@ func (server APIServer) ApplyAction(ctx context.Context, request *entropyv1beta1 func (server APIServer) GetLog(request *entropyv1beta1.GetLogRequest, stream entropyv1beta1.ResourceService_GetLogServer) error { ctx := stream.Context() - logStream, err := server.resourceService.GetLog(ctx, request.GetUrn(), request.GetFilter()) + logStream, err := server.resourceSvc.GetLog(ctx, request.GetUrn(), request.GetFilter()) if err != nil { return serverutils.ToRPCError(err) } @@ -194,7 +193,7 @@ func (server APIServer) GetLog(request *entropyv1beta1.GetLogRequest, stream ent } func (server APIServer) GetResourceRevisions(ctx context.Context, request *entropyv1beta1.GetResourceRevisionsRequest) (*entropyv1beta1.GetResourceRevisionsResponse, error) { - revisions, err := server.resourceService.GetRevisions(ctx, resource.RevisionsSelector{URN: request.GetUrn()}) + revisions, err := server.resourceSvc.GetRevisions(ctx, resource.RevisionsSelector{URN: request.GetUrn()}) if err != nil { return nil, serverutils.ToRPCError(err) } diff --git a/internal/server/v1/resources/server_test.go b/internal/server/v1/resources/server_test.go index a0b78dfb..63d0ae5c 100644 --- a/internal/server/v1/resources/server_test.go +++ b/internal/server/v1/resources/server_test.go @@ -59,7 +59,7 @@ func TestAPIServer_CreateResource(t *testing.T) { }, }, want: nil, - wantErr: status.Error(codes.AlreadyExists, "an entity with conflicting identifier exists"), + wantErr: status.Error(codes.AlreadyExists, "conflict: an entity with conflicting identifier exists"), }, { name: "InvalidRequest", @@ -84,7 +84,7 @@ func TestAPIServer_CreateResource(t *testing.T) { }, }, want: nil, - wantErr: status.Errorf(codes.InvalidArgument, "request is not valid"), + wantErr: status.Errorf(codes.InvalidArgument, "bad_request: request is not valid"), }, { name: "Success", @@ -195,7 +195,7 @@ func TestAPIServer_UpdateResource(t *testing.T) { }, }, want: nil, - wantErr: status.Error(codes.NotFound, "requested entity not found"), + wantErr: status.Error(codes.NotFound, "not_found: requested entity not found"), }, { name: "InvalidRequest", @@ -214,7 +214,7 @@ func TestAPIServer_UpdateResource(t *testing.T) { }, }, want: nil, - wantErr: status.Errorf(codes.InvalidArgument, "request is not valid"), + wantErr: status.Errorf(codes.InvalidArgument, "bad_request: request is not valid"), }, { name: "Success", @@ -317,7 +317,7 @@ func TestAPIServer_GetResource(t *testing.T) { Urn: "p-testdata-gl-testname-log", }, want: nil, - wantErr: status.Error(codes.NotFound, "requested entity not found"), + wantErr: status.Error(codes.NotFound, "not_found: requested entity not found"), }, { name: "Success", @@ -419,7 +419,7 @@ func TestAPIServer_ListResources(t *testing.T) { Kind: "log", }, want: nil, - wantErr: status.Error(codes.Internal, "some unexpected error occurred"), + wantErr: status.Error(codes.Internal, "internal_error: some unexpected error occurred: failed"), }, { name: "Success", @@ -518,7 +518,7 @@ func TestAPIServer_DeleteResource(t *testing.T) { Urn: "p-testdata-gl-testname-log", }, want: nil, - wantErr: status.Error(codes.NotFound, "requested entity not found"), + wantErr: status.Error(codes.NotFound, "not_found: requested entity not found"), }, { name: "Success", @@ -589,7 +589,7 @@ func TestAPIServer_ApplyAction(t *testing.T) { Action: "scale", }, want: nil, - wantErr: status.Error(codes.NotFound, "requested entity not found"), + wantErr: status.Error(codes.NotFound, "not_found: requested entity not found"), }, { name: "Success", diff --git a/modules/kubernetes/config_schema.json b/modules/kubernetes/config_schema.json deleted file mode 100644 index dc315cf2..00000000 --- a/modules/kubernetes/config_schema.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "host": { - "type": "string", - "format": "uri" - }, - "insecure": { - "type": "boolean", - "default": false - }, - "token": { - "type": "string" - }, - "client_key": { - "type": "string" - }, - "client_certificate": { - "type": "string" - }, - "cluster_ca_certificate": { - "type": "string" - } - }, - "required": [ - "host" - ], - "anyOf": [ - { - "required": [ - "token" - ] - }, - { - "required": [ - "client_key", - "client_certificate" - ], - "if": { - "not": { - "properties": { - "insecure": { - "const": true - } - } - } - }, - "then": { - "required": [ - "cluster_ca_certificate" - ] - } - } - ] -} \ No newline at end of file diff --git a/modules/kubernetes/config_schema_test.go b/modules/kubernetes/config_schema_test.go deleted file mode 100644 index 0128a370..00000000 --- a/modules/kubernetes/config_schema_test.go +++ /dev/null @@ -1,120 +0,0 @@ -package kubernetes - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/xeipuuv/gojsonschema" -) - -func TestModule_KubernetesJSONSchema(t *testing.T) { - tests := []struct { - title string - Case string - shouldBeValid bool - }{ - { - title: "TokenAuthPresent_InsecureTrue", - Case: `{ - "host": "http://0.0.0.0:1234", - "insecure": true, - "token": "token" - }`, - shouldBeValid: true, - }, - { - title: "TokenAuthPresent_InsecureFalse", - Case: `{ - "host": "http://0.0.0.0:1234", - "insecure": false, - "token": "foo" - }`, - shouldBeValid: true, - }, - { - title: "TokenAuthPresent_CertIsPresentToo", - Case: `{ - "host": "http://0.0.0.0:1234", - "insecure": false, - "token": "token", - "cluster_certificate": "c_ca_cert" - }`, - shouldBeValid: true, - }, - { - title: "CertAuthPresent_InsecureTrue", - Case: `{ - "host": "http://0.0.0.0:1234", - "insecure": true, - "client_key": "c_key", - "client_certificate": "c_cert" - }`, - shouldBeValid: true, - }, - { - title: "CertAuthPresent_InsecureFalse", - Case: `{ - "host": "http://0.0.0.0:1234", - "insecure": false, - "client_key": "c_key", - "client_certificate": "c_cert" - }`, - shouldBeValid: false, - }, - - { - title: "CertAuthPresent_InsecureFalse_WithCACert", - Case: `{ - "host": "http://0.0.0.0:1234", - "insecure": false, - "client_key": "c_key", - "client_certificate": "c_cert", - "cluster_ca_certificate": "ca_cert" - }`, - shouldBeValid: true, - }, - { - title: "Missing_ClientCert", - Case: `{ - "host": "http://0.0.0.0:1234", - "client_key": "c_key" - }`, - shouldBeValid: false, - }, - { - title: "Missing_ClientKey", - Case: `{ - "host": "http://0.0.0.0:1234", - "insecure": true, - "client_certificate": "c_cert" - }`, - shouldBeValid: false, - }, - { - title: "Missing_CACert", - Case: `{ - "host": "http://0.0.0.0:1234", - "insecure": false, - "client_key": "foo", - "client_certificate": "c_cert" - }`, - shouldBeValid: false, - }, - } - - schema, err := gojsonschema.NewSchema(gojsonschema.NewStringLoader(configSchema)) - require.NoError(t, err) - - for _, tt := range tests { - tt := tt - t.Run(tt.title, func(t *testing.T) { - t.Parallel() - - c := gojsonschema.NewStringLoader(tt.Case) - result, err := schema.Validate(c) - require.NoError(t, err) - assert.Equal(t, tt.shouldBeValid, result.Valid()) - }) - } -} diff --git a/modules/kubernetes/kubernetes.go b/modules/kubernetes/driver.go similarity index 62% rename from modules/kubernetes/kubernetes.go rename to modules/kubernetes/driver.go index bbddc9d6..346d2717 100644 --- a/modules/kubernetes/kubernetes.go +++ b/modules/kubernetes/driver.go @@ -2,10 +2,8 @@ package kubernetes import ( "context" - _ "embed" "encoding/json" - "k8s.io/apimachinery/pkg/version" "k8s.io/client-go/kubernetes" "github.com/goto/entropy/core/module" @@ -14,34 +12,9 @@ import ( "github.com/goto/entropy/pkg/kube" ) -//go:embed config_schema.json -var configSchema string +type kubeDriver struct{} -var Module = module.Descriptor{ - Kind: "kubernetes", - Actions: []module.ActionDesc{ - { - Name: module.CreateAction, - ParamSchema: configSchema, - }, - { - Name: module.UpdateAction, - ParamSchema: configSchema, - }, - }, - DriverFactory: func(conf json.RawMessage) (module.Driver, error) { - return &kubeModule{}, nil - }, -} - -type kubeModule struct{} - -type Output struct { - Configs kube.Config `json:"configs"` - ServerInfo version.Info `json:"server_info"` -} - -func (m *kubeModule) Plan(ctx context.Context, res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { +func (m *kubeDriver) Plan(ctx context.Context, res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { res.Resource.Spec = resource.Spec{ Configs: act.Params, Dependencies: nil, @@ -56,10 +29,11 @@ func (m *kubeModule) Plan(ctx context.Context, res module.ExpandedResource, act Status: resource.StatusCompleted, Output: output, } + return &module.Plan{Resource: res.Resource, Reason: "kubernetes cluster details updated"}, nil } -func (*kubeModule) Sync(_ context.Context, res module.ExpandedResource) (*resource.State, error) { +func (*kubeDriver) Sync(_ context.Context, res module.ExpandedResource) (*resource.State, error) { return &resource.State{ Status: resource.StatusCompleted, Output: res.Resource.State.Output, @@ -67,10 +41,12 @@ func (*kubeModule) Sync(_ context.Context, res module.ExpandedResource) (*resour }, nil } -func (*kubeModule) Output(_ context.Context, res module.ExpandedResource) (json.RawMessage, error) { +func (*kubeDriver) Output(_ context.Context, res module.ExpandedResource) (json.RawMessage, error) { conf := kube.DefaultClientConfig() if err := json.Unmarshal(res.Spec.Configs, &conf); err != nil { return nil, errors.ErrInvalid.WithMsgf("invalid json config value").WithCausef(err.Error()) + } else if err := conf.Sanitise(); err != nil { + return nil, err } clientSet, err := kubernetes.NewForConfig(conf.RESTConfig()) @@ -88,11 +64,3 @@ func (*kubeModule) Output(_ context.Context, res module.ExpandedResource) (json. ServerInfo: *info, }.JSON(), nil } - -func (out Output) JSON() []byte { - b, err := json.Marshal(out) - if err != nil { - panic(err) - } - return b -} diff --git a/modules/kubernetes/module.go b/modules/kubernetes/module.go new file mode 100644 index 00000000..a3dfd741 --- /dev/null +++ b/modules/kubernetes/module.go @@ -0,0 +1,23 @@ +package kubernetes + +import ( + _ "embed" + "encoding/json" + + "github.com/goto/entropy/core/module" +) + +var Module = module.Descriptor{ + Kind: "kubernetes", + Actions: []module.ActionDesc{ + { + Name: module.CreateAction, + }, + { + Name: module.UpdateAction, + }, + }, + DriverFactory: func(conf json.RawMessage) (module.Driver, error) { + return &kubeDriver{}, nil + }, +} diff --git a/modules/kubernetes/output.go b/modules/kubernetes/output.go new file mode 100644 index 00000000..99c42b6b --- /dev/null +++ b/modules/kubernetes/output.go @@ -0,0 +1,22 @@ +package kubernetes + +import ( + "encoding/json" + + "k8s.io/apimachinery/pkg/version" + + "github.com/goto/entropy/pkg/kube" +) + +type Output struct { + Configs kube.Config `json:"configs"` + ServerInfo version.Info `json:"server_info"` +} + +func (out Output) JSON() []byte { + b, err := json.Marshal(out) + if err != nil { + panic(err) + } + return b +} diff --git a/pkg/errors/errors.go b/pkg/errors/errors.go index c29767fa..3eafdb97 100644 --- a/pkg/errors/errors.go +++ b/pkg/errors/errors.go @@ -3,7 +3,6 @@ package errors import ( "errors" "fmt" - "strings" ) // These aliased values are added to avoid conflicting imports of standard `errors` @@ -16,11 +15,11 @@ var ( // Common error categories. Use `ErrX.WithXXX()` to clone and add context. var ( - ErrInvalid = Error{Code: "bad_request", Message: "Request is not valid"} - ErrNotFound = Error{Code: "not_found", Message: "Requested entity not found"} - ErrConflict = Error{Code: "conflict", Message: "An entity with conflicting identifier exists"} - ErrInternal = Error{Code: "internal_error", Message: "Some unexpected error occurred"} - ErrUnsupported = Error{Code: "unsupported", Message: "Requested feature is not supported"} + ErrInvalid = Error{Code: "bad_request", Message: "request is not valid"} + ErrNotFound = Error{Code: "not_found", Message: "requested entity not found"} + ErrConflict = Error{Code: "conflict", Message: "an entity with conflicting identifier exists"} + ErrInternal = Error{Code: "internal_error", Message: "some unexpected error occurred"} + ErrUnsupported = Error{Code: "unsupported", Message: "requested feature is not supported"} ) // Error represents any error returned by the Entropy components along with any @@ -63,10 +62,14 @@ func (err Error) Is(other error) bool { } func (err Error) Error() string { + msg := err.Code if err.Message != "" { - return strings.ToLower(err.Message) + msg += ": " + err.Message } - return fmt.Sprintf("%s: %s", err.Code, err.Cause) + if err.Cause != "" { + msg += ": " + err.Cause + } + return msg } // Errorf returns a formatted error similar to `fmt.Errorf` but uses the @@ -95,12 +98,3 @@ func E(err error) Error { } return ErrInternal.WithCausef(err.Error()) } - -// Verbose returns a verbose error value. -func Verbose(err error) error { - var e Error - if errors.As(err, &e) { - return e.WithMsgf("%s: %s (cause: %s)", e.Code, e.Message, e.Cause) - } - return err -} diff --git a/pkg/errors/errors_test.go b/pkg/errors/errors_test.go index e83981a2..18961334 100644 --- a/pkg/errors/errors_test.go +++ b/pkg/errors/errors_test.go @@ -16,7 +16,7 @@ func Test_E(t *testing.T) { want := errors.Error{ Code: "internal_error", Cause: "some native error", - Message: "Some unexpected error occurred", + Message: "some unexpected error occurred", } err := errors.New("some native error") @@ -41,31 +41,11 @@ func Test_E(t *testing.T) { }) } -func Test_Verbose(t *testing.T) { - t.Parallel() - - t.Run("NonError", func(t *testing.T) { - err := errors.New("some native error") - - got := errors.Verbose(err) - assert.EqualError(t, got, "some native error") - }) - - t.Run("CustomError", func(t *testing.T) { - err := errors.ErrInvalid. - WithMsgf("request is not valid"). - WithCausef("invalid parameter value") - - got := errors.Verbose(err) - assert.EqualError(t, got, "bad_request: request is not valid (cause: invalid parameter value)") - }) -} - func Test_Errorf(t *testing.T) { t.Parallel() e := errors.Errorf("failed: %d", 100) assert.Error(t, e) - assert.EqualError(t, e, "failed: 100") + assert.EqualError(t, e, "internal_error: failed: 100") } func Test_OneOf(t *testing.T) { @@ -92,12 +72,12 @@ func TestError_Error(t *testing.T) { { title: "WithoutCause", err: errors.ErrInvalid, - want: "request is not valid", + want: "bad_request: request is not valid", }, { title: "WithCause", - err: errors.ErrInvalid.WithMsgf("").WithCausef("foo"), - want: "bad_request: foo", + err: errors.ErrInvalid.WithMsgf("").WithCausef("input has bad field"), + want: "bad_request: input has bad field", }, } @@ -163,7 +143,7 @@ func TestError_WithCausef(t *testing.T) { err: errors.ErrInvalid.WithCausef("foo"), want: errors.Error{ Code: "bad_request", - Message: "Request is not valid", + Message: "request is not valid", Cause: "foo", }, }, @@ -172,7 +152,7 @@ func TestError_WithCausef(t *testing.T) { err: errors.ErrConflict.WithCausef("hello %s", "world"), want: errors.Error{ Code: "conflict", - Message: "An entity with conflicting identifier exists", + Message: "an entity with conflicting identifier exists", Cause: "hello world", }, }, diff --git a/pkg/kube/config.go b/pkg/kube/config.go index 8d679c0a..f85d93b8 100644 --- a/pkg/kube/config.go +++ b/pkg/kube/config.go @@ -4,6 +4,8 @@ import ( "time" "k8s.io/client-go/rest" + + "github.com/goto/entropy/pkg/errors" ) type Config struct { @@ -28,11 +30,12 @@ type Config struct { ClusterCACertificate string `json:"cluster_ca_certificate"` } -func (conf Config) RESTConfig() *rest.Config { +func (conf *Config) RESTConfig() *rest.Config { rc := &rest.Config{ Host: conf.Host, Timeout: conf.Timeout, TLSClientConfig: rest.TLSClientConfig{ + Insecure: conf.Insecure, CAData: []byte(conf.ClusterCACertificate), KeyData: []byte(conf.ClientKey), CertData: []byte(conf.ClientCertificate), @@ -46,8 +49,31 @@ func (conf Config) RESTConfig() *rest.Config { return rc } -func (conf Config) StreamingConfig() *rest.Config { +func (conf *Config) StreamingConfig() *rest.Config { rc := conf.RESTConfig() rc.Timeout = 0 return rc } + +func (conf *Config) Sanitise() error { + if conf.Host == "" { + return errors.ErrInvalid.WithMsgf("host must be set") + } + + if conf.Timeout == 0 { + conf.Timeout = 1 * time.Second + } + + if conf.Token == "" { + if conf.ClientKey == "" || conf.ClientCertificate == "" { + return errors.ErrInvalid. + WithMsgf("client_key and client_certificate must be set when token is not set") + } + } + + if !conf.Insecure && len(conf.ClusterCACertificate) == 0 { + return errors.ErrInvalid.WithMsgf("cluster_ca_certificate must be set when insecure=false") + } + + return nil +} diff --git a/pkg/telemetry/telemetry.go b/pkg/telemetry/telemetry.go index cba5244e..9a76827c 100644 --- a/pkg/telemetry/telemetry.go +++ b/pkg/telemetry/telemetry.go @@ -10,7 +10,7 @@ import ( type Config struct { // Debug sets the bind address for pprof & zpages server. - Debug string `mapstructure:"debug_addr"` + Debug string `mapstructure:"debug_addr" default:"localhost:8090"` // OpenCensus trace & metrics configurations. EnableCPU bool `mapstructure:"enable_cpu"` diff --git a/pkg/worker/mocks/job_queue.go b/pkg/worker/mocks/job_queue.go index 4b9a685f..950e4628 100644 --- a/pkg/worker/mocks/job_queue.go +++ b/pkg/worker/mocks/job_queue.go @@ -5,9 +5,8 @@ package mocks import ( context "context" - mock "github.com/stretchr/testify/mock" - worker "github.com/goto/entropy/pkg/worker" + mock "github.com/stretchr/testify/mock" ) // JobQueue is an autogenerated mock type for the JobQueue type From e96dcf910c5d9faa463976c0f672dac5ad5eade1 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Wed, 15 Mar 2023 19:12:49 +0530 Subject: [PATCH 06/72] fix: deployment id name (#5) * fix: deployment id name --- modules/firehose/config.go | 18 ++++++++----- modules/firehose/config_test.go | 47 +++++++++++++++++++++++++++++++++ pkg/worker/worker.go | 8 ++++++ 3 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 modules/firehose/config_test.go diff --git a/modules/firehose/config.go b/modules/firehose/config.go index fc19e8ab..cce928c4 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -5,6 +5,7 @@ import ( _ "embed" "encoding/json" "fmt" + "strings" "time" "github.com/goto/entropy/core/resource" @@ -13,8 +14,8 @@ import ( ) const ( + kubeDeploymentNameLengthLimit = 53 firehoseConsumerIDStartingSequence = "0001" - kubeDeploymentNameLengthLimit = 63 ) var ( @@ -114,20 +115,23 @@ func sanitiseDeploymentID(r resource.Resource, mc moduleConfig) (string, error) if len(releaseName) == 0 { releaseName = generateSafeReleaseName(r.Project, r.Name) } else if len(releaseName) >= kubeDeploymentNameLengthLimit { - return "", errors.ErrInvalid.WithMsgf("deployment_id must be shorter than 63 chars") + return "", errors.ErrInvalid.WithMsgf("deployment_id must be shorter than 53 chars") } return releaseName, nil } func generateSafeReleaseName(project, name string) string { - const suffix = "-firehose" + const prefix = "firehose-" + const randomHashLen = 6 + + releaseName := fmt.Sprintf("%s%s-%s", prefix, project, name) + if len(releaseName) >= kubeDeploymentNameLengthLimit { + releaseName = strings.Trim(releaseName[:kubeDeploymentNameLengthLimit-randomHashLen-1], "-") - releaseName := fmt.Sprintf("%s-%s", project, name) - if len(releaseName)+len(suffix) >= kubeDeploymentNameLengthLimit { val := sha256.Sum256([]byte(releaseName)) hash := fmt.Sprintf("%x", val) - releaseName = fmt.Sprintf("%s-%s", releaseName[:48], hash[:5]) + releaseName = releaseName + "-" + hash[:randomHashLen] } - return releaseName + suffix + return releaseName } diff --git a/modules/firehose/config_test.go b/modules/firehose/config_test.go new file mode 100644 index 00000000..7e7b89c3 --- /dev/null +++ b/modules/firehose/config_test.go @@ -0,0 +1,47 @@ +package firehose + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_generateSafeReleaseName(t *testing.T) { + t.Parallel() + + table := []struct { + project string + name string + want string + }{ + { + project: "g-pilotdata-gl", + name: "g-pilotdata-gl-test-firehose-des-4011-firehose", + want: "firehose-g-pilotdata-gl-g-pilotdata-gl-test-fi-63acaa", + }, + { + project: "abc", + name: "xyz", + want: "firehose-abc-xyz", + }, + { + project: "abcdefghijklmnopqrstuvxyz", + name: "ABCDEFGHIJKLMNOPQRSTUVXYZ", + want: "firehose-abcdefghijklmnopqrstuvxyz-ABCDEFGHIJK-0f1383", + }, + { + project: "abcdefghijklmnopqrstuvxyz", + name: "ABCDEFGHIJ-LMNOPQRSTUVXYZ", + want: "firehose-abcdefghijklmnopqrstuvxyz-ABCDEFGHIJ-c164fe", + }, + } + + for i, tt := range table { + t.Run(fmt.Sprintf("Case#%d", i), func(t *testing.T) { + got := generateSafeReleaseName(tt.project, tt.name) + assert.Equal(t, tt.want, got) + assert.True(t, len(got) <= 53) + }) + } +} diff --git a/pkg/worker/worker.go b/pkg/worker/worker.go index 70bcf8d1..6a2d1d7f 100644 --- a/pkg/worker/worker.go +++ b/pkg/worker/worker.go @@ -127,6 +127,7 @@ func (w *Worker) handleJob(ctx context.Context, job Job) (*Job, error) { w.logger.Info("got a pending job", zap.String("job_id", job.ID), zap.String("job_kind", job.Kind), + zap.String("status", job.Status), ) fn, exists := w.handlers[job.Kind] @@ -140,6 +141,13 @@ func (w *Worker) handleJob(ctx context.Context, job Job) (*Job, error) { } job.Attempt(ctx, time.Now(), fn) + + w.logger.Info("job attempted", + zap.String("job_id", job.ID), + zap.String("job_kind", job.Kind), + zap.String("status", job.Status), + zap.String("last_error", job.LastError), + ) return &job, nil } From 202e4ad86ee3cae966f33a577582deab2352eb08 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Thu, 16 Mar 2023 16:14:25 +0530 Subject: [PATCH 07/72] Fix/generic (#6) * chore: add better error description * refactor: merge firehose module files --- core/resource/resource.go | 8 +- internal/server/v1/resources/mappers.go | 35 +- internal/server/v1/resources/server.go | 2 +- modules/firehose/config.go | 21 +- modules/firehose/driver.go | 372 ++++++++++++++++++ .../firehose/{plan_test.go => driver_test.go} | 2 +- modules/firehose/log.go | 60 --- modules/firehose/module.go | 64 +-- modules/firehose/output.go | 16 +- modules/firehose/plan.go | 160 -------- modules/firehose/sync.go | 145 ------- {modules/firehose => pkg}/kafka/consumer.go | 0 12 files changed, 432 insertions(+), 453 deletions(-) create mode 100644 modules/firehose/driver.go rename modules/firehose/{plan_test.go => driver_test.go} (99%) delete mode 100644 modules/firehose/log.go delete mode 100644 modules/firehose/plan.go delete mode 100644 modules/firehose/sync.go rename {modules/firehose => pkg}/kafka/consumer.go (100%) diff --git a/core/resource/resource.go b/core/resource/resource.go index e080623b..64edcf40 100644 --- a/core/resource/resource.go +++ b/core/resource/resource.go @@ -95,7 +95,7 @@ func (res *Resource) Validate(isCreate bool) error { } if isCreate { - res.URN = generateURN(*res) + res.URN = GenerateURN(res.Kind, res.Project, res.Name) } return nil } @@ -126,7 +126,9 @@ func (f Filter) isMatch(r Resource) bool { return true } -func generateURN(res Resource) string { - parts := []string{"orn", "entropy", res.Kind, res.Project, res.Name} +// GenerateURN generates an Entropy URN address for the given combination. +// Note: Changing this will invalidate all existing resource identifiers. +func GenerateURN(kind, project, name string) string { + parts := []string{"orn", "entropy", kind, project, name} return strings.Join(parts, urnSeparator) } diff --git a/internal/server/v1/resources/mappers.go b/internal/server/v1/resources/mappers.go index 67a4bacb..088d2f15 100644 --- a/internal/server/v1/resources/mappers.go +++ b/internal/server/v1/resources/mappers.go @@ -17,12 +17,12 @@ const decimalBase = 10 func resourceToProto(res resource.Resource) (*entropyv1beta1.Resource, error) { protoState, err := resourceStateToProto(res.State) if err != nil { - return nil, err + return nil, errors.ErrInternal.WithMsgf("state to protobuf failed").WithCausef(err.Error()) } spec, err := resourceSpecToProto(res.Spec) if err != nil { - return nil, err + return nil, errors.ErrInternal.WithMsgf("spec to protobuf failed").WithCausef(err.Error()) } return &entropyv1beta1.Resource{ @@ -43,7 +43,7 @@ func resourceStateToProto(state resource.State) (*entropyv1beta1.ResourceState, if len(state.Output) > 0 { outputVal = &structpb.Value{} if err := json.Unmarshal(state.Output, outputVal); err != nil { - return nil, err + return nil, errors.ErrInternal.WithMsgf("failed to unmarshal output").WithCausef(err.Error()) } } @@ -62,7 +62,7 @@ func resourceStateToProto(state resource.State) (*entropyv1beta1.ResourceState, func resourceSpecToProto(spec resource.Spec) (*entropyv1beta1.ResourceSpec, error) { conf := structpb.Value{} if err := json.Unmarshal(spec.Configs, &conf); err != nil { - return nil, err + return nil, errors.ErrInternal.WithMsgf("json.Unmarshal failed for spec.configs").WithCausef(err.Error()) } var deps []*entropyv1beta1.ResourceDependency @@ -79,18 +79,13 @@ func resourceSpecToProto(spec resource.Spec) (*entropyv1beta1.ResourceSpec, erro }, nil } -func resourceFromProto(res *entropyv1beta1.Resource) (*resource.Resource, error) { +func resourceFromProto(res *entropyv1beta1.Resource, includeState bool) (*resource.Resource, error) { spec, err := resourceSpecFromProto(res.Spec) if err != nil { return nil, err } - jsonData, err := res.State.GetOutput().GetStructValue().MarshalJSON() - if err != nil { - return nil, err - } - - return &resource.Resource{ + mappedRes := &resource.Resource{ URN: res.GetUrn(), Kind: res.GetKind(), Name: res.GetName(), @@ -99,12 +94,22 @@ func resourceFromProto(res *entropyv1beta1.Resource) (*resource.Resource, error) CreatedAt: res.GetCreatedAt().AsTime(), UpdatedAt: res.GetUpdatedAt().AsTime(), Spec: *spec, - State: resource.State{ + } + + if includeState { + jsonData, err := res.State.GetOutput().GetStructValue().MarshalJSON() + if err != nil { + return nil, errors.ErrInvalid.WithMsgf("state.output is not valid json").WithCausef(err.Error()) + } + + mappedRes.State = resource.State{ Status: res.State.GetStatus().String(), Output: jsonData, ModuleData: res.State.GetModuleData(), - }, - }, nil + } + } + + return mappedRes, nil } func resourceSpecFromProto(spec *entropyv1beta1.ResourceSpec) (*resource.Spec, error) { @@ -120,7 +125,7 @@ func resourceSpecFromProto(spec *entropyv1beta1.ResourceSpec) (*resource.Spec, e confJSON, err := spec.GetConfigs().MarshalJSON() if err != nil { - return nil, err + return nil, errors.ErrInvalid.WithMsgf("configs is not valid JSON").WithCausef(err.Error()) } return &resource.Spec{ diff --git a/internal/server/v1/resources/server.go b/internal/server/v1/resources/server.go index e2b3eaae..5f7d93e5 100644 --- a/internal/server/v1/resources/server.go +++ b/internal/server/v1/resources/server.go @@ -36,7 +36,7 @@ func NewAPIServer(resourceService ResourceService) *APIServer { } func (server APIServer) CreateResource(ctx context.Context, request *entropyv1beta1.CreateResourceRequest) (*entropyv1beta1.CreateResourceResponse, error) { - res, err := resourceFromProto(request.Resource) + res, err := resourceFromProto(request.Resource, false) if err != nil { return nil, serverutils.ToRPCError(err) } diff --git a/modules/firehose/config.go b/modules/firehose/config.go index cce928c4..2f1f4935 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -18,18 +18,7 @@ const ( firehoseConsumerIDStartingSequence = "0001" ) -var ( - //go:embed schema/config.json - completeConfigSchema string - - //go:embed schema/scale.json - scaleActionSchema string - - //go:embed schema/reset.json - resetActionSchema string -) - -type moduleConfig struct { +type Config struct { State string `json:"state"` StopTime *time.Time `json:"stop_time"` Telegraf map[string]interface{} `json:"telegraf"` @@ -43,7 +32,7 @@ type moduleConfig struct { } `json:"firehose"` } -func (mc *moduleConfig) validateAndSanitize(r resource.Resource) error { +func (mc *Config) validateAndSanitize(r resource.Resource) error { if mc.StopTime != nil && mc.StopTime.Before(time.Now()) { return errors.ErrInvalid. WithMsgf("value for stop_time must be greater than current time") @@ -57,7 +46,7 @@ func (mc *moduleConfig) validateAndSanitize(r resource.Resource) error { return nil } -func (mc *moduleConfig) GetHelmReleaseConfig(r resource.Resource) (*helm.ReleaseConfig, error) { +func (mc *Config) GetHelmReleaseConfig(r resource.Resource) (*helm.ReleaseConfig, error) { var output Output err := json.Unmarshal(r.State.Output, &output) if err != nil { @@ -102,7 +91,7 @@ func (mc *moduleConfig) GetHelmReleaseConfig(r resource.Resource) (*helm.Release return rc, nil } -func (mc *moduleConfig) JSON() []byte { +func (mc *Config) JSON() []byte { b, err := json.Marshal(mc) if err != nil { panic(err) @@ -110,7 +99,7 @@ func (mc *moduleConfig) JSON() []byte { return b } -func sanitiseDeploymentID(r resource.Resource, mc moduleConfig) (string, error) { +func sanitiseDeploymentID(r resource.Resource, mc Config) (string, error) { releaseName := mc.Firehose.DeploymentID if len(releaseName) == 0 { releaseName = generateSafeReleaseName(r.Project, r.Name) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go new file mode 100644 index 00000000..07a4c6f5 --- /dev/null +++ b/modules/firehose/driver.go @@ -0,0 +1,372 @@ +package firehose + +import ( + "context" + "encoding/json" + "time" + + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/modules/kubernetes" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/helm" + "github.com/goto/entropy/pkg/kafka" + "github.com/goto/entropy/pkg/kube" + "github.com/goto/entropy/pkg/worker" +) + +const ( + networkErrorRetryDuration = 5 * time.Second + kubeAPIRetryBackoffDuration = 30 * time.Second +) + +const ( + releaseCreate = "release_create" + releaseUpdate = "release_update" + consumerReset = "consumer_reset" +) + +const ( + stateRunning = "RUNNING" + stateStopped = "STOPPED" +) + +const ( + ResetToDateTime = "DATETIME" + ResetToEarliest = "EARLIEST" + ResetToLatest = "LATEST" +) + +var ( + ErrNetwork = worker.RetryableError{RetryAfter: networkErrorRetryDuration} + ErrKubeAPI = worker.RetryableError{RetryAfter: kubeAPIRetryBackoffDuration} +) + +type driverConfig struct { + ChartRepository string `json:"chart_repository,omitempty"` + ChartName string `json:"chart_name,omitempty"` + ChartVersion string `json:"chart_version,omitempty"` + ImageRepository string `json:"image_repository,omitempty"` + ImageName string `json:"image_name,omitempty"` + ImageTag string `json:"image_tag,omitempty"` + Namespace string `json:"namespace,omitempty"` + ImagePullPolicy string `json:"image_pull_policy,omitempty"` +} + +type firehoseDriver struct { + Config driverConfig `json:"config"` +} + +func (m *firehoseDriver) Plan(_ context.Context, res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { + switch act.Name { + case module.CreateAction: + return m.planCreate(res, act) + + case ResetAction: + return m.planReset(res, act) + + default: + return m.planChange(res, act) + } +} + +func (m *firehoseDriver) Sync(ctx context.Context, res module.ExpandedResource) (*resource.State, error) { + r := res.Resource + + var data moduleData + if err := json.Unmarshal(r.State.ModuleData, &data); err != nil { + return nil, errors.ErrInternal.WithMsgf("invalid module data").WithCausef(err.Error()) + } + + var conf Config + if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json").WithCausef(err.Error()) + } + + var kubeOut kubernetes.Output + if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { + return nil, errors.ErrInternal.WithMsgf("invalid kube state").WithCausef(err.Error()) + } + + if len(data.PendingSteps) > 0 { + pendingStep := data.PendingSteps[0] + data.PendingSteps = data.PendingSteps[1:] + + switch pendingStep { + case releaseCreate, releaseUpdate: + if data.StateOverride != "" { + conf.State = data.StateOverride + } + if err := m.releaseSync(pendingStep == releaseCreate, conf, r, kubeOut); err != nil { + return nil, err + } + + case consumerReset: + if err := m.consumerReset(ctx, conf, r, data.ResetTo, kubeOut); err != nil { + return nil, err + } + data.StateOverride = "" + + default: + if err := m.releaseSync(pendingStep == releaseCreate, conf, r, kubeOut); err != nil { + return nil, err + } + } + } + + output, err := m.Output(ctx, res) + if err != nil { + return nil, err + } + + finalStatus := resource.StatusCompleted + if len(data.PendingSteps) > 0 { + finalStatus = resource.StatusPending + } + + return &resource.State{ + Status: finalStatus, + Output: output, + ModuleData: data.JSON(), + }, nil +} + +func (*firehoseDriver) Log(ctx context.Context, res module.ExpandedResource, filter map[string]string) (<-chan module.LogChunk, error) { + r := res.Resource + + var conf Config + if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + + var kubeOut kubernetes.Output + if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { + return nil, err + } + + if filter == nil { + filter = make(map[string]string) + } + + hc, err := conf.GetHelmReleaseConfig(r) + if err != nil { + return nil, err + } + + filter["app"] = hc.Name + + kubeCl := kube.NewClient(kubeOut.Configs) + logs, err := kubeCl.StreamLogs(ctx, hc.Namespace, filter) + if err != nil { + return nil, err + } + + mappedLogs := make(chan module.LogChunk) + go func() { + defer close(mappedLogs) + for { + select { + case log, ok := <-logs: + if !ok { + return + } + mappedLogs <- module.LogChunk{Data: log.Data, Labels: log.Labels} + case <-ctx.Done(): + return + } + } + }() + + return mappedLogs, err +} + +func (m *firehoseDriver) planCreate(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { + var plan module.Plan + r := res.Resource + + var reqConf Config + if err := json.Unmarshal(act.Params, &reqConf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + if err := reqConf.validateAndSanitize(res.Resource); err != nil { + return nil, err + } + + output := Output{ + Defaults: m.Config, + }.JSON() + + r.Spec.Configs = reqConf.JSON() + r.State = resource.State{ + Status: resource.StatusPending, + ModuleData: moduleData{ + PendingSteps: []string{releaseCreate}, + }.JSON(), + Output: output, + } + + plan.Resource = r + if reqConf.StopTime != nil { + plan.ScheduleRunAt = *reqConf.StopTime + } + plan.Reason = "firehose created" + return &plan, nil +} + +func (m *firehoseDriver) planChange(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { + var plan module.Plan + r := res.Resource + + var conf Config + if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + + switch act.Name { + case module.UpdateAction: + var reqConf Config + if err := json.Unmarshal(act.Params, &reqConf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + if err := reqConf.validateAndSanitize(r); err != nil { + return nil, err + } + conf = reqConf + + if conf.StopTime != nil { + plan.ScheduleRunAt = *conf.StopTime + } + plan.Reason = "firehose config updated" + + case ScaleAction: + var scaleParams struct { + Replicas int `json:"replicas"` + } + if err := json.Unmarshal(act.Params, &scaleParams); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + conf.Firehose.Replicas = scaleParams.Replicas + plan.Reason = "firehose scaled" + + case StartAction: + conf.State = stateRunning + plan.Reason = "firehose started" + + case StopAction: + conf.State = stateStopped + plan.Reason = "firehose stopped" + + case UpgradeAction: + var output Output + err := json.Unmarshal(res.State.Output, &output) + if err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid output json: %v", err) + } + + output.Defaults = m.Config + res.State.Output = output.JSON() + + plan.Reason = "firehose upgraded" + } + + r.Spec.Configs = conf.JSON() + r.State = resource.State{ + Status: resource.StatusPending, + Output: res.State.Output, + ModuleData: moduleData{ + PendingSteps: []string{releaseUpdate}, + }.JSON(), + } + plan.Resource = r + return &plan, nil +} + +func (*firehoseDriver) planReset(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { + r := res.Resource + + var conf Config + if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + + var resetParams struct { + To string `json:"to"` + Datetime string `json:"datetime"` + } + if err := json.Unmarshal(act.Params, &resetParams); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid action params json: %v", err) + } + + resetValue := resetParams.To + if resetParams.To == "DATETIME" { + resetValue = resetParams.Datetime + } + + r.Spec.Configs = conf.JSON() + r.State = resource.State{ + Status: resource.StatusPending, + Output: res.State.Output, + ModuleData: moduleData{ + ResetTo: resetValue, + PendingSteps: []string{releaseUpdate, consumerReset, releaseUpdate}, + StateOverride: stateStopped, + }.JSON(), + } + + return &module.Plan{Resource: r, Reason: "firehose consumer reset"}, nil +} + +func (*firehoseDriver) releaseSync(isCreate bool, conf Config, r resource.Resource, kube kubernetes.Output) error { + helmCl := helm.NewClient(&helm.Config{Kubernetes: kube.Configs}) + + if conf.State == stateStopped || (conf.StopTime != nil && conf.StopTime.Before(time.Now())) { + conf.Firehose.Replicas = 0 + } + + hc, err := conf.GetHelmReleaseConfig(r) + if err != nil { + return err + } + + var helmErr error + if isCreate { + _, helmErr = helmCl.Create(hc) + } else { + _, helmErr = helmCl.Update(hc) + } + + return helmErr +} + +func (*firehoseDriver) consumerReset(ctx context.Context, conf Config, r resource.Resource, resetTo string, out kubernetes.Output) error { + releaseConfig, err := conf.GetHelmReleaseConfig(r) + if err != nil { + return err + } + + cgm := kafka.NewConsumerGroupManager(conf.Firehose.KafkaBrokerAddress, kube.NewClient(out.Configs), releaseConfig.Namespace) + + switch resetTo { + case ResetToEarliest: + err = cgm.ResetOffsetToEarliest(ctx, conf.Firehose.KafkaConsumerID) + case ResetToLatest: + err = cgm.ResetOffsetToLatest(ctx, conf.Firehose.KafkaConsumerID) + default: + err = cgm.ResetOffsetToDatetime(ctx, conf.Firehose.KafkaConsumerID, resetTo) + } + + return handleErr(err) +} + +func handleErr(err error) error { + switch { + case errors.Is(err, kube.ErrJobCreationFailed): + return ErrNetwork.WithCause(err) + case errors.Is(err, kube.ErrJobNotFound): + return ErrKubeAPI.WithCause(err) + case errors.Is(err, kube.ErrJobExecutionFailed): + return ErrKubeAPI.WithCause(err) + default: + return err + } +} diff --git a/modules/firehose/plan_test.go b/modules/firehose/driver_test.go similarity index 99% rename from modules/firehose/plan_test.go rename to modules/firehose/driver_test.go index 0d9e8023..e71c5e49 100644 --- a/modules/firehose/plan_test.go +++ b/modules/firehose/driver_test.go @@ -157,7 +157,7 @@ func TestFirehoseModule_Plan(t *testing.T) { tt := tt t.Run(tt.title, func(t *testing.T) { t.Parallel() - m := firehoseModule{} + m := firehoseDriver{} got, err := m.Plan(context.Background(), tt.res, tt.act) if tt.wantErr != nil || err != nil { diff --git a/modules/firehose/log.go b/modules/firehose/log.go deleted file mode 100644 index a0c01aab..00000000 --- a/modules/firehose/log.go +++ /dev/null @@ -1,60 +0,0 @@ -package firehose - -import ( - "context" - "encoding/json" - - "github.com/goto/entropy/core/module" - "github.com/goto/entropy/modules/kubernetes" - "github.com/goto/entropy/pkg/errors" - "github.com/goto/entropy/pkg/kube" -) - -func (*firehoseModule) Log(ctx context.Context, res module.ExpandedResource, filter map[string]string) (<-chan module.LogChunk, error) { - r := res.Resource - - var conf moduleConfig - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - - var kubeOut kubernetes.Output - if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { - return nil, err - } - - if filter == nil { - filter = make(map[string]string) - } - - hc, err := conf.GetHelmReleaseConfig(r) - if err != nil { - return nil, err - } - - filter["app"] = hc.Name - - kubeCl := kube.NewClient(kubeOut.Configs) - logs, err := kubeCl.StreamLogs(ctx, hc.Namespace, filter) - if err != nil { - return nil, err - } - - mappedLogs := make(chan module.LogChunk) - go func() { - defer close(mappedLogs) - for { - select { - case log, ok := <-logs: - if !ok { - return - } - mappedLogs <- module.LogChunk{Data: log.Data, Labels: log.Labels} - case <-ctx.Done(): - return - } - } - }() - - return mappedLogs, err -} diff --git a/modules/firehose/module.go b/modules/firehose/module.go index 6de46e2f..de313652 100644 --- a/modules/firehose/module.go +++ b/modules/firehose/module.go @@ -16,24 +16,18 @@ const ( UpgradeAction = "upgrade" ) -const ( - releaseCreate = "release_create" - releaseUpdate = "release_update" - consumerReset = "consumer_reset" -) +const keyKubeDependency = "kube_cluster" -const ( - stateRunning = "RUNNING" - stateStopped = "STOPPED" -) +var ( + //go:embed schema/config.json + completeConfigSchema string -const ( - ResetToDateTime = "DATETIME" - ResetToEarliest = "EARLIEST" - ResetToLatest = "LATEST" -) + //go:embed schema/scale.json + scaleActionSchema string -const keyKubeDependency = "kube_cluster" + //go:embed schema/reset.json + resetActionSchema string +) var Module = module.Descriptor{ Kind: "firehose", @@ -75,33 +69,7 @@ var Module = module.Descriptor{ }, }, DriverFactory: func(conf json.RawMessage) (module.Driver, error) { - fm := firehoseModuleWithDefaultConfigs() - err := json.Unmarshal(conf, fm) - if err != nil { - return nil, err - } - return fm, nil - }, -} - -type firehoseModule struct { - Config config `json:"config"` -} - -type config struct { - ChartRepository string `json:"chart_repository,omitempty"` - ChartName string `json:"chart_name,omitempty"` - ChartVersion string `json:"chart_version,omitempty"` - ImageRepository string `json:"image_repository,omitempty"` - ImageName string `json:"image_name,omitempty"` - ImageTag string `json:"image_tag,omitempty"` - Namespace string `json:"namespace,omitempty"` - ImagePullPolicy string `json:"image_pull_policy,omitempty"` -} - -func firehoseModuleWithDefaultConfigs() *firehoseModule { - return &firehoseModule{ - config{ + driverCfg := driverConfig{ ChartRepository: "https://odpf.github.io/charts/", ChartName: "firehose", ChartVersion: "0.1.3", @@ -110,6 +78,14 @@ func firehoseModuleWithDefaultConfigs() *firehoseModule { ImageTag: "latest", Namespace: "firehose", ImagePullPolicy: "IfNotPresent", - }, - } + } + + if err := json.Unmarshal(conf, &driverCfg); err != nil { + return nil, err + } + + return &firehoseDriver{ + Config: driverCfg, + }, nil + }, } diff --git a/modules/firehose/output.go b/modules/firehose/output.go index 8e82d8df..b5a9844a 100644 --- a/modules/firehose/output.go +++ b/modules/firehose/output.go @@ -11,10 +11,10 @@ import ( ) type Output struct { - Namespace string `json:"namespace,omitempty"` - ReleaseName string `json:"release_name,omitempty"` - Pods []kube.Pod `json:"pods,omitempty"` - Defaults config `json:"defaults,omitempty"` + Namespace string `json:"namespace,omitempty"` + ReleaseName string `json:"release_name,omitempty"` + Pods []kube.Pod `json:"pods,omitempty"` + Defaults driverConfig `json:"defaults,omitempty"` } func (out Output) JSON() []byte { @@ -25,8 +25,8 @@ func (out Output) JSON() []byte { return b } -func (m *firehoseModule) Output(ctx context.Context, res module.ExpandedResource) (json.RawMessage, error) { - var conf moduleConfig +func (m *firehoseDriver) Output(ctx context.Context, res module.ExpandedResource) (json.RawMessage, error) { + var conf Config if err := json.Unmarshal(res.Resource.Spec.Configs, &conf); err != nil { return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) } @@ -54,10 +54,10 @@ func (m *firehoseModule) Output(ctx context.Context, res module.ExpandedResource }.JSON(), nil } -func (*firehoseModule) podDetails(ctx context.Context, res module.ExpandedResource) ([]kube.Pod, error) { +func (*firehoseDriver) podDetails(ctx context.Context, res module.ExpandedResource) ([]kube.Pod, error) { r := res.Resource - var conf moduleConfig + var conf Config if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) } diff --git a/modules/firehose/plan.go b/modules/firehose/plan.go deleted file mode 100644 index 7328945e..00000000 --- a/modules/firehose/plan.go +++ /dev/null @@ -1,160 +0,0 @@ -package firehose - -import ( - "context" - "encoding/json" - - "github.com/goto/entropy/core/module" - "github.com/goto/entropy/core/resource" - "github.com/goto/entropy/pkg/errors" -) - -func (m *firehoseModule) Plan(_ context.Context, res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { - switch act.Name { - case module.CreateAction: - return m.planCreate(res, act) - case ResetAction: - return m.planReset(res, act) - default: - return m.planChange(res, act) - } -} - -func (m *firehoseModule) planCreate(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { - var plan module.Plan - r := res.Resource - - var reqConf moduleConfig - if err := json.Unmarshal(act.Params, &reqConf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - if err := reqConf.validateAndSanitize(res.Resource); err != nil { - return nil, err - } - - output := Output{ - Defaults: m.Config, - }.JSON() - - r.Spec.Configs = reqConf.JSON() - r.State = resource.State{ - Status: resource.StatusPending, - ModuleData: moduleData{ - PendingSteps: []string{releaseCreate}, - }.JSON(), - Output: output, - } - - plan.Resource = r - if reqConf.StopTime != nil { - plan.ScheduleRunAt = *reqConf.StopTime - } - plan.Reason = "firehose created" - return &plan, nil -} - -func (m *firehoseModule) planChange(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { - var plan module.Plan - r := res.Resource - - var conf moduleConfig - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - - switch act.Name { - case module.UpdateAction: - var reqConf moduleConfig - if err := json.Unmarshal(act.Params, &reqConf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - if err := reqConf.validateAndSanitize(r); err != nil { - return nil, err - } - conf = reqConf - - if conf.StopTime != nil { - plan.ScheduleRunAt = *conf.StopTime - } - plan.Reason = "firehose config updated" - - case ScaleAction: - var scaleParams struct { - Replicas int `json:"replicas"` - } - if err := json.Unmarshal(act.Params, &scaleParams); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - conf.Firehose.Replicas = scaleParams.Replicas - plan.Reason = "firehose scaled" - - case StartAction: - conf.State = stateRunning - plan.Reason = "firehose started" - - case StopAction: - conf.State = stateStopped - plan.Reason = "firehose stopped" - - case UpgradeAction: - var output Output - err := json.Unmarshal(res.State.Output, &output) - if err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid output json: %v", err) - } - - output.Defaults = m.Config - res.State.Output = output.JSON() - - plan.Reason = "firehose upgraded" - } - - r.Spec.Configs = conf.JSON() - r.State = resource.State{ - Status: resource.StatusPending, - Output: res.State.Output, - ModuleData: moduleData{ - PendingSteps: []string{releaseUpdate}, - }.JSON(), - } - plan.Resource = r - return &plan, nil -} - -func (*firehoseModule) planReset(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { - r := res.Resource - - var conf moduleConfig - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - - var resetParams struct { - To string `json:"to"` - Datetime string `json:"datetime"` - } - if err := json.Unmarshal(act.Params, &resetParams); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid action params json: %v", err) - } - - var resetTo string - switch resetParams.To { - case "DATETIME": - resetTo = resetParams.Datetime - default: - resetTo = resetParams.To - } - - r.Spec.Configs = conf.JSON() - r.State = resource.State{ - Status: resource.StatusPending, - Output: res.State.Output, - ModuleData: moduleData{ - PendingSteps: []string{releaseUpdate, consumerReset, releaseUpdate}, - ResetTo: resetTo, - StateOverride: stateStopped, - }.JSON(), - } - - return &module.Plan{Resource: r, Reason: "firehose consumer reset"}, nil -} diff --git a/modules/firehose/sync.go b/modules/firehose/sync.go deleted file mode 100644 index 1b58347e..00000000 --- a/modules/firehose/sync.go +++ /dev/null @@ -1,145 +0,0 @@ -package firehose - -import ( - "context" - "encoding/json" - "time" - - "github.com/goto/entropy/core/module" - "github.com/goto/entropy/core/resource" - "github.com/goto/entropy/modules/firehose/kafka" - "github.com/goto/entropy/modules/kubernetes" - "github.com/goto/entropy/pkg/errors" - "github.com/goto/entropy/pkg/helm" - "github.com/goto/entropy/pkg/kube" - "github.com/goto/entropy/pkg/worker" -) - -const ( - networkErrorRetryDuration = 5 * time.Second - kubeAPIRetryBackoffDuration = 30 * time.Second -) - -var ( - ErrNetwork = worker.RetryableError{RetryAfter: networkErrorRetryDuration} - ErrKubeAPI = worker.RetryableError{RetryAfter: kubeAPIRetryBackoffDuration} -) - -func (m *firehoseModule) Sync(ctx context.Context, res module.ExpandedResource) (*resource.State, error) { - r := res.Resource - - var data moduleData - var pendingStep string - if err := json.Unmarshal(r.State.ModuleData, &data); err != nil { - return nil, err - } - - if len(data.PendingSteps) != 0 { - pendingStep = data.PendingSteps[0] - data.PendingSteps = data.PendingSteps[1:] - } - - var conf moduleConfig - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - - var kubeOut kubernetes.Output - if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { - return nil, err - } - - switch pendingStep { - case releaseCreate, releaseUpdate: - if data.StateOverride != "" { - conf.State = data.StateOverride - } - if err := m.releaseSync(pendingStep == releaseCreate, conf, r, kubeOut); err != nil { - return nil, err - } - case consumerReset: - if err := m.consumerReset(ctx, - conf, - r, - data.ResetTo, - kubeOut); err != nil { - return nil, err - } - data.StateOverride = "" - default: - if err := m.releaseSync(pendingStep == releaseCreate, conf, r, kubeOut); err != nil { - return nil, err - } - } - - finalStatus := resource.StatusCompleted - if len(data.PendingSteps) > 0 { - finalStatus = resource.StatusPending - } - - output, err := m.Output(ctx, res) - if err != nil { - return nil, err - } - - return &resource.State{ - Status: finalStatus, - Output: output, - ModuleData: data.JSON(), - }, nil -} - -func (*firehoseModule) releaseSync(isCreate bool, conf moduleConfig, r resource.Resource, kube kubernetes.Output) error { - helmCl := helm.NewClient(&helm.Config{Kubernetes: kube.Configs}) - - if conf.State == stateStopped || (conf.StopTime != nil && conf.StopTime.Before(time.Now())) { - conf.Firehose.Replicas = 0 - } - - hc, err := conf.GetHelmReleaseConfig(r) - if err != nil { - return err - } - - var helmErr error - if isCreate { - _, helmErr = helmCl.Create(hc) - } else { - _, helmErr = helmCl.Update(hc) - } - - return helmErr -} - -func (*firehoseModule) consumerReset(ctx context.Context, conf moduleConfig, r resource.Resource, resetTo string, out kubernetes.Output) error { - releaseConfig, err := conf.GetHelmReleaseConfig(r) - if err != nil { - return err - } - - cgm := kafka.NewConsumerGroupManager(conf.Firehose.KafkaBrokerAddress, kube.NewClient(out.Configs), releaseConfig.Namespace) - - switch resetTo { - case ResetToEarliest: - err = cgm.ResetOffsetToEarliest(ctx, conf.Firehose.KafkaConsumerID) - case ResetToLatest: - err = cgm.ResetOffsetToLatest(ctx, conf.Firehose.KafkaConsumerID) - default: - err = cgm.ResetOffsetToDatetime(ctx, conf.Firehose.KafkaConsumerID, resetTo) - } - - return handleErr(err) -} - -func handleErr(err error) error { - switch { - case errors.Is(err, kube.ErrJobCreationFailed): - return ErrNetwork.WithCause(err) - case errors.Is(err, kube.ErrJobNotFound): - return ErrKubeAPI.WithCause(err) - case errors.Is(err, kube.ErrJobExecutionFailed): - return ErrKubeAPI.WithCause(err) - default: - return err - } -} diff --git a/modules/firehose/kafka/consumer.go b/pkg/kafka/consumer.go similarity index 100% rename from modules/firehose/kafka/consumer.go rename to pkg/kafka/consumer.go From e758108dcad497dccb3df85dcd1018eb34a6bc80 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Thu, 16 Mar 2023 17:38:50 +0530 Subject: [PATCH 08/72] fix: change odpf reference to goto (#7) --- .goreleaser.yml | 2 +- README.md | 4 ++-- core/resource/resource_test.go | 2 +- docs/installation.md | 6 +++--- docs/modules/firehose.md | 2 +- modules/firehose/module.go | 4 ++-- pkg/helm/release_test.go | 6 +++--- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index dc3767c5..a2863627 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -67,7 +67,7 @@ brews: homepage: "https://github.com/goto/entropy" description: "Infrastructure orchestration tool." tap: - owner: odpf + owner: goto name: homebrew-tap license: "Apache 2.0" folder: Formula diff --git a/README.md b/README.md index d27622ab..6ee19413 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ in your PATH for easy use. `/usr/local/bin` is the most probable location. ```sh # Install entropy (requires homebrew installed) -$ brew install odpf/tap/entropy +$ brew install goto/tap/entropy # Check for installed entropy version $ entropy version @@ -83,7 +83,7 @@ $ make test Development of Entropy happens in the open on GitHub, and we are grateful to the community for contributing bugfixes and improvements. Read below to learn how you can take part in improving Entropy. -Read our [contributing guide](https://odpf.github.io/entropy/docs/contribute/contributing) to learn about our +Read our [contributing guide](https://goto.github.io/entropy/docs/contribute/contributing) to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to Entropy. To help you get your feet wet and get you familiar with our contribution process, we have a list diff --git a/core/resource/resource_test.go b/core/resource/resource_test.go index 36473a9b..d55fca91 100644 --- a/core/resource/resource_test.go +++ b/core/resource/resource_test.go @@ -50,7 +50,7 @@ func TestResource_Validate(t *testing.T) { res: resource.Resource{ Kind: "fake", Name: "foo", - Project: "odpf", + Project: "goto", }, want: nil, }, diff --git a/docs/installation.md b/docs/installation.md index f7551238..e44c7e8e 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -18,7 +18,7 @@ in your PATH for easy use. `/usr/local/bin` is the most probable location. ```sh # Install entropy (requires homebrew installed) -$ brew install odpf/taps/entropy +$ brew install goto/taps/entropy # Upgrade entropy (requires homebrew installed) $ brew upgrade entropy @@ -44,12 +44,12 @@ $ ./entropy version ### Using Docker image -Entropy ships a Docker image [odpf/entropy](https://hub.docker.com/r/goto/entropy) that enables you to use `entropy` as part of your Docker workflow. +Entropy ships a Docker image [goto/entropy](https://hub.docker.com/r/goto/entropy) that enables you to use `entropy` as part of your Docker workflow. For example, you can run `entropy version` with this command: ```bash -$ docker run odpf/entropy version +$ docker run goto/entropy version ``` ### Verifying the installation diff --git a/docs/modules/firehose.md b/docs/modules/firehose.md index 93d36f77..b870e4df 100644 --- a/docs/modules/firehose.md +++ b/docs/modules/firehose.md @@ -1,6 +1,6 @@ # Firehose -[Firehose](https://odpf.github.io/firehose/) is an extensible, no-code, and cloud-native service to load real-time streaming data from Kafka to data stores, data lakes, and analytical storage systems. +[Firehose](https://goto.github.io/firehose/) is an extensible, no-code, and cloud-native service to load real-time streaming data from Kafka to data stores, data lakes, and analytical storage systems. ## What happens in Plan? diff --git a/modules/firehose/module.go b/modules/firehose/module.go index de313652..0e263561 100644 --- a/modules/firehose/module.go +++ b/modules/firehose/module.go @@ -70,10 +70,10 @@ var Module = module.Descriptor{ }, DriverFactory: func(conf json.RawMessage) (module.Driver, error) { driverCfg := driverConfig{ - ChartRepository: "https://odpf.github.io/charts/", + ChartRepository: "https://goto.github.io/charts/", ChartName: "firehose", ChartVersion: "0.1.3", - ImageRepository: "odpf/firehose", + ImageRepository: "goto/firehose", ImageName: "firehose", ImageTag: "latest", Namespace: "firehose", diff --git a/pkg/helm/release_test.go b/pkg/helm/release_test.go index ac91569e..fd973f1e 100644 --- a/pkg/helm/release_test.go +++ b/pkg/helm/release_test.go @@ -63,7 +63,7 @@ func TestReleaseCreate(t *testing.T) { releaseConfig := DefaultReleaseConfig() releaseConfig.Name = releaseName - releaseConfig.Repository = "https://odpf.github.io/charts/" + releaseConfig.Repository = "https://goto.github.io/charts/" releaseConfig.Chart = "firehose" releaseConfig.Version = "0.1.1" releaseConfig.Values = jsonUnmarshal(jsonValues) @@ -83,7 +83,7 @@ func TestReleaseUpdate(t *testing.T) { releaseConfig := DefaultReleaseConfig() releaseConfig.Name = releaseName - releaseConfig.Repository = "https://odpf.github.io/charts/" + releaseConfig.Repository = "https://goto.github.io/charts/" releaseConfig.Chart = "firehose" releaseConfig.Version = "0.1.1" releaseConfig.Values = jsonUnmarshal(jsonValues) @@ -109,7 +109,7 @@ func TestReleaseDelete(t *testing.T) { releaseConfig := DefaultReleaseConfig() releaseConfig.Name = releaseName - releaseConfig.Repository = "https://odpf.github.io/charts/" + releaseConfig.Repository = "https://goto.github.io/charts/" releaseConfig.Chart = "firehose" releaseConfig.Version = "0.1.1" releaseConfig.Values = jsonUnmarshal(jsonValues) From 26d522671d8e52d23bfb7df6ffd07eac75fd8653 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Fri, 17 Mar 2023 10:34:58 +0530 Subject: [PATCH 09/72] generic refactors (#8) refactor: reduce firehose package --- core/write.go | 8 +- entropy.yaml | 2 +- modules/firehose/data.go | 17 ---- modules/firehose/driver.go | 91 +++++++++++++++---- modules/firehose/helm.go | 53 +++++++++++ modules/firehose/output.go | 77 ---------------- modules/firehose/{config.go => types.go} | 69 +++----------- .../{config_test.go => types_test.go} | 0 8 files changed, 147 insertions(+), 170 deletions(-) delete mode 100644 modules/firehose/data.go create mode 100644 modules/firehose/helm.go delete mode 100644 modules/firehose/output.go rename modules/firehose/{config.go => types.go} (61%) rename modules/firehose/{config_test.go => types_test.go} (100%) diff --git a/core/write.go b/core/write.go index 7509daec..6b7e367b 100644 --- a/core/write.go +++ b/core/write.go @@ -75,10 +75,6 @@ func (s *Service) execAction(ctx context.Context, res resource.Resource, act mod return &planned.Resource, nil } -func isCreate(actionName string) bool { - return actionName == module.CreateAction -} - func (s *Service) planChange(ctx context.Context, res resource.Resource, act module.ActionRequest) (*module.Plan, error) { modSpec, err := s.generateModuleSpec(ctx, res) if err != nil { @@ -136,3 +132,7 @@ func (s *Service) upsert(ctx context.Context, plan module.Plan, isCreate bool, s return nil } + +func isCreate(actionName string) bool { + return actionName == module.CreateAction +} diff --git a/entropy.yaml b/entropy.yaml index 1f683eda..1a86db93 100644 --- a/entropy.yaml +++ b/entropy.yaml @@ -33,7 +33,7 @@ worker: # Interval between successive polls by a single worker thread. be careful when # reducing this since it can cause contention when combined high threads value # and lot of entropy instances. - poll_interval: 1s + poll_interval: 1000000000 # instrumentation/metrics related configurations. telemetry: diff --git a/modules/firehose/data.go b/modules/firehose/data.go deleted file mode 100644 index cbcf2168..00000000 --- a/modules/firehose/data.go +++ /dev/null @@ -1,17 +0,0 @@ -package firehose - -import "encoding/json" - -type moduleData struct { - PendingSteps []string `json:"pending_steps"` - ResetTo string `json:"reset_to,omitempty"` - StateOverride string `json:"state_override,omitempty"` -} - -func (md moduleData) JSON() json.RawMessage { - bytes, err := json.Marshal(md) - if err != nil { - panic(err) - } - return bytes -} diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 07a4c6f5..d93d61ba 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -127,7 +127,7 @@ func (m *firehoseDriver) Sync(ctx context.Context, res module.ExpandedResource) return &resource.State{ Status: finalStatus, Output: output, - ModuleData: data.JSON(), + ModuleData: mustJSON(data), }, nil } @@ -148,7 +148,7 @@ func (*firehoseDriver) Log(ctx context.Context, res module.ExpandedResource, fil filter = make(map[string]string) } - hc, err := conf.GetHelmReleaseConfig(r) + hc, err := getHelmReleaseConf(r, conf) if err != nil { return nil, err } @@ -180,6 +180,57 @@ func (*firehoseDriver) Log(ctx context.Context, res module.ExpandedResource, fil return mappedLogs, err } +func (m *firehoseDriver) Output(ctx context.Context, res module.ExpandedResource) (json.RawMessage, error) { + var conf Config + if err := json.Unmarshal(res.Resource.Spec.Configs, &conf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + + var output Output + if err := json.Unmarshal(res.Resource.State.Output, &output); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid output json: %v", err) + } + + pods, err := m.podDetails(ctx, res) + if err != nil { + return nil, err + } + + hc, err := getHelmReleaseConf(res.Resource, conf) + if err != nil { + return nil, err + } + + return mustJSON(Output{ + Namespace: hc.Namespace, + ReleaseName: hc.Name, + Pods: pods, + Defaults: output.Defaults, + }), nil +} + +func (*firehoseDriver) podDetails(ctx context.Context, res module.ExpandedResource) ([]kube.Pod, error) { + r := res.Resource + + var conf Config + if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + + var kubeOut kubernetes.Output + if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { + return nil, err + } + + hc, err := getHelmReleaseConf(r, conf) + if err != nil { + return nil, err + } + + kubeCl := kube.NewClient(kubeOut.Configs) + return kubeCl.GetPodDetails(ctx, hc.Namespace, map[string]string{"app": hc.Name}) +} + func (m *firehoseDriver) planCreate(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { var plan module.Plan r := res.Resource @@ -192,16 +243,16 @@ func (m *firehoseDriver) planCreate(res module.ExpandedResource, act module.Acti return nil, err } - output := Output{ + output := mustJSON(Output{ Defaults: m.Config, - }.JSON() + }) - r.Spec.Configs = reqConf.JSON() + r.Spec.Configs = mustJSON(reqConf) r.State = resource.State{ Status: resource.StatusPending, - ModuleData: moduleData{ + ModuleData: mustJSON(moduleData{ PendingSteps: []string{releaseCreate}, - }.JSON(), + }), Output: output, } @@ -264,18 +315,18 @@ func (m *firehoseDriver) planChange(res module.ExpandedResource, act module.Acti } output.Defaults = m.Config - res.State.Output = output.JSON() + res.State.Output = mustJSON(output) plan.Reason = "firehose upgraded" } - r.Spec.Configs = conf.JSON() + r.Spec.Configs = mustJSON(conf) r.State = resource.State{ Status: resource.StatusPending, Output: res.State.Output, - ModuleData: moduleData{ + ModuleData: mustJSON(moduleData{ PendingSteps: []string{releaseUpdate}, - }.JSON(), + }), } plan.Resource = r return &plan, nil @@ -302,15 +353,15 @@ func (*firehoseDriver) planReset(res module.ExpandedResource, act module.ActionR resetValue = resetParams.Datetime } - r.Spec.Configs = conf.JSON() + r.Spec.Configs = mustJSON(conf) r.State = resource.State{ Status: resource.StatusPending, Output: res.State.Output, - ModuleData: moduleData{ + ModuleData: mustJSON(moduleData{ ResetTo: resetValue, PendingSteps: []string{releaseUpdate, consumerReset, releaseUpdate}, StateOverride: stateStopped, - }.JSON(), + }), } return &module.Plan{Resource: r, Reason: "firehose consumer reset"}, nil @@ -323,7 +374,7 @@ func (*firehoseDriver) releaseSync(isCreate bool, conf Config, r resource.Resour conf.Firehose.Replicas = 0 } - hc, err := conf.GetHelmReleaseConfig(r) + hc, err := getHelmReleaseConf(r, conf) if err != nil { return err } @@ -339,7 +390,7 @@ func (*firehoseDriver) releaseSync(isCreate bool, conf Config, r resource.Resour } func (*firehoseDriver) consumerReset(ctx context.Context, conf Config, r resource.Resource, resetTo string, out kubernetes.Output) error { - releaseConfig, err := conf.GetHelmReleaseConfig(r) + releaseConfig, err := getHelmReleaseConf(r, conf) if err != nil { return err } @@ -370,3 +421,11 @@ func handleErr(err error) error { return err } } + +func mustJSON(v any) json.RawMessage { + bytes, err := json.Marshal(v) + if err != nil { + panic(err) + } + return bytes +} diff --git a/modules/firehose/helm.go b/modules/firehose/helm.go new file mode 100644 index 00000000..4d6747a4 --- /dev/null +++ b/modules/firehose/helm.go @@ -0,0 +1,53 @@ +package firehose + +import ( + "encoding/json" + + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/helm" +) + +func getHelmReleaseConf(r resource.Resource, mc Config) (*helm.ReleaseConfig, error) { + var output Output + if err := json.Unmarshal(r.State.Output, &output); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid output json: %v", err) + } + defaults := output.Defaults + + relName, err := sanitiseDeploymentID(r, mc) + if err != nil { + return nil, err + } + + rc := helm.DefaultReleaseConfig() + rc.Name = relName + rc.Repository = defaults.ChartRepository + rc.Chart = defaults.ChartName + rc.Namespace = defaults.Namespace + rc.ForceUpdate = true + rc.Version = defaults.ChartVersion + + fc := mc.Firehose + fc.EnvVariables["SOURCE_KAFKA_BROKERS"] = fc.KafkaBrokerAddress + fc.EnvVariables["SOURCE_KAFKA_TOPIC"] = fc.KafkaTopic + fc.EnvVariables["SOURCE_KAFKA_CONSUMER_GROUP_ID"] = fc.KafkaConsumerID + + hv := map[string]interface{}{ + "replicaCount": mc.Firehose.Replicas, + "firehose": map[string]interface{}{ + "image": map[string]interface{}{ + "repository": defaults.ImageRepository, + "pullPolicy": defaults.ImagePullPolicy, + "tag": defaults.ImageTag, + }, + "config": fc.EnvVariables, + }, + } + if len(mc.Telegraf) > 0 { + hv["telegraf"] = mc.Telegraf + } + rc.Values = hv + + return rc, nil +} diff --git a/modules/firehose/output.go b/modules/firehose/output.go deleted file mode 100644 index b5a9844a..00000000 --- a/modules/firehose/output.go +++ /dev/null @@ -1,77 +0,0 @@ -package firehose - -import ( - "context" - "encoding/json" - - "github.com/goto/entropy/core/module" - "github.com/goto/entropy/modules/kubernetes" - "github.com/goto/entropy/pkg/errors" - "github.com/goto/entropy/pkg/kube" -) - -type Output struct { - Namespace string `json:"namespace,omitempty"` - ReleaseName string `json:"release_name,omitempty"` - Pods []kube.Pod `json:"pods,omitempty"` - Defaults driverConfig `json:"defaults,omitempty"` -} - -func (out Output) JSON() []byte { - b, err := json.Marshal(out) - if err != nil { - panic(err) - } - return b -} - -func (m *firehoseDriver) Output(ctx context.Context, res module.ExpandedResource) (json.RawMessage, error) { - var conf Config - if err := json.Unmarshal(res.Resource.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - - var output Output - if err := json.Unmarshal(res.Resource.State.Output, &output); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid output json: %v", err) - } - - pods, err := m.podDetails(ctx, res) - if err != nil { - return nil, err - } - - hc, err := conf.GetHelmReleaseConfig(res.Resource) - if err != nil { - return nil, err - } - - return Output{ - Namespace: hc.Namespace, - ReleaseName: hc.Name, - Pods: pods, - Defaults: output.Defaults, - }.JSON(), nil -} - -func (*firehoseDriver) podDetails(ctx context.Context, res module.ExpandedResource) ([]kube.Pod, error) { - r := res.Resource - - var conf Config - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - - var kubeOut kubernetes.Output - if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { - return nil, err - } - - hc, err := conf.GetHelmReleaseConfig(r) - if err != nil { - return nil, err - } - - kubeCl := kube.NewClient(kubeOut.Configs) - return kubeCl.GetPodDetails(ctx, hc.Namespace, map[string]string{"app": hc.Name}) -} diff --git a/modules/firehose/config.go b/modules/firehose/types.go similarity index 61% rename from modules/firehose/config.go rename to modules/firehose/types.go index 2f1f4935..aba1ee40 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/types.go @@ -3,14 +3,13 @@ package firehose import ( "crypto/sha256" _ "embed" - "encoding/json" "fmt" "strings" "time" "github.com/goto/entropy/core/resource" "github.com/goto/entropy/pkg/errors" - "github.com/goto/entropy/pkg/helm" + "github.com/goto/entropy/pkg/kube" ) const ( @@ -18,6 +17,19 @@ const ( firehoseConsumerIDStartingSequence = "0001" ) +type Output struct { + Namespace string `json:"namespace,omitempty"` + ReleaseName string `json:"release_name,omitempty"` + Pods []kube.Pod `json:"pods,omitempty"` + Defaults driverConfig `json:"defaults,omitempty"` +} + +type moduleData struct { + PendingSteps []string `json:"pending_steps"` + ResetTo string `json:"reset_to,omitempty"` + StateOverride string `json:"state_override,omitempty"` +} + type Config struct { State string `json:"state"` StopTime *time.Time `json:"stop_time"` @@ -46,59 +58,6 @@ func (mc *Config) validateAndSanitize(r resource.Resource) error { return nil } -func (mc *Config) GetHelmReleaseConfig(r resource.Resource) (*helm.ReleaseConfig, error) { - var output Output - err := json.Unmarshal(r.State.Output, &output) - if err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid output json: %v", err) - } - defaults := output.Defaults - - relName, err := sanitiseDeploymentID(r, *mc) - if err != nil { - return nil, err - } - - rc := helm.DefaultReleaseConfig() - rc.Name = relName - rc.Repository = defaults.ChartRepository - rc.Chart = defaults.ChartName - rc.Namespace = defaults.Namespace - rc.ForceUpdate = true - rc.Version = defaults.ChartVersion - - fc := mc.Firehose - fc.EnvVariables["SOURCE_KAFKA_BROKERS"] = fc.KafkaBrokerAddress - fc.EnvVariables["SOURCE_KAFKA_TOPIC"] = fc.KafkaTopic - fc.EnvVariables["SOURCE_KAFKA_CONSUMER_GROUP_ID"] = fc.KafkaConsumerID - - hv := map[string]interface{}{ - "replicaCount": mc.Firehose.Replicas, - "firehose": map[string]interface{}{ - "image": map[string]interface{}{ - "repository": defaults.ImageRepository, - "pullPolicy": defaults.ImagePullPolicy, - "tag": defaults.ImageTag, - }, - "config": fc.EnvVariables, - }, - } - if len(mc.Telegraf) > 0 { - hv["telegraf"] = mc.Telegraf - } - rc.Values = hv - - return rc, nil -} - -func (mc *Config) JSON() []byte { - b, err := json.Marshal(mc) - if err != nil { - panic(err) - } - return b -} - func sanitiseDeploymentID(r resource.Resource, mc Config) (string, error) { releaseName := mc.Firehose.DeploymentID if len(releaseName) == 0 { diff --git a/modules/firehose/config_test.go b/modules/firehose/types_test.go similarity index 100% rename from modules/firehose/config_test.go rename to modules/firehose/types_test.go From ab5b2dcd718dc754484604734d9fbf8d3fde41bd Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Fri, 17 Mar 2023 13:13:05 +0530 Subject: [PATCH 10/72] fix: firehose image name (#9) --- modules/firehose/driver.go | 4 ++-- modules/firehose/module.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index d93d61ba..798f8770 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -214,12 +214,12 @@ func (*firehoseDriver) podDetails(ctx context.Context, res module.ExpandedResour var conf Config if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + return nil, errors.ErrInvalid.WithMsgf("invalid config json").WithCausef(err.Error()) } var kubeOut kubernetes.Output if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { - return nil, err + return nil, errors.ErrInternal.WithMsgf("invalid kube out").WithCausef(err.Error()) } hc, err := getHelmReleaseConf(r, conf) diff --git a/modules/firehose/module.go b/modules/firehose/module.go index 0e263561..64c4ab4e 100644 --- a/modules/firehose/module.go +++ b/modules/firehose/module.go @@ -70,10 +70,10 @@ var Module = module.Descriptor{ }, DriverFactory: func(conf json.RawMessage) (module.Driver, error) { driverCfg := driverConfig{ - ChartRepository: "https://goto.github.io/charts/", + ChartRepository: "https://odpf.github.io/charts/", ChartName: "firehose", ChartVersion: "0.1.3", - ImageRepository: "goto/firehose", + ImageRepository: "gotocompany/firehose", ImageName: "firehose", ImageTag: "latest", Namespace: "firehose", From 022f7a40724794aebece4f194f0c736d133b7937 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Tue, 21 Mar 2023 11:05:29 +0530 Subject: [PATCH 11/72] refactor: re-implement firehose module (#10) * feat: implement create, update, reset * feat: implement upgrade * feat: implement start, stop, scale * test: add lots of tests * feat: implement reset-sync * refactor: simplify kafka reset flow * feat: implement log * refactor: separate client & server CLI * feat: fix entropy client cli --- Makefile | 2 +- cli/action.go | 79 --- cli/cli.go | 6 +- cli/client.go | 48 -- cli/client/client.go | 75 +++ cli/client/display.go | 93 ++++ cli/client/resource.go | 358 ++++++++++++ cli/client/utils.go | 60 ++ cli/logs.go | 80 --- cli/resource.go | 364 ------------- cli/utils.go | 68 --- core/module/driver.go | 4 +- core/write.go | 5 +- go.mod | 10 +- go.sum | 13 +- modules/firehose/config.go | 80 +++ modules/firehose/driver.go | 461 +++------------- modules/firehose/driver_log.go | 52 ++ modules/firehose/driver_output.go | 42 ++ modules/firehose/driver_output_test.go | 143 +++++ modules/firehose/driver_plan.go | 139 +++++ modules/firehose/driver_plan_test.go | 512 ++++++++++++++++++ modules/firehose/driver_sync.go | 88 +++ modules/firehose/driver_sync_test.go | 309 +++++++++++ modules/firehose/module.go | 119 ++-- modules/firehose/schema/config.json | 239 ++------ modules/firehoseold/driver.go | 428 +++++++++++++++ .../{firehose => firehoseold}/driver_test.go | 17 +- modules/{firehose => firehoseold}/helm.go | 2 +- modules/firehoseold/module.go | 91 ++++ modules/firehoseold/schema/config.json | 218 ++++++++ .../schema/reset.json | 0 .../schema/scale.json | 0 modules/{firehose => firehoseold}/types.go | 8 +- .../{firehose => firehoseold}/types_test.go | 2 +- pkg/kafka/consumer.go | 61 --- pkg/kafka/consumer_reset.go | 84 +++ pkg/validator/validator.go | 56 ++ 38 files changed, 3069 insertions(+), 1347 deletions(-) delete mode 100644 cli/action.go delete mode 100644 cli/client.go create mode 100644 cli/client/client.go create mode 100644 cli/client/display.go create mode 100644 cli/client/resource.go create mode 100644 cli/client/utils.go delete mode 100644 cli/logs.go delete mode 100644 cli/resource.go create mode 100644 modules/firehose/config.go create mode 100644 modules/firehose/driver_log.go create mode 100644 modules/firehose/driver_output.go create mode 100644 modules/firehose/driver_output_test.go create mode 100644 modules/firehose/driver_plan.go create mode 100644 modules/firehose/driver_plan_test.go create mode 100644 modules/firehose/driver_sync.go create mode 100644 modules/firehose/driver_sync_test.go create mode 100644 modules/firehoseold/driver.go rename modules/{firehose => firehoseold}/driver_test.go (85%) rename modules/{firehose => firehoseold}/helm.go (98%) create mode 100644 modules/firehoseold/module.go create mode 100644 modules/firehoseold/schema/config.json rename modules/{firehose => firehoseold}/schema/reset.json (100%) rename modules/{firehose => firehoseold}/schema/scale.json (100%) rename modules/{firehose => firehoseold}/types.go (96%) rename modules/{firehose => firehoseold}/types_test.go (98%) delete mode 100644 pkg/kafka/consumer.go create mode 100644 pkg/kafka/consumer_reset.go create mode 100644 pkg/validator/validator.go diff --git a/Makefile b/Makefile index a7c51863..e5d3f9f2 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ EXE=entropy .PHONY: all build clean tidy format test test-coverage proto -all: clean test build format lint +all: format clean test build tidy: @echo "Tidy up go.mod..." diff --git a/cli/action.go b/cli/action.go deleted file mode 100644 index 470e1d4d..00000000 --- a/cli/action.go +++ /dev/null @@ -1,79 +0,0 @@ -package cli - -import ( - "fmt" - - "github.com/MakeNowJust/heredoc" - "github.com/goto/salt/printer" - "github.com/goto/salt/term" - "github.com/spf13/cobra" - "google.golang.org/protobuf/types/known/structpb" - - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" -) - -func cmdAction() *cobra.Command { - var urn, file, output string - var params structpb.Value - cmd := &cobra.Command{ - Use: "action ", - Aliases: []string{"action"}, - Short: "Manage actions", - Example: heredoc.Doc(` - $ entropy action start --urn= --file= --out=json - `), - Annotations: map[string]string{ - "group:core": "true", - }, - Args: cobra.ExactArgs(1), - RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - - var reqBody entropyv1beta1.ApplyActionRequest - if file != "" { - if err := parseFile(file, ¶ms); err != nil { - return err - } - reqBody.Params = ¶ms - } - - reqBody.Urn = urn - reqBody.Action = args[0] - - err := reqBody.ValidateAll() - if err != nil { - return err - } - - client, cancel, err := createClient(cmd) - if err != nil { - return err - } - defer cancel() - - res, err := client.ApplyAction(cmd.Context(), &reqBody) - if err != nil { - return err - } - spinner.Stop() - - fmt.Println(term.Greenf("Action applied successfully")) - if output == outputJSON || output == outputYAML || output == outputYML { - formattedString, err := formatOutput(res.GetResource(), output) - if err != nil { - return err - } - fmt.Println(term.Bluef(formattedString)) - } - - return nil - }), - } - - cmd.Flags().StringVarP(&urn, "urn", "u", "", "urn of the resource") - cmd.Flags().StringVarP(&file, "file", "f", "", "path to the params file") - cmd.Flags().StringVarP(&output, "out", "o", "", "output format, `-o json | yaml`") - - return cmd -} diff --git a/cli/cli.go b/cli/cli.go index d40fa51f..9c4a023a 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -5,6 +5,8 @@ import ( "github.com/goto/salt/cmdx" "github.com/spf13/cobra" + + "github.com/goto/entropy/cli/client" ) var rootCmd = &cobra.Command{ @@ -21,9 +23,7 @@ func Execute(ctx context.Context) { cmdMigrate(), cmdVersion(), cmdShowConfigs(), - cmdResource(), - cmdAction(), - cmdLogs(), + client.Command(), ) cmdx.SetHelp(rootCmd) diff --git a/cli/client.go b/cli/client.go deleted file mode 100644 index 221185aa..00000000 --- a/cli/client.go +++ /dev/null @@ -1,48 +0,0 @@ -package cli - -import ( - "context" - "strconv" - "time" - - "github.com/spf13/cobra" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" - - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" -) - -const timeout = 2 - -func createConnection(ctx context.Context, host string) (*grpc.ClientConn, error) { - opts := []grpc.DialOption{ - grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithBlock(), - } - - return grpc.DialContext(ctx, host, opts...) -} - -func createClient(cmd *cobra.Command) (entropyv1beta1.ResourceServiceClient, func(), error) { - c, err := loadConfig(cmd) - if err != nil { - return nil, nil, err - } - - host := c.Service.Host + ":" + strconv.Itoa(c.Service.Port) - - dialTimeoutCtx, dialCancel := context.WithTimeout(cmd.Context(), time.Second*timeout) - conn, err := createConnection(dialTimeoutCtx, host) - if err != nil { - dialCancel() - return nil, nil, err - } - - cancel := func() { - dialCancel() - conn.Close() - } - - client := entropyv1beta1.NewResourceServiceClient(conn) - return client, cancel, nil -} diff --git a/cli/client/client.go b/cli/client/client.go new file mode 100644 index 00000000..62f9be18 --- /dev/null +++ b/cli/client/client.go @@ -0,0 +1,75 @@ +package client + +import ( + "context" + "time" + + "github.com/MakeNowJust/heredoc" + "github.com/spf13/cobra" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" +) + +const ( + outFormatFlag = "format" + entropyHostFlag = "entropy" + dialTimeoutFlag = "timeout" + + dialTimeout = 5 * time.Second +) + +func Command() *cobra.Command { + cmd := &cobra.Command{ + Use: "resource", + Short: "Entropy client with resource management commands", + Example: heredoc.Doc(` + $ entropy resource create + $ entropy resource list + $ entropy resource view + $ entropy resource delete + $ entropy resource edit + $ entropy resource revisions + `), + } + + cmd.PersistentFlags().StringP(entropyHostFlag, "E", "", "Entropy host to connect to") + cmd.PersistentFlags().DurationP(dialTimeoutFlag, "T", dialTimeout, "Dial timeout") + cmd.PersistentFlags().StringP(outFormatFlag, "F", "json", "output format (json, yaml)") + + cmd.AddCommand( + cmdStreamLogs(), + cmdApplyAction(), + cmdCreateResource(), + cmdViewResource(), + cmdEditResource(), + cmdDeleteResource(), + cmdListRevisions(), + ) + + return cmd +} + +func createClient(cmd *cobra.Command) (entropyv1beta1.ResourceServiceClient, func(), error) { + dialTimeoutVal, _ := cmd.Flags().GetDuration(dialTimeoutFlag) + entropyAddr, _ := cmd.Flags().GetString(entropyHostFlag) + + opts := []grpc.DialOption{ + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithBlock(), + } + + dialCtx, dialCancel := context.WithTimeout(cmd.Context(), dialTimeoutVal) + conn, err := grpc.DialContext(dialCtx, entropyAddr, opts...) + if err != nil { + dialCancel() + return nil, nil, err + } + + cancel := func() { + dialCancel() + _ = conn.Close() + } + return entropyv1beta1.NewResourceServiceClient(conn), cancel, nil +} diff --git a/cli/client/display.go b/cli/client/display.go new file mode 100644 index 00000000..46d18b2d --- /dev/null +++ b/cli/client/display.go @@ -0,0 +1,93 @@ +package client + +import ( + "encoding/json" + "fmt" + "io" + "os" + "strings" + + "github.com/BurntSushi/toml" + "github.com/spf13/cobra" + "gopkg.in/yaml.v3" + + "github.com/goto/entropy/pkg/errors" +) + +type FormatFn func(w io.Writer, v any) error + +// Display formats the given value 'v' using format specified as value for --format +// flag and writes to STDOUT. If --format=pretty/human, custom-formatter passed will +// be used. +func Display(cmd *cobra.Command, v any, prettyFormatter FormatFn) error { + format, _ := cmd.Flags().GetString("format") + format = strings.ToLower(strings.TrimSpace(format)) + + var formatter FormatFn + switch format { + case "json": + formatter = JSONFormat + + case "yaml", "yml": + formatter = YAMLFormat + + case "toml": + formatter = TOMLFormat + + case "pretty", "human": + if prettyFormatter != nil { + formatter = prettyFormatter + } else { + formatter = GoFormat + } + } + + if formatter == nil { + return errors.Errorf("--format value '%s' is not valid", format) + } + + return formatter(os.Stdout, v) +} + +// JSONFormat outputs 'v' formatted as indented JSON. +func JSONFormat(w io.Writer, v any) error { + enc := json.NewEncoder(w) + enc.SetIndent("", " ") + return enc.Encode(v) +} + +// TOMLFormat outputs 'v' formatted as per TOML spec. +func TOMLFormat(w io.Writer, v any) error { + enc := toml.NewEncoder(w) + return enc.Encode(v) +} + +// YAMLFormat outputs 'v' formatted as per YAML spec. +func YAMLFormat(w io.Writer, v any) error { + // note: since most values are json tagged but may not be + // yaml tagged, we do this to ensure keys are snake-cased. + val, err := jsonConvert(v) + if err != nil { + return err + } + return yaml.NewEncoder(w).Encode(val) +} + +// GoFormat outputs 'v' formatted using pp package. +func GoFormat(w io.Writer, v any) error { + _, err := fmt.Fprintln(w, v) + return err +} + +func jsonConvert(v any) (any, error) { + b, err := json.Marshal(v) + if err != nil { + return nil, err + } + + var val any + if err := json.Unmarshal(b, &val); err != nil { + return nil, err + } + return val, nil +} diff --git a/cli/client/resource.go b/cli/client/resource.go new file mode 100644 index 00000000..17738506 --- /dev/null +++ b/cli/client/resource.go @@ -0,0 +1,358 @@ +package client + +import ( + "fmt" + "io" + "os" + "strings" + + "github.com/goto/salt/printer" + "github.com/spf13/cobra" + "google.golang.org/protobuf/types/known/structpb" + + "github.com/goto/entropy/pkg/errors" + entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" +) + +func cmdViewResource() *cobra.Command { + var kind, project string + cmd := &cobra.Command{ + Use: "get [resource-urn]", + Args: cobra.MaximumNArgs(1), + Short: "List or View existing resource(s)", + Aliases: []string{"view"}, + RunE: handleErr(func(cmd *cobra.Command, args []string) error { + spinner := printer.Spin("") + defer spinner.Stop() + + client, cancel, err := createClient(cmd) + if err != nil { + return err + } + defer cancel() + + if len(args) == 1 { + // get resource + req := entropyv1beta1.GetResourceRequest{ + Urn: args[0], + } + res, err := client.GetResource(cmd.Context(), &req) + if err != nil { + return err + } + spinner.Stop() + + r := res.GetResource() + return Display(cmd, r, func(w io.Writer, v any) error { + printer.Table(os.Stdout, [][]string{ + {"URN", "NAME", "KIND", "PROJECT", "STATUS"}, + {r.Urn, r.Name, r.Kind, r.Project, r.State.Status.String()}, + }) + + return nil + }) + } + + // list resource + req := entropyv1beta1.ListResourcesRequest{ + Kind: kind, + Project: project, + } + res, err := client.ListResources(cmd.Context(), &req) + if err != nil { + return err + } + spinner.Stop() + + resources := res.GetResources() + return Display(cmd, resources, func(w io.Writer, _ any) error { + var report [][]string + report = append(report, []string{"URN", "NAME", "KIND", "PROJECT", "STATUS"}) + for _, r := range resources { + report = append(report, []string{r.Urn, r.Name, r.Kind, r.Project, r.State.Status.String()}) + } + printer.Table(os.Stdout, report) + _, _ = fmt.Fprintf(w, "Total: %d\n", len(report)-1) + return nil + }) + }), + } + + cmd.Flags().StringVarP(&kind, "kind", "k", "", "kind of resources") + cmd.Flags().StringVarP(&project, "project", "p", "", "project of resources") + + return cmd +} + +func cmdCreateResource() *cobra.Command { + cmd := &cobra.Command{ + Use: "create ", + Short: "Create a new resource on Entropy.", + RunE: handleErr(func(cmd *cobra.Command, args []string) error { + spinner := printer.Spin("") + defer spinner.Stop() + + var reqBody entropyv1beta1.Resource + if err := parseFile(args[0], &reqBody); err != nil { + return err + } else if err := reqBody.ValidateAll(); err != nil { + return err + } + + client, cancel, err := createClient(cmd) + if err != nil { + return err + } + defer cancel() + + req := &entropyv1beta1.CreateResourceRequest{ + Resource: &reqBody, + } + + res, err := client.CreateResource(cmd.Context(), req) + if err != nil { + return err + } + spinner.Stop() + + resource := res.GetResource() + return Display(cmd, resource, nil) + }), + } + + return cmd +} + +func cmdEditResource() *cobra.Command { + var file string + cmd := &cobra.Command{ + Use: "edit ", + Args: cobra.ExactArgs(1), + Short: "Make updates to an existing resource", + RunE: handleErr(func(cmd *cobra.Command, args []string) error { + spinner := printer.Spin("") + defer spinner.Stop() + + var newSpec entropyv1beta1.ResourceSpec + if err := parseFile(file, &newSpec); err != nil { + return err + } + + reqBody := entropyv1beta1.UpdateResourceRequest{ + Urn: args[0], + NewSpec: &newSpec, + } + if err := reqBody.ValidateAll(); err != nil { + return err + } + + client, cancel, err := createClient(cmd) + if err != nil { + return err + } + defer cancel() + + resp, err := client.UpdateResource(cmd.Context(), &reqBody) + if err != nil { + return err + } + spinner.Stop() + + resource := resp.GetResource() + return Display(cmd, resource, func(w io.Writer, _ any) error { + _, _ = fmt.Fprintln(w, "Update request placed successfully.") + return nil + }) + }), + } + + cmd.Flags().StringVarP(&file, "file", "f", "", "path to the updated spec of resource") + return cmd +} + +func cmdApplyAction() *cobra.Command { + var urn, file string + cmd := &cobra.Command{ + Use: "action ", + Args: cobra.ExactArgs(1), + Short: "Apply an action on an existing resource", + Aliases: []string{"execute"}, + RunE: handleErr(func(cmd *cobra.Command, args []string) error { + spinner := printer.Spin("") + defer spinner.Stop() + + var params structpb.Value + if file != "" { + if err := parseFile(file, ¶ms); err != nil { + return err + } + } + + reqBody := entropyv1beta1.ApplyActionRequest{ + Urn: urn, + Action: args[0], + Params: ¶ms, + } + + err := reqBody.ValidateAll() + if err != nil { + return err + } + + client, cancel, err := createClient(cmd) + if err != nil { + return err + } + defer cancel() + + res, err := client.ApplyAction(cmd.Context(), &reqBody) + if err != nil { + return err + } + spinner.Stop() + + resource := res.GetResource() + return Display(cmd, resource, nil) + }), + } + + cmd.Flags().StringVarP(&urn, "urn", "u", "", "urn of the resource") + cmd.Flags().StringVarP(&file, "file", "f", "", "path to the params file") + + return cmd +} + +func cmdDeleteResource() *cobra.Command { + cmd := &cobra.Command{ + Use: "delete ", + Args: cobra.ExactArgs(1), + Short: "Delete an existing resource.", + Aliases: []string{"rm", "del"}, + RunE: handleErr(func(cmd *cobra.Command, args []string) error { + spinner := printer.Spin("") + defer spinner.Stop() + + client, cancel, err := createClient(cmd) + if err != nil { + return err + } + defer cancel() + + _, err = client.DeleteResource(cmd.Context(), &entropyv1beta1.DeleteResourceRequest{Urn: args[0]}) + if err != nil { + return err + } + spinner.Stop() + + return Display(cmd, nil, func(w io.Writer, v any) error { + _, _ = fmt.Fprintln(w, "Delete request placed successfully") + return nil + }) + }), + } + return cmd +} + +func cmdListRevisions() *cobra.Command { + cmd := &cobra.Command{ + Use: "revisions", + Short: "List revisions of a resource.", + Aliases: []string{"revs"}, + RunE: handleErr(func(cmd *cobra.Command, args []string) error { + spinner := printer.Spin("") + defer spinner.Stop() + + var reqBody entropyv1beta1.GetResourceRevisionsRequest + reqBody.Urn = args[0] + + client, cancel, err := createClient(cmd) + if err != nil { + return err + } + defer cancel() + + req := &entropyv1beta1.GetResourceRevisionsRequest{Urn: args[0]} + res, err := client.GetResourceRevisions(cmd.Context(), req) + if err != nil { + return err + } + spinner.Stop() + + revisions := res.GetRevisions() + return Display(cmd, revisions, func(w io.Writer, v any) error { + var report [][]string + report = append(report, []string{"ID", "URN", "CREATED AT"}) + for _, rev := range res.GetRevisions() { + report = append(report, []string{rev.GetId(), rev.GetUrn(), rev.GetCreatedAt().AsTime().String()}) + } + printer.Table(os.Stdout, report) + _, _ = fmt.Fprintf(w, "Total: %d\n", len(report)-1) + return nil + }) + }), + } + + return cmd +} + +func cmdStreamLogs() *cobra.Command { + var filter []string + cmd := &cobra.Command{ + Use: "logs ", + Args: cobra.ExactArgs(1), + Short: "Stream real-time logs for an existing resource.", + Aliases: []string{"logs"}, + RunE: handleErr(func(cmd *cobra.Command, args []string) error { + spinner := printer.Spin("") + defer spinner.Stop() + + client, cancel, err := createClient(cmd) + if err != nil { + return err + } + defer cancel() + + filters := map[string]string{} + for _, f := range filter { + keyValue := strings.Split(f, ":") + filters[keyValue[0]] = keyValue[1] + } + + reqBody := &entropyv1beta1.GetLogRequest{ + Urn: args[0], + Filter: filters, + } + + if err := reqBody.ValidateAll(); err != nil { + return err + } + + stream, err := client.GetLog(cmd.Context(), reqBody) + if err != nil { + return err + } + spinner.Stop() + + for { + resp, err := stream.Recv() + if err != nil { + if errors.Is(err, io.EOF) { + break + } + return fmt.Errorf("failed to read stream: %w", err) + } + + chunk := resp.GetChunk() + _ = Display(cmd, chunk, func(w io.Writer, v any) error { + _, _ = fmt.Fprintln(w, string(chunk.GetData())) + return nil + }) + } + + return nil + }), + } + + cmd.Flags().StringSliceVarP(&filter, "filter", "f", nil, "Filter. (e.g., --filter=\"key:value\")") + return cmd +} diff --git a/cli/client/utils.go b/cli/client/utils.go new file mode 100644 index 00000000..4d08d666 --- /dev/null +++ b/cli/client/utils.go @@ -0,0 +1,60 @@ +package client + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/ghodss/yaml" + "github.com/spf13/cobra" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/reflect/protoreflect" + + "github.com/goto/entropy/pkg/errors" +) + +type RunEFunc func(cmd *cobra.Command, args []string) error + +func parseFile(filePath string, v protoreflect.ProtoMessage) error { + b, err := os.ReadFile(filePath) + if err != nil { + return err + } + + unmarshalOpts := protojson.UnmarshalOptions{} + + switch filepath.Ext(filePath) { + case ".json": + if err := unmarshalOpts.Unmarshal(b, v); err != nil { + return fmt.Errorf("invalid json: %w", err) + } + + case ".yaml", ".yml": + j, err := yaml.YAMLToJSON(b) + if err != nil { + return fmt.Errorf("invalid yaml: %w", err) + } + if err := unmarshalOpts.Unmarshal(j, v); err != nil { + return fmt.Errorf("invalid yaml: %w", err) + } + + default: + return errors.New("unsupported file type") // nolint + } + + return nil +} + +func fatalExitf(format string, args ...interface{}) { + fmt.Printf(format+"\n", args...) + os.Exit(1) +} + +func handleErr(fn RunEFunc) RunEFunc { + return func(cmd *cobra.Command, args []string) error { + if err := fn(cmd, args); err != nil { + fatalExitf(err.Error()) + } + return nil + } +} diff --git a/cli/logs.go b/cli/logs.go deleted file mode 100644 index ad77d513..00000000 --- a/cli/logs.go +++ /dev/null @@ -1,80 +0,0 @@ -package cli - -import ( - "errors" - "fmt" - "io" - "log" - "strings" - - "github.com/MakeNowJust/heredoc" - "github.com/goto/salt/printer" - "github.com/goto/salt/term" // nolint - "github.com/spf13/cobra" - - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" -) - -func cmdLogs() *cobra.Command { - var filter []string - filters := make(map[string]string) - cmd := &cobra.Command{ - Use: "logs ", - Aliases: []string{"logs"}, - Short: "Gets logs", - Example: heredoc.Doc(` - $ entropy logs --filter="key1=value1" --filter="key2=value2" - `), - Annotations: map[string]string{ - "group:core": "true", - }, - Args: cobra.ExactArgs(1), - RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - - client, cancel, err := createClient(cmd) - if err != nil { - return err - } - defer cancel() - - var reqBody entropyv1beta1.GetLogRequest - for _, f := range filter { - keyValue := strings.Split(f, "=") - filters[keyValue[0]] = keyValue[1] - } - reqBody.Filter = filters - reqBody.Urn = args[0] - - err = reqBody.ValidateAll() - if err != nil { - return err - } - - stream, err := client.GetLog(cmd.Context(), &reqBody) - if err != nil { - return err - } - spinner.Stop() - - for { - resp, err := stream.Recv() - if err != nil { - if errors.Is(err, io.EOF) { - break - } - return fmt.Errorf("failed to read stream: %w", err) - } - - log.SetFlags(0) - log.Printf(term.Bluef("%s", resp.GetChunk().GetData())) // nolint - } - - return nil - }), - } - - cmd.Flags().StringArrayVarP(&filter, "filter", "f", nil, "Use filters. Example: --filter=\"key=value\"") - return cmd -} diff --git a/cli/resource.go b/cli/resource.go deleted file mode 100644 index 4ded7d16..00000000 --- a/cli/resource.go +++ /dev/null @@ -1,364 +0,0 @@ -package cli - -import ( - "fmt" - "os" - - "github.com/MakeNowJust/heredoc" - "github.com/goto/salt/printer" - "github.com/goto/salt/term" // nolint - "github.com/spf13/cobra" - - entropyv1beta1 "github.com/goto/entropy/proto/gotocompany/entropy/v1beta1" -) - -func cmdResource() *cobra.Command { - cmd := &cobra.Command{ - Use: "resource", - Aliases: []string{"resources"}, - Short: "Manage resources", - Annotations: map[string]string{ - "group:core": "true", - }, - Example: heredoc.Doc(` - $ entropy resource create - $ entropy resource list - $ entropy resource view - $ entropy resource delete - $ entropy resource edit - $ entropy resource revisions - `), - } - - cmd.AddCommand( - createResourceCommand(), - listAllResourcesCommand(), - viewResourceCommand(), - editResourceCommand(), - deleteResourceCommand(), - getRevisionsCommand(), - ) - - return cmd -} - -func createResourceCommand() *cobra.Command { - var file, output string - cmd := &cobra.Command{ - Use: "create", - Short: "create a resource", - Example: heredoc.Doc(` - $ entropy resource create --file= --out=json - `), - Annotations: map[string]string{ - "action:core": "true", - }, - RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - - var reqBody entropyv1beta1.CreateResourceRequest - if err := parseFile(file, &reqBody); err != nil { - return err - } else if err := reqBody.ValidateAll(); err != nil { - return err - } - - client, cancel, err := createClient(cmd) - if err != nil { - return err - } - defer cancel() - - res, err := client.CreateResource(cmd.Context(), &reqBody) - if err != nil { - return err - } - spinner.Stop() - - fmt.Println("URN: \t", term.Greenf(res.Resource.Urn)) - if output == outputJSON || output == outputYAML || output == outputYML { - formattedOutput, err := formatOutput(res.GetResource(), output) - if err != nil { - return err - } - fmt.Println(term.Bluef(formattedOutput)) - } - - return nil - }), - } - - cmd.Flags().StringVarP(&file, "file", "f", "", "path to body of resource") - cmd.Flags().StringVarP(&output, "out", "o", "", "output format, `-o json | yaml`") - - return cmd -} - -func listAllResourcesCommand() *cobra.Command { - var output, kind, project string - cmd := &cobra.Command{ - Use: "list", - Short: "list all resources", - Example: heredoc.Doc(` - $ entropy resource list --kind= --project= --out=json - `), - Annotations: map[string]string{ - "action:core": "true", - }, - RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - - var reqBody entropyv1beta1.ListResourcesRequest - reqBody.Kind = kind - reqBody.Project = project - - client, cancel, err := createClient(cmd) - if err != nil { - return err - } - defer cancel() - - res, err := client.ListResources(cmd.Context(), &reqBody) - if err != nil { - return err - } - spinner.Stop() - - if output == outputJSON || output == outputYAML || output == outputYML { - for _, resource := range res.GetResources() { - formattedOutput, err := formatOutput(resource, output) - if err != nil { - return err - } - fmt.Println(term.Bluef(formattedOutput)) - } - } else { - var report [][]string - report = append(report, []string{"URN", "NAME", "KIND", "PROJECT", "STATUS"}) - count := 0 - for _, r := range res.GetResources() { - report = append(report, []string{r.Urn, r.Name, r.Kind, r.Project, r.State.Status.String()}) - count++ - } - printer.Table(os.Stdout, report) - fmt.Println("\nTotal: ", count) - - fmt.Println(term.Cyanf("To view all the data in JSON/YAML format, use flag `-o json | yaml`")) - } - return nil - }), - } - - cmd.Flags().StringVarP(&output, "out", "o", "", "output format, `-o json | yaml`") - cmd.Flags().StringVarP(&kind, "kind", "k", "", "kind of resources") - cmd.Flags().StringVarP(&project, "project", "p", "", "project of resources") - - return cmd -} - -func viewResourceCommand() *cobra.Command { - var output string - cmd := &cobra.Command{ - Use: "view ", - Short: "view a resource", - Example: heredoc.Doc(` - $ entropy resource view --out=json - `), - Annotations: map[string]string{ - "action:core": "true", - }, - Args: cobra.ExactArgs(1), - RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - - var reqBody entropyv1beta1.GetResourceRequest - reqBody.Urn = args[0] - - client, cancel, err := createClient(cmd) - if err != nil { - return err - } - defer cancel() - - res, err := client.GetResource(cmd.Context(), &reqBody) - if err != nil { - return err - } - spinner.Stop() - - if output == outputJSON || output == outputYAML || output == outputYML { - formattedOutput, err := formatOutput(res.GetResource(), output) - if err != nil { - return err - } - fmt.Println(term.Bluef(formattedOutput)) - } else { - r := res.GetResource() - - printer.Table(os.Stdout, [][]string{ - {"URN", "NAME", "KIND", "PROJECT", "STATUS"}, - {r.Urn, r.Name, r.Kind, r.Project, r.State.Status.String()}, - }) - - fmt.Println(term.Cyanf("\nTo view all the data in JSON/YAML format, use flag `-o json | yaml`")) - } - return nil - }), - } - - cmd.Flags().StringVarP(&output, "out", "o", "", "output format, `-o json | yaml`") - - return cmd -} - -func editResourceCommand() *cobra.Command { - var file string - cmd := &cobra.Command{ - Use: "edit ", - Short: "edit a resource", - Example: heredoc.Doc(` - $ entropy resource edit --file= - `), - Annotations: map[string]string{ - "action:core": "true", - }, - Args: cobra.ExactArgs(1), - RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - - var newSpec entropyv1beta1.ResourceSpec - if err := parseFile(file, &newSpec); err != nil { - return err - } else if err := newSpec.ValidateAll(); err != nil { - return err - } - - var reqBody entropyv1beta1.UpdateResourceRequest - reqBody.NewSpec = &newSpec - reqBody.Urn = args[0] - if err := reqBody.ValidateAll(); err != nil { - return err - } - - client, cancel, err := createClient(cmd) - if err != nil { - return err - } - defer cancel() - - _, err = client.UpdateResource(cmd.Context(), &reqBody) - if err != nil { - return err - } - spinner.Stop() - - fmt.Println(term.Greenf("Successfully updated")) - return nil - }), - } - - cmd.Flags().StringVarP(&file, "file", "f", "", "path to the updated spec of resource") - - return cmd -} - -func deleteResourceCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "delete ", - Short: "delete a resource", - Example: heredoc.Doc(` - $ entropy resource delete - `), - Annotations: map[string]string{ - "action:core": "true", - }, - Args: cobra.ExactArgs(1), - RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - - var reqBody entropyv1beta1.DeleteResourceRequest - reqBody.Urn = args[0] - - client, cancel, err := createClient(cmd) - if err != nil { - return err - } - defer cancel() - - _, err = client.DeleteResource(cmd.Context(), &reqBody) - if err != nil { - return err - } - spinner.Stop() - - fmt.Println(term.Greenf("Successfully deleted")) - return nil - }), - } - return cmd -} - -func getRevisionsCommand() *cobra.Command { - var output string - cmd := &cobra.Command{ - Use: "revisions", - Short: "get revisions of a resource", - Example: heredoc.Doc(` - $ entropy resource revisions --out=json - `), - Annotations: map[string]string{ - "action:core": "true", - }, - RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - - var reqBody entropyv1beta1.GetResourceRevisionsRequest - reqBody.Urn = args[0] - - client, cancel, err := createClient(cmd) - if err != nil { - return err - } - defer cancel() - - res, err := client.GetResourceRevisions(cmd.Context(), &reqBody) - if err != nil { - return err - } - spinner.Stop() - - if output == outputJSON || output == outputYAML || output == outputYML { - for _, rev := range res.GetRevisions() { - formattedOutput, err := formatOutput(rev, output) - if err != nil { - return err - } - fmt.Println(term.Bluef(formattedOutput)) - } - } else { - var report [][]string - report = append(report, []string{"ID", "URN", "CREATED AT"}) - count := 0 - for _, rev := range res.GetRevisions() { - report = append(report, []string{rev.GetId(), rev.GetUrn(), rev.GetCreatedAt().AsTime().String()}) - count++ - } - printer.Table(os.Stdout, report) - fmt.Println("\nTotal: ", count) - - fmt.Println(term.Cyanf("To view all the data in JSON/YAML format, use flag `-o json | yaml`")) - } - return nil - }), - } - - cmd.Flags().StringVarP(&output, "out", "o", "", "output format, `-o json | yaml`") - - return cmd -} diff --git a/cli/utils.go b/cli/utils.go index 67025e10..03e06eac 100644 --- a/cli/utils.go +++ b/cli/utils.go @@ -1,82 +1,14 @@ package cli import ( - "errors" "fmt" "os" - "path/filepath" - "github.com/ghodss/yaml" "github.com/spf13/cobra" - "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/reflect/protoreflect" -) - -const ( - outputJSON = "json" - outputYAML = "yaml" - outputYML = "yml" ) type RunEFunc func(cmd *cobra.Command, args []string) error -func parseFile(filePath string, v protoreflect.ProtoMessage) error { - b, err := os.ReadFile(filePath) - if err != nil { - return err - } - - unmarshalOpts := protojson.UnmarshalOptions{} - - switch filepath.Ext(filePath) { - case ".json": - if err := unmarshalOpts.Unmarshal(b, v); err != nil { - return fmt.Errorf("invalid json: %w", err) - } - - case ".yaml", ".yml": - j, err := yaml.YAMLToJSON(b) - if err != nil { - return fmt.Errorf("invalid yaml: %w", err) - } - if err := unmarshalOpts.Unmarshal(j, v); err != nil { - return fmt.Errorf("invalid yaml: %w", err) - } - - default: - return errors.New("unsupported file type") // nolint - } - - return nil -} - -func formatOutput(i protoreflect.ProtoMessage, format string) (string, error) { - marshalOpts := protojson.MarshalOptions{ - Indent: "\t", - Multiline: true, - UseProtoNames: true, - } - - b, e := marshalOpts.Marshal(i) - if e != nil { - return "", e - } - - switch format { - case outputJSON: - return string(b), nil - - case outputYAML, outputYML: - y, e := yaml.JSONToYAML(b) - if e != nil { - return "", e - } - return string(y), nil - default: - return "", errors.New("unsupported format") // nolint - } -} - func fatalExitf(format string, args ...interface{}) { fmt.Printf(format+"\n", args...) os.Exit(1) diff --git a/core/module/driver.go b/core/module/driver.go index dd7e416c..61f1b7f6 100644 --- a/core/module/driver.go +++ b/core/module/driver.go @@ -34,9 +34,9 @@ type Driver interface { // Plan represents the changes to be staged and later synced by module. type Plan struct { - Resource resource.Resource - ScheduleRunAt time.Time Reason string + Resource resource.Resource + ScheduleRunAt *time.Time } // Loggable extension of driver allows streaming log data for a resource. diff --git a/core/write.go b/core/write.go index 6b7e367b..0735d776 100644 --- a/core/write.go +++ b/core/write.go @@ -16,6 +16,7 @@ func (s *Service) CreateResource(ctx context.Context, res resource.Resource) (*r act := module.ActionRequest{ Name: module.CreateAction, Params: res.Spec.Configs, + Labels: res.Labels, } res.Spec.Configs = nil @@ -108,9 +109,9 @@ func (s *Service) upsert(ctx context.Context, plan module.Plan, isCreate bool, s return s.enqueueSyncJob(ctx, plan.Resource, s.clock(), JobKindSyncResource) }) - if !plan.ScheduleRunAt.IsZero() { + if plan.ScheduleRunAt != nil { hooks = append(hooks, func(ctx context.Context) error { - return s.enqueueSyncJob(ctx, plan.Resource, plan.ScheduleRunAt, JobKindScheduledSyncResource) + return s.enqueueSyncJob(ctx, plan.Resource, *plan.ScheduleRunAt, JobKindScheduledSyncResource) }) } diff --git a/go.mod b/go.mod index 6c3770d5..15807568 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/MakeNowJust/heredoc v1.0.0 github.com/Masterminds/squirrel v1.5.2 github.com/ghodss/yaml v1.0.0 + github.com/go-playground/validator/v10 v10.11.2 github.com/google/go-cmp v0.5.9 github.com/gorilla/mux v1.8.0 github.com/goto/salt v0.3.0 @@ -39,7 +40,7 @@ require ( require ( github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect - github.com/BurntSushi/toml v1.0.0 // indirect + github.com/BurntSushi/toml v1.0.0 github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.1.1 // indirect github.com/Masterminds/sprig/v3 v3.2.2 // indirect @@ -159,7 +160,7 @@ require ( go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect - golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect + golang.org/x/crypto v0.5.0 // indirect golang.org/x/net v0.5.0 // indirect golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 // indirect golang.org/x/sync v0.1.0 // indirect @@ -170,7 +171,7 @@ require ( google.golang.org/appengine v1.6.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + gopkg.in/yaml.v3 v3.0.1 k8s.io/apiextensions-apiserver v0.24.0 // indirect k8s.io/apiserver v0.24.0 // indirect k8s.io/cli-runtime v0.24.0 // indirect @@ -192,7 +193,10 @@ require ( github.com/cli/safeexec v1.0.0 // indirect github.com/go-kit/log v0.1.0 // indirect github.com/go-logfmt/logfmt v0.5.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/leodido/go-urn v1.2.1 // indirect github.com/newrelic/newrelic-telemetry-sdk-go v0.2.0 // indirect github.com/prometheus/statsd_exporter v0.21.0 // indirect google.golang.org/api v0.98.0 // indirect diff --git a/go.sum b/go.sum index 9531f60a..4aafd103 100644 --- a/go.sum +++ b/go.sum @@ -583,6 +583,13 @@ github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= +github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -964,6 +971,8 @@ github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -1552,8 +1561,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= diff --git a/modules/firehose/config.go b/modules/firehose/config.go new file mode 100644 index 00000000..4af71639 --- /dev/null +++ b/modules/firehose/config.go @@ -0,0 +1,80 @@ +package firehose + +import ( + "crypto/sha256" + _ "embed" + "encoding/json" + "fmt" + "strings" + + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/validator" +) + +const ( + confKeyConsumerID = "SOURCE_KAFKA_CONSUMER_GROUP_ID" + confKeyKafkaBrokers = "SOURCE_KAFKA_BROKERS" +) + +const kubeDeploymentNameLengthLimit = 53 + +var ( + //go:embed schema/config.json + configSchemaRaw []byte + + validateConfig = validator.FromJSONSchema(configSchemaRaw) +) + +type Config struct { + Telegraf map[string]any `json:"telegraf,omitempty"` + Replicas int `json:"replicas"` + Namespace string `json:"namespace,omitempty"` + DeploymentID string `json:"deployment_id,omitempty"` + ChartValues *chartValues `json:"chart_values,omitempty"` + EnvVariables map[string]string `json:"env_variables,omitempty"` +} + +func readConfig(r resource.Resource, confJSON json.RawMessage) (*Config, error) { + var cfg Config + if err := json.Unmarshal(confJSON, &cfg); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json").WithCausef(err.Error()) + } + + if cfg.Replicas <= 0 { + cfg.Replicas = 1 + } + + if err := validateConfig(confJSON); err != nil { + return nil, err + } + + // note: enforce the kubernetes deployment name length limit. + if len(cfg.DeploymentID) == 0 { + cfg.DeploymentID = generateSafeReleaseName(r.Project, r.Name) + } else if len(cfg.DeploymentID) >= kubeDeploymentNameLengthLimit { + return nil, errors.ErrInvalid.WithMsgf("deployment_id must be shorter than 53 chars") + } + + if consumerID := cfg.EnvVariables[confKeyConsumerID]; consumerID == "" { + cfg.EnvVariables[confKeyConsumerID] = fmt.Sprintf("%s-0001", cfg.DeploymentID) + } + + return &cfg, nil +} + +func generateSafeReleaseName(project, name string) string { + const prefix = "firehose-" + const randomHashLen = 6 + + releaseName := fmt.Sprintf("%s%s-%s", prefix, project, name) + if len(releaseName) >= kubeDeploymentNameLengthLimit { + releaseName = strings.Trim(releaseName[:kubeDeploymentNameLengthLimit-randomHashLen-1], "-") + + val := sha256.Sum256([]byte(releaseName)) + hash := fmt.Sprintf("%x", val) + releaseName = releaseName + "-" + hash[:randomHashLen] + } + + return releaseName +} diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 798f8770..9c32792d 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -3,423 +3,116 @@ package firehose import ( "context" "encoding/json" - "time" "github.com/goto/entropy/core/module" - "github.com/goto/entropy/core/resource" "github.com/goto/entropy/modules/kubernetes" "github.com/goto/entropy/pkg/errors" "github.com/goto/entropy/pkg/helm" - "github.com/goto/entropy/pkg/kafka" "github.com/goto/entropy/pkg/kube" - "github.com/goto/entropy/pkg/worker" ) const ( - networkErrorRetryDuration = 5 * time.Second - kubeAPIRetryBackoffDuration = 30 * time.Second + stepReleaseCreate = "release_create" + stepReleaseUpdate = "release_update" + stepReleaseStop = "release_stop" + stepKafkaReset = "consumer_reset" ) -const ( - releaseCreate = "release_create" - releaseUpdate = "release_update" - consumerReset = "consumer_reset" -) - -const ( - stateRunning = "RUNNING" - stateStopped = "STOPPED" -) - -const ( - ResetToDateTime = "DATETIME" - ResetToEarliest = "EARLIEST" - ResetToLatest = "LATEST" -) - -var ( - ErrNetwork = worker.RetryableError{RetryAfter: networkErrorRetryDuration} - ErrKubeAPI = worker.RetryableError{RetryAfter: kubeAPIRetryBackoffDuration} -) - -type driverConfig struct { - ChartRepository string `json:"chart_repository,omitempty"` - ChartName string `json:"chart_name,omitempty"` - ChartVersion string `json:"chart_version,omitempty"` - ImageRepository string `json:"image_repository,omitempty"` - ImageName string `json:"image_name,omitempty"` - ImageTag string `json:"image_tag,omitempty"` - Namespace string `json:"namespace,omitempty"` - ImagePullPolicy string `json:"image_pull_policy,omitempty"` +var defaultDriverConf = driverConf{ + Namespace: "firehose", + Telegraf: map[string]any{ + "enabled": false, + }, + ChartValues: chartValues{ + ImageTag: "latest", + ChartVersion: "0.1.3", + ImagePullPolicy: "IfNotPresent", + }, } type firehoseDriver struct { - Config driverConfig `json:"config"` + conf driverConf + kubeDeploy kubeDeployFn + kubeGetPod kubeGetPodFn + consumerReset consumerResetFn } -func (m *firehoseDriver) Plan(_ context.Context, res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { - switch act.Name { - case module.CreateAction: - return m.planCreate(res, act) - - case ResetAction: - return m.planReset(res, act) - - default: - return m.planChange(res, act) - } -} - -func (m *firehoseDriver) Sync(ctx context.Context, res module.ExpandedResource) (*resource.State, error) { - r := res.Resource - - var data moduleData - if err := json.Unmarshal(r.State.ModuleData, &data); err != nil { - return nil, errors.ErrInternal.WithMsgf("invalid module data").WithCausef(err.Error()) - } - - var conf Config - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json").WithCausef(err.Error()) - } - - var kubeOut kubernetes.Output - if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { - return nil, errors.ErrInternal.WithMsgf("invalid kube state").WithCausef(err.Error()) - } - - if len(data.PendingSteps) > 0 { - pendingStep := data.PendingSteps[0] - data.PendingSteps = data.PendingSteps[1:] - - switch pendingStep { - case releaseCreate, releaseUpdate: - if data.StateOverride != "" { - conf.State = data.StateOverride - } - if err := m.releaseSync(pendingStep == releaseCreate, conf, r, kubeOut); err != nil { - return nil, err - } - - case consumerReset: - if err := m.consumerReset(ctx, conf, r, data.ResetTo, kubeOut); err != nil { - return nil, err - } - data.StateOverride = "" - - default: - if err := m.releaseSync(pendingStep == releaseCreate, conf, r, kubeOut); err != nil { - return nil, err - } - } - } - - output, err := m.Output(ctx, res) - if err != nil { - return nil, err - } - - finalStatus := resource.StatusCompleted - if len(data.PendingSteps) > 0 { - finalStatus = resource.StatusPending - } - - return &resource.State{ - Status: finalStatus, - Output: output, - ModuleData: mustJSON(data), - }, nil -} - -func (*firehoseDriver) Log(ctx context.Context, res module.ExpandedResource, filter map[string]string) (<-chan module.LogChunk, error) { - r := res.Resource - - var conf Config - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - - var kubeOut kubernetes.Output - if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { - return nil, err - } - - if filter == nil { - filter = make(map[string]string) - } - - hc, err := getHelmReleaseConf(r, conf) - if err != nil { - return nil, err - } - - filter["app"] = hc.Name - - kubeCl := kube.NewClient(kubeOut.Configs) - logs, err := kubeCl.StreamLogs(ctx, hc.Namespace, filter) - if err != nil { - return nil, err - } - - mappedLogs := make(chan module.LogChunk) - go func() { - defer close(mappedLogs) - for { - select { - case log, ok := <-logs: - if !ok { - return - } - mappedLogs <- module.LogChunk{Data: log.Data, Labels: log.Labels} - case <-ctx.Done(): - return - } - } - }() - - return mappedLogs, err -} - -func (m *firehoseDriver) Output(ctx context.Context, res module.ExpandedResource) (json.RawMessage, error) { - var conf Config - if err := json.Unmarshal(res.Resource.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - - var output Output - if err := json.Unmarshal(res.Resource.State.Output, &output); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid output json: %v", err) - } - - pods, err := m.podDetails(ctx, res) - if err != nil { - return nil, err - } - - hc, err := getHelmReleaseConf(res.Resource, conf) - if err != nil { - return nil, err - } +type ( + kubeDeployFn func(ctx context.Context, isCreate bool, conf kube.Config, hc helm.ReleaseConfig) error + kubeGetPodFn func(ctx context.Context, conf kube.Config, ns string, labels map[string]string) ([]kube.Pod, error) + consumerResetFn func(ctx context.Context, conf Config, out kubernetes.Output, resetTo string) error +) - return mustJSON(Output{ - Namespace: hc.Namespace, - ReleaseName: hc.Name, - Pods: pods, - Defaults: output.Defaults, - }), nil +type driverConf struct { + Telegraf map[string]any `json:"telegraf"` + Namespace string `json:"namespace" validate:"required"` + ChartValues chartValues `json:"chart_values" validate:"required"` } -func (*firehoseDriver) podDetails(ctx context.Context, res module.ExpandedResource) ([]kube.Pod, error) { - r := res.Resource - - var conf Config - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json").WithCausef(err.Error()) - } - - var kubeOut kubernetes.Output - if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { - return nil, errors.ErrInternal.WithMsgf("invalid kube out").WithCausef(err.Error()) - } - - hc, err := getHelmReleaseConf(r, conf) - if err != nil { - return nil, err - } - - kubeCl := kube.NewClient(kubeOut.Configs) - return kubeCl.GetPodDetails(ctx, hc.Namespace, map[string]string{"app": hc.Name}) +type chartValues struct { + ImageTag string `json:"image_tag" validate:"required"` + ChartVersion string `json:"chart_version" validate:"required"` + ImagePullPolicy string `json:"image_pull_policy" validate:"required"` } -func (m *firehoseDriver) planCreate(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { - var plan module.Plan - r := res.Resource - - var reqConf Config - if err := json.Unmarshal(act.Params, &reqConf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - if err := reqConf.validateAndSanitize(res.Resource); err != nil { - return nil, err - } - - output := mustJSON(Output{ - Defaults: m.Config, - }) - - r.Spec.Configs = mustJSON(reqConf) - r.State = resource.State{ - Status: resource.StatusPending, - ModuleData: mustJSON(moduleData{ - PendingSteps: []string{releaseCreate}, - }), - Output: output, - } - - plan.Resource = r - if reqConf.StopTime != nil { - plan.ScheduleRunAt = *reqConf.StopTime - } - plan.Reason = "firehose created" - return &plan, nil +type Output struct { + Pods []kube.Pod `json:"pods,omitempty"` + Namespace string `json:"namespace,omitempty"` + ReleaseName string `json:"release_name,omitempty"` } -func (m *firehoseDriver) planChange(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { - var plan module.Plan - r := res.Resource - - var conf Config - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - - switch act.Name { - case module.UpdateAction: - var reqConf Config - if err := json.Unmarshal(act.Params, &reqConf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - if err := reqConf.validateAndSanitize(r); err != nil { - return nil, err - } - conf = reqConf - - if conf.StopTime != nil { - plan.ScheduleRunAt = *conf.StopTime - } - plan.Reason = "firehose config updated" - - case ScaleAction: - var scaleParams struct { - Replicas int `json:"replicas"` - } - if err := json.Unmarshal(act.Params, &scaleParams); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - conf.Firehose.Replicas = scaleParams.Replicas - plan.Reason = "firehose scaled" - - case StartAction: - conf.State = stateRunning - plan.Reason = "firehose started" - - case StopAction: - conf.State = stateStopped - plan.Reason = "firehose stopped" - - case UpgradeAction: - var output Output - err := json.Unmarshal(res.State.Output, &output) - if err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid output json: %v", err) - } - - output.Defaults = m.Config - res.State.Output = mustJSON(output) - - plan.Reason = "firehose upgraded" - } - - r.Spec.Configs = mustJSON(conf) - r.State = resource.State{ - Status: resource.StatusPending, - Output: res.State.Output, - ModuleData: mustJSON(moduleData{ - PendingSteps: []string{releaseUpdate}, - }), - } - plan.Resource = r - return &plan, nil +type transientData struct { + PendingSteps []string `json:"pending_steps"` + ResetOffsetTo string `json:"reset_offset_to,omitempty"` } -func (*firehoseDriver) planReset(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { - r := res.Resource - - var conf Config - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - - var resetParams struct { - To string `json:"to"` - Datetime string `json:"datetime"` - } - if err := json.Unmarshal(act.Params, &resetParams); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid action params json: %v", err) - } - - resetValue := resetParams.To - if resetParams.To == "DATETIME" { - resetValue = resetParams.Datetime - } - - r.Spec.Configs = mustJSON(conf) - r.State = resource.State{ - Status: resource.StatusPending, - Output: res.State.Output, - ModuleData: mustJSON(moduleData{ - ResetTo: resetValue, - PendingSteps: []string{releaseUpdate, consumerReset, releaseUpdate}, - StateOverride: stateStopped, - }), - } - - return &module.Plan{Resource: r, Reason: "firehose consumer reset"}, nil +func (fd *firehoseDriver) getHelmRelease(conf Config) *helm.ReleaseConfig { + const ( + chartRepo = "https://odpf.github.io/charts/" + chartName = "firehose" + imageRepo = "odpf/firehose" + ) + + rc := helm.DefaultReleaseConfig() + rc.Name = conf.DeploymentID + rc.Repository = chartRepo + rc.Chart = chartName + rc.Namespace = conf.Namespace + rc.ForceUpdate = true + rc.Version = conf.ChartValues.ChartVersion + rc.Values = map[string]interface{}{ + "replicaCount": conf.Replicas, + "firehose": map[string]interface{}{ + "image": map[string]interface{}{ + "repository": imageRepo, + "pullPolicy": conf.ChartValues.ImagePullPolicy, + "tag": conf.ChartValues.ImageTag, + }, + "config": conf.EnvVariables, + }, + "telegraf": fd.conf.Telegraf, + } + return rc } -func (*firehoseDriver) releaseSync(isCreate bool, conf Config, r resource.Resource, kube kubernetes.Output) error { - helmCl := helm.NewClient(&helm.Config{Kubernetes: kube.Configs}) - - if conf.State == stateStopped || (conf.StopTime != nil && conf.StopTime.Before(time.Now())) { - conf.Firehose.Replicas = 0 - } - - hc, err := getHelmReleaseConf(r, conf) - if err != nil { - return err - } - - var helmErr error - if isCreate { - _, helmErr = helmCl.Create(hc) - } else { - _, helmErr = helmCl.Update(hc) +func readOutputData(exr module.ExpandedResource) (*Output, error) { + var curOut Output + if err := json.Unmarshal(exr.Resource.State.Output, &curOut); err != nil { + return nil, errors.ErrInternal.WithMsgf("corrupted output").WithCausef(err.Error()) } - - return helmErr + return &curOut, nil } -func (*firehoseDriver) consumerReset(ctx context.Context, conf Config, r resource.Resource, resetTo string, out kubernetes.Output) error { - releaseConfig, err := getHelmReleaseConf(r, conf) - if err != nil { - return err +func readTransientData(exr module.ExpandedResource) (*transientData, error) { + if len(exr.Resource.State.ModuleData) == 0 { + return &transientData{}, nil } - cgm := kafka.NewConsumerGroupManager(conf.Firehose.KafkaBrokerAddress, kube.NewClient(out.Configs), releaseConfig.Namespace) - - switch resetTo { - case ResetToEarliest: - err = cgm.ResetOffsetToEarliest(ctx, conf.Firehose.KafkaConsumerID) - case ResetToLatest: - err = cgm.ResetOffsetToLatest(ctx, conf.Firehose.KafkaConsumerID) - default: - err = cgm.ResetOffsetToDatetime(ctx, conf.Firehose.KafkaConsumerID, resetTo) - } - - return handleErr(err) -} - -func handleErr(err error) error { - switch { - case errors.Is(err, kube.ErrJobCreationFailed): - return ErrNetwork.WithCause(err) - case errors.Is(err, kube.ErrJobNotFound): - return ErrKubeAPI.WithCause(err) - case errors.Is(err, kube.ErrJobExecutionFailed): - return ErrKubeAPI.WithCause(err) - default: - return err + var modData transientData + if err := json.Unmarshal(exr.Resource.State.ModuleData, &modData); err != nil { + return nil, errors.ErrInternal.WithMsgf("corrupted transient data").WithCausef(err.Error()) } + return &modData, nil } func mustJSON(v any) json.RawMessage { diff --git a/modules/firehose/driver_log.go b/modules/firehose/driver_log.go new file mode 100644 index 00000000..2222219b --- /dev/null +++ b/modules/firehose/driver_log.go @@ -0,0 +1,52 @@ +package firehose + +import ( + "context" + "encoding/json" + + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/modules/kubernetes" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/kube" +) + +func (*firehoseDriver) Log(ctx context.Context, res module.ExpandedResource, filter map[string]string) (<-chan module.LogChunk, error) { + conf, err := readConfig(res.Resource, res.Spec.Configs) + if err != nil { + return nil, errors.ErrInternal.WithCausef(err.Error()) + } + + if filter == nil { + filter = map[string]string{} + } + filter["app"] = conf.DeploymentID + + var kubeOut kubernetes.Output + if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { + return nil, errors.ErrInternal.WithCausef(err.Error()) + } + kubeCl := kube.NewClient(kubeOut.Configs) + + logs, err := kubeCl.StreamLogs(ctx, conf.Namespace, filter) + if err != nil { + return nil, err + } + + mappedLogs := make(chan module.LogChunk) + go func() { + defer close(mappedLogs) + for { + select { + case log, ok := <-logs: + if !ok { + return + } + mappedLogs <- module.LogChunk{Data: log.Data, Labels: log.Labels} + case <-ctx.Done(): + return + } + } + }() + + return mappedLogs, err +} diff --git a/modules/firehose/driver_output.go b/modules/firehose/driver_output.go new file mode 100644 index 00000000..24e12dc6 --- /dev/null +++ b/modules/firehose/driver_output.go @@ -0,0 +1,42 @@ +package firehose + +import ( + "context" + "encoding/json" + + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/modules/kubernetes" + "github.com/goto/entropy/pkg/errors" +) + +func (fd *firehoseDriver) Output(ctx context.Context, exr module.ExpandedResource) (json.RawMessage, error) { + output, err := readOutputData(exr) + if err != nil { + return nil, err + } + + conf, err := readConfig(exr.Resource, exr.Spec.Configs) + if err != nil { + return nil, errors.ErrInternal.WithCausef(err.Error()) + } + + var kubeOut kubernetes.Output + if err := json.Unmarshal(exr.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { + return nil, errors.ErrInternal.WithMsgf("invalid kube state").WithCausef(err.Error()) + } + + return fd.refreshOutput(ctx, *conf, *output, kubeOut) +} + +func (fd *firehoseDriver) refreshOutput(ctx context.Context, + conf Config, output Output, kubeOut kubernetes.Output, +) (json.RawMessage, error) { + rc := fd.getHelmRelease(conf) + pods, err := fd.kubeGetPod(ctx, kubeOut.Configs, rc.Namespace, map[string]string{"app": rc.Name}) + if err != nil { + return nil, errors.ErrInternal.WithCausef(err.Error()) + } + output.Pods = pods + + return mustJSON(output), nil +} diff --git a/modules/firehose/driver_output_test.go b/modules/firehose/driver_output_test.go new file mode 100644 index 00000000..ddcd0b19 --- /dev/null +++ b/modules/firehose/driver_output_test.go @@ -0,0 +1,143 @@ +package firehose + +import ( + "context" + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/kube" +) + +func TestFirehoseDriver_Output(t *testing.T) { + t.Parallel() + + table := []struct { + title string + kubeGetPod func(t *testing.T) kubeGetPodFn + exr module.ExpandedResource + want json.RawMessage + wantErr error + }{ + { + title: "InvalidModuleData", + exr: module.ExpandedResource{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + State: resource.State{}, + }, + }, + wantErr: errors.ErrInternal, + }, + { + title: "InvalidOutput", + exr: module.ExpandedResource{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + State: resource.State{ + ModuleData: mustJSON(transientData{}), + }, + }, + }, + wantErr: errors.ErrInternal, + }, + { + title: "InvalidConfig", + exr: module.ExpandedResource{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + State: resource.State{ + Output: mustJSON(Output{}), + ModuleData: mustJSON(transientData{}), + }, + }, + }, + wantErr: errors.ErrInternal, + }, + { + title: "GetPod_Failure", + exr: sampleResourceWithState(resource.State{ + Status: resource.StatusCompleted, + Output: mustJSON(Output{}), + }), + kubeGetPod: func(t *testing.T) kubeGetPodFn { + t.Helper() + return func(ctx context.Context, conf kube.Config, ns string, labels map[string]string) ([]kube.Pod, error) { + assert.Equal(t, ns, "firehose") + assert.Equal(t, labels["app"], "firehose-foo-fh1") + return nil, errors.New("failed") + } + }, + wantErr: errors.ErrInternal, + }, + { + title: "GetPod_Success", + exr: sampleResourceWithState(resource.State{ + Status: resource.StatusCompleted, + Output: mustJSON(Output{ + Pods: nil, + Namespace: "firehose", + ReleaseName: "foo-bar", + }), + }), + kubeGetPod: func(t *testing.T) kubeGetPodFn { + t.Helper() + return func(ctx context.Context, conf kube.Config, ns string, labels map[string]string) ([]kube.Pod, error) { + assert.Equal(t, ns, "firehose") + assert.Equal(t, labels["app"], "firehose-foo-fh1") + return []kube.Pod{ + { + Name: "foo-1", + Containers: []string{"firehose"}, + }, + }, nil + } + }, + want: mustJSON(Output{ + Pods: []kube.Pod{ + { + Name: "foo-1", + Containers: []string{"firehose"}, + }, + }, + Namespace: "firehose", + ReleaseName: "foo-bar", + }), + }, + } + + for _, tt := range table { + t.Run(tt.title, func(t *testing.T) { + fd := &firehoseDriver{ + conf: defaultDriverConf, + } + if tt.kubeGetPod != nil { + fd.kubeGetPod = tt.kubeGetPod(t) + } + + got, err := fd.Output(context.Background(), tt.exr) + if tt.wantErr != nil { + require.Error(t, err) + assert.True(t, errors.Is(err, tt.wantErr), "wantErr=%v\ngotErr=%v", tt.wantErr, err) + } else { + assert.NoError(t, err) + require.NotNil(t, got) + assert.JSONEq(t, string(tt.want), string(got)) + } + }) + } +} diff --git a/modules/firehose/driver_plan.go b/modules/firehose/driver_plan.go new file mode 100644 index 00000000..0d93b8a2 --- /dev/null +++ b/modules/firehose/driver_plan.go @@ -0,0 +1,139 @@ +package firehose + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/kafka" +) + +func (fd *firehoseDriver) Plan(_ context.Context, exr module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { + switch act.Name { + case module.CreateAction: + return fd.planCreate(exr, act) + + case ResetAction: + return fd.planReset(exr, act) + + default: + return fd.planChange(exr, act) + } +} + +func (fd *firehoseDriver) planChange(exr module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { + curConf, err := readConfig(exr.Resource, exr.Resource.Spec.Configs) + if err != nil { + return nil, err + } + + enqueueSteps := []string{stepReleaseUpdate} + switch act.Name { + case module.UpdateAction: + newConf, err := readConfig(exr.Resource, act.Params) + if err != nil { + return nil, err + } + + // restore configs that are not user-controlled. + newConf.DeploymentID = curConf.DeploymentID + newConf.ChartValues = curConf.ChartValues + newConf.Namespace = curConf.Namespace + newConf.Telegraf = curConf.Telegraf + + curConf = newConf + + case ScaleAction: + var scaleParams struct { + Replicas int `json:"replicas"` + } + if err := json.Unmarshal(act.Params, &scaleParams); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid params for scale action").WithCausef(err.Error()) + } else if scaleParams.Replicas < 1 { + return nil, errors.ErrInvalid.WithMsgf("replicas must be >= 1") + } + + curConf.Replicas = scaleParams.Replicas + + case StartAction: + // nothing to do here since stepReleaseUpdate will automatically + // start the firehose with last known value of 'replicas'. + + case StopAction: + enqueueSteps = []string{stepReleaseStop} + + case UpgradeAction: + // upgrade the chart values to the latest project-level config. + curConf.ChartValues = &fd.conf.ChartValues + } + + exr.Resource.Spec.Configs = mustJSON(curConf) + exr.Resource.State = resource.State{ + Status: resource.StatusPending, + Output: exr.Resource.State.Output, + ModuleData: mustJSON(transientData{ + PendingSteps: enqueueSteps, + }), + } + + return &module.Plan{ + Reason: fmt.Sprintf("firehose_%s", act.Name), + Resource: exr.Resource, + }, nil +} + +func (fd *firehoseDriver) planCreate(exr module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { + conf, err := readConfig(exr.Resource, act.Params) + if err != nil { + return nil, err + } + + // set project defaults. + conf.Telegraf = fd.conf.Telegraf + conf.Namespace = fd.conf.Namespace + conf.ChartValues = &fd.conf.ChartValues + + exr.Resource.Spec.Configs = mustJSON(conf) + exr.Resource.State = resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{ + Namespace: conf.Namespace, + ReleaseName: conf.DeploymentID, + }), + ModuleData: mustJSON(transientData{ + PendingSteps: []string{stepReleaseCreate}, + }), + } + + return &module.Plan{ + Reason: "firehose_create", + Resource: exr.Resource, + }, nil +} + +func (*firehoseDriver) planReset(exr module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { + resetValue, err := kafka.ParseResetParams(act.Params) + if err != nil { + return nil, err + } + + exr.Resource.State = resource.State{ + Status: resource.StatusPending, + Output: exr.Resource.State.Output, + ModuleData: mustJSON(transientData{ + ResetOffsetTo: resetValue, + PendingSteps: []string{ + stepReleaseStop, + stepKafkaReset, // reset the consumer group offset value. + stepReleaseUpdate, // restart the deployment. + }, + }), + } + return &module.Plan{ + Reason: "firehose_reset", + Resource: exr.Resource, + }, nil +} diff --git a/modules/firehose/driver_plan_test.go b/modules/firehose/driver_plan_test.go new file mode 100644 index 00000000..338810f1 --- /dev/null +++ b/modules/firehose/driver_plan_test.go @@ -0,0 +1,512 @@ +package firehose + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/pkg/errors" +) + +func TestFirehoseDriver_Plan(t *testing.T) { + t.Parallel() + + table := []struct { + title string + exr module.ExpandedResource + act module.ActionRequest + want *module.Plan + wantErr error + }{ + // create action tests + { + title: "Create_InvalidParamsJSON", + exr: module.ExpandedResource{}, + act: module.ActionRequest{ + Name: module.CreateAction, + Params: []byte("{"), + }, + wantErr: errors.ErrInvalid, + }, + { + title: "Create_InvalidParamsValue", + exr: module.ExpandedResource{}, + act: module.ActionRequest{ + Name: module.CreateAction, + Params: []byte("{}"), + }, + wantErr: errors.ErrInvalid, + }, + { + title: "Create_LongName", + exr: module.ExpandedResource{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz", + Kind: "firehose", + Name: "abcdefghijklmnopqrstuvwxyz", + Project: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", + }, + }, + act: module.ActionRequest{ + Name: module.CreateAction, + Params: mustJSON(map[string]any{ + "replicas": 1, + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + want: &module.Plan{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz", + Kind: "firehose", + Name: "abcdefghijklmnopqrstuvwxyz", + Project: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "replicas": 1, + "namespace": "firehose", + "deployment_id": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099", + "telegraf": map[string]any{ + "enabled": false, + }, + "chart_values": map[string]string{ + "chart_version": "0.1.3", + "image_pull_policy": "IfNotPresent", + "image_tag": "latest", + }, + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099-0001", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{ + Namespace: "firehose", + ReleaseName: "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099", + }), + ModuleData: mustJSON(transientData{ + PendingSteps: []string{stepReleaseCreate}, + }), + }, + }, + Reason: "firehose_create", + }, + wantErr: nil, + }, + { + title: "Create_ValidRequest", + exr: module.ExpandedResource{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + }, + }, + act: module.ActionRequest{ + Name: module.CreateAction, + Params: mustJSON(map[string]any{ + "replicas": 1, + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + want: &module.Plan{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "replicas": 1, + "namespace": "firehose", + "deployment_id": "firehose-foo-fh1", + "telegraf": map[string]any{ + "enabled": false, + }, + "chart_values": map[string]string{ + "chart_version": "0.1.3", + "image_pull_policy": "IfNotPresent", + "image_tag": "latest", + }, + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{ + Namespace: "firehose", + ReleaseName: "firehose-foo-fh1", + }), + ModuleData: mustJSON(transientData{ + PendingSteps: []string{stepReleaseCreate}, + }), + }, + }, + Reason: "firehose_create", + }, + wantErr: nil, + }, + + // update action tests + { + title: "Update_Valid", + exr: module.ExpandedResource{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "replicas": 1, + "deployment_id": "firehose-deployment-x", + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusCompleted, + Output: mustJSON(Output{ + Namespace: "foo", + ReleaseName: "bar", + }), + }, + }, + }, + act: module.ActionRequest{ + Name: module.UpdateAction, + Params: mustJSON(map[string]any{ + "replicas": 10, + "env_variables": map[string]string{ + "SINK_TYPE": "HTTP", // the change being applied + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + want: &module.Plan{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "replicas": 10, + "deployment_id": "firehose-deployment-x", + "env_variables": map[string]string{ + "SINK_TYPE": "HTTP", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{ + Namespace: "foo", + ReleaseName: "bar", + }), + ModuleData: mustJSON(transientData{ + PendingSteps: []string{stepReleaseUpdate}, + }), + }, + }, + Reason: "firehose_update", + }, + wantErr: nil, + }, + + // reset action tests + { + title: "Reset_InValid", + exr: module.ExpandedResource{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "replicas": 1, + "deployment_id": "firehose-deployment-x", + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusCompleted, + Output: mustJSON(Output{ + Namespace: "foo", + ReleaseName: "bar", + }), + }, + }, + }, + act: module.ActionRequest{ + Name: ResetAction, + Params: mustJSON(map[string]any{ + "reset_to": "some_random", + }), + }, + wantErr: errors.ErrInvalid, + }, + { + title: "Reset_Valid", + exr: module.ExpandedResource{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "replicas": 1, + "deployment_id": "firehose-deployment-x", + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusCompleted, + Output: mustJSON(Output{ + Namespace: "foo", + ReleaseName: "bar", + }), + }, + }, + }, + act: module.ActionRequest{ + Name: ResetAction, + Params: mustJSON(map[string]any{ + "to": "latest", + }), + }, + want: &module.Plan{ + Reason: "firehose_reset", + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "replicas": 1, + "deployment_id": "firehose-deployment-x", + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{ + Namespace: "foo", + ReleaseName: "bar", + }), + ModuleData: mustJSON(transientData{ + ResetOffsetTo: "latest", + PendingSteps: []string{ + stepReleaseStop, + stepKafkaReset, + stepReleaseUpdate, + }, + }), + }, + }, + }, + }, + + // upgrade action tests + { + title: "Upgrade_Valid", + exr: module.ExpandedResource{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "replicas": 1, + "deployment_id": "firehose-deployment-x", + "chart_values": map[string]string{ + "chart_version": "0.1.0", + "image_pull_policy": "IfNotPresent", + "image_tag": "latest", + }, + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusCompleted, + Output: mustJSON(Output{ + Namespace: "foo", + ReleaseName: "bar", + }), + }, + }, + }, + act: module.ActionRequest{ + Name: UpgradeAction, + }, + want: &module.Plan{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "replicas": 1, + "deployment_id": "firehose-deployment-x", + "chart_values": map[string]string{ + "chart_version": "0.1.3", + "image_pull_policy": "IfNotPresent", + "image_tag": "latest", + }, + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{ + Namespace: "foo", + ReleaseName: "bar", + }), + ModuleData: mustJSON(transientData{ + PendingSteps: []string{stepReleaseUpdate}, + }), + }, + }, + Reason: "firehose_upgrade", + }, + wantErr: nil, + }, + + // scale action tests + { + title: "Scale_Invalid_params", + exr: module.ExpandedResource{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "replicas": 1, + "deployment_id": "firehose-deployment-x", + "chart_values": map[string]string{ + "chart_version": "0.1.0", + "image_pull_policy": "IfNotPresent", + "image_tag": "latest", + }, + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusCompleted, + Output: mustJSON(Output{ + Namespace: "foo", + ReleaseName: "bar", + }), + }, + }, + }, + act: module.ActionRequest{ + Name: ScaleAction, + Params: []byte("{}"), + }, + wantErr: errors.ErrInvalid, + }, + } + + for _, tt := range table { + t.Run(tt.title, func(t *testing.T) { + dr := &firehoseDriver{ + conf: defaultDriverConf, + } + + got, err := dr.Plan(context.Background(), tt.exr, tt.act) + if tt.wantErr != nil { + require.Error(t, err) + assert.Nil(t, got) + assert.True(t, errors.Is(err, tt.wantErr), "wantErr=%v\ngotErr=%v", tt.wantErr, err) + } else { + assert.NoError(t, err) + require.NotNil(t, got) + + wantJSON := string(mustJSON(tt.want)) + gotJSON := string(mustJSON(got)) + assert.JSONEq(t, wantJSON, gotJSON) + } + }) + } +} diff --git a/modules/firehose/driver_sync.go b/modules/firehose/driver_sync.go new file mode 100644 index 00000000..22f586e5 --- /dev/null +++ b/modules/firehose/driver_sync.go @@ -0,0 +1,88 @@ +package firehose + +import ( + "context" + "encoding/json" + + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/modules/kubernetes" + "github.com/goto/entropy/pkg/errors" +) + +func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) (*resource.State, error) { + modData, err := readTransientData(exr) + if err != nil { + return nil, err + } + + out, err := readOutputData(exr) + if err != nil { + return nil, errors.ErrInternal.WithCausef(err.Error()) + } + + conf, err := readConfig(exr.Resource, exr.Spec.Configs) + if err != nil { + return nil, errors.ErrInternal.WithCausef(err.Error()) + } + + var kubeOut kubernetes.Output + if err := json.Unmarshal(exr.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { + return nil, errors.ErrInternal.WithMsgf("invalid kube state").WithCausef(err.Error()) + } + + // pickup the next pending step if available. + if len(modData.PendingSteps) > 0 { + pendingStep := modData.PendingSteps[0] + modData.PendingSteps = modData.PendingSteps[1:] + + switch pendingStep { + case stepReleaseCreate, stepReleaseUpdate, stepReleaseStop: + // we want to stop the current deployment. we do this by setting + // replicas to 0. But this value will not be persisted to DB since + // config changes during Sync() are not saved. + if pendingStep == stepReleaseStop { + conf.Replicas = 0 + } + + isCreate := pendingStep == stepReleaseCreate + if err := fd.releaseSync(ctx, isCreate, *conf, kubeOut); err != nil { + return nil, err + } + + case stepKafkaReset: + if err := fd.consumerReset(ctx, *conf, kubeOut, modData.ResetOffsetTo); err != nil { + return nil, err + } + + default: + return nil, errors.ErrInternal.WithMsgf("unknown step: '%s'", pendingStep) + } + } + + finalOut, err := fd.refreshOutput(ctx, *conf, *out, kubeOut) + if err != nil { + return nil, err + } + + finalState := resource.State{ + Status: resource.StatusPending, + Output: finalOut, + ModuleData: mustJSON(modData), + } + + if len(modData.PendingSteps) == 0 { + finalState.Status = resource.StatusCompleted + finalState.ModuleData = nil + } + + return &finalState, nil +} + +func (fd *firehoseDriver) releaseSync(ctx context.Context, isCreate bool, conf Config, kubeOut kubernetes.Output) error { + rc := fd.getHelmRelease(conf) + if err := fd.kubeDeploy(ctx, isCreate, kubeOut.Configs, *rc); err != nil { + return errors.ErrInternal.WithCausef(err.Error()) + } + return nil +} diff --git a/modules/firehose/driver_sync_test.go b/modules/firehose/driver_sync_test.go new file mode 100644 index 00000000..112000b6 --- /dev/null +++ b/modules/firehose/driver_sync_test.go @@ -0,0 +1,309 @@ +package firehose + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/modules/kubernetes" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/helm" + "github.com/goto/entropy/pkg/kube" +) + +func TestFirehoseDriver_Sync(t *testing.T) { + t.Parallel() + + table := []struct { + title string + kubeDeploy func(t *testing.T) kubeDeployFn + kubeGetPod func(t *testing.T) kubeGetPodFn + + exr module.ExpandedResource + want *resource.State + wantErr error + }{ + { + title: "InvalidModuleData", + exr: module.ExpandedResource{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + State: resource.State{}, + }, + }, + wantErr: errors.ErrInternal, + }, + { + title: "InvalidOutput", + exr: module.ExpandedResource{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + State: resource.State{ + ModuleData: mustJSON(transientData{}), + }, + }, + }, + wantErr: errors.ErrInternal, + }, + { + title: "InvalidConfig", + exr: module.ExpandedResource{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + State: resource.State{ + Output: mustJSON(Output{}), + ModuleData: mustJSON(transientData{}), + }, + }, + }, + wantErr: errors.ErrInternal, + }, + { + title: "NoPendingStep", + exr: sampleResourceWithState(resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{}), + ModuleData: mustJSON(transientData{ + PendingSteps: nil, + }), + }), + kubeGetPod: func(t *testing.T) kubeGetPodFn { + t.Helper() + return func(ctx context.Context, conf kube.Config, ns string, labels map[string]string) ([]kube.Pod, error) { + assert.Equal(t, ns, "firehose") + assert.Equal(t, labels["app"], "firehose-foo-fh1") + return []kube.Pod{ + { + Name: "foo-1", + Containers: []string{"firehose"}, + }, + }, nil + } + }, + want: &resource.State{ + Status: resource.StatusCompleted, + Output: mustJSON(Output{ + Pods: []kube.Pod{ + { + Name: "foo-1", + Containers: []string{"firehose"}, + }, + }, + }), + ModuleData: nil, + }, + }, + { + title: "Sync_refresh_output_failure", + exr: sampleResourceWithState(resource.State{ + Status: resource.StatusCompleted, + Output: mustJSON(Output{}), + }), + kubeGetPod: func(t *testing.T) kubeGetPodFn { + t.Helper() + return func(ctx context.Context, conf kube.Config, ns string, labels map[string]string) ([]kube.Pod, error) { + return nil, errors.New("failed") + } + }, + wantErr: errors.ErrInternal, + }, + { + title: "Sync_release_create_failure", + exr: sampleResourceWithState(resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{}), + ModuleData: mustJSON(transientData{ + PendingSteps: []string{stepReleaseCreate}, + }), + }), + kubeDeploy: func(t *testing.T) kubeDeployFn { + t.Helper() + return func(ctx context.Context, isCreate bool, conf kube.Config, hc helm.ReleaseConfig) error { + return errors.New("failed") + } + }, + kubeGetPod: func(t *testing.T) kubeGetPodFn { + t.Helper() + return func(ctx context.Context, conf kube.Config, ns string, labels map[string]string) ([]kube.Pod, error) { + assert.Equal(t, ns, "firehose") + assert.Equal(t, labels["app"], "firehose-foo-fh1") + return []kube.Pod{ + { + Name: "foo-1", + Containers: []string{"firehose"}, + }, + }, nil + } + }, + wantErr: errors.ErrInternal, + }, + { + title: "Sync_release_create_success", + exr: sampleResourceWithState(resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{}), + ModuleData: mustJSON(transientData{ + PendingSteps: []string{stepReleaseCreate}, + }), + }), + kubeDeploy: func(t *testing.T) kubeDeployFn { + t.Helper() + return func(ctx context.Context, isCreate bool, conf kube.Config, hc helm.ReleaseConfig) error { + assert.True(t, isCreate) + assert.Equal(t, hc.Values["replicaCount"], 1) + return nil + } + }, + kubeGetPod: func(t *testing.T) kubeGetPodFn { + t.Helper() + return func(ctx context.Context, conf kube.Config, ns string, labels map[string]string) ([]kube.Pod, error) { + assert.Equal(t, ns, "firehose") + assert.Equal(t, labels["app"], "firehose-foo-fh1") + return []kube.Pod{ + { + Name: "foo-1", + Containers: []string{"firehose"}, + }, + }, nil + } + }, + want: &resource.State{ + Status: resource.StatusCompleted, + Output: mustJSON(Output{ + Pods: []kube.Pod{ + { + Name: "foo-1", + Containers: []string{"firehose"}, + }, + }, + }), + ModuleData: nil, + }, + }, + { + title: "Sync_release_stop_success", + exr: sampleResourceWithState(resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{}), + ModuleData: mustJSON(transientData{ + PendingSteps: []string{stepReleaseStop}, + }), + }), + kubeDeploy: func(t *testing.T) kubeDeployFn { + t.Helper() + return func(ctx context.Context, isCreate bool, conf kube.Config, hc helm.ReleaseConfig) error { + assert.False(t, isCreate) + assert.Equal(t, hc.Values["replicaCount"], 0) + return nil + } + }, + kubeGetPod: func(t *testing.T) kubeGetPodFn { + t.Helper() + return func(ctx context.Context, conf kube.Config, ns string, labels map[string]string) ([]kube.Pod, error) { + assert.Equal(t, ns, "firehose") + assert.Equal(t, labels["app"], "firehose-foo-fh1") + return []kube.Pod{ + { + Name: "foo-1", + Containers: []string{"firehose"}, + }, + }, nil + } + }, + want: &resource.State{ + Status: resource.StatusCompleted, + Output: mustJSON(Output{ + Pods: []kube.Pod{ + { + Name: "foo-1", + Containers: []string{"firehose"}, + }, + }, + }), + ModuleData: nil, + }, + }, + } + + for _, tt := range table { + t.Run(tt.title, func(t *testing.T) { + fd := &firehoseDriver{ + conf: defaultDriverConf, + } + + if tt.kubeGetPod != nil { + fd.kubeGetPod = tt.kubeGetPod(t) + } + + if tt.kubeDeploy != nil { + fd.kubeDeploy = tt.kubeDeploy(t) + } + + got, err := fd.Sync(context.Background(), tt.exr) + if tt.wantErr != nil { + require.Error(t, err) + assert.True(t, errors.Is(err, tt.wantErr), "wantErr=%v\ngotErr=%v", tt.wantErr, err) + } else { + assert.NoError(t, err) + require.NotNil(t, got) + + wantJSON := string(mustJSON(tt.want)) + gotJSON := string(mustJSON(got)) + assert.JSONEq(t, wantJSON, gotJSON) + } + }) + } +} + +func sampleResourceWithState(state resource.State) module.ExpandedResource { + return module.ExpandedResource{ + Resource: resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "replicas": 1, + "namespace": "firehose", + "deployment_id": "firehose-foo-fh1", + "telegraf": map[string]any{ + "enabled": false, + }, + "chart_values": map[string]string{ + "chart_version": "0.1.3", + "image_pull_policy": "IfNotPresent", + "image_tag": "latest", + }, + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: state, + }, + Dependencies: map[string]module.ResolvedDependency{ + "kube_cluster": { + Kind: "kubernetes", + Output: mustJSON(kubernetes.Output{}), + }, + }, + } +} diff --git a/modules/firehose/module.go b/modules/firehose/module.go index 64c4ab4e..2465e0ec 100644 --- a/modules/firehose/module.go +++ b/modules/firehose/module.go @@ -1,34 +1,31 @@ package firehose import ( + "context" _ "embed" "encoding/json" + "time" "github.com/goto/entropy/core/module" "github.com/goto/entropy/modules/kubernetes" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/helm" + "github.com/goto/entropy/pkg/kafka" + "github.com/goto/entropy/pkg/kube" + "github.com/goto/entropy/pkg/validator" + "github.com/goto/entropy/pkg/worker" ) const ( - StopAction = "stop" - StartAction = "start" + keyKubeDependency = "kube_cluster" + ScaleAction = "scale" + StartAction = "start" + StopAction = "stop" ResetAction = "reset" UpgradeAction = "upgrade" ) -const keyKubeDependency = "kube_cluster" - -var ( - //go:embed schema/config.json - completeConfigSchema string - - //go:embed schema/scale.json - scaleActionSchema string - - //go:embed schema/reset.json - resetActionSchema string -) - var Module = module.Descriptor{ Kind: "firehose", Dependencies: map[string]string{ @@ -37,55 +34,93 @@ var Module = module.Descriptor{ Actions: []module.ActionDesc{ { Name: module.CreateAction, - Description: "Creates firehose instance.", - ParamSchema: completeConfigSchema, + Description: "Creates a new firehose", }, { Name: module.UpdateAction, - Description: "Updates an existing firehose instance.", - ParamSchema: completeConfigSchema, + Description: "Update all configurations of firehose", }, { - Name: ScaleAction, - Description: "Scale-up or scale-down an existing firehose instance.", - ParamSchema: scaleActionSchema, + Name: ResetAction, + Description: "Stop firehose, reset consumer group, restart", }, { Name: StopAction, - Description: "Stop firehose and all its components.", + Description: "Stop all replicas of this firehose.", }, { Name: StartAction, - Description: "Start firehose and all its components.", + Description: "Start the firehose if it is currently stopped.", }, { - Name: ResetAction, - Description: "Reset firehose kafka consumer group to given timestamp", - ParamSchema: resetActionSchema, + Name: ScaleAction, + Description: "Scale the number of replicas to given number.", }, { Name: UpgradeAction, - Description: "Upgrade firehose to current stable version", + Description: "Upgrade firehose version", }, }, - DriverFactory: func(conf json.RawMessage) (module.Driver, error) { - driverCfg := driverConfig{ - ChartRepository: "https://odpf.github.io/charts/", - ChartName: "firehose", - ChartVersion: "0.1.3", - ImageRepository: "gotocompany/firehose", - ImageName: "firehose", - ImageTag: "latest", - Namespace: "firehose", - ImagePullPolicy: "IfNotPresent", - } - - if err := json.Unmarshal(conf, &driverCfg); err != nil { + DriverFactory: func(confJSON json.RawMessage) (module.Driver, error) { + conf := defaultDriverConf // clone the default value + if err := json.Unmarshal(confJSON, &conf); err != nil { + return nil, err + } else if err := validator.TaggedStruct(conf); err != nil { return nil, err } return &firehoseDriver{ - Config: driverCfg, + conf: conf, + kubeDeploy: func(_ context.Context, isCreate bool, kubeConf kube.Config, hc helm.ReleaseConfig) error { + helmCl := helm.NewClient(&helm.Config{Kubernetes: kubeConf}) + + var errHelm error + if isCreate { + _, errHelm = helmCl.Create(&hc) + } else { + _, errHelm = helmCl.Update(&hc) + } + return errHelm + }, + kubeGetPod: func(ctx context.Context, conf kube.Config, ns string, labels map[string]string) ([]kube.Pod, error) { + kubeCl := kube.NewClient(conf) + return kubeCl.GetPodDetails(ctx, ns, labels) + }, + consumerReset: consumerReset, }, nil }, } + +func consumerReset(ctx context.Context, conf Config, out kubernetes.Output, resetTo string) error { + const ( + networkErrorRetryDuration = 5 * time.Second + kubeAPIRetryBackoffDuration = 30 * time.Second + ) + + var ( + errNetwork = worker.RetryableError{RetryAfter: networkErrorRetryDuration} + errKubeAPI = worker.RetryableError{RetryAfter: kubeAPIRetryBackoffDuration} + ) + + brokerAddr := conf.EnvVariables[confKeyKafkaBrokers] + consumerID := conf.EnvVariables[confKeyConsumerID] + + err := kafka.DoReset(ctx, kube.NewClient(out.Configs), conf.Namespace, brokerAddr, consumerID, resetTo) + if err != nil { + switch { + case errors.Is(err, kube.ErrJobCreationFailed): + return errNetwork.WithCause(err) + + case errors.Is(err, kube.ErrJobNotFound): + return errKubeAPI.WithCause(err) + + case errors.Is(err, kube.ErrJobExecutionFailed): + return errKubeAPI.WithCause(err) + + default: + return err + } + } + + return nil +} diff --git a/modules/firehose/schema/config.json b/modules/firehose/schema/config.json index 9b11611c..d994c90a 100644 --- a/modules/firehose/schema/config.json +++ b/modules/firehose/schema/config.json @@ -2,217 +2,66 @@ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "http://json-schema.org/draft-07/schema#", "type": "object", + "required": [ + "replicas", + "env_variables" + ], "properties": { - "state": { - "type": "string", - "enum": [ - "RUNNING", - "STOPPED" - ], - "default": "RUNNING" - }, "stop_time": { "type": "string", "format": "date-time" }, - "firehose": { + "replicas": { + "type": "number", + "default": 1, + "minimum": 1 + }, + "deployment_id": { + "type": "string" + }, + "env_variables": { "type": "object", + "additionalProperties": true, + "required": [ + "SINK_TYPE", + "INPUT_SCHEMA_PROTO_CLASS", + "SOURCE_KAFKA_BROKERS", + "SOURCE_KAFKA_TOPIC" + ], "properties": { - "replicas": { - "type": "number", - "default": 1, - "minimum": 1 - }, - "kafka_broker_address": { + "SOURCE_KAFKA_CONSUMER_GROUP_ID": { "type": "string" }, - "kafka_topic": { + "SOURCE_KAFKA_TOPIC": { "type": "string" }, - "kafka_consumer_id": { + "SOURCE_KAFKA_BROKERS": { "type": "string" }, - "env_variables": { - "type": "object", - "properties": { - "SINK_TYPE": { - "type": "string", - "enum": [ - "LOG", - "HTTP" - ] - }, - "KAFKA_RECORD_PARSER_MODE": { - "type": "string" - }, - "INPUT_SCHEMA_PROTO_CLASS": { - "type": "string" - } - }, - "additionalProperties": { - "type": "string" - }, - "required": [ - "SINK_TYPE", - "KAFKA_RECORD_PARSER_MODE", - "INPUT_SCHEMA_PROTO_CLASS" - ], - "allOf": [ - { - "if": { - "properties": { - "SINK_TYPE": { - "const": "HTTP" - } - }, - "required": [ - "SINK_TYPE" - ] - }, - "then": { - "properties": { - "SINK_HTTP_RETRY_STATUS_CODE_RANGES": { - "type": "string" - }, - "SINK_HTTP_REQUEST_LOG_STATUS_CODE_RANGES": { - "type": "string" - }, - "SINK_HTTP_REQUEST_TIMEOUT_MS": { - "type": "number" - }, - "SINK_HTTP_REQUEST_METHOD": { - "type": "string", - "enum": [ - "put", - "post" - ] - }, - "SINK_HTTP_MAX_CONNECTIONS": { - "type": "number" - }, - "SINK_HTTP_SERVICE_URL": { - "type": "string" - }, - "SINK_HTTP_HEADERS": { - "type": "string" - }, - "SINK_HTTP_PARAMETER_SOURCE": { - "type": "string", - "enum": [ - "key", - "message", - "disabled" - ] - }, - "SINK_HTTP_DATA_FORMAT": { - "type": "string", - "enum": [ - "proto", - "json" - ] - }, - "SINK_HTTP_OAUTH2_ENABLE": { - "type": "boolean" - }, - "SINK_HTTP_OAUTH2_ACCESS_TOKEN_URL": { - "type": "string" - }, - "SINK_HTTP_OAUTH2_CLIENT_NAME": { - "type": "string" - }, - "SINK_HTTP_OAUTH2_CLIENT_SECRET": { - "type": "string" - }, - "SINK_HTTP_OAUTH2_SCOPE": { - "type": "string" - }, - "SINK_HTTP_JSON_BODY_TEMPLATE": { - "type": "string" - }, - "SINK_HTTP_PARAMETER_PLACEMENT": { - "type": "string", - "enum": [ - "query", - "header" - ] - }, - "SINK_HTTP_PARAMETER_SCHEMA_PROTO_CLASS": { - "type": "string" - } - }, - "required": [ - "SINK_HTTP_PARAMETER_SCHEMA_PROTO_CLASS", - "SINK_HTTP_PARAMETER_PLACEMENT", - "SINK_HTTP_JSON_BODY_TEMPLATE", - "SINK_HTTP_OAUTH2_SCOPE", - "SINK_HTTP_OAUTH2_CLIENT_SECRET", - "SINK_HTTP_OAUTH2_CLIENT_NAME", - "SINK_HTTP_OAUTH2_ACCESS_TOKEN_URL", - "SINK_HTTP_OAUTH2_ENABLE", - "SINK_HTTP_DATA_FORMAT", - "SINK_HTTP_PARAMETER_SOURCE", - "SINK_HTTP_HEADERS", - "SINK_HTTP_SERVICE_URL", - "SINK_HTTP_MAX_CONNECTIONS", - "SINK_HTTP_REQUEST_METHOD", - "SINK_HTTP_REQUEST_TIMEOUT_MS", - "SINK_HTTP_REQUEST_LOG_STATUS_CODE_RANGES", - "SINK_HTTP_RETRY_STATUS_CODE_RANGES" - ] - } - } + "SINK_TYPE": { + "type": "string", + "enum": [ + "LOG", + "HTTP", + "POSTGRES", + "INFLUXDB", + "ELASTIC", + "REDIS", + "GRPC", + "PROMETHEUS", + "BIGQUERY", + "BLOB", + "BIGTABLE" ] - } - }, - "required": [ - "replicas", - "env_variables", - "kafka_broker_address", - "kafka_topic", - "kafka_consumer_id" - ] - }, - "telegraf": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": false }, - "config": { - "type": "object", - "properties": { - "output": { - "type": "object", - "properties": { - "prometheus_remote_write": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": false - }, - "url": { - "type": "string" - }, - "version": { - "type": "string" - } - }, - "required": [ - "enabled", - "url", - "version" - ] - } - } - } - } + "KAFKA_RECORD_PARSER_MODE": { + "type": "string", + "default": "message" + }, + "INPUT_SCHEMA_PROTO_CLASS": { + "type": "string" } } } - }, - "required": [ - "firehose" - ] + } } \ No newline at end of file diff --git a/modules/firehoseold/driver.go b/modules/firehoseold/driver.go new file mode 100644 index 00000000..c761b5e0 --- /dev/null +++ b/modules/firehoseold/driver.go @@ -0,0 +1,428 @@ +package firehoseold + +import ( + "context" + "encoding/json" + "time" + + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/modules/kubernetes" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/helm" + "github.com/goto/entropy/pkg/kafka" + "github.com/goto/entropy/pkg/kube" + "github.com/goto/entropy/pkg/worker" +) + +const ( + networkErrorRetryDuration = 5 * time.Second + kubeAPIRetryBackoffDuration = 30 * time.Second +) + +const ( + releaseCreate = "release_create" + releaseUpdate = "release_update" + consumerReset = "consumer_reset" +) + +const ( + stateRunning = "RUNNING" + stateStopped = "STOPPED" +) + +const ( + ResetToDateTime = "DATETIME" + ResetToEarliest = "EARLIEST" + ResetToLatest = "LATEST" +) + +var ( + ErrNetwork = worker.RetryableError{RetryAfter: networkErrorRetryDuration} + ErrKubeAPI = worker.RetryableError{RetryAfter: kubeAPIRetryBackoffDuration} +) + +type driverConfig struct { + ChartRepository string `json:"chart_repository,omitempty"` + ChartName string `json:"chart_name,omitempty"` + ChartVersion string `json:"chart_version,omitempty"` + ImageRepository string `json:"image_repository,omitempty"` + ImageName string `json:"image_name,omitempty"` + ImageTag string `json:"image_tag,omitempty"` + Namespace string `json:"namespace,omitempty"` + ImagePullPolicy string `json:"image_pull_policy,omitempty"` +} + +type firehoseDriver struct { + Config driverConfig `json:"config"` +} + +func (m *firehoseDriver) Plan(_ context.Context, res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { + switch act.Name { + case module.CreateAction: + return m.planCreate(res, act) + + case ResetAction: + return m.planReset(res, act) + + default: + return m.planChange(res, act) + } +} + +func (m *firehoseDriver) Sync(ctx context.Context, res module.ExpandedResource) (*resource.State, error) { + r := res.Resource + + var data moduleData + if err := json.Unmarshal(r.State.ModuleData, &data); err != nil { + return nil, errors.ErrInternal.WithMsgf("invalid module data").WithCausef(err.Error()) + } + + var conf Config + if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json").WithCausef(err.Error()) + } + + var kubeOut kubernetes.Output + if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { + return nil, errors.ErrInternal.WithMsgf("invalid kube state").WithCausef(err.Error()) + } + + if len(data.PendingSteps) > 0 { + pendingStep := data.PendingSteps[0] + data.PendingSteps = data.PendingSteps[1:] + + switch pendingStep { + case releaseCreate, releaseUpdate: + if data.StateOverride != "" { + conf.State = data.StateOverride + } + if err := m.releaseSync(pendingStep == releaseCreate, conf, r, kubeOut); err != nil { + return nil, err + } + + case consumerReset: + if err := m.consumerReset(ctx, conf, r, data.ResetTo, kubeOut); err != nil { + return nil, err + } + data.StateOverride = "" + + default: + if err := m.releaseSync(pendingStep == releaseCreate, conf, r, kubeOut); err != nil { + return nil, err + } + } + } + + output, err := m.Output(ctx, res) + if err != nil { + return nil, err + } + + finalStatus := resource.StatusCompleted + if len(data.PendingSteps) > 0 { + finalStatus = resource.StatusPending + } + + return &resource.State{ + Status: finalStatus, + Output: output, + ModuleData: mustJSON(data), + }, nil +} + +func (*firehoseDriver) Log(ctx context.Context, res module.ExpandedResource, filter map[string]string) (<-chan module.LogChunk, error) { + r := res.Resource + + var conf Config + if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + + var kubeOut kubernetes.Output + if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { + return nil, err + } + + if filter == nil { + filter = make(map[string]string) + } + + hc, err := getHelmReleaseConf(r, conf) + if err != nil { + return nil, err + } + + filter["app"] = hc.Name + + kubeCl := kube.NewClient(kubeOut.Configs) + logs, err := kubeCl.StreamLogs(ctx, hc.Namespace, filter) + if err != nil { + return nil, err + } + + mappedLogs := make(chan module.LogChunk) + go func() { + defer close(mappedLogs) + for { + select { + case log, ok := <-logs: + if !ok { + return + } + mappedLogs <- module.LogChunk{Data: log.Data, Labels: log.Labels} + case <-ctx.Done(): + return + } + } + }() + + return mappedLogs, err +} + +func (m *firehoseDriver) Output(ctx context.Context, res module.ExpandedResource) (json.RawMessage, error) { + var conf Config + if err := json.Unmarshal(res.Resource.Spec.Configs, &conf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + + var output Output + if err := json.Unmarshal(res.Resource.State.Output, &output); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid output json: %v", err) + } + + pods, err := m.podDetails(ctx, res) + if err != nil { + return nil, err + } + + hc, err := getHelmReleaseConf(res.Resource, conf) + if err != nil { + return nil, err + } + + return mustJSON(Output{ + Namespace: hc.Namespace, + ReleaseName: hc.Name, + Pods: pods, + Defaults: output.Defaults, + }), nil +} + +func (*firehoseDriver) podDetails(ctx context.Context, res module.ExpandedResource) ([]kube.Pod, error) { + r := res.Resource + + var conf Config + if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json").WithCausef(err.Error()) + } + + var kubeOut kubernetes.Output + if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { + return nil, errors.ErrInternal.WithMsgf("invalid kube out").WithCausef(err.Error()) + } + + hc, err := getHelmReleaseConf(r, conf) + if err != nil { + return nil, err + } + + kubeCl := kube.NewClient(kubeOut.Configs) + return kubeCl.GetPodDetails(ctx, hc.Namespace, map[string]string{"app": hc.Name}) +} + +func (m *firehoseDriver) planCreate(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { + var plan module.Plan + r := res.Resource + + var reqConf Config + if err := json.Unmarshal(act.Params, &reqConf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + if err := reqConf.validateAndSanitize(res.Resource); err != nil { + return nil, err + } + + output := mustJSON(Output{ + Defaults: m.Config, + }) + + r.Spec.Configs = mustJSON(reqConf) + r.State = resource.State{ + Status: resource.StatusPending, + ModuleData: mustJSON(moduleData{ + PendingSteps: []string{releaseCreate}, + }), + Output: output, + } + + plan.Resource = r + if reqConf.StopTime != nil { + plan.ScheduleRunAt = reqConf.StopTime + } + plan.Reason = "firehose created" + return &plan, nil +} + +func (m *firehoseDriver) planChange(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { + var plan module.Plan + r := res.Resource + + var conf Config + if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + + switch act.Name { + case module.UpdateAction: + var reqConf Config + if err := json.Unmarshal(act.Params, &reqConf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + if err := reqConf.validateAndSanitize(r); err != nil { + return nil, err + } + conf = reqConf + + if conf.StopTime != nil { + plan.ScheduleRunAt = conf.StopTime + } + plan.Reason = "firehose config updated" + + case ScaleAction: + var scaleParams struct { + Replicas int `json:"replicas"` + } + if err := json.Unmarshal(act.Params, &scaleParams); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + conf.Firehose.Replicas = scaleParams.Replicas + plan.Reason = "firehose scaled" + + case StartAction: + conf.State = stateRunning + plan.Reason = "firehose started" + + case StopAction: + conf.State = stateStopped + plan.Reason = "firehose stopped" + + case UpgradeAction: + var output Output + err := json.Unmarshal(res.State.Output, &output) + if err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid output json: %v", err) + } + + output.Defaults = m.Config + res.State.Output = mustJSON(output) + + plan.Reason = "firehose upgraded" + } + + r.Spec.Configs = mustJSON(conf) + r.State = resource.State{ + Status: resource.StatusPending, + Output: res.State.Output, + ModuleData: mustJSON(moduleData{ + PendingSteps: []string{releaseUpdate}, + }), + } + plan.Resource = r + return &plan, nil +} + +func (*firehoseDriver) planReset(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { + r := res.Resource + + var conf Config + if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) + } + + var resetParams struct { + To string `json:"to"` + Datetime string `json:"datetime"` + } + if err := json.Unmarshal(act.Params, &resetParams); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid action params json: %v", err) + } + + resetValue := resetParams.To + if resetParams.To == "DATETIME" { + resetValue = resetParams.Datetime + } + + r.Spec.Configs = mustJSON(conf) + r.State = resource.State{ + Status: resource.StatusPending, + Output: res.State.Output, + ModuleData: mustJSON(moduleData{ + ResetTo: resetValue, + PendingSteps: []string{releaseUpdate, consumerReset, releaseUpdate}, + StateOverride: stateStopped, + }), + } + + return &module.Plan{Resource: r, Reason: "firehose consumer reset"}, nil +} + +func (*firehoseDriver) releaseSync(isCreate bool, conf Config, r resource.Resource, kube kubernetes.Output) error { + helmCl := helm.NewClient(&helm.Config{Kubernetes: kube.Configs}) + + if conf.State == stateStopped || (conf.StopTime != nil && conf.StopTime.Before(time.Now())) { + conf.Firehose.Replicas = 0 + } + + hc, err := getHelmReleaseConf(r, conf) + if err != nil { + return err + } + + var helmErr error + if isCreate { + _, helmErr = helmCl.Create(hc) + } else { + _, helmErr = helmCl.Update(hc) + } + + return helmErr +} + +func (*firehoseDriver) consumerReset(ctx context.Context, conf Config, r resource.Resource, resetTo string, out kubernetes.Output) error { + releaseConfig, err := getHelmReleaseConf(r, conf) + if err != nil { + return err + } + + resetErr := kafka.DoReset(ctx, + kube.NewClient(out.Configs), + releaseConfig.Namespace, + conf.Firehose.KafkaBrokerAddress, + conf.Firehose.KafkaConsumerID, + resetTo, + ) + + return handleErr(resetErr) +} + +func handleErr(err error) error { + switch { + case errors.Is(err, kube.ErrJobCreationFailed): + return ErrNetwork.WithCause(err) + case errors.Is(err, kube.ErrJobNotFound): + return ErrKubeAPI.WithCause(err) + case errors.Is(err, kube.ErrJobExecutionFailed): + return ErrKubeAPI.WithCause(err) + default: + return err + } +} + +func mustJSON(v any) json.RawMessage { + bytes, err := json.Marshal(v) + if err != nil { + panic(err) + } + return bytes +} diff --git a/modules/firehose/driver_test.go b/modules/firehoseold/driver_test.go similarity index 85% rename from modules/firehose/driver_test.go rename to modules/firehoseold/driver_test.go index e71c5e49..e9d8e6b5 100644 --- a/modules/firehose/driver_test.go +++ b/modules/firehoseold/driver_test.go @@ -1,4 +1,4 @@ -package firehose +package firehoseold import ( "context" @@ -57,7 +57,7 @@ func TestFirehoseModule_Plan(t *testing.T) { Name: "test", Project: "demo", Spec: resource.Spec{ - Configs: []byte(`{"state":"RUNNING","stop_time":null,"telegraf":null,"firehose":{"replicas":1,"kafka_broker_address":"localhost:9092","kafka_topic":"test-topic","kafka_consumer_id":"test-consumer-id","env_variables":{}}}`), + Configs: []byte(`{"state":"RUNNING","telegraf":null,"firehose":{"replicas":1,"kafka_broker_address":"localhost:9092","kafka_topic":"test-topic","kafka_consumer_id":"test-consumer-id","env_variables":{}}}`), }, State: resource.State{ Status: resource.StatusPending, @@ -91,7 +91,7 @@ func TestFirehoseModule_Plan(t *testing.T) { Name: "test", Project: "demo", Spec: resource.Spec{ - Configs: []byte(`{"state":"RUNNING","stop_time":null,"telegraf":null,"firehose":{"replicas":5,"kafka_broker_address":"localhost:9092","kafka_topic":"test-topic","kafka_consumer_id":"test-consumer-id","env_variables":{}}}`), + Configs: []byte(`{"state":"RUNNING","telegraf":null,"firehose":{"replicas":5,"kafka_broker_address":"localhost:9092","kafka_topic":"test-topic","kafka_consumer_id":"test-consumer-id","env_variables":{}}}`), }, State: resource.State{ Status: resource.StatusPending, @@ -115,7 +115,7 @@ func TestFirehoseModule_Plan(t *testing.T) { Name: "test", Project: "demo", Spec: resource.Spec{ - Configs: []byte(`{"state":"RUNNING","stop_time":null,"telegraf":null,"firehose":{"replicas":1,"kafka_broker_address":"localhost:9092","kafka_topic":"test-topic","kafka_consumer_id":"test-consumer-id","env_variables":{}}}`), + Configs: []byte(`{"state":"RUNNING","telegraf":null,"firehose":{"replicas":1,"kafka_broker_address":"localhost:9092","kafka_topic":"test-topic","kafka_consumer_id":"test-consumer-id","env_variables":{}}}`), }, State: resource.State{ Status: resource.StatusPending, @@ -165,17 +165,20 @@ func TestFirehoseModule_Plan(t *testing.T) { assert.True(t, errors.Is(err, tt.wantErr)) assert.Nil(t, got) } else { + wantJSON := mustJSON(tt.want) + gotJSON := mustJSON(got) + assert.NoError(t, err) - assert.Equal(t, tt.want, got, cmp.Diff(tt.want, got)) + assert.JSONEq(t, string(wantJSON), string(gotJSON), cmp.Diff(wantJSON, gotJSON)) } }) } } -func parseTime(timeString string) time.Time { +func parseTime(timeString string) *time.Time { t, err := time.Parse(time.RFC3339, timeString) if err != nil { panic(err) } - return t + return &t } diff --git a/modules/firehose/helm.go b/modules/firehoseold/helm.go similarity index 98% rename from modules/firehose/helm.go rename to modules/firehoseold/helm.go index 4d6747a4..69504aff 100644 --- a/modules/firehose/helm.go +++ b/modules/firehoseold/helm.go @@ -1,4 +1,4 @@ -package firehose +package firehoseold import ( "encoding/json" diff --git a/modules/firehoseold/module.go b/modules/firehoseold/module.go new file mode 100644 index 00000000..dc607baa --- /dev/null +++ b/modules/firehoseold/module.go @@ -0,0 +1,91 @@ +package firehoseold + +import ( + _ "embed" + "encoding/json" + + "github.com/goto/entropy/core/module" + "github.com/goto/entropy/modules/kubernetes" +) + +const ( + StopAction = "stop" + StartAction = "start" + ScaleAction = "scale" + ResetAction = "reset" + UpgradeAction = "upgrade" +) + +const keyKubeDependency = "kube_cluster" + +var ( + //go:embed schema/config.json + completeConfigSchema string + + //go:embed schema/scale.json + scaleActionSchema string + + //go:embed schema/reset.json + resetActionSchema string +) + +var Module = module.Descriptor{ + Kind: "firehose_old", + Dependencies: map[string]string{ + keyKubeDependency: kubernetes.Module.Kind, + }, + Actions: []module.ActionDesc{ + { + Name: module.CreateAction, + Description: "Creates firehose instance.", + ParamSchema: completeConfigSchema, + }, + { + Name: module.UpdateAction, + Description: "Updates an existing firehose instance.", + ParamSchema: completeConfigSchema, + }, + { + Name: ScaleAction, + Description: "Scale-up or scale-down an existing firehose instance.", + ParamSchema: scaleActionSchema, + }, + { + Name: StopAction, + Description: "Stop firehose and all its components.", + }, + { + Name: StartAction, + Description: "Start firehose and all its components.", + }, + { + Name: ResetAction, + Description: "Reset firehose kafka consumer group to given timestamp", + ParamSchema: resetActionSchema, + }, + { + Name: UpgradeAction, + Description: "Upgrade firehose to current stable version", + }, + }, + DriverFactory: func(conf json.RawMessage) (module.Driver, error) { + driverCfg := driverConfig{ + ChartRepository: "https://odpf.github.io/charts/", + ChartName: "firehose", + ChartVersion: "0.1.3", + ImageRepository: "gotocompany/firehose", + ImageName: "firehose", + ImageTag: "latest", + Namespace: "firehose", + ImagePullPolicy: "IfNotPresent", + } + + if err := json.Unmarshal(conf, &driverCfg); err != nil { + return nil, err + } + + return &firehoseDriver{ + Config: driverCfg, + }, nil + }, +} diff --git a/modules/firehoseold/schema/config.json b/modules/firehoseold/schema/config.json new file mode 100644 index 00000000..9b11611c --- /dev/null +++ b/modules/firehoseold/schema/config.json @@ -0,0 +1,218 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "state": { + "type": "string", + "enum": [ + "RUNNING", + "STOPPED" + ], + "default": "RUNNING" + }, + "stop_time": { + "type": "string", + "format": "date-time" + }, + "firehose": { + "type": "object", + "properties": { + "replicas": { + "type": "number", + "default": 1, + "minimum": 1 + }, + "kafka_broker_address": { + "type": "string" + }, + "kafka_topic": { + "type": "string" + }, + "kafka_consumer_id": { + "type": "string" + }, + "env_variables": { + "type": "object", + "properties": { + "SINK_TYPE": { + "type": "string", + "enum": [ + "LOG", + "HTTP" + ] + }, + "KAFKA_RECORD_PARSER_MODE": { + "type": "string" + }, + "INPUT_SCHEMA_PROTO_CLASS": { + "type": "string" + } + }, + "additionalProperties": { + "type": "string" + }, + "required": [ + "SINK_TYPE", + "KAFKA_RECORD_PARSER_MODE", + "INPUT_SCHEMA_PROTO_CLASS" + ], + "allOf": [ + { + "if": { + "properties": { + "SINK_TYPE": { + "const": "HTTP" + } + }, + "required": [ + "SINK_TYPE" + ] + }, + "then": { + "properties": { + "SINK_HTTP_RETRY_STATUS_CODE_RANGES": { + "type": "string" + }, + "SINK_HTTP_REQUEST_LOG_STATUS_CODE_RANGES": { + "type": "string" + }, + "SINK_HTTP_REQUEST_TIMEOUT_MS": { + "type": "number" + }, + "SINK_HTTP_REQUEST_METHOD": { + "type": "string", + "enum": [ + "put", + "post" + ] + }, + "SINK_HTTP_MAX_CONNECTIONS": { + "type": "number" + }, + "SINK_HTTP_SERVICE_URL": { + "type": "string" + }, + "SINK_HTTP_HEADERS": { + "type": "string" + }, + "SINK_HTTP_PARAMETER_SOURCE": { + "type": "string", + "enum": [ + "key", + "message", + "disabled" + ] + }, + "SINK_HTTP_DATA_FORMAT": { + "type": "string", + "enum": [ + "proto", + "json" + ] + }, + "SINK_HTTP_OAUTH2_ENABLE": { + "type": "boolean" + }, + "SINK_HTTP_OAUTH2_ACCESS_TOKEN_URL": { + "type": "string" + }, + "SINK_HTTP_OAUTH2_CLIENT_NAME": { + "type": "string" + }, + "SINK_HTTP_OAUTH2_CLIENT_SECRET": { + "type": "string" + }, + "SINK_HTTP_OAUTH2_SCOPE": { + "type": "string" + }, + "SINK_HTTP_JSON_BODY_TEMPLATE": { + "type": "string" + }, + "SINK_HTTP_PARAMETER_PLACEMENT": { + "type": "string", + "enum": [ + "query", + "header" + ] + }, + "SINK_HTTP_PARAMETER_SCHEMA_PROTO_CLASS": { + "type": "string" + } + }, + "required": [ + "SINK_HTTP_PARAMETER_SCHEMA_PROTO_CLASS", + "SINK_HTTP_PARAMETER_PLACEMENT", + "SINK_HTTP_JSON_BODY_TEMPLATE", + "SINK_HTTP_OAUTH2_SCOPE", + "SINK_HTTP_OAUTH2_CLIENT_SECRET", + "SINK_HTTP_OAUTH2_CLIENT_NAME", + "SINK_HTTP_OAUTH2_ACCESS_TOKEN_URL", + "SINK_HTTP_OAUTH2_ENABLE", + "SINK_HTTP_DATA_FORMAT", + "SINK_HTTP_PARAMETER_SOURCE", + "SINK_HTTP_HEADERS", + "SINK_HTTP_SERVICE_URL", + "SINK_HTTP_MAX_CONNECTIONS", + "SINK_HTTP_REQUEST_METHOD", + "SINK_HTTP_REQUEST_TIMEOUT_MS", + "SINK_HTTP_REQUEST_LOG_STATUS_CODE_RANGES", + "SINK_HTTP_RETRY_STATUS_CODE_RANGES" + ] + } + } + ] + } + }, + "required": [ + "replicas", + "env_variables", + "kafka_broker_address", + "kafka_topic", + "kafka_consumer_id" + ] + }, + "telegraf": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "config": { + "type": "object", + "properties": { + "output": { + "type": "object", + "properties": { + "prometheus_remote_write": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "url": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "enabled", + "url", + "version" + ] + } + } + } + } + } + } + } + }, + "required": [ + "firehose" + ] +} \ No newline at end of file diff --git a/modules/firehose/schema/reset.json b/modules/firehoseold/schema/reset.json similarity index 100% rename from modules/firehose/schema/reset.json rename to modules/firehoseold/schema/reset.json diff --git a/modules/firehose/schema/scale.json b/modules/firehoseold/schema/scale.json similarity index 100% rename from modules/firehose/schema/scale.json rename to modules/firehoseold/schema/scale.json diff --git a/modules/firehose/types.go b/modules/firehoseold/types.go similarity index 96% rename from modules/firehose/types.go rename to modules/firehoseold/types.go index aba1ee40..e8eef47e 100644 --- a/modules/firehose/types.go +++ b/modules/firehoseold/types.go @@ -1,4 +1,4 @@ -package firehose +package firehoseold import ( "crypto/sha256" @@ -18,10 +18,10 @@ const ( ) type Output struct { - Namespace string `json:"namespace,omitempty"` - ReleaseName string `json:"release_name,omitempty"` Pods []kube.Pod `json:"pods,omitempty"` Defaults driverConfig `json:"defaults,omitempty"` + Namespace string `json:"namespace,omitempty"` + ReleaseName string `json:"release_name,omitempty"` } type moduleData struct { @@ -32,7 +32,7 @@ type moduleData struct { type Config struct { State string `json:"state"` - StopTime *time.Time `json:"stop_time"` + StopTime *time.Time `json:"stop_time,omitempty"` Telegraf map[string]interface{} `json:"telegraf"` Firehose struct { Replicas int `json:"replicas"` diff --git a/modules/firehose/types_test.go b/modules/firehoseold/types_test.go similarity index 98% rename from modules/firehose/types_test.go rename to modules/firehoseold/types_test.go index 7e7b89c3..20659c9c 100644 --- a/modules/firehose/types_test.go +++ b/modules/firehoseold/types_test.go @@ -1,4 +1,4 @@ -package firehose +package firehoseold import ( "fmt" diff --git a/pkg/kafka/consumer.go b/pkg/kafka/consumer.go deleted file mode 100644 index ef35377c..00000000 --- a/pkg/kafka/consumer.go +++ /dev/null @@ -1,61 +0,0 @@ -package kafka - -import ( - "context" - - "github.com/goto/entropy/pkg/kube" -) - -const ( - kafkaImage = "bitnami/kafka:2.0.0" - retries = 6 -) - -type ConsumerGroupManager struct { - brokers string - kube *kube.Client - namespace string -} - -func NewConsumerGroupManager(brokers string, kube *kube.Client, namespace string) *ConsumerGroupManager { - return &ConsumerGroupManager{ - brokers: brokers, - kube: kube, - namespace: namespace, - } -} - -func (k ConsumerGroupManager) ResetOffsetToDatetime(ctx context.Context, consumerID string, datetime string) error { - return k.kube.RunJob(ctx, k.namespace, - getJobName(consumerID), - kafkaImage, - append(k.getDefaultCMD(consumerID), "--to-datetime", datetime), - retries, - ) -} - -func (k ConsumerGroupManager) ResetOffsetToLatest(ctx context.Context, consumerID string) error { - return k.kube.RunJob(ctx, k.namespace, - getJobName(consumerID), - kafkaImage, - append(k.getDefaultCMD(consumerID), "--to-latest"), - retries, - ) -} - -func (k ConsumerGroupManager) ResetOffsetToEarliest(ctx context.Context, consumerID string) error { - return k.kube.RunJob(ctx, k.namespace, - getJobName(consumerID), - kafkaImage, - append(k.getDefaultCMD(consumerID), "--to-earliest"), - retries, - ) -} - -func (k ConsumerGroupManager) getDefaultCMD(consumerID string) []string { - return []string{"kafka-consumer-groups.sh", "--bootstrap-server", k.brokers, "--group", consumerID, "--reset-offsets", "--execute", "--all-topics"} -} - -func getJobName(consumerID string) string { - return consumerID + "-reset" -} diff --git a/pkg/kafka/consumer_reset.go b/pkg/kafka/consumer_reset.go new file mode 100644 index 00000000..04a1ec1d --- /dev/null +++ b/pkg/kafka/consumer_reset.go @@ -0,0 +1,84 @@ +package kafka + +import ( + "context" + "encoding/json" + "strings" + + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/kube" +) + +const ( + kafkaImage = "bitnami/kafka:2.0.0" + retries = 6 +) + +const ( + resetLatest = "latest" + resetEarliest = "earliest" + resetDatetime = "datetime" +) + +type ResetParams struct { + To string `json:"to"` + Datetime string `json:"datetime"` +} + +// DoReset executes a kubernetes job with kafka-consumer-group.sh installed to +// reset offset policy for the given consumer id on all topics. +func DoReset(ctx context.Context, jobCluster *kube.Client, kubeNamespace, kafkaBrokers, kafkaConsumerID, kafkaResetValue string) error { + jobName := kafkaConsumerID + "-reset" + + return jobCluster.RunJob(ctx, kubeNamespace, + jobName, + kafkaImage, + prepCommand(kafkaBrokers, kafkaConsumerID, kafkaResetValue), + retries, + ) +} + +// ParseResetParams parses the given JSON data as reset parameters value and +// returns the actual reset value to be used with DoReset(). +func ParseResetParams(bytes json.RawMessage) (string, error) { + var params ResetParams + if err := json.Unmarshal(bytes, ¶ms); err != nil { + return "", errors.ErrInvalid. + WithMsgf("invalid reset params"). + WithCausef(err.Error()) + } + + resetValue := strings.ToLower(params.To) + if params.To == resetDatetime { + resetValue = params.Datetime + } else if resetValue != resetLatest && resetValue != resetEarliest { + return "", errors.ErrInvalid. + WithMsgf("reset_value must be one of %v", []string{resetEarliest, resetLatest, resetDatetime}) + } + + return resetValue, nil +} + +func prepCommand(brokers, consumerID, kafkaResetValue string) []string { + args := []string{ + "kafka-consumer-groups.sh", + "--bootstrap-server", brokers, + "--group", consumerID, + "--reset-offsets", + "--execute", + "--all-topics", + } + + switch kafkaResetValue { + case resetLatest: + args = append(args, "--to-latest") + + case resetEarliest: + args = append(args, "--to-earliest") + + default: + args = append(args, "--to-datetime", kafkaResetValue) + } + + return args +} diff --git a/pkg/validator/validator.go b/pkg/validator/validator.go new file mode 100644 index 00000000..635dd3b4 --- /dev/null +++ b/pkg/validator/validator.go @@ -0,0 +1,56 @@ +package validator + +import ( + "fmt" + "strings" + + "github.com/go-playground/validator/v10" + "github.com/xeipuuv/gojsonschema" + + "github.com/goto/entropy/pkg/errors" +) + +// FromJSONSchema returns a validator that can validate using a JSON schema. +func FromJSONSchema(schemaVal []byte) func(jsonVal []byte) error { + schema, schemaErr := gojsonschema.NewSchema(gojsonschema.NewBytesLoader(schemaVal)) + + return func(jsonVal []byte) error { + if schemaErr != nil { + return errors.ErrInternal.WithCausef(schemaErr.Error()) + } + + result, err := schema.Validate(gojsonschema.NewBytesLoader(jsonVal)) + if err != nil { + return errors.ErrInternal.WithCausef(err.Error()) + } else if !result.Valid() { + var errorStrings []string + for _, resultErr := range result.Errors() { + errorStrings = append(errorStrings, resultErr.String()) + } + errorString := strings.Join(errorStrings, "\n") + return errors.ErrInvalid.WithMsgf(errorString) + } + + return nil + } +} + +// TaggedStruct validates the given struct-value using go-validate package +// based on 'validate' tags. +func TaggedStruct(structVal any) error { + err := validator.New().Struct(structVal) + if err != nil { + var fields []string + + var valErr *validator.ValidationErrors + if errors.As(err, &valErr) { + for _, fieldError := range *valErr { + fields = append(fields, fmt.Sprintf("%s: %s", fieldError.Field(), fieldError.Tag())) + } + return errors.ErrInvalid.WithMsgf("invalid values for fields").WithCausef(strings.Join(fields, ", ")) + } else { + return errors.ErrInvalid.WithCausef(err.Error()) + } + } + return nil +} From 4b6a2385a37a973d4599d1d7e9caaf3bcb1dc566 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Tue, 21 Mar 2023 14:59:28 +0530 Subject: [PATCH 12/72] fix: use previous telegraf conf (#11) * fix: use previous telegraf conf * refactor: remove old firehose module --- .gitignore | 3 +- cli/client/client.go | 13 +- cli/client/resource.go | 57 ++-- modules/firehose/driver.go | 4 +- modules/firehoseold/driver.go | 428 ------------------------- modules/firehoseold/driver_test.go | 184 ----------- modules/firehoseold/helm.go | 53 --- modules/firehoseold/module.go | 91 ------ modules/firehoseold/schema/config.json | 218 ------------- modules/firehoseold/schema/reset.json | 29 -- modules/firehoseold/schema/scale.json | 12 - modules/firehoseold/types.go | 85 ----- modules/firehoseold/types_test.go | 47 --- 13 files changed, 39 insertions(+), 1185 deletions(-) delete mode 100644 modules/firehoseold/driver.go delete mode 100644 modules/firehoseold/driver_test.go delete mode 100644 modules/firehoseold/helm.go delete mode 100644 modules/firehoseold/module.go delete mode 100644 modules/firehoseold/schema/config.json delete mode 100644 modules/firehoseold/schema/reset.json delete mode 100644 modules/firehoseold/schema/scale.json delete mode 100644 modules/firehoseold/types.go delete mode 100644 modules/firehoseold/types_test.go diff --git a/.gitignore b/.gitignore index 4cd243d3..3e4f4add 100644 --- a/.gitignore +++ b/.gitignore @@ -26,5 +26,6 @@ expt/ entropy*.dev.yaml entropy*.dev.yml - +test_*.yml +test_*.json requests.http diff --git a/cli/client/client.go b/cli/client/client.go index 62f9be18..75cd3b19 100644 --- a/cli/client/client.go +++ b/cli/client/client.go @@ -36,14 +36,14 @@ func Command() *cobra.Command { cmd.PersistentFlags().StringP(entropyHostFlag, "E", "", "Entropy host to connect to") cmd.PersistentFlags().DurationP(dialTimeoutFlag, "T", dialTimeout, "Dial timeout") - cmd.PersistentFlags().StringP(outFormatFlag, "F", "json", "output format (json, yaml)") + cmd.PersistentFlags().StringP(outFormatFlag, "F", "pretty", "output format (json, yaml, pretty)") cmd.AddCommand( - cmdStreamLogs(), - cmdApplyAction(), cmdCreateResource(), cmdViewResource(), cmdEditResource(), + cmdStreamLogs(), + cmdApplyAction(), cmdDeleteResource(), cmdListRevisions(), ) @@ -55,13 +55,8 @@ func createClient(cmd *cobra.Command) (entropyv1beta1.ResourceServiceClient, fun dialTimeoutVal, _ := cmd.Flags().GetDuration(dialTimeoutFlag) entropyAddr, _ := cmd.Flags().GetString(entropyHostFlag) - opts := []grpc.DialOption{ - grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithBlock(), - } - dialCtx, dialCancel := context.WithTimeout(cmd.Context(), dialTimeoutVal) - conn, err := grpc.DialContext(dialCtx, entropyAddr, opts...) + conn, err := grpc.DialContext(dialCtx, entropyAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { dialCancel() return nil, nil, err diff --git a/cli/client/resource.go b/cli/client/resource.go index 17738506..6c8f2697 100644 --- a/cli/client/resource.go +++ b/cli/client/resource.go @@ -22,9 +22,6 @@ func cmdViewResource() *cobra.Command { Short: "List or View existing resource(s)", Aliases: []string{"view"}, RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - client, cancel, err := createClient(cmd) if err != nil { return err @@ -36,6 +33,8 @@ func cmdViewResource() *cobra.Command { req := entropyv1beta1.GetResourceRequest{ Urn: args[0], } + spinner := printer.Spin("Getting resource...") + defer spinner.Stop() res, err := client.GetResource(cmd.Context(), &req) if err != nil { return err @@ -58,6 +57,9 @@ func cmdViewResource() *cobra.Command { Kind: kind, Project: project, } + + spinner := printer.Spin("Listing resources...") + defer spinner.Stop() res, err := client.ListResources(cmd.Context(), &req) if err != nil { return err @@ -71,8 +73,8 @@ func cmdViewResource() *cobra.Command { for _, r := range resources { report = append(report, []string{r.Urn, r.Name, r.Kind, r.Project, r.State.Status.String()}) } - printer.Table(os.Stdout, report) _, _ = fmt.Fprintf(w, "Total: %d\n", len(report)-1) + printer.Table(os.Stdout, report) return nil }) }), @@ -88,15 +90,11 @@ func cmdCreateResource() *cobra.Command { cmd := &cobra.Command{ Use: "create ", Short: "Create a new resource on Entropy.", + Args: cobra.ExactArgs(1), RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - var reqBody entropyv1beta1.Resource if err := parseFile(args[0], &reqBody); err != nil { return err - } else if err := reqBody.ValidateAll(); err != nil { - return err } client, cancel, err := createClient(cmd) @@ -109,6 +107,8 @@ func cmdCreateResource() *cobra.Command { Resource: &reqBody, } + spinner := printer.Spin("Creating resource...") + defer spinner.Stop() res, err := client.CreateResource(cmd.Context(), req) if err != nil { return err @@ -116,7 +116,11 @@ func cmdCreateResource() *cobra.Command { spinner.Stop() resource := res.GetResource() - return Display(cmd, resource, nil) + return Display(cmd, resource, func(w io.Writer, v any) error { + _, _ = fmt.Fprintf(w, "Resource created with URN '%s'.\n", resource.Urn) + _, _ = fmt.Fprintln(w, "Use 'entropy resource get ' to view resource.") + return nil + }) }), } @@ -130,9 +134,6 @@ func cmdEditResource() *cobra.Command { Args: cobra.ExactArgs(1), Short: "Make updates to an existing resource", RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - var newSpec entropyv1beta1.ResourceSpec if err := parseFile(file, &newSpec); err != nil { return err @@ -152,6 +153,8 @@ func cmdEditResource() *cobra.Command { } defer cancel() + spinner := printer.Spin("Updating resource...") + defer spinner.Stop() resp, err := client.UpdateResource(cmd.Context(), &reqBody) if err != nil { return err @@ -161,6 +164,7 @@ func cmdEditResource() *cobra.Command { resource := resp.GetResource() return Display(cmd, resource, func(w io.Writer, _ any) error { _, _ = fmt.Fprintln(w, "Update request placed successfully.") + _, _ = fmt.Fprintln(w, "Use 'entropy resource get ' to view status.") return nil }) }), @@ -178,9 +182,6 @@ func cmdApplyAction() *cobra.Command { Short: "Apply an action on an existing resource", Aliases: []string{"execute"}, RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - var params structpb.Value if file != "" { if err := parseFile(file, ¶ms); err != nil { @@ -205,6 +206,8 @@ func cmdApplyAction() *cobra.Command { } defer cancel() + spinner := printer.Spin("Applying action...") + defer spinner.Stop() res, err := client.ApplyAction(cmd.Context(), &reqBody) if err != nil { return err @@ -212,7 +215,11 @@ func cmdApplyAction() *cobra.Command { spinner.Stop() resource := res.GetResource() - return Display(cmd, resource, nil) + return Display(cmd, resource, func(w io.Writer, v any) error { + _, _ = fmt.Fprintln(w, "Action request placed successfully.") + _, _ = fmt.Fprintln(w, "Use 'entropy resource get ' to view status.") + return nil + }) }), } @@ -229,15 +236,14 @@ func cmdDeleteResource() *cobra.Command { Short: "Delete an existing resource.", Aliases: []string{"rm", "del"}, RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - client, cancel, err := createClient(cmd) if err != nil { return err } defer cancel() + spinner := printer.Spin("Deleting resource...") + defer spinner.Stop() _, err = client.DeleteResource(cmd.Context(), &entropyv1beta1.DeleteResourceRequest{Urn: args[0]}) if err != nil { return err @@ -259,9 +265,6 @@ func cmdListRevisions() *cobra.Command { Short: "List revisions of a resource.", Aliases: []string{"revs"}, RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - var reqBody entropyv1beta1.GetResourceRevisionsRequest reqBody.Urn = args[0] @@ -272,6 +275,9 @@ func cmdListRevisions() *cobra.Command { defer cancel() req := &entropyv1beta1.GetResourceRevisionsRequest{Urn: args[0]} + + spinner := printer.Spin("Retrieving resource revisions...") + defer spinner.Stop() res, err := client.GetResourceRevisions(cmd.Context(), req) if err != nil { return err @@ -303,9 +309,6 @@ func cmdStreamLogs() *cobra.Command { Short: "Stream real-time logs for an existing resource.", Aliases: []string{"logs"}, RunE: handleErr(func(cmd *cobra.Command, args []string) error { - spinner := printer.Spin("") - defer spinner.Stop() - client, cancel, err := createClient(cmd) if err != nil { return err @@ -327,6 +330,8 @@ func cmdStreamLogs() *cobra.Command { return err } + spinner := printer.Spin("Preparing to stream logs...") + defer spinner.Stop() stream, err := client.GetLog(cmd.Context(), reqBody) if err != nil { return err diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 9c32792d..44718560 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -66,7 +66,7 @@ type transientData struct { ResetOffsetTo string `json:"reset_offset_to,omitempty"` } -func (fd *firehoseDriver) getHelmRelease(conf Config) *helm.ReleaseConfig { +func (*firehoseDriver) getHelmRelease(conf Config) *helm.ReleaseConfig { const ( chartRepo = "https://odpf.github.io/charts/" chartName = "firehose" @@ -90,7 +90,7 @@ func (fd *firehoseDriver) getHelmRelease(conf Config) *helm.ReleaseConfig { }, "config": conf.EnvVariables, }, - "telegraf": fd.conf.Telegraf, + "telegraf": conf.Telegraf, } return rc } diff --git a/modules/firehoseold/driver.go b/modules/firehoseold/driver.go deleted file mode 100644 index c761b5e0..00000000 --- a/modules/firehoseold/driver.go +++ /dev/null @@ -1,428 +0,0 @@ -package firehoseold - -import ( - "context" - "encoding/json" - "time" - - "github.com/goto/entropy/core/module" - "github.com/goto/entropy/core/resource" - "github.com/goto/entropy/modules/kubernetes" - "github.com/goto/entropy/pkg/errors" - "github.com/goto/entropy/pkg/helm" - "github.com/goto/entropy/pkg/kafka" - "github.com/goto/entropy/pkg/kube" - "github.com/goto/entropy/pkg/worker" -) - -const ( - networkErrorRetryDuration = 5 * time.Second - kubeAPIRetryBackoffDuration = 30 * time.Second -) - -const ( - releaseCreate = "release_create" - releaseUpdate = "release_update" - consumerReset = "consumer_reset" -) - -const ( - stateRunning = "RUNNING" - stateStopped = "STOPPED" -) - -const ( - ResetToDateTime = "DATETIME" - ResetToEarliest = "EARLIEST" - ResetToLatest = "LATEST" -) - -var ( - ErrNetwork = worker.RetryableError{RetryAfter: networkErrorRetryDuration} - ErrKubeAPI = worker.RetryableError{RetryAfter: kubeAPIRetryBackoffDuration} -) - -type driverConfig struct { - ChartRepository string `json:"chart_repository,omitempty"` - ChartName string `json:"chart_name,omitempty"` - ChartVersion string `json:"chart_version,omitempty"` - ImageRepository string `json:"image_repository,omitempty"` - ImageName string `json:"image_name,omitempty"` - ImageTag string `json:"image_tag,omitempty"` - Namespace string `json:"namespace,omitempty"` - ImagePullPolicy string `json:"image_pull_policy,omitempty"` -} - -type firehoseDriver struct { - Config driverConfig `json:"config"` -} - -func (m *firehoseDriver) Plan(_ context.Context, res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { - switch act.Name { - case module.CreateAction: - return m.planCreate(res, act) - - case ResetAction: - return m.planReset(res, act) - - default: - return m.planChange(res, act) - } -} - -func (m *firehoseDriver) Sync(ctx context.Context, res module.ExpandedResource) (*resource.State, error) { - r := res.Resource - - var data moduleData - if err := json.Unmarshal(r.State.ModuleData, &data); err != nil { - return nil, errors.ErrInternal.WithMsgf("invalid module data").WithCausef(err.Error()) - } - - var conf Config - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json").WithCausef(err.Error()) - } - - var kubeOut kubernetes.Output - if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { - return nil, errors.ErrInternal.WithMsgf("invalid kube state").WithCausef(err.Error()) - } - - if len(data.PendingSteps) > 0 { - pendingStep := data.PendingSteps[0] - data.PendingSteps = data.PendingSteps[1:] - - switch pendingStep { - case releaseCreate, releaseUpdate: - if data.StateOverride != "" { - conf.State = data.StateOverride - } - if err := m.releaseSync(pendingStep == releaseCreate, conf, r, kubeOut); err != nil { - return nil, err - } - - case consumerReset: - if err := m.consumerReset(ctx, conf, r, data.ResetTo, kubeOut); err != nil { - return nil, err - } - data.StateOverride = "" - - default: - if err := m.releaseSync(pendingStep == releaseCreate, conf, r, kubeOut); err != nil { - return nil, err - } - } - } - - output, err := m.Output(ctx, res) - if err != nil { - return nil, err - } - - finalStatus := resource.StatusCompleted - if len(data.PendingSteps) > 0 { - finalStatus = resource.StatusPending - } - - return &resource.State{ - Status: finalStatus, - Output: output, - ModuleData: mustJSON(data), - }, nil -} - -func (*firehoseDriver) Log(ctx context.Context, res module.ExpandedResource, filter map[string]string) (<-chan module.LogChunk, error) { - r := res.Resource - - var conf Config - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - - var kubeOut kubernetes.Output - if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { - return nil, err - } - - if filter == nil { - filter = make(map[string]string) - } - - hc, err := getHelmReleaseConf(r, conf) - if err != nil { - return nil, err - } - - filter["app"] = hc.Name - - kubeCl := kube.NewClient(kubeOut.Configs) - logs, err := kubeCl.StreamLogs(ctx, hc.Namespace, filter) - if err != nil { - return nil, err - } - - mappedLogs := make(chan module.LogChunk) - go func() { - defer close(mappedLogs) - for { - select { - case log, ok := <-logs: - if !ok { - return - } - mappedLogs <- module.LogChunk{Data: log.Data, Labels: log.Labels} - case <-ctx.Done(): - return - } - } - }() - - return mappedLogs, err -} - -func (m *firehoseDriver) Output(ctx context.Context, res module.ExpandedResource) (json.RawMessage, error) { - var conf Config - if err := json.Unmarshal(res.Resource.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - - var output Output - if err := json.Unmarshal(res.Resource.State.Output, &output); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid output json: %v", err) - } - - pods, err := m.podDetails(ctx, res) - if err != nil { - return nil, err - } - - hc, err := getHelmReleaseConf(res.Resource, conf) - if err != nil { - return nil, err - } - - return mustJSON(Output{ - Namespace: hc.Namespace, - ReleaseName: hc.Name, - Pods: pods, - Defaults: output.Defaults, - }), nil -} - -func (*firehoseDriver) podDetails(ctx context.Context, res module.ExpandedResource) ([]kube.Pod, error) { - r := res.Resource - - var conf Config - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json").WithCausef(err.Error()) - } - - var kubeOut kubernetes.Output - if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { - return nil, errors.ErrInternal.WithMsgf("invalid kube out").WithCausef(err.Error()) - } - - hc, err := getHelmReleaseConf(r, conf) - if err != nil { - return nil, err - } - - kubeCl := kube.NewClient(kubeOut.Configs) - return kubeCl.GetPodDetails(ctx, hc.Namespace, map[string]string{"app": hc.Name}) -} - -func (m *firehoseDriver) planCreate(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { - var plan module.Plan - r := res.Resource - - var reqConf Config - if err := json.Unmarshal(act.Params, &reqConf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - if err := reqConf.validateAndSanitize(res.Resource); err != nil { - return nil, err - } - - output := mustJSON(Output{ - Defaults: m.Config, - }) - - r.Spec.Configs = mustJSON(reqConf) - r.State = resource.State{ - Status: resource.StatusPending, - ModuleData: mustJSON(moduleData{ - PendingSteps: []string{releaseCreate}, - }), - Output: output, - } - - plan.Resource = r - if reqConf.StopTime != nil { - plan.ScheduleRunAt = reqConf.StopTime - } - plan.Reason = "firehose created" - return &plan, nil -} - -func (m *firehoseDriver) planChange(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { - var plan module.Plan - r := res.Resource - - var conf Config - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - - switch act.Name { - case module.UpdateAction: - var reqConf Config - if err := json.Unmarshal(act.Params, &reqConf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - if err := reqConf.validateAndSanitize(r); err != nil { - return nil, err - } - conf = reqConf - - if conf.StopTime != nil { - plan.ScheduleRunAt = conf.StopTime - } - plan.Reason = "firehose config updated" - - case ScaleAction: - var scaleParams struct { - Replicas int `json:"replicas"` - } - if err := json.Unmarshal(act.Params, &scaleParams); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - conf.Firehose.Replicas = scaleParams.Replicas - plan.Reason = "firehose scaled" - - case StartAction: - conf.State = stateRunning - plan.Reason = "firehose started" - - case StopAction: - conf.State = stateStopped - plan.Reason = "firehose stopped" - - case UpgradeAction: - var output Output - err := json.Unmarshal(res.State.Output, &output) - if err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid output json: %v", err) - } - - output.Defaults = m.Config - res.State.Output = mustJSON(output) - - plan.Reason = "firehose upgraded" - } - - r.Spec.Configs = mustJSON(conf) - r.State = resource.State{ - Status: resource.StatusPending, - Output: res.State.Output, - ModuleData: mustJSON(moduleData{ - PendingSteps: []string{releaseUpdate}, - }), - } - plan.Resource = r - return &plan, nil -} - -func (*firehoseDriver) planReset(res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { - r := res.Resource - - var conf Config - if err := json.Unmarshal(r.Spec.Configs, &conf); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid config json: %v", err) - } - - var resetParams struct { - To string `json:"to"` - Datetime string `json:"datetime"` - } - if err := json.Unmarshal(act.Params, &resetParams); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid action params json: %v", err) - } - - resetValue := resetParams.To - if resetParams.To == "DATETIME" { - resetValue = resetParams.Datetime - } - - r.Spec.Configs = mustJSON(conf) - r.State = resource.State{ - Status: resource.StatusPending, - Output: res.State.Output, - ModuleData: mustJSON(moduleData{ - ResetTo: resetValue, - PendingSteps: []string{releaseUpdate, consumerReset, releaseUpdate}, - StateOverride: stateStopped, - }), - } - - return &module.Plan{Resource: r, Reason: "firehose consumer reset"}, nil -} - -func (*firehoseDriver) releaseSync(isCreate bool, conf Config, r resource.Resource, kube kubernetes.Output) error { - helmCl := helm.NewClient(&helm.Config{Kubernetes: kube.Configs}) - - if conf.State == stateStopped || (conf.StopTime != nil && conf.StopTime.Before(time.Now())) { - conf.Firehose.Replicas = 0 - } - - hc, err := getHelmReleaseConf(r, conf) - if err != nil { - return err - } - - var helmErr error - if isCreate { - _, helmErr = helmCl.Create(hc) - } else { - _, helmErr = helmCl.Update(hc) - } - - return helmErr -} - -func (*firehoseDriver) consumerReset(ctx context.Context, conf Config, r resource.Resource, resetTo string, out kubernetes.Output) error { - releaseConfig, err := getHelmReleaseConf(r, conf) - if err != nil { - return err - } - - resetErr := kafka.DoReset(ctx, - kube.NewClient(out.Configs), - releaseConfig.Namespace, - conf.Firehose.KafkaBrokerAddress, - conf.Firehose.KafkaConsumerID, - resetTo, - ) - - return handleErr(resetErr) -} - -func handleErr(err error) error { - switch { - case errors.Is(err, kube.ErrJobCreationFailed): - return ErrNetwork.WithCause(err) - case errors.Is(err, kube.ErrJobNotFound): - return ErrKubeAPI.WithCause(err) - case errors.Is(err, kube.ErrJobExecutionFailed): - return ErrKubeAPI.WithCause(err) - default: - return err - } -} - -func mustJSON(v any) json.RawMessage { - bytes, err := json.Marshal(v) - if err != nil { - panic(err) - } - return bytes -} diff --git a/modules/firehoseold/driver_test.go b/modules/firehoseold/driver_test.go deleted file mode 100644 index e9d8e6b5..00000000 --- a/modules/firehoseold/driver_test.go +++ /dev/null @@ -1,184 +0,0 @@ -package firehoseold - -import ( - "context" - "testing" - "time" - - "github.com/google/go-cmp/cmp" - "github.com/stretchr/testify/assert" - - "github.com/goto/entropy/core/module" - "github.com/goto/entropy/core/resource" - "github.com/goto/entropy/pkg/errors" -) - -func TestFirehoseModule_Plan(t *testing.T) { - t.Parallel() - - res := resource.Resource{ - URN: "orn:entropy:firehose:test", - Kind: "firehose", - Name: "test", - Project: "demo", - Spec: resource.Spec{ - Configs: []byte(`{"state":"RUNNING","firehose":{"replicas":1,"kafka_broker_address":"localhost:9092","kafka_topic":"test-topic","kafka_consumer_id":"test-consumer-id","env_variables":{}}}`), - }, - State: resource.State{}, - } - - table := []struct { - title string - res module.ExpandedResource - act module.ActionRequest - want *module.Plan - wantErr error - }{ - { - title: "InvalidConfiguration", - res: module.ExpandedResource{Resource: res}, - act: module.ActionRequest{ - Name: module.CreateAction, - Params: []byte(`{`), - }, - wantErr: errors.ErrInvalid, - }, - { - title: "ValidConfiguration", - res: module.ExpandedResource{Resource: res}, - act: module.ActionRequest{ - Name: module.CreateAction, - Params: []byte(`{"state":"RUNNING","firehose":{"replicas":1,"kafka_broker_address":"localhost:9092","kafka_topic":"test-topic","kafka_consumer_id":"test-consumer-id","env_variables":{}}}`), - }, - want: &module.Plan{ - Resource: resource.Resource{ - URN: "orn:entropy:firehose:test", - Kind: "firehose", - Name: "test", - Project: "demo", - Spec: resource.Spec{ - Configs: []byte(`{"state":"RUNNING","telegraf":null,"firehose":{"replicas":1,"kafka_broker_address":"localhost:9092","kafka_topic":"test-topic","kafka_consumer_id":"test-consumer-id","env_variables":{}}}`), - }, - State: resource.State{ - Status: resource.StatusPending, - ModuleData: []byte(`{"pending_steps":["release_create"]}`), - Output: []byte(`{"defaults":{}}`), - }, - }, - Reason: "firehose created", - }, - }, - { - title: "InvalidActionParams", - res: module.ExpandedResource{Resource: res}, - act: module.ActionRequest{ - Name: ScaleAction, - Params: []byte(`{`), - }, - wantErr: errors.ErrInvalid, - }, - { - title: "ValidScaleRequest", - res: module.ExpandedResource{Resource: res}, - act: module.ActionRequest{ - Name: ScaleAction, - Params: []byte(`{"replicas": 5}`), - }, - want: &module.Plan{ - Resource: resource.Resource{ - URN: "orn:entropy:firehose:test", - Kind: "firehose", - Name: "test", - Project: "demo", - Spec: resource.Spec{ - Configs: []byte(`{"state":"RUNNING","telegraf":null,"firehose":{"replicas":5,"kafka_broker_address":"localhost:9092","kafka_topic":"test-topic","kafka_consumer_id":"test-consumer-id","env_variables":{}}}`), - }, - State: resource.State{ - Status: resource.StatusPending, - ModuleData: []byte(`{"pending_steps":["release_update"]}`), - }, - }, - Reason: "firehose scaled", - }, - }, - { - title: "ValidResetRequest", - res: module.ExpandedResource{Resource: res}, - act: module.ActionRequest{ - Name: ResetAction, - Params: []byte(`{"to":"DATETIME","datetime":"2022-06-22T00:00:00+00:00"}`), - }, - want: &module.Plan{ - Resource: resource.Resource{ - URN: "orn:entropy:firehose:test", - Kind: "firehose", - Name: "test", - Project: "demo", - Spec: resource.Spec{ - Configs: []byte(`{"state":"RUNNING","telegraf":null,"firehose":{"replicas":1,"kafka_broker_address":"localhost:9092","kafka_topic":"test-topic","kafka_consumer_id":"test-consumer-id","env_variables":{}}}`), - }, - State: resource.State{ - Status: resource.StatusPending, - ModuleData: []byte(`{"pending_steps":["release_update","consumer_reset","release_update"],"reset_to":"2022-06-22T00:00:00+00:00","state_override":"STOPPED"}`), - }, - }, - Reason: "firehose consumer reset", - }, - }, - { - title: "WithStopTimeConfiguration", - res: module.ExpandedResource{Resource: res}, - act: module.ActionRequest{ - Name: module.CreateAction, - Params: []byte(`{"state":"RUNNING","stop_time":"3022-07-13T00:40:14.028016Z","firehose":{"replicas":1,"kafka_broker_address":"localhost:9092","kafka_topic":"test-topic","kafka_consumer_id":"test-consumer-id","env_variables":{}}}`), - }, - want: &module.Plan{ - Resource: resource.Resource{ - URN: "orn:entropy:firehose:test", - Kind: "firehose", - Name: "test", - Project: "demo", - Spec: resource.Spec{ - Configs: []byte(`{"state":"RUNNING","stop_time":"3022-07-13T00:40:14.028016Z","telegraf":null,"firehose":{"replicas":1,"kafka_broker_address":"localhost:9092","kafka_topic":"test-topic","kafka_consumer_id":"test-consumer-id","env_variables":{}}}`), - }, - State: resource.State{ - Status: resource.StatusPending, - ModuleData: []byte(`{"pending_steps":["release_create"]}`), - Output: []byte(`{"defaults":{}}`), - }, - }, - ScheduleRunAt: parseTime("3022-07-13T00:40:14.028016Z"), - Reason: "firehose created", - }, - }, - } - - for _, tt := range table { - tt := tt - t.Run(tt.title, func(t *testing.T) { - t.Parallel() - m := firehoseDriver{} - - got, err := m.Plan(context.Background(), tt.res, tt.act) - if tt.wantErr != nil || err != nil { - assert.Error(t, err) - assert.True(t, errors.Is(err, tt.wantErr)) - assert.Nil(t, got) - } else { - wantJSON := mustJSON(tt.want) - gotJSON := mustJSON(got) - - assert.NoError(t, err) - assert.JSONEq(t, string(wantJSON), string(gotJSON), cmp.Diff(wantJSON, gotJSON)) - } - }) - } -} - -func parseTime(timeString string) *time.Time { - t, err := time.Parse(time.RFC3339, timeString) - if err != nil { - panic(err) - } - return &t -} diff --git a/modules/firehoseold/helm.go b/modules/firehoseold/helm.go deleted file mode 100644 index 69504aff..00000000 --- a/modules/firehoseold/helm.go +++ /dev/null @@ -1,53 +0,0 @@ -package firehoseold - -import ( - "encoding/json" - - "github.com/goto/entropy/core/resource" - "github.com/goto/entropy/pkg/errors" - "github.com/goto/entropy/pkg/helm" -) - -func getHelmReleaseConf(r resource.Resource, mc Config) (*helm.ReleaseConfig, error) { - var output Output - if err := json.Unmarshal(r.State.Output, &output); err != nil { - return nil, errors.ErrInvalid.WithMsgf("invalid output json: %v", err) - } - defaults := output.Defaults - - relName, err := sanitiseDeploymentID(r, mc) - if err != nil { - return nil, err - } - - rc := helm.DefaultReleaseConfig() - rc.Name = relName - rc.Repository = defaults.ChartRepository - rc.Chart = defaults.ChartName - rc.Namespace = defaults.Namespace - rc.ForceUpdate = true - rc.Version = defaults.ChartVersion - - fc := mc.Firehose - fc.EnvVariables["SOURCE_KAFKA_BROKERS"] = fc.KafkaBrokerAddress - fc.EnvVariables["SOURCE_KAFKA_TOPIC"] = fc.KafkaTopic - fc.EnvVariables["SOURCE_KAFKA_CONSUMER_GROUP_ID"] = fc.KafkaConsumerID - - hv := map[string]interface{}{ - "replicaCount": mc.Firehose.Replicas, - "firehose": map[string]interface{}{ - "image": map[string]interface{}{ - "repository": defaults.ImageRepository, - "pullPolicy": defaults.ImagePullPolicy, - "tag": defaults.ImageTag, - }, - "config": fc.EnvVariables, - }, - } - if len(mc.Telegraf) > 0 { - hv["telegraf"] = mc.Telegraf - } - rc.Values = hv - - return rc, nil -} diff --git a/modules/firehoseold/module.go b/modules/firehoseold/module.go deleted file mode 100644 index dc607baa..00000000 --- a/modules/firehoseold/module.go +++ /dev/null @@ -1,91 +0,0 @@ -package firehoseold - -import ( - _ "embed" - "encoding/json" - - "github.com/goto/entropy/core/module" - "github.com/goto/entropy/modules/kubernetes" -) - -const ( - StopAction = "stop" - StartAction = "start" - ScaleAction = "scale" - ResetAction = "reset" - UpgradeAction = "upgrade" -) - -const keyKubeDependency = "kube_cluster" - -var ( - //go:embed schema/config.json - completeConfigSchema string - - //go:embed schema/scale.json - scaleActionSchema string - - //go:embed schema/reset.json - resetActionSchema string -) - -var Module = module.Descriptor{ - Kind: "firehose_old", - Dependencies: map[string]string{ - keyKubeDependency: kubernetes.Module.Kind, - }, - Actions: []module.ActionDesc{ - { - Name: module.CreateAction, - Description: "Creates firehose instance.", - ParamSchema: completeConfigSchema, - }, - { - Name: module.UpdateAction, - Description: "Updates an existing firehose instance.", - ParamSchema: completeConfigSchema, - }, - { - Name: ScaleAction, - Description: "Scale-up or scale-down an existing firehose instance.", - ParamSchema: scaleActionSchema, - }, - { - Name: StopAction, - Description: "Stop firehose and all its components.", - }, - { - Name: StartAction, - Description: "Start firehose and all its components.", - }, - { - Name: ResetAction, - Description: "Reset firehose kafka consumer group to given timestamp", - ParamSchema: resetActionSchema, - }, - { - Name: UpgradeAction, - Description: "Upgrade firehose to current stable version", - }, - }, - DriverFactory: func(conf json.RawMessage) (module.Driver, error) { - driverCfg := driverConfig{ - ChartRepository: "https://odpf.github.io/charts/", - ChartName: "firehose", - ChartVersion: "0.1.3", - ImageRepository: "gotocompany/firehose", - ImageName: "firehose", - ImageTag: "latest", - Namespace: "firehose", - ImagePullPolicy: "IfNotPresent", - } - - if err := json.Unmarshal(conf, &driverCfg); err != nil { - return nil, err - } - - return &firehoseDriver{ - Config: driverCfg, - }, nil - }, -} diff --git a/modules/firehoseold/schema/config.json b/modules/firehoseold/schema/config.json deleted file mode 100644 index 9b11611c..00000000 --- a/modules/firehoseold/schema/config.json +++ /dev/null @@ -1,218 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "state": { - "type": "string", - "enum": [ - "RUNNING", - "STOPPED" - ], - "default": "RUNNING" - }, - "stop_time": { - "type": "string", - "format": "date-time" - }, - "firehose": { - "type": "object", - "properties": { - "replicas": { - "type": "number", - "default": 1, - "minimum": 1 - }, - "kafka_broker_address": { - "type": "string" - }, - "kafka_topic": { - "type": "string" - }, - "kafka_consumer_id": { - "type": "string" - }, - "env_variables": { - "type": "object", - "properties": { - "SINK_TYPE": { - "type": "string", - "enum": [ - "LOG", - "HTTP" - ] - }, - "KAFKA_RECORD_PARSER_MODE": { - "type": "string" - }, - "INPUT_SCHEMA_PROTO_CLASS": { - "type": "string" - } - }, - "additionalProperties": { - "type": "string" - }, - "required": [ - "SINK_TYPE", - "KAFKA_RECORD_PARSER_MODE", - "INPUT_SCHEMA_PROTO_CLASS" - ], - "allOf": [ - { - "if": { - "properties": { - "SINK_TYPE": { - "const": "HTTP" - } - }, - "required": [ - "SINK_TYPE" - ] - }, - "then": { - "properties": { - "SINK_HTTP_RETRY_STATUS_CODE_RANGES": { - "type": "string" - }, - "SINK_HTTP_REQUEST_LOG_STATUS_CODE_RANGES": { - "type": "string" - }, - "SINK_HTTP_REQUEST_TIMEOUT_MS": { - "type": "number" - }, - "SINK_HTTP_REQUEST_METHOD": { - "type": "string", - "enum": [ - "put", - "post" - ] - }, - "SINK_HTTP_MAX_CONNECTIONS": { - "type": "number" - }, - "SINK_HTTP_SERVICE_URL": { - "type": "string" - }, - "SINK_HTTP_HEADERS": { - "type": "string" - }, - "SINK_HTTP_PARAMETER_SOURCE": { - "type": "string", - "enum": [ - "key", - "message", - "disabled" - ] - }, - "SINK_HTTP_DATA_FORMAT": { - "type": "string", - "enum": [ - "proto", - "json" - ] - }, - "SINK_HTTP_OAUTH2_ENABLE": { - "type": "boolean" - }, - "SINK_HTTP_OAUTH2_ACCESS_TOKEN_URL": { - "type": "string" - }, - "SINK_HTTP_OAUTH2_CLIENT_NAME": { - "type": "string" - }, - "SINK_HTTP_OAUTH2_CLIENT_SECRET": { - "type": "string" - }, - "SINK_HTTP_OAUTH2_SCOPE": { - "type": "string" - }, - "SINK_HTTP_JSON_BODY_TEMPLATE": { - "type": "string" - }, - "SINK_HTTP_PARAMETER_PLACEMENT": { - "type": "string", - "enum": [ - "query", - "header" - ] - }, - "SINK_HTTP_PARAMETER_SCHEMA_PROTO_CLASS": { - "type": "string" - } - }, - "required": [ - "SINK_HTTP_PARAMETER_SCHEMA_PROTO_CLASS", - "SINK_HTTP_PARAMETER_PLACEMENT", - "SINK_HTTP_JSON_BODY_TEMPLATE", - "SINK_HTTP_OAUTH2_SCOPE", - "SINK_HTTP_OAUTH2_CLIENT_SECRET", - "SINK_HTTP_OAUTH2_CLIENT_NAME", - "SINK_HTTP_OAUTH2_ACCESS_TOKEN_URL", - "SINK_HTTP_OAUTH2_ENABLE", - "SINK_HTTP_DATA_FORMAT", - "SINK_HTTP_PARAMETER_SOURCE", - "SINK_HTTP_HEADERS", - "SINK_HTTP_SERVICE_URL", - "SINK_HTTP_MAX_CONNECTIONS", - "SINK_HTTP_REQUEST_METHOD", - "SINK_HTTP_REQUEST_TIMEOUT_MS", - "SINK_HTTP_REQUEST_LOG_STATUS_CODE_RANGES", - "SINK_HTTP_RETRY_STATUS_CODE_RANGES" - ] - } - } - ] - } - }, - "required": [ - "replicas", - "env_variables", - "kafka_broker_address", - "kafka_topic", - "kafka_consumer_id" - ] - }, - "telegraf": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": false - }, - "config": { - "type": "object", - "properties": { - "output": { - "type": "object", - "properties": { - "prometheus_remote_write": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": false - }, - "url": { - "type": "string" - }, - "version": { - "type": "string" - } - }, - "required": [ - "enabled", - "url", - "version" - ] - } - } - } - } - } - } - } - }, - "required": [ - "firehose" - ] -} \ No newline at end of file diff --git a/modules/firehoseold/schema/reset.json b/modules/firehoseold/schema/reset.json deleted file mode 100644 index 73f9c664..00000000 --- a/modules/firehoseold/schema/reset.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "to": { - "type": "string", - "enum": ["DATETIME", "EARLIEST", "LATEST"] - } - }, - "if": { - "properties": { - "to": { - "const": "DATETIME" - } - } - }, - "then": { - "properties": { - "datetime": { - "type": "string", - "format": "date-time" - } - } - }, - "required": [ - "to" - ] -} diff --git a/modules/firehoseold/schema/scale.json b/modules/firehoseold/schema/scale.json deleted file mode 100644 index f1ee90ff..00000000 --- a/modules/firehoseold/schema/scale.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "replicas": { - "type": "number", - "minimum": 1 - } - }, - "required": ["replicas"] -} \ No newline at end of file diff --git a/modules/firehoseold/types.go b/modules/firehoseold/types.go deleted file mode 100644 index e8eef47e..00000000 --- a/modules/firehoseold/types.go +++ /dev/null @@ -1,85 +0,0 @@ -package firehoseold - -import ( - "crypto/sha256" - _ "embed" - "fmt" - "strings" - "time" - - "github.com/goto/entropy/core/resource" - "github.com/goto/entropy/pkg/errors" - "github.com/goto/entropy/pkg/kube" -) - -const ( - kubeDeploymentNameLengthLimit = 53 - firehoseConsumerIDStartingSequence = "0001" -) - -type Output struct { - Pods []kube.Pod `json:"pods,omitempty"` - Defaults driverConfig `json:"defaults,omitempty"` - Namespace string `json:"namespace,omitempty"` - ReleaseName string `json:"release_name,omitempty"` -} - -type moduleData struct { - PendingSteps []string `json:"pending_steps"` - ResetTo string `json:"reset_to,omitempty"` - StateOverride string `json:"state_override,omitempty"` -} - -type Config struct { - State string `json:"state"` - StopTime *time.Time `json:"stop_time,omitempty"` - Telegraf map[string]interface{} `json:"telegraf"` - Firehose struct { - Replicas int `json:"replicas"` - KafkaBrokerAddress string `json:"kafka_broker_address"` - KafkaTopic string `json:"kafka_topic"` - KafkaConsumerID string `json:"kafka_consumer_id"` - EnvVariables map[string]string `json:"env_variables"` - DeploymentID string `json:"deployment_id,omitempty"` - } `json:"firehose"` -} - -func (mc *Config) validateAndSanitize(r resource.Resource) error { - if mc.StopTime != nil && mc.StopTime.Before(time.Now()) { - return errors.ErrInvalid. - WithMsgf("value for stop_time must be greater than current time") - } - - if mc.Firehose.KafkaConsumerID == "" { - mc.Firehose.KafkaConsumerID = fmt.Sprintf("%s-%s-%s-%s", - r.Project, r.Name, "-firehose-", firehoseConsumerIDStartingSequence) - } - - return nil -} - -func sanitiseDeploymentID(r resource.Resource, mc Config) (string, error) { - releaseName := mc.Firehose.DeploymentID - if len(releaseName) == 0 { - releaseName = generateSafeReleaseName(r.Project, r.Name) - } else if len(releaseName) >= kubeDeploymentNameLengthLimit { - return "", errors.ErrInvalid.WithMsgf("deployment_id must be shorter than 53 chars") - } - return releaseName, nil -} - -func generateSafeReleaseName(project, name string) string { - const prefix = "firehose-" - const randomHashLen = 6 - - releaseName := fmt.Sprintf("%s%s-%s", prefix, project, name) - if len(releaseName) >= kubeDeploymentNameLengthLimit { - releaseName = strings.Trim(releaseName[:kubeDeploymentNameLengthLimit-randomHashLen-1], "-") - - val := sha256.Sum256([]byte(releaseName)) - hash := fmt.Sprintf("%x", val) - releaseName = releaseName + "-" + hash[:randomHashLen] - } - - return releaseName -} diff --git a/modules/firehoseold/types_test.go b/modules/firehoseold/types_test.go deleted file mode 100644 index 20659c9c..00000000 --- a/modules/firehoseold/types_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package firehoseold - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/assert" -) - -func Test_generateSafeReleaseName(t *testing.T) { - t.Parallel() - - table := []struct { - project string - name string - want string - }{ - { - project: "g-pilotdata-gl", - name: "g-pilotdata-gl-test-firehose-des-4011-firehose", - want: "firehose-g-pilotdata-gl-g-pilotdata-gl-test-fi-63acaa", - }, - { - project: "abc", - name: "xyz", - want: "firehose-abc-xyz", - }, - { - project: "abcdefghijklmnopqrstuvxyz", - name: "ABCDEFGHIJKLMNOPQRSTUVXYZ", - want: "firehose-abcdefghijklmnopqrstuvxyz-ABCDEFGHIJK-0f1383", - }, - { - project: "abcdefghijklmnopqrstuvxyz", - name: "ABCDEFGHIJ-LMNOPQRSTUVXYZ", - want: "firehose-abcdefghijklmnopqrstuvxyz-ABCDEFGHIJ-c164fe", - }, - } - - for i, tt := range table { - t.Run(fmt.Sprintf("Case#%d", i), func(t *testing.T) { - got := generateSafeReleaseName(tt.project, tt.name) - assert.Equal(t, tt.want, got) - assert.True(t, len(got) <= 53) - }) - } -} From 152a191c8e25703236fe15f26ffb1dbebb2ce304 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Tue, 21 Mar 2023 17:50:24 +0530 Subject: [PATCH 13/72] fix: length validation issue (#12) --- modules/firehose/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index 4af71639..a1a70f11 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -52,7 +52,7 @@ func readConfig(r resource.Resource, confJSON json.RawMessage) (*Config, error) // note: enforce the kubernetes deployment name length limit. if len(cfg.DeploymentID) == 0 { cfg.DeploymentID = generateSafeReleaseName(r.Project, r.Name) - } else if len(cfg.DeploymentID) >= kubeDeploymentNameLengthLimit { + } else if len(cfg.DeploymentID) > kubeDeploymentNameLengthLimit { return nil, errors.ErrInvalid.WithMsgf("deployment_id must be shorter than 53 chars") } From f66d8bfbeb9832080b9190e1bc54a085c475c833 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Fri, 24 Mar 2023 11:29:24 +0530 Subject: [PATCH 14/72] fix: goreleaser commit author (#14) fix: change commit author to bot --- .goreleaser.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index a2863627..088acbc4 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -76,5 +76,5 @@ brews: install: |- bin.install "entropy" commit_author: - name: Rohil Surana - email: rohilsurana96@gmail.com + name: github-actions[bot] + email: 41898282+github-actions[bot]@users.noreply.github.com From fade8c707c3a7cb695a7e1b0e9685c00fd02d638 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Fri, 24 Mar 2023 14:08:21 +0530 Subject: [PATCH 15/72] feat: add stop flag support (#13) --- modules/firehose/config.go | 3 +++ modules/firehose/driver.go | 36 +++++++++++++++++++++++----- modules/firehose/driver_plan.go | 15 ++++++++++-- modules/firehose/driver_plan_test.go | 5 ++++ modules/firehose/driver_sync.go | 2 +- 5 files changed, 52 insertions(+), 9 deletions(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index a1a70f11..2f42f4cd 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "strings" + "time" "github.com/goto/entropy/core/resource" "github.com/goto/entropy/pkg/errors" @@ -27,6 +28,8 @@ var ( ) type Config struct { + Stopped bool `json:"stopped"` + StopTime *time.Time `json:"stop_time,omitempty"` Telegraf map[string]any `json:"telegraf,omitempty"` Replicas int `json:"replicas"` Namespace string `json:"namespace,omitempty"` diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 44718560..d01cce3b 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -3,6 +3,7 @@ package firehose import ( "context" "encoding/json" + "strings" "github.com/goto/entropy/core/module" "github.com/goto/entropy/modules/kubernetes" @@ -18,6 +19,12 @@ const ( stepKafkaReset = "consumer_reset" ) +const ( + chartRepo = "https://goto.github.io/charts/" + chartName = "firehose" + imageRepo = "gotocompany/firehose" +) + var defaultDriverConf = driverConf{ Namespace: "firehose", Telegraf: map[string]any{ @@ -67,12 +74,6 @@ type transientData struct { } func (*firehoseDriver) getHelmRelease(conf Config) *helm.ReleaseConfig { - const ( - chartRepo = "https://odpf.github.io/charts/" - chartName = "firehose" - imageRepo = "odpf/firehose" - ) - rc := helm.DefaultReleaseConfig() rc.Name = conf.DeploymentID rc.Repository = chartRepo @@ -95,6 +96,29 @@ func (*firehoseDriver) getHelmRelease(conf Config) *helm.ReleaseConfig { return rc } +func mergeChartValues(cur, newVal *chartValues) (*chartValues, error) { + if newVal == nil { + return cur, nil + } + + merged := chartValues{ + ImageTag: cur.ImageTag, + ChartVersion: cur.ChartVersion, + ImagePullPolicy: cur.ImagePullPolicy, + } + + newTag := strings.TrimSpace(newVal.ImageTag) + if newTag != "" { + if strings.Contains(newTag, ":") && !strings.HasPrefix(newTag, imageRepo) { + return nil, errors.ErrInvalid. + WithMsgf("unknown image repo: '%s', must start with '%s'", newTag, imageRepo) + } + merged.ImageTag = strings.TrimPrefix(newTag, imageRepo) + } + + return &merged, nil +} + func readOutputData(exr module.ExpandedResource) (*Output, error) { var curOut Output if err := json.Unmarshal(exr.Resource.State.Output, &curOut); err != nil { diff --git a/modules/firehose/driver_plan.go b/modules/firehose/driver_plan.go index 0d93b8a2..a5f28918 100644 --- a/modules/firehose/driver_plan.go +++ b/modules/firehose/driver_plan.go @@ -38,9 +38,14 @@ func (fd *firehoseDriver) planChange(exr module.ExpandedResource, act module.Act return nil, err } + chartVals, err := mergeChartValues(curConf.ChartValues, newConf.ChartValues) + if err != nil { + return nil, err + } + // restore configs that are not user-controlled. newConf.DeploymentID = curConf.DeploymentID - newConf.ChartValues = curConf.ChartValues + newConf.ChartValues = chartVals newConf.Namespace = curConf.Namespace newConf.Telegraf = curConf.Telegraf @@ -67,6 +72,7 @@ func (fd *firehoseDriver) planChange(exr module.ExpandedResource, act module.Act case UpgradeAction: // upgrade the chart values to the latest project-level config. + // Note: upgrade/downgrade will happen based on module-level configs. curConf.ChartValues = &fd.conf.ChartValues } @@ -91,10 +97,15 @@ func (fd *firehoseDriver) planCreate(exr module.ExpandedResource, act module.Act return nil, err } + chartVals, err := mergeChartValues(&fd.conf.ChartValues, conf.ChartValues) + if err != nil { + return nil, err + } + // set project defaults. conf.Telegraf = fd.conf.Telegraf conf.Namespace = fd.conf.Namespace - conf.ChartValues = &fd.conf.ChartValues + conf.ChartValues = chartVals exr.Resource.Spec.Configs = mustJSON(conf) exr.Resource.State = resource.State{ diff --git a/modules/firehose/driver_plan_test.go b/modules/firehose/driver_plan_test.go index 338810f1..0629aeef 100644 --- a/modules/firehose/driver_plan_test.go +++ b/modules/firehose/driver_plan_test.go @@ -71,6 +71,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { Project: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", Spec: resource.Spec{ Configs: mustJSON(map[string]any{ + "stopped": false, "replicas": 1, "namespace": "firehose", "deployment_id": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099", @@ -137,6 +138,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { Project: "foo", Spec: resource.Spec{ Configs: mustJSON(map[string]any{ + "stopped": false, "replicas": 1, "namespace": "firehose", "deployment_id": "firehose-foo-fh1", @@ -224,6 +226,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { Project: "foo", Spec: resource.Spec{ Configs: mustJSON(map[string]any{ + "stopped": false, "replicas": 10, "deployment_id": "firehose-deployment-x", "env_variables": map[string]string{ @@ -376,6 +379,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { Project: "foo", Spec: resource.Spec{ Configs: mustJSON(map[string]any{ + "stopped": false, "replicas": 1, "deployment_id": "firehose-deployment-x", "chart_values": map[string]string{ @@ -412,6 +416,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { Project: "foo", Spec: resource.Spec{ Configs: mustJSON(map[string]any{ + "stopped": false, "replicas": 1, "deployment_id": "firehose-deployment-x", "chart_values": map[string]string{ diff --git a/modules/firehose/driver_sync.go b/modules/firehose/driver_sync.go index 22f586e5..038cd18a 100644 --- a/modules/firehose/driver_sync.go +++ b/modules/firehose/driver_sync.go @@ -41,7 +41,7 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) // we want to stop the current deployment. we do this by setting // replicas to 0. But this value will not be persisted to DB since // config changes during Sync() are not saved. - if pendingStep == stepReleaseStop { + if pendingStep == stepReleaseStop || conf.Stopped { conf.Replicas = 0 } From 226fd7f56839942cff12524d8c981da39a0156f1 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Sat, 25 Mar 2023 18:16:56 +0530 Subject: [PATCH 16/72] feat: add stop flag support (#13) (#15) --- Makefile | 2 +- cli/config.go | 16 +- cli/migrate.go | 2 +- cli/serve.go | 62 +--- core/core.go | 34 +- core/core_test.go | 2 +- core/mocks/async_worker.go | 7 +- core/mocks/driver.go | 42 ++- core/mocks/loggable_module.go | 52 ++- core/mocks/module_registry.go | 14 +- core/mocks/module_service.go | 52 ++- core/mocks/module_store.go | 37 +- core/mocks/resource_store.go | 90 ++++- core/module/driver.go | 10 +- core/module/service.go | 2 +- core/read.go | 24 +- core/read_test.go | 10 +- core/resource/resource.go | 4 + core/resource/state.go | 9 + core/sync.go | 127 +++---- core/write.go | 72 ++-- core/write_test.go | 160 ++++---- internal/server/v1/mocks/module_service.go | 47 ++- internal/server/v1/mocks/resource_service.go | 77 +++- internal/store/postgres/postgres.go | 22 +- internal/store/postgres/resource_model.go | 26 +- internal/store/postgres/resource_store.go | 142 +++++++- internal/store/postgres/revision_model.go | 24 +- internal/store/postgres/revision_store.go | 122 +++---- internal/store/postgres/schema.sql | 72 ++-- modules/firehose/driver.go | 2 + modules/firehose/driver_output_test.go | 4 +- modules/firehose/driver_plan.go | 47 ++- modules/firehose/driver_plan_test.go | 362 +++++++++---------- modules/firehose/driver_sync.go | 38 +- modules/firehose/driver_sync_test.go | 32 +- modules/firehose/module.go | 3 +- modules/kubernetes/driver.go | 6 +- modules/registry_test.go | 8 +- pkg/helm/release.go | 2 - pkg/worker/mocks/job_queue.go | 12 +- 41 files changed, 1099 insertions(+), 779 deletions(-) diff --git a/Makefile b/Makefile index e5d3f9f2..a8d73626 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ tidy: install: ## install required dependencies @echo "> installing dependencies" - go install github.com/vektra/mockery/v2@v2.14.0 + go install github.com/vektra/mockery/v2@latest go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1 go get -d google.golang.org/protobuf/proto@v1.28.1 go get -d google.golang.org/grpc@v1.49.0 diff --git a/cli/config.go b/cli/config.go index f44c8802..52b320e9 100644 --- a/cli/config.go +++ b/cli/config.go @@ -20,12 +20,18 @@ const configFlag = "config" // Config contains the application configuration. type Config struct { Log logger.LogConfig `mapstructure:"log"` - Worker workerConf `mapstructure:"worker"` + Syncer syncerConf `mapstructure:"syncer"` Service serveConfig `mapstructure:"service"` PGConnStr string `mapstructure:"pg_conn_str" default:"postgres://postgres@localhost:5432/entropy?sslmode=disable"` Telemetry telemetry.Config `mapstructure:"telemetry"` } +type syncerConf struct { + SyncInterval time.Duration `mapstructure:"sync_interval" default:"1s"` + RefreshInterval time.Duration `mapstructure:"refresh_interval" default:"3s"` + ExtendLockBy time.Duration `mapstructure:"extend_lock_by" default:"5s"` +} + type serveConfig struct { Host string `mapstructure:"host" default:""` Port int `mapstructure:"port" default:"8080"` @@ -33,14 +39,6 @@ type serveConfig struct { HTTPAddr string `mapstructure:"http_addr" default:":8081"` } -type workerConf struct { - QueueName string `mapstructure:"queue_name" default:"entropy_jobs"` - QueueSpec string `mapstructure:"queue_spec" default:"postgres://postgres@localhost:5432/entropy?sslmode=disable"` - - Threads int `mapstructure:"threads" default:"1"` - PollInterval time.Duration `mapstructure:"poll_interval" default:"100ms"` -} - func (serveCfg serveConfig) httpAddr() string { return serveCfg.HTTPAddr } func (serveCfg serveConfig) grpcAddr() string { diff --git a/cli/migrate.go b/cli/migrate.go index ee0393e0..350c60d0 100644 --- a/cli/migrate.go +++ b/cli/migrate.go @@ -36,6 +36,6 @@ func cmdMigrate() *cobra.Command { } func runMigrations(ctx context.Context, zapLog *zap.Logger, cfg Config) error { - store := setupStorage(zapLog, cfg.PGConnStr) + store := setupStorage(zapLog, cfg.PGConnStr, cfg.Syncer) return store.Migrate(ctx) } diff --git a/cli/serve.go b/cli/serve.go index 855430ef..5e057bbd 100644 --- a/cli/serve.go +++ b/cli/serve.go @@ -1,7 +1,6 @@ package cli import ( - "context" "time" "github.com/newrelic/go-agent/v3/newrelic" @@ -17,8 +16,6 @@ import ( "github.com/goto/entropy/modules/kubernetes" "github.com/goto/entropy/pkg/logger" "github.com/goto/entropy/pkg/telemetry" - "github.com/goto/entropy/pkg/worker" - "github.com/goto/entropy/pkg/worker/pgq" ) func cmdServe() *cobra.Command { @@ -52,49 +49,33 @@ func cmdServe() *cobra.Command { newrelic.ConfigLicense(cfg.Telemetry.NewRelicAPIKey), ) + store := setupStorage(zapLog, cfg.PGConnStr, cfg.Syncer) + moduleService := module.NewService(setupRegistry(zapLog), store) + resourceService := core.New(store, moduleService, time.Now, zapLog) + if migrate { if migrateErr := runMigrations(cmd.Context(), zapLog, cfg); migrateErr != nil { return migrateErr } } - asyncWorker := setupWorker(zapLog, cfg.Worker) if spawnWorker { go func() { - if runErr := asyncWorker.Run(cmd.Context()); runErr != nil { - zapLog.Error("worker exited with error", zap.Error(err)) + if runErr := resourceService.RunSyncer(cmd.Context(), cfg.Syncer.SyncInterval); runErr != nil { + zapLog.Error("syncer exited with error", zap.Error(err)) } }() } - return runServer(cmd.Context(), nrApp, zapLog, cfg, asyncWorker) + return entropyserver.Serve(cmd.Context(), + cfg.Service.httpAddr(), cfg.Service.grpcAddr(), + nrApp, zapLog, resourceService, moduleService, + ) }) return cmd } -func runServer(baseCtx context.Context, nrApp *newrelic.Application, zapLog *zap.Logger, cfg Config, asyncWorker *worker.Worker) error { - ctx, cancel := context.WithCancel(baseCtx) - defer cancel() - - store := setupStorage(zapLog, cfg.PGConnStr) - moduleService := module.NewService(setupRegistry(zapLog), store) - resourceService := core.New(store, moduleService, asyncWorker, time.Now, zapLog) - - if err := asyncWorker.Register(core.JobKindSyncResource, resourceService.HandleSyncJob); err != nil { - return err - } - - if err := asyncWorker.Register(core.JobKindScheduledSyncResource, resourceService.HandleSyncJob); err != nil { - return err - } - - return entropyserver.Serve(ctx, - cfg.Service.httpAddr(), cfg.Service.grpcAddr(), - nrApp, zapLog, resourceService, moduleService, - ) -} - func setupRegistry(logger *zap.Logger) module.Registry { supported := []module.Descriptor{ kubernetes.Module, @@ -113,27 +94,8 @@ func setupRegistry(logger *zap.Logger) module.Registry { return registry } -func setupWorker(logger *zap.Logger, conf workerConf) *worker.Worker { - pgQueue, err := pgq.Open(conf.QueueSpec, conf.QueueName) - if err != nil { - logger.Fatal("failed to init postgres job-queue", zap.Error(err)) - } - - opts := []worker.Option{ - worker.WithLogger(logger.Named("worker")), - worker.WithRunConfig(conf.Threads, conf.PollInterval), - } - - asyncWorker, err := worker.New(pgQueue, opts...) - if err != nil { - logger.Fatal("failed to init worker instance", zap.Error(err)) - } - - return asyncWorker -} - -func setupStorage(logger *zap.Logger, pgConStr string) *postgres.Store { - store, err := postgres.Open(pgConStr) +func setupStorage(logger *zap.Logger, pgConStr string, syncCfg syncerConf) *postgres.Store { + store, err := postgres.Open(pgConStr, syncCfg.RefreshInterval, syncCfg.ExtendLockBy) if err != nil { logger.Fatal("failed to connect to Postgres database", zap.Error(err), zap.String("conn_str", pgConStr)) diff --git a/core/core.go b/core/core.go index e5b4c0b9..817f76ef 100644 --- a/core/core.go +++ b/core/core.go @@ -1,6 +1,5 @@ package core -//go:generate mockery --name=AsyncWorker -r --case underscore --with-expecter --structname AsyncWorker --filename=async_worker.go --output=./mocks //go:generate mockery --name=ModuleService -r --case underscore --with-expecter --structname ModuleService --filename=module_service.go --output=./mocks import ( @@ -13,50 +12,47 @@ import ( "github.com/goto/entropy/core/module" "github.com/goto/entropy/core/resource" "github.com/goto/entropy/pkg/errors" - "github.com/goto/entropy/pkg/worker" ) type Service struct { - logger *zap.Logger - clock func() time.Time - store resource.Store - worker AsyncWorker - moduleSvc ModuleService + logger *zap.Logger + clock func() time.Time + store resource.Store + moduleSvc ModuleService + syncBackoff time.Duration } type ModuleService interface { - PlanAction(ctx context.Context, res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) + PlanAction(ctx context.Context, res module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) SyncState(ctx context.Context, res module.ExpandedResource) (*resource.State, error) StreamLogs(ctx context.Context, res module.ExpandedResource, filter map[string]string) (<-chan module.LogChunk, error) GetOutput(ctx context.Context, res module.ExpandedResource) (json.RawMessage, error) } -type AsyncWorker interface { - Enqueue(ctx context.Context, jobs ...worker.Job) error -} +func New(repo resource.Store, moduleSvc ModuleService, clockFn func() time.Time, lg *zap.Logger) *Service { + const defaultSyncBackoff = 5 * time.Second -func New(repo resource.Store, moduleSvc ModuleService, asyncWorker AsyncWorker, clockFn func() time.Time, lg *zap.Logger) *Service { if clockFn == nil { clockFn = time.Now } return &Service{ - logger: lg, - clock: clockFn, - store: repo, - worker: asyncWorker, - moduleSvc: moduleSvc, + logger: lg, + clock: clockFn, + store: repo, + syncBackoff: defaultSyncBackoff, + moduleSvc: moduleSvc, } } -func (s *Service) generateModuleSpec(ctx context.Context, res resource.Resource) (*module.ExpandedResource, error) { +func (svc *Service) generateModuleSpec(ctx context.Context, res resource.Resource) (*module.ExpandedResource, error) { modSpec := module.ExpandedResource{ Resource: res, Dependencies: map[string]module.ResolvedDependency{}, } for key, resURN := range res.Spec.Dependencies { - d, err := s.GetResource(ctx, resURN) + d, err := svc.GetResource(ctx, resURN) if err != nil { if errors.Is(err, errors.ErrNotFound) { return nil, errors.ErrInvalid. diff --git a/core/core_test.go b/core/core_test.go index b891a661..54628532 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -25,6 +25,6 @@ var ( func TestNew(t *testing.T) { t.Parallel() - s := core.New(&mocks.ResourceStore{}, &mocks.ModuleService{}, &mocks.AsyncWorker{}, deadClock, nil) + s := core.New(&mocks.ResourceStore{}, &mocks.ModuleService{}, deadClock, nil) assert.NotNil(t, s) } diff --git a/core/mocks/async_worker.go b/core/mocks/async_worker.go index 2223efda..ef62e849 100644 --- a/core/mocks/async_worker.go +++ b/core/mocks/async_worker.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.23.1. DO NOT EDIT. package mocks @@ -75,6 +75,11 @@ func (_c *AsyncWorker_Enqueue_Call) Return(_a0 error) *AsyncWorker_Enqueue_Call return _c } +func (_c *AsyncWorker_Enqueue_Call) RunAndReturn(run func(context.Context, ...worker.Job) error) *AsyncWorker_Enqueue_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewAsyncWorker interface { mock.TestingT Cleanup(func()) diff --git a/core/mocks/driver.go b/core/mocks/driver.go index bd8e990d..eda11a2c 100644 --- a/core/mocks/driver.go +++ b/core/mocks/driver.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.23.1. DO NOT EDIT. package mocks @@ -31,6 +31,10 @@ func (_m *ModuleDriver) Output(ctx context.Context, res module.ExpandedResource) ret := _m.Called(ctx, res) var r0 json.RawMessage + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource) (json.RawMessage, error)); ok { + return rf(ctx, res) + } if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource) json.RawMessage); ok { r0 = rf(ctx, res) } else { @@ -39,7 +43,6 @@ func (_m *ModuleDriver) Output(ctx context.Context, res module.ExpandedResource) } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, module.ExpandedResource) error); ok { r1 = rf(ctx, res) } else { @@ -73,20 +76,28 @@ func (_c *ModuleDriver_Output_Call) Return(_a0 json.RawMessage, _a1 error) *Modu return _c } +func (_c *ModuleDriver_Output_Call) RunAndReturn(run func(context.Context, module.ExpandedResource) (json.RawMessage, error)) *ModuleDriver_Output_Call { + _c.Call.Return(run) + return _c +} + // Plan provides a mock function with given fields: ctx, res, act -func (_m *ModuleDriver) Plan(ctx context.Context, res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { +func (_m *ModuleDriver) Plan(ctx context.Context, res module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) { ret := _m.Called(ctx, res, act) - var r0 *module.Plan - if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource, module.ActionRequest) *module.Plan); ok { + var r0 *resource.Resource + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource, module.ActionRequest) (*resource.Resource, error)); ok { + return rf(ctx, res, act) + } + if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource, module.ActionRequest) *resource.Resource); ok { r0 = rf(ctx, res, act) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*module.Plan) + r0 = ret.Get(0).(*resource.Resource) } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, module.ExpandedResource, module.ActionRequest) error); ok { r1 = rf(ctx, res, act) } else { @@ -116,16 +127,25 @@ func (_c *ModuleDriver_Plan_Call) Run(run func(ctx context.Context, res module.E return _c } -func (_c *ModuleDriver_Plan_Call) Return(_a0 *module.Plan, _a1 error) *ModuleDriver_Plan_Call { +func (_c *ModuleDriver_Plan_Call) Return(_a0 *resource.Resource, _a1 error) *ModuleDriver_Plan_Call { _c.Call.Return(_a0, _a1) return _c } +func (_c *ModuleDriver_Plan_Call) RunAndReturn(run func(context.Context, module.ExpandedResource, module.ActionRequest) (*resource.Resource, error)) *ModuleDriver_Plan_Call { + _c.Call.Return(run) + return _c +} + // Sync provides a mock function with given fields: ctx, res func (_m *ModuleDriver) Sync(ctx context.Context, res module.ExpandedResource) (*resource.State, error) { ret := _m.Called(ctx, res) var r0 *resource.State + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource) (*resource.State, error)); ok { + return rf(ctx, res) + } if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource) *resource.State); ok { r0 = rf(ctx, res) } else { @@ -134,7 +154,6 @@ func (_m *ModuleDriver) Sync(ctx context.Context, res module.ExpandedResource) ( } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, module.ExpandedResource) error); ok { r1 = rf(ctx, res) } else { @@ -168,6 +187,11 @@ func (_c *ModuleDriver_Sync_Call) Return(_a0 *resource.State, _a1 error) *Module return _c } +func (_c *ModuleDriver_Sync_Call) RunAndReturn(run func(context.Context, module.ExpandedResource) (*resource.State, error)) *ModuleDriver_Sync_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewModuleDriver interface { mock.TestingT Cleanup(func()) diff --git a/core/mocks/loggable_module.go b/core/mocks/loggable_module.go index 888df706..ecd2f59f 100644 --- a/core/mocks/loggable_module.go +++ b/core/mocks/loggable_module.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.23.1. DO NOT EDIT. package mocks @@ -31,6 +31,10 @@ func (_m *LoggableModule) Log(ctx context.Context, res module.ExpandedResource, ret := _m.Called(ctx, res, filter) var r0 <-chan module.LogChunk + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource, map[string]string) (<-chan module.LogChunk, error)); ok { + return rf(ctx, res, filter) + } if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource, map[string]string) <-chan module.LogChunk); ok { r0 = rf(ctx, res, filter) } else { @@ -39,7 +43,6 @@ func (_m *LoggableModule) Log(ctx context.Context, res module.ExpandedResource, } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, module.ExpandedResource, map[string]string) error); ok { r1 = rf(ctx, res, filter) } else { @@ -74,11 +77,20 @@ func (_c *LoggableModule_Log_Call) Return(_a0 <-chan module.LogChunk, _a1 error) return _c } +func (_c *LoggableModule_Log_Call) RunAndReturn(run func(context.Context, module.ExpandedResource, map[string]string) (<-chan module.LogChunk, error)) *LoggableModule_Log_Call { + _c.Call.Return(run) + return _c +} + // Output provides a mock function with given fields: ctx, res func (_m *LoggableModule) Output(ctx context.Context, res module.ExpandedResource) (json.RawMessage, error) { ret := _m.Called(ctx, res) var r0 json.RawMessage + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource) (json.RawMessage, error)); ok { + return rf(ctx, res) + } if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource) json.RawMessage); ok { r0 = rf(ctx, res) } else { @@ -87,7 +99,6 @@ func (_m *LoggableModule) Output(ctx context.Context, res module.ExpandedResourc } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, module.ExpandedResource) error); ok { r1 = rf(ctx, res) } else { @@ -121,20 +132,28 @@ func (_c *LoggableModule_Output_Call) Return(_a0 json.RawMessage, _a1 error) *Lo return _c } +func (_c *LoggableModule_Output_Call) RunAndReturn(run func(context.Context, module.ExpandedResource) (json.RawMessage, error)) *LoggableModule_Output_Call { + _c.Call.Return(run) + return _c +} + // Plan provides a mock function with given fields: ctx, res, act -func (_m *LoggableModule) Plan(ctx context.Context, res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { +func (_m *LoggableModule) Plan(ctx context.Context, res module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) { ret := _m.Called(ctx, res, act) - var r0 *module.Plan - if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource, module.ActionRequest) *module.Plan); ok { + var r0 *resource.Resource + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource, module.ActionRequest) (*resource.Resource, error)); ok { + return rf(ctx, res, act) + } + if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource, module.ActionRequest) *resource.Resource); ok { r0 = rf(ctx, res, act) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*module.Plan) + r0 = ret.Get(0).(*resource.Resource) } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, module.ExpandedResource, module.ActionRequest) error); ok { r1 = rf(ctx, res, act) } else { @@ -164,16 +183,25 @@ func (_c *LoggableModule_Plan_Call) Run(run func(ctx context.Context, res module return _c } -func (_c *LoggableModule_Plan_Call) Return(_a0 *module.Plan, _a1 error) *LoggableModule_Plan_Call { +func (_c *LoggableModule_Plan_Call) Return(_a0 *resource.Resource, _a1 error) *LoggableModule_Plan_Call { _c.Call.Return(_a0, _a1) return _c } +func (_c *LoggableModule_Plan_Call) RunAndReturn(run func(context.Context, module.ExpandedResource, module.ActionRequest) (*resource.Resource, error)) *LoggableModule_Plan_Call { + _c.Call.Return(run) + return _c +} + // Sync provides a mock function with given fields: ctx, res func (_m *LoggableModule) Sync(ctx context.Context, res module.ExpandedResource) (*resource.State, error) { ret := _m.Called(ctx, res) var r0 *resource.State + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource) (*resource.State, error)); ok { + return rf(ctx, res) + } if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource) *resource.State); ok { r0 = rf(ctx, res) } else { @@ -182,7 +210,6 @@ func (_m *LoggableModule) Sync(ctx context.Context, res module.ExpandedResource) } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, module.ExpandedResource) error); ok { r1 = rf(ctx, res) } else { @@ -216,6 +243,11 @@ func (_c *LoggableModule_Sync_Call) Return(_a0 *resource.State, _a1 error) *Logg return _c } +func (_c *LoggableModule_Sync_Call) RunAndReturn(run func(context.Context, module.ExpandedResource) (*resource.State, error)) *LoggableModule_Sync_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewLoggableModule interface { mock.TestingT Cleanup(func()) diff --git a/core/mocks/module_registry.go b/core/mocks/module_registry.go index 5dd6d1fc..1b523afe 100644 --- a/core/mocks/module_registry.go +++ b/core/mocks/module_registry.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.23.1. DO NOT EDIT. package mocks @@ -27,6 +27,11 @@ func (_m *ModuleRegistry) GetDriver(ctx context.Context, mod module.Module) (mod ret := _m.Called(ctx, mod) var r0 module.Driver + var r1 module.Descriptor + var r2 error + if rf, ok := ret.Get(0).(func(context.Context, module.Module) (module.Driver, module.Descriptor, error)); ok { + return rf(ctx, mod) + } if rf, ok := ret.Get(0).(func(context.Context, module.Module) module.Driver); ok { r0 = rf(ctx, mod) } else { @@ -35,14 +40,12 @@ func (_m *ModuleRegistry) GetDriver(ctx context.Context, mod module.Module) (mod } } - var r1 module.Descriptor if rf, ok := ret.Get(1).(func(context.Context, module.Module) module.Descriptor); ok { r1 = rf(ctx, mod) } else { r1 = ret.Get(1).(module.Descriptor) } - var r2 error if rf, ok := ret.Get(2).(func(context.Context, module.Module) error); ok { r2 = rf(ctx, mod) } else { @@ -76,6 +79,11 @@ func (_c *ModuleRegistry_GetDriver_Call) Return(_a0 module.Driver, _a1 module.De return _c } +func (_c *ModuleRegistry_GetDriver_Call) RunAndReturn(run func(context.Context, module.Module) (module.Driver, module.Descriptor, error)) *ModuleRegistry_GetDriver_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewModuleRegistry interface { mock.TestingT Cleanup(func()) diff --git a/core/mocks/module_service.go b/core/mocks/module_service.go index 03a6a29c..38f48081 100644 --- a/core/mocks/module_service.go +++ b/core/mocks/module_service.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.23.1. DO NOT EDIT. package mocks @@ -32,6 +32,10 @@ func (_m *ModuleService) GetOutput(ctx context.Context, res module.ExpandedResou ret := _m.Called(ctx, res) var r0 json.RawMessage + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource) (json.RawMessage, error)); ok { + return rf(ctx, res) + } if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource) json.RawMessage); ok { r0 = rf(ctx, res) } else { @@ -40,7 +44,6 @@ func (_m *ModuleService) GetOutput(ctx context.Context, res module.ExpandedResou } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, module.ExpandedResource) error); ok { r1 = rf(ctx, res) } else { @@ -74,20 +77,28 @@ func (_c *ModuleService_GetOutput_Call) Return(_a0 json.RawMessage, _a1 error) * return _c } +func (_c *ModuleService_GetOutput_Call) RunAndReturn(run func(context.Context, module.ExpandedResource) (json.RawMessage, error)) *ModuleService_GetOutput_Call { + _c.Call.Return(run) + return _c +} + // PlanAction provides a mock function with given fields: ctx, res, act -func (_m *ModuleService) PlanAction(ctx context.Context, res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { +func (_m *ModuleService) PlanAction(ctx context.Context, res module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) { ret := _m.Called(ctx, res, act) - var r0 *module.Plan - if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource, module.ActionRequest) *module.Plan); ok { + var r0 *resource.Resource + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource, module.ActionRequest) (*resource.Resource, error)); ok { + return rf(ctx, res, act) + } + if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource, module.ActionRequest) *resource.Resource); ok { r0 = rf(ctx, res, act) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*module.Plan) + r0 = ret.Get(0).(*resource.Resource) } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, module.ExpandedResource, module.ActionRequest) error); ok { r1 = rf(ctx, res, act) } else { @@ -117,16 +128,25 @@ func (_c *ModuleService_PlanAction_Call) Run(run func(ctx context.Context, res m return _c } -func (_c *ModuleService_PlanAction_Call) Return(_a0 *module.Plan, _a1 error) *ModuleService_PlanAction_Call { +func (_c *ModuleService_PlanAction_Call) Return(_a0 *resource.Resource, _a1 error) *ModuleService_PlanAction_Call { _c.Call.Return(_a0, _a1) return _c } +func (_c *ModuleService_PlanAction_Call) RunAndReturn(run func(context.Context, module.ExpandedResource, module.ActionRequest) (*resource.Resource, error)) *ModuleService_PlanAction_Call { + _c.Call.Return(run) + return _c +} + // StreamLogs provides a mock function with given fields: ctx, res, filter func (_m *ModuleService) StreamLogs(ctx context.Context, res module.ExpandedResource, filter map[string]string) (<-chan module.LogChunk, error) { ret := _m.Called(ctx, res, filter) var r0 <-chan module.LogChunk + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource, map[string]string) (<-chan module.LogChunk, error)); ok { + return rf(ctx, res, filter) + } if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource, map[string]string) <-chan module.LogChunk); ok { r0 = rf(ctx, res, filter) } else { @@ -135,7 +155,6 @@ func (_m *ModuleService) StreamLogs(ctx context.Context, res module.ExpandedReso } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, module.ExpandedResource, map[string]string) error); ok { r1 = rf(ctx, res, filter) } else { @@ -170,11 +189,20 @@ func (_c *ModuleService_StreamLogs_Call) Return(_a0 <-chan module.LogChunk, _a1 return _c } +func (_c *ModuleService_StreamLogs_Call) RunAndReturn(run func(context.Context, module.ExpandedResource, map[string]string) (<-chan module.LogChunk, error)) *ModuleService_StreamLogs_Call { + _c.Call.Return(run) + return _c +} + // SyncState provides a mock function with given fields: ctx, res func (_m *ModuleService) SyncState(ctx context.Context, res module.ExpandedResource) (*resource.State, error) { ret := _m.Called(ctx, res) var r0 *resource.State + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource) (*resource.State, error)); ok { + return rf(ctx, res) + } if rf, ok := ret.Get(0).(func(context.Context, module.ExpandedResource) *resource.State); ok { r0 = rf(ctx, res) } else { @@ -183,7 +211,6 @@ func (_m *ModuleService) SyncState(ctx context.Context, res module.ExpandedResou } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, module.ExpandedResource) error); ok { r1 = rf(ctx, res) } else { @@ -217,6 +244,11 @@ func (_c *ModuleService_SyncState_Call) Return(_a0 *resource.State, _a1 error) * return _c } +func (_c *ModuleService_SyncState_Call) RunAndReturn(run func(context.Context, module.ExpandedResource) (*resource.State, error)) *ModuleService_SyncState_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewModuleService interface { mock.TestingT Cleanup(func()) diff --git a/core/mocks/module_store.go b/core/mocks/module_store.go index 95fe96c9..ea3f05c6 100644 --- a/core/mocks/module_store.go +++ b/core/mocks/module_store.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.23.1. DO NOT EDIT. package mocks @@ -60,6 +60,11 @@ func (_c *ModuleStore_CreateModule_Call) Return(_a0 error) *ModuleStore_CreateMo return _c } +func (_c *ModuleStore_CreateModule_Call) RunAndReturn(run func(context.Context, module.Module) error) *ModuleStore_CreateModule_Call { + _c.Call.Return(run) + return _c +} + // DeleteModule provides a mock function with given fields: ctx, urn func (_m *ModuleStore) DeleteModule(ctx context.Context, urn string) error { ret := _m.Called(ctx, urn) @@ -98,11 +103,20 @@ func (_c *ModuleStore_DeleteModule_Call) Return(_a0 error) *ModuleStore_DeleteMo return _c } +func (_c *ModuleStore_DeleteModule_Call) RunAndReturn(run func(context.Context, string) error) *ModuleStore_DeleteModule_Call { + _c.Call.Return(run) + return _c +} + // GetModule provides a mock function with given fields: ctx, urn func (_m *ModuleStore) GetModule(ctx context.Context, urn string) (*module.Module, error) { ret := _m.Called(ctx, urn) var r0 *module.Module + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*module.Module, error)); ok { + return rf(ctx, urn) + } if rf, ok := ret.Get(0).(func(context.Context, string) *module.Module); ok { r0 = rf(ctx, urn) } else { @@ -111,7 +125,6 @@ func (_m *ModuleStore) GetModule(ctx context.Context, urn string) (*module.Modul } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { r1 = rf(ctx, urn) } else { @@ -145,11 +158,20 @@ func (_c *ModuleStore_GetModule_Call) Return(_a0 *module.Module, _a1 error) *Mod return _c } +func (_c *ModuleStore_GetModule_Call) RunAndReturn(run func(context.Context, string) (*module.Module, error)) *ModuleStore_GetModule_Call { + _c.Call.Return(run) + return _c +} + // ListModules provides a mock function with given fields: ctx, project func (_m *ModuleStore) ListModules(ctx context.Context, project string) ([]module.Module, error) { ret := _m.Called(ctx, project) var r0 []module.Module + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) ([]module.Module, error)); ok { + return rf(ctx, project) + } if rf, ok := ret.Get(0).(func(context.Context, string) []module.Module); ok { r0 = rf(ctx, project) } else { @@ -158,7 +180,6 @@ func (_m *ModuleStore) ListModules(ctx context.Context, project string) ([]modul } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { r1 = rf(ctx, project) } else { @@ -192,6 +213,11 @@ func (_c *ModuleStore_ListModules_Call) Return(_a0 []module.Module, _a1 error) * return _c } +func (_c *ModuleStore_ListModules_Call) RunAndReturn(run func(context.Context, string) ([]module.Module, error)) *ModuleStore_ListModules_Call { + _c.Call.Return(run) + return _c +} + // UpdateModule provides a mock function with given fields: ctx, m func (_m *ModuleStore) UpdateModule(ctx context.Context, m module.Module) error { ret := _m.Called(ctx, m) @@ -230,6 +256,11 @@ func (_c *ModuleStore_UpdateModule_Call) Return(_a0 error) *ModuleStore_UpdateMo return _c } +func (_c *ModuleStore_UpdateModule_Call) RunAndReturn(run func(context.Context, module.Module) error) *ModuleStore_UpdateModule_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewModuleStore interface { mock.TestingT Cleanup(func()) diff --git a/core/mocks/resource_store.go b/core/mocks/resource_store.go index 79ac941e..f55aefd6 100644 --- a/core/mocks/resource_store.go +++ b/core/mocks/resource_store.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.23.1. DO NOT EDIT. package mocks @@ -75,6 +75,11 @@ func (_c *ResourceStore_Create_Call) Return(_a0 error) *ResourceStore_Create_Cal return _c } +func (_c *ResourceStore_Create_Call) RunAndReturn(run func(context.Context, resource.Resource, ...resource.MutationHook) error) *ResourceStore_Create_Call { + _c.Call.Return(run) + return _c +} + // Delete provides a mock function with given fields: ctx, urn, hooks func (_m *ResourceStore) Delete(ctx context.Context, urn string, hooks ...resource.MutationHook) error { _va := make([]interface{}, len(hooks)) @@ -128,11 +133,20 @@ func (_c *ResourceStore_Delete_Call) Return(_a0 error) *ResourceStore_Delete_Cal return _c } +func (_c *ResourceStore_Delete_Call) RunAndReturn(run func(context.Context, string, ...resource.MutationHook) error) *ResourceStore_Delete_Call { + _c.Call.Return(run) + return _c +} + // GetByURN provides a mock function with given fields: ctx, urn func (_m *ResourceStore) GetByURN(ctx context.Context, urn string) (*resource.Resource, error) { ret := _m.Called(ctx, urn) var r0 *resource.Resource + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*resource.Resource, error)); ok { + return rf(ctx, urn) + } if rf, ok := ret.Get(0).(func(context.Context, string) *resource.Resource); ok { r0 = rf(ctx, urn) } else { @@ -141,7 +155,6 @@ func (_m *ResourceStore) GetByURN(ctx context.Context, urn string) (*resource.Re } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { r1 = rf(ctx, urn) } else { @@ -175,11 +188,20 @@ func (_c *ResourceStore_GetByURN_Call) Return(_a0 *resource.Resource, _a1 error) return _c } +func (_c *ResourceStore_GetByURN_Call) RunAndReturn(run func(context.Context, string) (*resource.Resource, error)) *ResourceStore_GetByURN_Call { + _c.Call.Return(run) + return _c +} + // List provides a mock function with given fields: ctx, filter func (_m *ResourceStore) List(ctx context.Context, filter resource.Filter) ([]resource.Resource, error) { ret := _m.Called(ctx, filter) var r0 []resource.Resource + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, resource.Filter) ([]resource.Resource, error)); ok { + return rf(ctx, filter) + } if rf, ok := ret.Get(0).(func(context.Context, resource.Filter) []resource.Resource); ok { r0 = rf(ctx, filter) } else { @@ -188,7 +210,6 @@ func (_m *ResourceStore) List(ctx context.Context, filter resource.Filter) ([]re } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, resource.Filter) error); ok { r1 = rf(ctx, filter) } else { @@ -222,11 +243,20 @@ func (_c *ResourceStore_List_Call) Return(_a0 []resource.Resource, _a1 error) *R return _c } +func (_c *ResourceStore_List_Call) RunAndReturn(run func(context.Context, resource.Filter) ([]resource.Resource, error)) *ResourceStore_List_Call { + _c.Call.Return(run) + return _c +} + // Revisions provides a mock function with given fields: ctx, selector func (_m *ResourceStore) Revisions(ctx context.Context, selector resource.RevisionsSelector) ([]resource.Revision, error) { ret := _m.Called(ctx, selector) var r0 []resource.Revision + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, resource.RevisionsSelector) ([]resource.Revision, error)); ok { + return rf(ctx, selector) + } if rf, ok := ret.Get(0).(func(context.Context, resource.RevisionsSelector) []resource.Revision); ok { r0 = rf(ctx, selector) } else { @@ -235,7 +265,6 @@ func (_m *ResourceStore) Revisions(ctx context.Context, selector resource.Revisi } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, resource.RevisionsSelector) error); ok { r1 = rf(ctx, selector) } else { @@ -269,6 +298,54 @@ func (_c *ResourceStore_Revisions_Call) Return(_a0 []resource.Revision, _a1 erro return _c } +func (_c *ResourceStore_Revisions_Call) RunAndReturn(run func(context.Context, resource.RevisionsSelector) ([]resource.Revision, error)) *ResourceStore_Revisions_Call { + _c.Call.Return(run) + return _c +} + +// SyncOne provides a mock function with given fields: ctx, syncFn +func (_m *ResourceStore) SyncOne(ctx context.Context, syncFn resource.SyncFn) error { + ret := _m.Called(ctx, syncFn) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, resource.SyncFn) error); ok { + r0 = rf(ctx, syncFn) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ResourceStore_SyncOne_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SyncOne' +type ResourceStore_SyncOne_Call struct { + *mock.Call +} + +// SyncOne is a helper method to define mock.On call +// - ctx context.Context +// - syncFn resource.SyncFn +func (_e *ResourceStore_Expecter) SyncOne(ctx interface{}, syncFn interface{}) *ResourceStore_SyncOne_Call { + return &ResourceStore_SyncOne_Call{Call: _e.mock.On("SyncOne", ctx, syncFn)} +} + +func (_c *ResourceStore_SyncOne_Call) Run(run func(ctx context.Context, syncFn resource.SyncFn)) *ResourceStore_SyncOne_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(resource.SyncFn)) + }) + return _c +} + +func (_c *ResourceStore_SyncOne_Call) Return(_a0 error) *ResourceStore_SyncOne_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ResourceStore_SyncOne_Call) RunAndReturn(run func(context.Context, resource.SyncFn) error) *ResourceStore_SyncOne_Call { + _c.Call.Return(run) + return _c +} + // Update provides a mock function with given fields: ctx, r, saveRevision, reason, hooks func (_m *ResourceStore) Update(ctx context.Context, r resource.Resource, saveRevision bool, reason string, hooks ...resource.MutationHook) error { _va := make([]interface{}, len(hooks)) @@ -324,6 +401,11 @@ func (_c *ResourceStore_Update_Call) Return(_a0 error) *ResourceStore_Update_Cal return _c } +func (_c *ResourceStore_Update_Call) RunAndReturn(run func(context.Context, resource.Resource, bool, string, ...resource.MutationHook) error) *ResourceStore_Update_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewResourceStore interface { mock.TestingT Cleanup(func()) diff --git a/core/module/driver.go b/core/module/driver.go index 61f1b7f6..cdcd86da 100644 --- a/core/module/driver.go +++ b/core/module/driver.go @@ -6,7 +6,6 @@ package module import ( "context" "encoding/json" - "time" "github.com/goto/entropy/core/resource" ) @@ -17,7 +16,7 @@ type Driver interface { // Plan SHOULD validate the action on the current version of the resource, // return the resource with config/status/state changes (if any) applied. // Plan SHOULD NOT have side effects on anything other than the resource. - Plan(ctx context.Context, res ExpandedResource, act ActionRequest) (*Plan, error) + Plan(ctx context.Context, res ExpandedResource, act ActionRequest) (*resource.Resource, error) // Sync is called repeatedly by Entropy core until the returned state is // a terminal status. Driver implementation is free to execute an action @@ -32,13 +31,6 @@ type Driver interface { Output(ctx context.Context, res ExpandedResource) (json.RawMessage, error) } -// Plan represents the changes to be staged and later synced by module. -type Plan struct { - Reason string - Resource resource.Resource - ScheduleRunAt *time.Time -} - // Loggable extension of driver allows streaming log data for a resource. type Loggable interface { Driver diff --git a/core/module/service.go b/core/module/service.go index e3d07405..d2c5ddef 100644 --- a/core/module/service.go +++ b/core/module/service.go @@ -21,7 +21,7 @@ func NewService(registry Registry, store Store) *Service { } } -func (mr *Service) PlanAction(ctx context.Context, res ExpandedResource, act ActionRequest) (*Plan, error) { +func (mr *Service) PlanAction(ctx context.Context, res ExpandedResource, act ActionRequest) (*resource.Resource, error) { mod, err := mr.discoverModule(ctx, res.Kind, res.Project) if err != nil { return nil, err diff --git a/core/read.go b/core/read.go index 7c1769aa..3818264e 100644 --- a/core/read.go +++ b/core/read.go @@ -8,8 +8,8 @@ import ( "github.com/goto/entropy/pkg/errors" ) -func (s *Service) GetResource(ctx context.Context, urn string) (*resource.Resource, error) { - res, err := s.store.GetByURN(ctx, urn) +func (svc *Service) GetResource(ctx context.Context, urn string) (*resource.Resource, error) { + res, err := svc.store.GetByURN(ctx, urn) if err != nil { if errors.Is(err, errors.ErrNotFound) { return nil, errors.ErrNotFound.WithMsgf("resource with urn '%s' not found", urn) @@ -17,12 +17,12 @@ func (s *Service) GetResource(ctx context.Context, urn string) (*resource.Resour return nil, errors.ErrInternal.WithCausef(err.Error()) } - modSpec, err := s.generateModuleSpec(ctx, *res) + modSpec, err := svc.generateModuleSpec(ctx, *res) if err != nil { return nil, err } - output, err := s.moduleSvc.GetOutput(ctx, *modSpec) + output, err := svc.moduleSvc.GetOutput(ctx, *modSpec) if err != nil { return nil, err } @@ -32,26 +32,26 @@ func (s *Service) GetResource(ctx context.Context, urn string) (*resource.Resour return res, nil } -func (s *Service) ListResources(ctx context.Context, filter resource.Filter) ([]resource.Resource, error) { - resources, err := s.store.List(ctx, filter) +func (svc *Service) ListResources(ctx context.Context, filter resource.Filter) ([]resource.Resource, error) { + resources, err := svc.store.List(ctx, filter) if err != nil { return nil, errors.ErrInternal.WithCausef(err.Error()) } return filter.Apply(resources), nil } -func (s *Service) GetLog(ctx context.Context, urn string, filter map[string]string) (<-chan module.LogChunk, error) { - res, err := s.GetResource(ctx, urn) +func (svc *Service) GetLog(ctx context.Context, urn string, filter map[string]string) (<-chan module.LogChunk, error) { + res, err := svc.GetResource(ctx, urn) if err != nil { return nil, err } - modSpec, err := s.generateModuleSpec(ctx, *res) + modSpec, err := svc.generateModuleSpec(ctx, *res) if err != nil { return nil, err } - logCh, err := s.moduleSvc.StreamLogs(ctx, *modSpec, filter) + logCh, err := svc.moduleSvc.StreamLogs(ctx, *modSpec, filter) if err != nil { if errors.Is(err, errors.ErrUnsupported) { return nil, errors.ErrUnsupported.WithMsgf("log streaming not supported for kind '%s'", res.Kind) @@ -61,8 +61,8 @@ func (s *Service) GetLog(ctx context.Context, urn string, filter map[string]stri return logCh, nil } -func (s *Service) GetRevisions(ctx context.Context, selector resource.RevisionsSelector) ([]resource.Revision, error) { - revs, err := s.store.Revisions(ctx, selector) +func (svc *Service) GetRevisions(ctx context.Context, selector resource.RevisionsSelector) ([]resource.Revision, error) { + revs, err := svc.store.Revisions(ctx, selector) if err != nil { return nil, errors.ErrInternal.WithCausef(err.Error()) } diff --git a/core/read_test.go b/core/read_test.go index 9a501005..d8160e70 100644 --- a/core/read_test.go +++ b/core/read_test.go @@ -32,7 +32,7 @@ func TestService_GetResource(t *testing.T) { GetByURN(mock.Anything, mock.Anything). Return(nil, errors.ErrNotFound). Once() - return core.New(repo, nil, &mocks.AsyncWorker{}, nil, nil) + return core.New(repo, nil, nil, nil) }, urn: "foo:bar:baz", wantErr: errors.ErrNotFound, @@ -52,7 +52,7 @@ func TestService_GetResource(t *testing.T) { Return(nil, nil). Once() - return core.New(repo, mod, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(repo, mod, deadClock, nil) }, urn: "foo:bar:baz", want: &sampleResource, @@ -99,7 +99,7 @@ func TestService_ListResources(t *testing.T) { List(mock.Anything, mock.Anything). Return(nil, nil). Once() - return core.New(repo, nil, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(repo, nil, deadClock, nil) }, want: nil, wantErr: nil, @@ -113,7 +113,7 @@ func TestService_ListResources(t *testing.T) { List(mock.Anything, mock.Anything). Return(nil, errStoreFailure). Once() - return core.New(repo, nil, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(repo, nil, deadClock, nil) }, want: nil, wantErr: errors.ErrInternal, @@ -127,7 +127,7 @@ func TestService_ListResources(t *testing.T) { List(mock.Anything, mock.Anything). Return([]resource.Resource{sampleResource}, nil). Once() - return core.New(repo, nil, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(repo, nil, deadClock, nil) }, want: []resource.Resource{sampleResource}, wantErr: nil, diff --git a/core/resource/resource.go b/core/resource/resource.go index 64edcf40..028cf891 100644 --- a/core/resource/resource.go +++ b/core/resource/resource.go @@ -25,8 +25,12 @@ type Store interface { Delete(ctx context.Context, urn string, hooks ...MutationHook) error Revisions(ctx context.Context, selector RevisionsSelector) ([]Revision, error) + + SyncOne(ctx context.Context, syncFn SyncFn) error } +type SyncFn func(ctx context.Context, res Resource) (*Resource, error) + // MutationHook values are passed to mutation operations of resource storage // to handle any transactional requirements. type MutationHook func(ctx context.Context) error diff --git a/core/resource/state.go b/core/resource/state.go index a661fd83..a435f81c 100644 --- a/core/resource/state.go +++ b/core/resource/state.go @@ -2,6 +2,7 @@ package resource import ( "encoding/json" + "time" ) const ( @@ -12,10 +13,18 @@ const ( StatusCompleted = "STATUS_COMPLETED" // terminal ) +type SyncResult struct { + Retries int `json:"retries"` + LastError string `json:"last_error"` +} + type State struct { Status string `json:"status"` Output json.RawMessage `json:"output"` ModuleData json.RawMessage `json:"module_data,omitempty"` + + NextSyncAt *time.Time `json:"next_sync_at,omitempty"` + SyncResult SyncResult `json:"sync_result"` } // IsTerminal returns true if state is terminal. A terminal state is diff --git a/core/sync.go b/core/sync.go index 80a9319d..9dd0f3fa 100644 --- a/core/sync.go +++ b/core/sync.go @@ -2,110 +2,77 @@ package core import ( "context" - "encoding/json" - "fmt" "time" - "github.com/goto/entropy/core/module" + "go.uber.org/zap" + "github.com/goto/entropy/core/resource" "github.com/goto/entropy/pkg/errors" - "github.com/goto/entropy/pkg/worker" -) - -const ( - JobKindSyncResource = "sync_resource" - JobKindScheduledSyncResource = "sched_sync_resource" ) -type syncJobPayload struct { - ResourceURN string `json:"resource_urn"` - UpdatedAt time.Time `json:"updated_at"` -} +// RunSyncer runs the syncer thread that keeps performing resource-sync at +// regular intervals. +func (svc *Service) RunSyncer(ctx context.Context, interval time.Duration) error { + tick := time.NewTimer(interval) + defer tick.Stop() -func (s *Service) enqueueSyncJob(ctx context.Context, res resource.Resource, runAt time.Time, jobType string) error { - data := syncJobPayload{ - ResourceURN: res.URN, - UpdatedAt: res.UpdatedAt, - } - - payload, err := json.Marshal(data) - if err != nil { - return err - } - - job := worker.Job{ - ID: fmt.Sprintf(jobType+"-%s-%d", res.URN, runAt.Unix()), - Kind: jobType, - RunAt: runAt, - Payload: payload, - } - - if err := s.worker.Enqueue(ctx, job); err != nil && !errors.Is(err, worker.ErrJobExists) { - return err - } - return nil -} + for { + select { + case <-ctx.Done(): + return ctx.Err() -// HandleSyncJob is meant to be invoked by asyncWorker when an enqueued job is -// ready. -// TODO: make this private and move the registration of this handler inside New(). -func (s *Service) HandleSyncJob(ctx context.Context, job worker.Job) ([]byte, error) { - const retryBackoff = 5 * time.Second + case <-tick.C: + tick.Reset(interval) - var data syncJobPayload - if err := json.Unmarshal(job.Payload, &data); err != nil { - return nil, err - } - - syncedRes, err := s.syncChange(ctx, data.ResourceURN) - if err != nil { - if errors.Is(err, errors.ErrInternal) { - return nil, &worker.RetryableError{ - Cause: err, - RetryAfter: retryBackoff, + err := svc.store.SyncOne(ctx, svc.handleSync) + if err != nil { + svc.logger.Warn("SyncOne() failed", zap.Error(err)) } } - return nil, err } - - return json.Marshal(map[string]interface{}{ - "status": syncedRes.State.Status, - }) } -func (s *Service) syncChange(ctx context.Context, urn string) (*resource.Resource, error) { - res, err := s.GetResource(ctx, urn) - if err != nil { - return nil, err - } +func (svc *Service) handleSync(ctx context.Context, res resource.Resource) (*resource.Resource, error) { + logEntry := svc.logger.With( + zap.String("resource_urn", res.URN), + zap.String("resource_status", res.State.Status), + zap.Int("retries", res.State.SyncResult.Retries), + zap.String("last_err", res.State.SyncResult.LastError), + ) - modSpec, err := s.generateModuleSpec(ctx, *res) + modSpec, err := svc.generateModuleSpec(ctx, res) if err != nil { + logEntry.Error("SyncOne() failed", zap.Error(err)) return nil, err } - oldState := res.State.Clone() - newState, err := s.moduleSvc.SyncState(ctx, *modSpec) + newState, err := svc.moduleSvc.SyncState(ctx, *modSpec) if err != nil { if errors.Is(err, errors.ErrInvalid) { - return nil, err + // ErrInvalid is expected to be returned when config is invalid. + // There is no point in retrying in this case. + res.State.Status = resource.StatusError + res.State.NextSyncAt = nil + } else { + // Some other error occurred. need to backoff and retry in some time. + tryAgainAt := svc.clock().Add(svc.syncBackoff) + res.State.NextSyncAt = &tryAgainAt } - return nil, errors.ErrInternal.WithMsgf("sync() failed").WithCausef(err.Error()) - } - res.UpdatedAt = s.clock() - res.State = *newState + res.State.SyncResult.LastError = err.Error() + res.State.SyncResult.Retries++ - // TODO: clarify on behaviour when resource schedule for deletion reaches error. - shouldDelete := oldState.InDeletion() && newState.IsTerminal() - if shouldDelete { - if err := s.DeleteResource(ctx, urn); err != nil { - return nil, err - } + logEntry.Error("SyncOne() failed", zap.Error(err)) } else { - if err := s.upsert(ctx, module.Plan{Resource: *res}, false, false, ""); err != nil { - return nil, err - } + res.State.SyncResult.Retries = 0 + res.State.SyncResult.LastError = "" + res.UpdatedAt = svc.clock() + res.State = *newState + + logEntry.Info("SyncOne() finished", + zap.String("final_status", res.State.Status), + zap.Timep("next_sync", res.State.NextSyncAt), + ) } - return res, nil + return &res, nil } diff --git a/core/write.go b/core/write.go index 0735d776..0d01c584 100644 --- a/core/write.go +++ b/core/write.go @@ -2,13 +2,14 @@ package core import ( "context" + "fmt" "github.com/goto/entropy/core/module" "github.com/goto/entropy/core/resource" "github.com/goto/entropy/pkg/errors" ) -func (s *Service) CreateResource(ctx context.Context, res resource.Resource) (*resource.Resource, error) { +func (svc *Service) CreateResource(ctx context.Context, res resource.Resource) (*resource.Resource, error) { if err := res.Validate(true); err != nil { return nil, err } @@ -20,32 +21,32 @@ func (s *Service) CreateResource(ctx context.Context, res resource.Resource) (*r } res.Spec.Configs = nil - return s.execAction(ctx, res, act) + return svc.execAction(ctx, res, act) } -func (s *Service) UpdateResource(ctx context.Context, urn string, req resource.UpdateRequest) (*resource.Resource, error) { +func (svc *Service) UpdateResource(ctx context.Context, urn string, req resource.UpdateRequest) (*resource.Resource, error) { if len(req.Spec.Dependencies) != 0 { return nil, errors.ErrUnsupported.WithMsgf("updating dependencies is not supported") } else if len(req.Spec.Configs) == 0 { return nil, errors.ErrInvalid.WithMsgf("no config is being updated, nothing to do") } - return s.ApplyAction(ctx, urn, module.ActionRequest{ + return svc.ApplyAction(ctx, urn, module.ActionRequest{ Name: module.UpdateAction, Params: req.Spec.Configs, Labels: req.Labels, }) } -func (s *Service) DeleteResource(ctx context.Context, urn string) error { - _, actionErr := s.ApplyAction(ctx, urn, module.ActionRequest{ +func (svc *Service) DeleteResource(ctx context.Context, urn string) error { + _, actionErr := svc.ApplyAction(ctx, urn, module.ActionRequest{ Name: module.DeleteAction, }) return actionErr } -func (s *Service) ApplyAction(ctx context.Context, urn string, act module.ActionRequest) (*resource.Resource, error) { - res, err := s.GetResource(ctx, urn) +func (svc *Service) ApplyAction(ctx context.Context, urn string, act module.ActionRequest) (*resource.Resource, error) { + res, err := svc.GetResource(ctx, urn) if err != nil { return nil, err } else if !res.State.IsTerminal() { @@ -53,36 +54,37 @@ func (s *Service) ApplyAction(ctx context.Context, urn string, act module.Action WithMsgf("cannot perform '%s' on resource in '%s'", act.Name, res.State.Status) } - return s.execAction(ctx, *res, act) + return svc.execAction(ctx, *res, act) } -func (s *Service) execAction(ctx context.Context, res resource.Resource, act module.ActionRequest) (*resource.Resource, error) { - planned, err := s.planChange(ctx, res, act) +func (svc *Service) execAction(ctx context.Context, res resource.Resource, act module.ActionRequest) (*resource.Resource, error) { + planned, err := svc.planChange(ctx, res, act) if err != nil { return nil, err } if isCreate(act.Name) { - planned.Resource.CreatedAt = s.clock() - planned.Resource.UpdatedAt = planned.Resource.CreatedAt + planned.CreatedAt = svc.clock() + planned.UpdatedAt = planned.CreatedAt } else { - planned.Resource.CreatedAt = res.CreatedAt - planned.Resource.UpdatedAt = s.clock() + planned.CreatedAt = res.CreatedAt + planned.UpdatedAt = svc.clock() } - if err := s.upsert(ctx, *planned, isCreate(act.Name), true, planned.Reason); err != nil { + reason := fmt.Sprintf("action:%s", act.Name) + if err := svc.upsert(ctx, *planned, isCreate(act.Name), true, reason); err != nil { return nil, err } - return &planned.Resource, nil + return planned, nil } -func (s *Service) planChange(ctx context.Context, res resource.Resource, act module.ActionRequest) (*module.Plan, error) { - modSpec, err := s.generateModuleSpec(ctx, res) +func (svc *Service) planChange(ctx context.Context, res resource.Resource, act module.ActionRequest) (*resource.Resource, error) { + modSpec, err := svc.generateModuleSpec(ctx, res) if err != nil { return nil, err } - planned, err := s.moduleSvc.PlanAction(ctx, *modSpec, act) + planned, err := svc.moduleSvc.PlanAction(ctx, *modSpec, act) if err != nil { if errors.Is(err, errors.ErrInvalid) { return nil, err @@ -90,43 +92,27 @@ func (s *Service) planChange(ctx context.Context, res resource.Resource, act mod return nil, errors.ErrInternal.WithMsgf("plan() failed").WithCausef(err.Error()) } - planned.Resource.Labels = act.Labels - if err := planned.Resource.Validate(isCreate(act.Name)); err != nil { + planned.Labels = act.Labels + if err := planned.Validate(isCreate(act.Name)); err != nil { return nil, err } return planned, nil } -func (s *Service) upsert(ctx context.Context, plan module.Plan, isCreate bool, saveRevision bool, reason string) error { - var hooks []resource.MutationHook - hooks = append(hooks, func(ctx context.Context) error { - if plan.Resource.State.IsTerminal() { - // no need to enqueue if resource has reached terminal state. - return nil - } - - return s.enqueueSyncJob(ctx, plan.Resource, s.clock(), JobKindSyncResource) - }) - - if plan.ScheduleRunAt != nil { - hooks = append(hooks, func(ctx context.Context) error { - return s.enqueueSyncJob(ctx, plan.Resource, *plan.ScheduleRunAt, JobKindScheduledSyncResource) - }) - } - +func (svc *Service) upsert(ctx context.Context, res resource.Resource, isCreate bool, saveRevision bool, reason string) error { var err error if isCreate { - err = s.store.Create(ctx, plan.Resource, hooks...) + err = svc.store.Create(ctx, res) } else { - err = s.store.Update(ctx, plan.Resource, saveRevision, reason, hooks...) + err = svc.store.Update(ctx, res, saveRevision, reason) } if err != nil { if isCreate && errors.Is(err, errors.ErrConflict) { - return errors.ErrConflict.WithMsgf("resource with urn '%s' already exists", plan.Resource.URN) + return errors.ErrConflict.WithMsgf("resource with urn '%s' already exists", res.URN) } else if !isCreate && errors.Is(err, errors.ErrNotFound) { - return errors.ErrNotFound.WithMsgf("resource with urn '%s' does not exist", plan.Resource.URN) + return errors.ErrNotFound.WithMsgf("resource with urn '%s' does not exist", res.URN) } return errors.ErrInternal.WithCausef(err.Error()) } diff --git a/core/write_test.go b/core/write_test.go index f6233519..29ddd3fc 100644 --- a/core/write_test.go +++ b/core/write_test.go @@ -37,7 +37,7 @@ func TestService_CreateResource(t *testing.T) { PlanAction(mock.Anything, mock.Anything, mock.Anything). Return(nil, errSample).Once() - return core.New(nil, mod, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(nil, mod, deadClock, nil) }, res: resource.Resource{ Kind: "mock", @@ -59,7 +59,7 @@ func TestService_CreateResource(t *testing.T) { Return(nil, errors.ErrNotFound). Once() - return core.New(resourceRepo, mod, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(resourceRepo, mod, deadClock, nil) }, res: resource.Resource{ Kind: "mock", @@ -98,7 +98,7 @@ func TestService_CreateResource(t *testing.T) { }, nil). Once() - return core.New(resourceRepo, mod, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(resourceRepo, mod, deadClock, nil) }, res: resource.Resource{ Kind: "mock", @@ -136,7 +136,7 @@ func TestService_CreateResource(t *testing.T) { }, nil). Once() - return core.New(resourceRepo, mod, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(resourceRepo, mod, deadClock, nil) }, res: resource.Resource{ Kind: "mock", @@ -158,12 +158,10 @@ func TestService_CreateResource(t *testing.T) { mod := &mocks.ModuleService{} mod.EXPECT(). PlanAction(mock.Anything, mock.Anything, mock.Anything). - Return(&module.Plan{ - Resource: resource.Resource{ - Kind: "mock", - Name: "child", - Project: "project", - }, + Return(&resource.Resource{ + Kind: "mock", + Name: "child", + Project: "project", }, nil).Once() resourceRepo := &mocks.ResourceStore{} @@ -172,7 +170,7 @@ func TestService_CreateResource(t *testing.T) { Return(errSample). Once() - return core.New(resourceRepo, mod, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(resourceRepo, mod, deadClock, nil) }, res: resource.Resource{ Kind: "mock", @@ -189,12 +187,10 @@ func TestService_CreateResource(t *testing.T) { mod := &mocks.ModuleService{} mod.EXPECT(). PlanAction(mock.Anything, mock.Anything, mock.Anything). - Return(&module.Plan{ - Resource: resource.Resource{ - Kind: "mock", - Name: "child", - Project: "project", - }, + Return(&resource.Resource{ + Kind: "mock", + Name: "child", + Project: "project", }, nil).Once() resourceRepo := &mocks.ResourceStore{} @@ -202,7 +198,7 @@ func TestService_CreateResource(t *testing.T) { Create(mock.Anything, mock.Anything, mock.Anything). Return(errors.ErrConflict).Once() - return core.New(resourceRepo, mod, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(resourceRepo, mod, deadClock, nil) }, res: resource.Resource{ Kind: "mock", @@ -219,13 +215,11 @@ func TestService_CreateResource(t *testing.T) { mod := &mocks.ModuleService{} mod.EXPECT(). PlanAction(mock.Anything, mock.Anything, mock.Anything). - Return(&module.Plan{ - Resource: resource.Resource{ - Kind: "mock", - Name: "child", - Project: "project", - State: resource.State{Status: resource.StatusCompleted}, - }, + Return(&resource.Resource{ + Kind: "mock", + Name: "child", + Project: "project", + State: resource.State{Status: resource.StatusCompleted}, }, nil).Once() mod.EXPECT(). GetOutput(mock.Anything, mock.Anything). @@ -247,8 +241,7 @@ func TestService_CreateResource(t *testing.T) { resourceRepo.EXPECT(). Create(mock.Anything, mock.Anything, mock.Anything). Run(func(ctx context.Context, r resource.Resource, hooks ...resource.MutationHook) { - assert.Len(t, hooks, 1) - assert.NoError(t, hooks[0](ctx)) + assert.Len(t, hooks, 0) }). Return(nil). Once() @@ -262,7 +255,7 @@ func TestService_CreateResource(t *testing.T) { }). Return(nil) - return core.New(resourceRepo, mod, mockWorker, deadClock, nil) + return core.New(resourceRepo, mod, deadClock, nil) }, res: resource.Resource{ Kind: "mock", @@ -335,7 +328,7 @@ func TestService_UpdateResource(t *testing.T) { Return(nil, errors.ErrNotFound). Once() - return core.New(resourceRepo, nil, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(resourceRepo, nil, deadClock, nil) }, urn: "orn:entropy:mock:project:child", update: resource.UpdateRequest{ @@ -364,7 +357,7 @@ func TestService_UpdateResource(t *testing.T) { Return(&testResource, nil). Once() - return core.New(resourceRepo, mod, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(resourceRepo, mod, deadClock, nil) }, urn: "orn:entropy:mock:project:child", update: resource.UpdateRequest{ @@ -381,7 +374,7 @@ func TestService_UpdateResource(t *testing.T) { mod := &mocks.ModuleService{} mod.EXPECT(). PlanAction(mock.Anything, mock.Anything, mock.Anything). - Return(&module.Plan{Resource: testResource}, nil).Once() + Return(&testResource, nil).Once() mod.EXPECT(). GetOutput(mock.Anything, mock.Anything). Return(nil, nil). @@ -396,8 +389,7 @@ func TestService_UpdateResource(t *testing.T) { resourceRepo.EXPECT(). Update(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Run(func(ctx context.Context, r resource.Resource, saveRevision bool, reason string, hooks ...resource.MutationHook) { - assert.Len(t, hooks, 1) - assert.NoError(t, hooks[0](ctx)) + assert.Len(t, hooks, 0) }). Return(testErr) @@ -412,7 +404,7 @@ func TestService_UpdateResource(t *testing.T) { Return(nil). Once() - return core.New(resourceRepo, mod, mockWorker, deadClock, nil) + return core.New(resourceRepo, mod, deadClock, nil) }, urn: "orn:entropy:mock:project:child", update: resource.UpdateRequest{ @@ -429,18 +421,16 @@ func TestService_UpdateResource(t *testing.T) { mod := &mocks.ModuleService{} mod.EXPECT(). PlanAction(mock.Anything, mock.Anything, mock.Anything). - Return(&module.Plan{ - Resource: resource.Resource{ - URN: "orn:entropy:mock:project:child", - Kind: "mock", - Name: "child", - Project: "project", - Spec: resource.Spec{ - Configs: []byte(`{"foo": "bar"}`), - }, - State: resource.State{Status: resource.StatusPending}, - CreatedAt: frozenTime, + Return(&resource.Resource{ + URN: "orn:entropy:mock:project:child", + Kind: "mock", + Name: "child", + Project: "project", + Spec: resource.Spec{ + Configs: []byte(`{"foo": "bar"}`), }, + State: resource.State{Status: resource.StatusPending}, + CreatedAt: frozenTime, }, nil).Once() mod.EXPECT(). GetOutput(mock.Anything, mock.Anything). @@ -456,23 +446,11 @@ func TestService_UpdateResource(t *testing.T) { Update(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(nil). Run(func(ctx context.Context, r resource.Resource, saveRevision bool, reason string, hooks ...resource.MutationHook) { - assert.Len(t, hooks, 1) - assert.NoError(t, hooks[0](ctx)) + assert.Len(t, hooks, 0) }). Twice() - mockWorker := &mocks.AsyncWorker{} - mockWorker.EXPECT(). - Enqueue(mock.Anything, mock.Anything). - Return(nil). - Run(func(ctx context.Context, jobs ...worker.Job) { - assert.Len(t, jobs, 1) - assert.Equal(t, jobs[0].ID, "sync_resource-orn:entropy:mock:project:child-1650536955") - assert.Equal(t, jobs[0].Kind, "sync_resource") - }). - Once() - - return core.New(resourceRepo, mod, mockWorker, deadClock, nil) + return core.New(resourceRepo, mod, deadClock, nil) }, urn: "orn:entropy:mock:project:child", update: resource.UpdateRequest{ @@ -535,7 +513,7 @@ func TestService_DeleteResource(t *testing.T) { Return(nil, testErr). Once() - return core.New(resourceRepo, nil, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(resourceRepo, nil, deadClock, nil) }, urn: "orn:entropy:mock:foo:bar", wantErr: testErr, @@ -547,16 +525,14 @@ func TestService_DeleteResource(t *testing.T) { mod := &mocks.ModuleService{} mod.EXPECT(). PlanAction(mock.Anything, mock.Anything, mock.Anything). - Return(&module.Plan{ - Resource: resource.Resource{ - URN: "orn:entropy:mock:project:child", - Kind: "mock", - Name: "child", - Project: "project", - State: resource.State{Status: resource.StatusPending}, - CreatedAt: frozenTime, - UpdatedAt: frozenTime, - }, + Return(&resource.Resource{ + URN: "orn:entropy:mock:project:child", + Kind: "mock", + Name: "child", + Project: "project", + State: resource.State{Status: resource.StatusPending}, + CreatedAt: frozenTime, + UpdatedAt: frozenTime, }, nil).Once() mod.EXPECT(). GetOutput(mock.Anything, mock.Anything). @@ -582,7 +558,7 @@ func TestService_DeleteResource(t *testing.T) { Return(testErr). Once() - return core.New(resourceRepo, mod, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(resourceRepo, mod, deadClock, nil) }, urn: "orn:entropy:mock:foo:bar", wantErr: errors.ErrInternal, @@ -594,16 +570,14 @@ func TestService_DeleteResource(t *testing.T) { mod := &mocks.ModuleService{} mod.EXPECT(). PlanAction(mock.Anything, mock.Anything, mock.Anything). - Return(&module.Plan{ - Resource: resource.Resource{ - URN: "orn:entropy:mock:project:child", - Kind: "mock", - Name: "child", - Project: "project", - State: resource.State{Status: resource.StatusPending}, - CreatedAt: frozenTime, - UpdatedAt: frozenTime, - }, + Return(&resource.Resource{ + URN: "orn:entropy:mock:project:child", + Kind: "mock", + Name: "child", + Project: "project", + State: resource.State{Status: resource.StatusPending}, + CreatedAt: frozenTime, + UpdatedAt: frozenTime, }, nil).Once() mod.EXPECT(). GetOutput(mock.Anything, mock.Anything). @@ -629,7 +603,7 @@ func TestService_DeleteResource(t *testing.T) { Return(nil). Once() - return core.New(resourceRepo, mod, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(resourceRepo, mod, deadClock, nil) }, urn: "orn:entropy:mock:foo:bar", wantErr: nil, @@ -679,7 +653,7 @@ func TestService_ApplyAction(t *testing.T) { Return(nil, errors.ErrNotFound). Once() - return core.New(resourceRepo, nil, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(resourceRepo, nil, deadClock, nil) }, urn: "orn:entropy:mock:foo:bar", action: sampleAction, @@ -706,7 +680,7 @@ func TestService_ApplyAction(t *testing.T) { }, nil). Once() - return core.New(resourceRepo, mod, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(resourceRepo, mod, deadClock, nil) }, urn: "orn:entropy:mock:foo:bar", action: sampleAction, @@ -739,7 +713,7 @@ func TestService_ApplyAction(t *testing.T) { }, nil). Once() - return core.New(resourceRepo, mod, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(resourceRepo, mod, deadClock, nil) }, urn: "orn:entropy:mock:foo:bar", action: sampleAction, @@ -753,14 +727,12 @@ func TestService_ApplyAction(t *testing.T) { mod := &mocks.ModuleService{} mod.EXPECT(). PlanAction(mock.Anything, mock.Anything, sampleAction). - Return(&module.Plan{ - Resource: resource.Resource{ - URN: "orn:entropy:mock:foo:bar", - Kind: "mock", - Project: "foo", - Name: "bar", - State: resource.State{Status: resource.StatusPending}, - }, + Return(&resource.Resource{ + URN: "orn:entropy:mock:foo:bar", + Kind: "mock", + Project: "foo", + Name: "bar", + State: resource.State{Status: resource.StatusPending}, }, nil).Once() mod.EXPECT(). GetOutput(mock.Anything, mock.Anything). @@ -784,7 +756,7 @@ func TestService_ApplyAction(t *testing.T) { Return(nil). Once() - return core.New(resourceRepo, mod, &mocks.AsyncWorker{}, deadClock, nil) + return core.New(resourceRepo, mod, deadClock, nil) }, urn: "orn:entropy:mock:foo:bar", action: sampleAction, diff --git a/internal/server/v1/mocks/module_service.go b/internal/server/v1/mocks/module_service.go index a486135c..b42c63aa 100644 --- a/internal/server/v1/mocks/module_service.go +++ b/internal/server/v1/mocks/module_service.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.23.1. DO NOT EDIT. package mocks @@ -29,6 +29,10 @@ func (_m *ModuleService) CreateModule(ctx context.Context, mod module.Module) (* ret := _m.Called(ctx, mod) var r0 *module.Module + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, module.Module) (*module.Module, error)); ok { + return rf(ctx, mod) + } if rf, ok := ret.Get(0).(func(context.Context, module.Module) *module.Module); ok { r0 = rf(ctx, mod) } else { @@ -37,7 +41,6 @@ func (_m *ModuleService) CreateModule(ctx context.Context, mod module.Module) (* } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, module.Module) error); ok { r1 = rf(ctx, mod) } else { @@ -71,6 +74,11 @@ func (_c *ModuleService_CreateModule_Call) Return(_a0 *module.Module, _a1 error) return _c } +func (_c *ModuleService_CreateModule_Call) RunAndReturn(run func(context.Context, module.Module) (*module.Module, error)) *ModuleService_CreateModule_Call { + _c.Call.Return(run) + return _c +} + // DeleteModule provides a mock function with given fields: ctx, urn func (_m *ModuleService) DeleteModule(ctx context.Context, urn string) error { ret := _m.Called(ctx, urn) @@ -109,11 +117,20 @@ func (_c *ModuleService_DeleteModule_Call) Return(_a0 error) *ModuleService_Dele return _c } +func (_c *ModuleService_DeleteModule_Call) RunAndReturn(run func(context.Context, string) error) *ModuleService_DeleteModule_Call { + _c.Call.Return(run) + return _c +} + // GetModule provides a mock function with given fields: ctx, urn func (_m *ModuleService) GetModule(ctx context.Context, urn string) (*module.Module, error) { ret := _m.Called(ctx, urn) var r0 *module.Module + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*module.Module, error)); ok { + return rf(ctx, urn) + } if rf, ok := ret.Get(0).(func(context.Context, string) *module.Module); ok { r0 = rf(ctx, urn) } else { @@ -122,7 +139,6 @@ func (_m *ModuleService) GetModule(ctx context.Context, urn string) (*module.Mod } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { r1 = rf(ctx, urn) } else { @@ -156,11 +172,20 @@ func (_c *ModuleService_GetModule_Call) Return(_a0 *module.Module, _a1 error) *M return _c } +func (_c *ModuleService_GetModule_Call) RunAndReturn(run func(context.Context, string) (*module.Module, error)) *ModuleService_GetModule_Call { + _c.Call.Return(run) + return _c +} + // ListModules provides a mock function with given fields: ctx, project func (_m *ModuleService) ListModules(ctx context.Context, project string) ([]module.Module, error) { ret := _m.Called(ctx, project) var r0 []module.Module + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) ([]module.Module, error)); ok { + return rf(ctx, project) + } if rf, ok := ret.Get(0).(func(context.Context, string) []module.Module); ok { r0 = rf(ctx, project) } else { @@ -169,7 +194,6 @@ func (_m *ModuleService) ListModules(ctx context.Context, project string) ([]mod } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { r1 = rf(ctx, project) } else { @@ -203,11 +227,20 @@ func (_c *ModuleService_ListModules_Call) Return(_a0 []module.Module, _a1 error) return _c } +func (_c *ModuleService_ListModules_Call) RunAndReturn(run func(context.Context, string) ([]module.Module, error)) *ModuleService_ListModules_Call { + _c.Call.Return(run) + return _c +} + // UpdateModule provides a mock function with given fields: ctx, urn, newConfigs func (_m *ModuleService) UpdateModule(ctx context.Context, urn string, newConfigs json.RawMessage) (*module.Module, error) { ret := _m.Called(ctx, urn, newConfigs) var r0 *module.Module + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, json.RawMessage) (*module.Module, error)); ok { + return rf(ctx, urn, newConfigs) + } if rf, ok := ret.Get(0).(func(context.Context, string, json.RawMessage) *module.Module); ok { r0 = rf(ctx, urn, newConfigs) } else { @@ -216,7 +249,6 @@ func (_m *ModuleService) UpdateModule(ctx context.Context, urn string, newConfig } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, string, json.RawMessage) error); ok { r1 = rf(ctx, urn, newConfigs) } else { @@ -251,6 +283,11 @@ func (_c *ModuleService_UpdateModule_Call) Return(_a0 *module.Module, _a1 error) return _c } +func (_c *ModuleService_UpdateModule_Call) RunAndReturn(run func(context.Context, string, json.RawMessage) (*module.Module, error)) *ModuleService_UpdateModule_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewModuleService interface { mock.TestingT Cleanup(func()) diff --git a/internal/server/v1/mocks/resource_service.go b/internal/server/v1/mocks/resource_service.go index 637f48be..a96fb7cd 100644 --- a/internal/server/v1/mocks/resource_service.go +++ b/internal/server/v1/mocks/resource_service.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.23.1. DO NOT EDIT. package mocks @@ -29,6 +29,10 @@ func (_m *ResourceService) ApplyAction(ctx context.Context, urn string, action m ret := _m.Called(ctx, urn, action) var r0 *resource.Resource + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, module.ActionRequest) (*resource.Resource, error)); ok { + return rf(ctx, urn, action) + } if rf, ok := ret.Get(0).(func(context.Context, string, module.ActionRequest) *resource.Resource); ok { r0 = rf(ctx, urn, action) } else { @@ -37,7 +41,6 @@ func (_m *ResourceService) ApplyAction(ctx context.Context, urn string, action m } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, string, module.ActionRequest) error); ok { r1 = rf(ctx, urn, action) } else { @@ -72,11 +75,20 @@ func (_c *ResourceService_ApplyAction_Call) Return(_a0 *resource.Resource, _a1 e return _c } +func (_c *ResourceService_ApplyAction_Call) RunAndReturn(run func(context.Context, string, module.ActionRequest) (*resource.Resource, error)) *ResourceService_ApplyAction_Call { + _c.Call.Return(run) + return _c +} + // CreateResource provides a mock function with given fields: ctx, res func (_m *ResourceService) CreateResource(ctx context.Context, res resource.Resource) (*resource.Resource, error) { ret := _m.Called(ctx, res) var r0 *resource.Resource + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, resource.Resource) (*resource.Resource, error)); ok { + return rf(ctx, res) + } if rf, ok := ret.Get(0).(func(context.Context, resource.Resource) *resource.Resource); ok { r0 = rf(ctx, res) } else { @@ -85,7 +97,6 @@ func (_m *ResourceService) CreateResource(ctx context.Context, res resource.Reso } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, resource.Resource) error); ok { r1 = rf(ctx, res) } else { @@ -119,6 +130,11 @@ func (_c *ResourceService_CreateResource_Call) Return(_a0 *resource.Resource, _a return _c } +func (_c *ResourceService_CreateResource_Call) RunAndReturn(run func(context.Context, resource.Resource) (*resource.Resource, error)) *ResourceService_CreateResource_Call { + _c.Call.Return(run) + return _c +} + // DeleteResource provides a mock function with given fields: ctx, urn func (_m *ResourceService) DeleteResource(ctx context.Context, urn string) error { ret := _m.Called(ctx, urn) @@ -157,11 +173,20 @@ func (_c *ResourceService_DeleteResource_Call) Return(_a0 error) *ResourceServic return _c } +func (_c *ResourceService_DeleteResource_Call) RunAndReturn(run func(context.Context, string) error) *ResourceService_DeleteResource_Call { + _c.Call.Return(run) + return _c +} + // GetLog provides a mock function with given fields: ctx, urn, filter func (_m *ResourceService) GetLog(ctx context.Context, urn string, filter map[string]string) (<-chan module.LogChunk, error) { ret := _m.Called(ctx, urn, filter) var r0 <-chan module.LogChunk + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, map[string]string) (<-chan module.LogChunk, error)); ok { + return rf(ctx, urn, filter) + } if rf, ok := ret.Get(0).(func(context.Context, string, map[string]string) <-chan module.LogChunk); ok { r0 = rf(ctx, urn, filter) } else { @@ -170,7 +195,6 @@ func (_m *ResourceService) GetLog(ctx context.Context, urn string, filter map[st } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, string, map[string]string) error); ok { r1 = rf(ctx, urn, filter) } else { @@ -205,11 +229,20 @@ func (_c *ResourceService_GetLog_Call) Return(_a0 <-chan module.LogChunk, _a1 er return _c } +func (_c *ResourceService_GetLog_Call) RunAndReturn(run func(context.Context, string, map[string]string) (<-chan module.LogChunk, error)) *ResourceService_GetLog_Call { + _c.Call.Return(run) + return _c +} + // GetResource provides a mock function with given fields: ctx, urn func (_m *ResourceService) GetResource(ctx context.Context, urn string) (*resource.Resource, error) { ret := _m.Called(ctx, urn) var r0 *resource.Resource + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*resource.Resource, error)); ok { + return rf(ctx, urn) + } if rf, ok := ret.Get(0).(func(context.Context, string) *resource.Resource); ok { r0 = rf(ctx, urn) } else { @@ -218,7 +251,6 @@ func (_m *ResourceService) GetResource(ctx context.Context, urn string) (*resour } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { r1 = rf(ctx, urn) } else { @@ -252,11 +284,20 @@ func (_c *ResourceService_GetResource_Call) Return(_a0 *resource.Resource, _a1 e return _c } +func (_c *ResourceService_GetResource_Call) RunAndReturn(run func(context.Context, string) (*resource.Resource, error)) *ResourceService_GetResource_Call { + _c.Call.Return(run) + return _c +} + // GetRevisions provides a mock function with given fields: ctx, selector func (_m *ResourceService) GetRevisions(ctx context.Context, selector resource.RevisionsSelector) ([]resource.Revision, error) { ret := _m.Called(ctx, selector) var r0 []resource.Revision + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, resource.RevisionsSelector) ([]resource.Revision, error)); ok { + return rf(ctx, selector) + } if rf, ok := ret.Get(0).(func(context.Context, resource.RevisionsSelector) []resource.Revision); ok { r0 = rf(ctx, selector) } else { @@ -265,7 +306,6 @@ func (_m *ResourceService) GetRevisions(ctx context.Context, selector resource.R } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, resource.RevisionsSelector) error); ok { r1 = rf(ctx, selector) } else { @@ -299,11 +339,20 @@ func (_c *ResourceService_GetRevisions_Call) Return(_a0 []resource.Revision, _a1 return _c } +func (_c *ResourceService_GetRevisions_Call) RunAndReturn(run func(context.Context, resource.RevisionsSelector) ([]resource.Revision, error)) *ResourceService_GetRevisions_Call { + _c.Call.Return(run) + return _c +} + // ListResources provides a mock function with given fields: ctx, filter func (_m *ResourceService) ListResources(ctx context.Context, filter resource.Filter) ([]resource.Resource, error) { ret := _m.Called(ctx, filter) var r0 []resource.Resource + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, resource.Filter) ([]resource.Resource, error)); ok { + return rf(ctx, filter) + } if rf, ok := ret.Get(0).(func(context.Context, resource.Filter) []resource.Resource); ok { r0 = rf(ctx, filter) } else { @@ -312,7 +361,6 @@ func (_m *ResourceService) ListResources(ctx context.Context, filter resource.Fi } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, resource.Filter) error); ok { r1 = rf(ctx, filter) } else { @@ -346,11 +394,20 @@ func (_c *ResourceService_ListResources_Call) Return(_a0 []resource.Resource, _a return _c } +func (_c *ResourceService_ListResources_Call) RunAndReturn(run func(context.Context, resource.Filter) ([]resource.Resource, error)) *ResourceService_ListResources_Call { + _c.Call.Return(run) + return _c +} + // UpdateResource provides a mock function with given fields: ctx, urn, req func (_m *ResourceService) UpdateResource(ctx context.Context, urn string, req resource.UpdateRequest) (*resource.Resource, error) { ret := _m.Called(ctx, urn, req) var r0 *resource.Resource + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, resource.UpdateRequest) (*resource.Resource, error)); ok { + return rf(ctx, urn, req) + } if rf, ok := ret.Get(0).(func(context.Context, string, resource.UpdateRequest) *resource.Resource); ok { r0 = rf(ctx, urn, req) } else { @@ -359,7 +416,6 @@ func (_m *ResourceService) UpdateResource(ctx context.Context, urn string, req r } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, string, resource.UpdateRequest) error); ok { r1 = rf(ctx, urn, req) } else { @@ -394,6 +450,11 @@ func (_c *ResourceService_UpdateResource_Call) Return(_a0 *resource.Resource, _a return _c } +func (_c *ResourceService_UpdateResource_Call) RunAndReturn(run func(context.Context, string, resource.UpdateRequest) (*resource.Resource, error)) *ResourceService_UpdateResource_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewResourceService interface { mock.TestingT Cleanup(func()) diff --git a/internal/store/postgres/postgres.go b/internal/store/postgres/postgres.go index 0110071b..6dd4a3f1 100644 --- a/internal/store/postgres/postgres.go +++ b/internal/store/postgres/postgres.go @@ -3,8 +3,11 @@ package postgres import ( "context" _ "embed" + "time" "github.com/jmoiron/sqlx" + + "github.com/goto/entropy/pkg/errors" ) const ( @@ -25,7 +28,9 @@ const ( var schema string type Store struct { - db *sqlx.DB + db *sqlx.DB + extendInterval time.Duration + refreshInterval time.Duration } func (st *Store) Migrate(ctx context.Context) error { @@ -35,11 +40,20 @@ func (st *Store) Migrate(ctx context.Context) error { func (st *Store) Close() error { return st.db.Close() } -// Open returns store instance backed by PostgreSQL. -func Open(conStr string) (*Store, error) { +// Open returns store instance backed by PostgresQL. +func Open(conStr string, refreshInterval, extendInterval time.Duration) (*Store, error) { db, err := sqlx.Open("postgres", conStr) if err != nil { return nil, err } - return &Store{db: db}, nil + + if refreshInterval >= extendInterval { + return nil, errors.New("refreshInterval must be lower than extendInterval") + } + + return &Store{ + db: db, + extendInterval: extendInterval, + refreshInterval: refreshInterval, + }, nil } diff --git a/internal/store/postgres/resource_model.go b/internal/store/postgres/resource_model.go index 543396bf..0f980010 100644 --- a/internal/store/postgres/resource_model.go +++ b/internal/store/postgres/resource_model.go @@ -3,6 +3,7 @@ package postgres import ( "context" "database/sql" + "encoding/json" "time" sq "github.com/Masterminds/squirrel" @@ -12,23 +13,26 @@ import ( ) type resourceModel struct { - ID int64 `db:"id"` - URN string `db:"urn"` - Kind string `db:"kind"` - Name string `db:"name"` - Project string `db:"project"` - CreatedAt time.Time `db:"created_at"` - UpdatedAt time.Time `db:"updated_at"` - SpecConfigs []byte `db:"spec_configs"` - StateStatus string `db:"state_status"` - StateOutput []byte `db:"state_output"` - StateModuleData []byte `db:"state_module_data"` + ID int64 `db:"id"` + URN string `db:"urn"` + Kind string `db:"kind"` + Name string `db:"name"` + Project string `db:"project"` + CreatedAt time.Time `db:"created_at"` + UpdatedAt time.Time `db:"updated_at"` + SpecConfigs []byte `db:"spec_configs"` + StateStatus string `db:"state_status"` + StateOutput []byte `db:"state_output"` + StateModuleData []byte `db:"state_module_data"` + StateNextSync *time.Time `db:"state_next_sync"` + StateSyncResult json.RawMessage `db:"state_sync_result"` } func readResourceRecord(ctx context.Context, r sqlx.QueryerContext, urn string, into *resourceModel) error { cols := []string{ "id", "urn", "kind", "project", "name", "created_at", "updated_at", "spec_configs", "state_status", "state_output", "state_module_data", + "state_next_sync", "state_sync_result", } builder := sq.Select(cols...).From(tableResources).Where(sq.Eq{"urn": urn}) diff --git a/internal/store/postgres/resource_store.go b/internal/store/postgres/resource_store.go index a2aa6b8d..093a1de5 100644 --- a/internal/store/postgres/resource_store.go +++ b/internal/store/postgres/resource_store.go @@ -3,6 +3,8 @@ package postgres import ( "context" "database/sql" + "encoding/json" + "time" sq "github.com/Masterminds/squirrel" "github.com/jmoiron/sqlx" @@ -36,6 +38,15 @@ func (st *Store) GetByURN(ctx context.Context, urn string) (*resource.Resource, return nil, txErr } + var syncResult resource.SyncResult + if len(rec.StateSyncResult) > 0 { + if err := json.Unmarshal(rec.StateSyncResult, &syncResult); err != nil { + return nil, errors.ErrInternal. + WithMsgf("failed to json unmarshal state_sync_result"). + WithCausef(err.Error()) + } + } + return &resource.Resource{ URN: rec.URN, Kind: rec.Kind, @@ -52,6 +63,8 @@ func (st *Store) GetByURN(ctx context.Context, urn string) (*resource.Resource, Status: rec.StateStatus, Output: rec.StateOutput, ModuleData: rec.StateModuleData, + NextSyncAt: rec.StateNextSync, + SyncResult: syncResult, }, }, nil } @@ -118,10 +131,10 @@ func (st *Store) Create(ctx context.Context, r resource.Resource, hooks ...resou URN: r.URN, Spec: r.Spec, Labels: r.Labels, - Reason: "resource created", + Reason: "action:create", } - if err := insertRevision(ctx, tx, rev); err != nil { + if err := insertRevision(ctx, tx, id, rev); err != nil { return translateErr(err) } @@ -150,6 +163,8 @@ func (st *Store) Update(ctx context.Context, r resource.Resource, saveRevision b "state_status": r.State.Status, "state_output": r.State.Output, "state_module_data": r.State.ModuleData, + "state_next_sync": r.State.NextSyncAt, + "state_sync_result": syncResultAsJSON(r.State.SyncResult), }). PlaceholderFormat(sq.Dollar) @@ -173,7 +188,7 @@ func (st *Store) Update(ctx context.Context, r resource.Resource, saveRevision b Reason: reason, } - if err := insertRevision(ctx, tx, rev); err != nil { + if err := insertRevision(ctx, tx, id, rev); err != nil { return translateErr(err) } } @@ -219,17 +234,113 @@ func (st *Store) Delete(ctx context.Context, urn string, hooks ...resource.Mutat return withinTx(ctx, st.db, false, deleteFn) } -func insertResourceRecord(ctx context.Context, runner sq.BaseRunner, r resource.Resource) (int64, error) { - q := sq.Insert(tableResources). +func (st *Store) SyncOne(ctx context.Context, syncFn resource.SyncFn) error { + urn, err := st.fetchResourceForSync(ctx) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + // No resource available for sync. + return nil + } + return err + } + + cur, err := st.GetByURN(ctx, urn) + if err != nil { + return err + } + + synced, err := st.handleDequeued(ctx, *cur, syncFn) + if err != nil { + return err + } + + return st.Update(ctx, *synced, false, "sync") +} + +func (st *Store) handleDequeued(baseCtx context.Context, res resource.Resource, fn resource.SyncFn) (*resource.Resource, error) { + runCtx, cancel := context.WithCancel(baseCtx) + defer cancel() + + // Run heartbeat to keep the resource being picked up by some other syncer + // thread. If heartbeat exits, runCtx will be cancelled and fn should exit. + go st.runHeartbeat(runCtx, cancel, res.URN) + + return fn(runCtx, res) +} + +func (st *Store) fetchResourceForSync(ctx context.Context) (string, error) { + var urn string + + // find a resource ready for sync, extend it next sync time atomically. + // this ensures multiple workers do not pick up same resources for sync. + err := withinTx(ctx, st.db, false, func(ctx context.Context, tx *sqlx.Tx) error { + builder := sq. + Select("urn"). + From(tableResources). + Where(sq.Expr("state_next_sync <= current_timestamp")). + Suffix("FOR UPDATE SKIP LOCKED") + + query, args, err := builder.PlaceholderFormat(sq.Dollar).ToSql() + if err != nil { + return err + } + + if err := st.db.QueryRowxContext(ctx, query, args...).Scan(&urn); err != nil { + return err + } + + return st.extendWaitTime(ctx, tx, urn) + }) + + return urn, err +} + +func (st *Store) runHeartbeat(ctx context.Context, cancel context.CancelFunc, id string) { + defer cancel() + + tick := time.NewTicker(st.refreshInterval) + defer tick.Stop() + + for { + select { + case <-ctx.Done(): + return + + case <-tick.C: + if err := st.extendWaitTime(ctx, st.db, id); err != nil { + return + } + } + } +} + +func (st *Store) extendWaitTime(ctx context.Context, r sq.BaseRunner, urn string) error { + extendTo := sq.Expr("current_timestamp + (? ||' seconds')::interval ", st.extendInterval.Seconds()) + extendQuery := sq.Update(tableResources). + Set("state_next_sync", extendTo). + Where(sq.Eq{"urn": urn}) + + _, err := extendQuery.PlaceholderFormat(sq.Dollar).RunWith(r).ExecContext(ctx) + return err +} + +func insertResourceRecord(ctx context.Context, runner sqlx.QueryerContext, r resource.Resource) (int64, error) { + builder := sq.Insert(tableResources). Columns("urn", "kind", "project", "name", "created_at", "updated_at", - "spec_configs", "state_status", "state_output", "state_module_data"). + "spec_configs", "state_status", "state_output", "state_module_data", + "state_next_sync", "state_sync_result"). Values(r.URN, r.Kind, r.Project, r.Name, r.CreatedAt, r.UpdatedAt, - r.Spec.Configs, r.State.Status, r.State.Output, r.State.ModuleData). - Suffix(`RETURNING "id"`). - PlaceholderFormat(sq.Dollar) + r.Spec.Configs, r.State.Status, r.State.Output, r.State.ModuleData, + r.State.NextSyncAt, syncResultAsJSON(r.State.SyncResult)). + Suffix(`RETURNING "id"`) + + q, args, err := builder.PlaceholderFormat(sq.Dollar).ToSql() + if err != nil { + return 0, err + } var id int64 - if err := q.RunWith(runner).QueryRowContext(ctx).Scan(&id); err != nil { + if err := runner.QueryRowxContext(ctx, q, args...).Scan(&id); err != nil { return 0, err } return id, nil @@ -265,3 +376,14 @@ func setDependencies(ctx context.Context, runner sq.BaseRunner, id int64, deps m return nil } + +func syncResultAsJSON(syncRes resource.SyncResult) json.RawMessage { + if syncRes == (resource.SyncResult{}) { + return nil + } + val, err := json.Marshal(syncRes) + if err != nil { + panic(err) + } + return val +} diff --git a/internal/store/postgres/revision_model.go b/internal/store/postgres/revision_model.go index fd222576..dcd26111 100644 --- a/internal/store/postgres/revision_model.go +++ b/internal/store/postgres/revision_model.go @@ -2,41 +2,19 @@ package postgres import ( "context" - "database/sql" "time" sq "github.com/Masterminds/squirrel" - "github.com/jmoiron/sqlx" - - "github.com/goto/entropy/pkg/errors" ) type revisionModel struct { ID int64 `db:"id"` - URN string `db:"urn"` Reason string `db:"reason"` CreatedAt time.Time `db:"created_at"` + ResourceID int64 `db:"resource_id"` SpecConfigs []byte `db:"spec_configs"` } -func readRevisionRecord(ctx context.Context, r sqlx.QueryerContext, id int64, into *revisionModel) error { - cols := []string{"id", "urn", "reason", "created_at", "spec_configs"} - builder := sq.Select(cols...).From(tableRevisions).Where(sq.Eq{"id": id}) - - query, args, err := builder.PlaceholderFormat(sq.Dollar).ToSql() - if err != nil { - return err - } - - if err := r.QueryRowxContext(ctx, query, args...).StructScan(into); err != nil { - if errors.Is(err, sql.ErrNoRows) { - return errors.ErrNotFound - } - return err - } - return nil -} - func readRevisionTags(ctx context.Context, r sq.BaseRunner, revisionID int64, into *[]string) error { return readTags(ctx, r, tableRevisionTags, columnRevisionID, revisionID, into) } diff --git a/internal/store/postgres/revision_store.go b/internal/store/postgres/revision_store.go index 116e9d1d..35e94b2f 100644 --- a/internal/store/postgres/revision_store.go +++ b/internal/store/postgres/revision_store.go @@ -12,103 +12,83 @@ import ( ) func (st *Store) Revisions(ctx context.Context, selector resource.RevisionsSelector) ([]resource.Revision, error) { - q := sq.Select("id"). - From(tableRevisions). - Where(sq.Eq{"urn": selector.URN}) - - rows, err := q.PlaceholderFormat(sq.Dollar).RunWith(st.db).QueryContext(ctx) - if err != nil { - if errors.Is(err, sql.ErrNoRows) { - return nil, nil - } - return nil, err - } - defer rows.Close() - var revs []resource.Revision - for rows.Next() { - var id int64 - if err := rows.Scan(&id); err != nil { - return nil, err - } - - r, err := st.getRevisionByID(ctx, id) + txFn := func(ctx context.Context, tx *sqlx.Tx) error { + resourceID, err := translateURNToID(ctx, tx, selector.URN) if err != nil { - return nil, err - } - revs = append(revs, *r) - } - - return revs, rows.Err() -} - -func (st *Store) getRevisionByID(ctx context.Context, id int64) (*resource.Revision, error) { - var rec revisionModel - var tags []string - deps := map[string]string{} - - readRevisionParts := func(ctx context.Context, tx *sqlx.Tx) error { - if err := readRevisionRecord(ctx, tx, id, &rec); err != nil { return err } - if err := readRevisionTags(ctx, tx, rec.ID, &tags); err != nil { + deps := map[string]string{} + if err := readResourceDeps(ctx, tx, resourceID, deps); err != nil { return err } - resourceID, err := translateURNToID(ctx, tx, rec.URN) + builder := sq.Select("*"). + From(tableRevisions). + Where(sq.Eq{"resource_id": resourceID}). + OrderBy("created_at DESC") + + q, args, err := builder.PlaceholderFormat(sq.Dollar).ToSql() if err != nil { return err } - if err := readResourceDeps(ctx, tx, resourceID, deps); err != nil { + rows, err := tx.QueryxContext(ctx, q, args...) + if err != nil { return err } + defer func() { _ = rows.Close() }() + + for rows.Next() { + var rm revisionModel + if err := rows.StructScan(&rm); err != nil { + return err + } + + var tags []string + if err := readRevisionTags(ctx, tx, rm.ID, &tags); err != nil { + return err + } + + revs = append(revs, resource.Revision{ + ID: rm.ID, + URN: selector.URN, + Reason: rm.Reason, + Labels: tagsToLabelMap(tags), + CreatedAt: rm.CreatedAt, + Spec: resource.Spec{ + Configs: rm.SpecConfigs, + Dependencies: deps, + }, + }) + } return nil } - if txErr := withinTx(ctx, st.db, true, readRevisionParts); txErr != nil { - return nil, txErr - } - - return &resource.Revision{ - ID: rec.ID, - URN: rec.URN, - Reason: rec.Reason, - Labels: tagsToLabelMap(tags), - CreatedAt: rec.CreatedAt, - Spec: resource.Spec{ - Configs: rec.SpecConfigs, - Dependencies: deps, - }, - }, nil -} - -func insertRevision(ctx context.Context, tx *sqlx.Tx, rev resource.Revision) error { - revisionID, err := insertRevisionRecord(ctx, tx, rev) - if err != nil { - return err - } - - if err := setRevisionTags(ctx, tx, revisionID, rev.Labels); err != nil { - return err + if err := withinTx(ctx, st.db, true, txFn); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, nil + } + return nil, err } - return nil + return revs, nil } -func insertRevisionRecord(ctx context.Context, runner sq.BaseRunner, r resource.Revision) (int64, error) { +func insertRevision(ctx context.Context, tx *sqlx.Tx, resID int64, rev resource.Revision) error { q := sq.Insert(tableRevisions). - Columns("urn", "reason", "spec_configs"). - Values(r.URN, r.Reason, r.Spec.Configs). + Columns("resource_id", "reason", "spec_configs"). + Values(resID, rev.Reason, rev.Spec.Configs). Suffix(`RETURNING "id"`). PlaceholderFormat(sq.Dollar) - var id int64 - if err := q.RunWith(runner).QueryRowContext(ctx).Scan(&id); err != nil { - return 0, err + var revisionID int64 + if err := q.RunWith(tx).QueryRowContext(ctx).Scan(&revisionID); err != nil { + return err } - return id, nil + + return setRevisionTags(ctx, tx, revisionID, rev.Labels) } func setRevisionTags(ctx context.Context, runner sq.BaseRunner, id int64, labels map[string]string) error { diff --git a/internal/store/postgres/schema.sql b/internal/store/postgres/schema.sql index 6f7c6f06..3e2a8e8b 100644 --- a/internal/store/postgres/schema.sql +++ b/internal/store/postgres/schema.sql @@ -1,35 +1,49 @@ -CREATE TABLE IF NOT EXISTS resources +CREATE TABLE IF NOT EXISTS modules ( - id BIGSERIAL NOT NULL PRIMARY KEY, - urn TEXT NOT NULL UNIQUE, - kind TEXT NOT NULL, - name TEXT NOT NULL, - project TEXT NOT NULL, - created_at timestamp NOT NULL DEFAULT current_timestamp, - updated_at timestamp NOT NULL DEFAULT current_timestamp, - spec_configs bytea NOT NULL, - state_status TEXT NOT NULL, - state_output bytea NOT NULL, - state_module_data bytea NOT NULL + urn TEXT NOT NULL PRIMARY KEY, + name TEXT NOT NULL, + project TEXT NOT NULL, + configs bytea NOT NULL, + created_at timestamptz NOT NULL DEFAULT current_timestamp, + updated_at timestamptz NOT NULL DEFAULT current_timestamp ); +CREATE INDEX IF NOT EXISTS idx_modules_project ON modules (project); +CREATE TABLE IF NOT EXISTS resources +( + id BIGSERIAL NOT NULL PRIMARY KEY, + urn TEXT NOT NULL UNIQUE, + kind TEXT NOT NULL, + name TEXT NOT NULL, + project TEXT NOT NULL, + created_at timestamptz NOT NULL DEFAULT current_timestamp, + updated_at timestamptz NOT NULL DEFAULT current_timestamp, + spec_configs bytea NOT NULL, + state_status TEXT NOT NULL, + state_output bytea NOT NULL, + state_module_data bytea NOT NULL, + state_next_sync timestamptz, + state_sync_result bytea +); CREATE INDEX IF NOT EXISTS idx_resources_kind ON resources (kind); -CREATE INDEX IF NOT EXISTS idx_resources_name ON resources (name); CREATE INDEX IF NOT EXISTS idx_resources_project ON resources (project); CREATE INDEX IF NOT EXISTS idx_resources_state_status ON resources (state_status); +CREATE INDEX IF NOT EXISTS idx_resources_next_sync ON resources (state_next_sync); CREATE TABLE IF NOT EXISTS resource_dependencies ( resource_id BIGINT NOT NULL REFERENCES resources (id), dependency_key TEXT NOT NULL, depends_on BIGINT NOT NULL REFERENCES resources (id), + UNIQUE (resource_id, dependency_key) ); CREATE TABLE IF NOT EXISTS resource_tags ( - resource_id BIGINT NOT NULL REFERENCES resources (id), tag TEXT NOT NULL, + resource_id BIGINT NOT NULL REFERENCES resources (id), + UNIQUE (resource_id, tag) ); CREATE INDEX IF NOT EXISTS idx_resource_tags_resource_id ON resource_tags (resource_id); @@ -37,33 +51,21 @@ CREATE INDEX IF NOT EXISTS idx_resource_tags_tag ON resource_tags (tag); CREATE TABLE IF NOT EXISTS revisions ( - id BIGSERIAL NOT NULL PRIMARY KEY, - urn TEXT NOT NULL, - spec_configs bytea NOT NULL, - created_at timestamp NOT NULL DEFAULT current_timestamp + id BIGSERIAL NOT NULL PRIMARY KEY, + reason TEXT NOT NULL DEFAULT '', + created_at timestamptz NOT NULL DEFAULT current_timestamp, + resource_id BIGINT NOT NULL REFERENCES resources (id), + spec_configs bytea NOT NULL ); - -CREATE INDEX IF NOT EXISTS idx_revisions_urn ON revisions (urn); +CREATE INDEX IF NOT EXISTS idx_revisions_resource_id ON revisions (resource_id); CREATE INDEX IF NOT EXISTS idx_revisions_created_at ON revisions (created_at); CREATE TABLE IF NOT EXISTS revision_tags ( - revision_id BIGINT NOT NULL REFERENCES revisions (id), tag TEXT NOT NULL, + revision_id BIGINT NOT NULL REFERENCES revisions (id), + UNIQUE (revision_id, tag) ); CREATE INDEX IF NOT EXISTS idx_revision_tags_revision_id ON revision_tags (revision_id); -CREATE INDEX IF NOT EXISTS idx_revision_tags_tag ON revision_tags (tag); - --- -CREATE TABLE IF NOT EXISTS modules ( - urn TEXT NOT NULL PRIMARY KEY, - name TEXT NOT NULL, - project TEXT NOT NULL, - configs jsonb NOT NULL, - created_at timestamp with time zone NOT NULL DEFAULT current_timestamp, - updated_at timestamp with time zone NOT NULL DEFAULT current_timestamp -); - -CREATE INDEX IF NOT EXISTS idx_modules_project ON modules (project); -ALTER TABLE revisions ADD COLUMN IF NOT EXISTS reason TEXT DEFAULT '' NOT NULL; +CREATE INDEX IF NOT EXISTS idx_revision_tags_tag ON revision_tags (tag); \ No newline at end of file diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index d01cce3b..d74e3da9 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "strings" + "time" "github.com/goto/entropy/core/module" "github.com/goto/entropy/modules/kubernetes" @@ -38,6 +39,7 @@ var defaultDriverConf = driverConf{ } type firehoseDriver struct { + timeNow func() time.Time conf driverConf kubeDeploy kubeDeployFn kubeGetPod kubeGetPodFn diff --git a/modules/firehose/driver_output_test.go b/modules/firehose/driver_output_test.go index ddcd0b19..68209f46 100644 --- a/modules/firehose/driver_output_test.go +++ b/modules/firehose/driver_output_test.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -123,7 +124,8 @@ func TestFirehoseDriver_Output(t *testing.T) { for _, tt := range table { t.Run(tt.title, func(t *testing.T) { fd := &firehoseDriver{ - conf: defaultDriverConf, + conf: defaultDriverConf, + timeNow: func() time.Time { return frozenTime }, } if tt.kubeGetPod != nil { fd.kubeGetPod = tt.kubeGetPod(t) diff --git a/modules/firehose/driver_plan.go b/modules/firehose/driver_plan.go index a5f28918..926f0ceb 100644 --- a/modules/firehose/driver_plan.go +++ b/modules/firehose/driver_plan.go @@ -3,7 +3,6 @@ package firehose import ( "context" "encoding/json" - "fmt" "github.com/goto/entropy/core/module" "github.com/goto/entropy/core/resource" @@ -11,7 +10,7 @@ import ( "github.com/goto/entropy/pkg/kafka" ) -func (fd *firehoseDriver) Plan(_ context.Context, exr module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { +func (fd *firehoseDriver) Plan(_ context.Context, exr module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) { switch act.Name { case module.CreateAction: return fd.planCreate(exr, act) @@ -24,13 +23,12 @@ func (fd *firehoseDriver) Plan(_ context.Context, exr module.ExpandedResource, a } } -func (fd *firehoseDriver) planChange(exr module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { +func (fd *firehoseDriver) planChange(exr module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) { curConf, err := readConfig(exr.Resource, exr.Resource.Spec.Configs) if err != nil { return nil, err } - enqueueSteps := []string{stepReleaseUpdate} switch act.Name { case module.UpdateAction: newConf, err := readConfig(exr.Resource, act.Params) @@ -64,11 +62,10 @@ func (fd *firehoseDriver) planChange(exr module.ExpandedResource, act module.Act curConf.Replicas = scaleParams.Replicas case StartAction: - // nothing to do here since stepReleaseUpdate will automatically - // start the firehose with last known value of 'replicas'. + curConf.Stopped = false case StopAction: - enqueueSteps = []string{stepReleaseStop} + curConf.Stopped = true case UpgradeAction: // upgrade the chart values to the latest project-level config. @@ -76,22 +73,22 @@ func (fd *firehoseDriver) planChange(exr module.ExpandedResource, act module.Act curConf.ChartValues = &fd.conf.ChartValues } + immediately := fd.timeNow() + exr.Resource.Spec.Configs = mustJSON(curConf) exr.Resource.State = resource.State{ Status: resource.StatusPending, Output: exr.Resource.State.Output, ModuleData: mustJSON(transientData{ - PendingSteps: enqueueSteps, + PendingSteps: []string{stepReleaseUpdate}, }), + NextSyncAt: &immediately, } - return &module.Plan{ - Reason: fmt.Sprintf("firehose_%s", act.Name), - Resource: exr.Resource, - }, nil + return &exr.Resource, nil } -func (fd *firehoseDriver) planCreate(exr module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { +func (fd *firehoseDriver) planCreate(exr module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) { conf, err := readConfig(exr.Resource, act.Params) if err != nil { return nil, err @@ -107,6 +104,8 @@ func (fd *firehoseDriver) planCreate(exr module.ExpandedResource, act module.Act conf.Namespace = fd.conf.Namespace conf.ChartValues = chartVals + immediately := fd.timeNow() + exr.Resource.Spec.Configs = mustJSON(conf) exr.Resource.State = resource.State{ Status: resource.StatusPending, @@ -114,37 +113,35 @@ func (fd *firehoseDriver) planCreate(exr module.ExpandedResource, act module.Act Namespace: conf.Namespace, ReleaseName: conf.DeploymentID, }), + NextSyncAt: &immediately, ModuleData: mustJSON(transientData{ PendingSteps: []string{stepReleaseCreate}, }), } - return &module.Plan{ - Reason: "firehose_create", - Resource: exr.Resource, - }, nil + return &exr.Resource, nil } -func (*firehoseDriver) planReset(exr module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { +func (fd *firehoseDriver) planReset(exr module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) { resetValue, err := kafka.ParseResetParams(act.Params) if err != nil { return nil, err } + immediately := fd.timeNow() + exr.Resource.State = resource.State{ - Status: resource.StatusPending, - Output: exr.Resource.State.Output, + Status: resource.StatusPending, + Output: exr.Resource.State.Output, + NextSyncAt: &immediately, ModuleData: mustJSON(transientData{ ResetOffsetTo: resetValue, PendingSteps: []string{ - stepReleaseStop, + stepReleaseStop, // stop the firehose stepKafkaReset, // reset the consumer group offset value. stepReleaseUpdate, // restart the deployment. }, }), } - return &module.Plan{ - Reason: "firehose_reset", - Resource: exr.Resource, - }, nil + return &exr.Resource, nil } diff --git a/modules/firehose/driver_plan_test.go b/modules/firehose/driver_plan_test.go index 0629aeef..40343927 100644 --- a/modules/firehose/driver_plan_test.go +++ b/modules/firehose/driver_plan_test.go @@ -3,6 +3,7 @@ package firehose import ( "context" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -12,6 +13,8 @@ import ( "github.com/goto/entropy/pkg/errors" ) +var frozenTime = time.Unix(1679668743, 0) + func TestFirehoseDriver_Plan(t *testing.T) { t.Parallel() @@ -19,7 +22,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { title string exr module.ExpandedResource act module.ActionRequest - want *module.Plan + want *resource.Resource wantErr error }{ // create action tests @@ -63,47 +66,45 @@ func TestFirehoseDriver_Plan(t *testing.T) { }, }), }, - want: &module.Plan{ - Resource: resource.Resource{ - URN: "urn:goto:entropy:ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz", - Kind: "firehose", - Name: "abcdefghijklmnopqrstuvwxyz", - Project: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", - Spec: resource.Spec{ - Configs: mustJSON(map[string]any{ - "stopped": false, - "replicas": 1, - "namespace": "firehose", - "deployment_id": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099", - "telegraf": map[string]any{ - "enabled": false, - }, - "chart_values": map[string]string{ - "chart_version": "0.1.3", - "image_pull_policy": "IfNotPresent", - "image_tag": "latest", - }, - "env_variables": map[string]string{ - "SINK_TYPE": "LOG", - "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", - "SOURCE_KAFKA_CONSUMER_GROUP_ID": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099-0001", - "SOURCE_KAFKA_BROKERS": "localhost:9092", - "SOURCE_KAFKA_TOPIC": "foo-log", - }, - }), - }, - State: resource.State{ - Status: resource.StatusPending, - Output: mustJSON(Output{ - Namespace: "firehose", - ReleaseName: "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099", - }), - ModuleData: mustJSON(transientData{ - PendingSteps: []string{stepReleaseCreate}, - }), - }, + want: &resource.Resource{ + URN: "urn:goto:entropy:ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz", + Kind: "firehose", + Name: "abcdefghijklmnopqrstuvwxyz", + Project: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "stopped": false, + "replicas": 1, + "namespace": "firehose", + "deployment_id": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099", + "telegraf": map[string]any{ + "enabled": false, + }, + "chart_values": map[string]string{ + "chart_version": "0.1.3", + "image_pull_policy": "IfNotPresent", + "image_tag": "latest", + }, + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099-0001", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{ + Namespace: "firehose", + ReleaseName: "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099", + }), + ModuleData: mustJSON(transientData{ + PendingSteps: []string{stepReleaseCreate}, + }), + NextSyncAt: &frozenTime, }, - Reason: "firehose_create", }, wantErr: nil, }, @@ -130,47 +131,45 @@ func TestFirehoseDriver_Plan(t *testing.T) { }, }), }, - want: &module.Plan{ - Resource: resource.Resource{ - URN: "urn:goto:entropy:foo:fh1", - Kind: "firehose", - Name: "fh1", - Project: "foo", - Spec: resource.Spec{ - Configs: mustJSON(map[string]any{ - "stopped": false, - "replicas": 1, - "namespace": "firehose", - "deployment_id": "firehose-foo-fh1", - "telegraf": map[string]any{ - "enabled": false, - }, - "chart_values": map[string]string{ - "chart_version": "0.1.3", - "image_pull_policy": "IfNotPresent", - "image_tag": "latest", - }, - "env_variables": map[string]string{ - "SINK_TYPE": "LOG", - "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", - "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", - "SOURCE_KAFKA_BROKERS": "localhost:9092", - "SOURCE_KAFKA_TOPIC": "foo-log", - }, - }), - }, - State: resource.State{ - Status: resource.StatusPending, - Output: mustJSON(Output{ - Namespace: "firehose", - ReleaseName: "firehose-foo-fh1", - }), - ModuleData: mustJSON(transientData{ - PendingSteps: []string{stepReleaseCreate}, - }), - }, + want: &resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "stopped": false, + "replicas": 1, + "namespace": "firehose", + "deployment_id": "firehose-foo-fh1", + "telegraf": map[string]any{ + "enabled": false, + }, + "chart_values": map[string]string{ + "chart_version": "0.1.3", + "image_pull_policy": "IfNotPresent", + "image_tag": "latest", + }, + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{ + Namespace: "firehose", + ReleaseName: "firehose-foo-fh1", + }), + ModuleData: mustJSON(transientData{ + PendingSteps: []string{stepReleaseCreate}, + }), + NextSyncAt: &frozenTime, }, - Reason: "firehose_create", }, wantErr: nil, }, @@ -218,38 +217,36 @@ func TestFirehoseDriver_Plan(t *testing.T) { }, }), }, - want: &module.Plan{ - Resource: resource.Resource{ - URN: "urn:goto:entropy:foo:fh1", - Kind: "firehose", - Name: "fh1", - Project: "foo", - Spec: resource.Spec{ - Configs: mustJSON(map[string]any{ - "stopped": false, - "replicas": 10, - "deployment_id": "firehose-deployment-x", - "env_variables": map[string]string{ - "SINK_TYPE": "HTTP", - "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", - "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", - "SOURCE_KAFKA_BROKERS": "localhost:9092", - "SOURCE_KAFKA_TOPIC": "foo-log", - }, - }), - }, - State: resource.State{ - Status: resource.StatusPending, - Output: mustJSON(Output{ - Namespace: "foo", - ReleaseName: "bar", - }), - ModuleData: mustJSON(transientData{ - PendingSteps: []string{stepReleaseUpdate}, - }), - }, + want: &resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "stopped": false, + "replicas": 10, + "deployment_id": "firehose-deployment-x", + "env_variables": map[string]string{ + "SINK_TYPE": "HTTP", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{ + Namespace: "foo", + ReleaseName: "bar", + }), + ModuleData: mustJSON(transientData{ + PendingSteps: []string{stepReleaseUpdate}, + }), + NextSyncAt: &frozenTime, }, - Reason: "firehose_update", }, wantErr: nil, }, @@ -329,41 +326,39 @@ func TestFirehoseDriver_Plan(t *testing.T) { "to": "latest", }), }, - want: &module.Plan{ - Reason: "firehose_reset", - Resource: resource.Resource{ - URN: "urn:goto:entropy:foo:fh1", - Kind: "firehose", - Name: "fh1", - Project: "foo", - Spec: resource.Spec{ - Configs: mustJSON(map[string]any{ - "replicas": 1, - "deployment_id": "firehose-deployment-x", - "env_variables": map[string]string{ - "SINK_TYPE": "LOG", - "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", - "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", - "SOURCE_KAFKA_BROKERS": "localhost:9092", - "SOURCE_KAFKA_TOPIC": "foo-log", - }, - }), - }, - State: resource.State{ - Status: resource.StatusPending, - Output: mustJSON(Output{ - Namespace: "foo", - ReleaseName: "bar", - }), - ModuleData: mustJSON(transientData{ - ResetOffsetTo: "latest", - PendingSteps: []string{ - stepReleaseStop, - stepKafkaReset, - stepReleaseUpdate, - }, - }), - }, + want: &resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "replicas": 1, + "deployment_id": "firehose-deployment-x", + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{ + Namespace: "foo", + ReleaseName: "bar", + }), + ModuleData: mustJSON(transientData{ + ResetOffsetTo: "latest", + PendingSteps: []string{ + stepReleaseStop, + stepKafkaReset, + stepReleaseUpdate, + }, + }), + NextSyncAt: &frozenTime, }, }, }, @@ -408,43 +403,41 @@ func TestFirehoseDriver_Plan(t *testing.T) { act: module.ActionRequest{ Name: UpgradeAction, }, - want: &module.Plan{ - Resource: resource.Resource{ - URN: "urn:goto:entropy:foo:fh1", - Kind: "firehose", - Name: "fh1", - Project: "foo", - Spec: resource.Spec{ - Configs: mustJSON(map[string]any{ - "stopped": false, - "replicas": 1, - "deployment_id": "firehose-deployment-x", - "chart_values": map[string]string{ - "chart_version": "0.1.3", - "image_pull_policy": "IfNotPresent", - "image_tag": "latest", - }, - "env_variables": map[string]string{ - "SINK_TYPE": "LOG", - "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", - "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", - "SOURCE_KAFKA_BROKERS": "localhost:9092", - "SOURCE_KAFKA_TOPIC": "foo-log", - }, - }), - }, - State: resource.State{ - Status: resource.StatusPending, - Output: mustJSON(Output{ - Namespace: "foo", - ReleaseName: "bar", - }), - ModuleData: mustJSON(transientData{ - PendingSteps: []string{stepReleaseUpdate}, - }), - }, + want: &resource.Resource{ + URN: "urn:goto:entropy:foo:fh1", + Kind: "firehose", + Name: "fh1", + Project: "foo", + Spec: resource.Spec{ + Configs: mustJSON(map[string]any{ + "stopped": false, + "replicas": 1, + "deployment_id": "firehose-deployment-x", + "chart_values": map[string]string{ + "chart_version": "0.1.3", + "image_pull_policy": "IfNotPresent", + "image_tag": "latest", + }, + "env_variables": map[string]string{ + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + }), + }, + State: resource.State{ + Status: resource.StatusPending, + Output: mustJSON(Output{ + Namespace: "foo", + ReleaseName: "bar", + }), + ModuleData: mustJSON(transientData{ + PendingSteps: []string{stepReleaseUpdate}, + }), + NextSyncAt: &frozenTime, }, - Reason: "firehose_upgrade", }, wantErr: nil, }, @@ -496,7 +489,8 @@ func TestFirehoseDriver_Plan(t *testing.T) { for _, tt := range table { t.Run(tt.title, func(t *testing.T) { dr := &firehoseDriver{ - conf: defaultDriverConf, + conf: defaultDriverConf, + timeNow: func() time.Time { return frozenTime }, } got, err := dr.Plan(context.Background(), tt.exr, tt.act) diff --git a/modules/firehose/driver_sync.go b/modules/firehose/driver_sync.go index 038cd18a..b974732f 100644 --- a/modules/firehose/driver_sync.go +++ b/modules/firehose/driver_sync.go @@ -31,6 +31,11 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) return nil, errors.ErrInternal.WithMsgf("invalid kube state").WithCausef(err.Error()) } + finalState := resource.State{ + Status: resource.StatusPending, + Output: exr.Resource.State.Output, + } + // pickup the next pending step if available. if len(modData.PendingSteps) > 0 { pendingStep := modData.PendingSteps[0] @@ -58,24 +63,35 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) default: return nil, errors.ErrInternal.WithMsgf("unknown step: '%s'", pendingStep) } - } - finalOut, err := fd.refreshOutput(ctx, *conf, *out, kubeOut) - if err != nil { - return nil, err + // we have more pending states, so enqueue resource for another sync + // as soon as possible. + immediately := fd.timeNow() + finalState.NextSyncAt = &immediately + finalState.ModuleData = mustJSON(modData) + + return &finalState, nil } - finalState := resource.State{ - Status: resource.StatusPending, - Output: finalOut, - ModuleData: mustJSON(modData), + // even if the resource is in completed state, we check this time to + // see if the firehose is expected to be stopped by this time. + finalState.NextSyncAt = conf.StopTime + if conf.StopTime != nil && conf.StopTime.Before(fd.timeNow()) { + conf.Replicas = 0 + if err := fd.releaseSync(ctx, false, *conf, kubeOut); err != nil { + return nil, err + } + finalState.NextSyncAt = nil } - if len(modData.PendingSteps) == 0 { - finalState.Status = resource.StatusCompleted - finalState.ModuleData = nil + finalOut, err := fd.refreshOutput(ctx, *conf, *out, kubeOut) + if err != nil { + return nil, err } + finalState.Output = finalOut + finalState.Status = resource.StatusCompleted + finalState.ModuleData = nil return &finalState, nil } diff --git a/modules/firehose/driver_sync_test.go b/modules/firehose/driver_sync_test.go index 112000b6..08f6dd09 100644 --- a/modules/firehose/driver_sync_test.go +++ b/modules/firehose/driver_sync_test.go @@ -3,6 +3,7 @@ package firehose import ( "context" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -181,16 +182,12 @@ func TestFirehoseDriver_Sync(t *testing.T) { } }, want: &resource.State{ - Status: resource.StatusCompleted, - Output: mustJSON(Output{ - Pods: []kube.Pod{ - { - Name: "foo-1", - Containers: []string{"firehose"}, - }, - }, + Status: resource.StatusPending, + Output: mustJSON(Output{}), + ModuleData: mustJSON(transientData{ + PendingSteps: []string{}, }), - ModuleData: nil, + NextSyncAt: &frozenTime, }, }, { @@ -224,16 +221,12 @@ func TestFirehoseDriver_Sync(t *testing.T) { } }, want: &resource.State{ - Status: resource.StatusCompleted, - Output: mustJSON(Output{ - Pods: []kube.Pod{ - { - Name: "foo-1", - Containers: []string{"firehose"}, - }, - }, + Status: resource.StatusPending, + Output: mustJSON(Output{}), + ModuleData: mustJSON(transientData{ + PendingSteps: []string{}, }), - ModuleData: nil, + NextSyncAt: &frozenTime, }, }, } @@ -241,7 +234,8 @@ func TestFirehoseDriver_Sync(t *testing.T) { for _, tt := range table { t.Run(tt.title, func(t *testing.T) { fd := &firehoseDriver{ - conf: defaultDriverConf, + conf: defaultDriverConf, + timeNow: func() time.Time { return frozenTime }, } if tt.kubeGetPod != nil { diff --git a/modules/firehose/module.go b/modules/firehose/module.go index 2465e0ec..8c5c350d 100644 --- a/modules/firehose/module.go +++ b/modules/firehose/module.go @@ -70,7 +70,8 @@ var Module = module.Descriptor{ } return &firehoseDriver{ - conf: conf, + conf: conf, + timeNow: time.Now, kubeDeploy: func(_ context.Context, isCreate bool, kubeConf kube.Config, hc helm.ReleaseConfig) error { helmCl := helm.NewClient(&helm.Config{Kubernetes: kubeConf}) diff --git a/modules/kubernetes/driver.go b/modules/kubernetes/driver.go index 346d2717..0e5717ce 100644 --- a/modules/kubernetes/driver.go +++ b/modules/kubernetes/driver.go @@ -14,7 +14,9 @@ import ( type kubeDriver struct{} -func (m *kubeDriver) Plan(ctx context.Context, res module.ExpandedResource, act module.ActionRequest) (*module.Plan, error) { +func (m *kubeDriver) Plan(ctx context.Context, res module.ExpandedResource, + act module.ActionRequest, +) (*resource.Resource, error) { res.Resource.Spec = resource.Spec{ Configs: act.Params, Dependencies: nil, @@ -30,7 +32,7 @@ func (m *kubeDriver) Plan(ctx context.Context, res module.ExpandedResource, act Output: output, } - return &module.Plan{Resource: res.Resource, Reason: "kubernetes cluster details updated"}, nil + return &res.Resource, nil } func (*kubeDriver) Sync(_ context.Context, res module.ExpandedResource) (*resource.State, error) { diff --git a/modules/registry_test.go b/modules/registry_test.go index bf1bc7c2..08e160e3 100644 --- a/modules/registry_test.go +++ b/modules/registry_test.go @@ -70,10 +70,10 @@ func TestRegistry_GetDriver(t *testing.T) { func TestRegistry_Register(t *testing.T) { t.Parallel() - reg := &modules.Registry{} t.Run("FirstRegistration_NoError", func(t *testing.T) { t.Parallel() + reg := &modules.Registry{} desc := module.Descriptor{ Kind: "foo", DriverFactory: func(conf json.RawMessage) (module.Driver, error) { @@ -92,6 +92,7 @@ func TestRegistry_Register(t *testing.T) { t.Run("SecondRegistration_Conflict", func(t *testing.T) { t.Parallel() + reg := &modules.Registry{} desc := module.Descriptor{ Kind: "foo", DriverFactory: func(conf json.RawMessage) (module.Driver, error) { @@ -99,6 +100,10 @@ func TestRegistry_Register(t *testing.T) { }, } + // first attempt. + assert.NoError(t, reg.Register(desc)) + + // second attempt. err := reg.Register(desc) assert.Error(t, err) assert.True(t, errors.Is(err, errors.ErrConflict)) @@ -119,6 +124,7 @@ func TestRegistry_Register(t *testing.T) { }, }, } + reg := &modules.Registry{} got := reg.Register(desc) assert.Error(t, got) assert.True(t, errors.Is(got, errors.ErrInvalid), cmp.Diff(got, errors.ErrInvalid)) diff --git a/pkg/helm/release.go b/pkg/helm/release.go index fdcb575b..f82ad10e 100644 --- a/pkg/helm/release.go +++ b/pkg/helm/release.go @@ -270,7 +270,6 @@ func getVersion(version string) string { func (p *Client) getChart(name string, cpo *action.ChartPathOptions) (*chart.Chart, error) { // TODO: Add a lock as Load function blows up if accessed concurrently - path, err := cpo.LocateChart(name, p.cliSettings) if err != nil { return nil, err @@ -280,7 +279,6 @@ func (p *Client) getChart(name string, cpo *action.ChartPathOptions) (*chart.Cha if err != nil { return nil, err } - return c, nil } diff --git a/pkg/worker/mocks/job_queue.go b/pkg/worker/mocks/job_queue.go index 950e4628..577c270c 100644 --- a/pkg/worker/mocks/job_queue.go +++ b/pkg/worker/mocks/job_queue.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.14.0. DO NOT EDIT. +// Code generated by mockery v2.23.1. DO NOT EDIT. package mocks @@ -61,6 +61,11 @@ func (_c *JobQueue_Dequeue_Call) Return(_a0 error) *JobQueue_Dequeue_Call { return _c } +func (_c *JobQueue_Dequeue_Call) RunAndReturn(run func(context.Context, []string, worker.DequeueFn) error) *JobQueue_Dequeue_Call { + _c.Call.Return(run) + return _c +} + // Enqueue provides a mock function with given fields: ctx, jobs func (_m *JobQueue) Enqueue(ctx context.Context, jobs ...worker.Job) error { _va := make([]interface{}, len(jobs)) @@ -113,6 +118,11 @@ func (_c *JobQueue_Enqueue_Call) Return(_a0 error) *JobQueue_Enqueue_Call { return _c } +func (_c *JobQueue_Enqueue_Call) RunAndReturn(run func(context.Context, ...worker.Job) error) *JobQueue_Enqueue_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewJobQueue interface { mock.TestingT Cleanup(func()) From cffb11fb5d6fa537f0373a4ac1ab38a3d3674c9c Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Mon, 27 Mar 2023 13:30:04 +0530 Subject: [PATCH 17/72] fix: revision listing db query (#16) --- internal/store/postgres/revision_store.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/internal/store/postgres/revision_store.go b/internal/store/postgres/revision_store.go index 35e94b2f..31c14145 100644 --- a/internal/store/postgres/revision_store.go +++ b/internal/store/postgres/revision_store.go @@ -46,16 +46,10 @@ func (st *Store) Revisions(ctx context.Context, selector resource.RevisionsSelec return err } - var tags []string - if err := readRevisionTags(ctx, tx, rm.ID, &tags); err != nil { - return err - } - revs = append(revs, resource.Revision{ ID: rm.ID, URN: selector.URN, Reason: rm.Reason, - Labels: tagsToLabelMap(tags), CreatedAt: rm.CreatedAt, Spec: resource.Spec{ Configs: rm.SpecConfigs, @@ -63,6 +57,15 @@ func (st *Store) Revisions(ctx context.Context, selector resource.RevisionsSelec }, }) } + _ = rows.Close() + + for i, rev := range revs { + var tags []string + if err := readRevisionTags(ctx, tx, rev.ID, &tags); err != nil { + return err + } + revs[i].Labels = tagsToLabelMap(tags) + } return nil } From b93cbb85a0a425f7d92321dda4c2180dd143af02 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Mon, 27 Mar 2023 16:19:17 +0530 Subject: [PATCH 18/72] fix: expose chart values type (#17) --- modules/firehose/config.go | 8 +++++++- modules/firehose/driver.go | 14 ++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index 2f42f4cd..0aeb9e77 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -34,10 +34,16 @@ type Config struct { Replicas int `json:"replicas"` Namespace string `json:"namespace,omitempty"` DeploymentID string `json:"deployment_id,omitempty"` - ChartValues *chartValues `json:"chart_values,omitempty"` + ChartValues *ChartValues `json:"chart_values,omitempty"` EnvVariables map[string]string `json:"env_variables,omitempty"` } +type ChartValues struct { + ImageTag string `json:"image_tag" validate:"required"` + ChartVersion string `json:"chart_version" validate:"required"` + ImagePullPolicy string `json:"image_pull_policy" validate:"required"` +} + func readConfig(r resource.Resource, confJSON json.RawMessage) (*Config, error) { var cfg Config if err := json.Unmarshal(confJSON, &cfg); err != nil { diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index d74e3da9..b8609237 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -31,7 +31,7 @@ var defaultDriverConf = driverConf{ Telegraf: map[string]any{ "enabled": false, }, - ChartValues: chartValues{ + ChartValues: ChartValues{ ImageTag: "latest", ChartVersion: "0.1.3", ImagePullPolicy: "IfNotPresent", @@ -55,13 +55,7 @@ type ( type driverConf struct { Telegraf map[string]any `json:"telegraf"` Namespace string `json:"namespace" validate:"required"` - ChartValues chartValues `json:"chart_values" validate:"required"` -} - -type chartValues struct { - ImageTag string `json:"image_tag" validate:"required"` - ChartVersion string `json:"chart_version" validate:"required"` - ImagePullPolicy string `json:"image_pull_policy" validate:"required"` + ChartValues ChartValues `json:"chart_values" validate:"required"` } type Output struct { @@ -98,12 +92,12 @@ func (*firehoseDriver) getHelmRelease(conf Config) *helm.ReleaseConfig { return rc } -func mergeChartValues(cur, newVal *chartValues) (*chartValues, error) { +func mergeChartValues(cur, newVal *ChartValues) (*ChartValues, error) { if newVal == nil { return cur, nil } - merged := chartValues{ + merged := ChartValues{ ImageTag: cur.ImageTag, ChartVersion: cur.ChartVersion, ImagePullPolicy: cur.ImagePullPolicy, From b063bba028b3bbde0d230a07d9c30f519946d7a1 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Thu, 30 Mar 2023 11:04:41 +0530 Subject: [PATCH 19/72] feat: strip trailing colon in image tag, add telegraf config template * fix: strip trailing colon in image tag * feat: add telegraf config templating --- modules/firehose/config.go | 9 +++++++- modules/firehose/driver.go | 36 +++++++++++++++++++++++-------- modules/firehose/driver_output.go | 11 +++++++--- modules/firehose/driver_plan.go | 2 +- modules/firehose/driver_sync.go | 15 ++++++++----- 5 files changed, 54 insertions(+), 19 deletions(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index 0aeb9e77..cff22282 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -30,7 +30,7 @@ var ( type Config struct { Stopped bool `json:"stopped"` StopTime *time.Time `json:"stop_time,omitempty"` - Telegraf map[string]any `json:"telegraf,omitempty"` + Telegraf *Telegraf `json:"telegraf,omitempty"` Replicas int `json:"replicas"` Namespace string `json:"namespace,omitempty"` DeploymentID string `json:"deployment_id,omitempty"` @@ -38,6 +38,13 @@ type Config struct { EnvVariables map[string]string `json:"env_variables,omitempty"` } +type Telegraf struct { + Enabled bool `json:"enabled"` + Image string `json:"image,omitempty"` + ConfigTpl string `json:"config_tpl,omitempty"` + TplValues map[string]any `json:"tpl_values,omitempty"` +} + type ChartValues struct { ImageTag string `json:"image_tag" validate:"required"` ChartVersion string `json:"chart_version" validate:"required"` diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index b8609237..0157970f 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -1,9 +1,11 @@ package firehose import ( + "bytes" "context" "encoding/json" "strings" + "text/template" "time" "github.com/goto/entropy/core/module" @@ -28,8 +30,8 @@ const ( var defaultDriverConf = driverConf{ Namespace: "firehose", - Telegraf: map[string]any{ - "enabled": false, + Telegraf: Telegraf{ + Enabled: false, }, ChartValues: ChartValues{ ImageTag: "latest", @@ -53,9 +55,9 @@ type ( ) type driverConf struct { - Telegraf map[string]any `json:"telegraf"` - Namespace string `json:"namespace" validate:"required"` - ChartValues ChartValues `json:"chart_values" validate:"required"` + Telegraf Telegraf `json:"telegraf"` + Namespace string `json:"namespace" validate:"required"` + ChartValues ChartValues `json:"chart_values" validate:"required"` } type Output struct { @@ -69,7 +71,19 @@ type transientData struct { ResetOffsetTo string `json:"reset_offset_to,omitempty"` } -func (*firehoseDriver) getHelmRelease(conf Config) *helm.ReleaseConfig { +func (*firehoseDriver) getHelmRelease(labels map[string]string, conf Config) (*helm.ReleaseConfig, error) { + var telegrafConfig bytes.Buffer + telegrafConfigTpl, err := template.New("").Parse(conf.Telegraf.ConfigTpl) + if err != nil { + return nil, err + } else if err := telegrafConfigTpl.Execute(&telegrafConfig, map[string]any{ + "Labels": labels, + "Config": conf, + "Values": conf.Telegraf.TplValues, + }); err != nil { + return nil, err + } + rc := helm.DefaultReleaseConfig() rc.Name = conf.DeploymentID rc.Repository = chartRepo @@ -87,9 +101,13 @@ func (*firehoseDriver) getHelmRelease(conf Config) *helm.ReleaseConfig { }, "config": conf.EnvVariables, }, - "telegraf": conf.Telegraf, + "telegraf": map[string]any{ + "enabled": conf.Telegraf.Enabled, + "image": conf.Telegraf.Image, + "config": telegrafConfig.String(), + }, } - return rc + return rc, nil } func mergeChartValues(cur, newVal *ChartValues) (*ChartValues, error) { @@ -109,7 +127,7 @@ func mergeChartValues(cur, newVal *ChartValues) (*ChartValues, error) { return nil, errors.ErrInvalid. WithMsgf("unknown image repo: '%s', must start with '%s'", newTag, imageRepo) } - merged.ImageTag = strings.TrimPrefix(newTag, imageRepo) + merged.ImageTag = strings.TrimPrefix(newTag, imageRepo+":") } return &merged, nil diff --git a/modules/firehose/driver_output.go b/modules/firehose/driver_output.go index 24e12dc6..bd8a8b27 100644 --- a/modules/firehose/driver_output.go +++ b/modules/firehose/driver_output.go @@ -5,6 +5,7 @@ import ( "encoding/json" "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" "github.com/goto/entropy/modules/kubernetes" "github.com/goto/entropy/pkg/errors" ) @@ -25,13 +26,17 @@ func (fd *firehoseDriver) Output(ctx context.Context, exr module.ExpandedResourc return nil, errors.ErrInternal.WithMsgf("invalid kube state").WithCausef(err.Error()) } - return fd.refreshOutput(ctx, *conf, *output, kubeOut) + return fd.refreshOutput(ctx, exr.Resource, *conf, *output, kubeOut) } func (fd *firehoseDriver) refreshOutput(ctx context.Context, - conf Config, output Output, kubeOut kubernetes.Output, + r resource.Resource, conf Config, output Output, kubeOut kubernetes.Output, ) (json.RawMessage, error) { - rc := fd.getHelmRelease(conf) + rc, err := fd.getHelmRelease(r.Labels, conf) + if err != nil { + return nil, errors.ErrInternal.WithCausef(err.Error()) + } + pods, err := fd.kubeGetPod(ctx, kubeOut.Configs, rc.Namespace, map[string]string{"app": rc.Name}) if err != nil { return nil, errors.ErrInternal.WithCausef(err.Error()) diff --git a/modules/firehose/driver_plan.go b/modules/firehose/driver_plan.go index 926f0ceb..bd7b6e34 100644 --- a/modules/firehose/driver_plan.go +++ b/modules/firehose/driver_plan.go @@ -100,7 +100,7 @@ func (fd *firehoseDriver) planCreate(exr module.ExpandedResource, act module.Act } // set project defaults. - conf.Telegraf = fd.conf.Telegraf + conf.Telegraf = &fd.conf.Telegraf conf.Namespace = fd.conf.Namespace conf.ChartValues = chartVals diff --git a/modules/firehose/driver_sync.go b/modules/firehose/driver_sync.go index b974732f..c0685797 100644 --- a/modules/firehose/driver_sync.go +++ b/modules/firehose/driver_sync.go @@ -51,7 +51,7 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) } isCreate := pendingStep == stepReleaseCreate - if err := fd.releaseSync(ctx, isCreate, *conf, kubeOut); err != nil { + if err := fd.releaseSync(ctx, exr.Resource, isCreate, *conf, kubeOut); err != nil { return nil, err } @@ -78,13 +78,13 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) finalState.NextSyncAt = conf.StopTime if conf.StopTime != nil && conf.StopTime.Before(fd.timeNow()) { conf.Replicas = 0 - if err := fd.releaseSync(ctx, false, *conf, kubeOut); err != nil { + if err := fd.releaseSync(ctx, exr.Resource, false, *conf, kubeOut); err != nil { return nil, err } finalState.NextSyncAt = nil } - finalOut, err := fd.refreshOutput(ctx, *conf, *out, kubeOut) + finalOut, err := fd.refreshOutput(ctx, exr.Resource, *conf, *out, kubeOut) if err != nil { return nil, err } @@ -95,8 +95,13 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) return &finalState, nil } -func (fd *firehoseDriver) releaseSync(ctx context.Context, isCreate bool, conf Config, kubeOut kubernetes.Output) error { - rc := fd.getHelmRelease(conf) +func (fd *firehoseDriver) releaseSync(ctx context.Context, r resource.Resource, + isCreate bool, conf Config, kubeOut kubernetes.Output) error { + rc, err := fd.getHelmRelease(r.Labels, conf) + if err != nil { + return errors.ErrInternal.WithCausef(err.Error()) + } + if err := fd.kubeDeploy(ctx, isCreate, kubeOut.Configs, *rc); err != nil { return errors.ErrInternal.WithCausef(err.Error()) } From fb2202d95e6064110a498c22e5169b4c09304a35 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Thu, 30 Mar 2023 15:23:52 +0530 Subject: [PATCH 20/72] fix: telegraf config format (#19) --- core/core.go | 27 +++++++++++++++----------- core/sync.go | 16 ++++++++++----- modules/firehose/config.go | 12 ++++++++---- modules/firehose/driver.go | 29 ++++------------------------ modules/firehose/driver_output.go | 10 +++------- modules/firehose/driver_plan.go | 2 +- modules/firehose/driver_plan_test.go | 6 ------ modules/firehose/driver_sync.go | 14 +++++--------- 8 files changed, 48 insertions(+), 68 deletions(-) diff --git a/core/core.go b/core/core.go index 817f76ef..ef9ea293 100644 --- a/core/core.go +++ b/core/core.go @@ -15,11 +15,12 @@ import ( ) type Service struct { - logger *zap.Logger - clock func() time.Time - store resource.Store - moduleSvc ModuleService - syncBackoff time.Duration + logger *zap.Logger + clock func() time.Time + store resource.Store + moduleSvc ModuleService + syncBackoff time.Duration + maxSyncRetries int } type ModuleService interface { @@ -30,18 +31,22 @@ type ModuleService interface { } func New(repo resource.Store, moduleSvc ModuleService, clockFn func() time.Time, lg *zap.Logger) *Service { - const defaultSyncBackoff = 5 * time.Second + const ( + defaultMaxRetries = 10 + defaultSyncBackoff = 5 * time.Second + ) if clockFn == nil { clockFn = time.Now } return &Service{ - logger: lg, - clock: clockFn, - store: repo, - syncBackoff: defaultSyncBackoff, - moduleSvc: moduleSvc, + logger: lg, + clock: clockFn, + store: repo, + syncBackoff: defaultSyncBackoff, + maxSyncRetries: defaultMaxRetries, + moduleSvc: moduleSvc, } } diff --git a/core/sync.go b/core/sync.go index 9dd0f3fa..25134c6b 100644 --- a/core/sync.go +++ b/core/sync.go @@ -48,20 +48,26 @@ func (svc *Service) handleSync(ctx context.Context, res resource.Resource) (*res newState, err := svc.moduleSvc.SyncState(ctx, *modSpec) if err != nil { + logEntry.Error("SyncOne() failed", zap.Error(err)) + + res.State.SyncResult.LastError = err.Error() + res.State.SyncResult.Retries++ if errors.Is(err, errors.ErrInvalid) { // ErrInvalid is expected to be returned when config is invalid. // There is no point in retrying in this case. res.State.Status = resource.StatusError res.State.NextSyncAt = nil + } else if svc.maxSyncRetries > 0 && res.State.SyncResult.Retries >= svc.maxSyncRetries { + // Some other error occurred and no more retries remaining. + // move the resource to failure state. + res.State.Status = resource.StatusError + res.State.NextSyncAt = nil } else { - // Some other error occurred. need to backoff and retry in some time. + // Some other error occurred and we still have remaining retries. + // need to backoff and retry in some time. tryAgainAt := svc.clock().Add(svc.syncBackoff) res.State.NextSyncAt = &tryAgainAt } - res.State.SyncResult.LastError = err.Error() - res.State.SyncResult.Retries++ - - logEntry.Error("SyncOne() failed", zap.Error(err)) } else { res.State.SyncResult.Retries = 0 res.State.SyncResult.LastError = "" diff --git a/modules/firehose/config.go b/modules/firehose/config.go index cff22282..66931db2 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -39,10 +39,14 @@ type Config struct { } type Telegraf struct { - Enabled bool `json:"enabled"` - Image string `json:"image,omitempty"` - ConfigTpl string `json:"config_tpl,omitempty"` - TplValues map[string]any `json:"tpl_values,omitempty"` + Enabled bool `json:"enabled,omitempty"` + Image ChartValues `json:"image,omitempty"` + Config TelegrafConf `json:"config,omitempty"` +} + +type TelegrafConf struct { + Output map[string]any `json:"output"` + AdditionalTags map[string]string `json:"additional_global_tags"` } type ChartValues struct { diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 0157970f..944bbd27 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -1,11 +1,9 @@ package firehose import ( - "bytes" "context" "encoding/json" "strings" - "text/template" "time" "github.com/goto/entropy/core/module" @@ -30,9 +28,6 @@ const ( var defaultDriverConf = driverConf{ Namespace: "firehose", - Telegraf: Telegraf{ - Enabled: false, - }, ChartValues: ChartValues{ ImageTag: "latest", ChartVersion: "0.1.3", @@ -55,7 +50,7 @@ type ( ) type driverConf struct { - Telegraf Telegraf `json:"telegraf"` + Telegraf *Telegraf `json:"telegraf"` Namespace string `json:"namespace" validate:"required"` ChartValues ChartValues `json:"chart_values" validate:"required"` } @@ -71,19 +66,7 @@ type transientData struct { ResetOffsetTo string `json:"reset_offset_to,omitempty"` } -func (*firehoseDriver) getHelmRelease(labels map[string]string, conf Config) (*helm.ReleaseConfig, error) { - var telegrafConfig bytes.Buffer - telegrafConfigTpl, err := template.New("").Parse(conf.Telegraf.ConfigTpl) - if err != nil { - return nil, err - } else if err := telegrafConfigTpl.Execute(&telegrafConfig, map[string]any{ - "Labels": labels, - "Config": conf, - "Values": conf.Telegraf.TplValues, - }); err != nil { - return nil, err - } - +func (*firehoseDriver) getHelmRelease(conf Config) *helm.ReleaseConfig { rc := helm.DefaultReleaseConfig() rc.Name = conf.DeploymentID rc.Repository = chartRepo @@ -101,13 +84,9 @@ func (*firehoseDriver) getHelmRelease(labels map[string]string, conf Config) (*h }, "config": conf.EnvVariables, }, - "telegraf": map[string]any{ - "enabled": conf.Telegraf.Enabled, - "image": conf.Telegraf.Image, - "config": telegrafConfig.String(), - }, + "telegraf": conf.Telegraf, } - return rc, nil + return rc } func mergeChartValues(cur, newVal *ChartValues) (*ChartValues, error) { diff --git a/modules/firehose/driver_output.go b/modules/firehose/driver_output.go index bd8a8b27..81161aa7 100644 --- a/modules/firehose/driver_output.go +++ b/modules/firehose/driver_output.go @@ -5,7 +5,6 @@ import ( "encoding/json" "github.com/goto/entropy/core/module" - "github.com/goto/entropy/core/resource" "github.com/goto/entropy/modules/kubernetes" "github.com/goto/entropy/pkg/errors" ) @@ -26,16 +25,13 @@ func (fd *firehoseDriver) Output(ctx context.Context, exr module.ExpandedResourc return nil, errors.ErrInternal.WithMsgf("invalid kube state").WithCausef(err.Error()) } - return fd.refreshOutput(ctx, exr.Resource, *conf, *output, kubeOut) + return fd.refreshOutput(ctx, *conf, *output, kubeOut) } func (fd *firehoseDriver) refreshOutput(ctx context.Context, - r resource.Resource, conf Config, output Output, kubeOut kubernetes.Output, + conf Config, output Output, kubeOut kubernetes.Output, ) (json.RawMessage, error) { - rc, err := fd.getHelmRelease(r.Labels, conf) - if err != nil { - return nil, errors.ErrInternal.WithCausef(err.Error()) - } + rc := fd.getHelmRelease(conf) pods, err := fd.kubeGetPod(ctx, kubeOut.Configs, rc.Namespace, map[string]string{"app": rc.Name}) if err != nil { diff --git a/modules/firehose/driver_plan.go b/modules/firehose/driver_plan.go index bd7b6e34..926f0ceb 100644 --- a/modules/firehose/driver_plan.go +++ b/modules/firehose/driver_plan.go @@ -100,7 +100,7 @@ func (fd *firehoseDriver) planCreate(exr module.ExpandedResource, act module.Act } // set project defaults. - conf.Telegraf = &fd.conf.Telegraf + conf.Telegraf = fd.conf.Telegraf conf.Namespace = fd.conf.Namespace conf.ChartValues = chartVals diff --git a/modules/firehose/driver_plan_test.go b/modules/firehose/driver_plan_test.go index 40343927..e55796f4 100644 --- a/modules/firehose/driver_plan_test.go +++ b/modules/firehose/driver_plan_test.go @@ -77,9 +77,6 @@ func TestFirehoseDriver_Plan(t *testing.T) { "replicas": 1, "namespace": "firehose", "deployment_id": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099", - "telegraf": map[string]any{ - "enabled": false, - }, "chart_values": map[string]string{ "chart_version": "0.1.3", "image_pull_policy": "IfNotPresent", @@ -142,9 +139,6 @@ func TestFirehoseDriver_Plan(t *testing.T) { "replicas": 1, "namespace": "firehose", "deployment_id": "firehose-foo-fh1", - "telegraf": map[string]any{ - "enabled": false, - }, "chart_values": map[string]string{ "chart_version": "0.1.3", "image_pull_policy": "IfNotPresent", diff --git a/modules/firehose/driver_sync.go b/modules/firehose/driver_sync.go index c0685797..f54a2831 100644 --- a/modules/firehose/driver_sync.go +++ b/modules/firehose/driver_sync.go @@ -51,7 +51,7 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) } isCreate := pendingStep == stepReleaseCreate - if err := fd.releaseSync(ctx, exr.Resource, isCreate, *conf, kubeOut); err != nil { + if err := fd.releaseSync(ctx, isCreate, *conf, kubeOut); err != nil { return nil, err } @@ -78,13 +78,13 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) finalState.NextSyncAt = conf.StopTime if conf.StopTime != nil && conf.StopTime.Before(fd.timeNow()) { conf.Replicas = 0 - if err := fd.releaseSync(ctx, exr.Resource, false, *conf, kubeOut); err != nil { + if err := fd.releaseSync(ctx, false, *conf, kubeOut); err != nil { return nil, err } finalState.NextSyncAt = nil } - finalOut, err := fd.refreshOutput(ctx, exr.Resource, *conf, *out, kubeOut) + finalOut, err := fd.refreshOutput(ctx, *conf, *out, kubeOut) if err != nil { return nil, err } @@ -95,12 +95,8 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) return &finalState, nil } -func (fd *firehoseDriver) releaseSync(ctx context.Context, r resource.Resource, - isCreate bool, conf Config, kubeOut kubernetes.Output) error { - rc, err := fd.getHelmRelease(r.Labels, conf) - if err != nil { - return errors.ErrInternal.WithCausef(err.Error()) - } +func (fd *firehoseDriver) releaseSync(ctx context.Context, isCreate bool, conf Config, kubeOut kubernetes.Output) error { + rc := fd.getHelmRelease(conf) if err := fd.kubeDeploy(ctx, isCreate, kubeOut.Configs, *rc); err != nil { return errors.ErrInternal.WithCausef(err.Error()) From eacb30fd8add4b933c9bff8fc17677fcb7bb96da Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Thu, 30 Mar 2023 16:09:08 +0530 Subject: [PATCH 21/72] feat: add support for dynamic telegraf labels (#20) --- modules/firehose/driver.go | 36 ++++++++++++++++++++++++++++--- modules/firehose/driver_output.go | 10 ++++++--- modules/firehose/driver_sync.go | 14 +++++++----- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 944bbd27..306d09bf 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -1,9 +1,11 @@ package firehose import ( + "bytes" "context" "encoding/json" "strings" + "text/template" "time" "github.com/goto/entropy/core/module" @@ -66,7 +68,34 @@ type transientData struct { ResetOffsetTo string `json:"reset_offset_to,omitempty"` } -func (*firehoseDriver) getHelmRelease(conf Config) *helm.ReleaseConfig { +func (*firehoseDriver) getHelmRelease(labels map[string]string, conf Config) (*helm.ReleaseConfig, error) { + var telegrafConf Telegraf + if conf.Telegraf != nil && conf.Telegraf.Enabled { + telegrafTags := map[string]string{} + for k, v := range conf.Telegraf.Config.AdditionalTags { + var buf bytes.Buffer + t, err := template.New("").Parse(v) + if err != nil { + return nil, errors.ErrInvalid. + WithMsgf("label template for '%s' is invalid", k).WithCausef(err.Error()) + } else if err := t.Execute(&buf, labels); err != nil { + return nil, errors.ErrInvalid. + WithMsgf("failed to render label template").WithCausef(err.Error()) + } + + telegrafTags[k] = buf.String() + } + + telegrafConf = Telegraf{ + Enabled: true, + Image: conf.Telegraf.Image, + Config: TelegrafConf{ + Output: conf.Telegraf.Config.Output, + AdditionalTags: telegrafTags, + }, + } + } + rc := helm.DefaultReleaseConfig() rc.Name = conf.DeploymentID rc.Repository = chartRepo @@ -84,9 +113,10 @@ func (*firehoseDriver) getHelmRelease(conf Config) *helm.ReleaseConfig { }, "config": conf.EnvVariables, }, - "telegraf": conf.Telegraf, + "telegraf": telegrafConf, } - return rc + + return rc, nil } func mergeChartValues(cur, newVal *ChartValues) (*ChartValues, error) { diff --git a/modules/firehose/driver_output.go b/modules/firehose/driver_output.go index 81161aa7..ea3c7e04 100644 --- a/modules/firehose/driver_output.go +++ b/modules/firehose/driver_output.go @@ -5,6 +5,7 @@ import ( "encoding/json" "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" "github.com/goto/entropy/modules/kubernetes" "github.com/goto/entropy/pkg/errors" ) @@ -25,13 +26,16 @@ func (fd *firehoseDriver) Output(ctx context.Context, exr module.ExpandedResourc return nil, errors.ErrInternal.WithMsgf("invalid kube state").WithCausef(err.Error()) } - return fd.refreshOutput(ctx, *conf, *output, kubeOut) + return fd.refreshOutput(ctx, exr.Resource, *conf, *output, kubeOut) } -func (fd *firehoseDriver) refreshOutput(ctx context.Context, +func (fd *firehoseDriver) refreshOutput(ctx context.Context, r resource.Resource, conf Config, output Output, kubeOut kubernetes.Output, ) (json.RawMessage, error) { - rc := fd.getHelmRelease(conf) + rc, err := fd.getHelmRelease(r.Labels, conf) + if err != nil { + return nil, err + } pods, err := fd.kubeGetPod(ctx, kubeOut.Configs, rc.Namespace, map[string]string{"app": rc.Name}) if err != nil { diff --git a/modules/firehose/driver_sync.go b/modules/firehose/driver_sync.go index f54a2831..0b00e3ac 100644 --- a/modules/firehose/driver_sync.go +++ b/modules/firehose/driver_sync.go @@ -51,7 +51,7 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) } isCreate := pendingStep == stepReleaseCreate - if err := fd.releaseSync(ctx, isCreate, *conf, kubeOut); err != nil { + if err := fd.releaseSync(ctx, exr.Resource, isCreate, *conf, kubeOut); err != nil { return nil, err } @@ -78,13 +78,13 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) finalState.NextSyncAt = conf.StopTime if conf.StopTime != nil && conf.StopTime.Before(fd.timeNow()) { conf.Replicas = 0 - if err := fd.releaseSync(ctx, false, *conf, kubeOut); err != nil { + if err := fd.releaseSync(ctx, exr.Resource, false, *conf, kubeOut); err != nil { return nil, err } finalState.NextSyncAt = nil } - finalOut, err := fd.refreshOutput(ctx, *conf, *out, kubeOut) + finalOut, err := fd.refreshOutput(ctx, exr.Resource, *conf, *out, kubeOut) if err != nil { return nil, err } @@ -95,8 +95,12 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) return &finalState, nil } -func (fd *firehoseDriver) releaseSync(ctx context.Context, isCreate bool, conf Config, kubeOut kubernetes.Output) error { - rc := fd.getHelmRelease(conf) +func (fd *firehoseDriver) releaseSync(ctx context.Context, r resource.Resource, + isCreate bool, conf Config, kubeOut kubernetes.Output) error { + rc, err := fd.getHelmRelease(r.Labels, conf) + if err != nil { + return err + } if err := fd.kubeDeploy(ctx, isCreate, kubeOut.Configs, *rc); err != nil { return errors.ErrInternal.WithCausef(err.Error()) From 9a378147dcdd4df4954096af96afe27cee1ae1ee Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Thu, 30 Mar 2023 16:31:47 +0530 Subject: [PATCH 22/72] fix: use go map for telegraf image spec (#21) --- modules/firehose/config.go | 6 +++--- modules/firehose/driver_sync.go | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index 66931db2..9ec9075d 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -39,9 +39,9 @@ type Config struct { } type Telegraf struct { - Enabled bool `json:"enabled,omitempty"` - Image ChartValues `json:"image,omitempty"` - Config TelegrafConf `json:"config,omitempty"` + Enabled bool `json:"enabled,omitempty"` + Image map[string]any `json:"image,omitempty"` + Config TelegrafConf `json:"config,omitempty"` } type TelegrafConf struct { diff --git a/modules/firehose/driver_sync.go b/modules/firehose/driver_sync.go index 0b00e3ac..492f33d4 100644 --- a/modules/firehose/driver_sync.go +++ b/modules/firehose/driver_sync.go @@ -96,7 +96,8 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) } func (fd *firehoseDriver) releaseSync(ctx context.Context, r resource.Resource, - isCreate bool, conf Config, kubeOut kubernetes.Output) error { + isCreate bool, conf Config, kubeOut kubernetes.Output, +) error { rc, err := fd.getHelmRelease(r.Labels, conf) if err != nil { return err From 52671a64e64f77e7cc313349f7b14a7ab1cc2bf9 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Thu, 30 Mar 2023 17:08:03 +0530 Subject: [PATCH 23/72] fix: use map to fix yaml marshal (#22) --- modules/firehose/config.go | 4 ++-- modules/firehose/driver.go | 15 +++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index 9ec9075d..a43a30ef 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -45,8 +45,8 @@ type Telegraf struct { } type TelegrafConf struct { - Output map[string]any `json:"output"` - AdditionalTags map[string]string `json:"additional_global_tags"` + Output map[string]any `json:"output"` + AdditionalGlobalTags map[string]string `json:"additional_global_tags"` } type ChartValues struct { diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 306d09bf..9dc05b73 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -72,7 +72,7 @@ func (*firehoseDriver) getHelmRelease(labels map[string]string, conf Config) (*h var telegrafConf Telegraf if conf.Telegraf != nil && conf.Telegraf.Enabled { telegrafTags := map[string]string{} - for k, v := range conf.Telegraf.Config.AdditionalTags { + for k, v := range conf.Telegraf.Config.AdditionalGlobalTags { var buf bytes.Buffer t, err := template.New("").Parse(v) if err != nil { @@ -90,8 +90,8 @@ func (*firehoseDriver) getHelmRelease(labels map[string]string, conf Config) (*h Enabled: true, Image: conf.Telegraf.Image, Config: TelegrafConf{ - Output: conf.Telegraf.Config.Output, - AdditionalTags: telegrafTags, + Output: conf.Telegraf.Config.Output, + AdditionalGlobalTags: telegrafTags, }, } } @@ -113,7 +113,14 @@ func (*firehoseDriver) getHelmRelease(labels map[string]string, conf Config) (*h }, "config": conf.EnvVariables, }, - "telegraf": telegrafConf, + "telegraf": map[string]interface{}{ + "enabled": telegrafConf.Enabled, + "image": telegrafConf.Image, + "config": map[string]any{ + "output": telegrafConf.Config.Output, + "additional_global_tags": telegrafConf.Config.AdditionalGlobalTags, + }, + }, } return rc, nil From 2b799d7bb979cebc76de56840d49b57096121329 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Thu, 30 Mar 2023 18:43:27 +0530 Subject: [PATCH 24/72] fix: set deployment-id length limit as 63 (#23) --- modules/firehose/config.go | 2 +- modules/firehose/driver_plan_test.go | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index a43a30ef..885fffb6 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -18,7 +18,7 @@ const ( confKeyKafkaBrokers = "SOURCE_KAFKA_BROKERS" ) -const kubeDeploymentNameLengthLimit = 53 +const kubeDeploymentNameLengthLimit = 63 var ( //go:embed schema/config.json diff --git a/modules/firehose/driver_plan_test.go b/modules/firehose/driver_plan_test.go index e55796f4..b9e1950d 100644 --- a/modules/firehose/driver_plan_test.go +++ b/modules/firehose/driver_plan_test.go @@ -48,9 +48,9 @@ func TestFirehoseDriver_Plan(t *testing.T) { title: "Create_LongName", exr: module.ExpandedResource{ Resource: resource.Resource{ - URN: "urn:goto:entropy:ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz", + URN: "urn:goto:entropy:ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz123", Kind: "firehose", - Name: "abcdefghijklmnopqrstuvwxyz", + Name: "abcdefghijklmnopqrstuvwxyz123", Project: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", }, }, @@ -67,16 +67,16 @@ func TestFirehoseDriver_Plan(t *testing.T) { }), }, want: &resource.Resource{ - URN: "urn:goto:entropy:ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz", + URN: "urn:goto:entropy:ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz123", Kind: "firehose", - Name: "abcdefghijklmnopqrstuvwxyz", + Name: "abcdefghijklmnopqrstuvwxyz123", Project: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", Spec: resource.Spec{ Configs: mustJSON(map[string]any{ "stopped": false, "replicas": 1, "namespace": "firehose", - "deployment_id": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099", + "deployment_id": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghijklmnopqrst-f1d02d", "chart_values": map[string]string{ "chart_version": "0.1.3", "image_pull_policy": "IfNotPresent", @@ -85,7 +85,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { "env_variables": map[string]string{ "SINK_TYPE": "LOG", "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", - "SOURCE_KAFKA_CONSUMER_GROUP_ID": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099-0001", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghijklmnopqrst-f1d02d-0001", "SOURCE_KAFKA_BROKERS": "localhost:9092", "SOURCE_KAFKA_TOPIC": "foo-log", }, @@ -95,7 +95,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { Status: resource.StatusPending, Output: mustJSON(Output{ Namespace: "firehose", - ReleaseName: "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099", + ReleaseName: "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghijklmnopqrst-f1d02d", }), ModuleData: mustJSON(transientData{ PendingSteps: []string{stepReleaseCreate}, From 3a368d2476bcacc6a73539559a6e890c2d56805b Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Thu, 30 Mar 2023 19:15:28 +0530 Subject: [PATCH 25/72] fix: revert 63 limit to 53 due helm limitation (#24) This reverts commit 2b799d7bb979cebc76de56840d49b57096121329. --- modules/firehose/config.go | 2 +- modules/firehose/driver_plan_test.go | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index 885fffb6..a43a30ef 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -18,7 +18,7 @@ const ( confKeyKafkaBrokers = "SOURCE_KAFKA_BROKERS" ) -const kubeDeploymentNameLengthLimit = 63 +const kubeDeploymentNameLengthLimit = 53 var ( //go:embed schema/config.json diff --git a/modules/firehose/driver_plan_test.go b/modules/firehose/driver_plan_test.go index b9e1950d..e55796f4 100644 --- a/modules/firehose/driver_plan_test.go +++ b/modules/firehose/driver_plan_test.go @@ -48,9 +48,9 @@ func TestFirehoseDriver_Plan(t *testing.T) { title: "Create_LongName", exr: module.ExpandedResource{ Resource: resource.Resource{ - URN: "urn:goto:entropy:ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz123", + URN: "urn:goto:entropy:ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz", Kind: "firehose", - Name: "abcdefghijklmnopqrstuvwxyz123", + Name: "abcdefghijklmnopqrstuvwxyz", Project: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", }, }, @@ -67,16 +67,16 @@ func TestFirehoseDriver_Plan(t *testing.T) { }), }, want: &resource.Resource{ - URN: "urn:goto:entropy:ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz123", + URN: "urn:goto:entropy:ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz", Kind: "firehose", - Name: "abcdefghijklmnopqrstuvwxyz123", + Name: "abcdefghijklmnopqrstuvwxyz", Project: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", Spec: resource.Spec{ Configs: mustJSON(map[string]any{ "stopped": false, "replicas": 1, "namespace": "firehose", - "deployment_id": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghijklmnopqrst-f1d02d", + "deployment_id": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099", "chart_values": map[string]string{ "chart_version": "0.1.3", "image_pull_policy": "IfNotPresent", @@ -85,7 +85,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { "env_variables": map[string]string{ "SINK_TYPE": "LOG", "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", - "SOURCE_KAFKA_CONSUMER_GROUP_ID": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghijklmnopqrst-f1d02d-0001", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099-0001", "SOURCE_KAFKA_BROKERS": "localhost:9092", "SOURCE_KAFKA_TOPIC": "foo-log", }, @@ -95,7 +95,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { Status: resource.StatusPending, Output: mustJSON(Output{ Namespace: "firehose", - ReleaseName: "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghijklmnopqrst-f1d02d", + ReleaseName: "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099", }), ModuleData: mustJSON(transientData{ PendingSteps: []string{stepReleaseCreate}, From d3e42c0a5d7bcd3cda6eecd6a07ec114fe49fa54 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Thu, 30 Mar 2023 19:53:34 +0530 Subject: [PATCH 26/72] feat: refactor release name to be consistent with old format (#25) --- modules/firehose/config.go | 32 ++++++++++++--------- modules/firehose/config_test.go | 42 ++++++++++++++++++++++++++++ modules/firehose/driver_plan_test.go | 10 +++---- 3 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 modules/firehose/config_test.go diff --git a/modules/firehose/config.go b/modules/firehose/config.go index a43a30ef..75671d90 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -18,7 +18,7 @@ const ( confKeyKafkaBrokers = "SOURCE_KAFKA_BROKERS" ) -const kubeDeploymentNameLengthLimit = 53 +const helmReleaseNameMaxLength = 53 var ( //go:embed schema/config.json @@ -71,9 +71,9 @@ func readConfig(r resource.Resource, confJSON json.RawMessage) (*Config, error) // note: enforce the kubernetes deployment name length limit. if len(cfg.DeploymentID) == 0 { - cfg.DeploymentID = generateSafeReleaseName(r.Project, r.Name) - } else if len(cfg.DeploymentID) > kubeDeploymentNameLengthLimit { - return nil, errors.ErrInvalid.WithMsgf("deployment_id must be shorter than 53 chars") + cfg.DeploymentID = safeReleaseName(fmt.Sprintf("%s-%s", r.Project, r.Name)) + } else if len(cfg.DeploymentID) > helmReleaseNameMaxLength { + return nil, errors.ErrInvalid.WithMsgf("deployment_id must not have more than 53 chars") } if consumerID := cfg.EnvVariables[confKeyConsumerID]; consumerID == "" { @@ -83,18 +83,24 @@ func readConfig(r resource.Resource, confJSON json.RawMessage) (*Config, error) return &cfg, nil } -func generateSafeReleaseName(project, name string) string { - const prefix = "firehose-" +func safeReleaseName(concatName string) string { const randomHashLen = 6 + var suffix = "-firehose" - releaseName := fmt.Sprintf("%s%s-%s", prefix, project, name) - if len(releaseName) >= kubeDeploymentNameLengthLimit { - releaseName = strings.Trim(releaseName[:kubeDeploymentNameLengthLimit-randomHashLen-1], "-") + // remove suffix if already there. + concatName = strings.TrimSuffix(concatName, suffix) - val := sha256.Sum256([]byte(releaseName)) - hash := fmt.Sprintf("%x", val) - releaseName = releaseName + "-" + hash[:randomHashLen] + if len(concatName) <= helmReleaseNameMaxLength-len(suffix) { + return concatName + suffix } - return releaseName + val := sha256.Sum256([]byte(concatName)) + hash := fmt.Sprintf("%x", val) + suffix = fmt.Sprintf("-%s%s", hash[:randomHashLen], suffix) + + // truncate and make room for the suffix. also trim any leading, trailing + // hyphens to prevent '--' (not allowed in deployment names). + truncated := concatName[0 : len(concatName)-len(suffix)] + truncated = strings.Trim(truncated, "-") + return truncated + suffix } diff --git a/modules/firehose/config_test.go b/modules/firehose/config_test.go new file mode 100644 index 00000000..1db2c745 --- /dev/null +++ b/modules/firehose/config_test.go @@ -0,0 +1,42 @@ +package firehose + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_safeReleaseName(t *testing.T) { + t.Parallel() + + table := []struct { + str string + want string + }{ + { + str: "abcd-efgh", + want: "abcd-efgh-firehose", + }, + { + str: "abcd-efgh-firehose", + want: "abcd-efgh-firehose", + }, + { + str: "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghijklmnopqrstuvwxyz", + want: "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-3801d0-firehose", + }, + { + str: "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghi---klmnopqrstuvwxyz", + want: "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghi-81c192-firehose", + }, + } + + for i, tt := range table { + t.Run(fmt.Sprintf("Case#%d", i), func(t *testing.T) { + got := safeReleaseName(tt.str) + assert.Equal(t, tt.want, got) + assert.True(t, len(got) <= helmReleaseNameMaxLength, "release name has length %d", len(got)) + }) + } +} diff --git a/modules/firehose/driver_plan_test.go b/modules/firehose/driver_plan_test.go index e55796f4..72db20dc 100644 --- a/modules/firehose/driver_plan_test.go +++ b/modules/firehose/driver_plan_test.go @@ -76,7 +76,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { "stopped": false, "replicas": 1, "namespace": "firehose", - "deployment_id": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099", + "deployment_id": "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-3801d0-firehose", "chart_values": map[string]string{ "chart_version": "0.1.3", "image_pull_policy": "IfNotPresent", @@ -85,7 +85,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { "env_variables": map[string]string{ "SINK_TYPE": "LOG", "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", - "SOURCE_KAFKA_CONSUMER_GROUP_ID": "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099-0001", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-3801d0-firehose-0001", "SOURCE_KAFKA_BROKERS": "localhost:9092", "SOURCE_KAFKA_TOPIC": "foo-log", }, @@ -95,7 +95,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { Status: resource.StatusPending, Output: mustJSON(Output{ Namespace: "firehose", - ReleaseName: "firehose-ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-9bf099", + ReleaseName: "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-3801d0-firehose", }), ModuleData: mustJSON(transientData{ PendingSteps: []string{stepReleaseCreate}, @@ -138,7 +138,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { "stopped": false, "replicas": 1, "namespace": "firehose", - "deployment_id": "firehose-foo-fh1", + "deployment_id": "foo-fh1-firehose", "chart_values": map[string]string{ "chart_version": "0.1.3", "image_pull_policy": "IfNotPresent", @@ -157,7 +157,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { Status: resource.StatusPending, Output: mustJSON(Output{ Namespace: "firehose", - ReleaseName: "firehose-foo-fh1", + ReleaseName: "foo-fh1-firehose", }), ModuleData: mustJSON(transientData{ PendingSteps: []string{stepReleaseCreate}, From cbc5e88397c240a3c4bd957e68f1b3a30ece6c32 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Thu, 30 Mar 2023 20:53:11 +0530 Subject: [PATCH 27/72] fix: helm release name limit (#26) --- modules/firehose/config.go | 5 +++-- modules/firehose/config_test.go | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index 75671d90..719890e6 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -85,7 +85,7 @@ func readConfig(r resource.Resource, confJSON json.RawMessage) (*Config, error) func safeReleaseName(concatName string) string { const randomHashLen = 6 - var suffix = "-firehose" + suffix := "-firehose" // remove suffix if already there. concatName = strings.TrimSuffix(concatName, suffix) @@ -100,7 +100,8 @@ func safeReleaseName(concatName string) string { // truncate and make room for the suffix. also trim any leading, trailing // hyphens to prevent '--' (not allowed in deployment names). - truncated := concatName[0 : len(concatName)-len(suffix)] + truncLen := helmReleaseNameMaxLength - len(suffix) + truncated := concatName[0:truncLen] truncated = strings.Trim(truncated, "-") return truncated + suffix } diff --git a/modules/firehose/config_test.go b/modules/firehose/config_test.go index 1db2c745..7ee6b3bd 100644 --- a/modules/firehose/config_test.go +++ b/modules/firehose/config_test.go @@ -30,6 +30,10 @@ func Test_safeReleaseName(t *testing.T) { str: "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghi---klmnopqrstuvwxyz", want: "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghi-81c192-firehose", }, + { + str: "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghijklmnopqr-stuvwxyz1234567890", + want: "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-bac696-firehose", + }, } for i, tt := range table { From dc4b7ca6ed218841a060941a48332ac9ca8359cf Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Mon, 3 Apr 2023 14:09:09 +0530 Subject: [PATCH 28/72] feat: implement deployment label templating (#27) --- modules/firehose/driver.go | 67 +++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 9dc05b73..313bf9a7 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -52,9 +52,10 @@ type ( ) type driverConf struct { - Telegraf *Telegraf `json:"telegraf"` - Namespace string `json:"namespace" validate:"required"` - ChartValues ChartValues `json:"chart_values" validate:"required"` + Labels map[string]string `json:"labels,omitempty"` + Telegraf *Telegraf `json:"telegraf"` + Namespace string `json:"namespace" validate:"required"` + ChartValues ChartValues `json:"chart_values" validate:"required"` } type Output struct { @@ -68,22 +69,12 @@ type transientData struct { ResetOffsetTo string `json:"reset_offset_to,omitempty"` } -func (*firehoseDriver) getHelmRelease(labels map[string]string, conf Config) (*helm.ReleaseConfig, error) { +func (fd *firehoseDriver) getHelmRelease(labels map[string]string, conf Config) (*helm.ReleaseConfig, error) { var telegrafConf Telegraf if conf.Telegraf != nil && conf.Telegraf.Enabled { - telegrafTags := map[string]string{} - for k, v := range conf.Telegraf.Config.AdditionalGlobalTags { - var buf bytes.Buffer - t, err := template.New("").Parse(v) - if err != nil { - return nil, errors.ErrInvalid. - WithMsgf("label template for '%s' is invalid", k).WithCausef(err.Error()) - } else if err := t.Execute(&buf, labels); err != nil { - return nil, errors.ErrInvalid. - WithMsgf("failed to render label template").WithCausef(err.Error()) - } - - telegrafTags[k] = buf.String() + telegrafTags, err := renderLabels(conf.Telegraf.Config.AdditionalGlobalTags, labels) + if err != nil { + return nil, err } telegrafConf = Telegraf{ @@ -96,6 +87,11 @@ func (*firehoseDriver) getHelmRelease(labels map[string]string, conf Config) (*h } } + deploymentLabels, err := renderLabels(fd.conf.Labels, labels) + if err != nil { + return nil, err + } + rc := helm.DefaultReleaseConfig() rc.Name = conf.DeploymentID rc.Repository = chartRepo @@ -104,6 +100,10 @@ func (*firehoseDriver) getHelmRelease(labels map[string]string, conf Config) (*h rc.ForceUpdate = true rc.Version = conf.ChartValues.ChartVersion rc.Values = map[string]interface{}{ + "labels": cloneAndMergeMaps(deploymentLabels, map[string]string{ + "deployment": conf.DeploymentID, + "orchestrator": "entropy", + }), "replicaCount": conf.Replicas, "firehose": map[string]interface{}{ "image": map[string]interface{}{ @@ -126,6 +126,24 @@ func (*firehoseDriver) getHelmRelease(labels map[string]string, conf Config) (*h return rc, nil } +func renderLabels(labelsTpl map[string]string, labelsValues map[string]string) (map[string]string, error) { + finalLabels := map[string]string{} + for k, v := range labelsTpl { + var buf bytes.Buffer + t, err := template.New("").Parse(v) + if err != nil { + return nil, errors.ErrInvalid. + WithMsgf("label template for '%s' is invalid", k).WithCausef(err.Error()) + } else if err := t.Execute(&buf, labelsValues); err != nil { + return nil, errors.ErrInvalid. + WithMsgf("failed to render label template").WithCausef(err.Error()) + } + + finalLabels[k] = buf.String() + } + return finalLabels, nil +} + func mergeChartValues(cur, newVal *ChartValues) (*ChartValues, error) { if newVal == nil { return cur, nil @@ -170,9 +188,20 @@ func readTransientData(exr module.ExpandedResource) (*transientData, error) { } func mustJSON(v any) json.RawMessage { - bytes, err := json.Marshal(v) + b, err := json.Marshal(v) if err != nil { panic(err) } - return bytes + return b +} + +func cloneAndMergeMaps(m1, m2 map[string]string) map[string]string { + res := map[string]string{} + for k, v := range m1 { + res[k] = v + } + for k, v := range m2 { + res[k] = v + } + return res } From 199def5da39bbc95f096a56fa504ece012d82a3b Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Tue, 4 Apr 2023 13:43:05 +0530 Subject: [PATCH 29/72] fix: expose name in firehose module (#28) --- modules/firehose/driver.go | 35 ++++++++++++++++++++----------- modules/firehose/driver_output.go | 2 +- modules/firehose/driver_sync.go | 2 +- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 313bf9a7..32751bca 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -9,6 +9,7 @@ import ( "time" "github.com/goto/entropy/core/module" + "github.com/goto/entropy/core/resource" "github.com/goto/entropy/modules/kubernetes" "github.com/goto/entropy/pkg/errors" "github.com/goto/entropy/pkg/helm" @@ -69,10 +70,10 @@ type transientData struct { ResetOffsetTo string `json:"reset_offset_to,omitempty"` } -func (fd *firehoseDriver) getHelmRelease(labels map[string]string, conf Config) (*helm.ReleaseConfig, error) { +func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config) (*helm.ReleaseConfig, error) { var telegrafConf Telegraf if conf.Telegraf != nil && conf.Telegraf.Enabled { - telegrafTags, err := renderLabels(conf.Telegraf.Config.AdditionalGlobalTags, labels) + telegrafTags, err := renderLabels(conf.Telegraf.Config.AdditionalGlobalTags, res.Labels) if err != nil { return nil, err } @@ -87,7 +88,13 @@ func (fd *firehoseDriver) getHelmRelease(labels map[string]string, conf Config) } } - deploymentLabels, err := renderLabels(fd.conf.Labels, labels) + labelTpl := cloneAndMergeMaps(res.Labels, map[string]string{ + "name": res.Name, + "deployment": conf.DeploymentID, + "orchestrator": "entropy", + }) + + deploymentLabels, err := renderLabels(fd.conf.Labels, labelTpl) if err != nil { return nil, err } @@ -99,21 +106,18 @@ func (fd *firehoseDriver) getHelmRelease(labels map[string]string, conf Config) rc.Namespace = conf.Namespace rc.ForceUpdate = true rc.Version = conf.ChartValues.ChartVersion - rc.Values = map[string]interface{}{ - "labels": cloneAndMergeMaps(deploymentLabels, map[string]string{ - "deployment": conf.DeploymentID, - "orchestrator": "entropy", - }), + rc.Values = map[string]any{ + "labels": deploymentLabels, "replicaCount": conf.Replicas, - "firehose": map[string]interface{}{ - "image": map[string]interface{}{ + "firehose": map[string]any{ + "image": map[string]any{ "repository": imageRepo, "pullPolicy": conf.ChartValues.ImagePullPolicy, "tag": conf.ChartValues.ImageTag, }, "config": conf.EnvVariables, }, - "telegraf": map[string]interface{}{ + "telegraf": map[string]any{ "enabled": telegrafConf.Enabled, "image": telegrafConf.Image, "config": map[string]any{ @@ -127,10 +131,12 @@ func (fd *firehoseDriver) getHelmRelease(labels map[string]string, conf Config) } func renderLabels(labelsTpl map[string]string, labelsValues map[string]string) (map[string]string, error) { + const useZeroValueForMissingKey = "missingkey=zero" + finalLabels := map[string]string{} for k, v := range labelsTpl { var buf bytes.Buffer - t, err := template.New("").Parse(v) + t, err := template.New("").Option(useZeroValueForMissingKey).Parse(v) if err != nil { return nil, errors.ErrInvalid. WithMsgf("label template for '%s' is invalid", k).WithCausef(err.Error()) @@ -139,6 +145,11 @@ func renderLabels(labelsTpl map[string]string, labelsValues map[string]string) ( WithMsgf("failed to render label template").WithCausef(err.Error()) } + labelVal := strings.TrimSpace(buf.String()) + if labelVal == "" { + continue + } + finalLabels[k] = buf.String() } return finalLabels, nil diff --git a/modules/firehose/driver_output.go b/modules/firehose/driver_output.go index ea3c7e04..32d9d913 100644 --- a/modules/firehose/driver_output.go +++ b/modules/firehose/driver_output.go @@ -32,7 +32,7 @@ func (fd *firehoseDriver) Output(ctx context.Context, exr module.ExpandedResourc func (fd *firehoseDriver) refreshOutput(ctx context.Context, r resource.Resource, conf Config, output Output, kubeOut kubernetes.Output, ) (json.RawMessage, error) { - rc, err := fd.getHelmRelease(r.Labels, conf) + rc, err := fd.getHelmRelease(r, conf) if err != nil { return nil, err } diff --git a/modules/firehose/driver_sync.go b/modules/firehose/driver_sync.go index 492f33d4..78f46dde 100644 --- a/modules/firehose/driver_sync.go +++ b/modules/firehose/driver_sync.go @@ -98,7 +98,7 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) func (fd *firehoseDriver) releaseSync(ctx context.Context, r resource.Resource, isCreate bool, conf Config, kubeOut kubernetes.Output, ) error { - rc, err := fd.getHelmRelease(r.Labels, conf) + rc, err := fd.getHelmRelease(r, conf) if err != nil { return err } From 00fc0d6d352a086140b3b39059e8c95ceff69aa9 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Wed, 5 Apr 2023 11:09:46 +0530 Subject: [PATCH 30/72] refactor: simplify helm package (#29) --- modules/firehose/driver.go | 26 ++- modules/firehose/module.go | 25 ++- pkg/helm/client.go | 63 ------ pkg/helm/{kube_rest.go => config.go} | 33 ++-- pkg/helm/helm.go | 227 ++++++++++++++++++++++ pkg/helm/release.go | 280 +-------------------------- pkg/helm/release_test.go | 125 ------------ pkg/helm/status.go | 11 -- 8 files changed, 286 insertions(+), 504 deletions(-) delete mode 100644 pkg/helm/client.go rename pkg/helm/{kube_rest.go => config.go} (56%) create mode 100644 pkg/helm/helm.go delete mode 100644 pkg/helm/release_test.go delete mode 100644 pkg/helm/status.go diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 32751bca..b74c500b 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -29,6 +29,17 @@ const ( imageRepo = "gotocompany/firehose" ) +const ( + labelsConfKey = "labels" + + labelName = "name" + labelProject = "project" + labelDeployment = "deployment" + labelOrchestrator = "orchestrator" + + orchestratorLabelValue = "entropy" +) + var defaultDriverConf = driverConf{ Namespace: "firehose", ChartValues: ChartValues{ @@ -88,13 +99,14 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config) (*h } } - labelTpl := cloneAndMergeMaps(res.Labels, map[string]string{ - "name": res.Name, - "deployment": conf.DeploymentID, - "orchestrator": "entropy", - }) + entropyLabels := map[string]string{ + labelName: res.Name, + labelProject: res.Project, + labelDeployment: conf.DeploymentID, + labelOrchestrator: orchestratorLabelValue, + } - deploymentLabels, err := renderLabels(fd.conf.Labels, labelTpl) + deploymentLabels, err := renderLabels(fd.conf.Labels, cloneAndMergeMaps(res.Labels, entropyLabels)) if err != nil { return nil, err } @@ -107,7 +119,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config) (*h rc.ForceUpdate = true rc.Version = conf.ChartValues.ChartVersion rc.Values = map[string]any{ - "labels": deploymentLabels, + labelsConfKey: cloneAndMergeMaps(deploymentLabels, entropyLabels), "replicaCount": conf.Replicas, "firehose": map[string]any{ "image": map[string]any{ diff --git a/modules/firehose/module.go b/modules/firehose/module.go index 8c5c350d..5b0b35b8 100644 --- a/modules/firehose/module.go +++ b/modules/firehose/module.go @@ -6,6 +6,8 @@ import ( "encoding/json" "time" + "helm.sh/helm/v3/pkg/release" + "github.com/goto/entropy/core/module" "github.com/goto/entropy/modules/kubernetes" "github.com/goto/entropy/pkg/errors" @@ -73,14 +75,25 @@ var Module = module.Descriptor{ conf: conf, timeNow: time.Now, kubeDeploy: func(_ context.Context, isCreate bool, kubeConf kube.Config, hc helm.ReleaseConfig) error { - helmCl := helm.NewClient(&helm.Config{Kubernetes: kubeConf}) + canUpdate := func(rel *release.Release) bool { + curLabels, ok := rel.Config[labelsConfKey].(map[string]any) + if !ok { + return false + } + newLabels, ok := hc.Values[labelsConfKey].(map[string]string) + if !ok { + return false + } + + isManagedByEntropy := curLabels[labelOrchestrator] == orchestratorLabelValue + isSameProject := curLabels[labelProject] == newLabels[labelProject] + isSameName := curLabels[labelName] == newLabels[labelName] - var errHelm error - if isCreate { - _, errHelm = helmCl.Create(&hc) - } else { - _, errHelm = helmCl.Update(&hc) + return isManagedByEntropy && isSameProject && isSameName } + + helmCl := helm.NewClient(&helm.Config{Kubernetes: kubeConf}) + _, errHelm := helmCl.Upsert(&hc, canUpdate) return errHelm }, kubeGetPod: func(ctx context.Context, conf kube.Config, ns string, labels map[string]string) ([]kube.Pod, error) { diff --git a/pkg/helm/client.go b/pkg/helm/client.go deleted file mode 100644 index 5059b00e..00000000 --- a/pkg/helm/client.go +++ /dev/null @@ -1,63 +0,0 @@ -package helm - -import ( - "github.com/mcuadros/go-defaults" - "helm.sh/helm/v3/pkg/action" - "helm.sh/helm/v3/pkg/cli" - apimachineryschema "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - "k8s.io/client-go/tools/clientcmd/api" - - "github.com/goto/entropy/pkg/kube" -) - -type Config struct { - // HelmDriver - The backend storage driver. Values are - configmap, secret, memory, sql - HelmDriver string `default:"secret"` - // Kubernetes configuration. - Kubernetes kube.Config -} - -type Client struct { - config *Config - cliSettings *cli.EnvSettings -} - -func DefaultClientConfig() *Config { - defaultProviderConfig := new(Config) - defaults.SetDefaults(defaultProviderConfig) - return defaultProviderConfig -} - -func NewClient(config *Config) *Client { - return &Client{config: config, cliSettings: cli.New()} -} - -func (p *Client) getActionConfiguration(namespace string) (*action.Configuration, error) { - actionConfig := new(action.Configuration) - - overrides := &clientcmd.ConfigOverrides{} - - overrides.AuthInfo.ClientCertificateData = []byte(p.config.Kubernetes.ClientCertificate) - overrides.AuthInfo.ClientKeyData = []byte(p.config.Kubernetes.ClientKey) - overrides.AuthInfo.Token = p.config.Kubernetes.Token - overrides.ClusterInfo.CertificateAuthorityData = []byte(p.config.Kubernetes.ClusterCACertificate) - overrides.ClusterInfo.InsecureSkipTLSVerify = p.config.Kubernetes.Insecure - - hasCA := len(overrides.ClusterInfo.CertificateAuthorityData) != 0 - hasCert := len(overrides.AuthInfo.ClientCertificateData) != 0 - defaultTLS := hasCA || hasCert || overrides.ClusterInfo.InsecureSkipTLSVerify - host, _, err := rest.DefaultServerURL(p.config.Kubernetes.Host, "", apimachineryschema.GroupVersion{}, defaultTLS) - if err != nil { - return nil, err - } - overrides.ClusterInfo.Server = host.String() - - clientConfig := clientcmd.NewDefaultClientConfig(*api.NewConfig(), overrides) - - if err := actionConfig.Init(&KubeConfig{ClientConfig: clientConfig}, namespace, p.config.HelmDriver, func(format string, v ...interface{}) {}); err != nil { - return nil, err - } - return actionConfig, nil -} diff --git a/pkg/helm/kube_rest.go b/pkg/helm/config.go similarity index 56% rename from pkg/helm/kube_rest.go rename to pkg/helm/config.go index 8741df20..b966ff82 100644 --- a/pkg/helm/kube_rest.go +++ b/pkg/helm/config.go @@ -1,47 +1,49 @@ package helm import ( - "sync" - "k8s.io/apimachinery/pkg/api/meta" "k8s.io/client-go/discovery" memcached "k8s.io/client-go/discovery/cached/memory" "k8s.io/client-go/rest" "k8s.io/client-go/restmapper" "k8s.io/client-go/tools/clientcmd" + + "github.com/goto/entropy/pkg/kube" ) -// KubeConfig is a RESTClientGetter interface implementation +// Config contains Helm CLI configuration parameters. +type Config struct { + HelmDriver string `default:"secret"` // values: configmap/secret/memory/sql + Kubernetes kube.Config +} + +// kubeClientGetter is a RESTClientGetter interface implementation // comes from https://github.com/hashicorp/terraform-provider-helm -type KubeConfig struct { +type kubeClientGetter struct { ClientConfig clientcmd.ClientConfig - - sync.Mutex } -// ToRESTConfig implemented interface method. -func (k *KubeConfig) ToRESTConfig() (*rest.Config, error) { +func (k *kubeClientGetter) ToRESTConfig() (*rest.Config, error) { config, err := k.ToRawKubeConfigLoader().ClientConfig() return config, err } -// ToDiscoveryClient implemented interface method. -func (k *KubeConfig) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) { +func (k *kubeClientGetter) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) { config, err := k.ToRESTConfig() if err != nil { return nil, err } // The more groups you have, the more discovery requests you need to make. - // given 25 groups (our groups + a few custom resources) with one-ish version each, discovery needs to make 50 requests - // double it just so we don't end up here again for a while. This config is only used for discovery. + // given 25 groups (our groups + a few custom resources) with one-ish version + // each, discovery needs to make 50 requests double it just so we don't end + // up here again for a while. This config is only used for discovery. config.Burst = 100 return memcached.NewMemCacheClient(discovery.NewDiscoveryClientForConfigOrDie(config)), nil } -// ToRESTMapper implemented interface method. -func (k *KubeConfig) ToRESTMapper() (meta.RESTMapper, error) { +func (k *kubeClientGetter) ToRESTMapper() (meta.RESTMapper, error) { discoveryClient, err := k.ToDiscoveryClient() if err != nil { return nil, err @@ -52,7 +54,6 @@ func (k *KubeConfig) ToRESTMapper() (meta.RESTMapper, error) { return expander, nil } -// ToRawKubeConfigLoader implemented interface method. -func (k *KubeConfig) ToRawKubeConfigLoader() clientcmd.ClientConfig { +func (k *kubeClientGetter) ToRawKubeConfigLoader() clientcmd.ClientConfig { return k.ClientConfig } diff --git a/pkg/helm/helm.go b/pkg/helm/helm.go new file mode 100644 index 00000000..c032a1fa --- /dev/null +++ b/pkg/helm/helm.go @@ -0,0 +1,227 @@ +package helm + +import ( + "fmt" + "net/url" + "strings" + "time" + + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/chart" + "helm.sh/helm/v3/pkg/chart/loader" + "helm.sh/helm/v3/pkg/cli" + "helm.sh/helm/v3/pkg/release" + apimachineryschema "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/tools/clientcmd/api" + + "github.com/goto/entropy/pkg/errors" +) + +type Client struct { + config *Config + cliSettings *cli.EnvSettings +} + +func (p *Client) Upsert(config *ReleaseConfig, canUpdateCheck func(rel *release.Release) bool) (*Result, error) { + actionConfig, err := p.getActionConfiguration(config.Namespace) + if err != nil { + return nil, errors.ErrInternal.WithMsgf("error while getting action configuration : %s", err) + } + + rel, err := fetchRelease(actionConfig, config.Name) + if err != nil && !errors.Is(err, errors.ErrNotFound) { + return nil, errors.ErrInternal.WithMsgf("failed to find release").WithCausef(err.Error()) + } + + isCreate := rel == nil // release doesn't exist already. + canUpdate := !isCreate && canUpdateCheck(rel) // exists already and we are allowed to update. + if !isCreate && !canUpdate { + return nil, errors.ErrConflict.WithMsgf("release with same name exists, but update not possible") + } + + if isCreate { + // release does not exist. + return p.doCreate(actionConfig, config) + } + + // already exists and is updatable. + return p.doUpdate(actionConfig, config) +} + +func (p *Client) Delete(config *ReleaseConfig) error { + actionConfig, err := p.getActionConfiguration(config.Namespace) + if err != nil { + return errors.ErrInternal.WithMsgf("error while getting action configuration : %s", err) + } + + act := action.NewUninstall(actionConfig) + if _, err := act.Run(config.Name); err != nil { + return errors.ErrInternal.WithMsgf("unable to uninstall release %s", err) + } + return nil +} + +func (p *Client) doCreate(actionConfig *action.Configuration, config *ReleaseConfig) (*Result, error) { + fetchedChart, chartPathOpts, err := p.getChart(config) + if err != nil { + return nil, errors.ErrInternal.WithMsgf("error while getting chart").WithCausef(err.Error()) + } + + act := action.NewInstall(actionConfig) + act.Wait = config.Wait + act.DryRun = false + act.Timeout = time.Duration(config.Timeout) * time.Second + act.Replace = config.Replace + act.OutputDir = "" + act.Namespace = config.Namespace + act.ClientOnly = false + act.Description = config.Description + act.WaitForJobs = config.WaitForJobs + act.ReleaseName = config.Name + act.GenerateName = false + act.NameTemplate = "" + act.CreateNamespace = config.CreateNamespace + act.ChartPathOptions = *chartPathOpts + + rel, err := act.Run(fetchedChart, config.Values) + if err != nil { + return nil, errors.ErrInternal.WithMsgf("create-release failed").WithCausef(err.Error()) + } + + return &Result{ + Config: config, + Release: rel, + }, nil +} + +func (p *Client) doUpdate(actionConfig *action.Configuration, config *ReleaseConfig) (*Result, error) { + fetchedChart, chartPathOpts, err := p.getChart(config) + if err != nil { + return nil, errors.ErrInternal.WithMsgf("error while getting chart").WithCausef(err.Error()) + } + + act := action.NewUpgrade(actionConfig) + act.ChartPathOptions = *chartPathOpts + act.DryRun = false + act.Wait = config.Wait + act.WaitForJobs = config.WaitForJobs + act.Timeout = time.Duration(config.Timeout) * time.Second + act.Namespace = config.Namespace + act.Description = config.Description + + rel, err := act.Run(config.Name, fetchedChart, config.Values) + if err != nil { + if isReleaseNotFoundErr(err) { + return nil, errors.ErrNotFound. + WithMsgf("update-release failed"). + WithCausef("release with given name not found") + } + return nil, errors.ErrInternal.WithMsgf("update-release failed").WithCausef(err.Error()) + } + + return &Result{ + Config: config, + Release: rel, + }, nil +} + +func (p *Client) getChart(config *ReleaseConfig) (*chart.Chart, *action.ChartPathOptions, error) { + repositoryURL, chartName := resolveChartName(config.Repository, strings.TrimSpace(config.Chart)) + + chartPathOpts := &action.ChartPathOptions{ + RepoURL: repositoryURL, + Version: getVersion(config.Version), + } + + // TODO: Add a lock as Load function blows up if accessed concurrently + path, err := chartPathOpts.LocateChart(chartName, p.cliSettings) + if err != nil { + return nil, nil, err + } + + fetchedChart, err := loader.Load(path) + if err != nil { + return nil, nil, err + } + + // TODO: check if chart has dependencies and load those dependencies + if fetchedChart.Metadata.Type != typeApplication { + return nil, nil, ErrChartNotApplication + } + + return fetchedChart, chartPathOpts, nil +} + +func (p *Client) getActionConfiguration(namespace string) (*action.Configuration, error) { + hasCA := len(p.config.Kubernetes.ClusterCACertificate) != 0 + hasCert := len(p.config.Kubernetes.ClientCertificate) != 0 + defaultTLS := hasCA || hasCert || p.config.Kubernetes.Insecure + host, _, err := rest.DefaultServerURL(p.config.Kubernetes.Host, "", apimachineryschema.GroupVersion{}, defaultTLS) + if err != nil { + return nil, err + } + + clientConfig := clientcmd.NewDefaultClientConfig(*api.NewConfig(), &clientcmd.ConfigOverrides{ + AuthInfo: api.AuthInfo{ + Token: p.config.Kubernetes.Token, + ClientKeyData: []byte(p.config.Kubernetes.ClientKey), + ClientCertificateData: []byte(p.config.Kubernetes.ClientCertificate), + }, + ClusterInfo: api.Cluster{ + Server: host.String(), + InsecureSkipTLSVerify: p.config.Kubernetes.Insecure, + CertificateAuthorityData: []byte(p.config.Kubernetes.ClusterCACertificate), + }, + }) + kubeConf := &kubeClientGetter{ClientConfig: clientConfig} + + actionConfig := &action.Configuration{} + if err := actionConfig.Init(kubeConf, namespace, p.config.HelmDriver, noOpLog); err != nil { + return nil, err + } + return actionConfig, nil +} + +func NewClient(config *Config) *Client { + return &Client{config: config, cliSettings: cli.New()} +} + +func fetchRelease(cfg *action.Configuration, name string) (*release.Release, error) { + get := action.NewGet(cfg) + res, err := get.Run(name) + if err != nil { + if isReleaseNotFoundErr(err) { + return nil, errors.ErrNotFound.WithCausef(err.Error()) + } + return nil, err + } + return res, nil +} + +func getVersion(version string) string { + if version == "" { + return ">0.0.0-0" + } + return strings.TrimSpace(version) +} + +func resolveChartName(repository, name string) (string, string) { + _, err := url.ParseRequestURI(repository) + if err == nil { + return repository, name + } + + if !strings.Contains(name, "/") && repository != "" { + name = fmt.Sprintf("%s/%s", repository, name) + } + + return "", name +} + +func isReleaseNotFoundErr(err error) bool { + return strings.Contains(err.Error(), "release: not found") +} + +func noOpLog(_ string, _ ...interface{}) {} diff --git a/pkg/helm/release.go b/pkg/helm/release.go index f82ad10e..07aa9b8d 100644 --- a/pkg/helm/release.go +++ b/pkg/helm/release.go @@ -1,16 +1,7 @@ package helm import ( - "encoding/json" - "fmt" - "net/url" - "strings" - "time" - "github.com/mcuadros/go-defaults" - "helm.sh/helm/v3/pkg/action" - "helm.sh/helm/v3/pkg/chart" - "helm.sh/helm/v3/pkg/chart/loader" "helm.sh/helm/v3/pkg/release" "github.com/goto/entropy/pkg/errors" @@ -18,12 +9,11 @@ import ( var ( typeApplication = "application" - ErrReleaseNotFound = errors.New("release not found") ErrChartNotApplication = errors.New("helm chart is not an application chart") ) type ReleaseConfig struct { - // Name - Release Name + // Name - Result Name Name string `json:"name" mapstructure:"name"` // Repository - Repository where to locate the requested chart. If is a URL the chart is installed without installing the repository. Repository string `json:"repository" mapstructure:"repository"` @@ -53,16 +43,9 @@ type ReleaseConfig struct { CreateNamespace bool `json:"create_namespace" mapstructure:"create_namespace" default:"false"` } -type Release struct { - Config *ReleaseConfig - Output ReleaseOutput -} - -type ReleaseOutput struct { - // Status - Status of the release. - Status Status - // Revision - Revision of the release. - Release string +type Result struct { + Config *ReleaseConfig + Release *release.Release } func DefaultReleaseConfig() *ReleaseConfig { @@ -70,258 +53,3 @@ func DefaultReleaseConfig() *ReleaseConfig { defaults.SetDefaults(defaultReleaseConfig) return defaultReleaseConfig } - -// Create - creates a helm release with its configs. -func (p *Client) Create(config *ReleaseConfig) (*Release, error) { - actionConfig, err := p.getActionConfiguration(config.Namespace) - if err != nil { - return nil, errors.ErrInternal.WithMsgf("error while getting action configuration: %s", err) - } - - chartPathOptions, chartName := p.chartPathOptions(config) - - fetchedChart, err := p.getChart(chartName, chartPathOptions) - if err != nil { - return nil, errors.ErrInternal.WithMsgf("error while getting chart: %s", err) - } - - // TODO: check if chart has dependencies and load those dependencies - - if fetchedChart.Metadata.Type != typeApplication { - return nil, ErrChartNotApplication - } - - client := action.NewInstall(actionConfig) - client.ChartPathOptions = *chartPathOptions - client.ClientOnly = false - client.DryRun = false - client.Wait = config.Wait - client.WaitForJobs = config.WaitForJobs - client.Timeout = time.Second * time.Duration(config.Timeout) - client.Namespace = config.Namespace - client.ReleaseName = config.Name - client.GenerateName = false - client.NameTemplate = "" - client.OutputDir = "" - client.Replace = config.Replace - client.Description = config.Description - client.CreateNamespace = config.CreateNamespace - - rel, err := client.Run(fetchedChart, config.Values) - if err != nil && rel == nil { - return nil, errors.ErrInternal.WithMsgf("error while installing release: %s", err) - } - - if err != nil && rel != nil { - releaseExists, releaseErr := p.resourceReleaseExists(config.Name, config.Namespace) - - if releaseErr != nil { - return nil, errors.ErrConflict.WithMsgf("release already exists: %s", releaseErr) - } - - if !releaseExists { - return nil, errors.ErrNotFound.WithMsgf("release doesn't exists: %s", err) - } - - releaseJSON, err := json.Marshal(rel) - if err != nil { - return nil, errors.ErrInternal.WithMsgf("error while json marshalling release: %s", err) - } - - return &Release{ - Config: config, - Output: ReleaseOutput{ - Status: mapReleaseStatus(rel.Info.Status), - Release: string(releaseJSON), - }, - }, errors.ErrInternal.WithMsgf("helm release created with failure: %s", err) - } - - releaseJSON, err := json.Marshal(rel) - if err != nil { - return nil, errors.ErrInternal.WithMsgf("error while json marshalling release: %s", err) - } - - return &Release{ - Config: config, - Output: ReleaseOutput{ - Status: mapReleaseStatus(rel.Info.Status), - Release: string(releaseJSON), - }, - }, nil -} - -// Update - updates a helm release with its configs. -func (p *Client) Update(config *ReleaseConfig) (*Release, error) { - var rel *release.Release - - actionConfig, err := p.getActionConfiguration(config.Namespace) - if err != nil { - return nil, errors.ErrInternal.WithMsgf("error while getting action configuration : %s", err) - } - - chartPathOptions, chartName := p.chartPathOptions(config) - - fetchedChart, err := p.getChart(chartName, chartPathOptions) - if err != nil { - return nil, errors.ErrInternal.WithMsgf("error while getting fetchedChart : %s", err) - } - - // TODO: check if fetchedChart has dependencies and load those dependencies - - if fetchedChart.Metadata.Type != typeApplication { - return nil, ErrChartNotApplication - } - - client := action.NewUpgrade(actionConfig) - client.ChartPathOptions = *chartPathOptions - client.DryRun = false - client.Wait = config.Wait - client.WaitForJobs = config.WaitForJobs - client.Timeout = time.Second * time.Duration(config.Timeout) - client.Namespace = config.Namespace - client.Description = config.Description - - rel, err = client.Run(config.Name, fetchedChart, config.Values) - if err != nil && rel == nil { - return nil, errors.ErrInternal.WithMsgf("error while updating release: %s", err) - } - - if err != nil && rel != nil { - releaseExists, _ := p.resourceReleaseExists(config.Name, config.Namespace) - - if !releaseExists { - return nil, errors.ErrNotFound.WithMsgf("release doesn't exists: %s", err) - } - - releaseJSON, jsonErr := json.Marshal(rel) - if jsonErr != nil { - return nil, errors.ErrInternal.WithMsgf("error while json marshalling release: %s", err) - } - - return &Release{ - Config: config, - Output: ReleaseOutput{ - Status: mapReleaseStatus(rel.Info.Status), - Release: string(releaseJSON), - }, - }, errors.ErrInternal.WithMsgf("helm release updated with failure: %s", err) - } - - releaseJSON, err := json.Marshal(rel) - if err != nil { - return nil, errors.ErrInternal.WithMsgf("error while json marshalling release: %s", err) - } - - return &Release{ - Config: config, - Output: ReleaseOutput{ - Status: mapReleaseStatus(rel.Info.Status), - Release: string(releaseJSON), - }, - }, nil -} - -func (p *Client) Delete(config *ReleaseConfig) error { - actionConfig, err := p.getActionConfiguration(config.Namespace) - if err != nil { - return errors.ErrInternal.WithMsgf("error while getting action configuration : %s", err) - } - - uninstall := action.NewUninstall(actionConfig) - run, err := uninstall.Run(config.Name) - if run != nil && run.Release.Info.Status == release.StatusUninstalled || run.Release.Info.Status == release.StatusUninstalling { - return nil - } else { - return errors.ErrInternal.WithMsgf("unable to uninstall release %s", err) - } -} - -func (*Client) chartPathOptions(config *ReleaseConfig) (*action.ChartPathOptions, string) { - repositoryURL, chartName := resolveChartName(config.Repository, strings.TrimSpace(config.Chart)) - - version := getVersion(config.Version) - - return &action.ChartPathOptions{ - RepoURL: repositoryURL, - Version: version, - }, chartName -} - -func resolveChartName(repository, name string) (string, string) { - _, err := url.ParseRequestURI(repository) - if err == nil { - return repository, name - } - - if !strings.Contains(name, "/") && repository != "" { - name = fmt.Sprintf("%s/%s", repository, name) - } - - return "", name -} - -func getVersion(version string) string { - if version == "" { - return ">0.0.0-0" - } - return strings.TrimSpace(version) -} - -func (p *Client) getChart(name string, cpo *action.ChartPathOptions) (*chart.Chart, error) { - // TODO: Add a lock as Load function blows up if accessed concurrently - path, err := cpo.LocateChart(name, p.cliSettings) - if err != nil { - return nil, err - } - - c, err := loader.Load(path) - if err != nil { - return nil, err - } - return c, nil -} - -func (p *Client) resourceReleaseExists(name string, namespace string) (bool, error) { - c, err := p.getActionConfiguration(namespace) - if err != nil { - return false, err - } - - _, err = p.getRelease(c, name) - - if err == nil { - return true, nil - } - - if errors.Is(err, ErrReleaseNotFound) { - return false, nil - } - - return false, err -} - -func (*Client) getRelease(cfg *action.Configuration, name string) (*release.Release, error) { - // TODO: Add provider level lock to make sure no other operation is changing this release - - get := action.NewGet(cfg) - res, err := get.Run(name) - if err != nil { - if strings.Contains(err.Error(), "release: not found") { - return nil, ErrReleaseNotFound - } - return nil, err - } - return res, nil -} - -func mapReleaseStatus(status release.Status) Status { - switch status { - case "unknown": - return StatusUnknown - case "deployed": - return StatusSuccess - default: - return StatusFailed - } -} diff --git a/pkg/helm/release_test.go b/pkg/helm/release_test.go deleted file mode 100644 index fd973f1e..00000000 --- a/pkg/helm/release_test.go +++ /dev/null @@ -1,125 +0,0 @@ -//go:build integration -// +build integration - -package helm - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "math/rand" - "os" - "testing" - - "github.com/stretchr/testify/assert" -) - -var jsonValues = ` -{ - "firehose": { - "image": { - "tag": "0.1.1" - } - } -} -` - -var updatedJsonValues = ` -{ - "firehose": { - "image": { - "tag": "0.1.2" - } - } -} -` - -func jsonMarshal(data interface{}) string { - j, _ := json.MarshalIndent(data, "", " ") - return string(j) -} - -func jsonUnmarshal(data string) map[string]interface{} { - ret := map[string]interface{}{} - _ = json.Unmarshal([]byte(data), &ret) - return ret -} - -func getClient() *Client { - envKubeAPIServer := os.Getenv("TEST_K8S_API_SERVER") - envKubeSAToken := os.Getenv("TEST_K8S_SA_TOKEN") - clientConfig := DefaultClientConfig() - clientConfig.Kubernetes.Host = envKubeAPIServer - clientConfig.Kubernetes.Insecure = true - tokenBytes, _ := base64.StdEncoding.DecodeString(envKubeSAToken) - clientConfig.Kubernetes.Token = string(tokenBytes) - return NewClient(clientConfig) -} - -func TestReleaseCreate(t *testing.T) { - client := getClient() - - releaseName := fmt.Sprintf("test-entropy-helm-client-create-%d", rand.Int()) - - releaseConfig := DefaultReleaseConfig() - releaseConfig.Name = releaseName - releaseConfig.Repository = "https://goto.github.io/charts/" - releaseConfig.Chart = "firehose" - releaseConfig.Version = "0.1.1" - releaseConfig.Values = jsonUnmarshal(jsonValues) - releaseConfig.WaitForJobs = true - rel, err := client.Create(releaseConfig) - - assert.Nil(t, err) - assert.NotNil(t, rel) - - _ = client.Delete(releaseConfig) -} - -func TestReleaseUpdate(t *testing.T) { - client := getClient() - - releaseName := fmt.Sprintf("test-entropy-helm-client-update-%d", rand.Int()) - - releaseConfig := DefaultReleaseConfig() - releaseConfig.Name = releaseName - releaseConfig.Repository = "https://goto.github.io/charts/" - releaseConfig.Chart = "firehose" - releaseConfig.Version = "0.1.1" - releaseConfig.Values = jsonUnmarshal(jsonValues) - releaseConfig.WaitForJobs = true - rel, err := client.Create(releaseConfig) - - assert.Nil(t, err) - assert.NotNil(t, rel) - - releaseConfig.Values = jsonUnmarshal(updatedJsonValues) - rel2, err := client.Update(releaseConfig) - - assert.Nil(t, err) - assert.NotNil(t, rel2) - - _ = client.Delete(releaseConfig) -} - -func TestReleaseDelete(t *testing.T) { - client := getClient() - - releaseName := fmt.Sprintf("test-entropy-helm-client-delete-%d", rand.Int()) - - releaseConfig := DefaultReleaseConfig() - releaseConfig.Name = releaseName - releaseConfig.Repository = "https://goto.github.io/charts/" - releaseConfig.Chart = "firehose" - releaseConfig.Version = "0.1.1" - releaseConfig.Values = jsonUnmarshal(jsonValues) - releaseConfig.WaitForJobs = true - rel, err := client.Create(releaseConfig) - - assert.Nil(t, err) - assert.NotNil(t, rel) - - err = client.Delete(releaseConfig) - - assert.Nil(t, err) -} diff --git a/pkg/helm/status.go b/pkg/helm/status.go deleted file mode 100644 index 4db8b81c..00000000 --- a/pkg/helm/status.go +++ /dev/null @@ -1,11 +0,0 @@ -package helm - -const ( - StatusUnknown Status = "unknown" - StatusSuccess Status = "success" - StatusFailed Status = "failed" -) - -type Status string - -func (x Status) String() string { return string(x) } From a354d34e1559f9125413775539b2c1c9461b6739 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Wed, 5 Apr 2023 17:15:23 +0530 Subject: [PATCH 31/72] feat: add labels to list-resource api (#30) --- Makefile | 2 +- internal/server/v1/resources/mappers.go | 15 +- internal/server/v1/resources/server.go | 2 +- proto/entropy.swagger.yaml | 12 + proto/gotocompany/common/v1/service.pb.go | 5 +- .../gotocompany/common/v1/service_grpc.pb.go | 1 - .../gotocompany/entropy/v1beta1/module.pb.go | 5 +- .../entropy/v1beta1/module_grpc.pb.go | 1 - .../entropy/v1beta1/resource.pb.go | 657 ++++++++++-------- .../entropy/v1beta1/resource.pb.validate.go | 35 + .../entropy/v1beta1/resource_grpc.pb.go | 1 - 11 files changed, 422 insertions(+), 314 deletions(-) diff --git a/Makefile b/Makefile index a8d73626..ee132c29 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ NAME=github.com/goto/entropy VERSION=$(shell git describe --tags --always --first-parent 2>/dev/null) COMMIT=$(shell git rev-parse --short HEAD) -PROTON_COMMIT="5b5dc727b525925bcec025b355983ca61d7ccf68" +PROTON_COMMIT="1d611a9efbfecfa54945906214b19b72e6fbb841" BUILD_TIME=$(shell date) COVERAGE_DIR=coverage BUILD_DIR=dist diff --git a/internal/server/v1/resources/mappers.go b/internal/server/v1/resources/mappers.go index 088d2f15..35fb5fd8 100644 --- a/internal/server/v1/resources/mappers.go +++ b/internal/server/v1/resources/mappers.go @@ -52,10 +52,19 @@ func resourceStateToProto(state resource.State) (*entropyv1beta1.ResourceState, protoStatus = entropyv1beta1.ResourceState_Status(resourceStatus) } + var nextSyncAt *timestamppb.Timestamp + if state.NextSyncAt != nil { + nextSyncAt = timestamppb.New(*state.NextSyncAt) + } + return &entropyv1beta1.ResourceState{ - Status: protoStatus, - Output: outputVal, - ModuleData: state.ModuleData, + Status: protoStatus, + Output: outputVal, + ModuleData: state.ModuleData, + LogOptions: nil, + SyncRetries: int32(state.SyncResult.Retries), + SyncLastError: state.SyncResult.LastError, + NextSyncAt: nextSyncAt, }, nil } diff --git a/internal/server/v1/resources/server.go b/internal/server/v1/resources/server.go index 5f7d93e5..b2f62be2 100644 --- a/internal/server/v1/resources/server.go +++ b/internal/server/v1/resources/server.go @@ -102,7 +102,7 @@ func (server APIServer) ListResources(ctx context.Context, request *entropyv1bet filter := resource.Filter{ Kind: request.GetKind(), Project: request.GetProject(), - Labels: nil, + Labels: request.Labels, } resources, err := server.resourceSvc.ListResources(ctx, filter) diff --git a/proto/entropy.swagger.yaml b/proto/entropy.swagger.yaml index 0559c476..cd86e5cd 100644 --- a/proto/entropy.swagger.yaml +++ b/proto/entropy.swagger.yaml @@ -510,9 +510,21 @@ definitions: module_data: type: string format: byte + next_sync_at: + type: string + format: date-time output: {} status: $ref: '#/definitions/ResourceState.Status' + sync_last_error: + type: string + sync_retries: + type: integer + format: int32 + description: |- + information about the ongoing sync process. + if status is ERROR / PENDING, this value can be used to understand + the issue. ResourceState.Status: type: string enum: diff --git a/proto/gotocompany/common/v1/service.pb.go b/proto/gotocompany/common/v1/service.pb.go index 551e9aac..5de1cb00 100644 --- a/proto/gotocompany/common/v1/service.pb.go +++ b/proto/gotocompany/common/v1/service.pb.go @@ -7,14 +7,13 @@ package v1 import ( - reflect "reflect" - sync "sync" - _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" ) const ( diff --git a/proto/gotocompany/common/v1/service_grpc.pb.go b/proto/gotocompany/common/v1/service_grpc.pb.go index 5823bcca..13c31ab3 100644 --- a/proto/gotocompany/common/v1/service_grpc.pb.go +++ b/proto/gotocompany/common/v1/service_grpc.pb.go @@ -4,7 +4,6 @@ package v1 import ( context "context" - grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" diff --git a/proto/gotocompany/entropy/v1beta1/module.pb.go b/proto/gotocompany/entropy/v1beta1/module.pb.go index 665a4a5a..e4c447b2 100644 --- a/proto/gotocompany/entropy/v1beta1/module.pb.go +++ b/proto/gotocompany/entropy/v1beta1/module.pb.go @@ -7,14 +7,13 @@ package entropyv1beta1 import ( - reflect "reflect" - sync "sync" - _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" structpb "google.golang.org/protobuf/types/known/structpb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" ) const ( diff --git a/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go b/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go index 45f627b3..c469596d 100644 --- a/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go +++ b/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go @@ -4,7 +4,6 @@ package entropyv1beta1 import ( context "context" - grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" diff --git a/proto/gotocompany/entropy/v1beta1/resource.pb.go b/proto/gotocompany/entropy/v1beta1/resource.pb.go index 8d68acb8..d691250b 100644 --- a/proto/gotocompany/entropy/v1beta1/resource.pb.go +++ b/proto/gotocompany/entropy/v1beta1/resource.pb.go @@ -7,14 +7,13 @@ package entropyv1beta1 import ( - reflect "reflect" - sync "sync" - _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" structpb "google.golang.org/protobuf/types/known/structpb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" ) const ( @@ -297,6 +296,12 @@ type ResourceState struct { Output *structpb.Value `protobuf:"bytes,2,opt,name=output,proto3" json:"output,omitempty"` ModuleData []byte `protobuf:"bytes,3,opt,name=module_data,json=moduleData,proto3" json:"module_data,omitempty"` LogOptions *LogOptions `protobuf:"bytes,4,opt,name=log_options,json=logOptions,proto3" json:"log_options,omitempty"` + // information about the ongoing sync process. + // if status is ERROR / PENDING, this value can be used to understand + // the issue. + SyncRetries int32 `protobuf:"varint,5,opt,name=sync_retries,json=syncRetries,proto3" json:"sync_retries,omitempty"` + SyncLastError string `protobuf:"bytes,6,opt,name=sync_last_error,json=syncLastError,proto3" json:"sync_last_error,omitempty"` + NextSyncAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=next_sync_at,json=nextSyncAt,proto3" json:"next_sync_at,omitempty"` } func (x *ResourceState) Reset() { @@ -359,6 +364,27 @@ func (x *ResourceState) GetLogOptions() *LogOptions { return nil } +func (x *ResourceState) GetSyncRetries() int32 { + if x != nil { + return x.SyncRetries + } + return 0 +} + +func (x *ResourceState) GetSyncLastError() string { + if x != nil { + return x.SyncLastError + } + return "" +} + +func (x *ResourceState) GetNextSyncAt() *timestamppb.Timestamp { + if x != nil { + return x.NextSyncAt + } + return nil +} + type Resource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -477,6 +503,9 @@ type ListResourcesRequest struct { Project string `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"` Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` + // filter by labels. if specified, only resources with all the + // given labels will be returned. + Labels map[string]string `protobuf:"bytes,3,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *ListResourcesRequest) Reset() { @@ -525,6 +554,13 @@ func (x *ListResourcesRequest) GetKind() string { return "" } +func (x *ListResourcesRequest) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + type ListResourcesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1452,7 +1488,7 @@ var file_gotocompany_entropy_v1beta1_resource_proto_rawDesc = []byte{ 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xe7, 0x02, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf0, 0x03, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x49, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, @@ -1467,269 +1503,287 @@ var file_gotocompany_entropy_v1beta1_resource_proto_rawDesc = []byte{ 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x0a, 0x6c, 0x6f, 0x67, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x70, - 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, - 0x4e, 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, - 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, - 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x04, - 0x22, 0xdb, 0x03, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x10, 0x0a, - 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, - 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, - 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x12, 0x49, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, - 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, - 0x41, 0x74, 0x12, 0x3d, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, - 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, - 0x63, 0x12, 0x40, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2a, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, - 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x44, - 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6b, 0x69, 0x6e, 0x64, 0x22, 0x5c, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, - 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, - 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x22, 0x26, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x22, 0x58, 0x0a, 0x13, 0x47, 0x65, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, - 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x22, 0x5a, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, + 0x6e, 0x73, 0x52, 0x0a, 0x6c, 0x6f, 0x67, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, + 0x0a, 0x0c, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x73, 0x79, 0x6e, 0x63, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, + 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x79, 0x6e, 0x63, + 0x4c, 0x61, 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x3c, 0x0a, 0x0c, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x6e, 0x65, 0x78, + 0x74, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x74, 0x22, 0x70, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, + 0x0c, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, + 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, + 0x44, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, + 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x04, 0x22, 0xdb, 0x03, 0x0a, 0x08, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x49, 0x0a, 0x06, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3d, 0x0a, 0x04, 0x73, + 0x70, 0x65, 0x63, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x40, 0x0a, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x67, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x39, 0x0a, 0x0b, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd6, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, + 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x55, + 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, + 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, + 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0x5c, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x09, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, + 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x26, + 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x22, 0x58, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x22, 0x5b, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, - 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x82, 0x02, - 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x44, 0x0a, 0x08, 0x6e, 0x65, 0x77, - 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, + 0x22, 0x5a, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x53, 0x70, 0x65, 0x63, 0x12, - 0x56, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x3e, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, - 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, + 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x5b, 0x0a, 0x16, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x82, 0x02, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x44, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x70, 0x65, + 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, + 0x65, 0x63, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x53, 0x70, 0x65, 0x63, 0x12, 0x56, 0x0a, 0x06, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x67, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, + 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5b, + 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x29, 0x0a, 0x15, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0xfe, 0x01, 0x0a, 0x12, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x2e, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x12, 0x53, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x3b, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, + 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0x58, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x08, + 0x4c, 0x6f, 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x49, 0x0a, 0x06, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, + 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x43, 0x68, + 0x75, 0x6e, 0x6b, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0x5b, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, - 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, - 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, - 0x29, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfe, 0x01, 0x0a, 0x12, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, - 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x16, 0x0a, - 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x53, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, - 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x58, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, - 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, - 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, - 0xa4, 0x01, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, - 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, - 0x12, 0x49, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, - 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, - 0x6f, 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xac, 0x01, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x6f, - 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x4e, 0x0a, 0x06, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x67, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x39, 0x0a, 0x0b, 0x46, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4d, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, + 0x38, 0x01, 0x22, 0xac, 0x01, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x4e, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x05, 0x63, - 0x68, 0x75, 0x6e, 0x6b, 0x22, 0xd4, 0x02, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x51, 0x0a, 0x06, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x67, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, - 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, - 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3d, 0x0a, 0x04, 0x73, 0x70, 0x65, - 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, - 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, - 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, - 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2f, 0x0a, 0x1b, 0x47, - 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x22, 0x6b, 0x0a, 0x1c, - 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x09, - 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x2d, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, - 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x09, - 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x32, 0x91, 0x0a, 0x0a, 0x0f, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x92, 0x01, - 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, - 0x31, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, - 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x39, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0x4d, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, - 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x12, 0x92, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x12, 0x2f, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, - 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, + 0x2e, 0x4c, 0x6f, 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, + 0x22, 0xd4, 0x02, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x51, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3d, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x12, 0x9f, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x67, 0x6f, 0x74, + 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, + 0x73, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x1a, 0x39, 0x0a, 0x0b, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2f, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x22, 0x6b, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x09, 0x72, 0x65, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, + 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x72, 0x65, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x32, 0x91, 0x0a, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x92, 0x01, 0x0a, 0x0d, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x67, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, + 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, + 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, + 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x92, + 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2f, + 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, + 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x30, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, + 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, + 0x72, 0x6e, 0x7d, 0x12, 0x9f, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, - 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, - 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x08, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x9e, 0x01, 0x0a, 0x0e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x67, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x9e, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x33, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, - 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, - 0x32, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x12, 0x9b, 0x01, 0x0a, 0x0e, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x2e, + 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x32, 0x18, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x12, 0x9b, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x67, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x33, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, - 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, 0x18, - 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x12, 0xab, 0x01, 0x0a, 0x0b, 0x41, 0x70, 0x70, - 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x67, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x33, 0x3a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x29, 0x2f, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, - 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x8a, 0x01, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4c, 0x6f, - 0x67, 0x12, 0x2a, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, - 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, 0x18, 0x2f, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, + 0x75, 0x72, 0x6e, 0x7d, 0x12, 0xab, 0x01, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, + 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x3a, + 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x29, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, + 0x7d, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x7d, 0x12, 0x8a, 0x01, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x12, 0x2a, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, - 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x2f, 0x6c, 0x6f, 0x67, - 0x73, 0x30, 0x01, 0x12, 0xb7, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x2e, 0x67, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, - 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, - 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, - 0x72, 0x6e, 0x7d, 0x2f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x77, 0x0a, - 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x74, 0x6f, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2f, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2f, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x67, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, + 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x30, 0x01, 0x12, + 0xb7, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, + 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x2f, + 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x77, 0x0a, 0x26, 0x63, 0x6f, 0x6d, + 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x6e, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x42, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x6e, 0x2f, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x3b, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1745,7 +1799,7 @@ func file_gotocompany_entropy_v1beta1_resource_proto_rawDescGZIP() []byte { } var file_gotocompany_entropy_v1beta1_resource_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_gotocompany_entropy_v1beta1_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 31) +var file_gotocompany_entropy_v1beta1_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 32) var file_gotocompany_entropy_v1beta1_resource_proto_goTypes = []interface{}{ (ResourceState_Status)(0), // 0: gotocompany.entropy.v1beta1.ResourceState.Status (*ResourceDependency)(nil), // 1: gotocompany.entropy.v1beta1.ResourceDependency @@ -1774,65 +1828,68 @@ var file_gotocompany_entropy_v1beta1_resource_proto_goTypes = []interface{}{ (*GetResourceRevisionsResponse)(nil), // 24: gotocompany.entropy.v1beta1.GetResourceRevisionsResponse nil, // 25: gotocompany.entropy.v1beta1.LogOptions.FiltersEntry nil, // 26: gotocompany.entropy.v1beta1.Resource.LabelsEntry - nil, // 27: gotocompany.entropy.v1beta1.UpdateResourceRequest.LabelsEntry - nil, // 28: gotocompany.entropy.v1beta1.ApplyActionRequest.LabelsEntry - nil, // 29: gotocompany.entropy.v1beta1.LogChunk.LabelsEntry - nil, // 30: gotocompany.entropy.v1beta1.GetLogRequest.FilterEntry - nil, // 31: gotocompany.entropy.v1beta1.ResourceRevision.LabelsEntry - (*structpb.Value)(nil), // 32: google.protobuf.Value - (*timestamppb.Timestamp)(nil), // 33: google.protobuf.Timestamp + nil, // 27: gotocompany.entropy.v1beta1.ListResourcesRequest.LabelsEntry + nil, // 28: gotocompany.entropy.v1beta1.UpdateResourceRequest.LabelsEntry + nil, // 29: gotocompany.entropy.v1beta1.ApplyActionRequest.LabelsEntry + nil, // 30: gotocompany.entropy.v1beta1.LogChunk.LabelsEntry + nil, // 31: gotocompany.entropy.v1beta1.GetLogRequest.FilterEntry + nil, // 32: gotocompany.entropy.v1beta1.ResourceRevision.LabelsEntry + (*structpb.Value)(nil), // 33: google.protobuf.Value + (*timestamppb.Timestamp)(nil), // 34: google.protobuf.Timestamp } var file_gotocompany_entropy_v1beta1_resource_proto_depIdxs = []int32{ - 32, // 0: gotocompany.entropy.v1beta1.ResourceSpec.configs:type_name -> google.protobuf.Value + 33, // 0: gotocompany.entropy.v1beta1.ResourceSpec.configs:type_name -> google.protobuf.Value 1, // 1: gotocompany.entropy.v1beta1.ResourceSpec.dependencies:type_name -> gotocompany.entropy.v1beta1.ResourceDependency 25, // 2: gotocompany.entropy.v1beta1.LogOptions.filters:type_name -> gotocompany.entropy.v1beta1.LogOptions.FiltersEntry 0, // 3: gotocompany.entropy.v1beta1.ResourceState.status:type_name -> gotocompany.entropy.v1beta1.ResourceState.Status - 32, // 4: gotocompany.entropy.v1beta1.ResourceState.output:type_name -> google.protobuf.Value + 33, // 4: gotocompany.entropy.v1beta1.ResourceState.output:type_name -> google.protobuf.Value 4, // 5: gotocompany.entropy.v1beta1.ResourceState.log_options:type_name -> gotocompany.entropy.v1beta1.LogOptions - 26, // 6: gotocompany.entropy.v1beta1.Resource.labels:type_name -> gotocompany.entropy.v1beta1.Resource.LabelsEntry - 33, // 7: gotocompany.entropy.v1beta1.Resource.created_at:type_name -> google.protobuf.Timestamp - 33, // 8: gotocompany.entropy.v1beta1.Resource.updated_at:type_name -> google.protobuf.Timestamp - 2, // 9: gotocompany.entropy.v1beta1.Resource.spec:type_name -> gotocompany.entropy.v1beta1.ResourceSpec - 5, // 10: gotocompany.entropy.v1beta1.Resource.state:type_name -> gotocompany.entropy.v1beta1.ResourceState - 6, // 11: gotocompany.entropy.v1beta1.ListResourcesResponse.resources:type_name -> gotocompany.entropy.v1beta1.Resource - 6, // 12: gotocompany.entropy.v1beta1.GetResourceResponse.resource:type_name -> gotocompany.entropy.v1beta1.Resource - 6, // 13: gotocompany.entropy.v1beta1.CreateResourceRequest.resource:type_name -> gotocompany.entropy.v1beta1.Resource - 6, // 14: gotocompany.entropy.v1beta1.CreateResourceResponse.resource:type_name -> gotocompany.entropy.v1beta1.Resource - 2, // 15: gotocompany.entropy.v1beta1.UpdateResourceRequest.new_spec:type_name -> gotocompany.entropy.v1beta1.ResourceSpec - 27, // 16: gotocompany.entropy.v1beta1.UpdateResourceRequest.labels:type_name -> gotocompany.entropy.v1beta1.UpdateResourceRequest.LabelsEntry - 6, // 17: gotocompany.entropy.v1beta1.UpdateResourceResponse.resource:type_name -> gotocompany.entropy.v1beta1.Resource - 32, // 18: gotocompany.entropy.v1beta1.ApplyActionRequest.params:type_name -> google.protobuf.Value - 28, // 19: gotocompany.entropy.v1beta1.ApplyActionRequest.labels:type_name -> gotocompany.entropy.v1beta1.ApplyActionRequest.LabelsEntry - 6, // 20: gotocompany.entropy.v1beta1.ApplyActionResponse.resource:type_name -> gotocompany.entropy.v1beta1.Resource - 29, // 21: gotocompany.entropy.v1beta1.LogChunk.labels:type_name -> gotocompany.entropy.v1beta1.LogChunk.LabelsEntry - 30, // 22: gotocompany.entropy.v1beta1.GetLogRequest.filter:type_name -> gotocompany.entropy.v1beta1.GetLogRequest.FilterEntry - 19, // 23: gotocompany.entropy.v1beta1.GetLogResponse.chunk:type_name -> gotocompany.entropy.v1beta1.LogChunk - 31, // 24: gotocompany.entropy.v1beta1.ResourceRevision.labels:type_name -> gotocompany.entropy.v1beta1.ResourceRevision.LabelsEntry - 33, // 25: gotocompany.entropy.v1beta1.ResourceRevision.created_at:type_name -> google.protobuf.Timestamp - 2, // 26: gotocompany.entropy.v1beta1.ResourceRevision.spec:type_name -> gotocompany.entropy.v1beta1.ResourceSpec - 22, // 27: gotocompany.entropy.v1beta1.GetResourceRevisionsResponse.revisions:type_name -> gotocompany.entropy.v1beta1.ResourceRevision - 3, // 28: gotocompany.entropy.v1beta1.LogOptions.FiltersEntry.value:type_name -> gotocompany.entropy.v1beta1.ListString - 7, // 29: gotocompany.entropy.v1beta1.ResourceService.ListResources:input_type -> gotocompany.entropy.v1beta1.ListResourcesRequest - 9, // 30: gotocompany.entropy.v1beta1.ResourceService.GetResource:input_type -> gotocompany.entropy.v1beta1.GetResourceRequest - 11, // 31: gotocompany.entropy.v1beta1.ResourceService.CreateResource:input_type -> gotocompany.entropy.v1beta1.CreateResourceRequest - 13, // 32: gotocompany.entropy.v1beta1.ResourceService.UpdateResource:input_type -> gotocompany.entropy.v1beta1.UpdateResourceRequest - 15, // 33: gotocompany.entropy.v1beta1.ResourceService.DeleteResource:input_type -> gotocompany.entropy.v1beta1.DeleteResourceRequest - 17, // 34: gotocompany.entropy.v1beta1.ResourceService.ApplyAction:input_type -> gotocompany.entropy.v1beta1.ApplyActionRequest - 20, // 35: gotocompany.entropy.v1beta1.ResourceService.GetLog:input_type -> gotocompany.entropy.v1beta1.GetLogRequest - 23, // 36: gotocompany.entropy.v1beta1.ResourceService.GetResourceRevisions:input_type -> gotocompany.entropy.v1beta1.GetResourceRevisionsRequest - 8, // 37: gotocompany.entropy.v1beta1.ResourceService.ListResources:output_type -> gotocompany.entropy.v1beta1.ListResourcesResponse - 10, // 38: gotocompany.entropy.v1beta1.ResourceService.GetResource:output_type -> gotocompany.entropy.v1beta1.GetResourceResponse - 12, // 39: gotocompany.entropy.v1beta1.ResourceService.CreateResource:output_type -> gotocompany.entropy.v1beta1.CreateResourceResponse - 14, // 40: gotocompany.entropy.v1beta1.ResourceService.UpdateResource:output_type -> gotocompany.entropy.v1beta1.UpdateResourceResponse - 16, // 41: gotocompany.entropy.v1beta1.ResourceService.DeleteResource:output_type -> gotocompany.entropy.v1beta1.DeleteResourceResponse - 18, // 42: gotocompany.entropy.v1beta1.ResourceService.ApplyAction:output_type -> gotocompany.entropy.v1beta1.ApplyActionResponse - 21, // 43: gotocompany.entropy.v1beta1.ResourceService.GetLog:output_type -> gotocompany.entropy.v1beta1.GetLogResponse - 24, // 44: gotocompany.entropy.v1beta1.ResourceService.GetResourceRevisions:output_type -> gotocompany.entropy.v1beta1.GetResourceRevisionsResponse - 37, // [37:45] is the sub-list for method output_type - 29, // [29:37] is the sub-list for method input_type - 29, // [29:29] is the sub-list for extension type_name - 29, // [29:29] is the sub-list for extension extendee - 0, // [0:29] is the sub-list for field type_name + 34, // 6: gotocompany.entropy.v1beta1.ResourceState.next_sync_at:type_name -> google.protobuf.Timestamp + 26, // 7: gotocompany.entropy.v1beta1.Resource.labels:type_name -> gotocompany.entropy.v1beta1.Resource.LabelsEntry + 34, // 8: gotocompany.entropy.v1beta1.Resource.created_at:type_name -> google.protobuf.Timestamp + 34, // 9: gotocompany.entropy.v1beta1.Resource.updated_at:type_name -> google.protobuf.Timestamp + 2, // 10: gotocompany.entropy.v1beta1.Resource.spec:type_name -> gotocompany.entropy.v1beta1.ResourceSpec + 5, // 11: gotocompany.entropy.v1beta1.Resource.state:type_name -> gotocompany.entropy.v1beta1.ResourceState + 27, // 12: gotocompany.entropy.v1beta1.ListResourcesRequest.labels:type_name -> gotocompany.entropy.v1beta1.ListResourcesRequest.LabelsEntry + 6, // 13: gotocompany.entropy.v1beta1.ListResourcesResponse.resources:type_name -> gotocompany.entropy.v1beta1.Resource + 6, // 14: gotocompany.entropy.v1beta1.GetResourceResponse.resource:type_name -> gotocompany.entropy.v1beta1.Resource + 6, // 15: gotocompany.entropy.v1beta1.CreateResourceRequest.resource:type_name -> gotocompany.entropy.v1beta1.Resource + 6, // 16: gotocompany.entropy.v1beta1.CreateResourceResponse.resource:type_name -> gotocompany.entropy.v1beta1.Resource + 2, // 17: gotocompany.entropy.v1beta1.UpdateResourceRequest.new_spec:type_name -> gotocompany.entropy.v1beta1.ResourceSpec + 28, // 18: gotocompany.entropy.v1beta1.UpdateResourceRequest.labels:type_name -> gotocompany.entropy.v1beta1.UpdateResourceRequest.LabelsEntry + 6, // 19: gotocompany.entropy.v1beta1.UpdateResourceResponse.resource:type_name -> gotocompany.entropy.v1beta1.Resource + 33, // 20: gotocompany.entropy.v1beta1.ApplyActionRequest.params:type_name -> google.protobuf.Value + 29, // 21: gotocompany.entropy.v1beta1.ApplyActionRequest.labels:type_name -> gotocompany.entropy.v1beta1.ApplyActionRequest.LabelsEntry + 6, // 22: gotocompany.entropy.v1beta1.ApplyActionResponse.resource:type_name -> gotocompany.entropy.v1beta1.Resource + 30, // 23: gotocompany.entropy.v1beta1.LogChunk.labels:type_name -> gotocompany.entropy.v1beta1.LogChunk.LabelsEntry + 31, // 24: gotocompany.entropy.v1beta1.GetLogRequest.filter:type_name -> gotocompany.entropy.v1beta1.GetLogRequest.FilterEntry + 19, // 25: gotocompany.entropy.v1beta1.GetLogResponse.chunk:type_name -> gotocompany.entropy.v1beta1.LogChunk + 32, // 26: gotocompany.entropy.v1beta1.ResourceRevision.labels:type_name -> gotocompany.entropy.v1beta1.ResourceRevision.LabelsEntry + 34, // 27: gotocompany.entropy.v1beta1.ResourceRevision.created_at:type_name -> google.protobuf.Timestamp + 2, // 28: gotocompany.entropy.v1beta1.ResourceRevision.spec:type_name -> gotocompany.entropy.v1beta1.ResourceSpec + 22, // 29: gotocompany.entropy.v1beta1.GetResourceRevisionsResponse.revisions:type_name -> gotocompany.entropy.v1beta1.ResourceRevision + 3, // 30: gotocompany.entropy.v1beta1.LogOptions.FiltersEntry.value:type_name -> gotocompany.entropy.v1beta1.ListString + 7, // 31: gotocompany.entropy.v1beta1.ResourceService.ListResources:input_type -> gotocompany.entropy.v1beta1.ListResourcesRequest + 9, // 32: gotocompany.entropy.v1beta1.ResourceService.GetResource:input_type -> gotocompany.entropy.v1beta1.GetResourceRequest + 11, // 33: gotocompany.entropy.v1beta1.ResourceService.CreateResource:input_type -> gotocompany.entropy.v1beta1.CreateResourceRequest + 13, // 34: gotocompany.entropy.v1beta1.ResourceService.UpdateResource:input_type -> gotocompany.entropy.v1beta1.UpdateResourceRequest + 15, // 35: gotocompany.entropy.v1beta1.ResourceService.DeleteResource:input_type -> gotocompany.entropy.v1beta1.DeleteResourceRequest + 17, // 36: gotocompany.entropy.v1beta1.ResourceService.ApplyAction:input_type -> gotocompany.entropy.v1beta1.ApplyActionRequest + 20, // 37: gotocompany.entropy.v1beta1.ResourceService.GetLog:input_type -> gotocompany.entropy.v1beta1.GetLogRequest + 23, // 38: gotocompany.entropy.v1beta1.ResourceService.GetResourceRevisions:input_type -> gotocompany.entropy.v1beta1.GetResourceRevisionsRequest + 8, // 39: gotocompany.entropy.v1beta1.ResourceService.ListResources:output_type -> gotocompany.entropy.v1beta1.ListResourcesResponse + 10, // 40: gotocompany.entropy.v1beta1.ResourceService.GetResource:output_type -> gotocompany.entropy.v1beta1.GetResourceResponse + 12, // 41: gotocompany.entropy.v1beta1.ResourceService.CreateResource:output_type -> gotocompany.entropy.v1beta1.CreateResourceResponse + 14, // 42: gotocompany.entropy.v1beta1.ResourceService.UpdateResource:output_type -> gotocompany.entropy.v1beta1.UpdateResourceResponse + 16, // 43: gotocompany.entropy.v1beta1.ResourceService.DeleteResource:output_type -> gotocompany.entropy.v1beta1.DeleteResourceResponse + 18, // 44: gotocompany.entropy.v1beta1.ResourceService.ApplyAction:output_type -> gotocompany.entropy.v1beta1.ApplyActionResponse + 21, // 45: gotocompany.entropy.v1beta1.ResourceService.GetLog:output_type -> gotocompany.entropy.v1beta1.GetLogResponse + 24, // 46: gotocompany.entropy.v1beta1.ResourceService.GetResourceRevisions:output_type -> gotocompany.entropy.v1beta1.GetResourceRevisionsResponse + 39, // [39:47] is the sub-list for method output_type + 31, // [31:39] is the sub-list for method input_type + 31, // [31:31] is the sub-list for extension type_name + 31, // [31:31] is the sub-list for extension extendee + 0, // [0:31] is the sub-list for field type_name } func init() { file_gotocompany_entropy_v1beta1_resource_proto_init() } @@ -2136,7 +2193,7 @@ func file_gotocompany_entropy_v1beta1_resource_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_gotocompany_entropy_v1beta1_resource_proto_rawDesc, NumEnums: 1, - NumMessages: 31, + NumMessages: 32, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gotocompany/entropy/v1beta1/resource.pb.validate.go b/proto/gotocompany/entropy/v1beta1/resource.pb.validate.go index 46600873..3fce543e 100644 --- a/proto/gotocompany/entropy/v1beta1/resource.pb.validate.go +++ b/proto/gotocompany/entropy/v1beta1/resource.pb.validate.go @@ -627,6 +627,39 @@ func (m *ResourceState) validate(all bool) error { } } + // no validation rules for SyncRetries + + // no validation rules for SyncLastError + + if all { + switch v := interface{}(m.GetNextSyncAt()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ResourceStateValidationError{ + field: "NextSyncAt", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ResourceStateValidationError{ + field: "NextSyncAt", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetNextSyncAt()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResourceStateValidationError{ + field: "NextSyncAt", + reason: "embedded message failed validation", + cause: err, + } + } + } + if len(errors) > 0 { return ResourceStateMultiError(errors) } @@ -954,6 +987,8 @@ func (m *ListResourcesRequest) validate(all bool) error { // no validation rules for Kind + // no validation rules for Labels + if len(errors) > 0 { return ListResourcesRequestMultiError(errors) } diff --git a/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go b/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go index aa4696be..4bb55330 100644 --- a/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go +++ b/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go @@ -4,7 +4,6 @@ package entropyv1beta1 import ( context "context" - grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" From 84ec3ccbeb27cd842e218120a7a978b7ede187dd Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Thu, 6 Apr 2023 12:14:50 +0530 Subject: [PATCH 32/72] feat: merge action and existing labels (#31) --- core/write.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/core/write.go b/core/write.go index 0d01c584..9966e621 100644 --- a/core/write.go +++ b/core/write.go @@ -92,11 +92,10 @@ func (svc *Service) planChange(ctx context.Context, res resource.Resource, act m return nil, errors.ErrInternal.WithMsgf("plan() failed").WithCausef(err.Error()) } - planned.Labels = act.Labels + planned.Labels = mergeLabels(res.Labels, act.Labels) if err := planned.Validate(isCreate(act.Name)); err != nil { return nil, err } - return planned, nil } @@ -123,3 +122,24 @@ func (svc *Service) upsert(ctx context.Context, res resource.Resource, isCreate func isCreate(actionName string) bool { return actionName == module.CreateAction } + +func mergeLabels(m1, m2 map[string]string) map[string]string { + if m1 == nil && m2 == nil { + return nil + } + res := map[string]string{} + for k, v := range m1 { + res[k] = v + } + for k, v := range m2 { + res[k] = v + } + + // clean the empty values. + for k, v := range res { + if v == "" { + delete(res, k) + } + } + return res +} From 4538cb7fff8e3d9c114a525f51b1c14750073e85 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Thu, 6 Apr 2023 15:15:34 +0530 Subject: [PATCH 33/72] fix: remove name label to prevent length issues (#32) --- modules/firehose/driver.go | 4 ---- modules/firehose/module.go | 5 ++--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index b74c500b..4f2162db 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -32,8 +32,6 @@ const ( const ( labelsConfKey = "labels" - labelName = "name" - labelProject = "project" labelDeployment = "deployment" labelOrchestrator = "orchestrator" @@ -100,8 +98,6 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config) (*h } entropyLabels := map[string]string{ - labelName: res.Name, - labelProject: res.Project, labelDeployment: conf.DeploymentID, labelOrchestrator: orchestratorLabelValue, } diff --git a/modules/firehose/module.go b/modules/firehose/module.go index 5b0b35b8..5b081449 100644 --- a/modules/firehose/module.go +++ b/modules/firehose/module.go @@ -86,10 +86,9 @@ var Module = module.Descriptor{ } isManagedByEntropy := curLabels[labelOrchestrator] == orchestratorLabelValue - isSameProject := curLabels[labelProject] == newLabels[labelProject] - isSameName := curLabels[labelName] == newLabels[labelName] + isSameDeployment := curLabels[labelDeployment] == newLabels[labelDeployment] - return isManagedByEntropy && isSameProject && isSameName + return isManagedByEntropy && isSameDeployment } helmCl := helm.NewClient(&helm.Config{Kubernetes: kubeConf}) From 71766cb7c6f8505f0c3482d1ce90f272a80af872 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Tue, 11 Apr 2023 22:40:38 +0530 Subject: [PATCH 34/72] feat: add jdbc sink type (#33) Update config.json --- modules/firehose/schema/config.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/firehose/schema/config.json b/modules/firehose/schema/config.json index d994c90a..5fb6e9df 100644 --- a/modules/firehose/schema/config.json +++ b/modules/firehose/schema/config.json @@ -51,7 +51,8 @@ "PROMETHEUS", "BIGQUERY", "BLOB", - "BIGTABLE" + "BIGTABLE", + "JDBC" ] }, "KAFKA_RECORD_PARSER_MODE": { @@ -64,4 +65,4 @@ } } } -} \ No newline at end of file +} From 4e03452f07f61ad82c7fe5f2059b5abd32cce589 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Wed, 12 Apr 2023 14:05:59 +0530 Subject: [PATCH 35/72] feat: allow custom usage for each firehose (#34) --- modules/firehose/config.go | 7 +++- modules/firehose/driver.go | 39 ++++++++++++++++++++++ modules/firehose/driver_log.go | 4 +-- modules/firehose/driver_output.go | 2 +- modules/firehose/driver_plan.go | 6 ++-- modules/firehose/driver_plan_test.go | 48 ++++++++++++++++++++++++++++ modules/firehose/driver_sync.go | 2 +- 7 files changed, 100 insertions(+), 8 deletions(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index 719890e6..04937d12 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -36,6 +36,8 @@ type Config struct { DeploymentID string `json:"deployment_id,omitempty"` ChartValues *ChartValues `json:"chart_values,omitempty"` EnvVariables map[string]string `json:"env_variables,omitempty"` + Limits UsageSpec `json:"limits,omitempty"` + Requests UsageSpec `json:"requests,omitempty"` } type Telegraf struct { @@ -55,7 +57,7 @@ type ChartValues struct { ImagePullPolicy string `json:"image_pull_policy" validate:"required"` } -func readConfig(r resource.Resource, confJSON json.RawMessage) (*Config, error) { +func readConfig(r resource.Resource, confJSON json.RawMessage, dc driverConf) (*Config, error) { var cfg Config if err := json.Unmarshal(confJSON, &cfg); err != nil { return nil, errors.ErrInvalid.WithMsgf("invalid config json").WithCausef(err.Error()) @@ -80,6 +82,9 @@ func readConfig(r resource.Resource, confJSON json.RawMessage) (*Config, error) cfg.EnvVariables[confKeyConsumerID] = fmt.Sprintf("%s-0001", cfg.DeploymentID) } + cfg.Limits = dc.Limits.merge(cfg.Limits) + cfg.Requests = dc.Requests.merge(cfg.Requests) + return &cfg, nil } diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 4f2162db..71682f03 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -45,6 +45,14 @@ var defaultDriverConf = driverConf{ ChartVersion: "0.1.3", ImagePullPolicy: "IfNotPresent", }, + Limits: UsageSpec{ + CPU: "200m", + Memory: "512Mi", + }, + Requests: UsageSpec{ + CPU: "200m", + Memory: "512Mi", + }, } type firehoseDriver struct { @@ -66,6 +74,13 @@ type driverConf struct { Telegraf *Telegraf `json:"telegraf"` Namespace string `json:"namespace" validate:"required"` ChartValues ChartValues `json:"chart_values" validate:"required"` + Limits UsageSpec `json:"limits,omitempty" validate:"required"` + Requests UsageSpec `json:"requests,omitempty" validate:"required"` +} + +type UsageSpec struct { + CPU string `json:"cpu,omitempty" validate:"required"` + Memory string `json:"memory,omitempty" validate:"required"` } type Output struct { @@ -124,6 +139,16 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config) (*h "tag": conf.ChartValues.ImageTag, }, "config": conf.EnvVariables, + "resources": map[string]any{ + "limits": map[string]any{ + "cpu": conf.Limits.CPU, + "memory": conf.Limits.Memory, + }, + "requests": map[string]any{ + "cpu": conf.Requests.CPU, + "memory": conf.Requests.Memory, + }, + }, }, "telegraf": map[string]any{ "enabled": telegrafConf.Enabled, @@ -224,3 +249,17 @@ func cloneAndMergeMaps(m1, m2 map[string]string) map[string]string { } return res } + +func (us UsageSpec) merge(overide UsageSpec) UsageSpec { + clone := us + + if overide.CPU != "" { + clone.CPU = overide.CPU + } + + if overide.Memory != "" { + clone.Memory = overide.Memory + } + + return clone +} diff --git a/modules/firehose/driver_log.go b/modules/firehose/driver_log.go index 2222219b..8f9f8be6 100644 --- a/modules/firehose/driver_log.go +++ b/modules/firehose/driver_log.go @@ -10,8 +10,8 @@ import ( "github.com/goto/entropy/pkg/kube" ) -func (*firehoseDriver) Log(ctx context.Context, res module.ExpandedResource, filter map[string]string) (<-chan module.LogChunk, error) { - conf, err := readConfig(res.Resource, res.Spec.Configs) +func (fd *firehoseDriver) Log(ctx context.Context, res module.ExpandedResource, filter map[string]string) (<-chan module.LogChunk, error) { + conf, err := readConfig(res.Resource, res.Spec.Configs, fd.conf) if err != nil { return nil, errors.ErrInternal.WithCausef(err.Error()) } diff --git a/modules/firehose/driver_output.go b/modules/firehose/driver_output.go index 32d9d913..74f8fd37 100644 --- a/modules/firehose/driver_output.go +++ b/modules/firehose/driver_output.go @@ -16,7 +16,7 @@ func (fd *firehoseDriver) Output(ctx context.Context, exr module.ExpandedResourc return nil, err } - conf, err := readConfig(exr.Resource, exr.Spec.Configs) + conf, err := readConfig(exr.Resource, exr.Spec.Configs, fd.conf) if err != nil { return nil, errors.ErrInternal.WithCausef(err.Error()) } diff --git a/modules/firehose/driver_plan.go b/modules/firehose/driver_plan.go index 926f0ceb..6b590abb 100644 --- a/modules/firehose/driver_plan.go +++ b/modules/firehose/driver_plan.go @@ -24,14 +24,14 @@ func (fd *firehoseDriver) Plan(_ context.Context, exr module.ExpandedResource, a } func (fd *firehoseDriver) planChange(exr module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) { - curConf, err := readConfig(exr.Resource, exr.Resource.Spec.Configs) + curConf, err := readConfig(exr.Resource, exr.Resource.Spec.Configs, fd.conf) if err != nil { return nil, err } switch act.Name { case module.UpdateAction: - newConf, err := readConfig(exr.Resource, act.Params) + newConf, err := readConfig(exr.Resource, act.Params, fd.conf) if err != nil { return nil, err } @@ -89,7 +89,7 @@ func (fd *firehoseDriver) planChange(exr module.ExpandedResource, act module.Act } func (fd *firehoseDriver) planCreate(exr module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) { - conf, err := readConfig(exr.Resource, act.Params) + conf, err := readConfig(exr.Resource, act.Params, fd.conf) if err != nil { return nil, err } diff --git a/modules/firehose/driver_plan_test.go b/modules/firehose/driver_plan_test.go index 72db20dc..7233dde7 100644 --- a/modules/firehose/driver_plan_test.go +++ b/modules/firehose/driver_plan_test.go @@ -82,6 +82,14 @@ func TestFirehoseDriver_Plan(t *testing.T) { "image_pull_policy": "IfNotPresent", "image_tag": "latest", }, + "limits": map[string]any{ + "cpu": "200m", + "memory": "512Mi", + }, + "requests": map[string]any{ + "cpu": "200m", + "memory": "512Mi", + }, "env_variables": map[string]string{ "SINK_TYPE": "LOG", "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", @@ -144,6 +152,14 @@ func TestFirehoseDriver_Plan(t *testing.T) { "image_pull_policy": "IfNotPresent", "image_tag": "latest", }, + "limits": map[string]any{ + "cpu": "200m", + "memory": "512Mi", + }, + "requests": map[string]any{ + "cpu": "200m", + "memory": "512Mi", + }, "env_variables": map[string]string{ "SINK_TYPE": "LOG", "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", @@ -228,6 +244,14 @@ func TestFirehoseDriver_Plan(t *testing.T) { "SOURCE_KAFKA_BROKERS": "localhost:9092", "SOURCE_KAFKA_TOPIC": "foo-log", }, + "limits": map[string]any{ + "cpu": "200m", + "memory": "512Mi", + }, + "requests": map[string]any{ + "cpu": "200m", + "memory": "512Mi", + }, }), }, State: resource.State{ @@ -303,6 +327,14 @@ func TestFirehoseDriver_Plan(t *testing.T) { "SOURCE_KAFKA_BROKERS": "localhost:9092", "SOURCE_KAFKA_TOPIC": "foo-log", }, + "limits": map[string]any{ + "cpu": "200m", + "memory": "512Mi", + }, + "requests": map[string]any{ + "cpu": "200m", + "memory": "512Mi", + }, }), }, State: resource.State{ @@ -336,6 +368,14 @@ func TestFirehoseDriver_Plan(t *testing.T) { "SOURCE_KAFKA_BROKERS": "localhost:9092", "SOURCE_KAFKA_TOPIC": "foo-log", }, + "limits": map[string]any{ + "cpu": "200m", + "memory": "512Mi", + }, + "requests": map[string]any{ + "cpu": "200m", + "memory": "512Mi", + }, }), }, State: resource.State{ @@ -412,6 +452,14 @@ func TestFirehoseDriver_Plan(t *testing.T) { "image_pull_policy": "IfNotPresent", "image_tag": "latest", }, + "limits": map[string]any{ + "cpu": "200m", + "memory": "512Mi", + }, + "requests": map[string]any{ + "cpu": "200m", + "memory": "512Mi", + }, "env_variables": map[string]string{ "SINK_TYPE": "LOG", "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", diff --git a/modules/firehose/driver_sync.go b/modules/firehose/driver_sync.go index 78f46dde..2aa1353c 100644 --- a/modules/firehose/driver_sync.go +++ b/modules/firehose/driver_sync.go @@ -21,7 +21,7 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) return nil, errors.ErrInternal.WithCausef(err.Error()) } - conf, err := readConfig(exr.Resource, exr.Spec.Configs) + conf, err := readConfig(exr.Resource, exr.Spec.Configs, fd.conf) if err != nil { return nil, errors.ErrInternal.WithCausef(err.Error()) } From b01368867934550bf146868aaac0470862e5fc9b Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Tue, 18 Apr 2023 12:59:20 +0530 Subject: [PATCH 36/72] feat: add tolerations feature (#35) * feat: add tolerations feature * Update modules/firehose/driver.go Co-authored-by: StewartJingga * fix: fix sink types for firehose module --------- Co-authored-by: StewartJingga --- modules/firehose/driver.go | 114 ++++++++++++++++++++++++++-- modules/firehose/driver_output.go | 2 +- modules/firehose/driver_sync.go | 2 +- modules/firehose/schema/config.json | 14 ++-- modules/kubernetes/output.go | 12 ++- 5 files changed, 126 insertions(+), 18 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 71682f03..4f4d8f4a 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "fmt" "strings" "text/template" "time" @@ -70,12 +71,36 @@ type ( ) type driverConf struct { - Labels map[string]string `json:"labels,omitempty"` - Telegraf *Telegraf `json:"telegraf"` - Namespace string `json:"namespace" validate:"required"` - ChartValues ChartValues `json:"chart_values" validate:"required"` - Limits UsageSpec `json:"limits,omitempty" validate:"required"` - Requests UsageSpec `json:"requests,omitempty" validate:"required"` + Labels map[string]string `json:"labels,omitempty"` + Telegraf *Telegraf `json:"telegraf"` + Namespace string `json:"namespace" validate:"required"` + ChartValues ChartValues `json:"chart_values" validate:"required"` + Limits UsageSpec `json:"limits,omitempty" validate:"required"` + Requests UsageSpec `json:"requests,omitempty" validate:"required"` + Tolerations map[string]Toleration `json:"tolerations"` + InitContainer InitContainer `json:"init_container"` + + GCSSinkCredential string `json:"gcs_sink_credential,omitempty"` + DLQGCSSinkCredential string `json:"dlq_gcs_sink_credential,omitempty"` + BigQuerySinkCredential string `json:"big_query_sink_credential,omitempty"` +} + +type InitContainer struct { + Enabled bool `json:"enabled"` + + Args []string `json:"args"` + Command []string `json:"command"` + + Repository string `json:"repository"` + ImageTag string `json:"image_tag"` + PullPolicy string `json:"pull_policy"` +} + +type Toleration struct { + Key string `json:"key"` + Value string `json:"value"` + Effect string `json:"effect"` + Operator string `json:"operator"` } type UsageSpec struct { @@ -94,7 +119,9 @@ type transientData struct { ResetOffsetTo string `json:"reset_offset_to,omitempty"` } -func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config) (*helm.ReleaseConfig, error) { +func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, + kubeOut kubernetes.Output, +) (*helm.ReleaseConfig, error) { var telegrafConf Telegraf if conf.Telegraf != nil && conf.Telegraf.Enabled { telegrafTags, err := renderLabels(conf.Telegraf.Config.AdditionalGlobalTags, res.Labels) @@ -112,6 +139,17 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config) (*h } } + tolerationKey := fmt.Sprintf("firehose_%s", conf.EnvVariables["SINK_TYPE"]) + var tolerations []map[string]any + for _, t := range kubeOut.Tolerations[tolerationKey] { + tolerations = append(tolerations, map[string]any{ + "key": t.Key, + "value": t.Value, + "effect": t.Effect, + "operator": t.Operator, + }) + } + entropyLabels := map[string]string{ labelDeployment: conf.DeploymentID, labelOrchestrator: orchestratorLabelValue, @@ -122,6 +160,55 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config) (*h return nil, err } + var volumes []map[string]any + var volumeMounts []map[string]any + + newVolume := func(name string) map[string]any { + const mountMode = 420 + return map[string]any{ + "name": name, + "items": []map[string]any{{"key": "token", "path": "auth.json"}}, + "secretName": name, + "defaultMode": mountMode, + } + } + + if fd.conf.GCSSinkCredential != "" { + const mountPath = "/etc/secret/blob-gcs-sink" + const credentialPath = mountPath + "/auth.json" + + volumes = append(volumes, newVolume(fd.conf.GCSSinkCredential)) + volumeMounts = append(volumeMounts, map[string]any{ + "name": fd.conf.GCSSinkCredential, + "mountPath": mountPath, + }) + conf.EnvVariables["SINK_BLOB_GCS_CREDENTIAL_PATH"] = credentialPath + } + + if fd.conf.DLQGCSSinkCredential != "" { + const mountPath = "/etc/secret/dlq-gcs" + const credentialPath = mountPath + "/auth.json" + + volumes = append(volumes, newVolume(fd.conf.DLQGCSSinkCredential)) + volumeMounts = append(volumeMounts, map[string]any{ + "name": fd.conf.DLQGCSSinkCredential, + "mountPath": mountPath, + }) + conf.EnvVariables["DLQ_GCS_CREDENTIAL_PATH"] = credentialPath + } + + if fd.conf.BigQuerySinkCredential != "" { + const mountPath = "/etc/secret/bigquery-sink" + const credentialPath = mountPath + "/auth.json" + + volumes = append(volumes, newVolume(fd.conf.BigQuerySinkCredential)) + volumeMounts = append(volumeMounts, map[string]any{ + "name": fd.conf.BigQuerySinkCredential, + "mountPath": mountPath, + }) + conf.EnvVariables["SINK_BIGQUERY_CREDENTIAL_PATH"] = credentialPath + } + rc := helm.DefaultReleaseConfig() rc.Name = conf.DeploymentID rc.Repository = chartRepo @@ -149,6 +236,19 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config) (*h "memory": conf.Requests.Memory, }, }, + "tolerations": tolerations, + "volumeMounts": volumeMounts, + "volumes": volumes, + }, + "init-firehose": map[string]any{ + "enabled": fd.conf.InitContainer.Enabled, + "image": map[string]any{ + "repository": fd.conf.InitContainer.Repository, + "pullPolicy": fd.conf.InitContainer.PullPolicy, + "tag": fd.conf.InitContainer.ImageTag, + }, + "command": fd.conf.InitContainer.Command, + "args": fd.conf.InitContainer.Args, }, "telegraf": map[string]any{ "enabled": telegrafConf.Enabled, diff --git a/modules/firehose/driver_output.go b/modules/firehose/driver_output.go index 74f8fd37..d20fa4a8 100644 --- a/modules/firehose/driver_output.go +++ b/modules/firehose/driver_output.go @@ -32,7 +32,7 @@ func (fd *firehoseDriver) Output(ctx context.Context, exr module.ExpandedResourc func (fd *firehoseDriver) refreshOutput(ctx context.Context, r resource.Resource, conf Config, output Output, kubeOut kubernetes.Output, ) (json.RawMessage, error) { - rc, err := fd.getHelmRelease(r, conf) + rc, err := fd.getHelmRelease(r, conf, kubeOut) if err != nil { return nil, err } diff --git a/modules/firehose/driver_sync.go b/modules/firehose/driver_sync.go index 2aa1353c..035e94be 100644 --- a/modules/firehose/driver_sync.go +++ b/modules/firehose/driver_sync.go @@ -98,7 +98,7 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) func (fd *firehoseDriver) releaseSync(ctx context.Context, r resource.Resource, isCreate bool, conf Config, kubeOut kubernetes.Output, ) error { - rc, err := fd.getHelmRelease(r, conf) + rc, err := fd.getHelmRelease(r, conf, kubeOut) if err != nil { return err } diff --git a/modules/firehose/schema/config.json b/modules/firehose/schema/config.json index 5fb6e9df..a63f3235 100644 --- a/modules/firehose/schema/config.json +++ b/modules/firehose/schema/config.json @@ -41,18 +41,18 @@ "SINK_TYPE": { "type": "string", "enum": [ - "LOG", + "JDBC", "HTTP", - "POSTGRES", "INFLUXDB", - "ELASTIC", - "REDIS", + "ELASTICSEARCH", "GRPC", "PROMETHEUS", - "BIGQUERY", "BLOB", - "BIGTABLE", - "JDBC" + "MONGODB", + "LOG", + "REDIS", + "BIGQUERY", + "BIGTABLE" ] }, "KAFKA_RECORD_PARSER_MODE": { diff --git a/modules/kubernetes/output.go b/modules/kubernetes/output.go index 99c42b6b..d245e44b 100644 --- a/modules/kubernetes/output.go +++ b/modules/kubernetes/output.go @@ -9,8 +9,16 @@ import ( ) type Output struct { - Configs kube.Config `json:"configs"` - ServerInfo version.Info `json:"server_info"` + Configs kube.Config `json:"configs"` + ServerInfo version.Info `json:"server_info"` + Tolerations map[string][]Toleration `json:"tolerations"` +} + +type Toleration struct { + Key string `json:"key"` + Value string `json:"value"` + Effect string `json:"effect"` + Operator string `json:"operator"` } func (out Output) JSON() []byte { From a5f3898259cfbe9f3bc4f76112234ff90e438bc6 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Fri, 21 Apr 2023 10:48:59 +0530 Subject: [PATCH 37/72] fix: move volume values outside firehose key (#36) * fix: move volume values outside firehose key * feat: add nodeAffinitiyMatchExpressions * chore: typo * chore: typo * refactor: remove if check --------- Co-authored-by: Ishan Arya --- modules/firehose/driver.go | 46 +++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 4f4d8f4a..f90009d9 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -71,20 +71,37 @@ type ( ) type driverConf struct { - Labels map[string]string `json:"labels,omitempty"` - Telegraf *Telegraf `json:"telegraf"` - Namespace string `json:"namespace" validate:"required"` - ChartValues ChartValues `json:"chart_values" validate:"required"` - Limits UsageSpec `json:"limits,omitempty" validate:"required"` - Requests UsageSpec `json:"requests,omitempty" validate:"required"` - Tolerations map[string]Toleration `json:"tolerations"` - InitContainer InitContainer `json:"init_container"` + Labels map[string]string `json:"labels,omitempty"` + Telegraf *Telegraf `json:"telegraf"` + Namespace string `json:"namespace" validate:"required"` + ChartValues ChartValues `json:"chart_values" validate:"required"` + Limits UsageSpec `json:"limits,omitempty" validate:"required"` + Requests UsageSpec `json:"requests,omitempty" validate:"required"` + Tolerations map[string]Toleration `json:"tolerations"` + InitContainer InitContainer `json:"init_container"` + NodeAffinityMatchExpressions NodeAffinityMatchExpressions `json:"node_affinity_match_expressions"` GCSSinkCredential string `json:"gcs_sink_credential,omitempty"` DLQGCSSinkCredential string `json:"dlq_gcs_sink_credential,omitempty"` BigQuerySinkCredential string `json:"big_query_sink_credential,omitempty"` } +type NodeAffinityMatchExpressions struct { + RequiredDuringSchedulingIgnoredDuringExecution []Preference `json:"requiredDuringSchedulingIgnoredDuringExecution,omitempty"` + PreferredDuringSchedulingIgnoredDuringExecution []WeightedPreference `json:"preferredDuringSchedulingIgnoredDuringExecution,omitempty"` +} + +type WeightedPreference struct { + Weight int `json:"weight" validate:"required"` + Preference []Preference `json:"preference" validate:"required"` +} + +type Preference struct { + Key string `json:"key" validate:"required"` + Operator string `json:"operator" validate:"required"` + Values []string `json:"values"` +} + type InitContainer struct { Enabled bool `json:"enabled"` @@ -162,6 +179,11 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, var volumes []map[string]any var volumeMounts []map[string]any + var requiredDuringSchedulingIgnoredDuringExecution []Preference + var preferredDuringSchedulingIgnoredDuringExecution []WeightedPreference + + requiredDuringSchedulingIgnoredDuringExecution = fd.conf.NodeAffinityMatchExpressions.RequiredDuringSchedulingIgnoredDuringExecution + preferredDuringSchedulingIgnoredDuringExecution = fd.conf.NodeAffinityMatchExpressions.PreferredDuringSchedulingIgnoredDuringExecution newVolume := func(name string) map[string]any { const mountMode = 420 @@ -236,9 +258,13 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, "memory": conf.Requests.Memory, }, }, - "tolerations": tolerations, "volumeMounts": volumeMounts, - "volumes": volumes, + }, + "volumes": volumes, + "tolerations": tolerations, + "nodeAffinityMatchExpressions": map[string]any{ + "requiredDuringSchedulingIgnoredDuringExecution": requiredDuringSchedulingIgnoredDuringExecution, + "preferredDuringSchedulingIgnoredDuringExecution": preferredDuringSchedulingIgnoredDuringExecution, }, "init-firehose": map[string]any{ "enabled": fd.conf.InitContainer.Enabled, From d3193e79e41b016c83dc36257a92097baeadfc86 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Fri, 21 Apr 2023 15:04:24 +0530 Subject: [PATCH 38/72] fix: add secret key (#37) * fix: add secret key * fix: unecessary nesting --- modules/firehose/driver.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index f90009d9..421f8193 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -177,7 +177,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, return nil, err } - var volumes []map[string]any + var secretsAsVolumes []map[string]any var volumeMounts []map[string]any var requiredDuringSchedulingIgnoredDuringExecution []Preference var preferredDuringSchedulingIgnoredDuringExecution []WeightedPreference @@ -199,7 +199,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, const mountPath = "/etc/secret/blob-gcs-sink" const credentialPath = mountPath + "/auth.json" - volumes = append(volumes, newVolume(fd.conf.GCSSinkCredential)) + secretsAsVolumes = append(secretsAsVolumes, newVolume(fd.conf.GCSSinkCredential)) volumeMounts = append(volumeMounts, map[string]any{ "name": fd.conf.GCSSinkCredential, "mountPath": mountPath, @@ -211,7 +211,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, const mountPath = "/etc/secret/dlq-gcs" const credentialPath = mountPath + "/auth.json" - volumes = append(volumes, newVolume(fd.conf.DLQGCSSinkCredential)) + secretsAsVolumes = append(secretsAsVolumes, newVolume(fd.conf.DLQGCSSinkCredential)) volumeMounts = append(volumeMounts, map[string]any{ "name": fd.conf.DLQGCSSinkCredential, "mountPath": mountPath, @@ -223,7 +223,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, const mountPath = "/etc/secret/bigquery-sink" const credentialPath = mountPath + "/auth.json" - volumes = append(volumes, newVolume(fd.conf.BigQuerySinkCredential)) + secretsAsVolumes = append(secretsAsVolumes, newVolume(fd.conf.BigQuerySinkCredential)) volumeMounts = append(volumeMounts, map[string]any{ "name": fd.conf.BigQuerySinkCredential, "mountPath": mountPath, @@ -260,8 +260,8 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, }, "volumeMounts": volumeMounts, }, - "volumes": volumes, - "tolerations": tolerations, + "secretsAsVolumes": secretsAsVolumes, + "tolerations": tolerations, "nodeAffinityMatchExpressions": map[string]any{ "requiredDuringSchedulingIgnoredDuringExecution": requiredDuringSchedulingIgnoredDuringExecution, "preferredDuringSchedulingIgnoredDuringExecution": preferredDuringSchedulingIgnoredDuringExecution, From 0919cc5d284c60c90623e0544798ad563d4f5637 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Thu, 27 Apr 2023 11:58:25 +0530 Subject: [PATCH 39/72] feat: add toleration to kube module config (#38) * feat: add toleration to kube module config * refactor: do config parsing in descriptor * refactor: marshal config to struct * chore: lint issue --- modules/firehose/driver.go | 25 +++++++++---------------- modules/kubernetes/driver.go | 11 +++++++---- modules/kubernetes/module.go | 8 +++++++- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 421f8193..ee2315c4 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -71,15 +71,15 @@ type ( ) type driverConf struct { - Labels map[string]string `json:"labels,omitempty"` - Telegraf *Telegraf `json:"telegraf"` - Namespace string `json:"namespace" validate:"required"` - ChartValues ChartValues `json:"chart_values" validate:"required"` - Limits UsageSpec `json:"limits,omitempty" validate:"required"` - Requests UsageSpec `json:"requests,omitempty" validate:"required"` - Tolerations map[string]Toleration `json:"tolerations"` - InitContainer InitContainer `json:"init_container"` - NodeAffinityMatchExpressions NodeAffinityMatchExpressions `json:"node_affinity_match_expressions"` + Labels map[string]string `json:"labels,omitempty"` + Telegraf *Telegraf `json:"telegraf"` + Namespace string `json:"namespace" validate:"required"` + ChartValues ChartValues `json:"chart_values" validate:"required"` + Limits UsageSpec `json:"limits,omitempty" validate:"required"` + Requests UsageSpec `json:"requests,omitempty" validate:"required"` + Tolerations map[string]kubernetes.Toleration `json:"tolerations"` + InitContainer InitContainer `json:"init_container"` + NodeAffinityMatchExpressions NodeAffinityMatchExpressions `json:"node_affinity_match_expressions"` GCSSinkCredential string `json:"gcs_sink_credential,omitempty"` DLQGCSSinkCredential string `json:"dlq_gcs_sink_credential,omitempty"` @@ -113,13 +113,6 @@ type InitContainer struct { PullPolicy string `json:"pull_policy"` } -type Toleration struct { - Key string `json:"key"` - Value string `json:"value"` - Effect string `json:"effect"` - Operator string `json:"operator"` -} - type UsageSpec struct { CPU string `json:"cpu,omitempty" validate:"required"` Memory string `json:"memory,omitempty" validate:"required"` diff --git a/modules/kubernetes/driver.go b/modules/kubernetes/driver.go index 0e5717ce..7c5888b9 100644 --- a/modules/kubernetes/driver.go +++ b/modules/kubernetes/driver.go @@ -12,7 +12,9 @@ import ( "github.com/goto/entropy/pkg/kube" ) -type kubeDriver struct{} +type kubeDriver struct { + Tolerations map[string][]Toleration `json:"tolerations"` +} func (m *kubeDriver) Plan(ctx context.Context, res module.ExpandedResource, act module.ActionRequest, @@ -43,7 +45,7 @@ func (*kubeDriver) Sync(_ context.Context, res module.ExpandedResource) (*resour }, nil } -func (*kubeDriver) Output(_ context.Context, res module.ExpandedResource) (json.RawMessage, error) { +func (m *kubeDriver) Output(_ context.Context, res module.ExpandedResource) (json.RawMessage, error) { conf := kube.DefaultClientConfig() if err := json.Unmarshal(res.Spec.Configs, &conf); err != nil { return nil, errors.ErrInvalid.WithMsgf("invalid json config value").WithCausef(err.Error()) @@ -62,7 +64,8 @@ func (*kubeDriver) Output(_ context.Context, res module.ExpandedResource) (json. } return Output{ - Configs: conf, - ServerInfo: *info, + Configs: conf, + ServerInfo: *info, + Tolerations: m.Tolerations, }.JSON(), nil } diff --git a/modules/kubernetes/module.go b/modules/kubernetes/module.go index a3dfd741..ea28762e 100644 --- a/modules/kubernetes/module.go +++ b/modules/kubernetes/module.go @@ -5,6 +5,7 @@ import ( "encoding/json" "github.com/goto/entropy/core/module" + "github.com/goto/entropy/pkg/errors" ) var Module = module.Descriptor{ @@ -18,6 +19,11 @@ var Module = module.Descriptor{ }, }, DriverFactory: func(conf json.RawMessage) (module.Driver, error) { - return &kubeDriver{}, nil + kd := &kubeDriver{} + err := json.Unmarshal(conf, &kd) + if err != nil { + return nil, errors.ErrInvalid.WithMsgf("failed to unmarshal module config: %v", err) + } + return kd, nil }, } From 74d17e4faf1771f7af8f226ab73b708aa3467f46 Mon Sep 17 00:00:00 2001 From: Shivaprasad Bhat Date: Tue, 9 May 2023 10:25:36 +0530 Subject: [PATCH 40/72] feat: add support for sink specific requests & limits (#39) --- modules/firehose/config.go | 43 ++++++++++++++++------ modules/firehose/driver.go | 73 ++++++++++++++++++++++++++++---------- 2 files changed, 86 insertions(+), 30 deletions(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index 04937d12..d5e6cedb 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -14,6 +14,7 @@ import ( ) const ( + confSinkType = "SINK_TYPE" confKeyConsumerID = "SOURCE_KAFKA_CONSUMER_GROUP_ID" confKeyKafkaBrokers = "SOURCE_KAFKA_BROKERS" ) @@ -28,16 +29,31 @@ var ( ) type Config struct { - Stopped bool `json:"stopped"` - StopTime *time.Time `json:"stop_time,omitempty"` - Telegraf *Telegraf `json:"telegraf,omitempty"` - Replicas int `json:"replicas"` - Namespace string `json:"namespace,omitempty"` - DeploymentID string `json:"deployment_id,omitempty"` - ChartValues *ChartValues `json:"chart_values,omitempty"` + // Stopped flag when set forces the firehose to be stopped on next sync. + Stopped bool `json:"stopped"` + + // StopTime can be set to schedule the firehose to be stopped at given time. + StopTime *time.Time `json:"stop_time,omitempty"` + + // Replicas is the number of firehose instances to run. + Replicas int `json:"replicas"` + + // Namespace is the target namespace where firehose should be deployed. + // Inherits from driver config. + Namespace string `json:"namespace,omitempty"` + + // DeploymentID will be used as the release-name for the deployment. + // Must be shorter than 53 chars if set. If not set, one will be generated + // automatically. + DeploymentID string `json:"deployment_id,omitempty"` + + // EnvVariables contains all the firehose environment config values. EnvVariables map[string]string `json:"env_variables,omitempty"` - Limits UsageSpec `json:"limits,omitempty"` - Requests UsageSpec `json:"requests,omitempty"` + + Limits UsageSpec `json:"limits,omitempty"` + Requests UsageSpec `json:"requests,omitempty"` + Telegraf *Telegraf `json:"telegraf,omitempty"` + ChartValues *ChartValues `json:"chart_values,omitempty"` } type Telegraf struct { @@ -82,8 +98,13 @@ func readConfig(r resource.Resource, confJSON json.RawMessage, dc driverConf) (* cfg.EnvVariables[confKeyConsumerID] = fmt.Sprintf("%s-0001", cfg.DeploymentID) } - cfg.Limits = dc.Limits.merge(cfg.Limits) - cfg.Requests = dc.Requests.merge(cfg.Requests) + rl := dc.RequestsAndLimits[defaultKey] + if overrides, ok := dc.RequestsAndLimits[cfg.EnvVariables[confSinkType]]; ok { + rl.Limits = rl.Limits.merge(overrides.Limits) + rl.Requests = rl.Requests.merge(overrides.Requests) + } + cfg.Limits = rl.Limits + cfg.Requests = rl.Requests return &cfg, nil } diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index ee2315c4..d819aa07 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -39,6 +39,8 @@ const ( orchestratorLabelValue = "entropy" ) +const defaultKey = "default" + var defaultDriverConf = driverConf{ Namespace: "firehose", ChartValues: ChartValues{ @@ -46,13 +48,17 @@ var defaultDriverConf = driverConf{ ChartVersion: "0.1.3", ImagePullPolicy: "IfNotPresent", }, - Limits: UsageSpec{ - CPU: "200m", - Memory: "512Mi", - }, - Requests: UsageSpec{ - CPU: "200m", - Memory: "512Mi", + RequestsAndLimits: map[string]RequestsAndLimits{ + defaultKey: { + Limits: UsageSpec{ + CPU: "200m", + Memory: "512Mi", + }, + Requests: UsageSpec{ + CPU: "200m", + Memory: "512Mi", + }, + }, }, } @@ -71,19 +77,48 @@ type ( ) type driverConf struct { - Labels map[string]string `json:"labels,omitempty"` - Telegraf *Telegraf `json:"telegraf"` - Namespace string `json:"namespace" validate:"required"` - ChartValues ChartValues `json:"chart_values" validate:"required"` - Limits UsageSpec `json:"limits,omitempty" validate:"required"` - Requests UsageSpec `json:"requests,omitempty" validate:"required"` - Tolerations map[string]kubernetes.Toleration `json:"tolerations"` - InitContainer InitContainer `json:"init_container"` - NodeAffinityMatchExpressions NodeAffinityMatchExpressions `json:"node_affinity_match_expressions"` - - GCSSinkCredential string `json:"gcs_sink_credential,omitempty"` - DLQGCSSinkCredential string `json:"dlq_gcs_sink_credential,omitempty"` + // Labels to be injected to the chart during deployment. Values can be Go templates. + Labels map[string]string `json:"labels,omitempty"` + + // Telegraf is the telegraf configuration for the deployment. + Telegraf *Telegraf `json:"telegraf"` + + // Namespace is the kubernetes namespace where firehoses will be deployed. + Namespace string `json:"namespace" validate:"required"` + + // ChartValues is the chart and image version information. + ChartValues ChartValues `json:"chart_values" validate:"required"` + + // Tolerations represents the tolerations to be set for the deployment. + // The key in the map is the sink-type in upper case. + Tolerations map[string]kubernetes.Toleration `json:"tolerations"` + + // InitContainer can be set to have a container that is used as init_container on the + // deployment. + InitContainer InitContainer `json:"init_container"` + + // GCSSinkCredential can be set to the name of kubernetes secret containing GCS credential. + // The secret must already exist on the target kube cluster in the same namespace. + // The secret will be mounted as a volume and the appropriate credential path will be set. + GCSSinkCredential string `json:"gcs_sink_credential,omitempty"` + + // DLQGCSSinkCredential is same as GCSSinkCredential but for DLQ. + DLQGCSSinkCredential string `json:"dlq_gcs_sink_credential,omitempty"` + + // BigQuerySinkCredential is same as GCSSinkCredential but for BigQuery credential. BigQuerySinkCredential string `json:"big_query_sink_credential,omitempty"` + + // RequestsAndLimits can be set to configure the container cpu/memory requests & limits. + // 'default' key will be used as base and any sink-type will be used as the override. + RequestsAndLimits map[string]RequestsAndLimits `json:"requests_and_limits" validate:"required"` + + // NodeAffinityMatchExpressions can be used to set node-affinity for the deployment. + NodeAffinityMatchExpressions NodeAffinityMatchExpressions `json:"node_affinity_match_expressions"` +} + +type RequestsAndLimits struct { + Limits UsageSpec `json:"limits,omitempty"` + Requests UsageSpec `json:"requests,omitempty"` } type NodeAffinityMatchExpressions struct { From 7e4caa74c40ba5088d1c2b84201b2fea6dd225f8 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Wed, 17 May 2023 10:52:34 +0530 Subject: [PATCH 41/72] feat: add firehose base config (#40) --- modules/firehose/config.go | 2 ++ modules/firehose/driver.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index d5e6cedb..3428c81b 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -79,6 +79,8 @@ func readConfig(r resource.Resource, confJSON json.RawMessage, dc driverConf) (* return nil, errors.ErrInvalid.WithMsgf("invalid config json").WithCausef(err.Error()) } + cfg.EnvVariables = cloneAndMergeMaps(dc.EnvVariables, cfg.EnvVariables) + if cfg.Replicas <= 0 { cfg.Replicas = 1 } diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index d819aa07..dad5a58e 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -93,6 +93,8 @@ type driverConf struct { // The key in the map is the sink-type in upper case. Tolerations map[string]kubernetes.Toleration `json:"tolerations"` + EnvVariables map[string]string `json:"env_variables,omitempty"` + // InitContainer can be set to have a container that is used as init_container on the // deployment. InitContainer InitContainer `json:"init_container"` From 57a30e8bde2c2a8d0ae46c441ad80daa92d287f2 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Mon, 17 Jul 2023 12:04:01 +0530 Subject: [PATCH 42/72] feat: offset reset history (#42) * feat: offset reset history - when reset action is triggered, entropy will save the offset reset value in env variables' * test: fix reset test * fix: store offset reset value - SOURCE_KAFKA_CONSUMER_CONFIG_AUTO_OFFSET_RESET is not to be used to store resetoffset value since it is used by firehose to auto-offset-reset - rather use a new field for this --- modules/firehose/config.go | 3 +++ modules/firehose/driver_plan.go | 8 ++++++++ modules/firehose/driver_plan_test.go | 2 ++ 3 files changed, 13 insertions(+) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index 3428c81b..9f17e939 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -50,6 +50,9 @@ type Config struct { // EnvVariables contains all the firehose environment config values. EnvVariables map[string]string `json:"env_variables,omitempty"` + // ResetOffset represents the value to which kafka consumer offset was set to + ResetOffset string `json:"reset_offset,omitempty"` + Limits UsageSpec `json:"limits,omitempty"` Requests UsageSpec `json:"requests,omitempty"` Telegraf *Telegraf `json:"telegraf,omitempty"` diff --git a/modules/firehose/driver_plan.go b/modules/firehose/driver_plan.go index 6b590abb..3fafb940 100644 --- a/modules/firehose/driver_plan.go +++ b/modules/firehose/driver_plan.go @@ -130,6 +130,14 @@ func (fd *firehoseDriver) planReset(exr module.ExpandedResource, act module.Acti immediately := fd.timeNow() + curConf, err := readConfig(exr.Resource, exr.Resource.Spec.Configs, fd.conf) + if err != nil { + return nil, err + } + + curConf.ResetOffset = resetValue + + exr.Resource.Spec.Configs = mustJSON(curConf) exr.Resource.State = resource.State{ Status: resource.StatusPending, Output: exr.Resource.State.Output, diff --git a/modules/firehose/driver_plan_test.go b/modules/firehose/driver_plan_test.go index 7233dde7..fcb8b8ab 100644 --- a/modules/firehose/driver_plan_test.go +++ b/modules/firehose/driver_plan_test.go @@ -368,6 +368,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { "SOURCE_KAFKA_BROKERS": "localhost:9092", "SOURCE_KAFKA_TOPIC": "foo-log", }, + "reset_offset": "latest", "limits": map[string]any{ "cpu": "200m", "memory": "512Mi", @@ -376,6 +377,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { "cpu": "200m", "memory": "512Mi", }, + "stopped": false, }), }, State: resource.State{ From 0128a81868b3e652f9028b639ee2495feb1eeec4 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Mon, 17 Jul 2023 12:05:48 +0530 Subject: [PATCH 43/72] feat: add statsd variables to envVariables (#41) * feat: add metrics keys to envVariables * feat: make statsd tags a template field * chore: remove whitespace --- modules/firehose/driver.go | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index dad5a58e..3e13f719 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -41,6 +41,11 @@ const ( const defaultKey = "default" +const ( + metricStatsdHost = "localhost" + metricStatsdPort = "8152" +) + var defaultDriverConf = driverConf{ Namespace: "firehose", ChartValues: ChartValues{ @@ -171,7 +176,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, ) (*helm.ReleaseConfig, error) { var telegrafConf Telegraf if conf.Telegraf != nil && conf.Telegraf.Enabled { - telegrafTags, err := renderLabels(conf.Telegraf.Config.AdditionalGlobalTags, res.Labels) + telegrafTags, err := renderTpl(conf.Telegraf.Config.AdditionalGlobalTags, res.Labels) if err != nil { return nil, err } @@ -202,7 +207,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, labelOrchestrator: orchestratorLabelValue, } - deploymentLabels, err := renderLabels(fd.conf.Labels, cloneAndMergeMaps(res.Labels, entropyLabels)) + deploymentLabels, err := renderTpl(fd.conf.Labels, cloneAndMergeMaps(res.Labels, entropyLabels)) if err != nil { return nil, err } @@ -261,6 +266,16 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, conf.EnvVariables["SINK_BIGQUERY_CREDENTIAL_PATH"] = credentialPath } + if telegrafConf.Enabled { + conf.EnvVariables, err = renderTpl(conf.EnvVariables, cloneAndMergeMaps(conf.EnvVariables, cloneAndMergeMaps(deploymentLabels, cloneAndMergeMaps(res.Labels, entropyLabels)))) + if err != nil { + return nil, err + } + + conf.EnvVariables["METRIC_STATSD_HOST"] = metricStatsdHost + conf.EnvVariables["METRIC_STATSD_PORT"] = metricStatsdPort + } + rc := helm.DefaultReleaseConfig() rc.Name = conf.DeploymentID rc.Repository = chartRepo @@ -319,7 +334,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, return rc, nil } -func renderLabels(labelsTpl map[string]string, labelsValues map[string]string) (map[string]string, error) { +func renderTpl(labelsTpl map[string]string, labelsValues map[string]string) (map[string]string, error) { const useZeroValueForMissingKey = "missingkey=zero" finalLabels := map[string]string{} From e54c6f90b46fbd281a2b3a3c09094cfa8339c1c6 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Mon, 17 Jul 2023 12:34:13 +0530 Subject: [PATCH 44/72] fix: goreleaser action upgrade (#43) fix: goreleaser action - goreleaser github action was failing while attempting release --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 717deb88..69871d2d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v2.6.1 + uses: goreleaser/goreleaser-action@v4.3.0 with: distribution: goreleaser version: latest From 272eb864d65936822eaafa5e4a2f732b1da97159 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Mon, 17 Jul 2023 12:48:57 +0530 Subject: [PATCH 45/72] fix: change rm-dist flag to clean (#44) --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 69871d2d..ee26509a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,6 +25,6 @@ jobs: with: distribution: goreleaser version: latest - args: --rm-dist + args: --clean env: GITHUB_TOKEN: ${{ secrets.GO_RELEASER_TOKEN }} From 1538c02d85e82a7d90d084089897095a40738f72 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Mon, 17 Jul 2023 13:44:44 +0530 Subject: [PATCH 46/72] fix: goreleaser (#45) * fix: change rm-dist flag to clean * fix: change to old version which supports replacements --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ee26509a..e3ff7215 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ jobs: uses: goreleaser/goreleaser-action@v4.3.0 with: distribution: goreleaser - version: latest + version: v1.18.2 args: --clean env: GITHUB_TOKEN: ${{ secrets.GO_RELEASER_TOKEN }} From f3642c1239829b10bd16af31fa025f808e06b830 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Wed, 19 Jul 2023 11:12:27 +0530 Subject: [PATCH 47/72] feat: stoptime in firehose start (#46) - will receive an optional field stop_time in body - if received, it will set the value to stoptime to this value --- modules/firehose/driver_plan.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/firehose/driver_plan.go b/modules/firehose/driver_plan.go index 3fafb940..70e1363d 100644 --- a/modules/firehose/driver_plan.go +++ b/modules/firehose/driver_plan.go @@ -3,6 +3,7 @@ package firehose import ( "context" "encoding/json" + "time" "github.com/goto/entropy/core/module" "github.com/goto/entropy/core/resource" @@ -62,7 +63,16 @@ func (fd *firehoseDriver) planChange(exr module.ExpandedResource, act module.Act curConf.Replicas = scaleParams.Replicas case StartAction: + var startParams struct { + StopTime *time.Time `json:"stop_time"` + } + if err := json.Unmarshal(act.Params, &startParams); err != nil { + return nil, errors.ErrInvalid.WithMsgf("invalid params for start action").WithCausef(err.Error()) + } curConf.Stopped = false + if startParams.StopTime != nil { + curConf.StopTime = startParams.StopTime + } case StopAction: curConf.Stopped = true From cadc134b8efb437cc6da0caa387eb50b4a9bfd58 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Tue, 25 Jul 2023 10:54:29 +0530 Subject: [PATCH 48/72] refactor: public ScaleParams & StartParams (#47) * refactor: public ScaleParams & StartParams * chore: update config.go --- modules/firehose/config.go | 8 ++++++++ modules/firehose/driver_plan.go | 9 ++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index 9f17e939..8e1a0a29 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -28,6 +28,14 @@ var ( validateConfig = validator.FromJSONSchema(configSchemaRaw) ) +type ScaleParams struct { + Replicas int `json:"replicas"` +} + +type StartParams struct { + StopTime *time.Time `json:"stop_time"` +} + type Config struct { // Stopped flag when set forces the firehose to be stopped on next sync. Stopped bool `json:"stopped"` diff --git a/modules/firehose/driver_plan.go b/modules/firehose/driver_plan.go index 70e1363d..b2b160a8 100644 --- a/modules/firehose/driver_plan.go +++ b/modules/firehose/driver_plan.go @@ -3,7 +3,6 @@ package firehose import ( "context" "encoding/json" - "time" "github.com/goto/entropy/core/module" "github.com/goto/entropy/core/resource" @@ -51,9 +50,7 @@ func (fd *firehoseDriver) planChange(exr module.ExpandedResource, act module.Act curConf = newConf case ScaleAction: - var scaleParams struct { - Replicas int `json:"replicas"` - } + var scaleParams ScaleParams if err := json.Unmarshal(act.Params, &scaleParams); err != nil { return nil, errors.ErrInvalid.WithMsgf("invalid params for scale action").WithCausef(err.Error()) } else if scaleParams.Replicas < 1 { @@ -63,9 +60,7 @@ func (fd *firehoseDriver) planChange(exr module.ExpandedResource, act module.Act curConf.Replicas = scaleParams.Replicas case StartAction: - var startParams struct { - StopTime *time.Time `json:"stop_time"` - } + var startParams StartParams if err := json.Unmarshal(act.Params, &startParams); err != nil { return nil, errors.ErrInvalid.WithMsgf("invalid params for start action").WithCausef(err.Error()) } From 2217ff1d6ae7bf59471ec7f954a4db7d3a7cbbe9 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Wed, 26 Jul 2023 23:07:41 +0530 Subject: [PATCH 49/72] feat: add urn to deployment labels (#48) * feat: add urn to deployment labels - this can be used as a metrics tag * fix: new map for template labels * fix: remove urn label form entropylabels --- modules/firehose/driver.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 3e13f719..b6bfb301 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -35,17 +35,13 @@ const ( labelDeployment = "deployment" labelOrchestrator = "orchestrator" + labelURN = "urn" orchestratorLabelValue = "entropy" ) const defaultKey = "default" -const ( - metricStatsdHost = "localhost" - metricStatsdPort = "8152" -) - var defaultDriverConf = driverConf{ Namespace: "firehose", ChartValues: ChartValues{ @@ -207,6 +203,10 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, labelOrchestrator: orchestratorLabelValue, } + otherLabels := map[string]string{ + labelURN: res.URN, + } + deploymentLabels, err := renderTpl(fd.conf.Labels, cloneAndMergeMaps(res.Labels, entropyLabels)) if err != nil { return nil, err @@ -267,13 +267,10 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, } if telegrafConf.Enabled { - conf.EnvVariables, err = renderTpl(conf.EnvVariables, cloneAndMergeMaps(conf.EnvVariables, cloneAndMergeMaps(deploymentLabels, cloneAndMergeMaps(res.Labels, entropyLabels)))) + conf.EnvVariables, err = renderTpl(conf.EnvVariables, cloneAndMergeMaps(cloneAndMergeMaps(conf.EnvVariables, cloneAndMergeMaps(deploymentLabels, cloneAndMergeMaps(res.Labels, entropyLabels))), otherLabels)) if err != nil { return nil, err } - - conf.EnvVariables["METRIC_STATSD_HOST"] = metricStatsdHost - conf.EnvVariables["METRIC_STATSD_PORT"] = metricStatsdPort } rc := helm.DefaultReleaseConfig() From 178f6a82b973073dc20337d29ca04be2f6efc168 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Thu, 27 Jul 2023 15:39:55 +0530 Subject: [PATCH 50/72] feat: createdBy and updatedBy in resource & revision (#49) * feat: createdBy and updatedBy in resource & revision * feat: update resource proto" --- Makefile | 2 +- buf.gen.yaml | 15 +- core/module/action.go | 1 + core/resource/resource.go | 4 + core/write.go | 5 + go.mod | 6 +- go.sum | 9 +- internal/server/server.go | 22 +- internal/server/serverutils/context.go | 38 ++ internal/server/v1/resources/mappers.go | 3 + internal/server/v1/resources/server.go | 19 + internal/server/v1/resources/server_test.go | 19 +- internal/store/postgres/resource_model.go | 4 +- internal/store/postgres/resource_store.go | 25 +- internal/store/postgres/revision_model.go | 1 + internal/store/postgres/revision_store.go | 5 +- internal/store/postgres/schema.sql | 8 +- proto/entropy.swagger.yaml | 85 ++-- proto/gotocompany/common/v1/service.pb.go | 22 +- proto/gotocompany/common/v1/service.pb.gw.go | 2 +- .../common/v1/service.pb.validate.go | 3 + .../gotocompany/common/v1/service_grpc.pb.go | 12 +- .../gotocompany/entropy/v1beta1/module.pb.go | 2 +- .../entropy/v1beta1/module.pb.gw.go | 2 +- .../entropy/v1beta1/module.pb.validate.go | 11 + .../entropy/v1beta1/module_grpc.pb.go | 32 +- .../entropy/v1beta1/resource.pb.go | 476 ++++++++++-------- .../entropy/v1beta1/resource.pb.gw.go | 6 +- .../entropy/v1beta1/resource.pb.validate.go | 30 ++ .../entropy/v1beta1/resource_grpc.pb.go | 45 +- 30 files changed, 570 insertions(+), 344 deletions(-) create mode 100644 internal/server/serverutils/context.go diff --git a/Makefile b/Makefile index ee132c29..9641c414 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ NAME=github.com/goto/entropy VERSION=$(shell git describe --tags --always --first-parent 2>/dev/null) COMMIT=$(shell git rev-parse --short HEAD) -PROTON_COMMIT="1d611a9efbfecfa54945906214b19b72e6fbb841" +PROTON_COMMIT="ec066344b8597f9238dbbfe3cd05532a49df59ca" BUILD_TIME=$(shell date) COVERAGE_DIR=coverage BUILD_DIR=dist diff --git a/buf.gen.yaml b/buf.gen.yaml index e50d1450..d6efdb7f 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -1,20 +1,21 @@ version: v1 plugins: - - remote: "buf.build/library/plugins/go:v1.27.1-1" + - plugin: buf.build/protocolbuffers/go:v1.30.0 out: proto opt: paths=source_relative - - remote: "buf.build/library/plugins/go-grpc:v1.1.0-2" + - plugin: buf.build/grpc/go:v1.3.0 out: proto opt: paths=source_relative,require_unimplemented_servers=true - - remote: buf.build/odpf/plugins/validate - out: "proto" - opt: "paths=source_relative,lang=go" - - remote: "buf.build/grpc-ecosystem/plugins/grpc-gateway:v2.11.3-1" + - plugin: buf.build/bufbuild/validate-go:v1.0.1 + out: proto + opt: + - paths=source_relative + - plugin: buf.build/grpc-ecosystem/gateway:v2.15.2 out: proto opt: - paths=source_relative - allow_repeated_fields_in_body=true - - remote: "buf.build/grpc-ecosystem/plugins/openapiv2:v2.11.3-1" + - plugin: buf.build/grpc-ecosystem/openapiv2:v2.15.2 out: proto opt: - allow_repeated_fields_in_body=true diff --git a/core/module/action.go b/core/module/action.go index ea2ed58a..3cc964a2 100644 --- a/core/module/action.go +++ b/core/module/action.go @@ -20,6 +20,7 @@ type ActionRequest struct { Name string `json:"name"` Params json.RawMessage `json:"params"` Labels map[string]string `json:"labels"` + UserID string } // ActionDesc is a descriptor for an action supported by a module. diff --git a/core/resource/resource.go b/core/resource/resource.go index 028cf891..736dd020 100644 --- a/core/resource/resource.go +++ b/core/resource/resource.go @@ -45,6 +45,8 @@ type Resource struct { Labels map[string]string `json:"labels"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` + UpdatedBy string `json:"updated_by"` + CreatedBy string `json:"created_by"` Spec Spec `json:"spec"` State State `json:"state"` } @@ -63,6 +65,7 @@ type Filter struct { type UpdateRequest struct { Spec Spec `json:"spec"` Labels map[string]string `json:"labels"` + UserID string } type RevisionsSelector struct { @@ -75,6 +78,7 @@ type Revision struct { Reason string `json:"reason"` Labels map[string]string `json:"labels"` CreatedAt time.Time `json:"created_at"` + CreatedBy string `json:"created_by"` Spec Spec `json:"spec"` } diff --git a/core/write.go b/core/write.go index 9966e621..186c4488 100644 --- a/core/write.go +++ b/core/write.go @@ -18,6 +18,7 @@ func (svc *Service) CreateResource(ctx context.Context, res resource.Resource) ( Name: module.CreateAction, Params: res.Spec.Configs, Labels: res.Labels, + UserID: res.CreatedBy, } res.Spec.Configs = nil @@ -35,6 +36,7 @@ func (svc *Service) UpdateResource(ctx context.Context, urn string, req resource Name: module.UpdateAction, Params: req.Spec.Configs, Labels: req.Labels, + UserID: req.UserID, }) } @@ -66,9 +68,12 @@ func (svc *Service) execAction(ctx context.Context, res resource.Resource, act m if isCreate(act.Name) { planned.CreatedAt = svc.clock() planned.UpdatedAt = planned.CreatedAt + planned.CreatedBy = act.UserID + planned.UpdatedBy = act.UserID } else { planned.CreatedAt = res.CreatedAt planned.UpdatedAt = svc.clock() + planned.UpdatedBy = act.UserID } reason := fmt.Sprintf("action:%s", act.Name) diff --git a/go.mod b/go.mod index 15807568..5b33f3f5 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/briandowns/spinner v1.18.0 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect github.com/charmbracelet/glamour v0.3.0 // indirect github.com/containerd/containerd v1.6.6 // indirect @@ -162,12 +162,12 @@ require ( go.uber.org/multierr v1.8.0 // indirect golang.org/x/crypto v0.5.0 // indirect golang.org/x/net v0.5.0 // indirect - golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 // indirect + golang.org/x/oauth2 v0.4.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.4.0 // indirect golang.org/x/term v0.4.0 // indirect golang.org/x/text v0.6.0 // indirect - golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect + golang.org/x/time v0.1.0 // indirect google.golang.org/appengine v1.6.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect diff --git a/go.sum b/go.sum index 4aafd103..f08db965 100644 --- a/go.sum +++ b/go.sum @@ -256,8 +256,9 @@ github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6 github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 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/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= github.com/charmbracelet/glamour v0.3.0 h1:3H+ZrKlSg8s+WU6V7eF2eRVYt8lCueffbi7r2+ffGkc= @@ -1719,8 +1720,9 @@ golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA= golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1909,8 +1911,9 @@ golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= +golang.org/x/time v0.1.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-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/internal/server/server.go b/internal/server/server.go index 039d7dbc..3ebc1194 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -22,6 +22,7 @@ import ( "google.golang.org/grpc/reflection" "google.golang.org/protobuf/encoding/protojson" + "github.com/goto/entropy/internal/server/serverutils" modulesv1 "github.com/goto/entropy/internal/server/v1/modules" resourcesv1 "github.com/goto/entropy/internal/server/v1/resources" "github.com/goto/entropy/pkg/common" @@ -52,15 +53,18 @@ func Serve(ctx context.Context, httpAddr, grpcAddr string, nrApp *newrelic.Appli grpc.StatsHandler(&ocgrpc.ServerHandler{}), } grpcServer := grpc.NewServer(grpcOpts...) - rpcHTTPGateway := runtime.NewServeMux(runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{ - MarshalOptions: protojson.MarshalOptions{ - UseProtoNames: true, - EmitUnpopulated: true, - }, - UnmarshalOptions: protojson.UnmarshalOptions{ - DiscardUnknown: true, - }, - })) + rpcHTTPGateway := runtime.NewServeMux( + runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{ + MarshalOptions: protojson.MarshalOptions{ + UseProtoNames: true, + EmitUnpopulated: true, + }, + UnmarshalOptions: protojson.UnmarshalOptions{ + DiscardUnknown: true, + }, + }), + runtime.WithMetadata(serverutils.ExtractRequestMetadata), + ) reflection.Register(grpcServer) diff --git a/internal/server/serverutils/context.go b/internal/server/serverutils/context.go new file mode 100644 index 00000000..101b19f4 --- /dev/null +++ b/internal/server/serverutils/context.go @@ -0,0 +1,38 @@ +package serverutils + +import ( + "context" + "net/http" + "strings" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +const userIDHeader = "user-id" + +func GetUserIdentifier(ctx context.Context) (string, error) { + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + return "", status.Errorf(codes.DataLoss, "failed to get metadata") + } + + xrid := md[userIDHeader] + if len(xrid) == 0 { + return "", status.Errorf(codes.InvalidArgument, "missing '%s' header", userIDHeader) + } + + userID := strings.TrimSpace(xrid[0]) + if userID == "" { + return "", status.Errorf(codes.InvalidArgument, "empty '%s' header", userIDHeader) + } + + return userID, nil +} + +func ExtractRequestMetadata(_ context.Context, request *http.Request) metadata.MD { + header := request.Header.Get(userIDHeader) + md := metadata.Pairs(userIDHeader, header) + return md +} diff --git a/internal/server/v1/resources/mappers.go b/internal/server/v1/resources/mappers.go index 35fb5fd8..b30c5ac9 100644 --- a/internal/server/v1/resources/mappers.go +++ b/internal/server/v1/resources/mappers.go @@ -35,6 +35,8 @@ func resourceToProto(res resource.Resource) (*entropyv1beta1.Resource, error) { UpdatedAt: timestamppb.New(res.UpdatedAt), Spec: spec, State: protoState, + CreatedBy: res.CreatedBy, + UpdatedBy: res.UpdatedBy, }, nil } @@ -155,6 +157,7 @@ func revisionToProto(revision resource.Revision) (*entropyv1beta1.ResourceRevisi Reason: revision.Reason, Labels: revision.Labels, CreatedAt: timestamppb.New(revision.CreatedAt), + CreatedBy: revision.CreatedBy, Spec: spec, }, nil } diff --git a/internal/server/v1/resources/server.go b/internal/server/v1/resources/server.go index b2f62be2..aa640599 100644 --- a/internal/server/v1/resources/server.go +++ b/internal/server/v1/resources/server.go @@ -41,6 +41,13 @@ func (server APIServer) CreateResource(ctx context.Context, request *entropyv1be return nil, serverutils.ToRPCError(err) } + userIdentifier, err := serverutils.GetUserIdentifier(ctx) + if err != nil { + return nil, serverutils.ToRPCError(err) + } + res.CreatedBy = userIdentifier + res.UpdatedBy = userIdentifier + result, err := server.resourceSvc.CreateResource(ctx, *res) if err != nil { return nil, serverutils.ToRPCError(err) @@ -62,9 +69,15 @@ func (server APIServer) UpdateResource(ctx context.Context, request *entropyv1be return nil, serverutils.ToRPCError(err) } + userIdentifier, err := serverutils.GetUserIdentifier(ctx) + if err != nil { + return nil, serverutils.ToRPCError(err) + } + updateRequest := resource.UpdateRequest{ Spec: *newSpec, Labels: request.Labels, + UserID: userIdentifier, } res, err := server.resourceSvc.UpdateResource(ctx, request.GetUrn(), updateRequest) @@ -139,10 +152,16 @@ func (server APIServer) ApplyAction(ctx context.Context, request *entropyv1beta1 return nil, err } + userIdentifier, err := serverutils.GetUserIdentifier(ctx) + if err != nil { + return nil, serverutils.ToRPCError(err) + } + action := module.ActionRequest{ Name: request.GetAction(), Params: paramsJSON, Labels: request.Labels, + UserID: userIdentifier, } updatedRes, err := server.resourceSvc.ApplyAction(ctx, request.GetUrn(), action) diff --git a/internal/server/v1/resources/server_test.go b/internal/server/v1/resources/server_test.go index 63d0ae5c..9353b16e 100644 --- a/internal/server/v1/resources/server_test.go +++ b/internal/server/v1/resources/server_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/structpb" @@ -148,7 +149,11 @@ func TestAPIServer_CreateResource(t *testing.T) { t.Parallel() srv := tt.setup(t) - got, err := srv.CreateResource(context.Background(), tt.request) + ctx := context.Background() + md := metadata.New(map[string]string{"user-id": "john.doe@goto.com"}) + ctx = metadata.NewIncomingContext(ctx, md) + + got, err := srv.CreateResource(ctx, tt.request) if tt.wantErr != nil { assert.Error(t, err) assert.Truef(t, errors.Is(err, tt.wantErr), "'%s' != '%s'", tt.wantErr, err) @@ -273,7 +278,11 @@ func TestAPIServer_UpdateResource(t *testing.T) { t.Parallel() srv := tt.setup(t) - got, err := srv.UpdateResource(context.Background(), tt.request) + ctx := context.Background() + md := metadata.New(map[string]string{"user-id": "john.doe@goto.com"}) + ctx = metadata.NewIncomingContext(ctx, md) + + got, err := srv.UpdateResource(ctx, tt.request) if tt.wantErr != nil { assert.Error(t, err) assert.True(t, errors.Is(err, tt.wantErr)) @@ -647,7 +656,11 @@ func TestAPIServer_ApplyAction(t *testing.T) { t.Parallel() srv := tt.setup(t) - got, err := srv.ApplyAction(context.Background(), tt.request) + ctx := context.Background() + md := metadata.New(map[string]string{"user-id": "john.doe@goto.com"}) + ctx = metadata.NewIncomingContext(ctx, md) + + got, err := srv.ApplyAction(ctx, tt.request) if tt.wantErr != nil { assert.Error(t, err) assert.True(t, errors.Is(err, tt.wantErr)) diff --git a/internal/store/postgres/resource_model.go b/internal/store/postgres/resource_model.go index 0f980010..386a4fd3 100644 --- a/internal/store/postgres/resource_model.go +++ b/internal/store/postgres/resource_model.go @@ -20,6 +20,8 @@ type resourceModel struct { Project string `db:"project"` CreatedAt time.Time `db:"created_at"` UpdatedAt time.Time `db:"updated_at"` + CreatedBy string `db:"created_by"` + UpdatedBy string `db:"updated_by"` SpecConfigs []byte `db:"spec_configs"` StateStatus string `db:"state_status"` StateOutput []byte `db:"state_output"` @@ -30,7 +32,7 @@ type resourceModel struct { func readResourceRecord(ctx context.Context, r sqlx.QueryerContext, urn string, into *resourceModel) error { cols := []string{ - "id", "urn", "kind", "project", "name", "created_at", "updated_at", + "id", "urn", "kind", "project", "name", "created_at", "updated_at", "created_by", "updated_by", "spec_configs", "state_status", "state_output", "state_module_data", "state_next_sync", "state_sync_result", } diff --git a/internal/store/postgres/resource_store.go b/internal/store/postgres/resource_store.go index 093a1de5..b0b3ba45 100644 --- a/internal/store/postgres/resource_store.go +++ b/internal/store/postgres/resource_store.go @@ -55,6 +55,8 @@ func (st *Store) GetByURN(ctx context.Context, urn string) (*resource.Resource, Labels: tagsToLabelMap(tags), CreatedAt: rec.CreatedAt, UpdatedAt: rec.UpdatedAt, + CreatedBy: rec.CreatedBy, + UpdatedBy: rec.UpdatedBy, Spec: resource.Spec{ Configs: rec.SpecConfigs, Dependencies: deps, @@ -128,10 +130,11 @@ func (st *Store) Create(ctx context.Context, r resource.Resource, hooks ...resou } rev := resource.Revision{ - URN: r.URN, - Spec: r.Spec, - Labels: r.Labels, - Reason: "action:create", + URN: r.URN, + Spec: r.Spec, + Labels: r.Labels, + Reason: "action:create", + CreatedBy: r.UpdatedBy, } if err := insertRevision(ctx, tx, id, rev); err != nil { @@ -159,6 +162,7 @@ func (st *Store) Update(ctx context.Context, r resource.Resource, saveRevision b Where(sq.Eq{"id": id}). SetMap(map[string]interface{}{ "updated_at": sq.Expr("current_timestamp"), + "updated_by": r.UpdatedBy, "spec_configs": r.Spec.Configs, "state_status": r.State.Status, "state_output": r.State.Output, @@ -182,10 +186,11 @@ func (st *Store) Update(ctx context.Context, r resource.Resource, saveRevision b if saveRevision { rev := resource.Revision{ - URN: r.URN, - Spec: r.Spec, - Labels: r.Labels, - Reason: reason, + URN: r.URN, + Spec: r.Spec, + Labels: r.Labels, + Reason: reason, + CreatedBy: r.UpdatedBy, } if err := insertRevision(ctx, tx, id, rev); err != nil { @@ -326,10 +331,10 @@ func (st *Store) extendWaitTime(ctx context.Context, r sq.BaseRunner, urn string func insertResourceRecord(ctx context.Context, runner sqlx.QueryerContext, r resource.Resource) (int64, error) { builder := sq.Insert(tableResources). - Columns("urn", "kind", "project", "name", "created_at", "updated_at", + Columns("urn", "kind", "project", "name", "created_at", "updated_at", "created_by", "updated_by", "spec_configs", "state_status", "state_output", "state_module_data", "state_next_sync", "state_sync_result"). - Values(r.URN, r.Kind, r.Project, r.Name, r.CreatedAt, r.UpdatedAt, + Values(r.URN, r.Kind, r.Project, r.Name, r.CreatedAt, r.UpdatedAt, r.CreatedBy, r.UpdatedBy, r.Spec.Configs, r.State.Status, r.State.Output, r.State.ModuleData, r.State.NextSyncAt, syncResultAsJSON(r.State.SyncResult)). Suffix(`RETURNING "id"`) diff --git a/internal/store/postgres/revision_model.go b/internal/store/postgres/revision_model.go index dcd26111..03268bc5 100644 --- a/internal/store/postgres/revision_model.go +++ b/internal/store/postgres/revision_model.go @@ -11,6 +11,7 @@ type revisionModel struct { ID int64 `db:"id"` Reason string `db:"reason"` CreatedAt time.Time `db:"created_at"` + CreatedBy string `db:"created_by"` ResourceID int64 `db:"resource_id"` SpecConfigs []byte `db:"spec_configs"` } diff --git a/internal/store/postgres/revision_store.go b/internal/store/postgres/revision_store.go index 31c14145..bb1f989d 100644 --- a/internal/store/postgres/revision_store.go +++ b/internal/store/postgres/revision_store.go @@ -51,6 +51,7 @@ func (st *Store) Revisions(ctx context.Context, selector resource.RevisionsSelec URN: selector.URN, Reason: rm.Reason, CreatedAt: rm.CreatedAt, + CreatedBy: rm.CreatedBy, Spec: resource.Spec{ Configs: rm.SpecConfigs, Dependencies: deps, @@ -81,8 +82,8 @@ func (st *Store) Revisions(ctx context.Context, selector resource.RevisionsSelec func insertRevision(ctx context.Context, tx *sqlx.Tx, resID int64, rev resource.Revision) error { q := sq.Insert(tableRevisions). - Columns("resource_id", "reason", "spec_configs"). - Values(resID, rev.Reason, rev.Spec.Configs). + Columns("resource_id", "reason", "spec_configs", "created_by"). + Values(resID, rev.Reason, rev.Spec.Configs, rev.CreatedBy). Suffix(`RETURNING "id"`). PlaceholderFormat(sq.Dollar) diff --git a/internal/store/postgres/schema.sql b/internal/store/postgres/schema.sql index 3e2a8e8b..68f0b53e 100644 --- a/internal/store/postgres/schema.sql +++ b/internal/store/postgres/schema.sql @@ -68,4 +68,10 @@ CREATE TABLE IF NOT EXISTS revision_tags UNIQUE (revision_id, tag) ); CREATE INDEX IF NOT EXISTS idx_revision_tags_revision_id ON revision_tags (revision_id); -CREATE INDEX IF NOT EXISTS idx_revision_tags_tag ON revision_tags (tag); \ No newline at end of file +CREATE INDEX IF NOT EXISTS idx_revision_tags_tag ON revision_tags (tag); + +ALTER TABLE resources + ADD COLUMN IF NOT EXISTS created_by TEXT NOT NULL DEFAULT '', + ADD COLUMN IF NOT EXISTS updated_by TEXT NOT NULL DEFAULT ''; + +ALTER TABLE revisions ADD COLUMN IF NOT EXISTS created_by TEXT NOT NULL DEFAULT ''; \ No newline at end of file diff --git a/proto/entropy.swagger.yaml b/proto/entropy.swagger.yaml index cd86e5cd..a707c6cc 100644 --- a/proto/entropy.swagger.yaml +++ b/proto/entropy.swagger.yaml @@ -214,12 +214,12 @@ paths: schema: type: object properties: + new_spec: + $ref: '#/definitions/ResourceSpec' labels: type: object additionalProperties: type: string - new_spec: - $ref: '#/definitions/ResourceSpec' tags: - ResourceService /v1beta1/resources/{urn}/actions/{action}: @@ -258,10 +258,10 @@ paths: schema: type: object properties: - error: - $ref: '#/definitions/rpc.Status' result: $ref: '#/definitions/GetLogResponse' + error: + $ref: '#/definitions/rpc.Status' title: Stream result of GetLogResponse default: description: An unexpected error response. @@ -360,6 +360,7 @@ definitions: revisions: type: array items: + type: object $ref: '#/definitions/ResourceRevision' GetVersionRequest: type: object @@ -377,6 +378,7 @@ definitions: modules: type: array items: + type: object $ref: '#/definitions/Module' ListResourcesResponse: type: object @@ -384,6 +386,7 @@ definitions: resources: type: array items: + type: object $ref: '#/definitions/Resource' ListString: type: object @@ -412,19 +415,19 @@ definitions: Module: type: object properties: - configs: {} - created_at: + urn: type: string - format: date-time name: type: string project: type: string - updated_at: + created_at: type: string format: date-time - urn: + updated_at: type: string + format: date-time + configs: {} NullValue: type: string enum: @@ -440,27 +443,31 @@ definitions: Resource: type: object properties: - created_at: + urn: type: string - format: date-time kind: type: string + name: + type: string + project: + type: string labels: type: object additionalProperties: type: string - name: + created_at: type: string - project: + format: date-time + updated_at: type: string + format: date-time spec: $ref: '#/definitions/ResourceSpec' state: $ref: '#/definitions/ResourceState' - updated_at: + created_by: type: string - format: date-time - urn: + updated_by: type: string ResourceDependency: type: object @@ -476,20 +483,22 @@ definitions: ResourceRevision: type: object properties: - created_at: - type: string - format: date-time id: type: string + urn: + type: string labels: type: object additionalProperties: type: string - reason: + created_at: type: string + format: date-time spec: $ref: '#/definitions/ResourceSpec' - urn: + reason: + type: string + created_by: type: string ResourceSpec: type: object @@ -498,6 +507,7 @@ definitions: dependencies: type: array items: + type: object $ref: '#/definitions/ResourceDependency' description: |- dependencies can be used to refer to other existing resources @@ -505,19 +515,14 @@ definitions: ResourceState: type: object properties: - log_options: - $ref: '#/definitions/LogOptions' - module_data: - type: string - format: byte - next_sync_at: - type: string - format: date-time - output: {} status: $ref: '#/definitions/ResourceState.Status' - sync_last_error: + output: {} + module_data: type: string + format: byte + log_options: + $ref: '#/definitions/LogOptions' sync_retries: type: integer format: int32 @@ -525,6 +530,11 @@ definitions: information about the ongoing sync process. if status is ERROR / PENDING, this value can be used to understand the issue. + sync_last_error: + type: string + next_sync_at: + type: string + format: date-time ResourceState.Status: type: string enum: @@ -547,18 +557,18 @@ definitions: Version: type: object properties: - architecture: + version: + type: string + commit: type: string build_time: type: string format: date-time - commit: - type: string lang_version: type: string os: type: string - version: + architecture: type: string rpc.Status: type: object @@ -566,11 +576,12 @@ definitions: code: type: integer format: int32 + message: + type: string details: type: array items: + type: object $ref: '#/definitions/Any' - message: - type: string externalDocs: description: Common endpoints for all services diff --git a/proto/gotocompany/common/v1/service.pb.go b/proto/gotocompany/common/v1/service.pb.go index 5de1cb00..1672caf2 100644 --- a/proto/gotocompany/common/v1/service.pb.go +++ b/proto/gotocompany/common/v1/service.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.27.1 +// protoc-gen-go v1.30.0 // protoc (unknown) // source: gotocompany/common/v1/service.proto @@ -249,16 +249,16 @@ var file_gotocompany_common_v1_service_proto_rawDesc = []byte{ 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x42, 0x8b, 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x42, 0x12, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x20, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x92, 0x41, 0x31, - 0x12, 0x07, 0x32, 0x05, 0x30, 0x2e, 0x31, 0x2e, 0x30, 0x2a, 0x01, 0x01, 0x72, 0x23, 0x0a, 0x21, - 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x20, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, - 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x6f, 0x6e, 0x42, 0x8b, 0x01, 0x92, 0x41, 0x31, 0x12, 0x07, 0x32, 0x05, 0x30, 0x2e, 0x31, + 0x2e, 0x30, 0x2a, 0x01, 0x01, 0x72, 0x23, 0x0a, 0x21, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x20, + 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, + 0x6c, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, + 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x42, 0x12, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x20, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x74, 0x6f, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x76, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/gotocompany/common/v1/service.pb.gw.go b/proto/gotocompany/common/v1/service.pb.gw.go index 457b50f9..43e57236 100644 --- a/proto/gotocompany/common/v1/service.pb.gw.go +++ b/proto/gotocompany/common/v1/service.pb.gw.go @@ -102,7 +102,7 @@ func RegisterCommonServiceHandlerServer(ctx context.Context, mux *runtime.ServeM // RegisterCommonServiceHandlerFromEndpoint is same as RegisterCommonServiceHandler but // automatically dials to "endpoint" and closes the connection when "ctx" gets done. func RegisterCommonServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) + conn, err := grpc.DialContext(ctx, endpoint, opts...) if err != nil { return err } diff --git a/proto/gotocompany/common/v1/service.pb.validate.go b/proto/gotocompany/common/v1/service.pb.validate.go index 0588dd5f..05cb7d8e 100644 --- a/proto/gotocompany/common/v1/service.pb.validate.go +++ b/proto/gotocompany/common/v1/service.pb.validate.go @@ -89,6 +89,7 @@ func (m *GetVersionRequest) validate(all bool) error { if len(errors) > 0 { return GetVersionRequestMultiError(errors) } + return nil } @@ -219,6 +220,7 @@ func (m *GetVersionResponse) validate(all bool) error { if len(errors) > 0 { return GetVersionResponseMultiError(errors) } + return nil } @@ -358,6 +360,7 @@ func (m *Version) validate(all bool) error { if len(errors) > 0 { return VersionMultiError(errors) } + return nil } diff --git a/proto/gotocompany/common/v1/service_grpc.pb.go b/proto/gotocompany/common/v1/service_grpc.pb.go index 13c31ab3..ecad6c42 100644 --- a/proto/gotocompany/common/v1/service_grpc.pb.go +++ b/proto/gotocompany/common/v1/service_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: gotocompany/common/v1/service.proto package v1 @@ -14,6 +18,10 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + CommonService_GetVersion_FullMethodName = "/gotocompany.common.v1.CommonService/GetVersion" +) + // CommonServiceClient is the client API for CommonService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -31,7 +39,7 @@ func NewCommonServiceClient(cc grpc.ClientConnInterface) CommonServiceClient { func (c *commonServiceClient) GetVersion(ctx context.Context, in *GetVersionRequest, opts ...grpc.CallOption) (*GetVersionResponse, error) { out := new(GetVersionResponse) - err := c.cc.Invoke(ctx, "/gotocompany.common.v1.CommonService/GetVersion", in, out, opts...) + err := c.cc.Invoke(ctx, CommonService_GetVersion_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -76,7 +84,7 @@ func _CommonService_GetVersion_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/gotocompany.common.v1.CommonService/GetVersion", + FullMethod: CommonService_GetVersion_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(CommonServiceServer).GetVersion(ctx, req.(*GetVersionRequest)) diff --git a/proto/gotocompany/entropy/v1beta1/module.pb.go b/proto/gotocompany/entropy/v1beta1/module.pb.go index e4c447b2..dd6acd0f 100644 --- a/proto/gotocompany/entropy/v1beta1/module.pb.go +++ b/proto/gotocompany/entropy/v1beta1/module.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.27.1 +// protoc-gen-go v1.30.0 // protoc (unknown) // source: gotocompany/entropy/v1beta1/module.proto diff --git a/proto/gotocompany/entropy/v1beta1/module.pb.gw.go b/proto/gotocompany/entropy/v1beta1/module.pb.gw.go index 16655f87..3d569e0e 100644 --- a/proto/gotocompany/entropy/v1beta1/module.pb.gw.go +++ b/proto/gotocompany/entropy/v1beta1/module.pb.gw.go @@ -410,7 +410,7 @@ func RegisterModuleServiceHandlerServer(ctx context.Context, mux *runtime.ServeM // RegisterModuleServiceHandlerFromEndpoint is same as RegisterModuleServiceHandler but // automatically dials to "endpoint" and closes the connection when "ctx" gets done. func RegisterModuleServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) + conn, err := grpc.DialContext(ctx, endpoint, opts...) if err != nil { return err } diff --git a/proto/gotocompany/entropy/v1beta1/module.pb.validate.go b/proto/gotocompany/entropy/v1beta1/module.pb.validate.go index 52f2cb00..cce53c4b 100644 --- a/proto/gotocompany/entropy/v1beta1/module.pb.validate.go +++ b/proto/gotocompany/entropy/v1beta1/module.pb.validate.go @@ -152,6 +152,7 @@ func (m *Module) validate(all bool) error { if len(errors) > 0 { return ModuleMultiError(errors) } + return nil } @@ -252,6 +253,7 @@ func (m *ListModulesRequest) validate(all bool) error { if len(errors) > 0 { return ListModulesRequestMultiError(errors) } + return nil } @@ -387,6 +389,7 @@ func (m *ListModulesResponse) validate(all bool) error { if len(errors) > 0 { return ListModulesResponseMultiError(errors) } + return nil } @@ -490,6 +493,7 @@ func (m *GetModuleRequest) validate(all bool) error { if len(errors) > 0 { return GetModuleRequestMultiError(errors) } + return nil } @@ -618,6 +622,7 @@ func (m *GetModuleResponse) validate(all bool) error { if len(errors) > 0 { return GetModuleResponseMultiError(errors) } + return nil } @@ -748,6 +753,7 @@ func (m *CreateModuleRequest) validate(all bool) error { if len(errors) > 0 { return CreateModuleRequestMultiError(errors) } + return nil } @@ -878,6 +884,7 @@ func (m *CreateModuleResponse) validate(all bool) error { if len(errors) > 0 { return CreateModuleResponseMultiError(errors) } + return nil } @@ -1010,6 +1017,7 @@ func (m *UpdateModuleRequest) validate(all bool) error { if len(errors) > 0 { return UpdateModuleRequestMultiError(errors) } + return nil } @@ -1140,6 +1148,7 @@ func (m *UpdateModuleResponse) validate(all bool) error { if len(errors) > 0 { return UpdateModuleResponseMultiError(errors) } + return nil } @@ -1243,6 +1252,7 @@ func (m *DeleteModuleRequest) validate(all bool) error { if len(errors) > 0 { return DeleteModuleRequestMultiError(errors) } + return nil } @@ -1344,6 +1354,7 @@ func (m *DeleteModuleResponse) validate(all bool) error { if len(errors) > 0 { return DeleteModuleResponseMultiError(errors) } + return nil } diff --git a/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go b/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go index c469596d..a7015b3c 100644 --- a/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go +++ b/proto/gotocompany/entropy/v1beta1/module_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: gotocompany/entropy/v1beta1/module.proto package entropyv1beta1 @@ -14,6 +18,14 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + ModuleService_ListModules_FullMethodName = "/gotocompany.entropy.v1beta1.ModuleService/ListModules" + ModuleService_GetModule_FullMethodName = "/gotocompany.entropy.v1beta1.ModuleService/GetModule" + ModuleService_CreateModule_FullMethodName = "/gotocompany.entropy.v1beta1.ModuleService/CreateModule" + ModuleService_UpdateModule_FullMethodName = "/gotocompany.entropy.v1beta1.ModuleService/UpdateModule" + ModuleService_DeleteModule_FullMethodName = "/gotocompany.entropy.v1beta1.ModuleService/DeleteModule" +) + // ModuleServiceClient is the client API for ModuleService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -35,7 +47,7 @@ func NewModuleServiceClient(cc grpc.ClientConnInterface) ModuleServiceClient { func (c *moduleServiceClient) ListModules(ctx context.Context, in *ListModulesRequest, opts ...grpc.CallOption) (*ListModulesResponse, error) { out := new(ListModulesResponse) - err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ModuleService/ListModules", in, out, opts...) + err := c.cc.Invoke(ctx, ModuleService_ListModules_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -44,7 +56,7 @@ func (c *moduleServiceClient) ListModules(ctx context.Context, in *ListModulesRe func (c *moduleServiceClient) GetModule(ctx context.Context, in *GetModuleRequest, opts ...grpc.CallOption) (*GetModuleResponse, error) { out := new(GetModuleResponse) - err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ModuleService/GetModule", in, out, opts...) + err := c.cc.Invoke(ctx, ModuleService_GetModule_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -53,7 +65,7 @@ func (c *moduleServiceClient) GetModule(ctx context.Context, in *GetModuleReques func (c *moduleServiceClient) CreateModule(ctx context.Context, in *CreateModuleRequest, opts ...grpc.CallOption) (*CreateModuleResponse, error) { out := new(CreateModuleResponse) - err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ModuleService/CreateModule", in, out, opts...) + err := c.cc.Invoke(ctx, ModuleService_CreateModule_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -62,7 +74,7 @@ func (c *moduleServiceClient) CreateModule(ctx context.Context, in *CreateModule func (c *moduleServiceClient) UpdateModule(ctx context.Context, in *UpdateModuleRequest, opts ...grpc.CallOption) (*UpdateModuleResponse, error) { out := new(UpdateModuleResponse) - err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ModuleService/UpdateModule", in, out, opts...) + err := c.cc.Invoke(ctx, ModuleService_UpdateModule_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -71,7 +83,7 @@ func (c *moduleServiceClient) UpdateModule(ctx context.Context, in *UpdateModule func (c *moduleServiceClient) DeleteModule(ctx context.Context, in *DeleteModuleRequest, opts ...grpc.CallOption) (*DeleteModuleResponse, error) { out := new(DeleteModuleResponse) - err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ModuleService/DeleteModule", in, out, opts...) + err := c.cc.Invoke(ctx, ModuleService_DeleteModule_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -132,7 +144,7 @@ func _ModuleService_ListModules_Handler(srv interface{}, ctx context.Context, de } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/gotocompany.entropy.v1beta1.ModuleService/ListModules", + FullMethod: ModuleService_ListModules_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ModuleServiceServer).ListModules(ctx, req.(*ListModulesRequest)) @@ -150,7 +162,7 @@ func _ModuleService_GetModule_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/gotocompany.entropy.v1beta1.ModuleService/GetModule", + FullMethod: ModuleService_GetModule_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ModuleServiceServer).GetModule(ctx, req.(*GetModuleRequest)) @@ -168,7 +180,7 @@ func _ModuleService_CreateModule_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/gotocompany.entropy.v1beta1.ModuleService/CreateModule", + FullMethod: ModuleService_CreateModule_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ModuleServiceServer).CreateModule(ctx, req.(*CreateModuleRequest)) @@ -186,7 +198,7 @@ func _ModuleService_UpdateModule_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/gotocompany.entropy.v1beta1.ModuleService/UpdateModule", + FullMethod: ModuleService_UpdateModule_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ModuleServiceServer).UpdateModule(ctx, req.(*UpdateModuleRequest)) @@ -204,7 +216,7 @@ func _ModuleService_DeleteModule_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/gotocompany.entropy.v1beta1.ModuleService/DeleteModule", + FullMethod: ModuleService_DeleteModule_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ModuleServiceServer).DeleteModule(ctx, req.(*DeleteModuleRequest)) diff --git a/proto/gotocompany/entropy/v1beta1/resource.pb.go b/proto/gotocompany/entropy/v1beta1/resource.pb.go index d691250b..a452e6b5 100644 --- a/proto/gotocompany/entropy/v1beta1/resource.pb.go +++ b/proto/gotocompany/entropy/v1beta1/resource.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.27.1 +// protoc-gen-go v1.30.0 // protoc (unknown) // source: gotocompany/entropy/v1beta1/resource.proto @@ -399,6 +399,8 @@ type Resource struct { UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` Spec *ResourceSpec `protobuf:"bytes,8,opt,name=spec,proto3" json:"spec,omitempty"` State *ResourceState `protobuf:"bytes,9,opt,name=state,proto3" json:"state,omitempty"` + CreatedBy string `protobuf:"bytes,10,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` + UpdatedBy string `protobuf:"bytes,11,opt,name=updated_by,json=updatedBy,proto3" json:"updated_by,omitempty"` } func (x *Resource) Reset() { @@ -496,6 +498,20 @@ func (x *Resource) GetState() *ResourceState { return nil } +func (x *Resource) GetCreatedBy() string { + if x != nil { + return x.CreatedBy + } + return "" +} + +func (x *Resource) GetUpdatedBy() string { + if x != nil { + return x.UpdatedBy + } + return "" +} + type ListResourcesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1277,6 +1293,7 @@ type ResourceRevision struct { CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` Spec *ResourceSpec `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` Reason string `protobuf:"bytes,6,opt,name=reason,proto3" json:"reason,omitempty"` + CreatedBy string `protobuf:"bytes,7,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` } func (x *ResourceRevision) Reset() { @@ -1353,6 +1370,13 @@ func (x *ResourceRevision) GetReason() string { return "" } +func (x *ResourceRevision) GetCreatedBy() string { + if x != nil { + return x.CreatedBy + } + return "" +} + type GetResourceRevisionsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1519,7 +1543,7 @@ var file_gotocompany_entropy_v1beta1_resource_proto_rawDesc = []byte{ 0x0c, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x43, 0x4f, - 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x04, 0x22, 0xdb, 0x03, 0x0a, 0x08, 0x52, 0x65, + 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x04, 0x22, 0x99, 0x04, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, @@ -1545,245 +1569,251 @@ var file_gotocompany_entropy_v1beta1_resource_proto_rawDesc = []byte{ 0x61, 0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x39, 0x0a, 0x0b, - 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd6, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, - 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x55, - 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, - 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, - 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0x5c, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x09, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd6, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x55, 0x0a, 0x06, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, - 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x26, - 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x22, 0x58, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, - 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, - 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x22, 0x5a, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, - 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x5b, 0x0a, 0x16, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, - 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x82, 0x02, 0x0a, 0x15, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x44, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x70, 0x65, - 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, - 0x65, 0x63, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x53, 0x70, 0x65, 0x63, 0x12, 0x56, 0x0a, 0x06, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x67, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, - 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5b, - 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5c, + 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x29, 0x0a, 0x15, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0xfe, 0x01, 0x0a, 0x12, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x2e, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x12, 0x53, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x3b, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, - 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x58, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x08, - 0x4c, 0x6f, 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x49, 0x0a, 0x06, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, - 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x43, 0x68, - 0x75, 0x6e, 0x6b, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0xac, 0x01, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x4e, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, + 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x26, 0x0a, 0x12, + 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x75, 0x72, 0x6e, 0x22, 0x58, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, + 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, + 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x5a, + 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x5b, 0x0a, 0x16, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x39, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x4d, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, - 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x4c, 0x6f, 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, - 0x22, 0xd4, 0x02, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x51, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3d, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, - 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, - 0x73, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x1a, 0x39, 0x0a, 0x0b, - 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2f, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x22, 0x6b, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x09, 0x72, 0x65, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, - 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x72, 0x65, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x32, 0x91, 0x0a, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x92, 0x01, 0x0a, 0x0d, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x67, 0x6f, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x82, 0x02, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x75, 0x72, 0x6e, 0x12, 0x44, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, + 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, + 0x52, 0x07, 0x6e, 0x65, 0x77, 0x53, 0x70, 0x65, 0x63, 0x12, 0x56, 0x0a, 0x06, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x67, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5b, 0x0a, 0x16, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x29, 0x0a, 0x15, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x75, 0x72, 0x6e, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfe, + 0x01, 0x0a, 0x12, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x2e, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, + 0x53, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x3b, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, + 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, + 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x58, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x08, 0x4c, 0x6f, + 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x49, 0x0a, 0x06, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x67, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x43, 0x68, 0x75, 0x6e, + 0x6b, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0xac, 0x01, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x75, 0x72, 0x6e, 0x12, 0x4e, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x39, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x4d, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, + 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, + 0x6f, 0x67, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x05, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x22, 0xf3, + 0x02, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x51, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, + 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x41, 0x74, 0x12, 0x3d, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, + 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, + 0x65, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2f, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x72, 0x6e, 0x22, 0x6b, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x09, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x32, 0x91, 0x0a, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x92, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, - 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, - 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x92, - 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2f, - 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, - 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x30, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, - 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x92, 0x01, 0x0a, 0x0b, + 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2f, 0x2e, 0x67, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, + 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x67, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, + 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, + 0x12, 0x9f, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, + 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x12, + 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x12, 0x9e, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, + 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x67, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x32, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, - 0x72, 0x6e, 0x7d, 0x12, 0x9f, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x72, 0x6e, 0x7d, 0x12, 0x9b, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x9e, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x67, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, - 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x32, 0x18, 0x2f, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x12, 0x9b, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x2e, 0x67, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, - 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, - 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, 0x18, 0x2f, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, - 0x75, 0x72, 0x6e, 0x7d, 0x12, 0xab, 0x01, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, - 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, - 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x3a, - 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x29, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, - 0x7d, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x7d, 0x12, 0x8a, 0x01, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x12, 0x2a, 0x2e, - 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, - 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, - 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x67, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, - 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x30, 0x01, 0x12, - 0xb7, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, - 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, + 0x7d, 0x12, 0xab, 0x01, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x2f, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, + 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, + 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x3a, 0x06, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x22, 0x29, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x2f, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x12, + 0x8a, 0x01, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x12, 0x2a, 0x2e, 0x67, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, + 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x30, 0x01, 0x12, 0xb7, 0x01, 0x0a, + 0x14, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, + 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x39, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x65, 0x6e, + 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x24, 0x12, 0x22, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x2f, 0x72, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x77, 0x0a, 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x75, 0x72, 0x6e, 0x7d, 0x2f, - 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x77, 0x0a, 0x26, 0x63, 0x6f, 0x6d, - 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x6e, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x42, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x6e, 0x2f, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2f, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x3b, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x42, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, + 0x2f, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x3b, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/gotocompany/entropy/v1beta1/resource.pb.gw.go b/proto/gotocompany/entropy/v1beta1/resource.pb.gw.go index 99e32e79..3f28d8ed 100644 --- a/proto/gotocompany/entropy/v1beta1/resource.pb.gw.go +++ b/proto/gotocompany/entropy/v1beta1/resource.pb.gw.go @@ -274,7 +274,7 @@ func local_request_ResourceService_DeleteResource_0(ctx context.Context, marshal } var ( - filter_ResourceService_ApplyAction_0 = &utilities.DoubleArray{Encoding: map[string]int{"params": 0, "urn": 1, "action": 2}, Base: []int{1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 2, 3, 4}} + filter_ResourceService_ApplyAction_0 = &utilities.DoubleArray{Encoding: map[string]int{"params": 0, "urn": 1, "action": 2}, Base: []int{1, 2, 4, 6, 0, 0, 0, 0, 0, 0}, Check: []int{0, 1, 1, 1, 2, 2, 3, 3, 4, 4}} ) func request_ResourceService_ApplyAction_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -380,7 +380,7 @@ func local_request_ResourceService_ApplyAction_0(ctx context.Context, marshaler } var ( - filter_ResourceService_GetLog_0 = &utilities.DoubleArray{Encoding: map[string]int{"urn": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} + filter_ResourceService_GetLog_0 = &utilities.DoubleArray{Encoding: map[string]int{"urn": 0}, Base: []int{1, 2, 0, 0}, Check: []int{0, 1, 2, 2}} ) func request_ResourceService_GetLog_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (ResourceService_GetLogClient, runtime.ServerMetadata, error) { @@ -670,7 +670,7 @@ func RegisterResourceServiceHandlerServer(ctx context.Context, mux *runtime.Serv // RegisterResourceServiceHandlerFromEndpoint is same as RegisterResourceServiceHandler but // automatically dials to "endpoint" and closes the connection when "ctx" gets done. func RegisterResourceServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) + conn, err := grpc.DialContext(ctx, endpoint, opts...) if err != nil { return err } diff --git a/proto/gotocompany/entropy/v1beta1/resource.pb.validate.go b/proto/gotocompany/entropy/v1beta1/resource.pb.validate.go index 3fce543e..b765d778 100644 --- a/proto/gotocompany/entropy/v1beta1/resource.pb.validate.go +++ b/proto/gotocompany/entropy/v1beta1/resource.pb.validate.go @@ -64,6 +64,7 @@ func (m *ResourceDependency) validate(all bool) error { if len(errors) > 0 { return ResourceDependencyMultiError(errors) } + return nil } @@ -228,6 +229,7 @@ func (m *ResourceSpec) validate(all bool) error { if len(errors) > 0 { return ResourceSpecMultiError(errors) } + return nil } @@ -326,6 +328,7 @@ func (m *ListString) validate(all bool) error { if len(errors) > 0 { return ListStringMultiError(errors) } + return nil } @@ -470,6 +473,7 @@ func (m *LogOptions) validate(all bool) error { if len(errors) > 0 { return LogOptionsMultiError(errors) } + return nil } @@ -663,6 +667,7 @@ func (m *ResourceState) validate(all bool) error { if len(errors) > 0 { return ResourceStateMultiError(errors) } + return nil } @@ -885,9 +890,14 @@ func (m *Resource) validate(all bool) error { } } + // no validation rules for CreatedBy + + // no validation rules for UpdatedBy + if len(errors) > 0 { return ResourceMultiError(errors) } + return nil } @@ -992,6 +1002,7 @@ func (m *ListResourcesRequest) validate(all bool) error { if len(errors) > 0 { return ListResourcesRequestMultiError(errors) } + return nil } @@ -1127,6 +1138,7 @@ func (m *ListResourcesResponse) validate(all bool) error { if len(errors) > 0 { return ListResourcesResponseMultiError(errors) } + return nil } @@ -1230,6 +1242,7 @@ func (m *GetResourceRequest) validate(all bool) error { if len(errors) > 0 { return GetResourceRequestMultiError(errors) } + return nil } @@ -1360,6 +1373,7 @@ func (m *GetResourceResponse) validate(all bool) error { if len(errors) > 0 { return GetResourceResponseMultiError(errors) } + return nil } @@ -1490,6 +1504,7 @@ func (m *CreateResourceRequest) validate(all bool) error { if len(errors) > 0 { return CreateResourceRequestMultiError(errors) } + return nil } @@ -1620,6 +1635,7 @@ func (m *CreateResourceResponse) validate(all bool) error { if len(errors) > 0 { return CreateResourceResponseMultiError(errors) } + return nil } @@ -1754,6 +1770,7 @@ func (m *UpdateResourceRequest) validate(all bool) error { if len(errors) > 0 { return UpdateResourceRequestMultiError(errors) } + return nil } @@ -1884,6 +1901,7 @@ func (m *UpdateResourceResponse) validate(all bool) error { if len(errors) > 0 { return UpdateResourceResponseMultiError(errors) } + return nil } @@ -1987,6 +2005,7 @@ func (m *DeleteResourceRequest) validate(all bool) error { if len(errors) > 0 { return DeleteResourceRequestMultiError(errors) } + return nil } @@ -2088,6 +2107,7 @@ func (m *DeleteResourceResponse) validate(all bool) error { if len(errors) > 0 { return DeleteResourceResponseMultiError(errors) } + return nil } @@ -2224,6 +2244,7 @@ func (m *ApplyActionRequest) validate(all bool) error { if len(errors) > 0 { return ApplyActionRequestMultiError(errors) } + return nil } @@ -2354,6 +2375,7 @@ func (m *ApplyActionResponse) validate(all bool) error { if len(errors) > 0 { return ApplyActionResponseMultiError(errors) } + return nil } @@ -2459,6 +2481,7 @@ func (m *LogChunk) validate(all bool) error { if len(errors) > 0 { return LogChunkMultiError(errors) } + return nil } @@ -2561,6 +2584,7 @@ func (m *GetLogRequest) validate(all bool) error { if len(errors) > 0 { return GetLogRequestMultiError(errors) } + return nil } @@ -2689,6 +2713,7 @@ func (m *GetLogResponse) validate(all bool) error { if len(errors) > 0 { return GetLogResponseMultiError(errors) } + return nil } @@ -2851,9 +2876,12 @@ func (m *ResourceRevision) validate(all bool) error { // no validation rules for Reason + // no validation rules for CreatedBy + if len(errors) > 0 { return ResourceRevisionMultiError(errors) } + return nil } @@ -2955,6 +2983,7 @@ func (m *GetResourceRevisionsRequest) validate(all bool) error { if len(errors) > 0 { return GetResourceRevisionsRequestMultiError(errors) } + return nil } @@ -3091,6 +3120,7 @@ func (m *GetResourceRevisionsResponse) validate(all bool) error { if len(errors) > 0 { return GetResourceRevisionsResponseMultiError(errors) } + return nil } diff --git a/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go b/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go index 4bb55330..2520fddc 100644 --- a/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go +++ b/proto/gotocompany/entropy/v1beta1/resource_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: gotocompany/entropy/v1beta1/resource.proto package entropyv1beta1 @@ -14,6 +18,17 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + ResourceService_ListResources_FullMethodName = "/gotocompany.entropy.v1beta1.ResourceService/ListResources" + ResourceService_GetResource_FullMethodName = "/gotocompany.entropy.v1beta1.ResourceService/GetResource" + ResourceService_CreateResource_FullMethodName = "/gotocompany.entropy.v1beta1.ResourceService/CreateResource" + ResourceService_UpdateResource_FullMethodName = "/gotocompany.entropy.v1beta1.ResourceService/UpdateResource" + ResourceService_DeleteResource_FullMethodName = "/gotocompany.entropy.v1beta1.ResourceService/DeleteResource" + ResourceService_ApplyAction_FullMethodName = "/gotocompany.entropy.v1beta1.ResourceService/ApplyAction" + ResourceService_GetLog_FullMethodName = "/gotocompany.entropy.v1beta1.ResourceService/GetLog" + ResourceService_GetResourceRevisions_FullMethodName = "/gotocompany.entropy.v1beta1.ResourceService/GetResourceRevisions" +) + // ResourceServiceClient is the client API for ResourceService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -38,7 +53,7 @@ func NewResourceServiceClient(cc grpc.ClientConnInterface) ResourceServiceClient func (c *resourceServiceClient) ListResources(ctx context.Context, in *ListResourcesRequest, opts ...grpc.CallOption) (*ListResourcesResponse, error) { out := new(ListResourcesResponse) - err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ResourceService/ListResources", in, out, opts...) + err := c.cc.Invoke(ctx, ResourceService_ListResources_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -47,7 +62,7 @@ func (c *resourceServiceClient) ListResources(ctx context.Context, in *ListResou func (c *resourceServiceClient) GetResource(ctx context.Context, in *GetResourceRequest, opts ...grpc.CallOption) (*GetResourceResponse, error) { out := new(GetResourceResponse) - err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ResourceService/GetResource", in, out, opts...) + err := c.cc.Invoke(ctx, ResourceService_GetResource_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -56,7 +71,7 @@ func (c *resourceServiceClient) GetResource(ctx context.Context, in *GetResource func (c *resourceServiceClient) CreateResource(ctx context.Context, in *CreateResourceRequest, opts ...grpc.CallOption) (*CreateResourceResponse, error) { out := new(CreateResourceResponse) - err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ResourceService/CreateResource", in, out, opts...) + err := c.cc.Invoke(ctx, ResourceService_CreateResource_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -65,7 +80,7 @@ func (c *resourceServiceClient) CreateResource(ctx context.Context, in *CreateRe func (c *resourceServiceClient) UpdateResource(ctx context.Context, in *UpdateResourceRequest, opts ...grpc.CallOption) (*UpdateResourceResponse, error) { out := new(UpdateResourceResponse) - err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ResourceService/UpdateResource", in, out, opts...) + err := c.cc.Invoke(ctx, ResourceService_UpdateResource_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -74,7 +89,7 @@ func (c *resourceServiceClient) UpdateResource(ctx context.Context, in *UpdateRe func (c *resourceServiceClient) DeleteResource(ctx context.Context, in *DeleteResourceRequest, opts ...grpc.CallOption) (*DeleteResourceResponse, error) { out := new(DeleteResourceResponse) - err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ResourceService/DeleteResource", in, out, opts...) + err := c.cc.Invoke(ctx, ResourceService_DeleteResource_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -83,7 +98,7 @@ func (c *resourceServiceClient) DeleteResource(ctx context.Context, in *DeleteRe func (c *resourceServiceClient) ApplyAction(ctx context.Context, in *ApplyActionRequest, opts ...grpc.CallOption) (*ApplyActionResponse, error) { out := new(ApplyActionResponse) - err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ResourceService/ApplyAction", in, out, opts...) + err := c.cc.Invoke(ctx, ResourceService_ApplyAction_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -91,7 +106,7 @@ func (c *resourceServiceClient) ApplyAction(ctx context.Context, in *ApplyAction } func (c *resourceServiceClient) GetLog(ctx context.Context, in *GetLogRequest, opts ...grpc.CallOption) (ResourceService_GetLogClient, error) { - stream, err := c.cc.NewStream(ctx, &ResourceService_ServiceDesc.Streams[0], "/gotocompany.entropy.v1beta1.ResourceService/GetLog", opts...) + stream, err := c.cc.NewStream(ctx, &ResourceService_ServiceDesc.Streams[0], ResourceService_GetLog_FullMethodName, opts...) if err != nil { return nil, err } @@ -124,7 +139,7 @@ func (x *resourceServiceGetLogClient) Recv() (*GetLogResponse, error) { func (c *resourceServiceClient) GetResourceRevisions(ctx context.Context, in *GetResourceRevisionsRequest, opts ...grpc.CallOption) (*GetResourceRevisionsResponse, error) { out := new(GetResourceRevisionsResponse) - err := c.cc.Invoke(ctx, "/gotocompany.entropy.v1beta1.ResourceService/GetResourceRevisions", in, out, opts...) + err := c.cc.Invoke(ctx, ResourceService_GetResourceRevisions_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -197,7 +212,7 @@ func _ResourceService_ListResources_Handler(srv interface{}, ctx context.Context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/gotocompany.entropy.v1beta1.ResourceService/ListResources", + FullMethod: ResourceService_ListResources_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ResourceServiceServer).ListResources(ctx, req.(*ListResourcesRequest)) @@ -215,7 +230,7 @@ func _ResourceService_GetResource_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/gotocompany.entropy.v1beta1.ResourceService/GetResource", + FullMethod: ResourceService_GetResource_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ResourceServiceServer).GetResource(ctx, req.(*GetResourceRequest)) @@ -233,7 +248,7 @@ func _ResourceService_CreateResource_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/gotocompany.entropy.v1beta1.ResourceService/CreateResource", + FullMethod: ResourceService_CreateResource_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ResourceServiceServer).CreateResource(ctx, req.(*CreateResourceRequest)) @@ -251,7 +266,7 @@ func _ResourceService_UpdateResource_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/gotocompany.entropy.v1beta1.ResourceService/UpdateResource", + FullMethod: ResourceService_UpdateResource_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ResourceServiceServer).UpdateResource(ctx, req.(*UpdateResourceRequest)) @@ -269,7 +284,7 @@ func _ResourceService_DeleteResource_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/gotocompany.entropy.v1beta1.ResourceService/DeleteResource", + FullMethod: ResourceService_DeleteResource_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ResourceServiceServer).DeleteResource(ctx, req.(*DeleteResourceRequest)) @@ -287,7 +302,7 @@ func _ResourceService_ApplyAction_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/gotocompany.entropy.v1beta1.ResourceService/ApplyAction", + FullMethod: ResourceService_ApplyAction_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ResourceServiceServer).ApplyAction(ctx, req.(*ApplyActionRequest)) @@ -326,7 +341,7 @@ func _ResourceService_GetResourceRevisions_Handler(srv interface{}, ctx context. } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/gotocompany.entropy.v1beta1.ResourceService/GetResourceRevisions", + FullMethod: ResourceService_GetResourceRevisions_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ResourceServiceServer).GetResourceRevisions(ctx, req.(*GetResourceRevisionsRequest)) From 178e82c958cfff42e1ffb5fdd9937d1761598e9b Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Thu, 27 Jul 2023 16:05:17 +0530 Subject: [PATCH 51/72] feat: broaden AdditionalGlobalTags scope (#50) - AdditionalGlobalTags to take values from all env_variables and labels --- modules/firehose/driver.go | 45 +++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index b6bfb301..78cf658e 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -171,8 +171,30 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, kubeOut kubernetes.Output, ) (*helm.ReleaseConfig, error) { var telegrafConf Telegraf + + entropyLabels := map[string]string{ + labelDeployment: conf.DeploymentID, + labelOrchestrator: orchestratorLabelValue, + } + + otherLabels := map[string]string{ + labelURN: res.URN, + } + + deploymentLabels, err := renderTpl(fd.conf.Labels, cloneAndMergeMaps(res.Labels, entropyLabels)) + if err != nil { + return nil, err + } + if conf.Telegraf != nil && conf.Telegraf.Enabled { - telegrafTags, err := renderTpl(conf.Telegraf.Config.AdditionalGlobalTags, res.Labels) + mergedLabelsAndEnvVariablesMap := cloneAndMergeMaps(cloneAndMergeMaps(conf.EnvVariables, cloneAndMergeMaps(deploymentLabels, cloneAndMergeMaps(res.Labels, entropyLabels))), otherLabels) + + conf.EnvVariables, err = renderTpl(conf.EnvVariables, mergedLabelsAndEnvVariablesMap) + if err != nil { + return nil, err + } + + telegrafTags, err := renderTpl(conf.Telegraf.Config.AdditionalGlobalTags, mergedLabelsAndEnvVariablesMap) if err != nil { return nil, err } @@ -198,20 +220,6 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, }) } - entropyLabels := map[string]string{ - labelDeployment: conf.DeploymentID, - labelOrchestrator: orchestratorLabelValue, - } - - otherLabels := map[string]string{ - labelURN: res.URN, - } - - deploymentLabels, err := renderTpl(fd.conf.Labels, cloneAndMergeMaps(res.Labels, entropyLabels)) - if err != nil { - return nil, err - } - var secretsAsVolumes []map[string]any var volumeMounts []map[string]any var requiredDuringSchedulingIgnoredDuringExecution []Preference @@ -266,13 +274,6 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, conf.EnvVariables["SINK_BIGQUERY_CREDENTIAL_PATH"] = credentialPath } - if telegrafConf.Enabled { - conf.EnvVariables, err = renderTpl(conf.EnvVariables, cloneAndMergeMaps(cloneAndMergeMaps(conf.EnvVariables, cloneAndMergeMaps(deploymentLabels, cloneAndMergeMaps(res.Labels, entropyLabels))), otherLabels)) - if err != nil { - return nil, err - } - } - rc := helm.DefaultReleaseConfig() rc.Name = conf.DeploymentID rc.Repository = chartRepo From aac1e7f40cc2253c7690850f109cda6c144ee4fa Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Fri, 28 Jul 2023 16:53:06 +0530 Subject: [PATCH 52/72] fix: initialize as empty arrays (#51) - secretsAsVolumes, volumeMounts, requiredDuringSchedulingIgnoredDuringExecution, preferredDuringSchedulingIgnoredDuringExecution initialize as empty arrays --- modules/firehose/driver.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 78cf658e..1ba69637 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -210,7 +210,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, } tolerationKey := fmt.Sprintf("firehose_%s", conf.EnvVariables["SINK_TYPE"]) - var tolerations []map[string]any + var tolerations = []map[string]any{} for _, t := range kubeOut.Tolerations[tolerationKey] { tolerations = append(tolerations, map[string]any{ "key": t.Key, @@ -220,13 +220,17 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, }) } - var secretsAsVolumes []map[string]any - var volumeMounts []map[string]any - var requiredDuringSchedulingIgnoredDuringExecution []Preference - var preferredDuringSchedulingIgnoredDuringExecution []WeightedPreference + var secretsAsVolumes = []map[string]any{} + var volumeMounts = []map[string]any{} + var requiredDuringSchedulingIgnoredDuringExecution = []Preference{} + var preferredDuringSchedulingIgnoredDuringExecution = []WeightedPreference{} - requiredDuringSchedulingIgnoredDuringExecution = fd.conf.NodeAffinityMatchExpressions.RequiredDuringSchedulingIgnoredDuringExecution - preferredDuringSchedulingIgnoredDuringExecution = fd.conf.NodeAffinityMatchExpressions.PreferredDuringSchedulingIgnoredDuringExecution + if fd.conf.NodeAffinityMatchExpressions.RequiredDuringSchedulingIgnoredDuringExecution != nil { + requiredDuringSchedulingIgnoredDuringExecution = fd.conf.NodeAffinityMatchExpressions.RequiredDuringSchedulingIgnoredDuringExecution + } + if fd.conf.NodeAffinityMatchExpressions.PreferredDuringSchedulingIgnoredDuringExecution != nil { + preferredDuringSchedulingIgnoredDuringExecution = fd.conf.NodeAffinityMatchExpressions.PreferredDuringSchedulingIgnoredDuringExecution + } newVolume := func(name string) map[string]any { const mountMode = 420 From 0cb3d281bf7f20f15f3669be595cda07fc0df79e Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Mon, 31 Jul 2023 13:07:25 +0530 Subject: [PATCH 53/72] feat: firehose update to take the latest driver configs (#52) * feat: firehose update to take the latest telegraf values from module * feat: init-container configs to be updated on edit * test: fix driver tests --- modules/firehose/config.go | 9 +++++---- modules/firehose/driver_plan.go | 3 ++- modules/firehose/driver_plan_test.go | 7 ++++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index 8e1a0a29..ad73908d 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -61,10 +61,11 @@ type Config struct { // ResetOffset represents the value to which kafka consumer offset was set to ResetOffset string `json:"reset_offset,omitempty"` - Limits UsageSpec `json:"limits,omitempty"` - Requests UsageSpec `json:"requests,omitempty"` - Telegraf *Telegraf `json:"telegraf,omitempty"` - ChartValues *ChartValues `json:"chart_values,omitempty"` + Limits UsageSpec `json:"limits,omitempty"` + Requests UsageSpec `json:"requests,omitempty"` + Telegraf *Telegraf `json:"telegraf,omitempty"` + ChartValues *ChartValues `json:"chart_values,omitempty"` + InitContainer InitContainer `json:"init_container,omitempty"` } type Telegraf struct { diff --git a/modules/firehose/driver_plan.go b/modules/firehose/driver_plan.go index b2b160a8..3b0b5338 100644 --- a/modules/firehose/driver_plan.go +++ b/modules/firehose/driver_plan.go @@ -45,7 +45,8 @@ func (fd *firehoseDriver) planChange(exr module.ExpandedResource, act module.Act newConf.DeploymentID = curConf.DeploymentID newConf.ChartValues = chartVals newConf.Namespace = curConf.Namespace - newConf.Telegraf = curConf.Telegraf + newConf.Telegraf = fd.conf.Telegraf + newConf.InitContainer = fd.conf.InitContainer curConf = newConf diff --git a/modules/firehose/driver_plan_test.go b/modules/firehose/driver_plan_test.go index fcb8b8ab..c984979f 100644 --- a/modules/firehose/driver_plan_test.go +++ b/modules/firehose/driver_plan_test.go @@ -97,6 +97,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { "SOURCE_KAFKA_BROKERS": "localhost:9092", "SOURCE_KAFKA_TOPIC": "foo-log", }, + "init_container": map[string]interface{}{"args": interface{}(nil), "command": interface{}(nil), "enabled": false, "image_tag": "", "pull_policy": "", "repository": ""}, }), }, State: resource.State{ @@ -167,6 +168,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { "SOURCE_KAFKA_BROKERS": "localhost:9092", "SOURCE_KAFKA_TOPIC": "foo-log", }, + "init_container": map[string]interface{}{"args": interface{}(nil), "command": interface{}(nil), "enabled": false, "image_tag": "", "pull_policy": "", "repository": ""}, }), }, State: resource.State{ @@ -252,6 +254,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { "cpu": "200m", "memory": "512Mi", }, + "init_container": map[string]interface{}{"args": interface{}(nil), "command": interface{}(nil), "enabled": false, "image_tag": "", "pull_policy": "", "repository": ""}, }), }, State: resource.State{ @@ -377,7 +380,8 @@ func TestFirehoseDriver_Plan(t *testing.T) { "cpu": "200m", "memory": "512Mi", }, - "stopped": false, + "stopped": false, + "init_container": map[string]interface{}{"args": interface{}(nil), "command": interface{}(nil), "enabled": false, "image_tag": "", "pull_policy": "", "repository": ""}, }), }, State: resource.State{ @@ -469,6 +473,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { "SOURCE_KAFKA_BROKERS": "localhost:9092", "SOURCE_KAFKA_TOPIC": "foo-log", }, + "init_container": map[string]interface{}{"args": interface{}(nil), "command": interface{}(nil), "enabled": false, "image_tag": "", "pull_policy": "", "repository": ""}, }), }, State: resource.State{ From b66407dee5e99dc6dc0f8b6e4d265451ccf86bb8 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Mon, 7 Aug 2023 14:15:45 +0530 Subject: [PATCH 54/72] fix: update stopped status (#53) dquote> - if the stoptime is in past, stopped flag value shall be updated to true as well --- modules/firehose/driver_sync.go | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/firehose/driver_sync.go b/modules/firehose/driver_sync.go index 035e94be..bbd61df9 100644 --- a/modules/firehose/driver_sync.go +++ b/modules/firehose/driver_sync.go @@ -78,6 +78,7 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) finalState.NextSyncAt = conf.StopTime if conf.StopTime != nil && conf.StopTime.Before(fd.timeNow()) { conf.Replicas = 0 + conf.Stopped = true if err := fd.releaseSync(ctx, exr.Resource, false, *conf, kubeOut); err != nil { return nil, err } From 01dc9fe1ca7e4444a8c3ec9df618c5f7cace57bb Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Wed, 16 Aug 2023 12:33:21 +0530 Subject: [PATCH 55/72] feat: add logging request body (#54) * feat: add logging request body * fix: avoid returning err in requestLogger * feat: avoid logging /ping path --- internal/server/middlewares.go | 43 +++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/internal/server/middlewares.go b/internal/server/middlewares.go index b65015e4..2930c4cb 100644 --- a/internal/server/middlewares.go +++ b/internal/server/middlewares.go @@ -1,7 +1,10 @@ package server import ( + "bytes" + "encoding/json" "fmt" + "io" "net/http" "strings" "time" @@ -85,23 +88,47 @@ func requestLogger(lg *zap.Logger) gorillamux.MiddlewareFunc { span := trace.FromContext(req.Context()) clientID, _, _ := req.BasicAuth() + + wrapped := &wrappedWriter{ + Status: http.StatusOK, + ResponseWriter: wr, + } + next.ServeHTTP(wrapped, req) + + if req.URL.Path == "/ping" { + return + } + fields := []zap.Field{ zap.String("path", req.URL.Path), zap.String("method", req.Method), zap.String("request_id", req.Header.Get(headerRequestID)), zap.String("client_id", clientID), zap.String("trace_id", span.SpanContext().TraceID.String()), + zap.Duration("response_time", time.Since(t)), + zap.Int("status", wrapped.Status), } - wrapped := &wrappedWriter{ - Status: http.StatusOK, - ResponseWriter: wr, + switch req.Method { + case http.MethodGet: + break + default: + buf, err := io.ReadAll(req.Body) + if err != nil { + lg.Debug("error reading request body: %v", zap.String("error", err.Error())) + } else if len(buf) > 0 { + dst := &bytes.Buffer{} + err := json.Compact(dst, buf) + if err != nil { + lg.Debug("error json compacting request body: %v", zap.String("error", err.Error())) + } else { + fields = append(fields, zap.String("request_body", dst.String())) + } + } + + reader := io.NopCloser(bytes.NewBuffer(buf)) + req.Body = reader } - next.ServeHTTP(wrapped, req) - fields = append(fields, - zap.Duration("response_time", time.Since(t)), - zap.Int("status", wrapped.Status), - ) if !is2xx(wrapped.Status) { lg.Warn("request handled with non-2xx response", fields...) From b58f67f30435cb03c5df198ffd0fc038aaf3c451 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Mon, 21 Aug 2023 16:53:37 +0530 Subject: [PATCH 56/72] feat: mounts as secrets (#55) --- modules/firehose/driver.go | 42 ++++++++++++++------------------------ 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 1ba69637..2e1bb52e 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -220,8 +220,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, }) } - var secretsAsVolumes = []map[string]any{} - var volumeMounts = []map[string]any{} + var mountSecrets = []map[string]any{} var requiredDuringSchedulingIgnoredDuringExecution = []Preference{} var preferredDuringSchedulingIgnoredDuringExecution = []WeightedPreference{} @@ -232,24 +231,14 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, preferredDuringSchedulingIgnoredDuringExecution = fd.conf.NodeAffinityMatchExpressions.PreferredDuringSchedulingIgnoredDuringExecution } - newVolume := func(name string) map[string]any { - const mountMode = 420 - return map[string]any{ - "name": name, - "items": []map[string]any{{"key": "token", "path": "auth.json"}}, - "secretName": name, - "defaultMode": mountMode, - } - } - if fd.conf.GCSSinkCredential != "" { const mountPath = "/etc/secret/blob-gcs-sink" const credentialPath = mountPath + "/auth.json" - secretsAsVolumes = append(secretsAsVolumes, newVolume(fd.conf.GCSSinkCredential)) - volumeMounts = append(volumeMounts, map[string]any{ - "name": fd.conf.GCSSinkCredential, - "mountPath": mountPath, + mountSecrets = append(mountSecrets, map[string]any{ + "value": fd.conf.GCSSinkCredential, + "key": "token", + "path": mountPath, }) conf.EnvVariables["SINK_BLOB_GCS_CREDENTIAL_PATH"] = credentialPath } @@ -258,10 +247,10 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, const mountPath = "/etc/secret/dlq-gcs" const credentialPath = mountPath + "/auth.json" - secretsAsVolumes = append(secretsAsVolumes, newVolume(fd.conf.DLQGCSSinkCredential)) - volumeMounts = append(volumeMounts, map[string]any{ - "name": fd.conf.DLQGCSSinkCredential, - "mountPath": mountPath, + mountSecrets = append(mountSecrets, map[string]any{ + "value": fd.conf.DLQGCSSinkCredential, + "key": "token", + "path": mountPath, }) conf.EnvVariables["DLQ_GCS_CREDENTIAL_PATH"] = credentialPath } @@ -270,10 +259,10 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, const mountPath = "/etc/secret/bigquery-sink" const credentialPath = mountPath + "/auth.json" - secretsAsVolumes = append(secretsAsVolumes, newVolume(fd.conf.BigQuerySinkCredential)) - volumeMounts = append(volumeMounts, map[string]any{ - "name": fd.conf.BigQuerySinkCredential, - "mountPath": mountPath, + mountSecrets = append(mountSecrets, map[string]any{ + "value": fd.conf.BigQuerySinkCredential, + "key": "token", + "path": mountPath, }) conf.EnvVariables["SINK_BIGQUERY_CREDENTIAL_PATH"] = credentialPath } @@ -305,10 +294,8 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, "memory": conf.Requests.Memory, }, }, - "volumeMounts": volumeMounts, }, - "secretsAsVolumes": secretsAsVolumes, - "tolerations": tolerations, + "tolerations": tolerations, "nodeAffinityMatchExpressions": map[string]any{ "requiredDuringSchedulingIgnoredDuringExecution": requiredDuringSchedulingIgnoredDuringExecution, "preferredDuringSchedulingIgnoredDuringExecution": preferredDuringSchedulingIgnoredDuringExecution, @@ -331,6 +318,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, "additional_global_tags": telegrafConf.Config.AdditionalGlobalTags, }, }, + "mountSecrets": mountSecrets, } return rc, nil From 43d59833972f5583381f3fd239ae3aa9718eb9d5 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Mon, 21 Aug 2023 18:50:43 +0530 Subject: [PATCH 57/72] fix: mount secrets (#56) fix: path and key --- modules/firehose/driver.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 2e1bb52e..61585969 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -232,39 +232,39 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, } if fd.conf.GCSSinkCredential != "" { - const mountPath = "/etc/secret/blob-gcs-sink" - const credentialPath = mountPath + "/auth.json" + const mountFile = "gcs_auth.json" + var credPath = fmt.Sprintf("/etc/secret/%s-mount-secrets/%s", conf.DeploymentID, mountFile) mountSecrets = append(mountSecrets, map[string]any{ "value": fd.conf.GCSSinkCredential, - "key": "token", - "path": mountPath, + "key": "gcs_credential", + "path": mountFile, }) - conf.EnvVariables["SINK_BLOB_GCS_CREDENTIAL_PATH"] = credentialPath + conf.EnvVariables["SINK_BLOB_GCS_CREDENTIAL_PATH"] = credPath } if fd.conf.DLQGCSSinkCredential != "" { - const mountPath = "/etc/secret/dlq-gcs" - const credentialPath = mountPath + "/auth.json" + const mountFile = "dlq_gcs_auth.json" + var credPath = fmt.Sprintf("/etc/secret/%s-mount-secrets/%s", conf.DeploymentID, mountFile) mountSecrets = append(mountSecrets, map[string]any{ "value": fd.conf.DLQGCSSinkCredential, - "key": "token", - "path": mountPath, + "key": "dlq_gcs_credential", + "path": mountFile, }) - conf.EnvVariables["DLQ_GCS_CREDENTIAL_PATH"] = credentialPath + conf.EnvVariables["DLQ_GCS_CREDENTIAL_PATH"] = credPath } if fd.conf.BigQuerySinkCredential != "" { - const mountPath = "/etc/secret/bigquery-sink" - const credentialPath = mountPath + "/auth.json" + const mountFile = "bigquery_auth.json" + var credPath = fmt.Sprintf("/etc/secret/%s-mount-secrets/%s", conf.DeploymentID, mountFile) mountSecrets = append(mountSecrets, map[string]any{ "value": fd.conf.BigQuerySinkCredential, - "key": "token", - "path": mountPath, + "key": "bigquery_credential", + "path": mountFile, }) - conf.EnvVariables["SINK_BIGQUERY_CREDENTIAL_PATH"] = credentialPath + conf.EnvVariables["DLQ_GCS_CREDENTIAL_PATH"] = credPath } rc := helm.DefaultReleaseConfig() From 63bc82b8dd9ba9f74ce7afc83bf056f64f063324 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Mon, 21 Aug 2023 20:21:04 +0530 Subject: [PATCH 58/72] fix: key name (#57) --- modules/firehose/driver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 61585969..0d431698 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -264,7 +264,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, "key": "bigquery_credential", "path": mountFile, }) - conf.EnvVariables["DLQ_GCS_CREDENTIAL_PATH"] = credPath + conf.EnvVariables["SINK_BIGQUERY_CREDENTIAL_PATH"] = credPath } rc := helm.DefaultReleaseConfig() From 198c6611cfa03a609e1e0eeee23537b5fc99631e Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Thu, 24 Aug 2023 13:26:34 +0530 Subject: [PATCH 59/72] fix: add bigtable cred path (#58) --- modules/firehose/driver.go | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 0d431698..4adacb30 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -241,6 +241,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, "path": mountFile, }) conf.EnvVariables["SINK_BLOB_GCS_CREDENTIAL_PATH"] = credPath + conf.EnvVariables["SINK_BIGTABLE_CREDENTIAL_PATH"] = credPath } if fd.conf.DLQGCSSinkCredential != "" { From e0da338ec104e85caa55f9b1834a654f972dc4a1 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Thu, 24 Aug 2023 15:56:32 +0530 Subject: [PATCH 60/72] fix: remove skipping empty values for env variables (#59) * fix: remove skipping empty values for env variables * fix: lint issue --- modules/firehose/driver.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 4adacb30..f1310f83 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -340,10 +340,11 @@ func renderTpl(labelsTpl map[string]string, labelsValues map[string]string) (map WithMsgf("failed to render label template").WithCausef(err.Error()) } - labelVal := strings.TrimSpace(buf.String()) - if labelVal == "" { - continue - } + // allow empty values + // labelVal := strings.TrimSpace(buf.String()) + // if labelVal == "" { + // continue + // } finalLabels[k] = buf.String() } From bc5e389f5749976e09d781a3a0982d99b963750a Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Mon, 28 Aug 2023 14:54:28 +0530 Subject: [PATCH 61/72] fix: mount path to be independent of dep id (#60) fix: mount path to be independent of dep id" --- modules/firehose/driver.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index f1310f83..5f168290 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -233,7 +233,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, if fd.conf.GCSSinkCredential != "" { const mountFile = "gcs_auth.json" - var credPath = fmt.Sprintf("/etc/secret/%s-mount-secrets/%s", conf.DeploymentID, mountFile) + var credPath = fmt.Sprintf("/etc/secret/%s", mountFile) mountSecrets = append(mountSecrets, map[string]any{ "value": fd.conf.GCSSinkCredential, @@ -246,7 +246,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, if fd.conf.DLQGCSSinkCredential != "" { const mountFile = "dlq_gcs_auth.json" - var credPath = fmt.Sprintf("/etc/secret/%s-mount-secrets/%s", conf.DeploymentID, mountFile) + var credPath = fmt.Sprintf("/etc/secret/%s", mountFile) mountSecrets = append(mountSecrets, map[string]any{ "value": fd.conf.DLQGCSSinkCredential, @@ -258,7 +258,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, if fd.conf.BigQuerySinkCredential != "" { const mountFile = "bigquery_auth.json" - var credPath = fmt.Sprintf("/etc/secret/%s-mount-secrets/%s", conf.DeploymentID, mountFile) + var credPath = fmt.Sprintf("/etc/secret/%s", mountFile) mountSecrets = append(mountSecrets, map[string]any{ "value": fd.conf.BigQuerySinkCredential, From 4397eb2ace76f08a314e9c6693015d90615e043b Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Wed, 30 Aug 2023 15:53:29 +0530 Subject: [PATCH 62/72] feat: return only running & non-terminating pods (#61) - skip pods in output if they are not in running state or in pending state --- pkg/kube/client.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/kube/client.go b/pkg/kube/client.go index bd933e35..7812b73f 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -287,6 +287,11 @@ func (c Client) GetPodDetails(ctx context.Context, namespace string, labelSelect } for _, pod := range pods.Items { + // not listing pods that are not in running state or are about to terminate + if pod.Status.Phase != corev1.PodRunning || pod.DeletionTimestamp != nil { + continue + } + podDetail := Pod{ Name: pod.Name, } From 305fb4705cac95d15b90f372a1374b853ba01e8d Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Wed, 30 Aug 2023 16:21:06 +0530 Subject: [PATCH 63/72] feat: get resource to persist output (#62) - get call will persist the output to DB if it's changed --- core/read.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/read.go b/core/read.go index 3818264e..04fbfa92 100644 --- a/core/read.go +++ b/core/read.go @@ -1,6 +1,7 @@ package core import ( + "bytes" "context" "github.com/goto/entropy/core/module" @@ -27,7 +28,13 @@ func (svc *Service) GetResource(ctx context.Context, urn string) (*resource.Reso return nil, err } - res.State.Output = output + if !bytes.Equal(res.State.Output, output) { + res.State.Output = output + err = svc.store.Update(ctx, *res, false, "") + if err != nil { + return nil, err + } + } return res, nil } From f82209fdf51712d2ce4732fda6a8a19457375ebc Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Thu, 31 Aug 2023 13:49:59 +0530 Subject: [PATCH 64/72] feat: add name as extra label (#64) --- modules/firehose/driver.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 5f168290..eb016338 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -36,6 +36,7 @@ const ( labelDeployment = "deployment" labelOrchestrator = "orchestrator" labelURN = "urn" + labelName = "name" orchestratorLabelValue = "entropy" ) @@ -178,7 +179,8 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, } otherLabels := map[string]string{ - labelURN: res.URN, + labelURN: res.URN, + labelName: res.Name, } deploymentLabels, err := renderTpl(fd.conf.Labels, cloneAndMergeMaps(res.Labels, entropyLabels)) From 32547eff63cf66647df396f7e4e77be11414d19d Mon Sep 17 00:00:00 2001 From: Abduh Date: Mon, 4 Sep 2023 12:03:58 +0700 Subject: [PATCH 65/72] feat: support google service account for gke usage (#63) * feat: support google service account for gke usage * chore: bump up salt --- go.mod | 14 +++++--- go.sum | 28 +++++++++++----- modules/firehose/driver_log.go | 5 ++- modules/firehose/module.go | 11 ++++-- modules/kubernetes/driver.go | 7 +++- pkg/kube/client.go | 16 ++++++--- pkg/kube/config.go | 61 ++++++++++++++++++++++++++-------- 7 files changed, 106 insertions(+), 36 deletions(-) diff --git a/go.mod b/go.mod index 5b33f3f5..d08a1527 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/go-playground/validator/v10 v10.11.2 github.com/google/go-cmp v0.5.9 github.com/gorilla/mux v1.8.0 - github.com/goto/salt v0.3.0 + github.com/goto/salt v0.3.3 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 github.com/jmoiron/sqlx v1.3.5 @@ -28,8 +28,9 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 go.opencensus.io v0.24.0 go.uber.org/zap v1.21.0 - google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc - google.golang.org/grpc v1.49.0 + google.golang.org/api v0.103.0 + google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd + google.golang.org/grpc v1.50.1 google.golang.org/protobuf v1.28.1 gopkg.in/yaml.v2 v2.4.0 helm.sh/helm/v3 v3.9.0 @@ -162,7 +163,7 @@ require ( go.uber.org/multierr v1.8.0 // indirect golang.org/x/crypto v0.5.0 // indirect golang.org/x/net v0.5.0 // indirect - golang.org/x/oauth2 v0.4.0 // indirect + golang.org/x/oauth2 v0.4.0 golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.4.0 // indirect golang.org/x/term v0.4.0 // indirect @@ -189,6 +190,8 @@ require ( ) require ( + cloud.google.com/go/compute v1.14.0 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cli/safeexec v1.0.0 // indirect github.com/go-kit/log v0.1.0 // indirect @@ -196,8 +199,9 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect + github.com/googleapis/gax-go/v2 v2.7.0 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/newrelic/newrelic-telemetry-sdk-go v0.2.0 // indirect github.com/prometheus/statsd_exporter v0.21.0 // indirect - google.golang.org/api v0.98.0 // indirect ) diff --git a/go.sum b/go.sum index f08db965..d525c886 100644 --- a/go.sum +++ b/go.sum @@ -33,6 +33,7 @@ cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0c cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -45,10 +46,15 @@ cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6m cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.14.0 h1:hfm2+FfxVmnRlh6LpB7cg1ZNU+5edAHmW679JePztk0= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -762,7 +768,8 @@ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -770,6 +777,8 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0 github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +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/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= @@ -792,8 +801,8 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= -github.com/goto/salt v0.3.0 h1:7bFVqh6/zHfyImkrl2mYJHsFuGd2OBM/8rKs+giDpbc= -github.com/goto/salt v0.3.0/go.mod h1:L8PtSbpUFFo/Yh5YZ0FTgV9FIAvtqGdNa2BkA5M3jWo= +github.com/goto/salt v0.3.3 h1:lsUsY9VuwmzfB1B9ndJE6BI5vx4Z7pupIX4uP/LxDys= +github.com/goto/salt v0.3.3/go.mod h1:L8PtSbpUFFo/Yh5YZ0FTgV9FIAvtqGdNa2BkA5M3jWo= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -1692,7 +1701,6 @@ golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220919232410-f2f64ebce3c1/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= @@ -2005,6 +2013,7 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T 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= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= @@ -2054,8 +2063,8 @@ google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69 google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.98.0 h1:yxZrcxXESimy6r6mdL5Q6EnZwmewDJK2dVg3g75s5Dg= -google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.103.0 h1:9yuVqlu2JCvcLg9p8S3fcFLZij8EPSyvODIY1rkMizQ= +google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= google.golang.org/appengine v1.0.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2160,9 +2169,9 @@ google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= 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 h1:Nf+EdcTLHR8qDNN/KfkQL0u0ssxt9OhbaWCl5C0ucEI= google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd h1:OjndDrsik+Gt+e6fs45z9AxiewiKyLKYpA45W5Kpkks= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -2201,8 +2210,9 @@ google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu 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 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff --git a/modules/firehose/driver_log.go b/modules/firehose/driver_log.go index 8f9f8be6..bd629bd6 100644 --- a/modules/firehose/driver_log.go +++ b/modules/firehose/driver_log.go @@ -25,7 +25,10 @@ func (fd *firehoseDriver) Log(ctx context.Context, res module.ExpandedResource, if err := json.Unmarshal(res.Dependencies[keyKubeDependency].Output, &kubeOut); err != nil { return nil, errors.ErrInternal.WithCausef(err.Error()) } - kubeCl := kube.NewClient(kubeOut.Configs) + kubeCl, err := kube.NewClient(kubeOut.Configs) + if err != nil { + return nil, errors.ErrInternal.WithMsgf("failed to create new kube client on firehose driver Log").WithCausef(err.Error()) + } logs, err := kubeCl.StreamLogs(ctx, conf.Namespace, filter) if err != nil { diff --git a/modules/firehose/module.go b/modules/firehose/module.go index 5b081449..2569d2d4 100644 --- a/modules/firehose/module.go +++ b/modules/firehose/module.go @@ -96,7 +96,10 @@ var Module = module.Descriptor{ return errHelm }, kubeGetPod: func(ctx context.Context, conf kube.Config, ns string, labels map[string]string) ([]kube.Pod, error) { - kubeCl := kube.NewClient(conf) + kubeCl, err := kube.NewClient(conf) + if err != nil { + return nil, errors.ErrInternal.WithMsgf("failed to create new kube client on firehose driver kube get pod").WithCausef(err.Error()) + } return kubeCl.GetPodDetails(ctx, ns, labels) }, consumerReset: consumerReset, @@ -118,8 +121,12 @@ func consumerReset(ctx context.Context, conf Config, out kubernetes.Output, rese brokerAddr := conf.EnvVariables[confKeyKafkaBrokers] consumerID := conf.EnvVariables[confKeyConsumerID] - err := kafka.DoReset(ctx, kube.NewClient(out.Configs), conf.Namespace, brokerAddr, consumerID, resetTo) + kubeClient, err := kube.NewClient(out.Configs) if err != nil { + return err + } + + if err := kafka.DoReset(ctx, kubeClient, conf.Namespace, brokerAddr, consumerID, resetTo); err != nil { switch { case errors.Is(err, kube.ErrJobCreationFailed): return errNetwork.WithCause(err) diff --git a/modules/kubernetes/driver.go b/modules/kubernetes/driver.go index 7c5888b9..52a415ed 100644 --- a/modules/kubernetes/driver.go +++ b/modules/kubernetes/driver.go @@ -53,7 +53,12 @@ func (m *kubeDriver) Output(_ context.Context, res module.ExpandedResource) (jso return nil, err } - clientSet, err := kubernetes.NewForConfig(conf.RESTConfig()) + restConfig, err := conf.RESTConfig() + if err != nil { + return nil, errors.ErrInternal.WithMsgf("failed to create new kube client on kube driver output").WithCausef(err.Error()) + } + + clientSet, err := kubernetes.NewForConfig(restConfig) if err != nil { return nil, errors.ErrInvalid.WithMsgf("failed to create client: %v", err) } diff --git a/pkg/kube/client.go b/pkg/kube/client.go index 7812b73f..10fb4315 100644 --- a/pkg/kube/client.go +++ b/pkg/kube/client.go @@ -125,11 +125,19 @@ func DefaultClientConfig() Config { return defaultProviderConfig } -func NewClient(config Config) *Client { - return &Client{ - restConfig: *config.RESTConfig(), - streamingConfig: *config.StreamingConfig(), +func NewClient(config Config) (*Client, error) { + restConfig, err := config.RESTConfig() + if err != nil { + return nil, err + } + streamingConfig, err := config.StreamingConfig() + if err != nil { + return nil, err } + return &Client{ + restConfig: *restConfig, + streamingConfig: *streamingConfig, + }, nil } func (c Client) StreamLogs(ctx context.Context, namespace string, filter map[string]string) (<-chan LogChunk, error) { diff --git a/pkg/kube/config.go b/pkg/kube/config.go index f85d93b8..07547ba5 100644 --- a/pkg/kube/config.go +++ b/pkg/kube/config.go @@ -1,20 +1,27 @@ package kube import ( + "context" "time" + "golang.org/x/oauth2/google" + "google.golang.org/api/container/v1" "k8s.io/client-go/rest" "github.com/goto/entropy/pkg/errors" ) +const ( + providerTypeGKE = "gke" +) + type Config struct { // Host - The hostname (in form of URI) of Kubernetes master. Host string `json:"host"` Timeout time.Duration `json:"timeout" default:"100ms"` - // Token - Token to authenticate a service account + // Token - Token to authenticate with static oauth2 access token Token string `json:"token"` // Insecure - Whether server should be accessed without verifying the TLS certificate. @@ -28,9 +35,14 @@ type Config struct { // ClusterCACertificate - PEM-encoded root certificates bundle for TLS authentication. ClusterCACertificate string `json:"cluster_ca_certificate"` + + // ProviderType indicates which provider that hos k8s: gke, eks, etc... + // If it is `gke`, entropy will fetch auth from the default source + // left it empty if token or client key will be used + ProviderType string `json:"provider_type"` } -func (conf *Config) RESTConfig() *rest.Config { +func (conf *Config) RESTConfig() (*rest.Config, error) { rc := &rest.Config{ Host: conf.Host, Timeout: conf.Timeout, @@ -42,17 +54,36 @@ func (conf *Config) RESTConfig() *rest.Config { }, } - if conf.Token != "" { + if conf.ProviderType != "" { + switch conf.ProviderType { + case providerTypeGKE: + ts, err := google.DefaultTokenSource(context.Background(), container.CloudPlatformScope) + if err != nil { + return nil, errors.ErrInvalid.WithMsgf("%s: can't fetch credentials from service account json", conf.ProviderType).WithCausef(err.Error()) + } + oauth2Token, err := ts.Token() + if err != nil { + return nil, errors.ErrInternal.WithMsgf("%s: can't get token from token source", conf.ProviderType).WithCausef(err.Error()) + } + rc.BearerToken = oauth2Token.AccessToken + conf.Token = oauth2Token.AccessToken + default: + return nil, errors.ErrInternal.WithMsgf("%s: unsupported provider type", conf.ProviderType) + } + } else if conf.Token != "" { rc.BearerToken = conf.Token } - return rc + return rc, nil } -func (conf *Config) StreamingConfig() *rest.Config { - rc := conf.RESTConfig() +func (conf *Config) StreamingConfig() (*rest.Config, error) { + rc, err := conf.RESTConfig() + if err != nil { + return nil, err + } rc.Timeout = 0 - return rc + return rc, nil } func (conf *Config) Sanitise() error { @@ -64,15 +95,17 @@ func (conf *Config) Sanitise() error { conf.Timeout = 1 * time.Second } - if conf.Token == "" { - if conf.ClientKey == "" || conf.ClientCertificate == "" { - return errors.ErrInvalid. - WithMsgf("client_key and client_certificate must be set when token is not set") + if conf.ProviderType == "" { + if conf.Token == "" { + if conf.ClientKey == "" || conf.ClientCertificate == "" { + return errors.ErrInvalid. + WithMsgf("client_key and client_certificate must be set when token and service account is not set") + } } - } - if !conf.Insecure && len(conf.ClusterCACertificate) == 0 { - return errors.ErrInvalid.WithMsgf("cluster_ca_certificate must be set when insecure=false") + if !conf.Insecure && len(conf.ClusterCACertificate) == 0 { + return errors.ErrInvalid.WithMsgf("cluster_ca_certificate must be set when insecure=false") + } } return nil From 851bee468f9d1596b7eface8570a097817d5063e Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Thu, 7 Sep 2023 15:34:58 +0530 Subject: [PATCH 66/72] test: payloads sent to LOG, BQ and GCS/BLOB sinks (#66) * test: payloads sent to LOG, BQ and GCS/BLOB sinks * fix: lint issue --- modules/firehose/driver_test.go | 696 ++++++++++++++++++++++++++++++++ 1 file changed, 696 insertions(+) create mode 100644 modules/firehose/driver_test.go diff --git a/modules/firehose/driver_test.go b/modules/firehose/driver_test.go new file mode 100644 index 00000000..ed607565 --- /dev/null +++ b/modules/firehose/driver_test.go @@ -0,0 +1,696 @@ +package firehose + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/goto/entropy/core/resource" + "github.com/goto/entropy/modules/kubernetes" + "github.com/goto/entropy/pkg/errors" + "github.com/goto/entropy/pkg/helm" +) + +func TestFirehoseDriver(t *testing.T) { + t.Parallel() + + table := []struct { + title string + res resource.Resource + kubeOutput kubernetes.Output + want *helm.ReleaseConfig + wantErr error + }{ + { + title: "LOG_Sink", + res: resource.Resource{ + URN: "orn:entropy:firehose:project-1:resource-1-firehose", + Kind: "firehose", + Name: "resource-1", + Project: "project-1", + Labels: map[string]string{ + "team": "team-1", + }, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + UpdatedBy: "john.doe@goto.com", + CreatedBy: "john.doe@goto.com", + Spec: resource.Spec{ + Configs: []byte(`{ + "env_variables": { + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log" + }, + "replicas": 1 + }`), + Dependencies: map[string]string{}, + }, + State: resource.State{ + Status: resource.StatusPending, + Output: nil, + }, + }, + kubeOutput: kubernetes.Output{ + Tolerations: map[string][]kubernetes.Toleration{ + "firehose_LOG": { + { + Key: "key1", + Operator: "Equal", + Value: "value1", + Effect: "NoSchedule", + }, + }, + "firehose_BIGQUERY": { + { + Key: "key2", + Operator: "Equal", + Value: "value2", + Effect: "NoSchedule", + }, + }, + }, + }, + want: &helm.ReleaseConfig{ + Name: "project-1-resource-1-firehose", + Repository: "https://goto.github.io/charts/", + Chart: "firehose", + Version: "0.1.13", + Namespace: "namespace-1", + Timeout: 300, + Wait: true, + ForceUpdate: true, + Values: map[string]any{ + "firehose": map[string]any{ + "config": map[string]any{ + "DEFAULT_KEY_IN_FIREHOSE_MODULE_1": "default-key-in-firehose-module-value_1", + "DEFAULT_KEY_IN_FIREHOSE_MODULE_2": "default-key-in-firehose-module-value_2", + "DLQ_GCS_CREDENTIAL_PATH": "/etc/secret/dlq_gcs_auth.json", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SINK_BIGQUERY_CREDENTIAL_PATH": "/etc/secret/bigquery_auth.json", + "SINK_BIGTABLE_CREDENTIAL_PATH": "/etc/secret/gcs_auth.json", + "SINK_BLOB_GCS_CREDENTIAL_PATH": "/etc/secret/gcs_auth.json", + "SINK_TYPE": "LOG", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", + "SOURCE_KAFKA_TOPIC": "foo-log", + }, + "image": map[string]any{ + "pullPolicy": "IfNotPresent", + "repository": "gotocompany/firehose", + "tag": "0.8.1", + }, + "resources": map[string]any{ + "limits": map[string]any{ + "cpu": "6000m", + "memory": "6000Mi", + }, + "requests": map[string]any{ + "cpu": "600m", + "memory": "2500Mi", + }, + }, + }, + "init-firehose": map[string]any{ + "enabled": true, + "image": map[string]any{ + "repository": "busybox", + "pullPolicy": "IfNotPresent", + "tag": "latest", + }, + "command": []string{"cmd1", "--a"}, + "args": []string{"arg1", "arg2"}, + }, + "labels": map[string]string{ + "deployment": "project-1-resource-1-firehose", + "team": "team-1", + "orchestrator": "entropy", + }, + "mountSecrets": []map[string]string{ + { + "key": "gcs_credential", + "path": "gcs_auth.json", + "value": "gcs-credential", + }, + { + "key": "dlq_gcs_credential", + "path": "dlq_gcs_auth.json", + "value": "dlq-gcs-credential", + }, + { + "key": "bigquery_credential", + "path": "bigquery_auth.json", + "value": "big-query-credential", + }, + }, + "nodeAffinityMatchExpressions": map[string]any{ + "preferredDuringSchedulingIgnoredDuringExecution": []WeightedPreference{ + { + Weight: 1, + Preference: []Preference{ + { + Key: "another-node-label-key", + Operator: "In", + Values: []string{"another-node-label-value"}, + }, + }, + }, + }, + "requiredDuringSchedulingIgnoredDuringExecution": []Preference{ + { + Key: "topology.kubernetes.io/zone", + Operator: "In", + Values: []string{"antarctica-east1", "antarctica-west1"}, + }, + }, + }, + "replicaCount": 1, + "telegraf": map[string]any{ + "enabled": true, + "image": map[string]string{ + "pullPolicy": "IfNotPresent", + "repository": "telegraf", + "tag": "1.18.0-alpine", + }, + "config": map[string]any{ + "output": map[string]any{ + "prometheus_remote_write": map[string]any{ + "enabled": true, + "url": "http://goto.com", + }, + }, + "additional_global_tags": map[string]string{ + "app": "orn:entropy:firehose:project-1:resource-1-firehose", + }, + }, + }, + "tolerations": []map[string]any{ + { + "key": "key1", + "operator": "Equal", + "value": "value1", + "effect": "NoSchedule", + }, + }, + }, + }, + wantErr: nil, + }, + { + title: "BIGQUERY_Sink", + res: resource.Resource{ + URN: "orn:entropy:firehose:project-1:resource-2-firehose", + Kind: "firehose", + Name: "resource-2", + Project: "project-1", + Labels: map[string]string{ + "team": "team-2", + }, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + UpdatedBy: "john.doe2@goto.com", + CreatedBy: "john.doe2@goto.com", + Spec: resource.Spec{ + Configs: []byte(`{ + "env_variables": { + "SINK_TYPE": "BIGQUERY", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar-2", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz-2", + "SOURCE_KAFKA_BROKERS": "localhost:9093", + "SOURCE_KAFKA_TOPIC": "foo-log-2" + }, + "replicas": 2 + }`), + Dependencies: map[string]string{}, + }, + State: resource.State{ + Status: resource.StatusPending, + Output: nil, + }, + }, + kubeOutput: kubernetes.Output{ + Tolerations: map[string][]kubernetes.Toleration{ + "firehose_LOG": { + { + Key: "key1", + Operator: "Equal", + Value: "value1", + Effect: "NoSchedule", + }, + }, + "firehose_BIGQUERY": { + { + Key: "key2", + Operator: "Equal", + Value: "value2", + Effect: "NoSchedule", + }, + }, + }, + }, + want: &helm.ReleaseConfig{ + Name: "project-1-resource-2-firehose", + Repository: "https://goto.github.io/charts/", + Chart: "firehose", + Version: "0.1.13", + Namespace: "namespace-1", + Timeout: 300, + Wait: true, + ForceUpdate: true, + Values: map[string]any{ + "firehose": map[string]any{ + "config": map[string]any{ + "DEFAULT_KEY_IN_FIREHOSE_MODULE_1": "default-key-in-firehose-module-value_1", + "DEFAULT_KEY_IN_FIREHOSE_MODULE_2": "default-key-in-firehose-module-value_2", + "DLQ_GCS_CREDENTIAL_PATH": "/etc/secret/dlq_gcs_auth.json", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar-2", + "SINK_BIGQUERY_CREDENTIAL_PATH": "/etc/secret/bigquery_auth.json", + "SINK_BIGTABLE_CREDENTIAL_PATH": "/etc/secret/gcs_auth.json", + "SINK_BLOB_GCS_CREDENTIAL_PATH": "/etc/secret/gcs_auth.json", + "SINK_TYPE": "BIGQUERY", + "SOURCE_KAFKA_BROKERS": "localhost:9093", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz-2", + "SOURCE_KAFKA_TOPIC": "foo-log-2", + }, + "image": map[string]any{ + "pullPolicy": "IfNotPresent", + "repository": "gotocompany/firehose", + "tag": "0.8.1", + }, + "resources": map[string]any{ + "limits": map[string]any{ + "cpu": "6000m", + "memory": "20000Mi", + }, + "requests": map[string]any{ + "cpu": "300m", + "memory": "2000Mi", + }, + }, + }, + "init-firehose": map[string]any{ + "enabled": true, + "image": map[string]any{ + "repository": "busybox", + "pullPolicy": "IfNotPresent", + "tag": "latest", + }, + "command": []string{"cmd1", "--a"}, + "args": []string{"arg1", "arg2"}, + }, + "labels": map[string]string{ + "deployment": "project-1-resource-2-firehose", + "team": "team-2", + "orchestrator": "entropy", + }, + "mountSecrets": []map[string]string{ + { + "key": "gcs_credential", + "path": "gcs_auth.json", + "value": "gcs-credential", + }, + { + "key": "dlq_gcs_credential", + "path": "dlq_gcs_auth.json", + "value": "dlq-gcs-credential", + }, + { + "key": "bigquery_credential", + "path": "bigquery_auth.json", + "value": "big-query-credential", + }, + }, + "nodeAffinityMatchExpressions": map[string]any{ + "preferredDuringSchedulingIgnoredDuringExecution": []WeightedPreference{ + { + Weight: 1, + Preference: []Preference{ + { + Key: "another-node-label-key", + Operator: "In", + Values: []string{"another-node-label-value"}, + }, + }, + }, + }, + "requiredDuringSchedulingIgnoredDuringExecution": []Preference{ + { + Key: "topology.kubernetes.io/zone", + Operator: "In", + Values: []string{"antarctica-east1", "antarctica-west1"}, + }, + }, + }, + "replicaCount": 2, + "telegraf": map[string]any{ + "enabled": true, + "image": map[string]string{ + "pullPolicy": "IfNotPresent", + "repository": "telegraf", + "tag": "1.18.0-alpine", + }, + "config": map[string]any{ + "output": map[string]any{ + "prometheus_remote_write": map[string]any{ + "enabled": true, + "url": "http://goto.com", + }, + }, + "additional_global_tags": map[string]string{ + "app": "orn:entropy:firehose:project-1:resource-2-firehose", + }, + }, + }, + "tolerations": []map[string]any{ + { + "key": "key2", + "operator": "Equal", + "value": "value2", + "effect": "NoSchedule", + }, + }, + }, + }, + wantErr: nil, + }, + { + title: "BLOB_Sink", + res: resource.Resource{ + URN: "orn:entropy:firehose:project-1:resource-3-firehose", + Kind: "firehose", + Name: "resource-3", + Project: "project-1", + Labels: map[string]string{ + "team": "team-3", + }, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + UpdatedBy: "john.doe3@goto.com", + CreatedBy: "john.doe3@goto.com", + Spec: resource.Spec{ + Configs: []byte(`{ + "env_variables": { + "SINK_TYPE": "BLOB", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar-3", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz-3", + "SOURCE_KAFKA_BROKERS": "localhost:9094", + "SOURCE_KAFKA_TOPIC": "foo-log-3" + }, + "replicas": 3 + }`), + Dependencies: map[string]string{}, + }, + State: resource.State{ + Status: resource.StatusPending, + Output: nil, + }, + }, + kubeOutput: kubernetes.Output{ + Tolerations: map[string][]kubernetes.Toleration{ + "firehose_LOG": { + { + Key: "key1", + Operator: "Equal", + Value: "value1", + Effect: "NoSchedule", + }, + }, + "firehose_BIGQUERY": { + { + Key: "key2", + Operator: "Equal", + Value: "value2", + Effect: "NoSchedule", + }, + }, + "firehose_BLOB": { + { + Key: "key3", + Operator: "Equal", + Value: "value3", + Effect: "NoSchedule", + }, + }, + }, + }, + want: &helm.ReleaseConfig{ + Name: "project-1-resource-3-firehose", + Repository: "https://goto.github.io/charts/", + Chart: "firehose", + Version: "0.1.13", + Namespace: "namespace-1", + Timeout: 300, + Wait: true, + ForceUpdate: true, + Values: map[string]any{ + "firehose": map[string]any{ + "config": map[string]any{ + "DEFAULT_KEY_IN_FIREHOSE_MODULE_1": "default-key-in-firehose-module-value_1", + "DEFAULT_KEY_IN_FIREHOSE_MODULE_2": "default-key-in-firehose-module-value_2", + "DLQ_GCS_CREDENTIAL_PATH": "/etc/secret/dlq_gcs_auth.json", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar-3", + "SINK_BIGQUERY_CREDENTIAL_PATH": "/etc/secret/bigquery_auth.json", + "SINK_BIGTABLE_CREDENTIAL_PATH": "/etc/secret/gcs_auth.json", + "SINK_BLOB_GCS_CREDENTIAL_PATH": "/etc/secret/gcs_auth.json", + "SINK_TYPE": "BLOB", + "SOURCE_KAFKA_BROKERS": "localhost:9094", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz-3", + "SOURCE_KAFKA_TOPIC": "foo-log-3", + }, + "image": map[string]any{ + "pullPolicy": "IfNotPresent", + "repository": "gotocompany/firehose", + "tag": "0.8.1", + }, + "resources": map[string]any{ + "limits": map[string]any{ + "cpu": "6000m", + "memory": "20000Mi", + }, + "requests": map[string]any{ + "cpu": "300m", + "memory": "2000Mi", + }, + }, + }, + "init-firehose": map[string]any{ + "enabled": true, + "image": map[string]any{ + "repository": "busybox", + "pullPolicy": "IfNotPresent", + "tag": "latest", + }, + "command": []string{"cmd1", "--a"}, + "args": []string{"arg1", "arg2"}, + }, + "labels": map[string]string{ + "deployment": "project-1-resource-3-firehose", + "team": "team-3", + "orchestrator": "entropy", + }, + "mountSecrets": []map[string]string{ + { + "key": "gcs_credential", + "path": "gcs_auth.json", + "value": "gcs-credential", + }, + { + "key": "dlq_gcs_credential", + "path": "dlq_gcs_auth.json", + "value": "dlq-gcs-credential", + }, + { + "key": "bigquery_credential", + "path": "bigquery_auth.json", + "value": "big-query-credential", + }, + }, + "nodeAffinityMatchExpressions": map[string]any{ + "preferredDuringSchedulingIgnoredDuringExecution": []WeightedPreference{ + { + Weight: 1, + Preference: []Preference{ + { + Key: "another-node-label-key", + Operator: "In", + Values: []string{"another-node-label-value"}, + }, + }, + }, + }, + "requiredDuringSchedulingIgnoredDuringExecution": []Preference{ + { + Key: "topology.kubernetes.io/zone", + Operator: "In", + Values: []string{"antarctica-east1", "antarctica-west1"}, + }, + }, + }, + "replicaCount": 3, + "telegraf": map[string]any{ + "enabled": true, + "image": map[string]string{ + "pullPolicy": "IfNotPresent", + "repository": "telegraf", + "tag": "1.18.0-alpine", + }, + "config": map[string]any{ + "output": map[string]any{ + "prometheus_remote_write": map[string]any{ + "enabled": true, + "url": "http://goto.com", + }, + }, + "additional_global_tags": map[string]string{ + "app": "orn:entropy:firehose:project-1:resource-3-firehose", + }, + }, + }, + "tolerations": []map[string]any{ + { + "key": "key3", + "operator": "Equal", + "value": "value3", + "effect": "NoSchedule", + }, + }, + }, + }, + wantErr: nil, + }, + } + + for _, tt := range table { + t.Run(tt.title, func(t *testing.T) { + fd := &firehoseDriver{ + conf: firehoseDriverConf(), + timeNow: func() time.Time { return frozenTime }, + } + + conf, _ := readConfig(tt.res, tt.res.Spec.Configs, fd.conf) + chartVals, _ := mergeChartValues(&fd.conf.ChartValues, conf.ChartValues) + + conf.Telegraf = fd.conf.Telegraf + conf.Namespace = fd.conf.Namespace + conf.ChartValues = chartVals + + got, err := fd.getHelmRelease(tt.res, *conf, tt.kubeOutput) + if tt.wantErr != nil { + require.Error(t, err) + assert.True(t, errors.Is(err, tt.wantErr), "wantErr=%v\ngotErr=%v", tt.wantErr, err) + } else { + assert.NoError(t, err) + require.NotNil(t, got) + + wantJSON := string(mustJSON(tt.want)) + gotJSON := string(mustJSON(got)) + assert.JSONEq(t, wantJSON, gotJSON) + } + }) + } +} + +func firehoseDriverConf() driverConf { + return driverConf{ + NodeAffinityMatchExpressions: NodeAffinityMatchExpressions{ + RequiredDuringSchedulingIgnoredDuringExecution: []Preference{ + { + Key: "topology.kubernetes.io/zone", + Operator: "In", + Values: []string{"antarctica-east1", "antarctica-west1"}, + }, + }, + PreferredDuringSchedulingIgnoredDuringExecution: []WeightedPreference{ + { + Weight: 1, + Preference: []Preference{ + { + Key: "another-node-label-key", + Operator: "In", + Values: []string{"another-node-label-value"}, + }, + }, + }, + }, + }, + EnvVariables: map[string]string{ + "DEFAULT_KEY_IN_FIREHOSE_MODULE_1": "default-key-in-firehose-module-value_1", + "DEFAULT_KEY_IN_FIREHOSE_MODULE_2": "default-key-in-firehose-module-value_2", + }, + ChartValues: ChartValues{ + ChartVersion: "0.1.13", + ImageTag: "0.8.1", + ImagePullPolicy: "IfNotPresent", + }, + BigQuerySinkCredential: "big-query-credential", + GCSSinkCredential: "gcs-credential", + DLQGCSSinkCredential: "dlq-gcs-credential", + InitContainer: InitContainer{ + Args: []string{"arg1", "arg2"}, + Command: []string{"cmd1", "--a"}, + Enabled: true, + ImageTag: "latest", + PullPolicy: "IfNotPresent", + Repository: "busybox", + }, + Labels: map[string]string{ + "team": "{{.team}}", + }, + Namespace: "namespace-1", + RequestsAndLimits: map[string]RequestsAndLimits{ + "BIGQUERY": { + Limits: UsageSpec{ + CPU: "6000m", + Memory: "20000Mi", + }, + Requests: UsageSpec{ + CPU: "300m", + Memory: "2000Mi", + }, + }, + "BLOB": { + Limits: UsageSpec{ + CPU: "6000m", + Memory: "20000Mi", + }, + Requests: UsageSpec{ + CPU: "300m", + Memory: "2000Mi", + }, + }, + "default": { + Limits: UsageSpec{ + CPU: "6000m", + Memory: "6000Mi", + }, + Requests: UsageSpec{ + CPU: "600m", + Memory: "2500Mi", + }, + }, + }, + Telegraf: &Telegraf{ + Enabled: true, + Image: map[string]any{ + "pullPolicy": "IfNotPresent", + "repository": "telegraf", + "tag": "1.18.0-alpine", + }, + Config: TelegrafConf{ + Output: map[string]any{ + "prometheus_remote_write": map[string]any{ + "enabled": true, + "url": "http://goto.com", + }, + }, + AdditionalGlobalTags: map[string]string{ + "app": "{{ .urn }}", + }, + }, + }, + } +} From 4137feee8555ae78a22024b31af3bdbd5dfa2f25 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Mon, 11 Sep 2023 11:02:13 +0530 Subject: [PATCH 67/72] fix: add delay before executing reset (#69) * fix: add delay before executing reset - kafka takes some time before it registers the stopped consumer - hence when we try to attemp the reset immediately, it fails - even though it fails, it does not return a failed response * feat: make delay configurable * chore: update comment * Update driver.go * change time to seconds * feat: handle context cancellation --- modules/firehose/driver.go | 5 ++++- modules/firehose/driver_sync.go | 2 +- modules/firehose/module.go | 37 ++++++++++++++++++++------------- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index eb016338..773aef9f 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -75,7 +75,7 @@ type firehoseDriver struct { type ( kubeDeployFn func(ctx context.Context, isCreate bool, conf kube.Config, hc helm.ReleaseConfig) error kubeGetPodFn func(ctx context.Context, conf kube.Config, ns string, labels map[string]string) ([]kube.Pod, error) - consumerResetFn func(ctx context.Context, conf Config, out kubernetes.Output, resetTo string) error + consumerResetFn func(ctx context.Context, conf Config, out kubernetes.Output, resetTo string, offsetResetDelaySeconds int) error ) type driverConf struct { @@ -118,6 +118,9 @@ type driverConf struct { // NodeAffinityMatchExpressions can be used to set node-affinity for the deployment. NodeAffinityMatchExpressions NodeAffinityMatchExpressions `json:"node_affinity_match_expressions"` + + // delay between stopping a firehose and making an offset reset request + OffsetResetDelaySeconds int `json:"offset_reset_delay_seconds"` } type RequestsAndLimits struct { diff --git a/modules/firehose/driver_sync.go b/modules/firehose/driver_sync.go index bbd61df9..aa5fcf5d 100644 --- a/modules/firehose/driver_sync.go +++ b/modules/firehose/driver_sync.go @@ -56,7 +56,7 @@ func (fd *firehoseDriver) Sync(ctx context.Context, exr module.ExpandedResource) } case stepKafkaReset: - if err := fd.consumerReset(ctx, *conf, kubeOut, modData.ResetOffsetTo); err != nil { + if err := fd.consumerReset(ctx, *conf, kubeOut, modData.ResetOffsetTo, fd.conf.OffsetResetDelaySeconds); err != nil { return nil, err } diff --git a/modules/firehose/module.go b/modules/firehose/module.go index 2569d2d4..bc587af5 100644 --- a/modules/firehose/module.go +++ b/modules/firehose/module.go @@ -107,15 +107,17 @@ var Module = module.Descriptor{ }, } -func consumerReset(ctx context.Context, conf Config, out kubernetes.Output, resetTo string) error { +func consumerReset(ctx context.Context, conf Config, out kubernetes.Output, resetTo string, offsetResetDelaySeconds int) error { const ( - networkErrorRetryDuration = 5 * time.Second - kubeAPIRetryBackoffDuration = 30 * time.Second + networkErrorRetryDuration = 5 * time.Second + kubeAPIRetryBackoffDuration = 30 * time.Second + contextCancellationBackoffDuration = 30 * time.Second ) var ( - errNetwork = worker.RetryableError{RetryAfter: networkErrorRetryDuration} - errKubeAPI = worker.RetryableError{RetryAfter: kubeAPIRetryBackoffDuration} + errNetwork = worker.RetryableError{RetryAfter: networkErrorRetryDuration} + errKubeAPI = worker.RetryableError{RetryAfter: kubeAPIRetryBackoffDuration} + errResetContextCancellation = worker.RetryableError{RetryAfter: contextCancellationBackoffDuration} ) brokerAddr := conf.EnvVariables[confKeyKafkaBrokers] @@ -126,20 +128,25 @@ func consumerReset(ctx context.Context, conf Config, out kubernetes.Output, rese return err } - if err := kafka.DoReset(ctx, kubeClient, conf.Namespace, brokerAddr, consumerID, resetTo); err != nil { - switch { - case errors.Is(err, kube.ErrJobCreationFailed): - return errNetwork.WithCause(err) + select { + case <-time.After(time.Duration(offsetResetDelaySeconds) * time.Second): + if err := kafka.DoReset(ctx, kubeClient, conf.Namespace, brokerAddr, consumerID, resetTo); err != nil { + switch { + case errors.Is(err, kube.ErrJobCreationFailed): + return errNetwork.WithCause(err) - case errors.Is(err, kube.ErrJobNotFound): - return errKubeAPI.WithCause(err) + case errors.Is(err, kube.ErrJobNotFound): + return errKubeAPI.WithCause(err) - case errors.Is(err, kube.ErrJobExecutionFailed): - return errKubeAPI.WithCause(err) + case errors.Is(err, kube.ErrJobExecutionFailed): + return errKubeAPI.WithCause(err) - default: - return err + default: + return err + } } + case <-ctx.Done(): + return errResetContextCancellation.WithCause(errors.New("context cancelled while reset")) } return nil From 9773fcda1c09e3fdb068be562a9691cfacf73a60 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Thu, 14 Sep 2023 16:12:05 +0530 Subject: [PATCH 68/72] fix: job name should be within 63 char limit (#70) * fix: use deployment id for deriving job name * refactor: remove var declaration --- modules/firehose/module.go | 2 +- pkg/kafka/consumer_reset.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/firehose/module.go b/modules/firehose/module.go index bc587af5..d1b12e6a 100644 --- a/modules/firehose/module.go +++ b/modules/firehose/module.go @@ -130,7 +130,7 @@ func consumerReset(ctx context.Context, conf Config, out kubernetes.Output, rese select { case <-time.After(time.Duration(offsetResetDelaySeconds) * time.Second): - if err := kafka.DoReset(ctx, kubeClient, conf.Namespace, brokerAddr, consumerID, resetTo); err != nil { + if err := kafka.DoReset(ctx, kubeClient, conf.Namespace, brokerAddr, consumerID, resetTo, conf.DeploymentID); err != nil { switch { case errors.Is(err, kube.ErrJobCreationFailed): return errNetwork.WithCause(err) diff --git a/pkg/kafka/consumer_reset.go b/pkg/kafka/consumer_reset.go index 04a1ec1d..da3dc30f 100644 --- a/pkg/kafka/consumer_reset.go +++ b/pkg/kafka/consumer_reset.go @@ -27,8 +27,8 @@ type ResetParams struct { // DoReset executes a kubernetes job with kafka-consumer-group.sh installed to // reset offset policy for the given consumer id on all topics. -func DoReset(ctx context.Context, jobCluster *kube.Client, kubeNamespace, kafkaBrokers, kafkaConsumerID, kafkaResetValue string) error { - jobName := kafkaConsumerID + "-reset" +func DoReset(ctx context.Context, jobCluster *kube.Client, kubeNamespace, kafkaBrokers, kafkaConsumerID, kafkaResetValue, resetJobName string) error { + jobName := resetJobName + "-reset" return jobCluster.RunJob(ctx, kubeNamespace, jobName, From ee9a1057af30e5c764943cf1ce247de5caf4c377 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Thu, 14 Sep 2023 23:18:17 +0530 Subject: [PATCH 69/72] fix: remove -firehose from job name (#71) * fix: remove -firehose from job name * fix: lint issue --- pkg/kafka/consumer_reset.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/kafka/consumer_reset.go b/pkg/kafka/consumer_reset.go index da3dc30f..f2636354 100644 --- a/pkg/kafka/consumer_reset.go +++ b/pkg/kafka/consumer_reset.go @@ -28,10 +28,12 @@ type ResetParams struct { // DoReset executes a kubernetes job with kafka-consumer-group.sh installed to // reset offset policy for the given consumer id on all topics. func DoReset(ctx context.Context, jobCluster *kube.Client, kubeNamespace, kafkaBrokers, kafkaConsumerID, kafkaResetValue, resetJobName string) error { - jobName := resetJobName + "-reset" + suffix := "-firehose" + resetJobName = strings.TrimSuffix(resetJobName, suffix) + resetJobName += "-reset" return jobCluster.RunJob(ctx, kubeNamespace, - jobName, + resetJobName, kafkaImage, prepCommand(kafkaBrokers, kafkaConsumerID, kafkaResetValue), retries, From 2c4ef1f6372bf4f446db2d155991b2534a80ac86 Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Wed, 20 Sep 2023 11:33:42 +0530 Subject: [PATCH 70/72] feat: old reset strategy (#72) * feat: use group incremental reset strategy * test: getNewConsumerGroupID * fix: lint issue * fix: lint issue * fix: use regex * fix: lint issue * test: fix group id numbers * fix: use shorted if syntax * fix: test * fix: readConfig * refactor: rename new-reset to reset-v2 * fix: error message * fix: var name * fix: var name --- modules/firehose/config.go | 4 +- modules/firehose/driver_plan.go | 67 +++++++++++++++++++++++++- modules/firehose/driver_plan_test.go | 72 +++++++++++++++++++++------- modules/firehose/module.go | 1 + pkg/kafka/consumer_reset.go | 31 ++++++++++-- 5 files changed, 152 insertions(+), 23 deletions(-) diff --git a/modules/firehose/config.go b/modules/firehose/config.go index ad73908d..10b2e0c4 100644 --- a/modules/firehose/config.go +++ b/modules/firehose/config.go @@ -108,8 +108,10 @@ func readConfig(r resource.Resource, confJSON json.RawMessage, dc driverConf) (* return nil, errors.ErrInvalid.WithMsgf("deployment_id must not have more than 53 chars") } + // we name a consumer group by adding a sequence suffix to the deployment name + // this sequence will later be incremented to name new consumer group while resetting offset if consumerID := cfg.EnvVariables[confKeyConsumerID]; consumerID == "" { - cfg.EnvVariables[confKeyConsumerID] = fmt.Sprintf("%s-0001", cfg.DeploymentID) + cfg.EnvVariables[confKeyConsumerID] = fmt.Sprintf("%s-1", cfg.DeploymentID) } rl := dc.RequestsAndLimits[defaultKey] diff --git a/modules/firehose/driver_plan.go b/modules/firehose/driver_plan.go index 3b0b5338..5f49975e 100644 --- a/modules/firehose/driver_plan.go +++ b/modules/firehose/driver_plan.go @@ -3,6 +3,9 @@ package firehose import ( "context" "encoding/json" + "fmt" + "regexp" + "strconv" "github.com/goto/entropy/core/module" "github.com/goto/entropy/core/resource" @@ -10,6 +13,11 @@ import ( "github.com/goto/entropy/pkg/kafka" ) +const SourceKafkaConsumerAutoOffsetReset = "SOURCE_KAFKA_CONSUMER_CONFIG_AUTO_OFFSET_RESET" + +var suffixRegex = regexp.MustCompile(`^([A-Za-z0-9-]+)-([0-9]+)$`) +var errGroupIDFormat = fmt.Errorf("group id must match the format '%s'", suffixRegex) + func (fd *firehoseDriver) Plan(_ context.Context, exr module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) { switch act.Name { case module.CreateAction: @@ -18,6 +26,9 @@ func (fd *firehoseDriver) Plan(_ context.Context, exr module.ExpandedResource, a case ResetAction: return fd.planReset(exr, act) + case ResetV2Action: + return fd.planResetV2(exr, act) + default: return fd.planChange(exr, act) } @@ -128,8 +139,8 @@ func (fd *firehoseDriver) planCreate(exr module.ExpandedResource, act module.Act return &exr.Resource, nil } -func (fd *firehoseDriver) planReset(exr module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) { - resetValue, err := kafka.ParseResetParams(act.Params) +func (fd *firehoseDriver) planResetV2(exr module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) { + resetValue, err := kafka.ParseResetV2Params(act.Params) if err != nil { return nil, err } @@ -159,3 +170,55 @@ func (fd *firehoseDriver) planReset(exr module.ExpandedResource, act module.Acti } return &exr.Resource, nil } + +func (fd *firehoseDriver) planReset(exr module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) { + resetValue, err := kafka.ParseResetParams(act.Params) + if err != nil { + return nil, err + } + + immediately := fd.timeNow() + + curConf, err := readConfig(exr.Resource, exr.Resource.Spec.Configs, fd.conf) + if err != nil { + return nil, err + } + + curConf.ResetOffset = resetValue + curConf.EnvVariables[SourceKafkaConsumerAutoOffsetReset] = resetValue + curConf.EnvVariables[confKeyConsumerID], err = getNewConsumerGroupID(curConf.EnvVariables[confKeyConsumerID]) + if err != nil { + return nil, err + } + + exr.Resource.Spec.Configs = mustJSON(curConf) + exr.Resource.State = resource.State{ + Status: resource.StatusPending, + Output: exr.Resource.State.Output, + NextSyncAt: &immediately, + ModuleData: mustJSON(transientData{ + PendingSteps: []string{ + stepReleaseStop, // stop the firehose + stepReleaseUpdate, // restart the deployment. + }, + }), + } + return &exr.Resource, nil +} + +func getNewConsumerGroupID(curGroup string) (string, error) { + matches := suffixRegex.FindStringSubmatch(curGroup) + if expLen := 3; len(matches) != expLen { + return "", errGroupIDFormat + } + prefix, sequence := matches[1], matches[2] + + seq, err := strconv.Atoi(sequence) + if err != nil { + return "", errors.Errorf("error converting group sequence %s to int: %v", sequence, err) + } else { + seq++ + } + + return fmt.Sprintf("%s-%d", prefix, seq), nil +} diff --git a/modules/firehose/driver_plan_test.go b/modules/firehose/driver_plan_test.go index c984979f..e4f81ed6 100644 --- a/modules/firehose/driver_plan_test.go +++ b/modules/firehose/driver_plan_test.go @@ -93,7 +93,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { "env_variables": map[string]string{ "SINK_TYPE": "LOG", "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", - "SOURCE_KAFKA_CONSUMER_GROUP_ID": "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-3801d0-firehose-0001", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghij-3801d0-firehose-1", "SOURCE_KAFKA_BROKERS": "localhost:9092", "SOURCE_KAFKA_TOPIC": "foo-log", }, @@ -306,7 +306,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { act: module.ActionRequest{ Name: ResetAction, Params: mustJSON(map[string]any{ - "reset_to": "some_random", + "to": "some_random", }), }, wantErr: errors.ErrInvalid, @@ -324,11 +324,12 @@ func TestFirehoseDriver_Plan(t *testing.T) { "replicas": 1, "deployment_id": "firehose-deployment-x", "env_variables": map[string]string{ - "SINK_TYPE": "LOG", - "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", - "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", - "SOURCE_KAFKA_BROKERS": "localhost:9092", - "SOURCE_KAFKA_TOPIC": "foo-log", + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "firehose-deployment-x-1", + "SOURCE_KAFKA_CONSUMER_CONFIG_AUTO_OFFSET_RESET": "latest", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", }, "limits": map[string]any{ "cpu": "200m", @@ -352,7 +353,7 @@ func TestFirehoseDriver_Plan(t *testing.T) { act: module.ActionRequest{ Name: ResetAction, Params: mustJSON(map[string]any{ - "to": "latest", + "to": "earliest", }), }, want: &resource.Resource{ @@ -365,13 +366,14 @@ func TestFirehoseDriver_Plan(t *testing.T) { "replicas": 1, "deployment_id": "firehose-deployment-x", "env_variables": map[string]string{ - "SINK_TYPE": "LOG", - "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", - "SOURCE_KAFKA_CONSUMER_GROUP_ID": "foo-bar-baz", - "SOURCE_KAFKA_BROKERS": "localhost:9092", - "SOURCE_KAFKA_TOPIC": "foo-log", + "SINK_TYPE": "LOG", + "INPUT_SCHEMA_PROTO_CLASS": "com.foo.Bar", + "SOURCE_KAFKA_CONSUMER_GROUP_ID": "firehose-deployment-x-2", + "SOURCE_KAFKA_CONSUMER_CONFIG_AUTO_OFFSET_RESET": "earliest", + "SOURCE_KAFKA_BROKERS": "localhost:9092", + "SOURCE_KAFKA_TOPIC": "foo-log", }, - "reset_offset": "latest", + "reset_offset": "earliest", "limits": map[string]any{ "cpu": "200m", "memory": "512Mi", @@ -391,10 +393,8 @@ func TestFirehoseDriver_Plan(t *testing.T) { ReleaseName: "bar", }), ModuleData: mustJSON(transientData{ - ResetOffsetTo: "latest", PendingSteps: []string{ stepReleaseStop, - stepKafkaReset, stepReleaseUpdate, }, }), @@ -558,3 +558,43 @@ func TestFirehoseDriver_Plan(t *testing.T) { }) } } + +func TestGetNewConsumerGroupID(t *testing.T) { + t.Parallel() + + table := []struct { + title string + deploymentID string + consumerGroupID string + want string + wantErr error + }{ + { + title: "invalid-group-id", + consumerGroupID: "test-firehose-xyz", + want: "", + wantErr: errGroupIDFormat, + }, + { + title: "valid-group-id", + consumerGroupID: "test-firehose-0999", + want: "test-firehose-1000", + wantErr: nil, + }, + } + + for _, tt := range table { + t.Run(tt.title, func(t *testing.T) { + got, err := getNewConsumerGroupID(tt.consumerGroupID) + if tt.wantErr != nil { + require.Error(t, err) + assert.Equal(t, "", got) + assert.ErrorIs(t, err, tt.wantErr) + } else { + assert.NoError(t, err) + require.NotNil(t, got) + assert.Equal(t, tt.want, got) + } + }) + } +} diff --git a/modules/firehose/module.go b/modules/firehose/module.go index d1b12e6a..2b519cd5 100644 --- a/modules/firehose/module.go +++ b/modules/firehose/module.go @@ -25,6 +25,7 @@ const ( StartAction = "start" StopAction = "stop" ResetAction = "reset" + ResetV2Action = "reset-v2" UpgradeAction = "upgrade" ) diff --git a/pkg/kafka/consumer_reset.go b/pkg/kafka/consumer_reset.go index f2636354..a59e8e44 100644 --- a/pkg/kafka/consumer_reset.go +++ b/pkg/kafka/consumer_reset.go @@ -20,11 +20,15 @@ const ( resetDatetime = "datetime" ) -type ResetParams struct { +type ResetV2Params struct { To string `json:"to"` Datetime string `json:"datetime"` } +type ResetParams struct { + To string `json:"to"` +} + // DoReset executes a kubernetes job with kafka-consumer-group.sh installed to // reset offset policy for the given consumer id on all topics. func DoReset(ctx context.Context, jobCluster *kube.Client, kubeNamespace, kafkaBrokers, kafkaConsumerID, kafkaResetValue, resetJobName string) error { @@ -40,10 +44,10 @@ func DoReset(ctx context.Context, jobCluster *kube.Client, kubeNamespace, kafkaB ) } -// ParseResetParams parses the given JSON data as reset parameters value and +// ParseResetV2Params parses the given JSON data as reset parameters value and // returns the actual reset value to be used with DoReset(). -func ParseResetParams(bytes json.RawMessage) (string, error) { - var params ResetParams +func ParseResetV2Params(bytes json.RawMessage) (string, error) { + var params ResetV2Params if err := json.Unmarshal(bytes, ¶ms); err != nil { return "", errors.ErrInvalid. WithMsgf("invalid reset params"). @@ -61,6 +65,25 @@ func ParseResetParams(bytes json.RawMessage) (string, error) { return resetValue, nil } +// ParseResetParams parses the given JSON data as reset parameters value and +// returns the actual reset value to be used with DoReset(). +func ParseResetParams(bytes json.RawMessage) (string, error) { + var params ResetParams + if err := json.Unmarshal(bytes, ¶ms); err != nil { + return "", errors.ErrInvalid. + WithMsgf("invalid reset params"). + WithCausef(err.Error()) + } + + resetValue := strings.ToLower(params.To) + if resetValue != resetLatest && resetValue != resetEarliest { + return "", errors.ErrInvalid. + WithMsgf("reset_value must be one of %v", []string{resetEarliest, resetLatest}) + } + + return resetValue, nil +} + func prepCommand(brokers, consumerID, kafkaResetValue string) []string { args := []string{ "kafka-consumer-groups.sh", From 4fdfd5096d97b5a240449ed629c2bd7e0d8de86f Mon Sep 17 00:00:00 2001 From: Ishan Arya Date: Thu, 21 Sep 2023 15:35:31 +0530 Subject: [PATCH 71/72] fix: empty body while logging (#67) * fix: empty body while logging - body was read while processing the request - made a copy of the body buffer, to log later * refactor: use io.Copy * fix: use io.Readall * fix: return if body reading fails * fix: change log type to error --- internal/server/middlewares.go | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/internal/server/middlewares.go b/internal/server/middlewares.go index 2930c4cb..ab0cc35c 100644 --- a/internal/server/middlewares.go +++ b/internal/server/middlewares.go @@ -93,6 +93,15 @@ func requestLogger(lg *zap.Logger) gorillamux.MiddlewareFunc { Status: http.StatusOK, ResponseWriter: wr, } + + bodyBytes, err := io.ReadAll(req.Body) + if err != nil { + lg.Error("error reading request body: %v", zap.String("error", err.Error())) + return + } + reader := io.NopCloser(bytes.NewBuffer(bodyBytes)) + req.Body = reader + next.ServeHTTP(wrapped, req) if req.URL.Path == "/ping" { @@ -109,25 +118,14 @@ func requestLogger(lg *zap.Logger) gorillamux.MiddlewareFunc { zap.Int("status", wrapped.Status), } - switch req.Method { - case http.MethodGet: - break - default: - buf, err := io.ReadAll(req.Body) + if len(bodyBytes) > 0 { + dst := bytes.NewBuffer(nil) + err = json.Compact(dst, bodyBytes) if err != nil { - lg.Debug("error reading request body: %v", zap.String("error", err.Error())) - } else if len(buf) > 0 { - dst := &bytes.Buffer{} - err := json.Compact(dst, buf) - if err != nil { - lg.Debug("error json compacting request body: %v", zap.String("error", err.Error())) - } else { - fields = append(fields, zap.String("request_body", dst.String())) - } + lg.Error("error json compacting request body: %v", zap.String("error", err.Error())) + } else { + fields = append(fields, zap.String("request_body", dst.String())) } - - reader := io.NopCloser(bytes.NewBuffer(buf)) - req.Body = reader } if !is2xx(wrapped.Status) { From a69dda5e0e454aafd0c97534c5261424dba1f921 Mon Sep 17 00:00:00 2001 From: lavkesh Date: Wed, 27 Sep 2023 14:39:00 +0800 Subject: [PATCH 72/72] feat: add global logger --- cli/migrate.go | 12 +++++------ cli/serve.go | 24 +++++++++++----------- core/core.go | 6 +----- core/core_test.go | 2 +- core/read_test.go | 10 ++++----- core/sync.go | 4 ++-- core/write_test.go | 36 ++++++++++++++++----------------- internal/server/middlewares.go | 10 ++++----- internal/server/server.go | 9 ++++----- modules/firehose/driver.go | 14 ++++++------- modules/firehose/driver_plan.go | 6 ++++-- pkg/logger/logger.go | 9 +++++++-- pkg/telemetry/telemetry.go | 6 +++--- 13 files changed, 74 insertions(+), 74 deletions(-) diff --git a/cli/migrate.go b/cli/migrate.go index 350c60d0..6ffefa1e 100644 --- a/cli/migrate.go +++ b/cli/migrate.go @@ -3,10 +3,8 @@ package cli import ( "context" - "github.com/spf13/cobra" - "go.uber.org/zap" - "github.com/goto/entropy/pkg/logger" + "github.com/spf13/cobra" ) func cmdMigrate() *cobra.Command { @@ -24,18 +22,18 @@ func cmdMigrate() *cobra.Command { return err } - zapLog, err := logger.New(&cfg.Log) + err = logger.Setup(&cfg.Log) if err != nil { return err } - return runMigrations(cmd.Context(), zapLog, cfg) + return runMigrations(cmd.Context(), cfg) }) return cmd } -func runMigrations(ctx context.Context, zapLog *zap.Logger, cfg Config) error { - store := setupStorage(zapLog, cfg.PGConnStr, cfg.Syncer) +func runMigrations(ctx context.Context, cfg Config) error { + store := setupStorage(cfg.PGConnStr, cfg.Syncer) return store.Migrate(ctx) } diff --git a/cli/serve.go b/cli/serve.go index 5e057bbd..1e00058c 100644 --- a/cli/serve.go +++ b/cli/serve.go @@ -38,23 +38,23 @@ func cmdServe() *cobra.Command { return err } - zapLog, err := logger.New(&cfg.Log) + err = logger.Setup(&cfg.Log) if err != nil { return err } - telemetry.Init(cmd.Context(), cfg.Telemetry, zapLog) + telemetry.Init(cmd.Context(), cfg.Telemetry) nrApp, err := newrelic.NewApplication( newrelic.ConfigAppName(cfg.Telemetry.ServiceName), newrelic.ConfigLicense(cfg.Telemetry.NewRelicAPIKey), ) - store := setupStorage(zapLog, cfg.PGConnStr, cfg.Syncer) - moduleService := module.NewService(setupRegistry(zapLog), store) - resourceService := core.New(store, moduleService, time.Now, zapLog) + store := setupStorage(cfg.PGConnStr, cfg.Syncer) + moduleService := module.NewService(setupRegistry(), store) + resourceService := core.New(store, moduleService, time.Now) if migrate { - if migrateErr := runMigrations(cmd.Context(), zapLog, cfg); migrateErr != nil { + if migrateErr := runMigrations(cmd.Context(), cfg); migrateErr != nil { return migrateErr } } @@ -62,21 +62,21 @@ func cmdServe() *cobra.Command { if spawnWorker { go func() { if runErr := resourceService.RunSyncer(cmd.Context(), cfg.Syncer.SyncInterval); runErr != nil { - zapLog.Error("syncer exited with error", zap.Error(err)) + zap.L().Error("syncer exited with error", zap.Error(err)) } }() } return entropyserver.Serve(cmd.Context(), cfg.Service.httpAddr(), cfg.Service.grpcAddr(), - nrApp, zapLog, resourceService, moduleService, + nrApp, resourceService, moduleService, ) }) return cmd } -func setupRegistry(logger *zap.Logger) module.Registry { +func setupRegistry() module.Registry { supported := []module.Descriptor{ kubernetes.Module, firehose.Module, @@ -85,7 +85,7 @@ func setupRegistry(logger *zap.Logger) module.Registry { registry := &modules.Registry{} for _, desc := range supported { if err := registry.Register(desc); err != nil { - logger.Fatal("failed to register module", + zap.L().Fatal("failed to register module", zap.String("module_kind", desc.Kind), zap.Error(err), ) @@ -94,10 +94,10 @@ func setupRegistry(logger *zap.Logger) module.Registry { return registry } -func setupStorage(logger *zap.Logger, pgConStr string, syncCfg syncerConf) *postgres.Store { +func setupStorage(pgConStr string, syncCfg syncerConf) *postgres.Store { store, err := postgres.Open(pgConStr, syncCfg.RefreshInterval, syncCfg.ExtendLockBy) if err != nil { - logger.Fatal("failed to connect to Postgres database", + zap.L().Fatal("failed to connect to Postgres database", zap.Error(err), zap.String("conn_str", pgConStr)) } return store diff --git a/core/core.go b/core/core.go index ef9ea293..cbffd67d 100644 --- a/core/core.go +++ b/core/core.go @@ -7,15 +7,12 @@ import ( "encoding/json" "time" - "go.uber.org/zap" - "github.com/goto/entropy/core/module" "github.com/goto/entropy/core/resource" "github.com/goto/entropy/pkg/errors" ) type Service struct { - logger *zap.Logger clock func() time.Time store resource.Store moduleSvc ModuleService @@ -30,7 +27,7 @@ type ModuleService interface { GetOutput(ctx context.Context, res module.ExpandedResource) (json.RawMessage, error) } -func New(repo resource.Store, moduleSvc ModuleService, clockFn func() time.Time, lg *zap.Logger) *Service { +func New(repo resource.Store, moduleSvc ModuleService, clockFn func() time.Time) *Service { const ( defaultMaxRetries = 10 defaultSyncBackoff = 5 * time.Second @@ -41,7 +38,6 @@ func New(repo resource.Store, moduleSvc ModuleService, clockFn func() time.Time, } return &Service{ - logger: lg, clock: clockFn, store: repo, syncBackoff: defaultSyncBackoff, diff --git a/core/core_test.go b/core/core_test.go index 54628532..bee41da8 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -25,6 +25,6 @@ var ( func TestNew(t *testing.T) { t.Parallel() - s := core.New(&mocks.ResourceStore{}, &mocks.ModuleService{}, deadClock, nil) + s := core.New(&mocks.ResourceStore{}, &mocks.ModuleService{}, deadClock) assert.NotNil(t, s) } diff --git a/core/read_test.go b/core/read_test.go index d8160e70..e33e6991 100644 --- a/core/read_test.go +++ b/core/read_test.go @@ -32,7 +32,7 @@ func TestService_GetResource(t *testing.T) { GetByURN(mock.Anything, mock.Anything). Return(nil, errors.ErrNotFound). Once() - return core.New(repo, nil, nil, nil) + return core.New(repo, nil, nil) }, urn: "foo:bar:baz", wantErr: errors.ErrNotFound, @@ -52,7 +52,7 @@ func TestService_GetResource(t *testing.T) { Return(nil, nil). Once() - return core.New(repo, mod, deadClock, nil) + return core.New(repo, mod, deadClock) }, urn: "foo:bar:baz", want: &sampleResource, @@ -99,7 +99,7 @@ func TestService_ListResources(t *testing.T) { List(mock.Anything, mock.Anything). Return(nil, nil). Once() - return core.New(repo, nil, deadClock, nil) + return core.New(repo, nil, deadClock) }, want: nil, wantErr: nil, @@ -113,7 +113,7 @@ func TestService_ListResources(t *testing.T) { List(mock.Anything, mock.Anything). Return(nil, errStoreFailure). Once() - return core.New(repo, nil, deadClock, nil) + return core.New(repo, nil, deadClock) }, want: nil, wantErr: errors.ErrInternal, @@ -127,7 +127,7 @@ func TestService_ListResources(t *testing.T) { List(mock.Anything, mock.Anything). Return([]resource.Resource{sampleResource}, nil). Once() - return core.New(repo, nil, deadClock, nil) + return core.New(repo, nil, deadClock) }, want: []resource.Resource{sampleResource}, wantErr: nil, diff --git a/core/sync.go b/core/sync.go index 25134c6b..d4d17795 100644 --- a/core/sync.go +++ b/core/sync.go @@ -26,14 +26,14 @@ func (svc *Service) RunSyncer(ctx context.Context, interval time.Duration) error err := svc.store.SyncOne(ctx, svc.handleSync) if err != nil { - svc.logger.Warn("SyncOne() failed", zap.Error(err)) + zap.L().Warn("SyncOne() failed", zap.Error(err)) } } } } func (svc *Service) handleSync(ctx context.Context, res resource.Resource) (*resource.Resource, error) { - logEntry := svc.logger.With( + logEntry := zap.L().With( zap.String("resource_urn", res.URN), zap.String("resource_status", res.State.Status), zap.Int("retries", res.State.SyncResult.Retries), diff --git a/core/write_test.go b/core/write_test.go index 29ddd3fc..4fd64826 100644 --- a/core/write_test.go +++ b/core/write_test.go @@ -37,7 +37,7 @@ func TestService_CreateResource(t *testing.T) { PlanAction(mock.Anything, mock.Anything, mock.Anything). Return(nil, errSample).Once() - return core.New(nil, mod, deadClock, nil) + return core.New(nil, mod, deadClock) }, res: resource.Resource{ Kind: "mock", @@ -59,7 +59,7 @@ func TestService_CreateResource(t *testing.T) { Return(nil, errors.ErrNotFound). Once() - return core.New(resourceRepo, mod, deadClock, nil) + return core.New(resourceRepo, mod, deadClock) }, res: resource.Resource{ Kind: "mock", @@ -98,7 +98,7 @@ func TestService_CreateResource(t *testing.T) { }, nil). Once() - return core.New(resourceRepo, mod, deadClock, nil) + return core.New(resourceRepo, mod, deadClock) }, res: resource.Resource{ Kind: "mock", @@ -136,7 +136,7 @@ func TestService_CreateResource(t *testing.T) { }, nil). Once() - return core.New(resourceRepo, mod, deadClock, nil) + return core.New(resourceRepo, mod, deadClock) }, res: resource.Resource{ Kind: "mock", @@ -170,7 +170,7 @@ func TestService_CreateResource(t *testing.T) { Return(errSample). Once() - return core.New(resourceRepo, mod, deadClock, nil) + return core.New(resourceRepo, mod, deadClock) }, res: resource.Resource{ Kind: "mock", @@ -198,7 +198,7 @@ func TestService_CreateResource(t *testing.T) { Create(mock.Anything, mock.Anything, mock.Anything). Return(errors.ErrConflict).Once() - return core.New(resourceRepo, mod, deadClock, nil) + return core.New(resourceRepo, mod, deadClock) }, res: resource.Resource{ Kind: "mock", @@ -255,7 +255,7 @@ func TestService_CreateResource(t *testing.T) { }). Return(nil) - return core.New(resourceRepo, mod, deadClock, nil) + return core.New(resourceRepo, mod, deadClock) }, res: resource.Resource{ Kind: "mock", @@ -328,7 +328,7 @@ func TestService_UpdateResource(t *testing.T) { Return(nil, errors.ErrNotFound). Once() - return core.New(resourceRepo, nil, deadClock, nil) + return core.New(resourceRepo, nil, deadClock) }, urn: "orn:entropy:mock:project:child", update: resource.UpdateRequest{ @@ -357,7 +357,7 @@ func TestService_UpdateResource(t *testing.T) { Return(&testResource, nil). Once() - return core.New(resourceRepo, mod, deadClock, nil) + return core.New(resourceRepo, mod, deadClock) }, urn: "orn:entropy:mock:project:child", update: resource.UpdateRequest{ @@ -404,7 +404,7 @@ func TestService_UpdateResource(t *testing.T) { Return(nil). Once() - return core.New(resourceRepo, mod, deadClock, nil) + return core.New(resourceRepo, mod, deadClock) }, urn: "orn:entropy:mock:project:child", update: resource.UpdateRequest{ @@ -450,7 +450,7 @@ func TestService_UpdateResource(t *testing.T) { }). Twice() - return core.New(resourceRepo, mod, deadClock, nil) + return core.New(resourceRepo, mod, deadClock) }, urn: "orn:entropy:mock:project:child", update: resource.UpdateRequest{ @@ -513,7 +513,7 @@ func TestService_DeleteResource(t *testing.T) { Return(nil, testErr). Once() - return core.New(resourceRepo, nil, deadClock, nil) + return core.New(resourceRepo, nil, deadClock) }, urn: "orn:entropy:mock:foo:bar", wantErr: testErr, @@ -558,7 +558,7 @@ func TestService_DeleteResource(t *testing.T) { Return(testErr). Once() - return core.New(resourceRepo, mod, deadClock, nil) + return core.New(resourceRepo, mod, deadClock) }, urn: "orn:entropy:mock:foo:bar", wantErr: errors.ErrInternal, @@ -603,7 +603,7 @@ func TestService_DeleteResource(t *testing.T) { Return(nil). Once() - return core.New(resourceRepo, mod, deadClock, nil) + return core.New(resourceRepo, mod, deadClock) }, urn: "orn:entropy:mock:foo:bar", wantErr: nil, @@ -653,7 +653,7 @@ func TestService_ApplyAction(t *testing.T) { Return(nil, errors.ErrNotFound). Once() - return core.New(resourceRepo, nil, deadClock, nil) + return core.New(resourceRepo, nil, deadClock) }, urn: "orn:entropy:mock:foo:bar", action: sampleAction, @@ -680,7 +680,7 @@ func TestService_ApplyAction(t *testing.T) { }, nil). Once() - return core.New(resourceRepo, mod, deadClock, nil) + return core.New(resourceRepo, mod, deadClock) }, urn: "orn:entropy:mock:foo:bar", action: sampleAction, @@ -713,7 +713,7 @@ func TestService_ApplyAction(t *testing.T) { }, nil). Once() - return core.New(resourceRepo, mod, deadClock, nil) + return core.New(resourceRepo, mod, deadClock) }, urn: "orn:entropy:mock:foo:bar", action: sampleAction, @@ -756,7 +756,7 @@ func TestService_ApplyAction(t *testing.T) { Return(nil). Once() - return core.New(resourceRepo, mod, deadClock, nil) + return core.New(resourceRepo, mod, deadClock) }, urn: "orn:entropy:mock:foo:bar", action: sampleAction, diff --git a/internal/server/middlewares.go b/internal/server/middlewares.go index ab0cc35c..9f4f8970 100644 --- a/internal/server/middlewares.go +++ b/internal/server/middlewares.go @@ -81,7 +81,7 @@ func requestID() gorillamux.MiddlewareFunc { } } -func requestLogger(lg *zap.Logger) gorillamux.MiddlewareFunc { +func requestLogger() gorillamux.MiddlewareFunc { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(wr http.ResponseWriter, req *http.Request) { t := time.Now() @@ -96,7 +96,7 @@ func requestLogger(lg *zap.Logger) gorillamux.MiddlewareFunc { bodyBytes, err := io.ReadAll(req.Body) if err != nil { - lg.Error("error reading request body: %v", zap.String("error", err.Error())) + zap.L().Error("error reading request body: %v", zap.String("error", err.Error())) return } reader := io.NopCloser(bytes.NewBuffer(bodyBytes)) @@ -122,16 +122,16 @@ func requestLogger(lg *zap.Logger) gorillamux.MiddlewareFunc { dst := bytes.NewBuffer(nil) err = json.Compact(dst, bodyBytes) if err != nil { - lg.Error("error json compacting request body: %v", zap.String("error", err.Error())) + zap.L().Error("error json compacting request body: %v", zap.String("error", err.Error())) } else { fields = append(fields, zap.String("request_body", dst.String())) } } if !is2xx(wrapped.Status) { - lg.Warn("request handled with non-2xx response", fields...) + zap.L().Warn("request handled with non-2xx response", fields...) } else { - lg.Info("request handled", fields...) + zap.L().Info("request handled", fields...) } }) } diff --git a/internal/server/server.go b/internal/server/server.go index 3ebc1194..857da037 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -40,14 +40,14 @@ const ( // Serve initialises all the gRPC+HTTP API routes, starts listening for requests at addr, and blocks until server exits. // Server exits gracefully when context is cancelled. -func Serve(ctx context.Context, httpAddr, grpcAddr string, nrApp *newrelic.Application, logger *zap.Logger, +func Serve(ctx context.Context, httpAddr, grpcAddr string, nrApp *newrelic.Application, resourceSvc resourcesv1.ResourceService, moduleSvc modulesv1.ModuleService, ) error { grpcOpts := []grpc.ServerOption{ grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( grpc_recovery.UnaryServerInterceptor(), grpc_ctxtags.UnaryServerInterceptor(), - grpc_zap.UnaryServerInterceptor(logger), + grpc_zap.UnaryServerInterceptor(zap.L()), nrgrpc.UnaryServerInterceptor(nrApp), )), grpc.StatsHandler(&ocgrpc.ServerHandler{}), @@ -75,7 +75,6 @@ func Serve(ctx context.Context, httpAddr, grpcAddr string, nrApp *newrelic.Appli } resourceServiceRPC := &resourcesv1.LogWrapper{ - Logger: logger, ResourceServiceServer: resourcesv1.NewAPIServer(resourceSvc), } grpcServer.RegisterService(&entropyv1beta1.ResourceService_ServiceDesc, resourceServiceRPC) @@ -99,10 +98,10 @@ func Serve(ctx context.Context, httpAddr, grpcAddr string, nrApp *newrelic.Appli httpRouter.Use( requestID(), withOpenCensus(), - requestLogger(logger), // nolint + requestLogger(), // nolint ) - logger.Info("starting http & grpc servers", + zap.L().Info("starting http & grpc servers", zap.String("http_addr", httpAddr), zap.String("grpc_addr", grpcAddr), ) diff --git a/modules/firehose/driver.go b/modules/firehose/driver.go index 773aef9f..f1db3317 100644 --- a/modules/firehose/driver.go +++ b/modules/firehose/driver.go @@ -215,7 +215,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, } tolerationKey := fmt.Sprintf("firehose_%s", conf.EnvVariables["SINK_TYPE"]) - var tolerations = []map[string]any{} + tolerations := []map[string]any{} for _, t := range kubeOut.Tolerations[tolerationKey] { tolerations = append(tolerations, map[string]any{ "key": t.Key, @@ -225,9 +225,9 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, }) } - var mountSecrets = []map[string]any{} - var requiredDuringSchedulingIgnoredDuringExecution = []Preference{} - var preferredDuringSchedulingIgnoredDuringExecution = []WeightedPreference{} + mountSecrets := []map[string]any{} + requiredDuringSchedulingIgnoredDuringExecution := []Preference{} + preferredDuringSchedulingIgnoredDuringExecution := []WeightedPreference{} if fd.conf.NodeAffinityMatchExpressions.RequiredDuringSchedulingIgnoredDuringExecution != nil { requiredDuringSchedulingIgnoredDuringExecution = fd.conf.NodeAffinityMatchExpressions.RequiredDuringSchedulingIgnoredDuringExecution @@ -238,7 +238,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, if fd.conf.GCSSinkCredential != "" { const mountFile = "gcs_auth.json" - var credPath = fmt.Sprintf("/etc/secret/%s", mountFile) + credPath := fmt.Sprintf("/etc/secret/%s", mountFile) mountSecrets = append(mountSecrets, map[string]any{ "value": fd.conf.GCSSinkCredential, @@ -251,7 +251,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, if fd.conf.DLQGCSSinkCredential != "" { const mountFile = "dlq_gcs_auth.json" - var credPath = fmt.Sprintf("/etc/secret/%s", mountFile) + credPath := fmt.Sprintf("/etc/secret/%s", mountFile) mountSecrets = append(mountSecrets, map[string]any{ "value": fd.conf.DLQGCSSinkCredential, @@ -263,7 +263,7 @@ func (fd *firehoseDriver) getHelmRelease(res resource.Resource, conf Config, if fd.conf.BigQuerySinkCredential != "" { const mountFile = "bigquery_auth.json" - var credPath = fmt.Sprintf("/etc/secret/%s", mountFile) + credPath := fmt.Sprintf("/etc/secret/%s", mountFile) mountSecrets = append(mountSecrets, map[string]any{ "value": fd.conf.BigQuerySinkCredential, diff --git a/modules/firehose/driver_plan.go b/modules/firehose/driver_plan.go index 5f49975e..c85c914d 100644 --- a/modules/firehose/driver_plan.go +++ b/modules/firehose/driver_plan.go @@ -15,8 +15,10 @@ import ( const SourceKafkaConsumerAutoOffsetReset = "SOURCE_KAFKA_CONSUMER_CONFIG_AUTO_OFFSET_RESET" -var suffixRegex = regexp.MustCompile(`^([A-Za-z0-9-]+)-([0-9]+)$`) -var errGroupIDFormat = fmt.Errorf("group id must match the format '%s'", suffixRegex) +var ( + suffixRegex = regexp.MustCompile(`^([A-Za-z0-9-]+)-([0-9]+)$`) + errGroupIDFormat = fmt.Errorf("group id must match the format '%s'", suffixRegex) +) func (fd *firehoseDriver) Plan(_ context.Context, exr module.ExpandedResource, act module.ActionRequest) (*resource.Resource, error) { switch act.Name { diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index ccc6861c..19454d35 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -9,11 +9,16 @@ type LogConfig struct { Level string `mapstructure:"level" default:"info"` } -func New(config *LogConfig) (*zap.Logger, error) { +func Setup(config *LogConfig) error { defaultConfig := zap.NewProductionConfig() defaultConfig.Level = zap.NewAtomicLevelAt(getZapLogLevelFromString(config.Level)) logger, err := zap.NewProductionConfig().Build() - return logger, err + if err != nil { + return err + } + // Setting up global Logger. This can be accessed by zap.L() + zap.ReplaceGlobals(logger) + return nil } func getZapLogLevelFromString(level string) zapcore.Level { diff --git a/pkg/telemetry/telemetry.go b/pkg/telemetry/telemetry.go index 9a76827c..77c49ff8 100644 --- a/pkg/telemetry/telemetry.go +++ b/pkg/telemetry/telemetry.go @@ -31,7 +31,7 @@ type Config struct { // Init initialises OpenCensus based async-telemetry processes and // returns (i.e., it does not block). -func Init(ctx context.Context, cfg Config, lg *zap.Logger) { +func Init(ctx context.Context, cfg Config) { mux := http.NewServeMux() mux.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine")) mux.Handle("/debug/pprof/heap", pprof.Handler("heap")) @@ -39,14 +39,14 @@ func Init(ctx context.Context, cfg Config, lg *zap.Logger) { mux.Handle("/debug/pprof/block", pprof.Handler("block")) if err := setupOpenCensus(ctx, mux, cfg); err != nil { - lg.Error("failed to setup OpenCensus", zap.Error(err)) + zap.L().Error("failed to setup OpenCensus", zap.Error(err)) } if cfg.Debug != "" { go func() { // nolint if err := http.ListenAndServe(cfg.Debug, mux); err != nil { - lg.Error("debug server exited due to error", zap.Error(err)) + zap.L().Error("debug server exited due to error", zap.Error(err)) } }() }