diff --git a/detectors/gcp/app_engine.go b/detectors/gcp/app_engine.go index ad8a14ebd..9c893a530 100644 --- a/detectors/gcp/app_engine.go +++ b/detectors/gcp/app_engine.go @@ -50,3 +50,8 @@ func (d *Detector) AppEngineServiceInstance() (string, error) { } return "", errEnvVarNotFound } + +// AppEngineAvailabilityZoneAndRegion returns the zone and region in which this program is running +func (d *Detector) AppEngineAvailabilityZoneAndRegion() (string, string, error) { + return d.GCEAvailabilityZoneAndRegion() +} diff --git a/detectors/gcp/faas.go b/detectors/gcp/faas.go index fda7f006a..7ad296ab6 100644 --- a/detectors/gcp/faas.go +++ b/detectors/gcp/faas.go @@ -40,31 +40,31 @@ func (d *Detector) onCloudFunctions() bool { return found } -// FAASName returns the name of the cloud run or cloud functions service. -func (d *Detector) FAASName() (string, error) { +// FaaSName returns the name of the cloud run or cloud functions service. +func (d *Detector) FaaSName() (string, error) { if name, found := d.os.LookupEnv(faasServiceEnv); found { return name, nil } return "", errEnvVarNotFound } -// FAASVersion returns the revision of the cloud run or cloud functions service -func (d *Detector) FAASVersion() (string, error) { +// FaaSVersion returns the revision of the cloud run or cloud functions service +func (d *Detector) FaaSVersion() (string, error) { if version, found := d.os.LookupEnv(faasRevisionEnv); found { return version, nil } return "", errEnvVarNotFound } -// FAASVersion returns the instance id of the cloud run instance or cloud function -func (d *Detector) FAASInstanceID() (string, error) { +// FaaSID returns the instance id of the cloud run instance or cloud function +func (d *Detector) FaaSID() (string, error) { return d.metadata.InstanceID() } -// FAASCloudRegion detects region from the metadata server. It is in the +// FaaSCloudRegion detects region from the metadata server. It is in the // format /projects//regions/. // https://cloud.google.com/run/docs/reference/container-contract#metadata-server -func (d *Detector) FAASCloudRegion() (string, error) { +func (d *Detector) FaaSCloudRegion() (string, error) { region, err := d.metadata.Get(regionMetadataAttr) if err != nil { return "", err diff --git a/detectors/gcp/faas_test.go b/detectors/gcp/faas_test.go index e2ddb3158..fd84c183b 100644 --- a/detectors/gcp/faas_test.go +++ b/detectors/gcp/faas_test.go @@ -21,78 +21,78 @@ import ( "github.com/stretchr/testify/assert" ) -func TestFAASName(t *testing.T) { +func TestFaaSName(t *testing.T) { d := NewTestDetector(&FakeMetadataProvider{}, &FakeOSProvider{ Vars: map[string]string{ faasServiceEnv: "my-service", }, }) - name, err := d.FAASName() + name, err := d.FaaSName() assert.NoError(t, err) assert.Equal(t, name, "my-service") } -func TestFAASNameErr(t *testing.T) { +func TestFaaSNameErr(t *testing.T) { d := NewTestDetector(&FakeMetadataProvider{}, &FakeOSProvider{ Vars: map[string]string{}, }) - name, err := d.FAASName() + name, err := d.FaaSName() assert.Error(t, err) assert.Equal(t, name, "") } -func TestFAASVersion(t *testing.T) { +func TestFaaSVersion(t *testing.T) { d := NewTestDetector(&FakeMetadataProvider{}, &FakeOSProvider{ Vars: map[string]string{ faasRevisionEnv: "version-123", }, }) - version, err := d.FAASVersion() + version, err := d.FaaSVersion() assert.NoError(t, err) assert.Equal(t, version, "version-123") } -func TestFAASVersionErr(t *testing.T) { +func TestFaaSVersionErr(t *testing.T) { d := NewTestDetector(&FakeMetadataProvider{}, &FakeOSProvider{ Vars: map[string]string{}, }) - version, err := d.FAASVersion() + version, err := d.FaaSVersion() assert.Error(t, err) assert.Equal(t, version, "") } -func TestFAASInstanceID(t *testing.T) { +func TestFaaSInstanceID(t *testing.T) { d := NewTestDetector(&FakeMetadataProvider{ FakeInstanceID: "instance-id-123", }, &FakeOSProvider{}) - instance, err := d.FAASInstanceID() + instance, err := d.FaaSID() assert.NoError(t, err) assert.Equal(t, instance, "instance-id-123") } -func TestFAASInstanceIDErr(t *testing.T) { +func TestFaaSInstanceIDErr(t *testing.T) { d := NewTestDetector(&FakeMetadataProvider{ Err: fmt.Errorf("fake error"), }, &FakeOSProvider{}) - instance, err := d.FAASInstanceID() + instance, err := d.FaaSID() assert.Error(t, err) assert.Equal(t, instance, "") } -func TestFAASCloudRegion(t *testing.T) { +func TestFaaSCloudRegion(t *testing.T) { d := NewTestDetector(&FakeMetadataProvider{ Attributes: map[string]string{regionMetadataAttr: "/projects/123/regions/us-central1"}, }, &FakeOSProvider{}) - instance, err := d.FAASCloudRegion() + instance, err := d.FaaSCloudRegion() assert.NoError(t, err) assert.Equal(t, instance, "us-central1") } -func TestFAASCloudRegionErr(t *testing.T) { +func TestFaaSCloudRegionErr(t *testing.T) { d := NewTestDetector(&FakeMetadataProvider{ Err: fmt.Errorf("fake error"), }, &FakeOSProvider{}) - instance, err := d.FAASCloudRegion() + instance, err := d.FaaSCloudRegion() assert.Error(t, err) assert.Equal(t, instance, "") } diff --git a/detectors/gcp/go.mod b/detectors/gcp/go.mod index 4ab781556..a8ee28d01 100644 --- a/detectors/gcp/go.mod +++ b/detectors/gcp/go.mod @@ -1,4 +1,4 @@ -module go.opentelemetry.io/contrib/detectors/gcp +module github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp go 1.17 diff --git a/e2e-test-server/Dockerfile b/e2e-test-server/Dockerfile index 01792a401..a49a27e1b 100644 --- a/e2e-test-server/Dockerfile +++ b/e2e-test-server/Dockerfile @@ -19,6 +19,7 @@ WORKDIR /workspace/e2e-test-server/ # In-repo dependencies COPY exporter/trace/ ../exporter/trace/ COPY internal/resourcemapping/ ../internal/resourcemapping +COPY detectors/gcp/ ../detectors/gcp/ # cache deps before copying source so that source changes don't invalidate our # downloaded layer and we don't need to re-download as much. diff --git a/e2e-test-server/endtoendserver/scenarios.go b/e2e-test-server/endtoendserver/scenarios.go index c7b4ad439..4991bafbf 100644 --- a/e2e-test-server/endtoendserver/scenarios.go +++ b/e2e-test-server/endtoendserver/scenarios.go @@ -19,20 +19,20 @@ import ( "log" "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/trace" "google.golang.org/genproto/googleapis/rpc/code" ) var scenarioHandlers = map[string]scenarioHandler{ - "/basicPropagator": (*Server).unimplementedHandler, - "/basicTrace": (*Server).basicTraceHandler, - "/complexTrace": (*Server).complexTraceHandler, - "/health": (*Server).healthHandler, + "/basicPropagator": &unimplementedHandler{}, + "/basicTrace": &basicTraceHandler{}, + "/complexTrace": &complexTraceHandler{}, + "/detectResource": &detectResourceHandler{}, + "/health": &healthHandler{}, } -type scenarioHandler func(*Server, context.Context, request, *sdktrace.TracerProvider) *response - type request struct { scenario string testID string @@ -44,13 +44,26 @@ type response struct { traceID trace.TraceID } +type scenarioHandler interface { + handle(context.Context, request, *sdktrace.TracerProvider) *response + tracerProvider() (*sdktrace.TracerProvider, error) +} + // healthHandler returns an OK response without creating any traces. -func (s *Server) healthHandler(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response { +type healthHandler struct{} + +func (*healthHandler) handle(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response { return &response{statusCode: code.Code_OK} } +func (*healthHandler) tracerProvider() (*sdktrace.TracerProvider, error) { + return newTraceProvider(resource.Empty()) +} + // basicTraceHandler creates a basic trace and returns an OK response. -func (s *Server) basicTraceHandler(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response { +type basicTraceHandler struct{} + +func (*basicTraceHandler) handle(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response { if req.testID == "" { log.Printf("request is missing required field 'testID'. request: %+v", req) return &response{ @@ -67,8 +80,14 @@ func (s *Server) basicTraceHandler(ctx context.Context, req request, tracerProvi return &response{statusCode: code.Code_OK, traceID: span.SpanContext().TraceID()} } +func (*basicTraceHandler) tracerProvider() (*sdktrace.TracerProvider, error) { + return newTraceProvider(resource.Empty()) +} + // complexTraceHandler creates a complex trace and returns an OK response. -func (s *Server) complexTraceHandler(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response { +type complexTraceHandler struct{} + +func (*complexTraceHandler) handle(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response { if req.testID == "" { log.Printf("request is missing required field 'testID'. request: %+v", req) return &response{ @@ -105,8 +124,50 @@ func (s *Server) complexTraceHandler(ctx context.Context, req request, tracerPro return &response{statusCode: code.Code_OK, traceID: rootSpan.SpanContext().TraceID()} } +func (*complexTraceHandler) tracerProvider() (*sdktrace.TracerProvider, error) { + return newTraceProvider(resource.Empty()) +} + +// detectResourceHandler creates a basic trace with resource info and returns an OK response. +type detectResourceHandler struct{} + +func (*detectResourceHandler) handle(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response { + if req.testID == "" { + log.Printf("request is missing required field 'testID'. request: %+v", req) + return &response{ + statusCode: code.Code_INVALID_ARGUMENT, + data: []byte("request is missing required field 'testID'"), + } + } + + tracer := tracerProvider.Tracer(instrumentingModuleName) + _, span := tracer.Start(ctx, "resourceDetectionTrace", + trace.WithAttributes(attribute.String(testIDKey, req.testID))) + span.End() + + return &response{statusCode: code.Code_OK, traceID: span.SpanContext().TraceID()} +} + +func (*detectResourceHandler) tracerProvider() (*sdktrace.TracerProvider, error) { + res, err := resource.New(context.Background(), + resource.WithDetectors(&testDetector{}), + resource.WithFromEnv(), + resource.WithTelemetrySDK(), + ) + if err != nil { + return nil, err + } + return newTraceProvider(res) +} + // unimplementedHandler returns an UNIMPLEMENTED response without creating any traces. -func (s *Server) unimplementedHandler(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response { +type unimplementedHandler struct{} + +func (*unimplementedHandler) handle(ctx context.Context, req request, tracerProvider *sdktrace.TracerProvider) *response { log.Printf("received unhandled scenario %q", req.scenario) return &response{statusCode: code.Code_UNIMPLEMENTED} } + +func (*unimplementedHandler) tracerProvider() (*sdktrace.TracerProvider, error) { + return newTraceProvider(resource.Empty()) +} diff --git a/e2e-test-server/endtoendserver/server.go b/e2e-test-server/endtoendserver/server.go index 50f7579ab..2d36b9bf4 100644 --- a/e2e-test-server/endtoendserver/server.go +++ b/e2e-test-server/endtoendserver/server.go @@ -20,11 +20,15 @@ import ( "log" "strconv" + "cloud.google.com/go/compute/metadata" "cloud.google.com/go/pubsub" + "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.7.0" "google.golang.org/genproto/googleapis/rpc/code" + "github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp" texporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace" ) @@ -71,12 +75,6 @@ func (s *Server) Shutdown(ctx context.Context) { func (s *Server) onReceive(ctx context.Context, m *pubsub.Message) { defer m.Ack() - tracerProvider, err := newTraceProvider() - if err != nil { - log.Printf("could not initialize a tracer-provider: %v", err) - return - } - testID := m.Attributes[testIDKey] scenario := m.Attributes[scenarioKey] if scenario == "" { @@ -93,7 +91,13 @@ func (s *Server) onReceive(ctx context.Context, m *pubsub.Message) { handler := scenarioHandlers[scenario] if handler == nil { - handler = (*Server).unimplementedHandler + handler = &unimplementedHandler{} + } + + tracerProvider, err := handler.tracerProvider() + if err != nil { + log.Printf("could not initialize a tracer-provider: %v", err) + return } req := request{ @@ -101,7 +105,7 @@ func (s *Server) onReceive(ctx context.Context, m *pubsub.Message) { testID: testID, } - res := handler(s, ctx, req, tracerProvider) + res := handler.handle(ctx, req, tracerProvider) if err := shutdownTraceProvider(ctx, tracerProvider); err != nil { log.Printf("could not shutdown tracer-provider: %v", err) @@ -133,7 +137,7 @@ func (s *Server) respond(ctx context.Context, testID string, res *response) erro return err } -func newTraceProvider() (*sdktrace.TracerProvider, error) { +func newTraceProvider(res *resource.Resource) (*sdktrace.TracerProvider, error) { exporter, err := texporter.New(texporter.WithProjectID(projectID)) if err != nil { return nil, err @@ -141,13 +145,103 @@ func newTraceProvider() (*sdktrace.TracerProvider, error) { traceProvider := sdktrace.NewTracerProvider( sdktrace.WithBatcher(exporter, sdktrace.WithBatchTimeout(traceBatchTimeout)), - // Set resource to empty so we don't add labels that the - // e2e test runner doesn't expect. See b/192584837. - sdktrace.WithResource(resource.Empty())) + sdktrace.WithResource(res)) return traceProvider, nil } +// TODO: replace with upstream resource detector +type testDetector struct{} + +func (d *testDetector) Detect(ctx context.Context) (*resource.Resource, error) { + if !metadata.OnGCE() { + return nil, nil + } + detector := gcp.NewDetector() + projectID, err := detector.ProjectID() + if err != nil { + return nil, err + } + attributes := []attribute.KeyValue{semconv.CloudProviderGCP, semconv.CloudAccountIDKey.String(projectID)} + + switch detector.CloudPlatform() { + case gcp.GKE: + attributes = append(attributes, semconv.CloudPlatformGCPKubernetesEngine) + v, locType, err := detector.GKEAvailabilityZoneOrRegion() + if err != nil { + return nil, err + } + switch locType { + case gcp.Zone: + attributes = append(attributes, semconv.CloudAvailabilityZoneKey.String(v)) + case gcp.Region: + attributes = append(attributes, semconv.CloudRegionKey.String(v)) + default: + return nil, fmt.Errorf("location must be zone or region. Got %v", locType) + } + return detectWithFuncs(attributes, map[attribute.Key]detectionFunc{ + semconv.K8SClusterNameKey: detector.GKEClusterName, + semconv.HostIDKey: detector.GKEHostID, + semconv.HostNameKey: detector.GKEHostName, + }) + case gcp.CloudRun: + attributes = append(attributes, semconv.CloudPlatformGCPCloudRun) + return detectWithFuncs(attributes, map[attribute.Key]detectionFunc{ + semconv.FaaSNameKey: detector.FaaSName, + semconv.FaaSVersionKey: detector.FaaSVersion, + semconv.FaaSIDKey: detector.FaaSID, + semconv.CloudRegionKey: detector.FaaSCloudRegion, + }) + case gcp.CloudFunctions: + attributes = append(attributes, semconv.CloudPlatformGCPCloudFunctions) + return detectWithFuncs(attributes, map[attribute.Key]detectionFunc{ + semconv.FaaSNameKey: detector.FaaSName, + semconv.FaaSVersionKey: detector.FaaSVersion, + semconv.FaaSIDKey: detector.FaaSID, + semconv.CloudRegionKey: detector.FaaSCloudRegion, + }) + case gcp.AppEngine: + attributes = append(attributes, semconv.CloudPlatformGCPAppEngine) + zone, region, err := detector.AppEngineAvailabilityZoneAndRegion() + if err != nil { + return nil, err + } + attributes = append(attributes, semconv.CloudAvailabilityZoneKey.String(zone)) + attributes = append(attributes, semconv.CloudRegionKey.String(region)) + return detectWithFuncs(attributes, map[attribute.Key]detectionFunc{ + semconv.FaaSNameKey: detector.AppEngineServiceName, + semconv.FaaSVersionKey: detector.AppEngineServiceVersion, + semconv.FaaSIDKey: detector.AppEngineServiceInstance, + }) + default: + attributes = append(attributes, semconv.CloudPlatformGCPComputeEngine) + zone, region, err := detector.GCEAvailabilityZoneAndRegion() + if err != nil { + return nil, err + } + attributes = append(attributes, semconv.CloudAvailabilityZoneKey.String(zone)) + attributes = append(attributes, semconv.CloudRegionKey.String(region)) + return detectWithFuncs(attributes, map[attribute.Key]detectionFunc{ + semconv.HostTypeKey: detector.GCEHostType, + semconv.HostIDKey: detector.GCEHostID, + semconv.HostNameKey: detector.GCEHostName, + }) + } +} + +type detectionFunc func() (string, error) + +func detectWithFuncs(attributes []attribute.KeyValue, funcs map[attribute.Key]detectionFunc) (*resource.Resource, error) { + for key, detect := range funcs { + v, err := detect() + if err != nil { + return nil, err + } + attributes = append(attributes, key.String(v)) + } + return resource.NewWithAttributes(semconv.SchemaURL, attributes...), nil +} + func shutdownTraceProvider(ctx context.Context, tracerProvider *sdktrace.TracerProvider) error { if err := tracerProvider.ForceFlush(ctx); err != nil { return fmt.Errorf("traceProvider.ForceFlush(): %v", err) diff --git a/e2e-test-server/go.mod b/e2e-test-server/go.mod index 38821c2c9..9da95074d 100644 --- a/e2e-test-server/go.mod +++ b/e2e-test-server/go.mod @@ -9,12 +9,16 @@ require ( go.opentelemetry.io/otel v1.6.3 go.opentelemetry.io/otel/sdk v1.6.2 go.opentelemetry.io/otel/trace v1.6.3 - google.golang.org/genproto v0.0.0-20220405205423-9d709892a2bf + google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3 +) + +require ( + cloud.google.com/go/compute v1.6.1 + github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v0.0.0-20220518135511-55ba58d44b33 ) require ( cloud.google.com/go v0.100.2 // indirect - cloud.google.com/go/compute v1.5.0 // indirect cloud.google.com/go/trace v1.2.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.30.1 // indirect github.com/go-logr/logr v1.2.3 // indirect @@ -22,14 +26,14 @@ require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-cmp v0.5.7 // indirect - github.com/googleapis/gax-go/v2 v2.2.0 // indirect + github.com/googleapis/gax-go/v2 v2.3.0 // indirect go.opencensus.io v0.23.0 // indirect - golang.org/x/net v0.0.0-20220325170049-de3da57026de // indirect - golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect + golang.org/x/net v0.0.0-20220412020605-290c469a71a5 // indirect + golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886 // indirect + golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect golang.org/x/text v0.3.7 // indirect - google.golang.org/api v0.74.0 // indirect + google.golang.org/api v0.75.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/grpc v1.45.0 // indirect google.golang.org/protobuf v1.28.0 // indirect @@ -39,4 +43,6 @@ replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trac replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping => ../internal/resourcemapping +replace github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp => ../detectors/gcp + retract v1.0.0-RC1 diff --git a/e2e-test-server/go.sum b/e2e-test-server/go.sum index 43b96cb14..a62e106a7 100644 --- a/e2e-test-server/go.sum +++ b/e2e-test-server/go.sum @@ -37,8 +37,10 @@ cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4g 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 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM= 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 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= 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/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= @@ -174,8 +176,9 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/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 h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE= github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0 h1:nRJtk3y8Fm770D42QV6T90ZnvFZyk7agSo3Q+Z9p3WI= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleinterns/cloud-operations-api-mock v0.0.0-20200709193332-a1e58c29bdd3 h1:eHv/jVY/JNop1xg2J9cBb4EzyMpWZoNCP1BslSAIkOI= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -302,8 +305,9 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/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-20220325170049-de3da57026de h1:pZB1TWnKi+o4bENlbzAgLrEbY4RMYmUIRobMcSmfeYc= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5 h1:bRb386wvrE+oBNdF1d/Xh9mQrfQ4ecYhW5qJ5GvTGT4= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -321,8 +325,9 @@ golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ 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-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= 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= @@ -389,8 +394,9 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc 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-20220328115105-d36c6a25d886 h1:eJv7u3ksNXoLbGSKuv2s/SIO4tJVxc/A+MTpzxDgz/Q= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -461,8 +467,9 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -499,8 +506,9 @@ google.golang.org/api v0.64.0/go.mod h1:931CdxA8Rm4t6zqTFGSsgwbAEZ2+GMYurbndwSim 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 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE= google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0 h1:0AYh/ae6l9TDUvIQrDw5QRpM100P6oHgD+o3dYHMzJg= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -580,8 +588,11 @@ google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2 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-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220405205423-9d709892a2bf h1:JTjwKJX9erVpsw17w+OIPP7iAgEkN/r8urhWSunEDTs= -google.golang.org/genproto v0.0.0-20220405205423-9d709892a2bf/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +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 h1:SeX3QUcBj3fciwnfPT9kt5gBhFy/FCZtYZ+I/RB8agc= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=