From 5bbdb775103eae146ed90dfe0008ccac0e6bc1ef Mon Sep 17 00:00:00 2001 From: ParthaI <47887552+ParthaI@users.noreply.github.com> Date: Fri, 4 Oct 2024 20:11:31 +0530 Subject: [PATCH] Add table gcp_vertex_ai_notebook_runtime_template Closes #659 (#660) --- ...gcp_vertex_ai_notebook_runtime_template,md | 145 +++++++++ gcp/plugin.go | 1 + gcp/service.go | 8 + ...gcp_vertex_ai_notebook_runtime_template.go | 288 ++++++++++++++++++ gcp/vertex_ai_location_list.go | 3 + go.mod | 22 +- go.sum | 51 ++-- 7 files changed, 480 insertions(+), 38 deletions(-) create mode 100644 docs/tables/gcp_vertex_ai_notebook_runtime_template,md create mode 100644 gcp/table_gcp_vertex_ai_notebook_runtime_template.go diff --git a/docs/tables/gcp_vertex_ai_notebook_runtime_template,md b/docs/tables/gcp_vertex_ai_notebook_runtime_template,md new file mode 100644 index 00000000..283f5eb2 --- /dev/null +++ b/docs/tables/gcp_vertex_ai_notebook_runtime_template,md @@ -0,0 +1,145 @@ +--- +title: "Steampipe Table: gcp_vertex_ai_notebook_runtime_template - Query GCP Vertex AI Notebook Runtime Templates using SQL" +description: "Allows users to query GCP Vertex AI Notebook Runtime Templates, providing detailed information on configuration, machine specs, networking, and other related details." +--- + +# Table: gcp_vertex_ai_notebook_runtime_template - Query GCP Vertex AI Notebook Runtime Templates using SQL + +Google Cloud Vertex AI Notebook Runtime Templates provide preconfigured environments for machine learning workloads. These templates allow you to define runtime settings such as machine type, networking, disk storage, and more. The `gcp_vertex_ai_notebook_runtime_template` table in Steampipe allows you to query detailed information about Notebook Runtime Templates, including network configurations, service account settings, and machine specifications. + +## Table Usage Guide + +The `gcp_vertex_ai_notebook_runtime_template` table helps cloud administrators, data scientists, and machine learning engineers gather insights into their Vertex AI Notebook Runtime Templates. You can query the configuration settings for machine specs, network access, disk storage, and more. This table is particularly useful for monitoring resource usage, managing templates, and ensuring that the runtime environment meets your workload needs. + +## Examples + +### Basic info +Retrieve basic information about the Notebook Runtime Templates, including their name, location, and creation time. + +```sql+postgres +select + name, + display_name, + location, + create_time, + is_default +from + gcp_vertex_ai_notebook_runtime_template; +``` + +```sql+sqlite +select + name, + display_name, + location, + create_time, + is_default +from + gcp_vertex_ai_notebook_runtime_template; +``` + +### List templates by machine type +Identify templates that are using a specific machine type, such as "e2-standard-4". + +```sql+postgres +select + name, + display_name, + machine_spec ->> 'machine_type' as machine_type, + location +from + gcp_vertex_ai_notebook_runtime_template +where + machine_spec ->> 'machine_type' = 'e2-standard-4'; +``` + +```sql+sqlite +select + name, + display_name, + json_extract(machine_spec, '$.machine_type') as machine_type, + location +from + gcp_vertex_ai_notebook_runtime_template +where + json_extract(machine_spec, '$.machine_type') = 'e2-standard-4'; +``` + +### List templates with internet access enabled +Retrieve templates that have internet access enabled in their network configuration. + +```sql+postgres +select + name, + network_spec ->> 'enable_internet_access' as internet_access, + network_spec ->> 'network' as network, + location +from + gcp_vertex_ai_notebook_runtime_template +where + network_spec ->> 'enable_internet_access' = 'true'; +``` + +```sql+sqlite +select + name, + json_extract(network_spec, '$.enable_internet_access') as internet_access, + json_extract(network_spec, '$.network') as network, + location +from + gcp_vertex_ai_notebook_runtime_template +where + json_extract(network_spec, '$.enable_internet_access') = 'true'; +``` + +### List templates by disk size +Identify templates with specific persistent disk sizes, which is useful for understanding storage configurations. + +```sql+postgres +select + name, + data_persistent_disk_spec ->> 'disk_size_gb' as disk_size_gb, + location +from + gcp_vertex_ai_notebook_runtime_template +where + data_persistent_disk_spec ->> 'disk_size_gb' = '10'; +``` + +```sql+sqlite +select + name, + json_extract(data_persistent_disk_spec, '$.disk_size_gb') as disk_size_gb, + location +from + gcp_vertex_ai_notebook_runtime_template +where + json_extract(data_persistent_disk_spec, '$.disk_size_gb') = '10'; +``` + +### List templates by tag +Retrieve templates associated with specific tags for organizational purposes. + +```sql+postgres +select + name, + display_name, + tags ->> 'foo' as tag_value, + location +from + gcp_vertex_ai_notebook_runtime_template +where + tags ->> 'foo' = 'bar'; +``` + +```sql+sqlite +select + name, + display_name, + json_extract(tags, '$.foo') as tag_value, + location +from + gcp_vertex_ai_notebook_runtime_template +where + json_extract(tags, '$.foo') = 'bar'; +``` \ No newline at end of file diff --git a/gcp/plugin.go b/gcp/plugin.go index ab170e35..40f74507 100644 --- a/gcp/plugin.go +++ b/gcp/plugin.go @@ -145,6 +145,7 @@ func Plugin(ctx context.Context) *plugin.Plugin { "gcp_storage_object": tableGcpStorageObject(ctx), "gcp_tag_binding": tableGcpTagBinding(ctx), "gcp_vertex_ai_endpoint": tableGcpVertexAIEndpoint(ctx), + "gcp_vertex_ai_notebook_runtime_template": tableGcpVertexAINotebookRuntimeTemplate(ctx), "gcp_vertex_ai_model": tableGcpVertexAIModel(ctx), "gcp_vpc_access_connector": tableGcpVPCAccessConnector(ctx), /* diff --git a/gcp/service.go b/gcp/service.go index f0c36a61..90153b74 100644 --- a/gcp/service.go +++ b/gcp/service.go @@ -70,6 +70,7 @@ type AIplatfromServiceClients struct { Index *aiplatform.IndexClient Job *aiplatform.JobClient Model *aiplatform.ModelClient + Notebook *aiplatform.NotebookClient } func AIService(ctx context.Context, d *plugin.QueryData, clientType string) (*AIplatfromServiceClients, error) { @@ -128,6 +129,13 @@ func AIService(ctx context.Context, d *plugin.QueryData, clientType string) (*AI } clients.Model = svc return clients, nil + case "Notebook": + svc, err := aiplatform.NewNotebookClient(ctx, opts...) + if err != nil { + return nil, err + } + clients.Notebook = svc + return clients, nil } d.ConnectionManager.Cache.Set(serviceCacheKey, clients) diff --git a/gcp/table_gcp_vertex_ai_notebook_runtime_template.go b/gcp/table_gcp_vertex_ai_notebook_runtime_template.go new file mode 100644 index 00000000..bb9d410b --- /dev/null +++ b/gcp/table_gcp_vertex_ai_notebook_runtime_template.go @@ -0,0 +1,288 @@ +package gcp + +import ( + "context" + "strings" + + "cloud.google.com/go/aiplatform/apiv1/aiplatformpb" + + "github.com/turbot/go-kit/types" + "github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" + "github.com/turbot/steampipe-plugin-sdk/v5/plugin" + "github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform" + "google.golang.org/api/iterator" +) + +func tableGcpVertexAINotebookRuntimeTemplate(ctx context.Context) *plugin.Table { + return &plugin.Table{ + Name: "gcp_vertex_ai_notebook_runtime_template", + Description: "GCP Vertex AI Notebook Runtime Template", + Get: &plugin.GetConfig{ + KeyColumns: plugin.SingleColumn("name"), + Hydrate: getAIPlatformNotebookRuntimeTemplate, + ShouldIgnoreError: isIgnorableError([]string{"Unauthenticated", "Unimplemented", "InvalidArgument"}), + }, + List: &plugin.ListConfig{ + Hydrate: listAIPlatformNotebookRuntimeTemplates, + ShouldIgnoreError: isIgnorableError([]string{"Unauthenticated", "Unimplemented", "InvalidArgument"}), + }, + GetMatrixItemFunc: BuildVertexAILocationListByClientType("Notebook"), + Columns: []*plugin.Column{ + { + Name: "name", + Type: proto.ColumnType_STRING, + Description: "The resource name of the Notebook Runtime Template.", + Transform: transform.FromField("Name"), + }, + { + Name: "display_name", + Type: proto.ColumnType_STRING, + Description: "The display name of the Notebook Runtime Template.", + }, + { + Name: "description", + Type: proto.ColumnType_STRING, + Description: "The description of the Notebook Runtime Template.", + }, + { + Name: "notebook_runtime_type", + Type: proto.ColumnType_STRING, + Description: "The type of the notebook runtime template.", + Transform: transform.From(getNotebookRuntimeTemplateType), + }, + { + Name: "is_default", + Type: proto.ColumnType_BOOL, + Description: "Specifies whether this is the default template.", + }, + { + Name: "service_account", + Type: proto.ColumnType_STRING, + Description: "The service account that the runtime workload runs as.", + }, + { + Name: "etag", + Type: proto.ColumnType_STRING, + Description: "Used to perform consistent read-modify-write updates.", + }, + { + Name: "create_time", + Type: proto.ColumnType_TIMESTAMP, + Transform: transform.FromField("CreateTime").Transform(convertTimestamppbAsTime), + Description: "Timestamp when this Notebook Runtime Template was created.", + }, + { + Name: "update_time", + Type: proto.ColumnType_TIMESTAMP, + Transform: transform.FromField("UpdateTime").Transform(convertTimestamppbAsTime), + Description: "Timestamp when this Notebook Runtime Template was last updated.", + }, + { + Name: "machine_spec", + Type: proto.ColumnType_JSON, + Description: "The specification of a single machine for the template.", + }, + { + Name: "data_persistent_disk_spec", + Type: proto.ColumnType_JSON, + Description: "The specification of persistent disk attached to the runtime as data disk storage.", + }, + { + Name: "network_spec", + Type: proto.ColumnType_JSON, + Description: "The specification of the network for the Notebook Runtime Template.", + }, + { + Name: "idle_shutdown_config", + Type: proto.ColumnType_JSON, + Description: "The idle shutdown configuration of the Notebook Runtime Template.", + }, + { + Name: "euc_config", + Type: proto.ColumnType_JSON, + Description: "The EUC (End User Computing) configuration of the Notebook Runtime Template.", + }, + { + Name: "shielded_vm_config", + Type: proto.ColumnType_JSON, + Description: "The configuration for Shielded VM for the runtime template.", + }, + { + Name: "network_tags", + Type: proto.ColumnType_JSON, + Description: "The Compute Engine network tags to add to the runtime.", + }, + + // Standard steampipe columns + { + Name: "title", + Type: proto.ColumnType_STRING, + Transform: transform.FromField("DisplayName"), + Description: ColumnDescriptionTitle, + }, + { + Name: "tags", + Type: proto.ColumnType_JSON, + Transform: transform.FromField("Labels"), + Description: ColumnDescriptionTags, + }, + { + Name: "akas", + Type: proto.ColumnType_JSON, + Transform: transform.FromP(gcpNotebookRuntimeTemplate, "Akas"), + Description: ColumnDescriptionAkas, + }, + + // Standard gcp columns + { + Name: "location", + Type: proto.ColumnType_STRING, + Transform: transform.FromP(gcpNotebookRuntimeTemplate, "Location"), + Description: ColumnDescriptionLocation, + }, + { + Name: "project", + Type: proto.ColumnType_STRING, + Hydrate: getProject, + Transform: transform.FromValue(), + Description: ColumnDescriptionProject, + }, + }, + } +} + +func listAIPlatformNotebookRuntimeTemplates(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { + logger := plugin.Logger(ctx) + + region := d.EqualsQualString("location") + var location string + matrixLocation := d.EqualsQualString(matrixKeyLocation) + // Since, when the service API is disabled, matrixLocation value will be nil + if matrixLocation != "" { + location = matrixLocation + } + + // Minimize API call as per given location + if region != "" && region != location { + logger.Warn("gcp_vertex_ai_notebook_runtime_template.listAIPlatformNotebookRuntimeTemplates", "location", region, "matrixLocation", location) + return nil, nil + } + + // Get project details + + projectId, err := getProject(ctx, d, h) + if err != nil { + logger.Error("gcp_vertex_ai_notebook_runtime_template.listAIPlatformNotebookRuntimeTemplates", "cache_error", err) + return nil, err + } + + project := projectId.(string) + + // Page size should be in range of [0, 100]. + pageSize := types.Int64(100) + limit := d.QueryContext.Limit + if d.QueryContext.Limit != nil { + if *limit < *pageSize { + pageSize = limit + } + } + + // Create Service Connection + service, err := AIService(ctx, d, "Notebook") + if err != nil { + logger.Error("gcp_vertex_ai_notebook_runtime_template.listAIPlatformNotebookRuntimeTemplates", "connection_error", err) + return nil, err + } + + req := &aiplatformpb.ListNotebookRuntimeTemplatesRequest{ + Parent: "projects/" + project + "/locations/" + location, + PageSize: int32(*pageSize), + } + + it := service.Notebook.ListNotebookRuntimeTemplates(ctx, req) + + for { + template, err := it.Next() + if err != nil { + if strings.Contains(err.Error(), "404") { + return nil, nil + } + if err == iterator.Done { + break + } + logger.Error("gcp_vertex_ai_notebook_runtime_template.listAIPlatformNotebookRuntimeTemplates", err) + return nil, err + } + + d.StreamListItem(ctx, template) + + if d.RowsRemaining(ctx) == 0 { + break + } + } + + return nil, nil +} + +//// HYDRATE FUNCTIONS + +func getAIPlatformNotebookRuntimeTemplate(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { + logger := plugin.Logger(ctx) + + matrixLocation := d.EqualsQualString(matrixKeyLocation) + + name := d.EqualsQualString("name") + splitName := strings.Split(name, "/") + + // Validate - name should not be blank and restrict the API call for other locations + if len(name) > 3 && splitName[3] != matrixLocation{ + return nil, nil + } + + service, err := AIService(ctx, d, "Notebook") + if err != nil { + if strings.Contains(err.Error(), "404") || strings.Contains(err.Error(), "NotFound") { + return nil, nil + } + logger.Error("gcp_vertex_ai_notebook_runtime_template.getAIPlatformNotebookRuntimeTemplate", "service_error", err) + return nil, err + } + + // Assuming the 'name' column contains the full resource name of the Model + // e.g., projects/projectID/locations/locationID/models/modelID + req := &aiplatformpb.GetNotebookRuntimeTemplateRequest{ + Name: name, + } + + // Call the API + result, err := service.Notebook.GetNotebookRuntimeTemplate(ctx, req) + if err != nil { + if strings.Contains(err.Error(), "404") || strings.Contains(err.Error(), "NotFound") { + return nil, nil + } + logger.Error("gcp_vertex_ai_notebook_runtime_template.getAIPlatformNotebookRuntimeTemplate", "api_error", err) + return nil, err + } + + return result, nil +} + +/// TRANSFORM FUNCTIONS + +func gcpNotebookRuntimeTemplate(ctx context.Context, d *transform.TransformData) (interface{}, error) { + param := d.Param.(string) + AIData := d.HydrateItem.(*aiplatformpb.NotebookRuntimeTemplate) + akas := []string{"gcp://aiplatform.googleapis.com/" + AIData.Name} + + turbotData := map[string]interface{}{ + "Location": strings.Split(AIData.Name, "/")[3], + "Akas": akas, + } + return turbotData[param], nil +} + +func getNotebookRuntimeTemplateType(ctx context.Context, d *transform.TransformData) (interface{}, error) { + AIData := d.HydrateItem.(*aiplatformpb.NotebookRuntimeTemplate) + + return aiplatformpb.NotebookRuntimeType_name[int32(AIData.NotebookRuntimeType)], nil +} diff --git a/gcp/vertex_ai_location_list.go b/gcp/vertex_ai_location_list.go index f2d42fe0..61c397f5 100644 --- a/gcp/vertex_ai_location_list.go +++ b/gcp/vertex_ai_location_list.go @@ -57,6 +57,9 @@ func BuildVertexAILocationList(clientType string) func(ctx context.Context, d *p case "Model": resp := service.Model.ListLocations(ctx, input) resourceLocations = append(resourceLocations, iterateLocationResponse(resp)...) + case "Notebook": + resp := service.Notebook.ListLocations(ctx, input) + resourceLocations = append(resourceLocations, iterateLocationResponse(resp)...) } // validate location list diff --git a/go.mod b/go.mod index a4886bfc..680c191d 100644 --- a/go.mod +++ b/go.mod @@ -5,17 +5,17 @@ go 1.22.4 toolchain go1.22.6 require ( - cloud.google.com/go/aiplatform v1.60.0 + cloud.google.com/go/aiplatform v1.67.0 cloud.google.com/go/resourcemanager v1.9.5 github.com/mitchellh/go-homedir v1.1.0 github.com/turbot/go-kit v0.10.0-rc.0 github.com/turbot/steampipe-plugin-sdk/v5 v5.10.4 - google.golang.org/api v0.162.0 + google.golang.org/api v0.172.0 ) require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/longrunning v0.5.5 // indirect + cloud.google.com/go/longrunning v0.5.6 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/eko/gocache/lib/v4 v4.1.5 // indirect github.com/eko/gocache/store/bigcache/v4 v4.2.1 // indirect @@ -23,22 +23,22 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/golang/mock v1.6.0 // indirect github.com/google/s2a-go v0.1.7 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/mod v0.8.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.6.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect ) require ( - cloud.google.com/go v0.112.0 // indirect + cloud.google.com/go v0.112.1 // indirect cloud.google.com/go/compute v1.24.0 // indirect - cloud.google.com/go/iam v1.1.6 // indirect + cloud.google.com/go/iam v1.1.7 // indirect cloud.google.com/go/redis v1.14.2 - cloud.google.com/go/storage v1.36.0 // indirect + cloud.google.com/go/storage v1.38.0 // indirect github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect github.com/agext/levenshtein v1.2.2 // indirect github.com/allegro/bigcache/v3 v3.1.0 // indirect @@ -63,7 +63,7 @@ require ( github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.0 // indirect + github.com/googleapis/gax-go/v2 v2.12.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-getter v1.7.5 // indirect @@ -108,7 +108,7 @@ require ( go.opentelemetry.io/proto/otlp v1.2.0 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/net v0.23.0 // indirect - golang.org/x/oauth2 v0.17.0 + golang.org/x/oauth2 v0.18.0 golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect diff --git a/go.sum b/go.sum index c3155885..342f5000 100644 --- a/go.sum +++ b/go.sum @@ -30,12 +30,12 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9 cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= -cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= -cloud.google.com/go/aiplatform v1.60.0 h1:0cSrii1ZeLr16MbBoocyy5KVnrSdiQ3KN/vtrTe7RqE= -cloud.google.com/go/aiplatform v1.60.0/go.mod h1:eTlGuHOahHprZw3Hio5VKmtThIOak5/qy6pzdsqcQnM= +cloud.google.com/go/aiplatform v1.67.0 h1:YWeqD4BjYwrmY4fa+isGcw0P81lJ3dKVxbWxdBchoiU= +cloud.google.com/go/aiplatform v1.67.0/go.mod h1:s/sJ6btBEr6bKnrNWdK9ZgHCvwbZNdP90b3DDtxxw+Y= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= @@ -111,14 +111,14 @@ cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y97 cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= -cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= +cloud.google.com/go/iam v1.1.7 h1:z4VHOhwKLF/+UYXAJDFwGtNF0b6gjsW1Pk9Ml0U/IoM= +cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/longrunning v0.5.5 h1:GOE6pZFdSrTb4KAiKnXsJBtlE6mEyaW44oKyMILWnOg= -cloud.google.com/go/longrunning v0.5.5/go.mod h1:WV2LAxD8/rg5Z1cNW6FJ/ZpX4E4VnDnoTk0yawPBB7s= +cloud.google.com/go/longrunning v0.5.6 h1:xAe8+0YaWoCKr9t1+aWe+OeQgN/iJK1fEgZSXmjuEaE= +cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn9GqyjaBT8/mA= cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= @@ -179,8 +179,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= -cloud.google.com/go/storage v1.36.0 h1:P0mOkAcaJxhCTvAkMhxMfrTKiNcub4YmmPBtlhAyTr8= -cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= +cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= +cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= @@ -244,8 +244,6 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ= github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -273,8 +271,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= -github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= @@ -407,8 +403,8 @@ github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99 github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= -github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= +github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= @@ -589,10 +585,10 @@ 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/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 h1:UNQQKPfTDe1J81ViolILjTKPr9WetKW6uei2hFgJmFs= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.26.0 h1:+hm+I+KigBy3M24/h1p/NHkUx/evbLH0PNcjpMyCHc4= @@ -740,8 +736,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= -golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= 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= @@ -919,8 +915,9 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= 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= @@ -969,8 +966,8 @@ google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.162.0 h1:Vhs54HkaEpkMBdgGdOT2P6F0csGG/vxDS0hWHJzmmps= -google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0= +google.golang.org/api v0.172.0 h1:/1OcMZGPmW1rX2LCu2CmGUD1KXK1+pfzxotxyRUCCdk= +google.golang.org/api v0.172.0/go.mod h1:+fJZq6QXWfa9pXhnIzsjx4yI22d4aI9ZpLb58gvXjis= 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= @@ -1083,8 +1080,8 @@ google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= +google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda h1:b6F6WIV4xHHD0FA4oIyzU6mHWg2WI2X1RBehwa5QN38= +google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda/go.mod h1:AHcE/gZH76Bk/ROZhQphlRoWo5xKDEtz3eVEO1LfA8c= google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=