From 45220bd1f17158a96694b53afeb0374f877c3ebf Mon Sep 17 00:00:00 2001 From: Mateusz Urbanek Date: Thu, 12 Dec 2024 09:50:53 +0100 Subject: [PATCH] refactor(driver)!: drop otel libs (#127) ## Description This pull request removes dependency on OTEL instrumentation, to reduce binary size and simplify dependencies. Additionally it updates reference to new COSI repository, so that CRD and Controller can be deployed. N/A Signed-off-by: Mateusz Urbanek --- .golangci.yml | 52 +--- Makefile | 31 +-- cmd/linode-cosi-driver/main.go | 125 ++------- go.mod | 24 +- go.sum | 26 -- hack/tools.go | 1 - helm/linode-cosi-driver/Chart.yaml | 4 +- helm/linode-cosi-driver/README.md | 3 +- .../templates/ConfigMap.yaml | 22 -- .../templates/Deployment.yaml | 11 - helm/linode-cosi-driver/values.schema.json | 4 - helm/linode-cosi-driver/values.yaml | 6 - pkg/grpc/{handlers => }/handlers.go | 5 +- pkg/linodeclient/tracedclient/README.md | 49 ---- .../tracedclient/tracedclient.gen.go | 247 ------------------ .../logger/logger.go => logutils/grpc.go} | 22 +- .../logger/logger.go => logutils/maxprocs.go} | 13 +- .../logger/logger.go => logutils/resty.go} | 6 +- pkg/observability/metrics/metrics.go | 50 ---- pkg/observability/observability.go | 23 -- pkg/observability/tracing/tracing.go | 82 ------ pkg/servers/identity/identity.go | 2 +- pkg/servers/identity/metrics.go | 31 --- pkg/servers/provisioner/consts.go | 1 - pkg/servers/provisioner/metrics.go | 31 --- pkg/servers/provisioner/provisioner.go | 132 +++------- .../provisionerintegration_test.go | 3 +- scripts/release-gen.sh | 26 -- 28 files changed, 113 insertions(+), 919 deletions(-) delete mode 100644 helm/linode-cosi-driver/templates/ConfigMap.yaml rename pkg/grpc/{handlers => }/handlers.go (97%) delete mode 100644 pkg/linodeclient/tracedclient/README.md delete mode 100644 pkg/linodeclient/tracedclient/tracedclient.gen.go rename pkg/{grpc/logger/logger.go => logutils/grpc.go} (66%) rename pkg/{maxprocs/logger/logger.go => logutils/maxprocs.go} (71%) rename pkg/{resty/logger/logger.go => logutils/resty.go} (91%) delete mode 100644 pkg/observability/metrics/metrics.go delete mode 100644 pkg/observability/observability.go delete mode 100644 pkg/observability/tracing/tracing.go delete mode 100644 pkg/servers/identity/metrics.go delete mode 100644 pkg/servers/provisioner/metrics.go delete mode 100755 scripts/release-gen.sh diff --git a/.golangci.yml b/.golangci.yml index 09d986b..87d8509 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,94 +1,60 @@ run: - # Timeout for analysis, e.g. 30s, 5m. timeout: 5m - - # Include test files. tests: true - - # List of build tags to pass to all linters. build-tags: - integration issues: - # Set to 0 to not skip any issues. max-issues-per-linter: 0 - - # Set to 0 to not skip any issues. max-same-issues: 0 output: - # Sort results by: filepath, then line, then column. sort-results: true - - # Make issues output unique by line. uniq-by-line: false linters: - # Enable specific linter enable: - # Detect context.Context contained in structs. - containedctx - # Check whether a function uses a non-inherited context. - contextcheck - # Find declarations and assignments with too many blank identifiers. - dogsled - # Check for unchecked errors. - errcheck - # Find code that will cause problems with the error wrapping scheme. - errorlint - # Inspects source code for security problems. + - gci - gosec - # Check that compiler directives are valid. - gocheckcompilerdirectives - # Calculate cognitive complexities of functions. - gocognit - # Find repeated strings that could be replaced by a constant. - goconst - # Provides functionalities missing from other linters. - gocritic - # Calculates cyclomatic complexity of a function. - gocyclo - # Check if comments end with a dot. - godot - # A stricter replacement for gofmt. - gofumpt - # Simplify the code. - gosimple - # Check for correctness of programs. - govet - # Detect ineffectual assignments. - ineffassign - # Correct commonly misspelled English words in source files. - misspell - # Magic Number Detector. - mnd - # Finds the code that returns nil even if it checks that the error is not nil. - nilerr - # Checks that there is no simultaneous return of nil error and an invalid value. - nilnil - # Find incorrect usages of t.Parallel(). - paralleltest - # Reports direct reads from proto message fields when getters should be used. - protogetter - # Drop-in replacement of golint. - revive - # Ensure consistent code style when using log/slog. - sloglint - # Find bugs and performance issues statically. - staticcheck - # Checks Go code for unused constants, variables, functions and types. - unused - # Empty lines linter. - wsl -# Setting of specific linters. linters-settings: paralleltest: - # Ignore missing calls to `t.Parallel()` and only report incorrect uses of it. ignore-missing: false sloglint: - # Enforce using key-value pairs only (incompatible with attr-only). kv-only: true - # Enforce a single key naming convention. key-naming-case: snake + + gci: + sections: + - standard + - default + - blank + - dot + - prefix(github.com/linode) diff --git a/Makefile b/Makefile index 4782840..7785cf1 100644 --- a/Makefile +++ b/Makefile @@ -19,8 +19,8 @@ PLATFORM ?= linux/$(shell go env GOARCH) CHAINSAW_ARGS ?= # Versions of COSI dependencies -CRD_VERSION := v0.1.0 -CONTROLLER_VERSION := v0.1.2-alpha1 +CRD_VERSION := 7ddc93baaa3f08c9c8990a17c7b958955d93c044 +CONTROLLER_VERSION := 7ddc93baaa3f08c9c8990a17c7b958955d93c044 # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) @@ -46,7 +46,7 @@ SHELL = /usr/bin/env bash -o pipefail .SHELLFLAGS = -ec .PHONY: all -all: generate +all: build .PHONY: clean clean: @@ -78,12 +78,8 @@ help: ## Display this help. ##@ Development -.PHONY: generate -generate: gowrap # Generate code. - go generate ./... - .PHONY: build -build: generate # Build the binary. +build: # Build the binary. ${GO_SETTINGS} go build \ ${GOFLAGS} \ -ldflags="${LDFLAGS}" \ @@ -103,14 +99,14 @@ generate-schemas: helm-values-schema-json ## Run generate schema for Helm Chart -output=helm/linode-cosi-driver/values.schema.json \ .PHONY: test -test: generate ## Run tests. +test: ## Run tests. go test \ -race \ -cover -covermode=atomic -coverprofile=coverage.out \ ./... .PHONY: test-integration -test-integration: generate ## Run integration tests. +test-integration: ## Run integration tests. go test \ -tags=integration \ -race \ @@ -174,13 +170,13 @@ cluster-reset: kind ctlptl .PHONY: deploy-deps deploy-deps: ## Deploy all dependencies of Linode COSI Driver. This step installs CRDs and Controller. - kubectl apply -k github.com/kubernetes-sigs/container-object-storage-interface-api/?ref=${CRD_VERSION} - kubectl apply -k github.com/kubernetes-sigs/container-object-storage-interface-controller/?ref=${CONTROLLER_VERSION} + kubectl apply -k github.com/kubernetes-sigs/container-object-storage-interface/?ref=${CRD_VERSION} + kubectl apply -k github.com/kubernetes-sigs/container-object-storage-interface//controller?ref=${CONTROLLER_VERSION} .PHONY: undeploy-deps undeploy-deps: ## Deploy all dependencies of Linode COSI Driver. This step installs CRDs and Controller. - kubectl delete -k github.com/kubernetes-sigs/container-object-storage-interface-controller/?ref=${CONTROLLER_VERSION} - kubectl delete -k github.com/kubernetes-sigs/container-object-storage-interface-api/?ref=${CRD_VERSION} + kubectl delete -k github.com/kubernetes-sigs/container-object-storage-interface/?ref=${CONTROLLER_VERSION} + kubectl delete -k github.com/kubernetes-sigs/container-object-storage-interface//controller?ref=${CRD_VERSION} .PHONY: deploy deploy: helm ## Deploy driver to the K8s cluster specified in ~/.kube/config. @@ -202,7 +198,6 @@ KUBECTL ?= kubectl CHAINSAW ?= $(LOCALBIN)/chainsaw CTLPTL ?= $(LOCALBIN)/ctlptl GOLANGCI_LINT ?= $(LOCALBIN)/golangci-lint -GOWRAP ?= $(LOCALBIN)/gowrap HELM ?= $(LOCALBIN)/helm HELM_DOCS ?= $(LOCALBIN)/helm-docs HELM_VALUES_SCHEMA_JSON ?= $(LOCALBIN)/helm-values-schema-json @@ -213,7 +208,6 @@ KUBE_LINTER ?= $(LOCALBIN)/kube-linter CHAINSAW_VERSION ?= $(shell grep 'github.com/kyverno/chainsaw ' ./go.mod | cut -d ' ' -f 2) CTLPTL_VERSION ?= $(shell grep 'github.com/tilt-dev/ctlptl ' ./go.mod | cut -d ' ' -f 2) GOLANGCI_LINT_VERSION ?= $(shell grep 'github.com/golangci/golangci-lint ' ./go.mod | cut -d ' ' -f 2) -GOWRAP_VERSION ?= $(shell grep 'github.com/hexdigest/gowrap ' ./go.mod | cut -d ' ' -f 2) HELM_VERSION ?= $(shell grep 'helm.sh/helm/v3 ' ./go.mod | cut -d ' ' -f 2) HELM_DOCS_VERSION ?= $(shell grep 'github.com/norwoodj/helm-docs ' ./go.mod | cut -d ' ' -f 2) HELM_VALUES_SCHEMA_JSON_VERSION ?= $(shell grep 'github.com/losisin/helm-values-schema-json ' ./go.mod | cut -d ' ' -f 2) @@ -235,11 +229,6 @@ golangci-lint: $(GOLANGCI_LINT)$(GOLANGCI_LINT_VERSION) ## Download golangci-lin $(GOLANGCI_LINT)$(GOLANGCI_LINT_VERSION): $(LOCALBIN) $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION)) -.PHONY: gowrap -gowrap: $(GOWRAP)$(GOWRAP_VERSION) ## Download gowrap locally if necessary. -$(GOWRAP)$(GOWRAP_VERSION): $(LOCALBIN) - $(call go-install-tool,$(GOWRAP),github.com/hexdigest/gowrap/cmd/gowrap,$(GOWRAP_VERSION)) - .PHONY: helm helm: $(HELM)$(HELM_VERSION) ## Download helm locally if necessary. $(HELM)$(HELM_VERSION): $(LOCALBIN) diff --git a/cmd/linode-cosi-driver/main.go b/cmd/linode-cosi-driver/main.go index c50cf40..46108d6 100644 --- a/cmd/linode-cosi-driver/main.go +++ b/cmd/linode-cosi-driver/main.go @@ -22,32 +22,24 @@ import ( "net/url" "os" "os/signal" - "strings" "sync" "syscall" "time" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery" + "go.uber.org/automaxprocs/maxprocs" + "google.golang.org/grpc" + cosi "sigs.k8s.io/container-object-storage-interface-spec" + "github.com/linode/linode-cosi-driver/pkg/endpoint" "github.com/linode/linode-cosi-driver/pkg/envflag" - "github.com/linode/linode-cosi-driver/pkg/grpc/handlers" - grpclogger "github.com/linode/linode-cosi-driver/pkg/grpc/logger" + grpchandlers "github.com/linode/linode-cosi-driver/pkg/grpc" "github.com/linode/linode-cosi-driver/pkg/linodeclient" - "github.com/linode/linode-cosi-driver/pkg/linodeclient/tracedclient" - maxprocslogger "github.com/linode/linode-cosi-driver/pkg/maxprocs/logger" - "github.com/linode/linode-cosi-driver/pkg/observability/metrics" - "github.com/linode/linode-cosi-driver/pkg/observability/tracing" - restylogger "github.com/linode/linode-cosi-driver/pkg/resty/logger" + "github.com/linode/linode-cosi-driver/pkg/logutils" "github.com/linode/linode-cosi-driver/pkg/servers/identity" "github.com/linode/linode-cosi-driver/pkg/servers/provisioner" "github.com/linode/linode-cosi-driver/pkg/version" - "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" - "go.opentelemetry.io/otel/sdk/resource" - semconv "go.opentelemetry.io/otel/semconv/v1.21.0" - "go.uber.org/automaxprocs/maxprocs" - "google.golang.org/grpc" - cosi "sigs.k8s.io/container-object-storage-interface-spec" ) const ( @@ -75,7 +67,7 @@ func main() { linodeAPIVersion: linodeAPIVersion, }, ); err != nil { - slog.Error("critical failure", "error", err) + slog.Error("Critical failure", "error", err) os.Exit(1) } } @@ -88,7 +80,7 @@ type mainOptions struct { } func run(ctx context.Context, log *slog.Logger, opts mainOptions) error { - _, err := maxprocs.Set(maxprocs.Logger(maxprocslogger.Wrap(log.Handler()))) + _, err := maxprocs.Set(maxprocs.Logger(logutils.ForMaxprocs(log.Handler()))) if err != nil { return fmt.Errorf("setting GOMAXPROCS failed: %w", err) } @@ -100,9 +92,6 @@ func run(ctx context.Context, log *slog.Logger, opts mainOptions) error { ) defer stop() - o11yShutdown := setupObservabillity(ctx, log) - defer o11yShutdown() - // create identity server idSrv, err := identity.New(driverName) if err != nil { @@ -119,12 +108,12 @@ func run(ctx context.Context, log *slog.Logger, opts mainOptions) error { return fmt.Errorf("unable to create new client: %w", err) } - client.SetLogger(restylogger.Wrap(log)) + client.SetLogger(logutils.ForResty(log)) // create provisioner server prvSrv, err := provisioner.New( log, - tracedclient.NewClientWithTracing(client, os.Getenv(envK8sPodName)), + client, ) if err != nil { return fmt.Errorf("failed to create provisioner server: %w", err) @@ -158,7 +147,7 @@ func run(ctx context.Context, log *slog.Logger, opts mainOptions) error { go shutdown(ctx, &wg, srv) - slog.Info("starting server", + slog.Info("Starting server", "endpoint", endpointURL, "version", version.Version) @@ -178,10 +167,9 @@ func grpcServer(ctx context.Context, provisioner cosi.ProvisionerServer, ) (*grpc.Server, error) { server := grpc.NewServer( - grpc.StatsHandler(otelgrpc.NewServerHandler()), grpc.ChainUnaryInterceptor( - logging.UnaryServerInterceptor(grpclogger.Wrap(log.Handler())), - recovery.UnaryServerInterceptor(recovery.WithRecoveryHandler(handlers.PanicRecovery(ctx, log.Handler()))), + logging.UnaryServerInterceptor(logutils.ForGRPC(log.Handler())), + recovery.UnaryServerInterceptor(recovery.WithRecoveryHandler(grpchandlers.PanicRecovery(ctx, log.Handler()))), ), ) @@ -202,9 +190,9 @@ func shutdown(ctx context.Context, ) { <-ctx.Done() defer wg.Done() - defer slog.Info("stopped") + defer slog.Info("Stopped") - slog.Info("shutting down") + slog.Info("Shutting down") dctx, stop := context.WithTimeout(context.Background(), gracePeriod) defer stop() @@ -220,7 +208,7 @@ func shutdown(ctx context.Context, for { select { case <-dctx.Done(): - slog.Warn("forcing shutdown") + slog.Warn("Forcing shutdown") g.Stop() return @@ -230,84 +218,3 @@ func shutdown(ctx context.Context, } } } - -func setupObservabillity(ctx context.Context, log *slog.Logger) func() { - node := os.Getenv(envK8sNodeName) - pod := os.Getenv(envK8sPodName) - - res := resource.NewWithAttributes( - semconv.SchemaURL, - semconv.ServiceName(driverName), - semconv.ServiceVersion(version.Version), - semconv.K8SPodName(pod), - semconv.K8SNodeName(node), - ) - - tracingShutdown, err := tracing.Setup(ctx, res) - if err != nil { - // non critical error, just log it. - log.Error("failed to setup tracing", - "error", err, - ) - } - - metricsShutdown, err := metrics.Setup(ctx, res) - if err != nil { - // non critical error, just log it. - log.Error("failed to setup metrics", - "error", err, - ) - } - - attrs := []any{} - - for _, kv := range os.Environ() { - k, v, ok := strings.Cut(kv, "=") - if ok && strings.HasPrefix(k, "OTEL_") { - attrs = append(attrs, slog.String(k, v)) - } - } - - log.Info("opentelemetry configuration applied", - attrs..., - ) - - return func() { - timeout := 25 * time.Second // nolint:mnd // 2.5x default OTLP timeout - - ctx, cancel := context.WithTimeout(context.WithoutCancel(ctx), timeout) - defer cancel() - - wg := &sync.WaitGroup{} - - if tracingShutdown != nil { - wg.Add(1) - - go func() { - defer wg.Done() - - if err := tracingShutdown(ctx); err != nil { - log.Error("failed to shutdown tracing", - "error", err, - ) - } - }() - } - - if metricsShutdown != nil { - wg.Add(1) - - go func() { - defer wg.Done() - - if err := tracingShutdown(ctx); err != nil { - log.Error("failed to shutdown tracing", - "error", err, - ) - } - }() - } - - wg.Wait() - } -} diff --git a/go.mod b/go.mod index 45dfd1f..9343e63 100644 --- a/go.mod +++ b/go.mod @@ -6,13 +6,6 @@ require ( github.com/go-resty/resty/v2 v2.16.0 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 github.com/linode/linodego v1.43.0 - go.opentelemetry.io/contrib/exporters/autoexport v0.57.0 - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.57.0 - go.opentelemetry.io/otel v1.32.0 - go.opentelemetry.io/otel/metric v1.32.0 - go.opentelemetry.io/otel/sdk v1.32.0 - go.opentelemetry.io/otel/sdk/metric v1.32.0 - go.opentelemetry.io/otel/trace v1.32.0 go.uber.org/automaxprocs v1.6.0 google.golang.org/grpc v1.68.0 sigs.k8s.io/container-object-storage-interface-spec v0.1.0 @@ -21,7 +14,6 @@ require ( // tools require ( github.com/golangci/golangci-lint v1.62.2 - github.com/hexdigest/gowrap v1.4.0 github.com/kyverno/chainsaw v0.2.11 github.com/losisin/helm-values-schema-json v1.6.4 github.com/norwoodj/helm-docs v1.14.2 @@ -353,21 +345,17 @@ require ( go.etcd.io/etcd/client/pkg/v3 v3.5.15 // indirect go.etcd.io/etcd/client/v3 v3.5.15 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/bridges/prometheus v0.57.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.57.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0 // indirect + go.opentelemetry.io/otel v1.32.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.54.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.8.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 // indirect - go.opentelemetry.io/otel/log v0.8.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.8.0 // indirect + go.opentelemetry.io/otel/metric v1.32.0 // indirect + go.opentelemetry.io/otel/sdk v1.32.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.32.0 // indirect + go.opentelemetry.io/otel/trace v1.32.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect diff --git a/go.sum b/go.sum index f5fe071..a46a5d5 100644 --- a/go.sum +++ b/go.sum @@ -588,8 +588,6 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/gojuno/minimock/v3 v3.0.10 h1:0UbfgdLHaNRPHWF/RFYPkwxV2KI+SE4tR0dDSFMD7+A= -github.com/gojuno/minimock/v3 v3.0.10/go.mod h1:CFXcUJYnBe+1QuNzm+WmdPYtvi/+7zQcPcyQGsbcIXg= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= @@ -806,8 +804,6 @@ github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= -github.com/hexdigest/gowrap v1.4.0 h1:Zjhnl1omZXJs40S1K0gaWQjvO9ADy3u1sGqLkYJNcP8= -github.com/hexdigest/gowrap v1.4.0/go.mod h1:uOPX6MbEZnYtf5i5/+rS0Aj8NC3P/V594uaoaiMMbRg= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -1380,46 +1376,24 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/bridges/prometheus v0.57.0 h1:UW0+QyeyBVhn+COBec3nGhfnFe5lwB0ic1JBVjzhk0w= -go.opentelemetry.io/contrib/bridges/prometheus v0.57.0/go.mod h1:ppciCHRLsyCio54qbzQv0E4Jyth/fLWDTJYfvWpcSVk= -go.opentelemetry.io/contrib/exporters/autoexport v0.57.0 h1:jmTVJ86dP60C01K3slFQa2NQ/Aoi7zA+wy7vMOKD9H4= -go.opentelemetry.io/contrib/exporters/autoexport v0.57.0/go.mod h1:EJBheUMttD/lABFyLXhce47Wr6DPWYReCzaZiXadH7g= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.57.0 h1:qtFISDHKolvIxzSs0gIaiPUPR0Cucb0F2coHC7ZLdps= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.57.0/go.mod h1:Y+Pop1Q6hCOnETWTW4NROK/q1hv50hM7yDaUTjG8lp8= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 h1:ZIg3ZT/aQ7AfKqdwp7ECpOK6vHqquXXuyTjIO8ZdmPs= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI= go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 h1:WzNab7hOOLzdDF/EoWCt4glhrbMPVMOO5JYTmpz36Ls= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0/go.mod h1:hKvJwTzJdp90Vh7p6q/9PAOd55dI6WA6sWj62a/JvSs= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0 h1:S+LdBGiQXtJdowoJoQPEtI52syEP/JYBUpjO49EQhV8= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0/go.mod h1:5KXybFvPGds3QinJWQT7pmXf+TN5YIa7CNYObWRkj50= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 h1:j7ZSD+5yn+lo3sGV69nW04rRR0jhYnBwjuX3r0HvnK0= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0/go.mod h1:WXbYJTUaZXAbYd8lbgGuvih0yuCfOFC5RJoYnoLcGz8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 h1:t/Qur3vKSkUCcDVaSumWF2PKHt85pc7fRvFuoVT8qFU= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0/go.mod h1:Rl61tySSdcOJWoEgYZVtmnKdA0GeKrSqkHC1t+91CH8= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 h1:IJFEoHiytixx8cMiVAO+GmHR6Frwu+u5Ur8njpFO6Ac= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0/go.mod h1:3rHrKNtLIoS0oZwkY2vxi+oJcwFRWdtUyRII+so45p8= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 h1:9kV11HXBHZAvuPUZxmMWrH8hZn/6UnHX4K0mu36vNsU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0/go.mod h1:JyA0FHXe22E1NeNiHmVp7kFHglnexDQ7uRWDiiJ1hKQ= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 h1:cMyu9O88joYEaI47CnQkxO1XZdpoTF9fEnW2duIddhw= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0/go.mod h1:6Am3rn7P9TVVeXYG+wtcGE7IE1tsQ+bP3AuWcKt/gOI= -go.opentelemetry.io/otel/exporters/prometheus v0.54.0 h1:rFwzp68QMgtzu9PgP3jm9XaMICI6TsofWWPcBDKwlsU= -go.opentelemetry.io/otel/exporters/prometheus v0.54.0/go.mod h1:QyjcV9qDP6VeK5qPyKETvNjmaaEc7+gqjh4SS0ZYzDU= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.8.0 h1:CHXNXwfKWfzS65yrlB2PVds1IBZcdsX8Vepy9of0iRU= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.8.0/go.mod h1:zKU4zUgKiaRxrdovSS2amdM5gOc59slmo/zJwGX+YBg= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0 h1:SZmDnHcgp3zwlPBS2JX2urGYe/jBKEIT6ZedHRUyCz8= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0/go.mod h1:fdWW0HtZJ7+jNpTKUR0GpMEDP69nR8YBJQxNiVCE3jk= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 h1:cC2yDI3IQd0Udsux7Qmq8ToKAx1XCilTQECZ0KDZyTw= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0/go.mod h1:2PD5Ex6z8CFzDbTdOlwyNIUywRr1DN0ospafJM1wJ+s= -go.opentelemetry.io/otel/log v0.8.0 h1:egZ8vV5atrUWUbnSsHn6vB8R21G2wrKqNiDt3iWertk= -go.opentelemetry.io/otel/log v0.8.0/go.mod h1:M9qvDdUTRCopJcGRKg57+JSQ9LgLBrwwfC32epk5NX8= go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= -go.opentelemetry.io/otel/sdk/log v0.8.0 h1:zg7GUYXqxk1jnGF/dTdLPrK06xJdrXgqgFLnI4Crxvs= -go.opentelemetry.io/otel/sdk/log v0.8.0/go.mod h1:50iXr0UVwQrYS45KbruFrEt4LvAdCaWWgIrsN3ZQggo= go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= diff --git a/hack/tools.go b/hack/tools.go index d494120..9490f39 100644 --- a/hack/tools.go +++ b/hack/tools.go @@ -5,7 +5,6 @@ package hack import ( _ "github.com/golangci/golangci-lint/cmd/golangci-lint" - _ "github.com/hexdigest/gowrap/cmd/gowrap" _ "github.com/kyverno/chainsaw" _ "github.com/losisin/helm-values-schema-json" _ "github.com/norwoodj/helm-docs/cmd/helm-docs" diff --git a/helm/linode-cosi-driver/Chart.yaml b/helm/linode-cosi-driver/Chart.yaml index 5c521a5..95b312c 100644 --- a/helm/linode-cosi-driver/Chart.yaml +++ b/helm/linode-cosi-driver/Chart.yaml @@ -2,5 +2,5 @@ apiVersion: v2 name: linode-cosi-driver description: A Kubernetes Container Object Storage Interface (COSI) Driver for Linode type: application -version: 0.3.0 -appVersion: v0.5.0 +version: 0.4.0 +appVersion: v0.6.0 diff --git a/helm/linode-cosi-driver/README.md b/helm/linode-cosi-driver/README.md index d9366ec..3f66f21 100644 --- a/helm/linode-cosi-driver/README.md +++ b/helm/linode-cosi-driver/README.md @@ -1,6 +1,6 @@ # linode-cosi-driver -![Version: 0.3.0](https://img.shields.io/badge/Version-0.3.0-informational?style=flat) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat) ![AppVersion: v0.5.0](https://img.shields.io/badge/AppVersion-v0.5.0-informational?style=flat) +![Version: 0.4.0](https://img.shields.io/badge/Version-0.4.0-informational?style=flat) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat) ![AppVersion: v0.6.0](https://img.shields.io/badge/AppVersion-v0.6.0-informational?style=flat) A Kubernetes Container Object Storage Interface (COSI) Driver for Linode @@ -13,7 +13,6 @@ A Kubernetes Container Object Storage Interface (COSI) Driver for Linode | driver.image.pullPolicy | string | `"IfNotPresent"` | Driver container image pull policy. | | driver.image.repository | string | `"docker.io/linode/linode-cosi-driver"` | Driver container image repository. | | driver.image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. | -| driver.otelConfig | object | `{}` | OpenTelemetry configuration. All values defined here conform to the OTEL specification, and are not strictly defined in the Chart values. | | fullnameOverride | string | `""` | Overrides the full chart name. | | imagePullSecrets | list | `[]` | List of Docker registry secret names to pull images. | | linodeApiUrl | string | `""` | Linode API URL, leave empty for default. | diff --git a/helm/linode-cosi-driver/templates/ConfigMap.yaml b/helm/linode-cosi-driver/templates/ConfigMap.yaml deleted file mode 100644 index 77a8987..0000000 --- a/helm/linode-cosi-driver/templates/ConfigMap.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "linode-cosi-driver.name" . }} - namespace: {{ .Release.Namespace }} - labels: - {{- include "linode-cosi-driver.labels" . | trim | nindent 4 }} - {{- with .Values.secret.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -data: - {{- if ne (len (keys .Values.driver.otelConfig)) 0 }} - {{- range $key, $val := .Values.driver.otelConfig }} - {{- $key | nindent 2 }}: {{ quote $val }} - {{- end }} - {{- else }} - OTEL_TRACES_EXPORTER: "none" - OTEL_METRICS_EXPORTER: "prometheus" - OTEL_EXPORTER_PROMETHEUS_HOST: "0.0.0.0" - OTEL_EXPORTER_PROMETHEUS_PORT: "9464" - {{- end }} diff --git a/helm/linode-cosi-driver/templates/Deployment.yaml b/helm/linode-cosi-driver/templates/Deployment.yaml index 7c05f6f..2a36bb3 100644 --- a/helm/linode-cosi-driver/templates/Deployment.yaml +++ b/helm/linode-cosi-driver/templates/Deployment.yaml @@ -55,17 +55,6 @@ spec: envFrom: - secretRef: name: {{ include "linode-cosi-driver.secretName" . }} - - configMapRef: - name: {{ include "linode-cosi-driver.name" . }} - env: - - name: K8S_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - - name: K8S_POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name volumeMounts: - name: cosi-socket-dir mountPath: /var/lib/cosi diff --git a/helm/linode-cosi-driver/values.schema.json b/helm/linode-cosi-driver/values.schema.json index 258b81d..2eb7f28 100644 --- a/helm/linode-cosi-driver/values.schema.json +++ b/helm/linode-cosi-driver/values.schema.json @@ -23,10 +23,6 @@ } }, "type": "object" - }, - "otelConfig": { - "properties": {}, - "type": "object" } }, "type": "object" diff --git a/helm/linode-cosi-driver/values.yaml b/helm/linode-cosi-driver/values.yaml index c345f4b..9a36510 100644 --- a/helm/linode-cosi-driver/values.yaml +++ b/helm/linode-cosi-driver/values.yaml @@ -25,12 +25,6 @@ driver: # -- Overrides the image tag whose default is the chart appVersion. tag: "" - # -- OpenTelemetry configuration. All values defined here conform to the OTEL specification, and are not strictly defined in the Chart values. - otelConfig: {} - # OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4317" - # OTEL_EXPORTER_OTLP_TIMEOUT: 10000 - # OTEL_EXPORTER_OTLP_PROTOCOL: "grpc" - sidecar: image: # -- Sidecar container image repository. diff --git a/pkg/grpc/handlers/handlers.go b/pkg/grpc/handlers.go similarity index 97% rename from pkg/grpc/handlers/handlers.go rename to pkg/grpc/handlers.go index 1f5b90f..88e486e 100644 --- a/pkg/grpc/handlers/handlers.go +++ b/pkg/grpc/handlers.go @@ -13,7 +13,7 @@ // limitations under the License. // Package handlers includes common HandlerFuncs that can be used around the gRPC environment. -package handlers +package grpc import ( "context" @@ -21,6 +21,7 @@ import ( "runtime/debug" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery" + "github.com/linode/linode-cosi-driver/pkg/logutils" "github.com/linode/linode-cosi-driver/pkg/version" ) @@ -46,7 +47,7 @@ func PanicRecovery(ctx context.Context, handler slog.Handler, callbacks ...func( if logger != nil { logger.Log(ctx, 0, - "Recovered from panic.", + "Recovered from panic", "panic", p, "stack", debug.Stack()) } diff --git a/pkg/linodeclient/tracedclient/README.md b/pkg/linodeclient/tracedclient/README.md deleted file mode 100644 index ccf05c1..0000000 --- a/pkg/linodeclient/tracedclient/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# Traced Client Wrapper - -This package, `tracedclient`, is a generated client wrapper for the Linode Client. The code is generated using the tool `gowrap` with a specified template for OpenTelemetry instrumentation. - -Code generation streamlines development, reduces boilerplate, and enhances consistency. It boosts productivity by automating repetitive tasks, saves time, and simplifies maintenance. It also minimizes errors and enforces standards. - -## Purpose - -1. **Instrumentation with OpenTelemetry:** The primary purpose of this code is to provide an instrumented version of the Linode COSI driver client with OpenTelemetry spans. This is achieved by adding tracing functionality to various methods in the client. - -2. **Observability:** OpenTelemetry is used for distributed tracing, which helps in observing and understanding how requests propagate through a system, making it easier to identify performance bottlenecks and troubleshoot issues. - -## Code Generation - -The code in this package is generated using the `gowrap` tool. To generate the code, you can use the following commands: - -- **Using `go generate`**: - - ```bash - go generate ./... - ``` - - This command will trigger the `go:generate` directives in the code, causing the `gowrap` tool to generate the necessary files. - - Ensure that you have the `gowrap` tool installed before running the code generation command. - -- **Using Makefile**: - - ```bash - make codegen - ``` - - The Makefile target will ensure that the `gowrap` tool is installed. - -## Usage Example - -To use the instrumented client: - -```go -baseClient := linodeclient.NewLinodeClient(token, ua, apiURL, apiVersion) // Initialize the original Linode client -tracedClient := tracedclient.NewClientWithTracing(baseClient, "instance_id") -``` - -Now, `tracedClient` can be used just like the original client, with the added benefit of OpenTelemetry tracing. - -## Links - -- [gowrap](http://github.com/hexdigest/gowrap): The `gowrap` tool used for code generation. -- [OpenTelemetry](https://opentelemetry.io/): OpenTelemetry project for observability and instrumentation. diff --git a/pkg/linodeclient/tracedclient/tracedclient.gen.go b/pkg/linodeclient/tracedclient/tracedclient.gen.go deleted file mode 100644 index 0ae6ecb..0000000 --- a/pkg/linodeclient/tracedclient/tracedclient.gen.go +++ /dev/null @@ -1,247 +0,0 @@ -// Code generated by gowrap. DO NOT EDIT. -// template: https://raw.githubusercontent.com/hexdigest/gowrap/6c8f05695fec23df85903a8da0af66ac414e2a63/templates/opentelemetry -// gowrap: http://github.com/hexdigest/gowrap - -package tracedclient - -//go:generate gowrap gen -p github.com/linode/linode-cosi-driver/pkg/linodeclient -i Client -t https://raw.githubusercontent.com/hexdigest/gowrap/6c8f05695fec23df85903a8da0af66ac414e2a63/templates/opentelemetry -o tracedclient.gen.go -l "" - -import ( - "context" - - _sourceLinodeclient "github.com/linode/linode-cosi-driver/pkg/linodeclient" - "github.com/linode/linodego" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" -) - -// ClientWithTracing implements _sourceLinodeclient.Client interface instrumented with opentracing spans -type ClientWithTracing struct { - _sourceLinodeclient.Client - _instance string - _spanDecorator func(span trace.Span, params, results map[string]interface{}) -} - -// NewClientWithTracing returns ClientWithTracing -func NewClientWithTracing(base _sourceLinodeclient.Client, instance string, spanDecorator ...func(span trace.Span, params, results map[string]interface{})) ClientWithTracing { - d := ClientWithTracing{ - Client: base, - _instance: instance, - } - - if len(spanDecorator) > 0 && spanDecorator[0] != nil { - d._spanDecorator = spanDecorator[0] - } - - return d -} - -// CreateObjectStorageBucket implements _sourceLinodeclient.Client -func (_d ClientWithTracing) CreateObjectStorageBucket(ctx context.Context, o1 linodego.ObjectStorageBucketCreateOptions) (op1 *linodego.ObjectStorageBucket, err error) { - ctx, _span := otel.Tracer(_d._instance).Start(ctx, "_sourceLinodeclient.Client.CreateObjectStorageBucket") - defer func() { - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "o1": o1}, map[string]interface{}{ - "op1": op1, - "err": err}) - } else if err != nil { - _span.RecordError(err) - _span.SetAttributes( - attribute.String("event", "error"), - attribute.String("message", err.Error()), - ) - } - - _span.End() - }() - return _d.Client.CreateObjectStorageBucket(ctx, o1) -} - -// CreateObjectStorageKey implements _sourceLinodeclient.Client -func (_d ClientWithTracing) CreateObjectStorageKey(ctx context.Context, o1 linodego.ObjectStorageKeyCreateOptions) (op1 *linodego.ObjectStorageKey, err error) { - ctx, _span := otel.Tracer(_d._instance).Start(ctx, "_sourceLinodeclient.Client.CreateObjectStorageKey") - defer func() { - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "o1": o1}, map[string]interface{}{ - "op1": op1, - "err": err}) - } else if err != nil { - _span.RecordError(err) - _span.SetAttributes( - attribute.String("event", "error"), - attribute.String("message", err.Error()), - ) - } - - _span.End() - }() - return _d.Client.CreateObjectStorageKey(ctx, o1) -} - -// DeleteObjectStorageBucket implements _sourceLinodeclient.Client -func (_d ClientWithTracing) DeleteObjectStorageBucket(ctx context.Context, s1 string, s2 string) (err error) { - ctx, _span := otel.Tracer(_d._instance).Start(ctx, "_sourceLinodeclient.Client.DeleteObjectStorageBucket") - defer func() { - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "s1": s1, - "s2": s2}, map[string]interface{}{ - "err": err}) - } else if err != nil { - _span.RecordError(err) - _span.SetAttributes( - attribute.String("event", "error"), - attribute.String("message", err.Error()), - ) - } - - _span.End() - }() - return _d.Client.DeleteObjectStorageBucket(ctx, s1, s2) -} - -// DeleteObjectStorageKey implements _sourceLinodeclient.Client -func (_d ClientWithTracing) DeleteObjectStorageKey(ctx context.Context, i1 int) (err error) { - ctx, _span := otel.Tracer(_d._instance).Start(ctx, "_sourceLinodeclient.Client.DeleteObjectStorageKey") - defer func() { - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "i1": i1}, map[string]interface{}{ - "err": err}) - } else if err != nil { - _span.RecordError(err) - _span.SetAttributes( - attribute.String("event", "error"), - attribute.String("message", err.Error()), - ) - } - - _span.End() - }() - return _d.Client.DeleteObjectStorageKey(ctx, i1) -} - -// GetObjectStorageBucket implements _sourceLinodeclient.Client -func (_d ClientWithTracing) GetObjectStorageBucket(ctx context.Context, s1 string, s2 string) (op1 *linodego.ObjectStorageBucket, err error) { - ctx, _span := otel.Tracer(_d._instance).Start(ctx, "_sourceLinodeclient.Client.GetObjectStorageBucket") - defer func() { - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "s1": s1, - "s2": s2}, map[string]interface{}{ - "op1": op1, - "err": err}) - } else if err != nil { - _span.RecordError(err) - _span.SetAttributes( - attribute.String("event", "error"), - attribute.String("message", err.Error()), - ) - } - - _span.End() - }() - return _d.Client.GetObjectStorageBucket(ctx, s1, s2) -} - -// GetObjectStorageBucketAccess implements _sourceLinodeclient.Client -func (_d ClientWithTracing) GetObjectStorageBucketAccess(ctx context.Context, s1 string, s2 string) (op1 *linodego.ObjectStorageBucketAccess, err error) { - ctx, _span := otel.Tracer(_d._instance).Start(ctx, "_sourceLinodeclient.Client.GetObjectStorageBucketAccess") - defer func() { - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "s1": s1, - "s2": s2}, map[string]interface{}{ - "op1": op1, - "err": err}) - } else if err != nil { - _span.RecordError(err) - _span.SetAttributes( - attribute.String("event", "error"), - attribute.String("message", err.Error()), - ) - } - - _span.End() - }() - return _d.Client.GetObjectStorageBucketAccess(ctx, s1, s2) -} - -// GetObjectStorageKey implements _sourceLinodeclient.Client -func (_d ClientWithTracing) GetObjectStorageKey(ctx context.Context, i1 int) (op1 *linodego.ObjectStorageKey, err error) { - ctx, _span := otel.Tracer(_d._instance).Start(ctx, "_sourceLinodeclient.Client.GetObjectStorageKey") - defer func() { - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "i1": i1}, map[string]interface{}{ - "op1": op1, - "err": err}) - } else if err != nil { - _span.RecordError(err) - _span.SetAttributes( - attribute.String("event", "error"), - attribute.String("message", err.Error()), - ) - } - - _span.End() - }() - return _d.Client.GetObjectStorageKey(ctx, i1) -} - -// ListObjectStorageKeys implements _sourceLinodeclient.Client -func (_d ClientWithTracing) ListObjectStorageKeys(ctx context.Context, lp1 *linodego.ListOptions) (oa1 []linodego.ObjectStorageKey, err error) { - ctx, _span := otel.Tracer(_d._instance).Start(ctx, "_sourceLinodeclient.Client.ListObjectStorageKeys") - defer func() { - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "lp1": lp1}, map[string]interface{}{ - "oa1": oa1, - "err": err}) - } else if err != nil { - _span.RecordError(err) - _span.SetAttributes( - attribute.String("event", "error"), - attribute.String("message", err.Error()), - ) - } - - _span.End() - }() - return _d.Client.ListObjectStorageKeys(ctx, lp1) -} - -// UpdateObjectStorageBucketAccess implements _sourceLinodeclient.Client -func (_d ClientWithTracing) UpdateObjectStorageBucketAccess(ctx context.Context, s1 string, s2 string, o1 linodego.ObjectStorageBucketUpdateAccessOptions) (err error) { - ctx, _span := otel.Tracer(_d._instance).Start(ctx, "_sourceLinodeclient.Client.UpdateObjectStorageBucketAccess") - defer func() { - if _d._spanDecorator != nil { - _d._spanDecorator(_span, map[string]interface{}{ - "ctx": ctx, - "s1": s1, - "s2": s2, - "o1": o1}, map[string]interface{}{ - "err": err}) - } else if err != nil { - _span.RecordError(err) - _span.SetAttributes( - attribute.String("event", "error"), - attribute.String("message", err.Error()), - ) - } - - _span.End() - }() - return _d.Client.UpdateObjectStorageBucketAccess(ctx, s1, s2, o1) -} diff --git a/pkg/grpc/logger/logger.go b/pkg/logutils/grpc.go similarity index 66% rename from pkg/grpc/logger/logger.go rename to pkg/logutils/grpc.go index b6a4dbb..e3211ed 100644 --- a/pkg/grpc/logger/logger.go +++ b/pkg/logutils/grpc.go @@ -1,4 +1,4 @@ -// Copyright 2023-2024 Akamai Technologies, Inc. +// Copyright 2024 Akamai Technologies, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,39 +12,39 @@ // See the License for the specific language governing permissions and // limitations under the License. -package logger +package logutils import ( "context" "log/slog" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/linode/linode-cosi-driver/pkg/logutils" + "github.com/linode/linode-cosi-driver/pkg/version" ) const ( - component = "grpc" + componentGrpc = "grpc" ) -type Logger struct { +type GRPCLogger struct { loggerImpl *slog.Logger } -var _ logging.Logger = (*Logger)(nil) +var _ logging.Logger = (*GRPCLogger)(nil) -func Wrap(handler slog.Handler) *Logger { +func ForGRPC(handler slog.Handler) *GRPCLogger { handler = handler.WithAttrs([]slog.Attr{ - slog.String(logutils.KeyComponentName, component), - slog.String(logutils.KeyComponentVersion, version.Version), + slog.String(KeyComponentName, componentGrpc), + slog.String(KeyComponentVersion, version.Version), }) - return &Logger{ + return &GRPCLogger{ loggerImpl: slog.New(handler), } } -func (l *Logger) Log(ctx context.Context, level logging.Level, msg string, fields ...any) { +func (l *GRPCLogger) Log(ctx context.Context, level logging.Level, msg string, fields ...any) { l.loggerImpl.Log(ctx, slog.Level(level), msg, fields...) diff --git a/pkg/maxprocs/logger/logger.go b/pkg/logutils/maxprocs.go similarity index 71% rename from pkg/maxprocs/logger/logger.go rename to pkg/logutils/maxprocs.go index bc2254d..fe1b334 100644 --- a/pkg/maxprocs/logger/logger.go +++ b/pkg/logutils/maxprocs.go @@ -1,4 +1,4 @@ -// Copyright 2023-2024 Akamai Technologies, Inc. +// Copyright 2024 Akamai Technologies, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,24 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -package logger +package logutils import ( "fmt" "log/slog" - "github.com/linode/linode-cosi-driver/pkg/logutils" "go.uber.org/automaxprocs/maxprocs" ) const ( - component = "maxprocs" + componentMaxprocs = "maxprocs" ) -func Wrap(handler slog.Handler) func(msg string, fields ...any) { +func ForMaxprocs(handler slog.Handler) func(msg string, fields ...any) { handler = handler.WithAttrs([]slog.Attr{ - slog.String(logutils.KeyComponentName, component), - slog.String(logutils.KeyComponentVersion, maxprocs.Version), + slog.String(KeyComponentName, componentMaxprocs), + slog.String(KeyComponentVersion, maxprocs.Version), }) log := slog.New(handler) diff --git a/pkg/resty/logger/logger.go b/pkg/logutils/resty.go similarity index 91% rename from pkg/resty/logger/logger.go rename to pkg/logutils/resty.go index 8a63800..bcbd2b8 100644 --- a/pkg/resty/logger/logger.go +++ b/pkg/logutils/resty.go @@ -1,4 +1,4 @@ -// Copyright 2023-2024 Akamai Technologies, Inc. +// Copyright 2024 Akamai Technologies, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package logger +package logutils import ( "fmt" @@ -27,7 +27,7 @@ type Logger struct { var _ resty.Logger = (*Logger)(nil) -func Wrap(logger *slog.Logger) *Logger { +func ForResty(logger *slog.Logger) *Logger { return &Logger{ loggerImpl: logger, } diff --git a/pkg/observability/metrics/metrics.go b/pkg/observability/metrics/metrics.go deleted file mode 100644 index db803aa..0000000 --- a/pkg/observability/metrics/metrics.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2023-2024 Akamai Technologies, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metrics - -import ( - "context" - - "go.opentelemetry.io/contrib/exporters/autoexport" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/metric" - sdkmetric "go.opentelemetry.io/otel/sdk/metric" - "go.opentelemetry.io/otel/sdk/resource" -) - -const meterName = "github.com/linode/linode-cosi-driver/pkg/observability/metrics" - -func Setup(ctx context.Context, resource *resource.Resource) (_ func(context.Context) error, err error) { - reader, err := autoexport.NewMetricReader(ctx) - if err != nil { - return nil, err - } - - options := []sdkmetric.Option{ - sdkmetric.WithReader(reader), - } - if resource != nil { - options = append(options, sdkmetric.WithResource(resource)) - } - - mp := sdkmetric.NewMeterProvider(options...) - otel.SetMeterProvider(mp) - - return mp.Shutdown, nil -} - -func Meter() metric.Meter { - return otel.Meter(meterName) -} diff --git a/pkg/observability/observability.go b/pkg/observability/observability.go deleted file mode 100644 index 6db4be5..0000000 --- a/pkg/observability/observability.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2023-2024 Akamai Technologies, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package observability - -const ( - ProtoGRPC = "grpc" - ProtoHTTPJSON = "http/json" - ProtoHTTPProtobuf = "http/protobuf" -) - -var OTLPProtocols = []string{ProtoGRPC, ProtoHTTPJSON, ProtoHTTPProtobuf} diff --git a/pkg/observability/tracing/tracing.go b/pkg/observability/tracing/tracing.go deleted file mode 100644 index e0e4fea..0000000 --- a/pkg/observability/tracing/tracing.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2023-2024 Akamai Technologies, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package tracing - -import ( - "context" - "fmt" - - "go.opentelemetry.io/contrib/exporters/autoexport" - "go.opentelemetry.io/otel" - otelcodes "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/propagation" - "go.opentelemetry.io/otel/sdk/resource" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - "go.opentelemetry.io/otel/trace" - grpccodes "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -const ( - tracerName = "github.com/linode/linode-cosi-driver/pkg/observability/tracing" - defaultSamplingRatio = 1 -) - -func Setup(ctx context.Context, resource *resource.Resource) (_ func(context.Context) error, err error) { - exporter, err := autoexport.NewSpanExporter(ctx) - if err != nil { - return nil, err - } - - options := []sdktrace.TracerProviderOption{ - sdktrace.WithBatcher(exporter), - } - if resource != nil { - options = append(options, sdktrace.WithResource(resource)) - } - - tp := sdktrace.NewTracerProvider(options...) - otel.SetTracerProvider(tp) - - // set global propagator to tracecontext (the default is no-op). - otel.SetTextMapPropagator(propagation.TraceContext{}) - - // Shutdown will flush any remaining spans and shut down the exporter. - return tp.Shutdown, nil -} - -func Start(ctx context.Context, name string) (context.Context, trace.Span) { - return otel.Tracer(tracerName).Start(ctx, name) -} - -// Error returns an error representing code and error message and records new event on the span. -// If code is OK, returns nil. -func Error(span trace.Span, code grpccodes.Code, err error, events ...string) error { - if span != nil { - for _, event := range events { - span.AddEvent(event) - } - } - - if err != nil && span != nil { - span.RecordError(err) - - if code != grpccodes.OK { - span.SetStatus(otelcodes.Error, err.Error()) - } - } - - return status.Error(code, fmt.Sprintf("%v", err)) -} diff --git a/pkg/servers/identity/identity.go b/pkg/servers/identity/identity.go index 15d24b6..1e53916 100644 --- a/pkg/servers/identity/identity.go +++ b/pkg/servers/identity/identity.go @@ -41,7 +41,7 @@ func New(driverName string) (*Server, error) { name: driverName, } - return srv, srv.registerMetrics() + return srv, nil } // DriverGetInfo call is meant to retrieve the unique provisioner Identity. diff --git a/pkg/servers/identity/metrics.go b/pkg/servers/identity/metrics.go deleted file mode 100644 index 3e42ffa..0000000 --- a/pkg/servers/identity/metrics.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2023-2024 Akamai Technologies, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package identity - -import "github.com/linode/linode-cosi-driver/pkg/observability/metrics" - -// registerMetrics is the common place of registering new metrics to the server. -// When creating new metrics from the meter1, we call something like: -// -// counter, err := meter.Float64Counter("example") -// -// As we expect the metrics to be registered, it is important to return and handle the error. -func (s *Server) registerMetrics() error { - _ = metrics.Meter() - - // TODO: any new metrics should be placed here. - - return nil -} diff --git a/pkg/servers/provisioner/consts.go b/pkg/servers/provisioner/consts.go index 704dcb6..778f40a 100644 --- a/pkg/servers/provisioner/consts.go +++ b/pkg/servers/provisioner/consts.go @@ -61,7 +61,6 @@ const ( var ( ErrNotFound = linodego.Error{Code: http.StatusNotFound} - ErrBucketExists = errors.New("bucket exists with different parameters") ErrUnsuportedAuth = errors.New("unsupported authentication schema") ErrMissingRegion = errors.New("region was not provided") ErrUnknownPermsissions = errors.New("unknown permissions") diff --git a/pkg/servers/provisioner/metrics.go b/pkg/servers/provisioner/metrics.go deleted file mode 100644 index 1973158..0000000 --- a/pkg/servers/provisioner/metrics.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2023-2024 Akamai Technologies, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package provisioner - -import "github.com/linode/linode-cosi-driver/pkg/observability/metrics" - -// registerMetrics is the common place of registering new metrics to the server. -// When creating new metrics from the meter1, we call something like: -// -// counter, err := meter.Float64Counter("example") -// -// As we expect the metrics to be registered, it is important to return and handle the error. -func (s *Server) registerMetrics() error { - _ = metrics.Meter() - - // TODO: any new metrics should be placed here. - - return nil -} diff --git a/pkg/servers/provisioner/provisioner.go b/pkg/servers/provisioner/provisioner.go index d1f4bff..f6e2ddd 100644 --- a/pkg/servers/provisioner/provisioner.go +++ b/pkg/servers/provisioner/provisioner.go @@ -22,13 +22,12 @@ import ( "strconv" "sync" - "github.com/linode/linode-cosi-driver/pkg/linodeclient" - "github.com/linode/linode-cosi-driver/pkg/observability/tracing" - "github.com/linode/linodego" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" cosi "sigs.k8s.io/container-object-storage-interface-spec" + + "github.com/linode/linode-cosi-driver/pkg/linodeclient" + "github.com/linode/linodego" ) // Server implements cosi.ProvisionerServer interface. @@ -49,21 +48,16 @@ func New(logger *slog.Logger, client linodeclient.Client) (*Server, error) { client: client, } - return srv, srv.registerMetrics() + return srv, nil } -// init checks if logger was initialized and starts new span. -func (s *Server) init(ctx context.Context, caller string) (context.Context, trace.Span) { +func (s *Server) logAttr(attr ...slog.Attr) *slog.Logger { s.once.Do(func() { if s.log == nil { s.log = slog.Default() } }) - return tracing.Start(ctx, caller) -} - -func (s *Server) logAttr(attr ...slog.Attr) *slog.Logger { return slog.New(s.log.Handler().WithAttrs(attr)) } @@ -73,9 +67,6 @@ func (s *Server) logAttr(attr ...slog.Attr) *slog.Logger { // 1. If a bucket that matches both name and parameters already exists, then OK (success) must be returned. // 2. If a bucket by same name, but different parameters is provided, then the appropriate error code ALREADY_EXISTS must be returned. func (s *Server) DriverCreateBucket(ctx context.Context, req *cosi.DriverCreateBucketRequest) (*cosi.DriverCreateBucketResponse, error) { - ctx, span := s.init(ctx, "DriverCreateBucket") - defer span.End() - label := req.GetName() region := req.GetParameters()[ParamRegion] cors := ParamCORSValue(req.GetParameters()[ParamCORS]) @@ -90,24 +81,19 @@ func (s *Server) DriverCreateBucket(ctx context.Context, req *cosi.DriverCreateB slog.String(KeyBucketLabel, label), ).WithGroup("DriverCreateBucket") - span.SetAttributes( - attribute.String(KeyBucketRegion, region), - attribute.String(KeyBucketLabel, label), - ) - - log.InfoContext(ctx, "bucket creation initiated") + log.InfoContext(ctx, "Bucket creation initiated") if region == "" { - log.ErrorContext(ctx, "required parameter was not provided in the request", "error", ErrMissingRegion) + log.ErrorContext(ctx, "Required parameter was not provided in the request", "error", ErrMissingRegion) - return nil, tracing.Error(span, codes.InvalidArgument, ErrMissingRegion) + return nil, status.Error(codes.InvalidArgument, "region was not provided") } bucket, err := s.client.GetObjectStorageBucket(ctx, region, label) if err != nil { if !errors.Is(err, ErrNotFound) { - log.ErrorContext(ctx, "failed to check if bucket exists", "error", err) - return nil, tracing.Error(span, codes.Internal, fmt.Errorf("failed to check if bucket exists: %w", err)) + log.ErrorContext(ctx, "Failed to check if bucket exists", "error", err) + return nil, status.Error(codes.Internal, fmt.Sprintf("failed to check if bucket exists: %v", err)) } opts := linodego.ObjectStorageBucketCreateOptions{ @@ -117,47 +103,47 @@ func (s *Server) DriverCreateBucket(ctx context.Context, req *cosi.DriverCreateB CorsEnabled: cors.BoolP(), } - log.InfoContext(ctx, "creating bucket") + log.InfoContext(ctx, "Creating bucket") bucket, err = s.client.CreateObjectStorageBucket(ctx, opts) if err != nil { - log.ErrorContext(ctx, "failed to create bucket", "error", err) - return nil, tracing.Error(span, codes.Internal, fmt.Errorf("failed to create bucket: %w", err)) + log.ErrorContext(ctx, "Failed to create bucket", "error", err) + return nil, status.Error(codes.Internal, fmt.Sprintf("failed to create bucket: %v", err)) } - log.InfoContext(ctx, "bucket created") + log.InfoContext(ctx, "Bucket created") return &cosi.DriverCreateBucketResponse{ BucketId: bucket.Region + "/" + bucket.Label, BucketInfo: bucketInfo(bucket.Region), - }, tracing.Error(span, codes.OK, nil, "bucket created") + }, status.Error(codes.OK, "bucket created") } - log.DebugContext(ctx, "bucket found, checking bucket access", + log.DebugContext(ctx, "Bucket found, checking bucket access", KeyBucketCreationTimestamp, bucket.Region, ) access, err := s.client.GetObjectStorageBucketAccess(ctx, region, label) if err != nil { - log.ErrorContext(ctx, "failed to check bucket access", "error", err) - return nil, tracing.Error(span, codes.Internal, fmt.Errorf("failed to check bucket access: %w", err)) + log.ErrorContext(ctx, "Failed to check bucket access", "error", err) + return nil, status.Error(codes.Internal, fmt.Sprintf("failed to check bucket access: %v", err)) } if access.ACL != acl || access.CorsEnabled != cors.Bool() { - log.ErrorContext(ctx, "bucket with different parameters already exists", + log.ErrorContext(ctx, "Bucket with different parameters already exists", "existing_"+KeyBucketACL, access.ACL, "existing_"+KeyBucketCORS, access.CorsEnabled, ) - return nil, tracing.Error(span, codes.AlreadyExists, ErrBucketExists) + return nil, status.Error(codes.AlreadyExists, "bucket exists with different parameters") } - log.InfoContext(ctx, "bucket exists") + log.InfoContext(ctx, "Bucket exists") return &cosi.DriverCreateBucketResponse{ BucketId: bucket.Region + "/" + bucket.Label, BucketInfo: bucketInfo(bucket.Region), - }, tracing.Error(span, codes.OK, nil, "bucket exists") + }, status.Error(codes.OK, "bucket exists") } // DriverDeleteBucket call is made to delete the bucket in the backend. @@ -165,9 +151,6 @@ func (s *Server) DriverCreateBucket(ctx context.Context, req *cosi.DriverCreateB // NOTE: this call needs to be idempotent. // If the bucket has already been deleted, then no error should be returned. func (s *Server) DriverDeleteBucket(ctx context.Context, req *cosi.DriverDeleteBucketRequest) (*cosi.DriverDeleteBucketResponse, error) { - ctx, span := s.init(ctx, "DriverDeleteBucket") - defer span.End() - region, label := parseBucketID(req.GetBucketId()) log := s.logAttr( @@ -176,23 +159,17 @@ func (s *Server) DriverDeleteBucket(ctx context.Context, req *cosi.DriverDeleteB slog.String(KeyBucketLabel, label), ).WithGroup("DriverDeleteBucket") - span.SetAttributes( - attribute.String(KeyBucketID, req.GetBucketId()), - attribute.String(KeyBucketRegion, region), - attribute.String(KeyBucketLabel, label), - ) - - log.InfoContext(ctx, "bucket deletion initiated") + log.InfoContext(ctx, "Bucket deletion initiated") err := s.client.DeleteObjectStorageBucket(ctx, region, label) if err == nil || errors.Is(err, ErrNotFound) { - log.InfoContext(ctx, "bucket deleted") - return &cosi.DriverDeleteBucketResponse{}, tracing.Error(span, codes.OK, err, "bucket deleted") + log.InfoContext(ctx, "Bucket deleted") + return &cosi.DriverDeleteBucketResponse{}, status.Error(codes.OK, "bucket deleted") } - log.ErrorContext(ctx, "failed to delete bucket", "error", err) + log.ErrorContext(ctx, "Failed to delete bucket", "error", err) - return nil, tracing.Error(span, codes.Internal, fmt.Errorf("failed to delete bucket: %w", err)) + return nil, status.Error(codes.Internal, fmt.Sprintf("failed to delete bucket: %v", err)) } // DriverGrantBucketAccess call grants access to an account. @@ -202,9 +179,6 @@ func (s *Server) DriverDeleteBucket(ctx context.Context, req *cosi.DriverDeleteB // The account_id returned in the response will be used as the unique identifier for deleting this access when calling DriverRevokeBucketAccess. // The returned secret does not need to be the same each call to achieve idempotency. func (s *Server) DriverGrantBucketAccess(ctx context.Context, req *cosi.DriverGrantBucketAccessRequest) (*cosi.DriverGrantBucketAccessResponse, error) { - ctx, span := s.init(ctx, "DriverGrantBucketAccess") - defer span.End() - region, label := parseBucketID(req.GetBucketId()) name := req.GetName() auth := req.GetAuthenticationType() @@ -223,23 +197,14 @@ func (s *Server) DriverGrantBucketAccess(ctx context.Context, req *cosi.DriverGr slog.Any(KeyBucketAccessPermissions, perms), ).WithGroup("DriverGrantBucketAccess") - span.SetAttributes( - attribute.String(KeyBucketID, req.GetBucketId()), - attribute.String(KeyBucketRegion, region), - attribute.String(KeyBucketLabel, label), - attribute.String(KeyBucketAccessName, name), - attribute.String(KeyBucketAccessAuth, auth.String()), - attribute.String(KeyBucketAccessPermissions, string(perms)), - ) - if auth != cosi.AuthenticationType_Key { - log.ErrorContext(ctx, "unsupported authentication type") + log.ErrorContext(ctx, "Unsupported authentication type") - return nil, tracing.Error(span, codes.InvalidArgument, fmt.Errorf("%w: %s", ErrUnsuportedAuth, auth.String())) + return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("%v: %s", ErrUnsuportedAuth, auth.String())) } else if perms != ParamPermissionsValueReadOnly && perms != ParamPermissionsValueReadWrite { - log.ErrorContext(ctx, "unknown permissions") + log.ErrorContext(ctx, "Unknown permissions") - return nil, tracing.Error(span, codes.InvalidArgument, fmt.Errorf("%w: %s", ErrUnknownPermsissions, perms)) + return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("%v: %s", ErrUnknownPermsissions, perms)) } opts := linodego.ObjectStorageKeyCreateOptions{ @@ -253,29 +218,26 @@ func (s *Server) DriverGrantBucketAccess(ctx context.Context, req *cosi.DriverGr }, } - log.InfoContext(ctx, "creating object storage key") + log.InfoContext(ctx, "Creating object storage key") key, err := s.client.CreateObjectStorageKey(ctx, opts) if err != nil { - log.ErrorContext(ctx, "failed to create object storage key", "error", err) - return nil, tracing.Error(span, codes.InvalidArgument, fmt.Errorf("failed to create object storage key: %w", err)) + log.ErrorContext(ctx, "Failed to create object storage key", "error", err) + return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("failed to create object storage key: %v", err)) } - log.InfoContext(ctx, "object storage key created") + log.InfoContext(ctx, "Object storage key created") return &cosi.DriverGrantBucketAccessResponse{ AccountId: fmt.Sprintf("%d", key.ID), Credentials: credentials(region, label, key.AccessKey, key.SecretKey), - }, tracing.Error(span, codes.OK, nil) + }, status.Error(codes.OK, "bucket access granted") } // DriverRevokeBucketAccess call revokes all access to a particular bucket from a principal. // // NOTE: this call needs to be idempotent. func (s *Server) DriverRevokeBucketAccess(ctx context.Context, req *cosi.DriverRevokeBucketAccessRequest) (*cosi.DriverRevokeBucketAccessResponse, error) { - ctx, span := s.init(ctx, "DriverRevokeBucketAccess") - defer span.End() - region, label := parseBucketID(req.GetBucketId()) id, err := strconv.Atoi(req.GetAccountId()) @@ -287,26 +249,18 @@ func (s *Server) DriverRevokeBucketAccess(ctx context.Context, req *cosi.DriverR slog.Int(KeyBucketAccessID, id), ).WithGroup("DriverRevokeBucketAccess") - span.SetAttributes( - attribute.String(KeyBucketID, req.GetBucketId()), - attribute.String(KeyBucketAccessIDRaw, req.GetBucketId()), - attribute.String(KeyBucketRegion, region), - attribute.String(KeyBucketLabel, label), - attribute.Int(KeyBucketAccessID, id), - ) - if err != nil { - log.ErrorContext(ctx, "invalid account id", "error", err) - return nil, tracing.Error(span, codes.InvalidArgument, fmt.Errorf("account id is invalid: %w", err)) + log.ErrorContext(ctx, "Invalid account id", "error", err) + return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("account id is invalid: %v", err)) } err = s.client.DeleteObjectStorageKey(ctx, id) if err == nil || errors.Is(err, ErrNotFound) { - log.InfoContext(ctx, "key deleted") - return &cosi.DriverRevokeBucketAccessResponse{}, tracing.Error(span, codes.OK, nil, "key deleted") + log.InfoContext(ctx, "Key deleted") + return &cosi.DriverRevokeBucketAccessResponse{}, status.Error(codes.OK, "key deleted") } - log.ErrorContext(ctx, "failed to delete key", "error", err) + log.ErrorContext(ctx, "Failed to delete key", "error", err) - return nil, tracing.Error(span, codes.Internal, fmt.Errorf("failed to delete key: %w", err)) + return nil, status.Error(codes.Internal, fmt.Sprintf("failed to delete key: %v", err)) } diff --git a/pkg/servers/provisioner/provisionerintegration_test.go b/pkg/servers/provisioner/provisionerintegration_test.go index ce4ea4f..11f73e1 100644 --- a/pkg/servers/provisioner/provisionerintegration_test.go +++ b/pkg/servers/provisioner/provisionerintegration_test.go @@ -24,12 +24,13 @@ import ( "testing" "time" + cosi "sigs.k8s.io/container-object-storage-interface-spec" + "github.com/linode/linode-cosi-driver/pkg/envflag" "github.com/linode/linode-cosi-driver/pkg/linodeclient" "github.com/linode/linode-cosi-driver/pkg/servers/provisioner" "github.com/linode/linode-cosi-driver/pkg/testutils" "github.com/linode/linode-cosi-driver/pkg/version" - cosi "sigs.k8s.io/container-object-storage-interface-spec" ) func idempotentRun(t *testing.T, n int, name string, run func(t *testing.T)) { diff --git a/scripts/release-gen.sh b/scripts/release-gen.sh deleted file mode 100755 index e146ff5..0000000 --- a/scripts/release-gen.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -AUTHOR="${1}" - -# Get the PR number -pr_number=$(gh pr list --author="${AUTHOR}" --state=open --json=number --jq='.[].number' --limit=1) - -# Check if the PR number is not empty -if [ -n "${pr_number}" ]; then - # Checkout to the PR - gh pr checkout "${pr_number}" - - helm-docs --badge-style=flat - - if ! git diff --quiet ; then - git add . - git commit -sm "chore(release): generated helm docs" - git push - else - echo "Nothing to commit!" - fi -else - echo "No open PR found for ${AUTHOR}" -fi