diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index fd321991..93183e66 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -2,37 +2,37 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/hashicorp/aws" { - version = "6.35.1" + version = "6.36.0" constraints = ">= 4.56.0" hashes = [ - "h1:0/uXxSpL98lpRqjRhjAvvWZVnJZnbOehfAlTrcPXURI=", - "h1:3AfkMHiID/TK41i9ipxdUbSx3v4hjIePNEZR0fEuQJ4=", - "h1:JDzMZ25sVEhH1IfEvIOHSobkAG6zVR9XJheIo/1Rxcg=", - "h1:LXMHE13aDvLoetIJuf5sSgg4Aop5iBZN+NKHfbG5zDc=", - "h1:OWVRgvaFuQ/uIysY2FJpLBA2syuDy2riakYgRxu8Vfs=", - "h1:RaWReVCoriJ00TKG4aLdybf291yTrhkTebXAB7gOOYg=", - "h1:Rkp2NXMY5RwM6J9bmep0l98i5mGBZ2yMhC+9nNaslUc=", - "h1:ZXdXwOk/VKPMcYlqEDevz+jyj4zoZKEV8D5zXOt3Lts=", - "h1:bau+2wU1EyOYFYbVSr+ldecm/JsRWrH/EJ2rPlSIT2Y=", - "h1:hNOrSOTUfwctGIrrd2033JXCcmA+zt+eeY2SNkg0Aq8=", - "h1:mj5knyv94JKLLBTwlTEv5Yn4MDAWYRPaYkCbZFhRYdU=", - "h1:qegJgE+n90ruKoC7xx+as0s9JSO64pRvCtw5Bxs6bTE=", - "h1:tjis0/YUzxXTgD7zaDS/ZVNyOU8oysKvso7GTteFaYU=", - "h1:xD+5zPhF0ry3sutriARfFVIg5m38VwYt66RveI3aUyI=", - "zh:0a16d1b0ba9379e5c5295e6b3caa42f0b8ba6b9f0a7cc9dbe58c232cf995db2d", - "zh:4b2e69907a1a2c557e45ef590f9fd6187ab5bf90378346ba9f723535e49ce908", - "zh:56bdafda0d629e15dc3dd9275b54f1fb953e2e09a3bc1a34e027da9d03ea4893", - "zh:5b84e933989150249036f84faad221dce0daa9d3043ff24401547e18f00b121e", - "zh:70bac98c27a14cb2cedabd741a1f7f1bab074c127efdcf02b54dbcf0d03db3cc", - "zh:7184f48bd077eaf68e184fd44f97e2d971cb77c59a68aedb95a0f8dc01b134fe", - "zh:7367589ae8b584bfcd83c973f5003e15010a453349c017a0d2cca8772d4fcfd9", - "zh:7ec9699dee49dd31bbc2d0e50fa1fff451eee5c1d9fd59bca7412acb49ce6594", - "zh:92dd139b96977a64af0e976cd06e84921033678ab97550f1b687c0ea54a8e82c", + "h1:4sdEWcVrQOP3xZJz1Ld7mJsRUghMD5/u3z/h2DryFzA=", + "h1:547WNLU+9TkcXoGBzH3G3A8dF+bTpCMhoBuMq7bjGxE=", + "h1:AiIqpFaYiDAO68q7WYQrQ2zGpRVojIzLG5bb9VFi4CY=", + "h1:I36O/YXrM2U+wQd+ncqAoPM/LwODXAHelhN2alctC94=", + "h1:I3tZF008rcWRN19En34I04cLrapWjCinPLLv6sB1zlE=", + "h1:MOGEhZW49aW+2Js3b1XVGwm7dyhcuH9k59q5buyalQM=", + "h1:NVoHUXXTNemFijAA9VsKxVzWKlIv66Hu8NBKzWHXXKY=", + "h1:NsGSj9/Rbd/NhsYR2hgDCaIhvcbUDu7f960fRvcMa9g=", + "h1:ObcjqX/3XDBVq7hMisa46jbhE/ku3bIPLlffoVlUooQ=", + "h1:SJhaTTZS+/tUPuQMPi9CFFP8M58FQm0Cvml4r1TC1Yw=", + "h1:UYt6mrz0d3PfTJRbJAxe+fLcJt7voXJCLLdwfHrApGk=", + "h1:gaxpIeOTszPUGCIiwbbAL9n64e4NB0Y/Tslw8e1fwHw=", + "h1:ivdqYb0xTWGul8CjUp2SRJjJtSUJbrZi+zPLIDkDTIw=", + "h1:r9icn1WEZVvEXiy6ZKexLzAPnXkkt+22jJ9WQYPfKB0=", + "zh:0eb4481315564aaeec4905a804fd0df22c40f509ad2af63615eeaa90abacf81c", + "zh:12c3cddc461a8dbaa04387fe83420b64c4c05cb5479d181674168ca7daefcc38", + "zh:1b55a09661e80acf6826faa38dd8fbff24c2ef620d2a0a16918491a222c55370", + "zh:269cb1a406d0cac762bce82119247395a0bbf0d4ad2492fb2ea5653b4f44bc05", + "zh:3bfb78e3345f0c3846e76578952a09fb5dda05d2d73e19473fb0af0000469a66", + "zh:3ead4f4388c7dd78ed198082a981746324da0d7a51460c9b455fd884d86fc82c", + "zh:44906654199991b3f1a21c6a984bc5f9f556ff4baa4e5f77e168968e941c2725", + "zh:4803d050d581b05b0fd0ae5cce95ec1784d66e2bc9da4b1f7663df0ce7914609", + "zh:4cf9fe8fae58b62e83c0672a9c66e0963b7289aaf768a250e9bc44570d82cbd5", + "zh:5bfd7a1fb3116164b411777115dd4b272a68984fa949c687e41a3041318c82f1", + "zh:77cbcf2db512617f10b81e11c20d40fa534ef07163171cbe35214fa8f74b4e85", + "zh:8201cabed01f1434bf9ea7fbcf2a95612a87a0398b870b2643bd1a5119793d2d", + "zh:9aaded4cf36ec2abbe35086733a4510e08819698180b21a9387ba4112aee02e0", "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", - "zh:9f2df575a5b010db60068668c48806595a3d617a2c0305035283fe8b72f07b19", - "zh:a4602b7602c75c8f726bdc7e706dc5c26736e47cc8381be01386aa8d8d998403", - "zh:bc25fefeeee10425df7aebfc21dc6532d19acdf03fa97b9e6d8c113adffd0a1d", - "zh:f445592040b5fc368a12e6edeffc951b2eb41e86413c4074638a13376e25a9cc", - "zh:ff43962a48bd8f85e17188736bbd3c145b6a1320bd8303221f6b4f9ec861e1e6", + "zh:f594ef2683a0d23d3a6f0ad6c84a55ed79368c158ee08c2f3b7c41ec446a701f", ] } diff --git a/aws-source/adapters/adapterhelpers_always_get_source.go b/aws-source/adapters/adapterhelpers_always_get_source.go index a946888a..a82f58f2 100644 --- a/aws-source/adapters/adapterhelpers_always_get_source.go +++ b/aws-source/adapters/adapterhelpers_always_get_source.go @@ -172,7 +172,7 @@ func (s *AlwaysGetAdapter[ListInput, ListOutput, GetInput, GetOutput, ClientStru if err != nil { err := WrapAWSError(err) if !CanRetry(err) { - s.cache.StoreError(ctx, err, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.cacheDuration(), ck) } return nil, err } @@ -252,7 +252,7 @@ func (s *AlwaysGetAdapter[ListInput, ListOutput, GetInput, GetOutput, ClientStru ItemType: s.ItemType, ResponderName: s.Name(), } - s.cache.StoreError(ctx, notFoundErr, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, notFoundErr, s.cacheDuration(), ck) } }() @@ -262,7 +262,7 @@ func (s *AlwaysGetAdapter[ListInput, ListOutput, GetInput, GetOutput, ClientStru hadError.Store(true) err := WrapAWSError(err) if !CanRetry(err) { - s.cache.StoreError(ctx, err, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.cacheDuration(), ck) } stream.SendError(err) return @@ -273,7 +273,7 @@ func (s *AlwaysGetAdapter[ListInput, ListOutput, GetInput, GetOutput, ClientStru hadError.Store(true) err := WrapAWSError(err) if !CanRetry(err) { - s.cache.StoreError(ctx, err, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.cacheDuration(), ck) } stream.SendError(err) return @@ -375,7 +375,7 @@ func (s *AlwaysGetAdapter[ListInput, ListOutput, GetInput, GetOutput, ClientStru if err != nil { err := WrapAWSError(err) if !CanRetry(err) { - s.cache.StoreError(ctx, err, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.cacheDuration(), ck) } stream.SendError(err) return @@ -394,7 +394,7 @@ func (s *AlwaysGetAdapter[ListInput, ListOutput, GetInput, GetOutput, ClientStru ItemType: s.ItemType, ResponderName: s.Name(), } - s.cache.StoreError(ctx, notFoundErr, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, notFoundErr, s.cacheDuration(), ck) } } else { stream.SendError(errors.New("SearchCustom called without SearchInputMapper or SearchGetInputMapper")) diff --git a/aws-source/adapters/adapterhelpers_describe_source.go b/aws-source/adapters/adapterhelpers_describe_source.go index e52bdc1f..ba5fb372 100644 --- a/aws-source/adapters/adapterhelpers_describe_source.go +++ b/aws-source/adapters/adapterhelpers_describe_source.go @@ -241,7 +241,7 @@ func (s *DescribeOnlyAdapter[Input, Output, ClientStruct, Options]) Get(ctx cont ItemType: s.ItemType, ResponderName: s.Name(), } - s.cache.StoreError(ctx, qErr, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, qErr, s.cacheDuration(), ck) return nil, qErr case numItems == 0: @@ -253,7 +253,7 @@ func (s *DescribeOnlyAdapter[Input, Output, ClientStruct, Options]) Get(ctx cont ItemType: s.ItemType, ResponderName: s.Name(), } - s.cache.StoreError(ctx, qErr, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, qErr, s.cacheDuration(), ck) return nil, qErr } @@ -418,7 +418,7 @@ func (s *DescribeOnlyAdapter[Input, Output, ClientStruct, Options]) processError // Only cache the error if is something that won't be fixed by retrying if sdpErr.GetErrorType() == sdp.QueryError_NOTFOUND || sdpErr.GetErrorType() == sdp.QueryError_NOSCOPE { - s.cache.StoreError(ctx, sdpErr, s.cacheDuration(), cacheKey) + s.cache.StoreUnavailableItem(ctx, sdpErr, s.cacheDuration(), cacheKey) } } @@ -507,7 +507,7 @@ func (s *DescribeOnlyAdapter[Input, Output, ClientStruct, Options]) describe(ctx ItemType: s.ItemType, ResponderName: s.Name(), } - s.cache.StoreError(ctx, notFoundErr, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, notFoundErr, s.cacheDuration(), ck) } } diff --git a/aws-source/adapters/adapterhelpers_get_list_adapter_v2.go b/aws-source/adapters/adapterhelpers_get_list_adapter_v2.go index d4c662b6..883cc843 100644 --- a/aws-source/adapters/adapterhelpers_get_list_adapter_v2.go +++ b/aws-source/adapters/adapterhelpers_get_list_adapter_v2.go @@ -167,7 +167,7 @@ func (s *GetListAdapterV2[ListInput, ListOutput, AWSItem, ClientStruct, Options] if err != nil { err := WrapAWSError(err) if !CanRetry(err) { - s.cache.StoreError(ctx, err, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.cacheDuration(), ck) } return nil, err } @@ -310,7 +310,7 @@ func (s *GetListAdapterV2[ListInput, ListOutput, AWSItem, ClientStruct, Options] ItemType: s.ItemType, ResponderName: s.Name(), } - s.cache.StoreError(ctx, notFoundErr, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, notFoundErr, s.cacheDuration(), ck) } } diff --git a/aws-source/adapters/adapterhelpers_get_list_source.go b/aws-source/adapters/adapterhelpers_get_list_source.go index 2b50a44d..9a185a59 100644 --- a/aws-source/adapters/adapterhelpers_get_list_source.go +++ b/aws-source/adapters/adapterhelpers_get_list_source.go @@ -140,7 +140,7 @@ func (s *GetListAdapter[AWSItem, ClientStruct, Options]) Get(ctx context.Context if err != nil { err := WrapAWSError(err) if !CanRetry(err) { - s.cache.StoreError(ctx, err, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.cacheDuration(), ck) } return nil, err } @@ -195,7 +195,7 @@ func (s *GetListAdapter[AWSItem, ClientStruct, Options]) List(ctx context.Contex if err != nil { err := WrapAWSError(err) if !CanRetry(err) { - s.cache.StoreError(ctx, err, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.cacheDuration(), ck) } return nil, err } @@ -230,7 +230,7 @@ func (s *GetListAdapter[AWSItem, ClientStruct, Options]) List(ctx context.Contex ItemType: s.ItemType, ResponderName: s.Name(), } - s.cache.StoreError(ctx, notFoundErr, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, notFoundErr, s.cacheDuration(), ck) } return items, nil @@ -319,7 +319,7 @@ func (s *GetListAdapter[AWSItem, ClientStruct, Options]) SearchCustom(ctx contex awsItems, err := s.SearchFunc(ctx, s.Client, scope, query) if err != nil { err = WrapAWSError(err) - s.cache.StoreError(ctx, err, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.cacheDuration(), ck) return nil, err } @@ -348,7 +348,7 @@ func (s *GetListAdapter[AWSItem, ClientStruct, Options]) SearchCustom(ctx contex ItemType: s.ItemType, ResponderName: s.Name(), } - s.cache.StoreError(ctx, notFoundErr, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, notFoundErr, s.cacheDuration(), ck) } return items, nil diff --git a/aws-source/adapters/cloudwatch-instance-metric.go b/aws-source/adapters/cloudwatch-instance-metric.go index c43b96a4..d8c345c4 100644 --- a/aws-source/adapters/cloudwatch-instance-metric.go +++ b/aws-source/adapters/cloudwatch-instance-metric.go @@ -293,7 +293,7 @@ func (a *CloudwatchInstanceMetricAdapter) Get(ctx context.Context, scope string, Scope: scope, } // Cache the error - a.cache.StoreError(ctx, qErr, a.cacheDuration(), ck) + a.cache.StoreUnavailableItem(ctx, qErr, a.cacheDuration(), ck) return nil, qErr } @@ -305,7 +305,7 @@ func (a *CloudwatchInstanceMetricAdapter) Get(ctx context.Context, scope string, Scope: scope, } // Cache the error - a.cache.StoreError(ctx, qErr, a.cacheDuration(), ck) + a.cache.StoreUnavailableItem(ctx, qErr, a.cacheDuration(), ck) return nil, qErr } diff --git a/aws-source/adapters/s3.go b/aws-source/adapters/s3.go index c4cef606..7287734b 100644 --- a/aws-source/adapters/s3.go +++ b/aws-source/adapters/s3.go @@ -226,7 +226,7 @@ func getImpl(ctx context.Context, cache sdpcache.Cache, client S3Client, scope s if errors.As(err, &queryErr) { // Cache not-found errors and other non-retryable errors if queryErr.GetErrorType() == sdp.QueryError_NOTFOUND || !CanRetry(queryErr) { - cache.StoreError(ctx, err, CacheDuration, ck) + cache.StoreUnavailableItem(ctx, err, CacheDuration, ck) } } return nil, err @@ -400,7 +400,7 @@ func getImpl(ctx context.Context, cache sdpcache.Cache, client S3Client, scope s ErrorString: err.Error(), Scope: scope, } - cache.StoreError(ctx, err, CacheDuration, ck) + cache.StoreUnavailableItem(ctx, err, CacheDuration, ck) return nil, err } @@ -596,7 +596,7 @@ func listImpl(ctx context.Context, cache sdpcache.Cache, client S3Client, scope if err != nil { err = sdp.NewQueryError(err) - cache.StoreError(ctx, err, CacheDuration, ck) + cache.StoreUnavailableItem(ctx, err, CacheDuration, ck) return nil, err } @@ -625,7 +625,7 @@ func listImpl(ctx context.Context, cache sdpcache.Cache, client S3Client, scope ItemType: "s3-bucket", ResponderName: "aws-s3-adapter", } - cache.StoreError(ctx, notFoundErr, CacheDuration, ck) + cache.StoreUnavailableItem(ctx, notFoundErr, CacheDuration, ck) return items, nil } diff --git a/cmd/changes_submit_plan.go b/cmd/changes_submit_plan.go index a127a636..29a0f60b 100644 --- a/cmd/changes_submit_plan.go +++ b/cmd/changes_submit_plan.go @@ -52,7 +52,7 @@ func changeTitle(ctx context.Context, arg string) string { return arg } - describeBytes, err := exec.CommandContext(ctx, "git", "describe", "--long").Output() //nolint:gosec // G702: all arguments are hardcoded string literals; no user input reaches this command + describeBytes, err := exec.CommandContext(ctx, "git", "describe", "--long").Output() describe := strings.TrimSpace(string(describeBytes)) if err != nil { log.WithError(err).Trace("failed to run 'git describe' for default title") diff --git a/cmd/pterm.go b/cmd/pterm.go index 0b533d76..e67fc8f9 100644 --- a/cmd/pterm.go +++ b/cmd/pterm.go @@ -151,7 +151,7 @@ func RunRevlinkWarmup(ctx context.Context, oi sdp.OvermindInstance, postPlanPrin } func RunPlan(ctx context.Context, args []string) error { - c := exec.CommandContext(ctx, "terraform", args...) //nolint:gosec // G702: args are CLI arguments from the local user who invoked this command; this tool runs on the user's own machine + c := exec.CommandContext(ctx, "terraform", args...) // remove go's default process cancel behaviour, so that terraform has a // chance to gracefully shutdown when ^C is pressed. Otherwise the @@ -180,7 +180,7 @@ func RunPlan(ctx context.Context, args []string) error { } func RunApply(ctx context.Context, args []string) error { - c := exec.CommandContext(ctx, "terraform", args...) //nolint:gosec // G702: args are CLI arguments from the local user who invoked this command; this tool runs on the user's own machine + c := exec.CommandContext(ctx, "terraform", args...) // remove go's default process cancel behaviour, so that terraform has a // chance to gracefully shutdown when ^C is pressed. Otherwise the diff --git a/cmd/root.go b/cmd/root.go index 512f4f95..0148f684 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -522,7 +522,7 @@ func login(ctx context.Context, cmd *cobra.Command, scopes []string, writer io.W } // apply a timeout to the main body of processing - ctx, _ = context.WithTimeout(ctx, timeout) //nolint:govet // the context will not leak as the command will exit when it is done + ctx, _ = context.WithTimeout(ctx, timeout) //nolint:govet,gosec // the context will not leak as the command will exit when it is done return ctx, oi, token, nil } diff --git a/cmd/terraform_plan.go b/cmd/terraform_plan.go index b7c67e7e..92962219 100644 --- a/cmd/terraform_plan.go +++ b/cmd/terraform_plan.go @@ -116,7 +116,7 @@ func TerraformPlanImpl(ctx context.Context, cmd *cobra.Command, oi sdp.OvermindI // Convert provided plan into JSON for easier parsing /////////////////////////////////////////////////////////////////// - tfPlanJsonCmd := exec.CommandContext(ctx, "terraform", "show", "-json", planFile) //nolint:gosec // G702: "terraform", "show", "-json" are hardcoded; planFile is from the local user's CLI -out flag + tfPlanJsonCmd := exec.CommandContext(ctx, "terraform", "show", "-json", planFile) tfPlanJsonCmd.Stderr = multi.NewWriter() // send output through PTerm; is usually empty @@ -182,7 +182,7 @@ func TerraformPlanImpl(ctx context.Context, cmd *cobra.Command, oi sdp.OvermindI } line := printer.Sprintf("%v (%v)", mapping.TerraformName, mapping.Message) - _, err = fmt.Fprintf(resourceExtractionResults, " %v\n", line) //nolint:gosec // G203: resourceExtractionResults is a pterm.MultiPrinter writer (terminal UI), not an http.ResponseWriter; no XSS vector + _, err = fmt.Fprintf(resourceExtractionResults, " %v\n", line) if err != nil { return fmt.Errorf("error writing to resource extraction results: %w", err) } @@ -230,7 +230,7 @@ func TerraformPlanImpl(ctx context.Context, cmd *cobra.Command, oi sdp.OvermindI } title := changeTitle(ctx, viper.GetString("title")) - tfPlanTextCmd := exec.CommandContext(ctx, "terraform", "show", planFile) //nolint:gosec // G702: "terraform" and "show" are hardcoded; planFile is from the local user's CLI -out flag + tfPlanTextCmd := exec.CommandContext(ctx, "terraform", "show", planFile) tfPlanTextCmd.Stderr = multi.NewWriter() // send output through PTerm; is usually empty @@ -514,7 +514,7 @@ func osc8Hyperlink(url, text string) string { // getTicketLinkFromPlan reads the plan file to create a unique hash to identify this change func getTicketLinkFromPlan(planFile string) (string, error) { - plan, err := os.ReadFile(planFile) //nolint:gosec // G703: planFile is from the local user's CLI args; reading their chosen file is the intended behavior of this CLI tool + plan, err := os.ReadFile(planFile) if err != nil { return "", fmt.Errorf("failed to read plan file (%v): %w", planFile, err) } diff --git a/cmd/version_check.go b/cmd/version_check.go index 62ac39fd..1be29d5f 100644 --- a/cmd/version_check.go +++ b/cmd/version_check.go @@ -55,7 +55,7 @@ func checkVersion(ctx context.Context, currentVersion string) (latestVersion str req.Header.Set("User-Agent", fmt.Sprintf("overmind-cli/%s", currentVersion)) req.Header.Set("Accept", "application/vnd.github.v3+json") - resp, err := client.Do(req) //nolint:gosec // G704: URL is the hardcoded constant githubReleasesURL; no user input reaches the request URL + resp, err := client.Do(req) if err != nil { log.WithError(err).Debug("Failed to check for CLI updates") return "", false diff --git a/go.mod b/go.mod index 0d293a59..c46a5e38 100644 --- a/go.mod +++ b/go.mod @@ -12,14 +12,14 @@ require ( atomicgo.dev/keyboard v0.2.9 buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20260209202127-80ab13bee0bf.1 buf.build/go/protovalidate v1.1.3 - charm.land/lipgloss/v2 v2.0.0 - cloud.google.com/go/aiplatform v1.119.0 + charm.land/lipgloss/v2 v2.0.2 + cloud.google.com/go/aiplatform v1.120.0 cloud.google.com/go/auth v0.18.2 cloud.google.com/go/auth/oauth2adapt v0.2.8 cloud.google.com/go/bigquery v1.74.0 cloud.google.com/go/bigtable v1.42.0 cloud.google.com/go/certificatemanager v1.9.6 - cloud.google.com/go/compute v1.56.0 + cloud.google.com/go/compute v1.57.0 cloud.google.com/go/compute/metadata v0.9.0 // indirect cloud.google.com/go/container v1.46.0 cloud.google.com/go/dataplex v1.28.0 @@ -38,7 +38,7 @@ require ( cloud.google.com/go/secretmanager v1.16.0 cloud.google.com/go/securitycentermanagement v1.1.6 cloud.google.com/go/spanner v1.88.0 - cloud.google.com/go/storage v1.60.0 + cloud.google.com/go/storage v1.61.3 cloud.google.com/go/storagetransfer v1.13.1 connectrpc.com/connect v1.18.1 // v1.19.0 was faulty, wait until it is above this version github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 @@ -73,17 +73,17 @@ require ( github.com/aws/aws-sdk-go-v2/service/ec2 v1.294.0 github.com/aws/aws-sdk-go-v2/service/ecs v1.73.1 github.com/aws/aws-sdk-go-v2/service/efs v1.41.12 - github.com/aws/aws-sdk-go-v2/service/eks v1.80.2 + github.com/aws/aws-sdk-go-v2/service/eks v1.81.0 github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.33.21 github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.54.8 - github.com/aws/aws-sdk-go-v2/service/iam v1.53.4 + github.com/aws/aws-sdk-go-v2/service/iam v1.53.5 github.com/aws/aws-sdk-go-v2/service/kms v1.50.2 github.com/aws/aws-sdk-go-v2/service/lambda v1.88.2 github.com/aws/aws-sdk-go-v2/service/networkfirewall v1.59.5 github.com/aws/aws-sdk-go-v2/service/networkmanager v1.41.6 github.com/aws/aws-sdk-go-v2/service/rds v1.116.2 github.com/aws/aws-sdk-go-v2/service/route53 v1.62.3 - github.com/aws/aws-sdk-go-v2/service/s3 v1.96.4 + github.com/aws/aws-sdk-go-v2/service/s3 v1.97.0 github.com/aws/aws-sdk-go-v2/service/sns v1.39.13 github.com/aws/aws-sdk-go-v2/service/sqs v1.42.23 github.com/aws/aws-sdk-go-v2/service/ssm v1.68.2 @@ -97,14 +97,14 @@ require ( github.com/go-jose/go-jose/v4 v4.1.3 github.com/google/btree v1.1.3 github.com/google/uuid v1.6.0 - github.com/googleapis/gax-go/v2 v2.17.0 + github.com/googleapis/gax-go/v2 v2.18.0 github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e github.com/hashicorp/go-retryablehttp v0.7.8 github.com/hashicorp/hcl/v2 v2.24.0 github.com/hashicorp/terraform-config-inspect v0.0.0-20260224005459-813a97530220 - github.com/hashicorp/terraform-plugin-framework v1.18.0 - github.com/hashicorp/terraform-plugin-go v0.30.0 - github.com/hashicorp/terraform-plugin-testing v1.14.0 + github.com/hashicorp/terraform-plugin-framework v1.19.0 + github.com/hashicorp/terraform-plugin-go v0.31.0 + github.com/hashicorp/terraform-plugin-testing v1.15.0 github.com/jedib0t/go-pretty/v6 v6.7.8 github.com/lithammer/fuzzysearch v1.1.8 // indirect github.com/micahhausler/aws-iam-policy v0.4.4 @@ -112,7 +112,7 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/muesli/reflow v0.3.0 github.com/nats-io/jwt/v2 v2.8.0 - github.com/nats-io/nats-server/v2 v2.12.4 + github.com/nats-io/nats-server/v2 v2.12.5 github.com/nats-io/nats.go v1.49.0 github.com/nats-io/nkeys v0.4.15 github.com/onsi/ginkgo/v2 v2.28.1 // indirect @@ -132,23 +132,23 @@ require ( github.com/zclconf/go-cty v1.18.0 go.etcd.io/bbolt v1.4.3 go.opentelemetry.io/contrib/detectors/aws/ec2/v2 v2.0.0-20250901115419-474a7992e57c - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.66.0 - go.opentelemetry.io/otel v1.41.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.41.0 - go.opentelemetry.io/otel/sdk v1.41.0 - go.opentelemetry.io/otel/trace v1.41.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 + go.opentelemetry.io/otel v1.42.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 + go.opentelemetry.io/otel/sdk v1.42.0 + go.opentelemetry.io/otel/trace v1.42.0 go.uber.org/automaxprocs v1.6.0 go.uber.org/goleak v1.3.0 go.uber.org/mock v0.6.0 - golang.org/x/net v0.51.0 - golang.org/x/oauth2 v0.35.0 - golang.org/x/sync v0.19.0 - golang.org/x/text v0.34.0 + golang.org/x/net v0.52.0 + golang.org/x/oauth2 v0.36.0 + golang.org/x/sync v0.20.0 + golang.org/x/text v0.35.0 gonum.org/v1/gonum v0.17.0 - google.golang.org/api v0.269.0 - google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 + google.golang.org/api v0.271.0 + google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c google.golang.org/grpc v1.79.2 google.golang.org/protobuf v1.36.11 gopkg.in/ini.v1 v1.67.1 @@ -175,12 +175,12 @@ require ( github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 // indirect - github.com/ProtonMail/go-crypto v1.1.6 // indirect + github.com/ProtonMail/go-crypto v1.3.0 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/alecthomas/chroma/v2 v2.16.0 // indirect github.com/alecthomas/kingpin/v2 v2.4.0 // indirect github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect - github.com/antithesishq/antithesis-sdk-go v0.5.0-default-no-op // indirect + github.com/antithesishq/antithesis-sdk-go v0.6.0-default-no-op // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/apache/arrow/go/v15 v15.0.2 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect @@ -239,7 +239,7 @@ require ( github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-tpm v0.9.8 // indirect github.com/google/s2a-go v0.1.9 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.12 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect github.com/gookit/color v1.5.4 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect @@ -251,21 +251,21 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.7.0 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect - github.com/hashicorp/go-version v1.7.0 // indirect - github.com/hashicorp/hc-install v0.9.2 // indirect + github.com/hashicorp/go-version v1.8.0 // indirect + github.com/hashicorp/hc-install v0.9.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect - github.com/hashicorp/terraform-exec v0.24.0 // indirect + github.com/hashicorp/terraform-exec v0.25.0 // indirect github.com/hashicorp/terraform-json v0.27.2 // indirect github.com/hashicorp/terraform-plugin-log v0.10.0 // indirect - github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.1 // indirect + github.com/hashicorp/terraform-plugin-sdk/v2 v2.40.0 // indirect github.com/hashicorp/terraform-registry-address v0.4.0 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.2 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.3 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/lestrrat-go/blackmagic v1.0.4 // indirect @@ -324,24 +324,24 @@ require ( go.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect go.opentelemetry.io/otel/log v0.11.0 // indirect - go.opentelemetry.io/otel/metric v1.41.0 // indirect + go.opentelemetry.io/otel/metric v1.42.0 // indirect go.opentelemetry.io/otel/schema v0.0.12 // indirect - go.opentelemetry.io/otel/sdk/metric v1.41.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.48.0 // indirect + golang.org/x/crypto v0.49.0 // indirect golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect golang.org/x/mod v0.33.0 // indirect - golang.org/x/sys v0.41.0 // indirect - golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2 // indirect - golang.org/x/term v0.40.0 // indirect - golang.org/x/time v0.14.0 // indirect - golang.org/x/tools v0.41.0 // indirect + golang.org/x/sys v0.42.0 // indirect + golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4 // indirect + golang.org/x/term v0.41.0 // indirect + golang.org/x/time v0.15.0 // indirect + golang.org/x/tools v0.42.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect + google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect diff --git a/go.sum b/go.sum index e7c3971c..a03a71f8 100644 --- a/go.sum +++ b/go.sum @@ -14,12 +14,12 @@ buf.build/go/protovalidate v1.1.3 h1:m2GVEgQWd7rk+vIoAZ+f0ygGjvQTuqPQapBBdcpWVPE buf.build/go/protovalidate v1.1.3/go.mod h1:9XIuohWz+kj+9JVn3WQneHA5LZP50mjvneZMnbLkiIE= cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= -charm.land/lipgloss/v2 v2.0.0 h1:sd8N/B3x892oiOjFfBQdXBQp3cAkvjGaU5TvVZC3ivo= -charm.land/lipgloss/v2 v2.0.0/go.mod h1:w6SnmsBFBmEFBodiEDurGS/sdUY/u1+v72DqUzc6J14= +charm.land/lipgloss/v2 v2.0.2 h1:xFolbF8JdpNkM2cEPTfXEcW1p6NRzOWTSamRfYEw8cs= +charm.land/lipgloss/v2 v2.0.2/go.mod h1:KjPle2Qd3YmvP1KL5OMHiHysGcNwq6u83MUjYkFvEkM= cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= -cloud.google.com/go/aiplatform v1.119.0 h1:Fum1ighlxsmwbmaf0nhuMDebcKJkpx2mgmd1YcyXaYY= -cloud.google.com/go/aiplatform v1.119.0/go.mod h1:27DcZJbaxFntewF6O0HojDE1B8JQOGKYopNjwoICFdI= +cloud.google.com/go/aiplatform v1.120.0 h1:jKWTpEs+xoUhDa1FMdSuhMcEQYyUiMdufGyX3zvtLVQ= +cloud.google.com/go/aiplatform v1.120.0/go.mod h1:6mDthfmy0oS1EQhVFdijoxkVdI2+HIZkpuGTBpedeCg= cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM= cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= @@ -30,8 +30,8 @@ cloud.google.com/go/bigtable v1.42.0 h1:SREvT4jLhJQZXUjsLmFs/1SMQJ+rKEj1cJuPE9li cloud.google.com/go/bigtable v1.42.0/go.mod h1:oZ30nofVB6/UYGg7lBwGLWSea7NZUvw/WvBBgLY07xU= cloud.google.com/go/certificatemanager v1.9.6 h1:v5X8X+THKrS9OFZb6k0GRDP1WQxLXTdMko7OInBliw4= cloud.google.com/go/certificatemanager v1.9.6/go.mod h1:vWogV874jKZkSRDFCMM3r7wqybv8WXs3XhyNff6o/Zo= -cloud.google.com/go/compute v1.56.0 h1:e8xch/mR0tJoUBj3nhNb96+MOQ1JGVGB+rBfVzWEU5I= -cloud.google.com/go/compute v1.56.0/go.mod h1:fMFC0mRv+fW2ISg7M3tpDfpZ+kkrHpC/ImNFRCYiNK0= +cloud.google.com/go/compute v1.57.0 h1:uACoYJCUftJxxoI7si8u1S9szRDalftrWSjo1Dizfx4= +cloud.google.com/go/compute v1.57.0/go.mod h1:3shEe5By6FSIqBbZJBuqC0InvJKBKUiWZjrwGd1wkyA= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/container v1.46.0 h1:xX94Lo3xrS5OkdMWKvpEVAbBwjN9uleVv6vOi02fL4s= @@ -72,8 +72,8 @@ cloud.google.com/go/securitycentermanagement v1.1.6 h1:XFqjKq4ZpKTj8xCXWs/mTmh/U cloud.google.com/go/securitycentermanagement v1.1.6/go.mod h1:nt5Z6rU4s2/j8R/EQxG5K7OfVAfAfwo89j0Nx2Srzaw= cloud.google.com/go/spanner v1.88.0 h1:HS+5TuEYZOVOXj9K+0EtrbTw7bKBLrMe3vgGsbnehmU= cloud.google.com/go/spanner v1.88.0/go.mod h1:MzulBwuuYwQUVdkZXBBFapmXee3N+sQrj2T/yup6uEE= -cloud.google.com/go/storage v1.60.0 h1:oBfZrSOCimggVNz9Y/bXY35uUcts7OViubeddTTVzQ8= -cloud.google.com/go/storage v1.60.0/go.mod h1:q+5196hXfejkctrnx+VYU8RKQr/L3c0cBIlrjmiAKE0= +cloud.google.com/go/storage v1.61.3 h1:VS//ZfBuPGDvakfD9xyPW1RGF1Vy3BWUoVZXgW1KMOg= +cloud.google.com/go/storage v1.61.3/go.mod h1:JtqK8BBB7TWv0HVGHubtUdzYYrakOQIsMLffZ2Z/HWk= cloud.google.com/go/storagetransfer v1.13.1 h1:Sjukr1LtUt7vLTHNvGc2gaAqlXNFeDFRIRmWGrFaJlY= cloud.google.com/go/storagetransfer v1.13.1/go.mod h1:S858w5l383ffkdqAqrAA+BC7KlhCqeNieK3sFf5Bj4Y= cloud.google.com/go/trace v1.11.7 h1:kDNDX8JkaAG3R2nq1lIdkb7FCSi1rCmsEtKVsty7p+U= @@ -157,8 +157,8 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/MrAlias/otel-schema-utils v0.4.0-alpha h1:6ZG9rw4NvxKwRp2Bmnfr8WJZVWLhK4e5n3+ezXE6Z2g= github.com/MrAlias/otel-schema-utils v0.4.0-alpha/go.mod h1:baehOhES9qiLv9xMcsY6ZQlKLBRR89XVJEvU7Yz3qJk= -github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw= -github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= +github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= @@ -171,8 +171,8 @@ github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0= github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= -github.com/antithesishq/antithesis-sdk-go v0.5.0-default-no-op h1:Ucf+QxEKMbPogRO5guBNe5cgd9uZgfoJLOYs8WWhtjM= -github.com/antithesishq/antithesis-sdk-go v0.5.0-default-no-op/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl3v2yvUZjmKncl7U91fup7E= +github.com/antithesishq/antithesis-sdk-go v0.6.0-default-no-op h1:kpBdlEPbRvff0mDD1gk7o9BhI16b9p5yYAXRlidpqJE= +github.com/antithesishq/antithesis-sdk-go v0.6.0-default-no-op/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl3v2yvUZjmKncl7U91fup7E= github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/apache/arrow/go/v15 v15.0.2 h1:60IliRbiyTWCWjERBCkO1W4Qun9svcYoZrSLcyOsMLE= @@ -219,14 +219,14 @@ github.com/aws/aws-sdk-go-v2/service/ecs v1.73.1 h1:TSmcWx+RzhGJrPNoFkuqANafJQ7x github.com/aws/aws-sdk-go-v2/service/ecs v1.73.1/go.mod h1:KWILGx+bRowcGyJU/va2Ift48c658blP5e1qvldnIRE= github.com/aws/aws-sdk-go-v2/service/efs v1.41.12 h1:YZXW11dESIf6CNhMG2ICZonCkzKBaGLuFamSJTYV5g0= github.com/aws/aws-sdk-go-v2/service/efs v1.41.12/go.mod h1:+rjniKD0YQAmjiDNJvLodKXn1vXWwMpctrr/M4zm1V4= -github.com/aws/aws-sdk-go-v2/service/eks v1.80.2 h1:+FLU7+D9AW9ZMQIg4YjIN/nTJV0A2TIB2f+ovZXqAdU= -github.com/aws/aws-sdk-go-v2/service/eks v1.80.2/go.mod h1:nx52u/3RVDWkOcrAchYgt7CXkrd03A6Gvzi0trtMFjQ= +github.com/aws/aws-sdk-go-v2/service/eks v1.81.0 h1:sI0DVFTT+ILkk4QDNKU5a+arj+kduG2qJZoI3vnDKcc= +github.com/aws/aws-sdk-go-v2/service/eks v1.81.0/go.mod h1:nx52u/3RVDWkOcrAchYgt7CXkrd03A6Gvzi0trtMFjQ= github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.33.21 h1:VriOdPKF8YrkMpnT76ZwA2LXk5aBInOfuzN14QGTOJc= github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.33.21/go.mod h1:sp4Mz5YUnYCvIkGNEcdEPp+DuHqquEZYXyIuKXuHzig= github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.54.8 h1:xUwbqWhKASQsigeQfeBjhbm6dAP1EeTulHnNSYv5Xfc= github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.54.8/go.mod h1:sQoz/dTooY3kCkNNGxVLTS7EacLA0qXUaK4BkpMjGOc= -github.com/aws/aws-sdk-go-v2/service/iam v1.53.4 h1:FUWGS7m97SYL0bk9Kb+Q4bVpcSrKOHNiIbEXIRFTRW4= -github.com/aws/aws-sdk-go-v2/service/iam v1.53.4/go.mod h1:seDE466zJ4haVuAVcRk+yIH4DWb3s6cqt3Od8GxnGAA= +github.com/aws/aws-sdk-go-v2/service/iam v1.53.5 h1:J8qtztl/SJ6lhk/Rke/F6PgpZ7V6UYq0my0Zc8hdLuc= +github.com/aws/aws-sdk-go-v2/service/iam v1.53.5/go.mod h1:seDE466zJ4haVuAVcRk+yIH4DWb3s6cqt3Od8GxnGAA= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.6 h1:XAq62tBTJP/85lFD5oqOOe7YYgWxY9LvWq8plyDvDVg= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.6/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.11 h1:BYf7XNsJMzl4mObARUBUib+j2tf0U//JAAtTnYqvqCw= @@ -249,8 +249,8 @@ github.com/aws/aws-sdk-go-v2/service/rds v1.116.2 h1:KQLPCn9BWXW0Y8DyzEokbTF9HOi github.com/aws/aws-sdk-go-v2/service/rds v1.116.2/go.mod h1:aPw0arz1e+cZUbF4LU7ZMYB1ZSYsJKi/tsAq9wADfeE= github.com/aws/aws-sdk-go-v2/service/route53 v1.62.3 h1:JRPXnIr0WwFsSHBmuCvT/uh0Vgys+crvwkOghbJEqi8= github.com/aws/aws-sdk-go-v2/service/route53 v1.62.3/go.mod h1:DHddp7OO4bY467WVCqWBzk5+aEWn7vqYkap7UigJzGk= -github.com/aws/aws-sdk-go-v2/service/s3 v1.96.4 h1:4ExZyubQ6LQQVuF2Qp9OsfEvsTdAWh5Gfwf6PgIdLdk= -github.com/aws/aws-sdk-go-v2/service/s3 v1.96.4/go.mod h1:NF3JcMGOiARAss1ld3WGORCw71+4ExDD2cbbdKS5PpA= +github.com/aws/aws-sdk-go-v2/service/s3 v1.97.0 h1:zyKY4OxzUImu+DigelJI9o49QQv8CjREs5E1CywjtIA= +github.com/aws/aws-sdk-go-v2/service/s3 v1.97.0/go.mod h1:NF3JcMGOiARAss1ld3WGORCw71+4ExDD2cbbdKS5PpA= github.com/aws/aws-sdk-go-v2/service/signin v1.0.7 h1:Y2cAXlClHsXkkOvWZFXATr34b0hxxloeQu/pAZz2row= github.com/aws/aws-sdk-go-v2/service/signin v1.0.7/go.mod h1:idzZ7gmDeqeNrSPkdbtMp9qWMgcBwykA7P7Rzh5DXVU= github.com/aws/aws-sdk-go-v2/service/sns v1.39.13 h1:8xP94tDzFpgwIOsusGiEFHPaqrpckDojoErk/ZFZTio= @@ -269,8 +269,8 @@ github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= -github.com/aymanbagabas/go-udiff v0.4.0 h1:TKnLPh7IbnizJIBKFWa9mKayRUBQ9Kh1BPCk6w2PnYM= -github.com/aymanbagabas/go-udiff v0.4.0/go.mod h1:0L9PGwj20lrtmEMeyw4WKJ/TMyDtvAoK9bf2u/mNo3w= +github.com/aymanbagabas/go-udiff v0.4.1 h1:OEIrQ8maEeDBXQDoGCbbTTXYJMYRCRO1fnodZ12Gv5o= +github.com/aymanbagabas/go-udiff v0.4.1/go.mod h1:0L9PGwj20lrtmEMeyw4WKJ/TMyDtvAoK9bf2u/mNo3w= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/brianvoe/gofakeit/v6 v6.28.0 h1:Xib46XXuQfmlLS2EXRuJpqcw8St6qSZz75OUo0tgAW4= @@ -360,8 +360,8 @@ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66D github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= -github.com/go-git/go-git/v5 v5.14.0 h1:/MD3lCrGjCen5WfEAzKg00MJJffKhC8gzS80ycmCi60= -github.com/go-git/go-git/v5 v5.14.0/go.mod h1:Z5Xhoia5PcWA3NF8vRLURn9E5FRhSl7dGj9ItW3Wk5k= +github.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s= +github.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M= github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -417,10 +417,10 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.12 h1:Fg+zsqzYEs1ZnvmcztTYxhgCBsx3eEhEwQ1W/lHq/sQ= -github.com/googleapis/enterprise-certificate-proxy v0.3.12/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= -github.com/googleapis/gax-go/v2 v2.17.0 h1:RksgfBpxqff0EZkDWYuz9q/uWsTVz+kf43LsZ1J6SMc= -github.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY= +github.com/googleapis/enterprise-certificate-proxy v0.3.14 h1:yh8ncqsbUY4shRD5dA6RlzjJaT4hi3kII+zYw8wmLb8= +github.com/googleapis/enterprise-certificate-proxy v0.3.14/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= +github.com/googleapis/gax-go/v2 v2.18.0 h1:jxP5Uuo3bxm3M6gGtV94P4lliVetoCB4Wk2x8QA86LI= +github.com/googleapis/gax-go/v2 v2.18.0/go.mod h1:uSzZN4a356eRG985CzJ3WfbFSpqkLTjsnhWGJR6EwrE= github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= @@ -452,10 +452,10 @@ github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3 github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.9.2 h1:v80EtNX4fCVHqzL9Lg/2xkp62bbvQMnvPQ0G+OmtO24= -github.com/hashicorp/hc-install v0.9.2/go.mod h1:XUqBQNnuT4RsxoxiM9ZaUk0NX8hi2h+Lb6/c0OZnC/I= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/hc-install v0.9.3 h1:1H4dgmgzxEVwT6E/d/vIL5ORGVKz9twRwDw+qA5Hyho= +github.com/hashicorp/hc-install v0.9.3/go.mod h1:FQlQ5I3I/X409N/J1U4pPeQQz1R3BoV0IysB7aiaQE0= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl/v2 v2.24.0 h1:2QJdZ454DSsYGoaE6QheQZjtKZSUs9Nh2izTWiwQxvE= @@ -464,20 +464,20 @@ github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/terraform-config-inspect v0.0.0-20260224005459-813a97530220 h1:v0h6j7IMgA24b8aWG5+d6WStIP9G8e/p0DKK3Bmk7YQ= github.com/hashicorp/terraform-config-inspect v0.0.0-20260224005459-813a97530220/go.mod h1:Gz/z9Hbn+4KSp8A2FBtNszfLSdT2Tn/uAKGuVqqWmDI= -github.com/hashicorp/terraform-exec v0.24.0 h1:mL0xlk9H5g2bn0pPF6JQZk5YlByqSqrO5VoaNtAf8OE= -github.com/hashicorp/terraform-exec v0.24.0/go.mod h1:lluc/rDYfAhYdslLJQg3J0oDqo88oGQAdHR+wDqFvo4= +github.com/hashicorp/terraform-exec v0.25.0 h1:Bkt6m3VkJqYh+laFMrWIpy9KHYFITpOyzRMNI35rNaY= +github.com/hashicorp/terraform-exec v0.25.0/go.mod h1:dl9IwsCfklDU6I4wq9/StFDp7dNbH/h5AnfS1RmiUl8= github.com/hashicorp/terraform-json v0.27.2 h1:BwGuzM6iUPqf9JYM/Z4AF1OJ5VVJEEzoKST/tRDBJKU= github.com/hashicorp/terraform-json v0.27.2/go.mod h1:GzPLJ1PLdUG5xL6xn1OXWIjteQRT2CNT9o/6A9mi9hE= -github.com/hashicorp/terraform-plugin-framework v1.18.0 h1:Xy6OfqSTZfAAKXSlJ810lYvuQvYkOpSUoNMQ9l2L1RA= -github.com/hashicorp/terraform-plugin-framework v1.18.0/go.mod h1:eeFIf68PME+kenJeqSrIcpHhYQK0TOyv7ocKdN4Z35E= -github.com/hashicorp/terraform-plugin-go v0.30.0 h1:VmEiD0n/ewxbvV5VI/bYwNtlSEAXtHaZlSnyUUuQK6k= -github.com/hashicorp/terraform-plugin-go v0.30.0/go.mod h1:8d523ORAW8OHgA9e8JKg0ezL3XUO84H0A25o4NY/jRo= +github.com/hashicorp/terraform-plugin-framework v1.19.0 h1:q0bwyhxAOR3vfdgbk9iplv3MlTv/dhBHTXjQOtQDoBA= +github.com/hashicorp/terraform-plugin-framework v1.19.0/go.mod h1:YRXOBu0jvs7xp4AThBbX4mAzYaMJ1JgtFH//oGKxwLc= +github.com/hashicorp/terraform-plugin-go v0.31.0 h1:0Fz2r9DQ+kNNl6bx8HRxFd1TfMKUvnrOtvJPmp3Z0q8= +github.com/hashicorp/terraform-plugin-go v0.31.0/go.mod h1:A88bDhd/cW7FnwqxQRz3slT+QY6yzbHKc6AOTtmdeS8= github.com/hashicorp/terraform-plugin-log v0.10.0 h1:eu2kW6/QBVdN4P3Ju2WiB2W3ObjkAsyfBsL3Wh1fj3g= github.com/hashicorp/terraform-plugin-log v0.10.0/go.mod h1:/9RR5Cv2aAbrqcTSdNmY1NRHP4E3ekrXRGjqORpXyB0= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.1 h1:mlAq/OrMlg04IuJT7NpefI1wwtdpWudnEmjuQs04t/4= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.1/go.mod h1:GQhpKVvvuwzD79e8/NZ+xzj+ZpWovdPAe8nfV/skwNU= -github.com/hashicorp/terraform-plugin-testing v1.14.0 h1:5t4VKrjOJ0rg0sVuSJ86dz5K7PHsMO6OKrHFzDBerWA= -github.com/hashicorp/terraform-plugin-testing v1.14.0/go.mod h1:1qfWkecyYe1Do2EEOK/5/WnTyvC8wQucUkkhiGLg5nk= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.40.0 h1:MKS/2URqeJRwJdbOfcbdsZCq/IRrNkqJNN0GtVIsuGs= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.40.0/go.mod h1:PuG4P97Ju3QXW6c6vRkRadWJbvnEu2Xh+oOuqcYOqX4= +github.com/hashicorp/terraform-plugin-testing v1.15.0 h1:/fimKyl0YgD7aAtJkuuAZjwBASXhCIwWqMbDLnKLMe4= +github.com/hashicorp/terraform-plugin-testing v1.15.0/go.mod h1:bGXMw7bE95EiZhSBV3rM2W8TiffaPTDuLS+HFI/lIYs= github.com/hashicorp/terraform-registry-address v0.4.0 h1:S1yCGomj30Sao4l5BMPjTGZmCNzuv7/GDTDX99E9gTk= github.com/hashicorp/terraform-registry-address v0.4.0/go.mod h1:LRS1Ay0+mAiRkUyltGT+UHWkIqTFvigGn/LbMshfflE= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= @@ -504,8 +504,8 @@ github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4 github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= -github.com/klauspost/compress v1.18.3 h1:9PJRvfbmTabkOX8moIpXPbMMbYN60bWImDDU7L+/6zw= -github.com/klauspost/compress v1.18.3/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= @@ -588,8 +588,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nats-io/jwt/v2 v2.8.0 h1:K7uzyz50+yGZDO5o772eRE7atlcSEENpL7P+b74JV1g= github.com/nats-io/jwt/v2 v2.8.0/go.mod h1:me11pOkwObtcBNR8AiMrUbtVOUGkqYjMQZ6jnSdVUIA= -github.com/nats-io/nats-server/v2 v2.12.4 h1:ZnT10v2LU2Xcoiy8ek9X6Se4YG8EuMfIfvAEuFVx1Ts= -github.com/nats-io/nats-server/v2 v2.12.4/go.mod h1:5MCp/pqm5SEfsvVZ31ll1088ZTwEUdvRX1Hmh/mTTDg= +github.com/nats-io/nats-server/v2 v2.12.5 h1:EOHLbsLJgUHUwzkj9gBTOlubkX+dmSs0EYWMdBiHivU= +github.com/nats-io/nats-server/v2 v2.12.5/go.mod h1:JQDAKcwdXs0NRhvYO31dzsXkzCyDkOBS7SKU3Nozu14= github.com/nats-io/nats.go v1.49.0 h1:yh/WvY59gXqYpgl33ZI+XoVPKyut/IcEaqtsiuTJpoE= github.com/nats-io/nats.go v1.49.0/go.mod h1:fDCn3mN5cY8HooHwE2ukiLb4p4G4ImmzvXyJt+tGwdw= github.com/nats-io/nkeys v0.4.15 h1:JACV5jRVO9V856KOapQ7x+EY8Jo3qw1vJt/9Jpwzkk4= @@ -744,30 +744,30 @@ go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK2 go.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.66.0 h1:PnV4kVnw0zOmwwFkAzCN5O07fw1YOIQor120zrh0AVo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.66.0/go.mod h1:ofAwF4uinaf8SXdVzzbL4OsxJ3VfeEg3f/F6CeF49/Y= -go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c= -go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 h1:ao6Oe+wSebTlQ1OEht7jlYTzQKE+pnx/iNywFvTbuuI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0/go.mod h1:u3T6vz0gh/NVzgDgiwkgLxpsSF6PaPmo2il0apGJbls= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 h1:inYW9ZhgqiDqh6BioM7DVHHzEGVq76Db5897WLGZ5Go= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0/go.mod h1:Izur+Wt8gClgMJqO/cZ8wdeeMryJ/xxiOVgFSSfpDTY= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 h1:5gn2urDL/FBnK8OkCfD1j3/ER79rUuTYmCvlXBKeYL8= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0/go.mod h1:0fBG6ZJxhqByfFZDwSwpZGzJU671HkwpWaNe2t4VUPI= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.41.0 h1:61oRQmYGMW7pXmFjPg1Muy84ndqMxQ6SH2L8fBG8fSY= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.41.0/go.mod h1:c0z2ubK4RQL+kSDuuFu9WnuXimObon3IiKjJf4NACvU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 h1:uLXP+3mghfMf7XmV4PkGfFhFKuNWoCvvx5wP/wOXo0o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0/go.mod h1:v0Tj04armyT59mnURNUJf7RCKcKzq+lgJs6QSjHjaTc= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.40.0 h1:ZrPRak/kS4xI3AVXy8F7pipuDXmDsrO8Lg+yQjBLjw0= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.40.0/go.mod h1:3y6kQCWztq6hyW8Z9YxQDDm0Je9AJoFar2G0yDcmhRk= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 h1:s/1iRkCKDfhlh1JF26knRneorus8aOwVIDhvYx9WoDw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0/go.mod h1:UI3wi0FXg1Pofb8ZBiBLhtMzgoTm1TYkMvn71fAqDzs= go.opentelemetry.io/otel/log v0.11.0 h1:c24Hrlk5WJ8JWcwbQxdBqxZdOK7PcP/LFtOtwpDTe3Y= go.opentelemetry.io/otel/log v0.11.0/go.mod h1:U/sxQ83FPmT29trrifhQg+Zj2lo1/IPN1PF6RTFqdwc= -go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ= -go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/schema v0.0.12 h1:X8NKrwH07Oe9SJruY/D1XmwHrb6D2+qrLs2POlZX7F4= go.opentelemetry.io/otel/schema v0.0.12/go.mod h1:+w+Q7DdGfykSNi+UU9GAQz5/rtYND6FkBJUWUXzZb0M= -go.opentelemetry.io/otel/sdk v1.41.0 h1:YPIEXKmiAwkGl3Gu1huk1aYWwtpRLeskpV+wPisxBp8= -go.opentelemetry.io/otel/sdk v1.41.0/go.mod h1:ahFdU0G5y8IxglBf0QBJXgSe7agzjE4GiTJ6HT9ud90= -go.opentelemetry.io/otel/sdk/metric v1.41.0 h1:siZQIYBAUd1rlIWQT2uCxWJxcCO7q3TriaMlf08rXw8= -go.opentelemetry.io/otel/sdk/metric v1.41.0/go.mod h1:HNBuSvT7ROaGtGI50ArdRLUnvRTRGniSUZbxiWxSO8Y= -go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0= -go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= @@ -782,8 +782,8 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY= golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -795,16 +795,16 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= -golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -823,50 +823,50 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2 h1:O1cMQHRfwNpDfDJerqRoE2oD+AFlyid87D40L/OkkJo= -golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2/go.mod h1:b7fPSJ0pKZ3ccUh8gnTONJxhn3c/PS6tyzQvyqw4iA8= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4 h1:bTLqdHv7xrGlFbvf5/TXNxy/iUwwdkjhqQTJDjW7aj0= +golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4/go.mod h1:g5NllXBEermZrmR51cJDQxmJUHUOfRAaNyWBM+R+548= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= -golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= +golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= +golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= -golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= -golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/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-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= -google.golang.org/api v0.269.0 h1:qDrTOxKUQ/P0MveH6a7vZ+DNHxJQjtGm/uvdbdGXCQg= -google.golang.org/api v0.269.0/go.mod h1:N8Wpcu23Tlccl0zSHEkcAZQKDLdquxK+l9r2LkwAauE= +google.golang.org/api v0.271.0 h1:cIPN4qcUc61jlh7oXu6pwOQqbJW2GqYh5PS6rB2C/JY= +google.golang.org/api v0.271.0/go.mod h1:CGT29bhwkbF+i11qkRUJb2KMKqcJ1hdFceEIRd9u64Q= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM= -google.golang.org/genproto v0.0.0-20260128011058-8636f8732409/go.mod h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM= -google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0= -google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d h1:vsOm753cOAMkt76efriTCDKjpCbK18XGHMJHo0JUKhc= +google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:0oz9d7g9QLSdv9/lgbIjowW1JoxMbxmBVNe8i6tORJI= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= +google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c h1:xgCzyF2LFIO/0X2UAoVRiXKU5Xg6VjToG4i2/ecSswk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= diff --git a/go/auth/auth.go b/go/auth/auth.go index 21f37347..9b7e2ce2 100644 --- a/go/auth/auth.go +++ b/go/auth/auth.go @@ -70,7 +70,7 @@ type ClientCredentialsConfig struct { // The ClientID of the application that we'll be authenticating as ClientID string // ClientSecret that corresponds to the ClientID - ClientSecret string //nolint:gosec // G101 (hardcoded secret): config field name, not a credential value; never JSON-marshaled into logs or responses + ClientSecret string } type TokenSourceOptionsFunc func(*clientcredentials.Config) @@ -128,7 +128,7 @@ func (flowConfig ClientCredentialsConfig) TokenSource(ctx context.Context, oAuth type Auth0Config struct { Domain string ClientID string - ClientSecret string //nolint:gosec // G101 (hardcoded secret): config field name, not a credential value; populated from env vars and only used in OAuth token exchange + ClientSecret string Audience string } @@ -298,7 +298,7 @@ func (n *natsTokenClient) Sign(in []byte) ([]byte, error) { // tokens type APIKeyTokenSource struct { // The API Key to use to authenticate to the Overmind API - ApiKey string //nolint:gosec // G101 (hardcoded secret): config field name, not a credential value; only passed to API key exchange endpoint + ApiKey string token *oauth2.Token apiKeyClient sdpconnect.ApiKeyServiceClient } diff --git a/go/auth/middleware_test.go b/go/auth/middleware_test.go index f0618753..5b00928c 100644 --- a/go/auth/middleware_test.go +++ b/go/auth/middleware_test.go @@ -705,7 +705,7 @@ func TestWithResourceMetadata(t *testing.T) { handler := WithResourceMetadata(prmURL, inner) rr := httptest.NewRecorder() - req := httptest.NewRequest(http.MethodPost, "/area51/mcp", nil) + req := httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/area51/mcp", nil) handler.ServeHTTP(rr, req) if rr.Code != http.StatusUnauthorized { @@ -727,7 +727,7 @@ func TestWithResourceMetadata(t *testing.T) { handler := WithResourceMetadata(prmURL, inner) rr := httptest.NewRecorder() - req := httptest.NewRequest(http.MethodPost, "/area51/mcp", nil) + req := httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/area51/mcp", nil) handler.ServeHTTP(rr, req) if rr.Code != http.StatusOK { @@ -747,7 +747,7 @@ func TestWithResourceMetadata(t *testing.T) { handler := WithResourceMetadata(prmURL, inner) rr := httptest.NewRecorder() - req := httptest.NewRequest(http.MethodPost, "/area51/mcp", nil) + req := httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/area51/mcp", nil) handler.ServeHTTP(rr, req) if rr.Code != http.StatusForbidden { @@ -767,7 +767,7 @@ func TestWithResourceMetadata(t *testing.T) { handler := WithResourceMetadata(prmURL, inner) rr := httptest.NewRecorder() - req := httptest.NewRequest(http.MethodGet, "/area51/mcp", nil) + req := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/area51/mcp", nil) handler.ServeHTTP(rr, req) if rr.Code != http.StatusOK { diff --git a/go/discovery/adapterhost_bench_test.go b/go/discovery/adapterhost_bench_test.go index 91501d79..7136e830 100644 --- a/go/discovery/adapterhost_bench_test.go +++ b/go/discovery/adapterhost_bench_test.go @@ -272,7 +272,7 @@ func (b *BenchmarkListAdapter) List(ctx context.Context, scope string, ignoreCac ErrorString: "no items found", Scope: scope, } - b.cache.StoreError(ctx, err, b.DefaultCacheDuration(), ck) + b.cache.StoreUnavailableItem(ctx, err, b.DefaultCacheDuration(), ck) return nil, err case "error": return nil, &sdp.QueryError{ diff --git a/go/discovery/engine.go b/go/discovery/engine.go index e5a1dfbb..eeef3dbe 100644 --- a/go/discovery/engine.go +++ b/go/discovery/engine.go @@ -62,7 +62,7 @@ type EngineConfig struct { // The 'ovm_*' API key to use to authenticate to the Overmind API. // This and 'SourceAccessToken' are mutually exclusive - ApiKey string //nolint:gosec // G101 (hardcoded secret): config field name, not a credential value; populated from CLI flags/env vars + ApiKey string // Static token passed to the source to authenticate. SourceAccessToken string // The access token to use to authenticate to the source SourceAccessTokenType string // The type of token to use to authenticate the source for managed sources diff --git a/go/discovery/shared_test.go b/go/discovery/shared_test.go index b4e42d99..52c0ccef 100644 --- a/go/discovery/shared_test.go +++ b/go/discovery/shared_test.go @@ -167,7 +167,7 @@ func (s *TestAdapter) Get(ctx context.Context, scope string, query string, ignor ErrorString: "no items found", Scope: scope, } - s.cache.StoreError(ctx, err, s.DefaultCacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.DefaultCacheDuration(), ck) return nil, err case "error": return nil, &sdp.QueryError{ @@ -210,7 +210,7 @@ func (s *TestAdapter) List(ctx context.Context, scope string, ignoreCache bool) ErrorString: "no items found", Scope: scope, } - s.cache.StoreError(ctx, err, s.DefaultCacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.DefaultCacheDuration(), ck) return nil, err case "error": return nil, &sdp.QueryError{ @@ -254,7 +254,7 @@ func (s *TestAdapter) Search(ctx context.Context, scope string, query string, ig ErrorString: "no items found", Scope: scope, } - s.cache.StoreError(ctx, err, s.DefaultCacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.DefaultCacheDuration(), ck) return nil, err case "error": return nil, &sdp.QueryError{ diff --git a/go/sdp-go/changes.pb.go b/go/sdp-go/changes.pb.go index 2d4c3d7f..789cb46c 100644 --- a/go/sdp-go/changes.pb.go +++ b/go/sdp-go/changes.pb.go @@ -482,6 +482,56 @@ func (ChangeStatus) EnumDescriptor() ([]byte, []int) { return file_changes_proto_rawDescGZIP(), []int{7} } +// Risk feedback sentiment values +type RiskFeedbackSentiment int32 + +const ( + RiskFeedbackSentiment_RISK_FEEDBACK_SENTIMENT_UNSPECIFIED RiskFeedbackSentiment = 0 + RiskFeedbackSentiment_RISK_FEEDBACK_SENTIMENT_POSITIVE RiskFeedbackSentiment = 1 + RiskFeedbackSentiment_RISK_FEEDBACK_SENTIMENT_NEGATIVE RiskFeedbackSentiment = 2 +) + +// Enum value maps for RiskFeedbackSentiment. +var ( + RiskFeedbackSentiment_name = map[int32]string{ + 0: "RISK_FEEDBACK_SENTIMENT_UNSPECIFIED", + 1: "RISK_FEEDBACK_SENTIMENT_POSITIVE", + 2: "RISK_FEEDBACK_SENTIMENT_NEGATIVE", + } + RiskFeedbackSentiment_value = map[string]int32{ + "RISK_FEEDBACK_SENTIMENT_UNSPECIFIED": 0, + "RISK_FEEDBACK_SENTIMENT_POSITIVE": 1, + "RISK_FEEDBACK_SENTIMENT_NEGATIVE": 2, + } +) + +func (x RiskFeedbackSentiment) Enum() *RiskFeedbackSentiment { + p := new(RiskFeedbackSentiment) + *p = x + return p +} + +func (x RiskFeedbackSentiment) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (RiskFeedbackSentiment) Descriptor() protoreflect.EnumDescriptor { + return file_changes_proto_enumTypes[8].Descriptor() +} + +func (RiskFeedbackSentiment) Type() protoreflect.EnumType { + return &file_changes_proto_enumTypes[8] +} + +func (x RiskFeedbackSentiment) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use RiskFeedbackSentiment.Descriptor instead. +func (RiskFeedbackSentiment) EnumDescriptor() ([]byte, []int) { + return file_changes_proto_rawDescGZIP(), []int{8} +} + type StartChangeResponse_State int32 const ( @@ -522,11 +572,11 @@ func (x StartChangeResponse_State) String() string { } func (StartChangeResponse_State) Descriptor() protoreflect.EnumDescriptor { - return file_changes_proto_enumTypes[8].Descriptor() + return file_changes_proto_enumTypes[9].Descriptor() } func (StartChangeResponse_State) Type() protoreflect.EnumType { - return &file_changes_proto_enumTypes[8] + return &file_changes_proto_enumTypes[9] } func (x StartChangeResponse_State) Number() protoreflect.EnumNumber { @@ -578,11 +628,11 @@ func (x EndChangeResponse_State) String() string { } func (EndChangeResponse_State) Descriptor() protoreflect.EnumDescriptor { - return file_changes_proto_enumTypes[9].Descriptor() + return file_changes_proto_enumTypes[10].Descriptor() } func (EndChangeResponse_State) Type() protoreflect.EnumType { - return &file_changes_proto_enumTypes[9] + return &file_changes_proto_enumTypes[10] } func (x EndChangeResponse_State) Number() protoreflect.EnumNumber { @@ -630,11 +680,11 @@ func (x Risk_Severity) String() string { } func (Risk_Severity) Descriptor() protoreflect.EnumDescriptor { - return file_changes_proto_enumTypes[10].Descriptor() + return file_changes_proto_enumTypes[11].Descriptor() } func (Risk_Severity) Type() protoreflect.EnumType { - return &file_changes_proto_enumTypes[10] + return &file_changes_proto_enumTypes[11] } func (x Risk_Severity) Number() protoreflect.EnumNumber { @@ -685,11 +735,11 @@ func (x ChangeAnalysisStatus_Status) String() string { } func (ChangeAnalysisStatus_Status) Descriptor() protoreflect.EnumDescriptor { - return file_changes_proto_enumTypes[11].Descriptor() + return file_changes_proto_enumTypes[12].Descriptor() } func (ChangeAnalysisStatus_Status) Type() protoreflect.EnumType { - return &file_changes_proto_enumTypes[11] + return &file_changes_proto_enumTypes[12] } func (x ChangeAnalysisStatus_Status) Number() protoreflect.EnumNumber { @@ -6583,6 +6633,111 @@ func (x *GenerateRiskFixResponse) GetFixSuggestion() string { return "" } +// Submit user feedback on a risk +type SubmitRiskFeedbackRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + RiskUuid []byte `protobuf:"bytes,1,opt,name=risk_uuid,json=riskUuid,proto3" json:"risk_uuid,omitempty"` + Sentiment RiskFeedbackSentiment `protobuf:"varint,2,opt,name=sentiment,proto3,enum=changes.RiskFeedbackSentiment" json:"sentiment,omitempty"` + FeedbackText string `protobuf:"bytes,3,opt,name=feedback_text,json=feedbackText,proto3" json:"feedback_text,omitempty"` + Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // extensible key-value pairs (e.g. utm_source, surface) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SubmitRiskFeedbackRequest) Reset() { + *x = SubmitRiskFeedbackRequest{} + mi := &file_changes_proto_msgTypes[97] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SubmitRiskFeedbackRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubmitRiskFeedbackRequest) ProtoMessage() {} + +func (x *SubmitRiskFeedbackRequest) ProtoReflect() protoreflect.Message { + mi := &file_changes_proto_msgTypes[97] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubmitRiskFeedbackRequest.ProtoReflect.Descriptor instead. +func (*SubmitRiskFeedbackRequest) Descriptor() ([]byte, []int) { + return file_changes_proto_rawDescGZIP(), []int{97} +} + +func (x *SubmitRiskFeedbackRequest) GetRiskUuid() []byte { + if x != nil { + return x.RiskUuid + } + return nil +} + +func (x *SubmitRiskFeedbackRequest) GetSentiment() RiskFeedbackSentiment { + if x != nil { + return x.Sentiment + } + return RiskFeedbackSentiment_RISK_FEEDBACK_SENTIMENT_UNSPECIFIED +} + +func (x *SubmitRiskFeedbackRequest) GetFeedbackText() string { + if x != nil { + return x.FeedbackText + } + return "" +} + +func (x *SubmitRiskFeedbackRequest) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + +type SubmitRiskFeedbackResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SubmitRiskFeedbackResponse) Reset() { + *x = SubmitRiskFeedbackResponse{} + mi := &file_changes_proto_msgTypes[98] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SubmitRiskFeedbackResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubmitRiskFeedbackResponse) ProtoMessage() {} + +func (x *SubmitRiskFeedbackResponse) ProtoReflect() protoreflect.Message { + mi := &file_changes_proto_msgTypes[98] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubmitRiskFeedbackResponse.ProtoReflect.Descriptor instead. +func (*SubmitRiskFeedbackResponse) Descriptor() ([]byte, []int) { + return file_changes_proto_rawDescGZIP(), []int{98} +} + // Represents the current state of a given health state, and the amount that // it has changed. This doesn't just look at the change in total number of // items, but also the number of items that have been added and removed, even @@ -6603,7 +6758,7 @@ type ChangeMetadata_HealthChange struct { func (x *ChangeMetadata_HealthChange) Reset() { *x = ChangeMetadata_HealthChange{} - mi := &file_changes_proto_msgTypes[99] + mi := &file_changes_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6615,7 +6770,7 @@ func (x *ChangeMetadata_HealthChange) String() string { func (*ChangeMetadata_HealthChange) ProtoMessage() {} func (x *ChangeMetadata_HealthChange) ProtoReflect() protoreflect.Message { - mi := &file_changes_proto_msgTypes[99] + mi := &file_changes_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7127,7 +7282,16 @@ const file_changes_proto_rawDesc = "" + "\x16GenerateRiskFixRequest\x12\x1a\n" + "\briskUUID\x18\x01 \x01(\fR\briskUUID\"?\n" + "\x17GenerateRiskFixResponse\x12$\n" + - "\rfixSuggestion\x18\x01 \x01(\tR\rfixSuggestion*\xf6\x01\n" + + "\rfixSuggestion\x18\x01 \x01(\tR\rfixSuggestion\"\xa6\x02\n" + + "\x19SubmitRiskFeedbackRequest\x12\x1b\n" + + "\trisk_uuid\x18\x01 \x01(\fR\briskUuid\x12<\n" + + "\tsentiment\x18\x02 \x01(\x0e2\x1e.changes.RiskFeedbackSentimentR\tsentiment\x12#\n" + + "\rfeedback_text\x18\x03 \x01(\tR\ffeedbackText\x12L\n" + + "\bmetadata\x18\x04 \x03(\v20.changes.SubmitRiskFeedbackRequest.MetadataEntryR\bmetadata\x1a;\n" + + "\rMetadataEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\x1c\n" + + "\x1aSubmitRiskFeedbackResponse*\xf6\x01\n" + "\x18MappedItemTimelineStatus\x12+\n" + "'MAPPED_ITEM_TIMELINE_STATUS_UNSPECIFIED\x10\x00\x12'\n" + "#MAPPED_ITEM_TIMELINE_STATUS_SUCCESS\x10\x01\x12%\n" + @@ -7173,7 +7337,11 @@ const file_changes_proto_rawDesc = "" + "\x16CHANGE_STATUS_DEFINING\x10\x01\x12\x1b\n" + "\x17CHANGE_STATUS_HAPPENING\x10\x02\x12 \n" + "\x18CHANGE_STATUS_PROCESSING\x10\x03\x1a\x02\b\x01\x12\x16\n" + - "\x12CHANGE_STATUS_DONE\x10\x042\x89\x11\n" + + "\x12CHANGE_STATUS_DONE\x10\x04*\x8c\x01\n" + + "\x15RiskFeedbackSentiment\x12'\n" + + "#RISK_FEEDBACK_SENTIMENT_UNSPECIFIED\x10\x00\x12$\n" + + " RISK_FEEDBACK_SENTIMENT_POSITIVE\x10\x01\x12$\n" + + " RISK_FEEDBACK_SENTIMENT_NEGATIVE\x10\x022\xe8\x11\n" + "\x0eChangesService\x12H\n" + "\vListChanges\x12\x1b.changes.ListChangesRequest\x1a\x1c.changes.ListChangesResponse\x12`\n" + "\x13ListChangesByStatus\x12#.changes.ListChangesByStatusRequest\x1a$.changes.ListChangesByStatusResponse\x12K\n" + @@ -7196,7 +7364,8 @@ const file_changes_proto_rawDesc = "" + "\x18ListChangingItemsSummary\x12(.changes.ListChangingItemsSummaryRequest\x1a).changes.ListChangingItemsSummaryResponse\x12<\n" + "\aGetDiff\x12\x17.changes.GetDiffRequest\x1a\x18.changes.GetDiffResponse\x12f\n" + "\x15PopulateChangeFilters\x12%.changes.PopulateChangeFiltersRequest\x1a&.changes.PopulateChangeFiltersResponse\x12T\n" + - "\x0fGenerateRiskFix\x12\x1f.changes.GenerateRiskFixRequest\x1a .changes.GenerateRiskFixResponse\x12c\n" + + "\x0fGenerateRiskFix\x12\x1f.changes.GenerateRiskFixRequest\x1a .changes.GenerateRiskFixResponse\x12]\n" + + "\x12SubmitRiskFeedback\x12\".changes.SubmitRiskFeedbackRequest\x1a#.changes.SubmitRiskFeedbackResponse\x12c\n" + "\x14GetHypothesesDetails\x12$.changes.GetHypothesesDetailsRequest\x1a%.changes.GetHypothesesDetailsResponse\x12W\n" + "\x10GetChangeSignals\x12 .changes.GetChangeSignalsRequest\x1a!.changes.GetChangeSignalsResponse\x12Z\n" + "\x11AddPlannedChanges\x12!.changes.AddPlannedChangesRequest\x1a\".changes.AddPlannedChangesResponse2\xfc\x04\n" + @@ -7221,8 +7390,8 @@ func file_changes_proto_rawDescGZIP() []byte { return file_changes_proto_rawDescData } -var file_changes_proto_enumTypes = make([]protoimpl.EnumInfo, 12) -var file_changes_proto_msgTypes = make([]protoimpl.MessageInfo, 101) +var file_changes_proto_enumTypes = make([]protoimpl.EnumInfo, 13) +var file_changes_proto_msgTypes = make([]protoimpl.MessageInfo, 104) var file_changes_proto_goTypes = []any{ (MappedItemTimelineStatus)(0), // 0: changes.MappedItemTimelineStatus (MappedItemMappingStatus)(0), // 1: changes.MappedItemMappingStatus @@ -7232,311 +7401,319 @@ var file_changes_proto_goTypes = []any{ (ChangeOutputFormat)(0), // 5: changes.ChangeOutputFormat (LabelType)(0), // 6: changes.LabelType (ChangeStatus)(0), // 7: changes.ChangeStatus - (StartChangeResponse_State)(0), // 8: changes.StartChangeResponse.State - (EndChangeResponse_State)(0), // 9: changes.EndChangeResponse.State - (Risk_Severity)(0), // 10: changes.Risk.Severity - (ChangeAnalysisStatus_Status)(0), // 11: changes.ChangeAnalysisStatus.Status - (*LabelRule)(nil), // 12: changes.LabelRule - (*LabelRuleMetadata)(nil), // 13: changes.LabelRuleMetadata - (*LabelRuleProperties)(nil), // 14: changes.LabelRuleProperties - (*ListLabelRulesRequest)(nil), // 15: changes.ListLabelRulesRequest - (*ListLabelRulesResponse)(nil), // 16: changes.ListLabelRulesResponse - (*CreateLabelRuleRequest)(nil), // 17: changes.CreateLabelRuleRequest - (*CreateLabelRuleResponse)(nil), // 18: changes.CreateLabelRuleResponse - (*GetLabelRuleRequest)(nil), // 19: changes.GetLabelRuleRequest - (*GetLabelRuleResponse)(nil), // 20: changes.GetLabelRuleResponse - (*UpdateLabelRuleRequest)(nil), // 21: changes.UpdateLabelRuleRequest - (*UpdateLabelRuleResponse)(nil), // 22: changes.UpdateLabelRuleResponse - (*DeleteLabelRuleRequest)(nil), // 23: changes.DeleteLabelRuleRequest - (*DeleteLabelRuleResponse)(nil), // 24: changes.DeleteLabelRuleResponse - (*TestLabelRuleRequest)(nil), // 25: changes.TestLabelRuleRequest - (*TestLabelRuleResponse)(nil), // 26: changes.TestLabelRuleResponse - (*ReapplyLabelRuleInTimeRangeRequest)(nil), // 27: changes.ReapplyLabelRuleInTimeRangeRequest - (*ReapplyLabelRuleInTimeRangeResponse)(nil), // 28: changes.ReapplyLabelRuleInTimeRangeResponse - (*KnowledgeReference)(nil), // 29: changes.KnowledgeReference - (*Knowledge)(nil), // 30: changes.Knowledge - (*GetHypothesesDetailsRequest)(nil), // 31: changes.GetHypothesesDetailsRequest - (*GetHypothesesDetailsResponse)(nil), // 32: changes.GetHypothesesDetailsResponse - (*HypothesesDetails)(nil), // 33: changes.HypothesesDetails - (*GetChangeTimelineV2Request)(nil), // 34: changes.GetChangeTimelineV2Request - (*GetChangeTimelineV2Response)(nil), // 35: changes.GetChangeTimelineV2Response - (*ChangeTimelineEntryV2)(nil), // 36: changes.ChangeTimelineEntryV2 - (*EmptyContent)(nil), // 37: changes.EmptyContent - (*MappedItemTimelineSummary)(nil), // 38: changes.MappedItemTimelineSummary - (*MappedItemsTimelineEntry)(nil), // 39: changes.MappedItemsTimelineEntry - (*CalculatedBlastRadiusTimelineEntry)(nil), // 40: changes.CalculatedBlastRadiusTimelineEntry - (*RecordObservationsTimelineEntry)(nil), // 41: changes.RecordObservationsTimelineEntry - (*FormHypothesesTimelineEntry)(nil), // 42: changes.FormHypothesesTimelineEntry - (*InvestigateHypothesesTimelineEntry)(nil), // 43: changes.InvestigateHypothesesTimelineEntry - (*HypothesisSummary)(nil), // 44: changes.HypothesisSummary - (*CalculatedRisksTimelineEntry)(nil), // 45: changes.CalculatedRisksTimelineEntry - (*CalculatedLabelsTimelineEntry)(nil), // 46: changes.CalculatedLabelsTimelineEntry - (*ChangeValidationTimelineEntry)(nil), // 47: changes.ChangeValidationTimelineEntry - (*ChangeValidationCategory)(nil), // 48: changes.ChangeValidationCategory - (*GetDiffRequest)(nil), // 49: changes.GetDiffRequest - (*GetDiffResponse)(nil), // 50: changes.GetDiffResponse - (*ListChangingItemsSummaryRequest)(nil), // 51: changes.ListChangingItemsSummaryRequest - (*ListChangingItemsSummaryResponse)(nil), // 52: changes.ListChangingItemsSummaryResponse - (*MappedItemDiff)(nil), // 53: changes.MappedItemDiff - (*StartChangeAnalysisRequest)(nil), // 54: changes.StartChangeAnalysisRequest - (*StartChangeAnalysisResponse)(nil), // 55: changes.StartChangeAnalysisResponse - (*AddPlannedChangesRequest)(nil), // 56: changes.AddPlannedChangesRequest - (*AddPlannedChangesResponse)(nil), // 57: changes.AddPlannedChangesResponse - (*ListHomeChangesRequest)(nil), // 58: changes.ListHomeChangesRequest - (*ChangeFiltersRequest)(nil), // 59: changes.ChangeFiltersRequest - (*ListHomeChangesResponse)(nil), // 60: changes.ListHomeChangesResponse - (*PopulateChangeFiltersRequest)(nil), // 61: changes.PopulateChangeFiltersRequest - (*PopulateChangeFiltersResponse)(nil), // 62: changes.PopulateChangeFiltersResponse - (*ItemDiffSummary)(nil), // 63: changes.ItemDiffSummary - (*ItemDiff)(nil), // 64: changes.ItemDiff - (*EnrichedTags)(nil), // 65: changes.EnrichedTags - (*TagValue)(nil), // 66: changes.TagValue - (*UserTagValue)(nil), // 67: changes.UserTagValue - (*AutoTagValue)(nil), // 68: changes.AutoTagValue - (*Label)(nil), // 69: changes.Label - (*ChangeSummary)(nil), // 70: changes.ChangeSummary - (*Change)(nil), // 71: changes.Change - (*ChangeMetadata)(nil), // 72: changes.ChangeMetadata - (*ChangeProperties)(nil), // 73: changes.ChangeProperties - (*GithubChangeInfo)(nil), // 74: changes.GithubChangeInfo - (*ListChangesRequest)(nil), // 75: changes.ListChangesRequest - (*ListChangesResponse)(nil), // 76: changes.ListChangesResponse - (*ListChangesByStatusRequest)(nil), // 77: changes.ListChangesByStatusRequest - (*ListChangesByStatusResponse)(nil), // 78: changes.ListChangesByStatusResponse - (*CreateChangeRequest)(nil), // 79: changes.CreateChangeRequest - (*CreateChangeResponse)(nil), // 80: changes.CreateChangeResponse - (*GetChangeRequest)(nil), // 81: changes.GetChangeRequest - (*GetChangeByTicketLinkRequest)(nil), // 82: changes.GetChangeByTicketLinkRequest - (*GetChangeSummaryRequest)(nil), // 83: changes.GetChangeSummaryRequest - (*GetChangeSummaryResponse)(nil), // 84: changes.GetChangeSummaryResponse - (*GetChangeSignalsRequest)(nil), // 85: changes.GetChangeSignalsRequest - (*GetChangeSignalsResponse)(nil), // 86: changes.GetChangeSignalsResponse - (*GetChangeResponse)(nil), // 87: changes.GetChangeResponse - (*GetChangeRisksRequest)(nil), // 88: changes.GetChangeRisksRequest - (*ChangeRiskMetadata)(nil), // 89: changes.ChangeRiskMetadata - (*GetChangeRisksResponse)(nil), // 90: changes.GetChangeRisksResponse - (*UpdateChangeRequest)(nil), // 91: changes.UpdateChangeRequest - (*UpdateChangeResponse)(nil), // 92: changes.UpdateChangeResponse - (*DeleteChangeRequest)(nil), // 93: changes.DeleteChangeRequest - (*ListChangesBySnapshotUUIDRequest)(nil), // 94: changes.ListChangesBySnapshotUUIDRequest - (*ListChangesBySnapshotUUIDResponse)(nil), // 95: changes.ListChangesBySnapshotUUIDResponse - (*DeleteChangeResponse)(nil), // 96: changes.DeleteChangeResponse - (*RefreshStateRequest)(nil), // 97: changes.RefreshStateRequest - (*RefreshStateResponse)(nil), // 98: changes.RefreshStateResponse - (*StartChangeRequest)(nil), // 99: changes.StartChangeRequest - (*StartChangeResponse)(nil), // 100: changes.StartChangeResponse - (*EndChangeRequest)(nil), // 101: changes.EndChangeRequest - (*EndChangeResponse)(nil), // 102: changes.EndChangeResponse - (*StartChangeSimpleResponse)(nil), // 103: changes.StartChangeSimpleResponse - (*EndChangeSimpleResponse)(nil), // 104: changes.EndChangeSimpleResponse - (*Risk)(nil), // 105: changes.Risk - (*ChangeAnalysisStatus)(nil), // 106: changes.ChangeAnalysisStatus - (*GenerateRiskFixRequest)(nil), // 107: changes.GenerateRiskFixRequest - (*GenerateRiskFixResponse)(nil), // 108: changes.GenerateRiskFixResponse - nil, // 109: changes.EnrichedTags.TagValueEntry - nil, // 110: changes.ChangeSummary.TagsEntry - (*ChangeMetadata_HealthChange)(nil), // 111: changes.ChangeMetadata.HealthChange - nil, // 112: changes.ChangeProperties.TagsEntry - (*timestamppb.Timestamp)(nil), // 113: google.protobuf.Timestamp - (*Edge)(nil), // 114: Edge - (*Query)(nil), // 115: Query - (*QueryError)(nil), // 116: QueryError - (*BlastRadiusConfig)(nil), // 117: config.BlastRadiusConfig - (*RoutineChangesConfig)(nil), // 118: config.RoutineChangesConfig - (*GithubOrganisationProfile)(nil), // 119: config.GithubOrganisationProfile - (*PaginationRequest)(nil), // 120: PaginationRequest - (SortOrder)(0), // 121: SortOrder - (*PaginationResponse)(nil), // 122: PaginationResponse - (*Reference)(nil), // 123: Reference - (Health)(0), // 124: Health - (*Item)(nil), // 125: Item + (RiskFeedbackSentiment)(0), // 8: changes.RiskFeedbackSentiment + (StartChangeResponse_State)(0), // 9: changes.StartChangeResponse.State + (EndChangeResponse_State)(0), // 10: changes.EndChangeResponse.State + (Risk_Severity)(0), // 11: changes.Risk.Severity + (ChangeAnalysisStatus_Status)(0), // 12: changes.ChangeAnalysisStatus.Status + (*LabelRule)(nil), // 13: changes.LabelRule + (*LabelRuleMetadata)(nil), // 14: changes.LabelRuleMetadata + (*LabelRuleProperties)(nil), // 15: changes.LabelRuleProperties + (*ListLabelRulesRequest)(nil), // 16: changes.ListLabelRulesRequest + (*ListLabelRulesResponse)(nil), // 17: changes.ListLabelRulesResponse + (*CreateLabelRuleRequest)(nil), // 18: changes.CreateLabelRuleRequest + (*CreateLabelRuleResponse)(nil), // 19: changes.CreateLabelRuleResponse + (*GetLabelRuleRequest)(nil), // 20: changes.GetLabelRuleRequest + (*GetLabelRuleResponse)(nil), // 21: changes.GetLabelRuleResponse + (*UpdateLabelRuleRequest)(nil), // 22: changes.UpdateLabelRuleRequest + (*UpdateLabelRuleResponse)(nil), // 23: changes.UpdateLabelRuleResponse + (*DeleteLabelRuleRequest)(nil), // 24: changes.DeleteLabelRuleRequest + (*DeleteLabelRuleResponse)(nil), // 25: changes.DeleteLabelRuleResponse + (*TestLabelRuleRequest)(nil), // 26: changes.TestLabelRuleRequest + (*TestLabelRuleResponse)(nil), // 27: changes.TestLabelRuleResponse + (*ReapplyLabelRuleInTimeRangeRequest)(nil), // 28: changes.ReapplyLabelRuleInTimeRangeRequest + (*ReapplyLabelRuleInTimeRangeResponse)(nil), // 29: changes.ReapplyLabelRuleInTimeRangeResponse + (*KnowledgeReference)(nil), // 30: changes.KnowledgeReference + (*Knowledge)(nil), // 31: changes.Knowledge + (*GetHypothesesDetailsRequest)(nil), // 32: changes.GetHypothesesDetailsRequest + (*GetHypothesesDetailsResponse)(nil), // 33: changes.GetHypothesesDetailsResponse + (*HypothesesDetails)(nil), // 34: changes.HypothesesDetails + (*GetChangeTimelineV2Request)(nil), // 35: changes.GetChangeTimelineV2Request + (*GetChangeTimelineV2Response)(nil), // 36: changes.GetChangeTimelineV2Response + (*ChangeTimelineEntryV2)(nil), // 37: changes.ChangeTimelineEntryV2 + (*EmptyContent)(nil), // 38: changes.EmptyContent + (*MappedItemTimelineSummary)(nil), // 39: changes.MappedItemTimelineSummary + (*MappedItemsTimelineEntry)(nil), // 40: changes.MappedItemsTimelineEntry + (*CalculatedBlastRadiusTimelineEntry)(nil), // 41: changes.CalculatedBlastRadiusTimelineEntry + (*RecordObservationsTimelineEntry)(nil), // 42: changes.RecordObservationsTimelineEntry + (*FormHypothesesTimelineEntry)(nil), // 43: changes.FormHypothesesTimelineEntry + (*InvestigateHypothesesTimelineEntry)(nil), // 44: changes.InvestigateHypothesesTimelineEntry + (*HypothesisSummary)(nil), // 45: changes.HypothesisSummary + (*CalculatedRisksTimelineEntry)(nil), // 46: changes.CalculatedRisksTimelineEntry + (*CalculatedLabelsTimelineEntry)(nil), // 47: changes.CalculatedLabelsTimelineEntry + (*ChangeValidationTimelineEntry)(nil), // 48: changes.ChangeValidationTimelineEntry + (*ChangeValidationCategory)(nil), // 49: changes.ChangeValidationCategory + (*GetDiffRequest)(nil), // 50: changes.GetDiffRequest + (*GetDiffResponse)(nil), // 51: changes.GetDiffResponse + (*ListChangingItemsSummaryRequest)(nil), // 52: changes.ListChangingItemsSummaryRequest + (*ListChangingItemsSummaryResponse)(nil), // 53: changes.ListChangingItemsSummaryResponse + (*MappedItemDiff)(nil), // 54: changes.MappedItemDiff + (*StartChangeAnalysisRequest)(nil), // 55: changes.StartChangeAnalysisRequest + (*StartChangeAnalysisResponse)(nil), // 56: changes.StartChangeAnalysisResponse + (*AddPlannedChangesRequest)(nil), // 57: changes.AddPlannedChangesRequest + (*AddPlannedChangesResponse)(nil), // 58: changes.AddPlannedChangesResponse + (*ListHomeChangesRequest)(nil), // 59: changes.ListHomeChangesRequest + (*ChangeFiltersRequest)(nil), // 60: changes.ChangeFiltersRequest + (*ListHomeChangesResponse)(nil), // 61: changes.ListHomeChangesResponse + (*PopulateChangeFiltersRequest)(nil), // 62: changes.PopulateChangeFiltersRequest + (*PopulateChangeFiltersResponse)(nil), // 63: changes.PopulateChangeFiltersResponse + (*ItemDiffSummary)(nil), // 64: changes.ItemDiffSummary + (*ItemDiff)(nil), // 65: changes.ItemDiff + (*EnrichedTags)(nil), // 66: changes.EnrichedTags + (*TagValue)(nil), // 67: changes.TagValue + (*UserTagValue)(nil), // 68: changes.UserTagValue + (*AutoTagValue)(nil), // 69: changes.AutoTagValue + (*Label)(nil), // 70: changes.Label + (*ChangeSummary)(nil), // 71: changes.ChangeSummary + (*Change)(nil), // 72: changes.Change + (*ChangeMetadata)(nil), // 73: changes.ChangeMetadata + (*ChangeProperties)(nil), // 74: changes.ChangeProperties + (*GithubChangeInfo)(nil), // 75: changes.GithubChangeInfo + (*ListChangesRequest)(nil), // 76: changes.ListChangesRequest + (*ListChangesResponse)(nil), // 77: changes.ListChangesResponse + (*ListChangesByStatusRequest)(nil), // 78: changes.ListChangesByStatusRequest + (*ListChangesByStatusResponse)(nil), // 79: changes.ListChangesByStatusResponse + (*CreateChangeRequest)(nil), // 80: changes.CreateChangeRequest + (*CreateChangeResponse)(nil), // 81: changes.CreateChangeResponse + (*GetChangeRequest)(nil), // 82: changes.GetChangeRequest + (*GetChangeByTicketLinkRequest)(nil), // 83: changes.GetChangeByTicketLinkRequest + (*GetChangeSummaryRequest)(nil), // 84: changes.GetChangeSummaryRequest + (*GetChangeSummaryResponse)(nil), // 85: changes.GetChangeSummaryResponse + (*GetChangeSignalsRequest)(nil), // 86: changes.GetChangeSignalsRequest + (*GetChangeSignalsResponse)(nil), // 87: changes.GetChangeSignalsResponse + (*GetChangeResponse)(nil), // 88: changes.GetChangeResponse + (*GetChangeRisksRequest)(nil), // 89: changes.GetChangeRisksRequest + (*ChangeRiskMetadata)(nil), // 90: changes.ChangeRiskMetadata + (*GetChangeRisksResponse)(nil), // 91: changes.GetChangeRisksResponse + (*UpdateChangeRequest)(nil), // 92: changes.UpdateChangeRequest + (*UpdateChangeResponse)(nil), // 93: changes.UpdateChangeResponse + (*DeleteChangeRequest)(nil), // 94: changes.DeleteChangeRequest + (*ListChangesBySnapshotUUIDRequest)(nil), // 95: changes.ListChangesBySnapshotUUIDRequest + (*ListChangesBySnapshotUUIDResponse)(nil), // 96: changes.ListChangesBySnapshotUUIDResponse + (*DeleteChangeResponse)(nil), // 97: changes.DeleteChangeResponse + (*RefreshStateRequest)(nil), // 98: changes.RefreshStateRequest + (*RefreshStateResponse)(nil), // 99: changes.RefreshStateResponse + (*StartChangeRequest)(nil), // 100: changes.StartChangeRequest + (*StartChangeResponse)(nil), // 101: changes.StartChangeResponse + (*EndChangeRequest)(nil), // 102: changes.EndChangeRequest + (*EndChangeResponse)(nil), // 103: changes.EndChangeResponse + (*StartChangeSimpleResponse)(nil), // 104: changes.StartChangeSimpleResponse + (*EndChangeSimpleResponse)(nil), // 105: changes.EndChangeSimpleResponse + (*Risk)(nil), // 106: changes.Risk + (*ChangeAnalysisStatus)(nil), // 107: changes.ChangeAnalysisStatus + (*GenerateRiskFixRequest)(nil), // 108: changes.GenerateRiskFixRequest + (*GenerateRiskFixResponse)(nil), // 109: changes.GenerateRiskFixResponse + (*SubmitRiskFeedbackRequest)(nil), // 110: changes.SubmitRiskFeedbackRequest + (*SubmitRiskFeedbackResponse)(nil), // 111: changes.SubmitRiskFeedbackResponse + nil, // 112: changes.EnrichedTags.TagValueEntry + nil, // 113: changes.ChangeSummary.TagsEntry + (*ChangeMetadata_HealthChange)(nil), // 114: changes.ChangeMetadata.HealthChange + nil, // 115: changes.ChangeProperties.TagsEntry + nil, // 116: changes.SubmitRiskFeedbackRequest.MetadataEntry + (*timestamppb.Timestamp)(nil), // 117: google.protobuf.Timestamp + (*Edge)(nil), // 118: Edge + (*Query)(nil), // 119: Query + (*QueryError)(nil), // 120: QueryError + (*BlastRadiusConfig)(nil), // 121: config.BlastRadiusConfig + (*RoutineChangesConfig)(nil), // 122: config.RoutineChangesConfig + (*GithubOrganisationProfile)(nil), // 123: config.GithubOrganisationProfile + (*PaginationRequest)(nil), // 124: PaginationRequest + (SortOrder)(0), // 125: SortOrder + (*PaginationResponse)(nil), // 126: PaginationResponse + (*Reference)(nil), // 127: Reference + (Health)(0), // 128: Health + (*Item)(nil), // 129: Item } var file_changes_proto_depIdxs = []int32{ - 13, // 0: changes.LabelRule.metadata:type_name -> changes.LabelRuleMetadata - 14, // 1: changes.LabelRule.properties:type_name -> changes.LabelRuleProperties - 113, // 2: changes.LabelRuleMetadata.createdAt:type_name -> google.protobuf.Timestamp - 113, // 3: changes.LabelRuleMetadata.updatedAt:type_name -> google.protobuf.Timestamp - 12, // 4: changes.ListLabelRulesResponse.rules:type_name -> changes.LabelRule - 14, // 5: changes.CreateLabelRuleRequest.properties:type_name -> changes.LabelRuleProperties - 12, // 6: changes.CreateLabelRuleResponse.rule:type_name -> changes.LabelRule - 12, // 7: changes.GetLabelRuleResponse.rule:type_name -> changes.LabelRule - 14, // 8: changes.UpdateLabelRuleRequest.properties:type_name -> changes.LabelRuleProperties - 12, // 9: changes.UpdateLabelRuleResponse.rule:type_name -> changes.LabelRule - 14, // 10: changes.TestLabelRuleRequest.properties:type_name -> changes.LabelRuleProperties - 69, // 11: changes.TestLabelRuleResponse.label:type_name -> changes.Label - 113, // 12: changes.ReapplyLabelRuleInTimeRangeRequest.startAt:type_name -> google.protobuf.Timestamp - 113, // 13: changes.ReapplyLabelRuleInTimeRangeRequest.endAt:type_name -> google.protobuf.Timestamp - 33, // 14: changes.GetHypothesesDetailsResponse.hypotheses:type_name -> changes.HypothesesDetails + 14, // 0: changes.LabelRule.metadata:type_name -> changes.LabelRuleMetadata + 15, // 1: changes.LabelRule.properties:type_name -> changes.LabelRuleProperties + 117, // 2: changes.LabelRuleMetadata.createdAt:type_name -> google.protobuf.Timestamp + 117, // 3: changes.LabelRuleMetadata.updatedAt:type_name -> google.protobuf.Timestamp + 13, // 4: changes.ListLabelRulesResponse.rules:type_name -> changes.LabelRule + 15, // 5: changes.CreateLabelRuleRequest.properties:type_name -> changes.LabelRuleProperties + 13, // 6: changes.CreateLabelRuleResponse.rule:type_name -> changes.LabelRule + 13, // 7: changes.GetLabelRuleResponse.rule:type_name -> changes.LabelRule + 15, // 8: changes.UpdateLabelRuleRequest.properties:type_name -> changes.LabelRuleProperties + 13, // 9: changes.UpdateLabelRuleResponse.rule:type_name -> changes.LabelRule + 15, // 10: changes.TestLabelRuleRequest.properties:type_name -> changes.LabelRuleProperties + 70, // 11: changes.TestLabelRuleResponse.label:type_name -> changes.Label + 117, // 12: changes.ReapplyLabelRuleInTimeRangeRequest.startAt:type_name -> google.protobuf.Timestamp + 117, // 13: changes.ReapplyLabelRuleInTimeRangeRequest.endAt:type_name -> google.protobuf.Timestamp + 34, // 14: changes.GetHypothesesDetailsResponse.hypotheses:type_name -> changes.HypothesesDetails 2, // 15: changes.HypothesesDetails.status:type_name -> changes.HypothesisStatus - 29, // 16: changes.HypothesesDetails.knowledgeUsed:type_name -> changes.KnowledgeReference - 36, // 17: changes.GetChangeTimelineV2Response.entries:type_name -> changes.ChangeTimelineEntryV2 + 30, // 16: changes.HypothesesDetails.knowledgeUsed:type_name -> changes.KnowledgeReference + 37, // 17: changes.GetChangeTimelineV2Response.entries:type_name -> changes.ChangeTimelineEntryV2 3, // 18: changes.ChangeTimelineEntryV2.status:type_name -> changes.ChangeTimelineEntryStatus - 113, // 19: changes.ChangeTimelineEntryV2.startedAt:type_name -> google.protobuf.Timestamp - 113, // 20: changes.ChangeTimelineEntryV2.endedAt:type_name -> google.protobuf.Timestamp - 39, // 21: changes.ChangeTimelineEntryV2.mappedItems:type_name -> changes.MappedItemsTimelineEntry - 40, // 22: changes.ChangeTimelineEntryV2.calculatedBlastRadius:type_name -> changes.CalculatedBlastRadiusTimelineEntry - 45, // 23: changes.ChangeTimelineEntryV2.calculatedRisks:type_name -> changes.CalculatedRisksTimelineEntry - 37, // 24: changes.ChangeTimelineEntryV2.empty:type_name -> changes.EmptyContent - 47, // 25: changes.ChangeTimelineEntryV2.changeValidation:type_name -> changes.ChangeValidationTimelineEntry - 46, // 26: changes.ChangeTimelineEntryV2.calculatedLabels:type_name -> changes.CalculatedLabelsTimelineEntry - 42, // 27: changes.ChangeTimelineEntryV2.formHypotheses:type_name -> changes.FormHypothesesTimelineEntry - 43, // 28: changes.ChangeTimelineEntryV2.investigateHypotheses:type_name -> changes.InvestigateHypothesesTimelineEntry - 41, // 29: changes.ChangeTimelineEntryV2.recordObservations:type_name -> changes.RecordObservationsTimelineEntry + 117, // 19: changes.ChangeTimelineEntryV2.startedAt:type_name -> google.protobuf.Timestamp + 117, // 20: changes.ChangeTimelineEntryV2.endedAt:type_name -> google.protobuf.Timestamp + 40, // 21: changes.ChangeTimelineEntryV2.mappedItems:type_name -> changes.MappedItemsTimelineEntry + 41, // 22: changes.ChangeTimelineEntryV2.calculatedBlastRadius:type_name -> changes.CalculatedBlastRadiusTimelineEntry + 46, // 23: changes.ChangeTimelineEntryV2.calculatedRisks:type_name -> changes.CalculatedRisksTimelineEntry + 38, // 24: changes.ChangeTimelineEntryV2.empty:type_name -> changes.EmptyContent + 48, // 25: changes.ChangeTimelineEntryV2.changeValidation:type_name -> changes.ChangeValidationTimelineEntry + 47, // 26: changes.ChangeTimelineEntryV2.calculatedLabels:type_name -> changes.CalculatedLabelsTimelineEntry + 43, // 27: changes.ChangeTimelineEntryV2.formHypotheses:type_name -> changes.FormHypothesesTimelineEntry + 44, // 28: changes.ChangeTimelineEntryV2.investigateHypotheses:type_name -> changes.InvestigateHypothesesTimelineEntry + 42, // 29: changes.ChangeTimelineEntryV2.recordObservations:type_name -> changes.RecordObservationsTimelineEntry 0, // 30: changes.MappedItemTimelineSummary.status:type_name -> changes.MappedItemTimelineStatus - 53, // 31: changes.MappedItemsTimelineEntry.mappedItems:type_name -> changes.MappedItemDiff - 38, // 32: changes.MappedItemsTimelineEntry.items:type_name -> changes.MappedItemTimelineSummary - 44, // 33: changes.FormHypothesesTimelineEntry.hypotheses:type_name -> changes.HypothesisSummary - 44, // 34: changes.InvestigateHypothesesTimelineEntry.hypotheses:type_name -> changes.HypothesisSummary + 54, // 31: changes.MappedItemsTimelineEntry.mappedItems:type_name -> changes.MappedItemDiff + 39, // 32: changes.MappedItemsTimelineEntry.items:type_name -> changes.MappedItemTimelineSummary + 45, // 33: changes.FormHypothesesTimelineEntry.hypotheses:type_name -> changes.HypothesisSummary + 45, // 34: changes.InvestigateHypothesesTimelineEntry.hypotheses:type_name -> changes.HypothesisSummary 2, // 35: changes.HypothesisSummary.status:type_name -> changes.HypothesisStatus - 105, // 36: changes.CalculatedRisksTimelineEntry.risks:type_name -> changes.Risk - 69, // 37: changes.CalculatedLabelsTimelineEntry.labels:type_name -> changes.Label - 48, // 38: changes.ChangeValidationTimelineEntry.validationChecklist:type_name -> changes.ChangeValidationCategory - 64, // 39: changes.GetDiffResponse.expectedItems:type_name -> changes.ItemDiff - 64, // 40: changes.GetDiffResponse.unexpectedItems:type_name -> changes.ItemDiff - 114, // 41: changes.GetDiffResponse.edges:type_name -> Edge - 64, // 42: changes.GetDiffResponse.missingItems:type_name -> changes.ItemDiff - 63, // 43: changes.ListChangingItemsSummaryResponse.items:type_name -> changes.ItemDiffSummary - 64, // 44: changes.MappedItemDiff.item:type_name -> changes.ItemDiff - 115, // 45: changes.MappedItemDiff.mappingQuery:type_name -> Query - 116, // 46: changes.MappedItemDiff.mappingError:type_name -> QueryError + 106, // 36: changes.CalculatedRisksTimelineEntry.risks:type_name -> changes.Risk + 70, // 37: changes.CalculatedLabelsTimelineEntry.labels:type_name -> changes.Label + 49, // 38: changes.ChangeValidationTimelineEntry.validationChecklist:type_name -> changes.ChangeValidationCategory + 65, // 39: changes.GetDiffResponse.expectedItems:type_name -> changes.ItemDiff + 65, // 40: changes.GetDiffResponse.unexpectedItems:type_name -> changes.ItemDiff + 118, // 41: changes.GetDiffResponse.edges:type_name -> Edge + 65, // 42: changes.GetDiffResponse.missingItems:type_name -> changes.ItemDiff + 64, // 43: changes.ListChangingItemsSummaryResponse.items:type_name -> changes.ItemDiffSummary + 65, // 44: changes.MappedItemDiff.item:type_name -> changes.ItemDiff + 119, // 45: changes.MappedItemDiff.mappingQuery:type_name -> Query + 120, // 46: changes.MappedItemDiff.mappingError:type_name -> QueryError 1, // 47: changes.MappedItemDiff.mapping_status:type_name -> changes.MappedItemMappingStatus - 53, // 48: changes.StartChangeAnalysisRequest.changingItems:type_name -> changes.MappedItemDiff - 117, // 49: changes.StartChangeAnalysisRequest.blastRadiusConfigOverride:type_name -> config.BlastRadiusConfig - 118, // 50: changes.StartChangeAnalysisRequest.routineChangesConfigOverride:type_name -> config.RoutineChangesConfig - 119, // 51: changes.StartChangeAnalysisRequest.githubOrganisationProfileOverride:type_name -> config.GithubOrganisationProfile - 30, // 52: changes.StartChangeAnalysisRequest.knowledge:type_name -> changes.Knowledge - 53, // 53: changes.AddPlannedChangesRequest.changingItems:type_name -> changes.MappedItemDiff - 120, // 54: changes.ListHomeChangesRequest.pagination:type_name -> PaginationRequest - 59, // 55: changes.ListHomeChangesRequest.filters:type_name -> changes.ChangeFiltersRequest - 10, // 56: changes.ChangeFiltersRequest.risks:type_name -> changes.Risk.Severity + 54, // 48: changes.StartChangeAnalysisRequest.changingItems:type_name -> changes.MappedItemDiff + 121, // 49: changes.StartChangeAnalysisRequest.blastRadiusConfigOverride:type_name -> config.BlastRadiusConfig + 122, // 50: changes.StartChangeAnalysisRequest.routineChangesConfigOverride:type_name -> config.RoutineChangesConfig + 123, // 51: changes.StartChangeAnalysisRequest.githubOrganisationProfileOverride:type_name -> config.GithubOrganisationProfile + 31, // 52: changes.StartChangeAnalysisRequest.knowledge:type_name -> changes.Knowledge + 54, // 53: changes.AddPlannedChangesRequest.changingItems:type_name -> changes.MappedItemDiff + 124, // 54: changes.ListHomeChangesRequest.pagination:type_name -> PaginationRequest + 60, // 55: changes.ListHomeChangesRequest.filters:type_name -> changes.ChangeFiltersRequest + 11, // 56: changes.ChangeFiltersRequest.risks:type_name -> changes.Risk.Severity 7, // 57: changes.ChangeFiltersRequest.statuses:type_name -> changes.ChangeStatus - 121, // 58: changes.ChangeFiltersRequest.sortOrder:type_name -> SortOrder - 70, // 59: changes.ListHomeChangesResponse.changes:type_name -> changes.ChangeSummary - 122, // 60: changes.ListHomeChangesResponse.pagination:type_name -> PaginationResponse - 123, // 61: changes.ItemDiffSummary.item:type_name -> Reference + 125, // 58: changes.ChangeFiltersRequest.sortOrder:type_name -> SortOrder + 71, // 59: changes.ListHomeChangesResponse.changes:type_name -> changes.ChangeSummary + 126, // 60: changes.ListHomeChangesResponse.pagination:type_name -> PaginationResponse + 127, // 61: changes.ItemDiffSummary.item:type_name -> Reference 4, // 62: changes.ItemDiffSummary.status:type_name -> changes.ItemDiffStatus - 124, // 63: changes.ItemDiffSummary.healthAfter:type_name -> Health - 123, // 64: changes.ItemDiff.item:type_name -> Reference + 128, // 63: changes.ItemDiffSummary.healthAfter:type_name -> Health + 127, // 64: changes.ItemDiff.item:type_name -> Reference 4, // 65: changes.ItemDiff.status:type_name -> changes.ItemDiffStatus - 125, // 66: changes.ItemDiff.before:type_name -> Item - 125, // 67: changes.ItemDiff.after:type_name -> Item - 123, // 68: changes.ItemDiff.mappedItemRef:type_name -> Reference - 109, // 69: changes.EnrichedTags.tagValue:type_name -> changes.EnrichedTags.TagValueEntry - 67, // 70: changes.TagValue.userTagValue:type_name -> changes.UserTagValue - 68, // 71: changes.TagValue.autoTagValue:type_name -> changes.AutoTagValue + 129, // 66: changes.ItemDiff.before:type_name -> Item + 129, // 67: changes.ItemDiff.after:type_name -> Item + 127, // 68: changes.ItemDiff.mappedItemRef:type_name -> Reference + 112, // 69: changes.EnrichedTags.tagValue:type_name -> changes.EnrichedTags.TagValueEntry + 68, // 70: changes.TagValue.userTagValue:type_name -> changes.UserTagValue + 69, // 71: changes.TagValue.autoTagValue:type_name -> changes.AutoTagValue 6, // 72: changes.Label.type:type_name -> changes.LabelType 7, // 73: changes.ChangeSummary.status:type_name -> changes.ChangeStatus - 113, // 74: changes.ChangeSummary.createdAt:type_name -> google.protobuf.Timestamp - 110, // 75: changes.ChangeSummary.tags:type_name -> changes.ChangeSummary.TagsEntry - 65, // 76: changes.ChangeSummary.enrichedTags:type_name -> changes.EnrichedTags - 69, // 77: changes.ChangeSummary.labels:type_name -> changes.Label - 74, // 78: changes.ChangeSummary.githubChangeInfo:type_name -> changes.GithubChangeInfo - 72, // 79: changes.Change.metadata:type_name -> changes.ChangeMetadata - 73, // 80: changes.Change.properties:type_name -> changes.ChangeProperties - 113, // 81: changes.ChangeMetadata.createdAt:type_name -> google.protobuf.Timestamp - 113, // 82: changes.ChangeMetadata.updatedAt:type_name -> google.protobuf.Timestamp + 117, // 74: changes.ChangeSummary.createdAt:type_name -> google.protobuf.Timestamp + 113, // 75: changes.ChangeSummary.tags:type_name -> changes.ChangeSummary.TagsEntry + 66, // 76: changes.ChangeSummary.enrichedTags:type_name -> changes.EnrichedTags + 70, // 77: changes.ChangeSummary.labels:type_name -> changes.Label + 75, // 78: changes.ChangeSummary.githubChangeInfo:type_name -> changes.GithubChangeInfo + 73, // 79: changes.Change.metadata:type_name -> changes.ChangeMetadata + 74, // 80: changes.Change.properties:type_name -> changes.ChangeProperties + 117, // 81: changes.ChangeMetadata.createdAt:type_name -> google.protobuf.Timestamp + 117, // 82: changes.ChangeMetadata.updatedAt:type_name -> google.protobuf.Timestamp 7, // 83: changes.ChangeMetadata.status:type_name -> changes.ChangeStatus - 111, // 84: changes.ChangeMetadata.UnknownHealthChange:type_name -> changes.ChangeMetadata.HealthChange - 111, // 85: changes.ChangeMetadata.OkHealthChange:type_name -> changes.ChangeMetadata.HealthChange - 111, // 86: changes.ChangeMetadata.WarningHealthChange:type_name -> changes.ChangeMetadata.HealthChange - 111, // 87: changes.ChangeMetadata.ErrorHealthChange:type_name -> changes.ChangeMetadata.HealthChange - 111, // 88: changes.ChangeMetadata.PendingHealthChange:type_name -> changes.ChangeMetadata.HealthChange - 74, // 89: changes.ChangeMetadata.githubChangeInfo:type_name -> changes.GithubChangeInfo - 106, // 90: changes.ChangeMetadata.changeAnalysisStatus:type_name -> changes.ChangeAnalysisStatus - 64, // 91: changes.ChangeProperties.plannedChanges:type_name -> changes.ItemDiff - 112, // 92: changes.ChangeProperties.tags:type_name -> changes.ChangeProperties.TagsEntry - 65, // 93: changes.ChangeProperties.enrichedTags:type_name -> changes.EnrichedTags - 69, // 94: changes.ChangeProperties.labels:type_name -> changes.Label - 71, // 95: changes.ListChangesResponse.changes:type_name -> changes.Change + 114, // 84: changes.ChangeMetadata.UnknownHealthChange:type_name -> changes.ChangeMetadata.HealthChange + 114, // 85: changes.ChangeMetadata.OkHealthChange:type_name -> changes.ChangeMetadata.HealthChange + 114, // 86: changes.ChangeMetadata.WarningHealthChange:type_name -> changes.ChangeMetadata.HealthChange + 114, // 87: changes.ChangeMetadata.ErrorHealthChange:type_name -> changes.ChangeMetadata.HealthChange + 114, // 88: changes.ChangeMetadata.PendingHealthChange:type_name -> changes.ChangeMetadata.HealthChange + 75, // 89: changes.ChangeMetadata.githubChangeInfo:type_name -> changes.GithubChangeInfo + 107, // 90: changes.ChangeMetadata.changeAnalysisStatus:type_name -> changes.ChangeAnalysisStatus + 65, // 91: changes.ChangeProperties.plannedChanges:type_name -> changes.ItemDiff + 115, // 92: changes.ChangeProperties.tags:type_name -> changes.ChangeProperties.TagsEntry + 66, // 93: changes.ChangeProperties.enrichedTags:type_name -> changes.EnrichedTags + 70, // 94: changes.ChangeProperties.labels:type_name -> changes.Label + 72, // 95: changes.ListChangesResponse.changes:type_name -> changes.Change 7, // 96: changes.ListChangesByStatusRequest.status:type_name -> changes.ChangeStatus - 71, // 97: changes.ListChangesByStatusResponse.changes:type_name -> changes.Change - 73, // 98: changes.CreateChangeRequest.properties:type_name -> changes.ChangeProperties - 71, // 99: changes.CreateChangeResponse.change:type_name -> changes.Change + 72, // 97: changes.ListChangesByStatusResponse.changes:type_name -> changes.Change + 74, // 98: changes.CreateChangeRequest.properties:type_name -> changes.ChangeProperties + 72, // 99: changes.CreateChangeResponse.change:type_name -> changes.Change 5, // 100: changes.GetChangeSummaryRequest.changeOutputFormat:type_name -> changes.ChangeOutputFormat - 10, // 101: changes.GetChangeSummaryRequest.riskSeverityFilter:type_name -> changes.Risk.Severity + 11, // 101: changes.GetChangeSummaryRequest.riskSeverityFilter:type_name -> changes.Risk.Severity 5, // 102: changes.GetChangeSignalsRequest.changeOutputFormat:type_name -> changes.ChangeOutputFormat - 71, // 103: changes.GetChangeResponse.change:type_name -> changes.Change - 106, // 104: changes.ChangeRiskMetadata.changeAnalysisStatus:type_name -> changes.ChangeAnalysisStatus - 105, // 105: changes.ChangeRiskMetadata.risks:type_name -> changes.Risk - 89, // 106: changes.GetChangeRisksResponse.changeRiskMetadata:type_name -> changes.ChangeRiskMetadata - 73, // 107: changes.UpdateChangeRequest.properties:type_name -> changes.ChangeProperties - 71, // 108: changes.UpdateChangeResponse.change:type_name -> changes.Change - 71, // 109: changes.ListChangesBySnapshotUUIDResponse.changes:type_name -> changes.Change - 8, // 110: changes.StartChangeResponse.state:type_name -> changes.StartChangeResponse.State - 9, // 111: changes.EndChangeResponse.state:type_name -> changes.EndChangeResponse.State - 10, // 112: changes.Risk.severity:type_name -> changes.Risk.Severity - 123, // 113: changes.Risk.relatedItems:type_name -> Reference - 11, // 114: changes.ChangeAnalysisStatus.status:type_name -> changes.ChangeAnalysisStatus.Status - 66, // 115: changes.EnrichedTags.TagValueEntry.value:type_name -> changes.TagValue - 75, // 116: changes.ChangesService.ListChanges:input_type -> changes.ListChangesRequest - 77, // 117: changes.ChangesService.ListChangesByStatus:input_type -> changes.ListChangesByStatusRequest - 79, // 118: changes.ChangesService.CreateChange:input_type -> changes.CreateChangeRequest - 81, // 119: changes.ChangesService.GetChange:input_type -> changes.GetChangeRequest - 82, // 120: changes.ChangesService.GetChangeByTicketLink:input_type -> changes.GetChangeByTicketLinkRequest - 83, // 121: changes.ChangesService.GetChangeSummary:input_type -> changes.GetChangeSummaryRequest - 34, // 122: changes.ChangesService.GetChangeTimelineV2:input_type -> changes.GetChangeTimelineV2Request - 88, // 123: changes.ChangesService.GetChangeRisks:input_type -> changes.GetChangeRisksRequest - 91, // 124: changes.ChangesService.UpdateChange:input_type -> changes.UpdateChangeRequest - 93, // 125: changes.ChangesService.DeleteChange:input_type -> changes.DeleteChangeRequest - 94, // 126: changes.ChangesService.ListChangesBySnapshotUUID:input_type -> changes.ListChangesBySnapshotUUIDRequest - 97, // 127: changes.ChangesService.RefreshState:input_type -> changes.RefreshStateRequest - 99, // 128: changes.ChangesService.StartChange:input_type -> changes.StartChangeRequest - 101, // 129: changes.ChangesService.EndChange:input_type -> changes.EndChangeRequest - 99, // 130: changes.ChangesService.StartChangeSimple:input_type -> changes.StartChangeRequest - 101, // 131: changes.ChangesService.EndChangeSimple:input_type -> changes.EndChangeRequest - 58, // 132: changes.ChangesService.ListHomeChanges:input_type -> changes.ListHomeChangesRequest - 54, // 133: changes.ChangesService.StartChangeAnalysis:input_type -> changes.StartChangeAnalysisRequest - 51, // 134: changes.ChangesService.ListChangingItemsSummary:input_type -> changes.ListChangingItemsSummaryRequest - 49, // 135: changes.ChangesService.GetDiff:input_type -> changes.GetDiffRequest - 61, // 136: changes.ChangesService.PopulateChangeFilters:input_type -> changes.PopulateChangeFiltersRequest - 107, // 137: changes.ChangesService.GenerateRiskFix:input_type -> changes.GenerateRiskFixRequest - 31, // 138: changes.ChangesService.GetHypothesesDetails:input_type -> changes.GetHypothesesDetailsRequest - 85, // 139: changes.ChangesService.GetChangeSignals:input_type -> changes.GetChangeSignalsRequest - 56, // 140: changes.ChangesService.AddPlannedChanges:input_type -> changes.AddPlannedChangesRequest - 15, // 141: changes.LabelService.ListLabelRules:input_type -> changes.ListLabelRulesRequest - 17, // 142: changes.LabelService.CreateLabelRule:input_type -> changes.CreateLabelRuleRequest - 19, // 143: changes.LabelService.GetLabelRule:input_type -> changes.GetLabelRuleRequest - 21, // 144: changes.LabelService.UpdateLabelRule:input_type -> changes.UpdateLabelRuleRequest - 23, // 145: changes.LabelService.DeleteLabelRule:input_type -> changes.DeleteLabelRuleRequest - 25, // 146: changes.LabelService.TestLabelRule:input_type -> changes.TestLabelRuleRequest - 27, // 147: changes.LabelService.ReapplyLabelRuleInTimeRange:input_type -> changes.ReapplyLabelRuleInTimeRangeRequest - 76, // 148: changes.ChangesService.ListChanges:output_type -> changes.ListChangesResponse - 78, // 149: changes.ChangesService.ListChangesByStatus:output_type -> changes.ListChangesByStatusResponse - 80, // 150: changes.ChangesService.CreateChange:output_type -> changes.CreateChangeResponse - 87, // 151: changes.ChangesService.GetChange:output_type -> changes.GetChangeResponse - 87, // 152: changes.ChangesService.GetChangeByTicketLink:output_type -> changes.GetChangeResponse - 84, // 153: changes.ChangesService.GetChangeSummary:output_type -> changes.GetChangeSummaryResponse - 35, // 154: changes.ChangesService.GetChangeTimelineV2:output_type -> changes.GetChangeTimelineV2Response - 90, // 155: changes.ChangesService.GetChangeRisks:output_type -> changes.GetChangeRisksResponse - 92, // 156: changes.ChangesService.UpdateChange:output_type -> changes.UpdateChangeResponse - 96, // 157: changes.ChangesService.DeleteChange:output_type -> changes.DeleteChangeResponse - 95, // 158: changes.ChangesService.ListChangesBySnapshotUUID:output_type -> changes.ListChangesBySnapshotUUIDResponse - 98, // 159: changes.ChangesService.RefreshState:output_type -> changes.RefreshStateResponse - 100, // 160: changes.ChangesService.StartChange:output_type -> changes.StartChangeResponse - 102, // 161: changes.ChangesService.EndChange:output_type -> changes.EndChangeResponse - 103, // 162: changes.ChangesService.StartChangeSimple:output_type -> changes.StartChangeSimpleResponse - 104, // 163: changes.ChangesService.EndChangeSimple:output_type -> changes.EndChangeSimpleResponse - 60, // 164: changes.ChangesService.ListHomeChanges:output_type -> changes.ListHomeChangesResponse - 55, // 165: changes.ChangesService.StartChangeAnalysis:output_type -> changes.StartChangeAnalysisResponse - 52, // 166: changes.ChangesService.ListChangingItemsSummary:output_type -> changes.ListChangingItemsSummaryResponse - 50, // 167: changes.ChangesService.GetDiff:output_type -> changes.GetDiffResponse - 62, // 168: changes.ChangesService.PopulateChangeFilters:output_type -> changes.PopulateChangeFiltersResponse - 108, // 169: changes.ChangesService.GenerateRiskFix:output_type -> changes.GenerateRiskFixResponse - 32, // 170: changes.ChangesService.GetHypothesesDetails:output_type -> changes.GetHypothesesDetailsResponse - 86, // 171: changes.ChangesService.GetChangeSignals:output_type -> changes.GetChangeSignalsResponse - 57, // 172: changes.ChangesService.AddPlannedChanges:output_type -> changes.AddPlannedChangesResponse - 16, // 173: changes.LabelService.ListLabelRules:output_type -> changes.ListLabelRulesResponse - 18, // 174: changes.LabelService.CreateLabelRule:output_type -> changes.CreateLabelRuleResponse - 20, // 175: changes.LabelService.GetLabelRule:output_type -> changes.GetLabelRuleResponse - 22, // 176: changes.LabelService.UpdateLabelRule:output_type -> changes.UpdateLabelRuleResponse - 24, // 177: changes.LabelService.DeleteLabelRule:output_type -> changes.DeleteLabelRuleResponse - 26, // 178: changes.LabelService.TestLabelRule:output_type -> changes.TestLabelRuleResponse - 28, // 179: changes.LabelService.ReapplyLabelRuleInTimeRange:output_type -> changes.ReapplyLabelRuleInTimeRangeResponse - 148, // [148:180] is the sub-list for method output_type - 116, // [116:148] is the sub-list for method input_type - 116, // [116:116] is the sub-list for extension type_name - 116, // [116:116] is the sub-list for extension extendee - 0, // [0:116] is the sub-list for field type_name + 72, // 103: changes.GetChangeResponse.change:type_name -> changes.Change + 107, // 104: changes.ChangeRiskMetadata.changeAnalysisStatus:type_name -> changes.ChangeAnalysisStatus + 106, // 105: changes.ChangeRiskMetadata.risks:type_name -> changes.Risk + 90, // 106: changes.GetChangeRisksResponse.changeRiskMetadata:type_name -> changes.ChangeRiskMetadata + 74, // 107: changes.UpdateChangeRequest.properties:type_name -> changes.ChangeProperties + 72, // 108: changes.UpdateChangeResponse.change:type_name -> changes.Change + 72, // 109: changes.ListChangesBySnapshotUUIDResponse.changes:type_name -> changes.Change + 9, // 110: changes.StartChangeResponse.state:type_name -> changes.StartChangeResponse.State + 10, // 111: changes.EndChangeResponse.state:type_name -> changes.EndChangeResponse.State + 11, // 112: changes.Risk.severity:type_name -> changes.Risk.Severity + 127, // 113: changes.Risk.relatedItems:type_name -> Reference + 12, // 114: changes.ChangeAnalysisStatus.status:type_name -> changes.ChangeAnalysisStatus.Status + 8, // 115: changes.SubmitRiskFeedbackRequest.sentiment:type_name -> changes.RiskFeedbackSentiment + 116, // 116: changes.SubmitRiskFeedbackRequest.metadata:type_name -> changes.SubmitRiskFeedbackRequest.MetadataEntry + 67, // 117: changes.EnrichedTags.TagValueEntry.value:type_name -> changes.TagValue + 76, // 118: changes.ChangesService.ListChanges:input_type -> changes.ListChangesRequest + 78, // 119: changes.ChangesService.ListChangesByStatus:input_type -> changes.ListChangesByStatusRequest + 80, // 120: changes.ChangesService.CreateChange:input_type -> changes.CreateChangeRequest + 82, // 121: changes.ChangesService.GetChange:input_type -> changes.GetChangeRequest + 83, // 122: changes.ChangesService.GetChangeByTicketLink:input_type -> changes.GetChangeByTicketLinkRequest + 84, // 123: changes.ChangesService.GetChangeSummary:input_type -> changes.GetChangeSummaryRequest + 35, // 124: changes.ChangesService.GetChangeTimelineV2:input_type -> changes.GetChangeTimelineV2Request + 89, // 125: changes.ChangesService.GetChangeRisks:input_type -> changes.GetChangeRisksRequest + 92, // 126: changes.ChangesService.UpdateChange:input_type -> changes.UpdateChangeRequest + 94, // 127: changes.ChangesService.DeleteChange:input_type -> changes.DeleteChangeRequest + 95, // 128: changes.ChangesService.ListChangesBySnapshotUUID:input_type -> changes.ListChangesBySnapshotUUIDRequest + 98, // 129: changes.ChangesService.RefreshState:input_type -> changes.RefreshStateRequest + 100, // 130: changes.ChangesService.StartChange:input_type -> changes.StartChangeRequest + 102, // 131: changes.ChangesService.EndChange:input_type -> changes.EndChangeRequest + 100, // 132: changes.ChangesService.StartChangeSimple:input_type -> changes.StartChangeRequest + 102, // 133: changes.ChangesService.EndChangeSimple:input_type -> changes.EndChangeRequest + 59, // 134: changes.ChangesService.ListHomeChanges:input_type -> changes.ListHomeChangesRequest + 55, // 135: changes.ChangesService.StartChangeAnalysis:input_type -> changes.StartChangeAnalysisRequest + 52, // 136: changes.ChangesService.ListChangingItemsSummary:input_type -> changes.ListChangingItemsSummaryRequest + 50, // 137: changes.ChangesService.GetDiff:input_type -> changes.GetDiffRequest + 62, // 138: changes.ChangesService.PopulateChangeFilters:input_type -> changes.PopulateChangeFiltersRequest + 108, // 139: changes.ChangesService.GenerateRiskFix:input_type -> changes.GenerateRiskFixRequest + 110, // 140: changes.ChangesService.SubmitRiskFeedback:input_type -> changes.SubmitRiskFeedbackRequest + 32, // 141: changes.ChangesService.GetHypothesesDetails:input_type -> changes.GetHypothesesDetailsRequest + 86, // 142: changes.ChangesService.GetChangeSignals:input_type -> changes.GetChangeSignalsRequest + 57, // 143: changes.ChangesService.AddPlannedChanges:input_type -> changes.AddPlannedChangesRequest + 16, // 144: changes.LabelService.ListLabelRules:input_type -> changes.ListLabelRulesRequest + 18, // 145: changes.LabelService.CreateLabelRule:input_type -> changes.CreateLabelRuleRequest + 20, // 146: changes.LabelService.GetLabelRule:input_type -> changes.GetLabelRuleRequest + 22, // 147: changes.LabelService.UpdateLabelRule:input_type -> changes.UpdateLabelRuleRequest + 24, // 148: changes.LabelService.DeleteLabelRule:input_type -> changes.DeleteLabelRuleRequest + 26, // 149: changes.LabelService.TestLabelRule:input_type -> changes.TestLabelRuleRequest + 28, // 150: changes.LabelService.ReapplyLabelRuleInTimeRange:input_type -> changes.ReapplyLabelRuleInTimeRangeRequest + 77, // 151: changes.ChangesService.ListChanges:output_type -> changes.ListChangesResponse + 79, // 152: changes.ChangesService.ListChangesByStatus:output_type -> changes.ListChangesByStatusResponse + 81, // 153: changes.ChangesService.CreateChange:output_type -> changes.CreateChangeResponse + 88, // 154: changes.ChangesService.GetChange:output_type -> changes.GetChangeResponse + 88, // 155: changes.ChangesService.GetChangeByTicketLink:output_type -> changes.GetChangeResponse + 85, // 156: changes.ChangesService.GetChangeSummary:output_type -> changes.GetChangeSummaryResponse + 36, // 157: changes.ChangesService.GetChangeTimelineV2:output_type -> changes.GetChangeTimelineV2Response + 91, // 158: changes.ChangesService.GetChangeRisks:output_type -> changes.GetChangeRisksResponse + 93, // 159: changes.ChangesService.UpdateChange:output_type -> changes.UpdateChangeResponse + 97, // 160: changes.ChangesService.DeleteChange:output_type -> changes.DeleteChangeResponse + 96, // 161: changes.ChangesService.ListChangesBySnapshotUUID:output_type -> changes.ListChangesBySnapshotUUIDResponse + 99, // 162: changes.ChangesService.RefreshState:output_type -> changes.RefreshStateResponse + 101, // 163: changes.ChangesService.StartChange:output_type -> changes.StartChangeResponse + 103, // 164: changes.ChangesService.EndChange:output_type -> changes.EndChangeResponse + 104, // 165: changes.ChangesService.StartChangeSimple:output_type -> changes.StartChangeSimpleResponse + 105, // 166: changes.ChangesService.EndChangeSimple:output_type -> changes.EndChangeSimpleResponse + 61, // 167: changes.ChangesService.ListHomeChanges:output_type -> changes.ListHomeChangesResponse + 56, // 168: changes.ChangesService.StartChangeAnalysis:output_type -> changes.StartChangeAnalysisResponse + 53, // 169: changes.ChangesService.ListChangingItemsSummary:output_type -> changes.ListChangingItemsSummaryResponse + 51, // 170: changes.ChangesService.GetDiff:output_type -> changes.GetDiffResponse + 63, // 171: changes.ChangesService.PopulateChangeFilters:output_type -> changes.PopulateChangeFiltersResponse + 109, // 172: changes.ChangesService.GenerateRiskFix:output_type -> changes.GenerateRiskFixResponse + 111, // 173: changes.ChangesService.SubmitRiskFeedback:output_type -> changes.SubmitRiskFeedbackResponse + 33, // 174: changes.ChangesService.GetHypothesesDetails:output_type -> changes.GetHypothesesDetailsResponse + 87, // 175: changes.ChangesService.GetChangeSignals:output_type -> changes.GetChangeSignalsResponse + 58, // 176: changes.ChangesService.AddPlannedChanges:output_type -> changes.AddPlannedChangesResponse + 17, // 177: changes.LabelService.ListLabelRules:output_type -> changes.ListLabelRulesResponse + 19, // 178: changes.LabelService.CreateLabelRule:output_type -> changes.CreateLabelRuleResponse + 21, // 179: changes.LabelService.GetLabelRule:output_type -> changes.GetLabelRuleResponse + 23, // 180: changes.LabelService.UpdateLabelRule:output_type -> changes.UpdateLabelRuleResponse + 25, // 181: changes.LabelService.DeleteLabelRule:output_type -> changes.DeleteLabelRuleResponse + 27, // 182: changes.LabelService.TestLabelRule:output_type -> changes.TestLabelRuleResponse + 29, // 183: changes.LabelService.ReapplyLabelRuleInTimeRange:output_type -> changes.ReapplyLabelRuleInTimeRangeResponse + 151, // [151:184] is the sub-list for method output_type + 118, // [118:151] is the sub-list for method input_type + 118, // [118:118] is the sub-list for extension type_name + 118, // [118:118] is the sub-list for extension extendee + 0, // [0:118] is the sub-list for field type_name } func init() { file_changes_proto_init() } @@ -7576,8 +7753,8 @@ func file_changes_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_changes_proto_rawDesc), len(file_changes_proto_rawDesc)), - NumEnums: 12, - NumMessages: 101, + NumEnums: 13, + NumMessages: 104, NumExtensions: 0, NumServices: 2, }, diff --git a/go/sdp-go/instance_detect.go b/go/sdp-go/instance_detect.go index 9f4ef8a5..2da3ac9e 100644 --- a/go/sdp-go/instance_detect.go +++ b/go/sdp-go/instance_detect.go @@ -58,7 +58,7 @@ func NewOvermindInstance(ctx context.Context, app string) (OvermindInstance, err } req = req.WithContext(ctx) - res, err := tracing.HTTPClient().Do(req) //nolint:gosec // G107 (SSRF): URL is built from the app base URL (CLI config) + hardcoded path /api/public/instance-data + res, err := tracing.HTTPClient().Do(req) if err != nil { return OvermindInstance{}, fmt.Errorf("could not fetch instance-data: %w", err) } diff --git a/go/sdp-go/sdpconnect/changes.connect.go b/go/sdp-go/sdpconnect/changes.connect.go index e9c7978e..9bc84807 100644 --- a/go/sdp-go/sdpconnect/changes.connect.go +++ b/go/sdp-go/sdpconnect/changes.connect.go @@ -100,6 +100,9 @@ const ( // ChangesServiceGenerateRiskFixProcedure is the fully-qualified name of the ChangesService's // GenerateRiskFix RPC. ChangesServiceGenerateRiskFixProcedure = "/changes.ChangesService/GenerateRiskFix" + // ChangesServiceSubmitRiskFeedbackProcedure is the fully-qualified name of the ChangesService's + // SubmitRiskFeedback RPC. + ChangesServiceSubmitRiskFeedbackProcedure = "/changes.ChangesService/SubmitRiskFeedback" // ChangesServiceGetHypothesesDetailsProcedure is the fully-qualified name of the ChangesService's // GetHypothesesDetails RPC. ChangesServiceGetHypothesesDetailsProcedure = "/changes.ChangesService/GetHypothesesDetails" @@ -192,6 +195,8 @@ type ChangesServiceClient interface { PopulateChangeFilters(context.Context, *connect.Request[sdp_go.PopulateChangeFiltersRequest]) (*connect.Response[sdp_go.PopulateChangeFiltersResponse], error) // Generates an AI-powered fix suggestion for a specific risk GenerateRiskFix(context.Context, *connect.Request[sdp_go.GenerateRiskFixRequest]) (*connect.Response[sdp_go.GenerateRiskFixResponse], error) + // Submit user feedback on a risk + SubmitRiskFeedback(context.Context, *connect.Request[sdp_go.SubmitRiskFeedbackRequest]) (*connect.Response[sdp_go.SubmitRiskFeedbackResponse], error) // The full details of all of the hypotheses that were considered or are being // considered as part of this change. GetHypothesesDetails(context.Context, *connect.Request[sdp_go.GetHypothesesDetailsRequest]) (*connect.Response[sdp_go.GetHypothesesDetailsResponse], error) @@ -352,6 +357,12 @@ func NewChangesServiceClient(httpClient connect.HTTPClient, baseURL string, opts connect.WithSchema(changesServiceMethods.ByName("GenerateRiskFix")), connect.WithClientOptions(opts...), ), + submitRiskFeedback: connect.NewClient[sdp_go.SubmitRiskFeedbackRequest, sdp_go.SubmitRiskFeedbackResponse]( + httpClient, + baseURL+ChangesServiceSubmitRiskFeedbackProcedure, + connect.WithSchema(changesServiceMethods.ByName("SubmitRiskFeedback")), + connect.WithClientOptions(opts...), + ), getHypothesesDetails: connect.NewClient[sdp_go.GetHypothesesDetailsRequest, sdp_go.GetHypothesesDetailsResponse]( httpClient, baseURL+ChangesServiceGetHypothesesDetailsProcedure, @@ -397,6 +408,7 @@ type changesServiceClient struct { getDiff *connect.Client[sdp_go.GetDiffRequest, sdp_go.GetDiffResponse] populateChangeFilters *connect.Client[sdp_go.PopulateChangeFiltersRequest, sdp_go.PopulateChangeFiltersResponse] generateRiskFix *connect.Client[sdp_go.GenerateRiskFixRequest, sdp_go.GenerateRiskFixResponse] + submitRiskFeedback *connect.Client[sdp_go.SubmitRiskFeedbackRequest, sdp_go.SubmitRiskFeedbackResponse] getHypothesesDetails *connect.Client[sdp_go.GetHypothesesDetailsRequest, sdp_go.GetHypothesesDetailsResponse] getChangeSignals *connect.Client[sdp_go.GetChangeSignalsRequest, sdp_go.GetChangeSignalsResponse] addPlannedChanges *connect.Client[sdp_go.AddPlannedChangesRequest, sdp_go.AddPlannedChangesResponse] @@ -512,6 +524,11 @@ func (c *changesServiceClient) GenerateRiskFix(ctx context.Context, req *connect return c.generateRiskFix.CallUnary(ctx, req) } +// SubmitRiskFeedback calls changes.ChangesService.SubmitRiskFeedback. +func (c *changesServiceClient) SubmitRiskFeedback(ctx context.Context, req *connect.Request[sdp_go.SubmitRiskFeedbackRequest]) (*connect.Response[sdp_go.SubmitRiskFeedbackResponse], error) { + return c.submitRiskFeedback.CallUnary(ctx, req) +} + // GetHypothesesDetails calls changes.ChangesService.GetHypothesesDetails. func (c *changesServiceClient) GetHypothesesDetails(ctx context.Context, req *connect.Request[sdp_go.GetHypothesesDetailsRequest]) (*connect.Response[sdp_go.GetHypothesesDetailsResponse], error) { return c.getHypothesesDetails.CallUnary(ctx, req) @@ -587,6 +604,8 @@ type ChangesServiceHandler interface { PopulateChangeFilters(context.Context, *connect.Request[sdp_go.PopulateChangeFiltersRequest]) (*connect.Response[sdp_go.PopulateChangeFiltersResponse], error) // Generates an AI-powered fix suggestion for a specific risk GenerateRiskFix(context.Context, *connect.Request[sdp_go.GenerateRiskFixRequest]) (*connect.Response[sdp_go.GenerateRiskFixResponse], error) + // Submit user feedback on a risk + SubmitRiskFeedback(context.Context, *connect.Request[sdp_go.SubmitRiskFeedbackRequest]) (*connect.Response[sdp_go.SubmitRiskFeedbackResponse], error) // The full details of all of the hypotheses that were considered or are being // considered as part of this change. GetHypothesesDetails(context.Context, *connect.Request[sdp_go.GetHypothesesDetailsRequest]) (*connect.Response[sdp_go.GetHypothesesDetailsResponse], error) @@ -743,6 +762,12 @@ func NewChangesServiceHandler(svc ChangesServiceHandler, opts ...connect.Handler connect.WithSchema(changesServiceMethods.ByName("GenerateRiskFix")), connect.WithHandlerOptions(opts...), ) + changesServiceSubmitRiskFeedbackHandler := connect.NewUnaryHandler( + ChangesServiceSubmitRiskFeedbackProcedure, + svc.SubmitRiskFeedback, + connect.WithSchema(changesServiceMethods.ByName("SubmitRiskFeedback")), + connect.WithHandlerOptions(opts...), + ) changesServiceGetHypothesesDetailsHandler := connect.NewUnaryHandler( ChangesServiceGetHypothesesDetailsProcedure, svc.GetHypothesesDetails, @@ -807,6 +832,8 @@ func NewChangesServiceHandler(svc ChangesServiceHandler, opts ...connect.Handler changesServicePopulateChangeFiltersHandler.ServeHTTP(w, r) case ChangesServiceGenerateRiskFixProcedure: changesServiceGenerateRiskFixHandler.ServeHTTP(w, r) + case ChangesServiceSubmitRiskFeedbackProcedure: + changesServiceSubmitRiskFeedbackHandler.ServeHTTP(w, r) case ChangesServiceGetHypothesesDetailsProcedure: changesServiceGetHypothesesDetailsHandler.ServeHTTP(w, r) case ChangesServiceGetChangeSignalsProcedure: @@ -910,6 +937,10 @@ func (UnimplementedChangesServiceHandler) GenerateRiskFix(context.Context, *conn return nil, connect.NewError(connect.CodeUnimplemented, errors.New("changes.ChangesService.GenerateRiskFix is not implemented")) } +func (UnimplementedChangesServiceHandler) SubmitRiskFeedback(context.Context, *connect.Request[sdp_go.SubmitRiskFeedbackRequest]) (*connect.Response[sdp_go.SubmitRiskFeedbackResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("changes.ChangesService.SubmitRiskFeedback is not implemented")) +} + func (UnimplementedChangesServiceHandler) GetHypothesesDetails(context.Context, *connect.Request[sdp_go.GetHypothesesDetailsRequest]) (*connect.Response[sdp_go.GetHypothesesDetailsResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("changes.ChangesService.GetHypothesesDetails is not implemented")) } diff --git a/go/sdpcache/bolt_cache.go b/go/sdpcache/bolt_cache.go index a024a229..b3a97948 100644 --- a/go/sdpcache/bolt_cache.go +++ b/go/sdpcache/bolt_cache.go @@ -848,8 +848,8 @@ func (c *BoltCache) StoreItem(ctx context.Context, item *sdp.Item, duration time c.storeResult(ctx, res) } -// StoreError stores an error in the cache with the specified duration. -func (c *BoltCache) StoreError(ctx context.Context, err error, duration time.Duration, ck CacheKey) { +// StoreUnavailableItem stores an error in the cache with the specified duration. +func (c *BoltCache) StoreUnavailableItem(ctx context.Context, err error, duration time.Duration, ck CacheKey) { if c == nil || err == nil { return } @@ -863,7 +863,7 @@ func (c *BoltCache) StoreError(ctx context.Context, err error, duration time.Dur methodStr = ck.Method.String() } - ctx, span := tracing.Tracer().Start(ctx, "BoltCache.StoreError", + ctx, span := tracing.Tracer().Start(ctx, "BoltCache.StoreUnavailableItem", trace.WithAttributes( attribute.String("ovm.cache.method", methodStr), attribute.String("ovm.cache.scope", ck.SST.Scope), @@ -994,7 +994,7 @@ func (c *BoltCache) storeResult(ctx context.Context, res CachedResult) { err = performUpdate() // Handle disk full errors - // Note: storeResult is called from StoreItem/StoreError which already holds compactMutex.RLock() + // Note: storeResult is called from StoreItem/StoreUnavailableItem which already holds compactMutex.RLock() // so we use the locked versions to avoid deadlock if err != nil && isDiskFullError(err) { // Attempt cleanup by purging expired items - needs to happen in a diff --git a/go/sdpcache/cache.go b/go/sdpcache/cache.go index ceea187b..f84bb423 100644 --- a/go/sdpcache/cache.go +++ b/go/sdpcache/cache.go @@ -204,8 +204,8 @@ type Cache interface { // StoreItem stores an item in the cache with the specified duration. StoreItem(ctx context.Context, item *sdp.Item, duration time.Duration, ck CacheKey) - // StoreError stores an error in the cache with the specified duration. - StoreError(ctx context.Context, err error, duration time.Duration, ck CacheKey) + // StoreUnavailableItem stores an error in the cache with the specified duration. + StoreUnavailableItem(ctx context.Context, err error, duration time.Duration, ck CacheKey) // Delete removes all entries matching the given cache key. Delete(ck CacheKey) @@ -246,8 +246,8 @@ func (n *NoOpCache) StoreItem(ctx context.Context, item *sdp.Item, duration time // No-op } -// StoreError does nothing -func (n *NoOpCache) StoreError(ctx context.Context, err error, duration time.Duration, ck CacheKey) { +// StoreUnavailableItem does nothing +func (n *NoOpCache) StoreUnavailableItem(ctx context.Context, err error, duration time.Duration, ck CacheKey) { // No-op } @@ -700,8 +700,8 @@ func (c *MemoryCache) StoreItem(ctx context.Context, item *sdp.Item, duration ti c.storeResult(ctx, res) } -// StoreError Stores an error for the given duration. -func (c *MemoryCache) StoreError(ctx context.Context, err error, duration time.Duration, cacheQuery CacheKey) { +// StoreUnavailableItem Stores an error for the given duration. +func (c *MemoryCache) StoreUnavailableItem(ctx context.Context, err error, duration time.Duration, cacheQuery CacheKey) { if c == nil || err == nil { return } diff --git a/go/sdpcache/cache_stuck_test.go b/go/sdpcache/cache_stuck_test.go index 38681940..b8fe1956 100644 --- a/go/sdpcache/cache_stuck_test.go +++ b/go/sdpcache/cache_stuck_test.go @@ -13,7 +13,7 @@ import ( // 1. A LIST operation is performed and gets a cache miss // 2. The caller starts the work // 3. The query encounters an error -// 4. The caller properly calls StoreError to cache the error +// 4. The caller properly calls StoreUnavailableItem to cache the error // 5. Subsequent requests get the cached error immediately (don't block) // // This test documents the fix for the cache timeout bug. @@ -36,7 +36,7 @@ func TestListErrorWithProperCleanup(t *testing.T) { var secondCallDuration time.Duration // First goroutine: Gets cache miss, simulates work that errors, - // and properly calls StoreError to cache the error + // and properly calls StoreUnavailableItem to cache the error wg.Go(func() { <-startBarrier @@ -56,8 +56,8 @@ func TestListErrorWithProperCleanup(t *testing.T) { ErrorType: sdp.QueryError_OTHER, ErrorString: "simulated list error", } - cache.StoreError(ctx, err, 1*time.Hour, ck) - t.Log("First goroutine: properly called StoreError") + cache.StoreUnavailableItem(ctx, err, 1*time.Hour, ck) + t.Log("First goroutine: properly called StoreUnavailableItem") }) // Second goroutine: Should get cached error immediately @@ -177,12 +177,12 @@ func TestListErrorWithProperDone(t *testing.T) { } } -// TestListErrorWithStoreError tests the CORRECT behavior where: +// TestListErrorWithStoreUnavailableItem tests the CORRECT behavior where: // 1. A LIST operation is performed and gets a cache miss // 2. The query encounters an error -// 3. The caller properly calls StoreError +// 3. The caller properly calls StoreUnavailableItem // 4. Subsequent requests should get the cached error immediately -func TestListErrorWithStoreError(t *testing.T) { +func TestListErrorWithStoreUnavailableItem(t *testing.T) { implementations := cacheImplementations(t) for _, impl := range implementations { @@ -211,7 +211,7 @@ func TestListErrorWithStoreError(t *testing.T) { var secondCallDuration time.Duration // First goroutine: Gets cache miss, simulates work that errors, - // and PROPERLY calls StoreError + // and PROPERLY calls StoreUnavailableItem wg.Go(func() { <-startBarrier @@ -227,8 +227,8 @@ func TestListErrorWithStoreError(t *testing.T) { time.Sleep(100 * time.Millisecond) // CORRECT BEHAVIOR: Store the error so other callers can get it - cache.StoreError(ctx, expectedError, 10*time.Second, ck) - t.Log("First goroutine: properly called StoreError") + cache.StoreUnavailableItem(ctx, expectedError, 10*time.Second, ck) + t.Log("First goroutine: properly called StoreUnavailableItem") }) // Second goroutine: Should receive the cached error diff --git a/go/sdpcache/cache_test.go b/go/sdpcache/cache_test.go index b8bf5326..073816bb 100644 --- a/go/sdpcache/cache_test.go +++ b/go/sdpcache/cache_test.go @@ -124,7 +124,7 @@ func TestStoreItem(t *testing.T) { } } -func TestStoreError(t *testing.T) { +func TestStoreUnavailableItem(t *testing.T) { implementations := cacheImplementations(t) for _, impl := range implementations { @@ -140,7 +140,7 @@ func TestStoreError(t *testing.T) { uav := "foo" - cache.StoreError(t.Context(), errors.New("arse"), 10*time.Second, CacheKey{ + cache.StoreUnavailableItem(t.Context(), errors.New("arse"), 10*time.Second, CacheKey{ SST: sst, Method: sdp.QueryMethod_GET.Enum(), Query: &uav, @@ -182,7 +182,7 @@ func TestStoreError(t *testing.T) { } // Test with multiple errors - cache.StoreError(t.Context(), errors.New("nope"), 10*time.Second, CacheKey{ + cache.StoreUnavailableItem(t.Context(), errors.New("nope"), 10*time.Second, CacheKey{ SST: sst, Method: sdp.QueryMethod_GET.Enum(), Query: &uav, @@ -773,7 +773,7 @@ func TestLookupWithCachedError(t *testing.T) { SourceName: sst.SourceName, ItemType: sst.Type, } - cache.StoreError(ctx, qErr, 10*time.Second, ck) + cache.StoreUnavailableItem(ctx, qErr, 10*time.Second, ck) // Lookup should return cached error cacheHit, _, items, returnedErr, done := cache.Lookup(ctx, sst.SourceName, method, sst.Scope, sst.Type, query, false) @@ -1325,10 +1325,10 @@ func TestUnexpiredOverwriteLogging(t *testing.T) { } // Store an error - cache.StoreError(ctx, errors.New("test error"), 10*time.Second, ck) + cache.StoreUnavailableItem(ctx, errors.New("test error"), 10*time.Second, ck) // Store the same error again before it expires (overwrite will be tracked via span attributes) - cache.StoreError(ctx, errors.New("another error"), 10*time.Second, ck) + cache.StoreUnavailableItem(ctx, errors.New("another error"), 10*time.Second, ck) }) } @@ -1853,7 +1853,7 @@ func TestBoltCacheLookupDeduplicationError(t *testing.T) { time.Sleep(50 * time.Millisecond) // Store the error - cache.StoreError(ctx, expectedError, 10*time.Second, ck) + cache.StoreUnavailableItem(ctx, expectedError, 10*time.Second, ck) }) // Waiter goroutines: should receive the error diff --git a/go/sdpcache/sharded_cache.go b/go/sdpcache/sharded_cache.go index 6d9b30c3..42423eb2 100644 --- a/go/sdpcache/sharded_cache.go +++ b/go/sdpcache/sharded_cache.go @@ -342,10 +342,10 @@ func (sc *ShardedCache) StoreItem(ctx context.Context, item *sdp.Item, duration sc.shards[idx].StoreItem(ctx, item, duration, ck) } -// StoreError routes the error based on the CacheKey: +// StoreUnavailableItem routes the error based on the CacheKey: // - GET errors (UniqueAttributeValue set) go to the same shard a GET Lookup would query. // - LIST/SEARCH errors go to shard 0 as a deterministic default; fan-out reads will find them. -func (sc *ShardedCache) StoreError(ctx context.Context, err error, duration time.Duration, ck CacheKey) { +func (sc *ShardedCache) StoreUnavailableItem(ctx context.Context, err error, duration time.Duration, ck CacheKey) { if err == nil { return } @@ -358,7 +358,7 @@ func (sc *ShardedCache) StoreError(ctx context.Context, err error, duration time span := trace.SpanFromContext(ctx) span.SetAttributes(attribute.Int("ovm.cache.shardIndex", idx)) - sc.shards[idx].StoreError(ctx, err, duration, ck) + sc.shards[idx].StoreUnavailableItem(ctx, err, duration, ck) } // Delete fans out to all shards. diff --git a/go/sdpcache/sharded_cache_test.go b/go/sdpcache/sharded_cache_test.go index fd656161..32a6f153 100644 --- a/go/sdpcache/sharded_cache_test.go +++ b/go/sdpcache/sharded_cache_test.go @@ -432,7 +432,7 @@ func TestShardedCacheErrorRouting(t *testing.T) { ErrorType: sdp.QueryError_NOTFOUND, ErrorString: "not found", } - cache.StoreError(ctx, qErr, 10*time.Second, ck) + cache.StoreUnavailableItem(ctx, qErr, 10*time.Second, ck) // Lookup should find the error hit, _, _, returnedErr, done := cache.Lookup(ctx, sst.SourceName, method, sst.Scope, sst.Type, uav, false) @@ -457,7 +457,7 @@ func TestShardedCacheErrorRouting(t *testing.T) { ErrorType: sdp.QueryError_OTHER, ErrorString: "list failed", } - cache.StoreError(ctx, qErr, 10*time.Second, ck) + cache.StoreUnavailableItem(ctx, qErr, 10*time.Second, ck) // LIST lookup fans out, should find the error on shard 0 hit, _, _, returnedErr, done := cache.Lookup(ctx, sst.SourceName, method, sst.Scope, sst.Type, "", false) diff --git a/k8s-source/adapters/generic_source.go b/k8s-source/adapters/generic_source.go index 9a139961..c7575e54 100644 --- a/k8s-source/adapters/generic_source.go +++ b/k8s-source/adapters/generic_source.go @@ -182,7 +182,7 @@ func (s *KubeTypeAdapter[Resource, ResourceList]) Get(ctx context.Context, scope ErrorType: sdp.QueryError_NOSCOPE, ErrorString: err.Error(), } - s.cache.StoreError(ctx, err, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.cacheDuration(), ck) return nil, err } @@ -196,13 +196,13 @@ func (s *KubeTypeAdapter[Resource, ResourceList]) Get(ctx context.Context, scope ErrorString: statusErr.ErrStatus.Message, } } - s.cache.StoreError(ctx, err, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.cacheDuration(), ck) return nil, err } item, err := s.resourceToItem(resource) if err != nil { - s.cache.StoreError(ctx, err, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.cacheDuration(), ck) return nil, err } s.cache.StoreItem(ctx, item, s.cacheDuration(), ck) @@ -227,7 +227,7 @@ func (s *KubeTypeAdapter[Resource, ResourceList]) List(ctx context.Context, scop items, err := s.listWithOptions(ctx, scope, metav1.ListOptions{}) if err != nil { - s.cache.StoreError(ctx, err, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.cacheDuration(), ck) return nil, err } @@ -276,7 +276,7 @@ func (s *KubeTypeAdapter[Resource, ResourceList]) Search(ctx context.Context, sc items, err := s.listWithOptions(ctx, scope, opts) if err != nil { - s.cache.StoreError(ctx, err, s.cacheDuration(), ck) + s.cache.StoreUnavailableItem(ctx, err, s.cacheDuration(), ck) return nil, err } diff --git a/sources/azure/clients/virtual-network-links-client.go b/sources/azure/clients/virtual-network-links-client.go new file mode 100644 index 00000000..cc6169a9 --- /dev/null +++ b/sources/azure/clients/virtual-network-links-client.go @@ -0,0 +1,32 @@ +package clients + +import ( + "context" + + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns" +) + +//go:generate mockgen -destination=../shared/mocks/mock_virtual_network_links_client.go -package=mocks -source=virtual-network-links-client.go + +type VirtualNetworkLinksPager = Pager[armprivatedns.VirtualNetworkLinksClientListResponse] + +type VirtualNetworkLinksClient interface { + NewListPager(resourceGroupName string, privateZoneName string, options *armprivatedns.VirtualNetworkLinksClientListOptions) VirtualNetworkLinksPager + Get(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, options *armprivatedns.VirtualNetworkLinksClientGetOptions) (armprivatedns.VirtualNetworkLinksClientGetResponse, error) +} + +type virtualNetworkLinksClient struct { + client *armprivatedns.VirtualNetworkLinksClient +} + +func (c *virtualNetworkLinksClient) NewListPager(resourceGroupName string, privateZoneName string, options *armprivatedns.VirtualNetworkLinksClientListOptions) VirtualNetworkLinksPager { + return c.client.NewListPager(resourceGroupName, privateZoneName, options) +} + +func (c *virtualNetworkLinksClient) Get(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, options *armprivatedns.VirtualNetworkLinksClientGetOptions) (armprivatedns.VirtualNetworkLinksClientGetResponse, error) { + return c.client.Get(ctx, resourceGroupName, privateZoneName, virtualNetworkLinkName, options) +} + +func NewVirtualNetworkLinksClient(client *armprivatedns.VirtualNetworkLinksClient) VirtualNetworkLinksClient { + return &virtualNetworkLinksClient{client: client} +} diff --git a/sources/azure/integration-tests/network-dns-virtual-network-link_test.go b/sources/azure/integration-tests/network-dns-virtual-network-link_test.go new file mode 100644 index 00000000..03352387 --- /dev/null +++ b/sources/azure/integration-tests/network-dns-virtual-network-link_test.go @@ -0,0 +1,456 @@ +package integrationtests + +import ( + "context" + "errors" + "fmt" + "net/http" + "os" + "testing" + "time" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v9" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources/v2" + log "github.com/sirupsen/logrus" + + "github.com/overmindtech/cli/go/discovery" + "github.com/overmindtech/cli/go/sdpcache" + "github.com/overmindtech/cli/sources" + "github.com/overmindtech/cli/sources/azure/clients" + "github.com/overmindtech/cli/sources/azure/manual" + azureshared "github.com/overmindtech/cli/sources/azure/shared" + "github.com/overmindtech/cli/sources/shared" +) + +const ( + integrationTestDNSVNetLinkName = "ovm-integ-test-dns-vnet-link" + integrationTestPrivateZoneName = "ovm-integ-test.private.zone" + integrationTestVNetForDNSName = "ovm-integ-test-vnet-dns" +) + +func TestNetworkDNSVirtualNetworkLinkIntegration(t *testing.T) { + subscriptionID := os.Getenv("AZURE_SUBSCRIPTION_ID") + if subscriptionID == "" { + t.Skip("AZURE_SUBSCRIPTION_ID environment variable not set") + } + + cred, err := azureshared.NewAzureCredential(t.Context()) + if err != nil { + t.Fatalf("Failed to create Azure credential: %v", err) + } + + rgClient, err := armresources.NewResourceGroupsClient(subscriptionID, cred, nil) + if err != nil { + t.Fatalf("Failed to create Resource Groups client: %v", err) + } + + privateDNSZonesClient, err := armprivatedns.NewPrivateZonesClient(subscriptionID, cred, nil) + if err != nil { + t.Fatalf("Failed to create Private DNS Zones client: %v", err) + } + + vnetLinksClient, err := armprivatedns.NewVirtualNetworkLinksClient(subscriptionID, cred, nil) + if err != nil { + t.Fatalf("Failed to create Virtual Network Links client: %v", err) + } + + vnetClient, err := armnetwork.NewVirtualNetworksClient(subscriptionID, cred, nil) + if err != nil { + t.Fatalf("Failed to create Virtual Networks client: %v", err) + } + + t.Run("Setup", func(t *testing.T) { + ctx := t.Context() + + err := createResourceGroup(ctx, rgClient, integrationTestResourceGroup, integrationTestLocation) + if err != nil { + t.Fatalf("Failed to create resource group: %v", err) + } + + err = createVNetForDNS(ctx, vnetClient, integrationTestResourceGroup, integrationTestVNetForDNSName, integrationTestLocation) + if err != nil { + t.Fatalf("Failed to create virtual network: %v", err) + } + + err = createPrivateDNSZoneForLink(ctx, privateDNSZonesClient, integrationTestResourceGroup, integrationTestPrivateZoneName) + if err != nil { + t.Fatalf("Failed to create private DNS zone: %v", err) + } + + err = waitForPrivateDNSZoneAvailable(ctx, privateDNSZonesClient, integrationTestResourceGroup, integrationTestPrivateZoneName) + if err != nil { + t.Fatalf("Failed waiting for private DNS zone: %v", err) + } + + vnetID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s", + subscriptionID, integrationTestResourceGroup, integrationTestVNetForDNSName) + + err = createVirtualNetworkLink(ctx, vnetLinksClient, integrationTestResourceGroup, integrationTestPrivateZoneName, integrationTestDNSVNetLinkName, vnetID, integrationTestLocation) + if err != nil { + t.Fatalf("Failed to create virtual network link: %v", err) + } + + err = waitForVirtualNetworkLinkAvailable(ctx, vnetLinksClient, integrationTestResourceGroup, integrationTestPrivateZoneName, integrationTestDNSVNetLinkName) + if err != nil { + t.Fatalf("Failed waiting for virtual network link: %v", err) + } + }) + + t.Run("Run", func(t *testing.T) { + t.Run("GetVirtualNetworkLink", func(t *testing.T) { + ctx := t.Context() + + wrapper := manual.NewNetworkDNSVirtualNetworkLink( + clients.NewVirtualNetworkLinksClient(vnetLinksClient), + []azureshared.ResourceGroupScope{azureshared.NewResourceGroupScope(subscriptionID, integrationTestResourceGroup)}, + ) + scope := wrapper.Scopes()[0] + adapter := sources.WrapperToAdapter(wrapper, sdpcache.NewNoOpCache()) + + query := shared.CompositeLookupKey(integrationTestPrivateZoneName, integrationTestDNSVNetLinkName) + sdpItem, qErr := adapter.Get(ctx, scope, query, true) + if qErr != nil { + t.Fatalf("Expected no error, got: %v", qErr) + } + + if sdpItem == nil { + t.Fatalf("Expected sdpItem to be non-nil") + } + + uniqueAttrKey := sdpItem.GetUniqueAttribute() + uniqueAttrValue, err := sdpItem.GetAttributes().Get(uniqueAttrKey) + if err != nil { + t.Fatalf("Failed to get unique attribute: %v", err) + } + + expectedUnique := shared.CompositeLookupKey(integrationTestPrivateZoneName, integrationTestDNSVNetLinkName) + if uniqueAttrValue != expectedUnique { + t.Errorf("Expected unique attribute value %s, got %s", expectedUnique, uniqueAttrValue) + } + + log.Printf("Successfully retrieved virtual network link %s", integrationTestDNSVNetLinkName) + }) + + t.Run("SearchVirtualNetworkLinks", func(t *testing.T) { + ctx := t.Context() + + wrapper := manual.NewNetworkDNSVirtualNetworkLink( + clients.NewVirtualNetworkLinksClient(vnetLinksClient), + []azureshared.ResourceGroupScope{azureshared.NewResourceGroupScope(subscriptionID, integrationTestResourceGroup)}, + ) + scope := wrapper.Scopes()[0] + adapter := sources.WrapperToAdapter(wrapper, sdpcache.NewNoOpCache()) + + searchable, ok := adapter.(discovery.SearchableAdapter) + if !ok { + t.Fatalf("Adapter does not support Search operation") + } + + sdpItems, err := searchable.Search(ctx, scope, integrationTestPrivateZoneName, true) + if err != nil { + t.Fatalf("Failed to search virtual network links: %v", err) + } + + if len(sdpItems) < 1 { + t.Fatalf("Expected at least one virtual network link, got %d", len(sdpItems)) + } + + var found bool + for _, item := range sdpItems { + uniqueAttrKey := item.GetUniqueAttribute() + if v, err := item.GetAttributes().Get(uniqueAttrKey); err == nil && v == shared.CompositeLookupKey(integrationTestPrivateZoneName, integrationTestDNSVNetLinkName) { + found = true + break + } + } + + if !found { + t.Fatalf("Expected to find link %s in the search results", integrationTestDNSVNetLinkName) + } + + log.Printf("Found %d virtual network links in search results", len(sdpItems)) + }) + + t.Run("VerifyLinkedItems", func(t *testing.T) { + ctx := t.Context() + + wrapper := manual.NewNetworkDNSVirtualNetworkLink( + clients.NewVirtualNetworkLinksClient(vnetLinksClient), + []azureshared.ResourceGroupScope{azureshared.NewResourceGroupScope(subscriptionID, integrationTestResourceGroup)}, + ) + scope := wrapper.Scopes()[0] + adapter := sources.WrapperToAdapter(wrapper, sdpcache.NewNoOpCache()) + + query := shared.CompositeLookupKey(integrationTestPrivateZoneName, integrationTestDNSVNetLinkName) + sdpItem, qErr := adapter.Get(ctx, scope, query, true) + if qErr != nil { + t.Fatalf("Expected no error, got: %v", qErr) + } + + linkedQueries := sdpItem.GetLinkedItemQueries() + if len(linkedQueries) == 0 { + t.Fatalf("Expected linked item queries, but got none") + } + + var hasPrivateDNSZoneLink, hasVNetLink bool + for _, liq := range linkedQueries { + q := liq.GetQuery() + if q.GetType() == azureshared.NetworkPrivateDNSZone.String() && q.GetQuery() == integrationTestPrivateZoneName { + hasPrivateDNSZoneLink = true + } + if q.GetType() == azureshared.NetworkVirtualNetwork.String() && q.GetQuery() == integrationTestVNetForDNSName { + hasVNetLink = true + } + } + + if !hasPrivateDNSZoneLink { + t.Error("Expected linked query to Private DNS Zone, but didn't find one") + } + if !hasVNetLink { + t.Error("Expected linked query to Virtual Network, but didn't find one") + } + + log.Printf("Verified %d linked item queries for virtual network link %s", len(linkedQueries), integrationTestDNSVNetLinkName) + }) + + t.Run("VerifyItemAttributes", func(t *testing.T) { + ctx := t.Context() + + wrapper := manual.NewNetworkDNSVirtualNetworkLink( + clients.NewVirtualNetworkLinksClient(vnetLinksClient), + []azureshared.ResourceGroupScope{azureshared.NewResourceGroupScope(subscriptionID, integrationTestResourceGroup)}, + ) + scope := wrapper.Scopes()[0] + adapter := sources.WrapperToAdapter(wrapper, sdpcache.NewNoOpCache()) + + query := shared.CompositeLookupKey(integrationTestPrivateZoneName, integrationTestDNSVNetLinkName) + sdpItem, qErr := adapter.Get(ctx, scope, query, true) + if qErr != nil { + t.Fatalf("Expected no error, got: %v", qErr) + } + + if sdpItem.GetType() != azureshared.NetworkDNSVirtualNetworkLink.String() { + t.Errorf("Expected type %s, got %s", azureshared.NetworkDNSVirtualNetworkLink.String(), sdpItem.GetType()) + } + + expectedScope := subscriptionID + "." + integrationTestResourceGroup + if sdpItem.GetScope() != expectedScope { + t.Errorf("Expected scope %s, got %s", expectedScope, sdpItem.GetScope()) + } + + if sdpItem.GetUniqueAttribute() != "uniqueAttr" { + t.Errorf("Expected unique attribute 'uniqueAttr', got %s", sdpItem.GetUniqueAttribute()) + } + + if err := sdpItem.Validate(); err != nil { + t.Errorf("Expected item to validate, got: %v", err) + } + }) + }) + + t.Run("Teardown", func(t *testing.T) { + ctx := t.Context() + + err := deleteVirtualNetworkLink(ctx, vnetLinksClient, integrationTestResourceGroup, integrationTestPrivateZoneName, integrationTestDNSVNetLinkName) + if err != nil { + t.Fatalf("Failed to delete virtual network link: %v", err) + } + + err = deletePrivateDNSZoneForLink(ctx, privateDNSZonesClient, integrationTestResourceGroup, integrationTestPrivateZoneName) + if err != nil { + t.Fatalf("Failed to delete private DNS zone: %v", err) + } + + err = deleteVNetForDNS(ctx, vnetClient, integrationTestResourceGroup, integrationTestVNetForDNSName) + if err != nil { + t.Fatalf("Failed to delete virtual network: %v", err) + } + }) +} + +func createVNetForDNS(ctx context.Context, client *armnetwork.VirtualNetworksClient, rg, name, location string) error { + _, err := client.Get(ctx, rg, name, nil) + if err == nil { + log.Printf("Virtual network %s already exists, skipping creation", name) + return nil + } + + poller, err := client.BeginCreateOrUpdate(ctx, rg, name, armnetwork.VirtualNetwork{ + Location: new(location), + Properties: &armnetwork.VirtualNetworkPropertiesFormat{ + AddressSpace: &armnetwork.AddressSpace{ + AddressPrefixes: []*string{new("10.100.0.0/16")}, + }, + }, + }, nil) + if err != nil { + var respErr *azcore.ResponseError + if errors.As(err, &respErr) && respErr.StatusCode == http.StatusConflict { + log.Printf("Virtual network %s already exists (conflict), skipping", name) + return nil + } + return fmt.Errorf("failed to create virtual network: %w", err) + } + _, err = poller.PollUntilDone(ctx, nil) + if err != nil { + return fmt.Errorf("failed to create virtual network: %w", err) + } + log.Printf("Virtual network %s created successfully", name) + return nil +} + +func createPrivateDNSZoneForLink(ctx context.Context, client *armprivatedns.PrivateZonesClient, rg, zoneName string) error { + _, err := client.Get(ctx, rg, zoneName, nil) + if err == nil { + log.Printf("Private DNS zone %s already exists, skipping creation", zoneName) + return nil + } + + poller, err := client.BeginCreateOrUpdate(ctx, rg, zoneName, armprivatedns.PrivateZone{ + Location: new("global"), + }, nil) + if err != nil { + var respErr *azcore.ResponseError + if errors.As(err, &respErr) && respErr.StatusCode == http.StatusConflict { + log.Printf("Private DNS zone %s already exists (conflict), skipping", zoneName) + return nil + } + return fmt.Errorf("failed to create private DNS zone: %w", err) + } + _, err = poller.PollUntilDone(ctx, nil) + if err != nil { + return fmt.Errorf("failed to create private DNS zone: %w", err) + } + log.Printf("Private DNS zone %s created successfully", zoneName) + return nil +} + +func waitForPrivateDNSZoneAvailable(ctx context.Context, client *armprivatedns.PrivateZonesClient, rg, zoneName string) error { + maxAttempts := 20 + pollInterval := 5 * time.Second + for attempt := 1; attempt <= maxAttempts; attempt++ { + resp, err := client.Get(ctx, rg, zoneName, nil) + if err != nil { + var respErr *azcore.ResponseError + if errors.As(err, &respErr) && respErr.StatusCode == http.StatusNotFound { + time.Sleep(pollInterval) + continue + } + return fmt.Errorf("error checking private DNS zone: %w", err) + } + if resp.Properties != nil && resp.Properties.ProvisioningState != nil && *resp.Properties.ProvisioningState == armprivatedns.ProvisioningStateSucceeded { + return nil + } + time.Sleep(pollInterval) + } + return fmt.Errorf("timeout waiting for private DNS zone %s", zoneName) +} + +func createVirtualNetworkLink(ctx context.Context, client *armprivatedns.VirtualNetworkLinksClient, rg, zoneName, linkName, vnetID, location string) error { + _, err := client.Get(ctx, rg, zoneName, linkName, nil) + if err == nil { + log.Printf("Virtual network link %s already exists, skipping creation", linkName) + return nil + } + + poller, err := client.BeginCreateOrUpdate(ctx, rg, zoneName, linkName, armprivatedns.VirtualNetworkLink{ + Location: new("global"), + Properties: &armprivatedns.VirtualNetworkLinkProperties{ + VirtualNetwork: &armprivatedns.SubResource{ + ID: &vnetID, + }, + RegistrationEnabled: new(false), + }, + }, nil) + if err != nil { + var respErr *azcore.ResponseError + if errors.As(err, &respErr) && respErr.StatusCode == http.StatusConflict { + log.Printf("Virtual network link %s already exists (conflict), skipping", linkName) + return nil + } + return fmt.Errorf("failed to create virtual network link: %w", err) + } + _, err = poller.PollUntilDone(ctx, nil) + if err != nil { + return fmt.Errorf("failed to create virtual network link: %w", err) + } + log.Printf("Virtual network link %s created successfully", linkName) + return nil +} + +func waitForVirtualNetworkLinkAvailable(ctx context.Context, client *armprivatedns.VirtualNetworkLinksClient, rg, zoneName, linkName string) error { + maxAttempts := 20 + pollInterval := 5 * time.Second + for attempt := 1; attempt <= maxAttempts; attempt++ { + resp, err := client.Get(ctx, rg, zoneName, linkName, nil) + if err != nil { + var respErr *azcore.ResponseError + if errors.As(err, &respErr) && respErr.StatusCode == http.StatusNotFound { + time.Sleep(pollInterval) + continue + } + return fmt.Errorf("error checking virtual network link: %w", err) + } + if resp.Properties != nil && resp.Properties.ProvisioningState != nil && *resp.Properties.ProvisioningState == armprivatedns.ProvisioningStateSucceeded { + return nil + } + time.Sleep(pollInterval) + } + return fmt.Errorf("timeout waiting for virtual network link %s", linkName) +} + +func deleteVirtualNetworkLink(ctx context.Context, client *armprivatedns.VirtualNetworkLinksClient, rg, zoneName, linkName string) error { + poller, err := client.BeginDelete(ctx, rg, zoneName, linkName, nil) + if err != nil { + var respErr *azcore.ResponseError + if errors.As(err, &respErr) && respErr.StatusCode == http.StatusNotFound { + log.Printf("Virtual network link %s not found, skipping deletion", linkName) + return nil + } + return fmt.Errorf("failed to delete virtual network link: %w", err) + } + _, err = poller.PollUntilDone(ctx, nil) + if err != nil { + return fmt.Errorf("failed to delete virtual network link: %w", err) + } + log.Printf("Virtual network link %s deleted successfully", linkName) + return nil +} + +func deletePrivateDNSZoneForLink(ctx context.Context, client *armprivatedns.PrivateZonesClient, rg, zoneName string) error { + poller, err := client.BeginDelete(ctx, rg, zoneName, nil) + if err != nil { + var respErr *azcore.ResponseError + if errors.As(err, &respErr) && respErr.StatusCode == http.StatusNotFound { + log.Printf("Private DNS zone %s not found, skipping deletion", zoneName) + return nil + } + return fmt.Errorf("failed to delete private DNS zone: %w", err) + } + _, err = poller.PollUntilDone(ctx, nil) + if err != nil { + return fmt.Errorf("failed to delete private DNS zone: %w", err) + } + log.Printf("Private DNS zone %s deleted successfully", zoneName) + return nil +} + +func deleteVNetForDNS(ctx context.Context, client *armnetwork.VirtualNetworksClient, rg, name string) error { + poller, err := client.BeginDelete(ctx, rg, name, nil) + if err != nil { + var respErr *azcore.ResponseError + if errors.As(err, &respErr) && respErr.StatusCode == http.StatusNotFound { + log.Printf("Virtual network %s not found, skipping deletion", name) + return nil + } + return fmt.Errorf("failed to delete virtual network: %w", err) + } + _, err = poller.PollUntilDone(ctx, nil) + if err != nil { + return fmt.Errorf("failed to delete virtual network: %w", err) + } + log.Printf("Virtual network %s deleted successfully", name) + return nil +} diff --git a/sources/azure/manual/adapters.go b/sources/azure/manual/adapters.go index 5f164a81..0367a752 100644 --- a/sources/azure/manual/adapters.go +++ b/sources/azure/manual/adapters.go @@ -368,6 +368,10 @@ func Adapters(ctx context.Context, subscriptionID string, regions []string, cred if err != nil { return nil, fmt.Errorf("failed to create private DNS zones client: %w", err) } + virtualNetworkLinksClient, err := armprivatedns.NewVirtualNetworkLinksClient(subscriptionID, cred, nil) + if err != nil { + return nil, fmt.Errorf("failed to create virtual network links client: %w", err) + } diskAccessesClient, err := armcompute.NewDiskAccessesClient(subscriptionID, cred, nil) if err != nil { return nil, fmt.Errorf("failed to create disk accesses client: %w", err) @@ -565,6 +569,10 @@ func Adapters(ctx context.Context, subscriptionID string, regions []string, cred clients.NewRecordSetsClient(recordSetsClient), resourceGroupScopes, ), cache), + sources.WrapperToAdapter(NewNetworkDNSVirtualNetworkLink( + clients.NewVirtualNetworkLinksClient(virtualNetworkLinksClient), + resourceGroupScopes, + ), cache), sources.WrapperToAdapter(NewBatchAccount( clients.NewBatchAccountsClient(batchAccountsClient), resourceGroupScopes, @@ -785,6 +793,7 @@ func Adapters(ctx context.Context, subscriptionID string, regions []string, cred sources.WrapperToAdapter(NewNetworkZone(nil, placeholderResourceGroupScopes), noOpCache), sources.WrapperToAdapter(NewNetworkPrivateDNSZone(nil, placeholderResourceGroupScopes), noOpCache), sources.WrapperToAdapter(NewNetworkDNSRecordSet(nil, placeholderResourceGroupScopes), noOpCache), + sources.WrapperToAdapter(NewNetworkDNSVirtualNetworkLink(nil, placeholderResourceGroupScopes), noOpCache), sources.WrapperToAdapter(NewBatchAccount(nil, placeholderResourceGroupScopes), noOpCache), sources.WrapperToAdapter(NewBatchBatchApplication(nil, placeholderResourceGroupScopes), noOpCache), sources.WrapperToAdapter(NewBatchBatchPool(nil, placeholderResourceGroupScopes), noOpCache), diff --git a/sources/azure/manual/network-dns-virtual-network-link.go b/sources/azure/manual/network-dns-virtual-network-link.go new file mode 100644 index 00000000..f9aeb5c9 --- /dev/null +++ b/sources/azure/manual/network-dns-virtual-network-link.go @@ -0,0 +1,240 @@ +package manual + +import ( + "context" + "errors" + + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns" + "github.com/overmindtech/cli/go/discovery" + "github.com/overmindtech/cli/go/sdp-go" + "github.com/overmindtech/cli/go/sdpcache" + "github.com/overmindtech/cli/sources" + "github.com/overmindtech/cli/sources/azure/clients" + azureshared "github.com/overmindtech/cli/sources/azure/shared" + "github.com/overmindtech/cli/sources/shared" +) + +var NetworkDNSVirtualNetworkLinkLookupByName = shared.NewItemTypeLookup("name", azureshared.NetworkDNSVirtualNetworkLink) + +type networkDNSVirtualNetworkLinkWrapper struct { + client clients.VirtualNetworkLinksClient + + *azureshared.MultiResourceGroupBase +} + +func NewNetworkDNSVirtualNetworkLink(client clients.VirtualNetworkLinksClient, resourceGroupScopes []azureshared.ResourceGroupScope) sources.SearchableWrapper { + return &networkDNSVirtualNetworkLinkWrapper{ + client: client, + MultiResourceGroupBase: azureshared.NewMultiResourceGroupBase( + resourceGroupScopes, + sdp.AdapterCategory_ADAPTER_CATEGORY_NETWORK, + azureshared.NetworkDNSVirtualNetworkLink, + ), + } +} + +// ref: https://learn.microsoft.com/en-us/rest/api/dns/privatednszones/virtualnetworklinks/get +func (c networkDNSVirtualNetworkLinkWrapper) Get(ctx context.Context, scope string, queryParts ...string) (*sdp.Item, *sdp.QueryError) { + if len(queryParts) < 2 { + return nil, azureshared.QueryError(errors.New("Get requires 2 query parts: privateZoneName and virtualNetworkLinkName"), scope, c.Type()) + } + privateZoneName := queryParts[0] + linkName := queryParts[1] + if privateZoneName == "" || linkName == "" { + return nil, azureshared.QueryError(errors.New("privateZoneName and virtualNetworkLinkName cannot be empty"), scope, c.Type()) + } + + rgScope, err := c.ResourceGroupScopeFromScope(scope) + if err != nil { + return nil, azureshared.QueryError(err, scope, c.Type()) + } + resp, err := c.client.Get(ctx, rgScope.ResourceGroup, privateZoneName, linkName, nil) + if err != nil { + return nil, azureshared.QueryError(err, scope, c.Type()) + } + return c.azureVirtualNetworkLinkToSDPItem(&resp.VirtualNetworkLink, privateZoneName, scope) +} + +func (c networkDNSVirtualNetworkLinkWrapper) GetLookups() sources.ItemTypeLookups { + return sources.ItemTypeLookups{ + NetworkPrivateDNSZoneLookupByName, + NetworkDNSVirtualNetworkLinkLookupByName, + } +} + +// ref: https://learn.microsoft.com/en-us/rest/api/dns/privatednszones/virtualnetworklinks/list +func (c networkDNSVirtualNetworkLinkWrapper) Search(ctx context.Context, scope string, queryParts ...string) ([]*sdp.Item, *sdp.QueryError) { + if len(queryParts) < 1 { + return nil, azureshared.QueryError(errors.New("Search requires 1 query part: privateZoneName"), scope, c.Type()) + } + privateZoneName := queryParts[0] + if privateZoneName == "" { + return nil, azureshared.QueryError(errors.New("privateZoneName cannot be empty"), scope, c.Type()) + } + + rgScope, err := c.ResourceGroupScopeFromScope(scope) + if err != nil { + return nil, azureshared.QueryError(err, scope, c.Type()) + } + pager := c.client.NewListPager(rgScope.ResourceGroup, privateZoneName, nil) + + var items []*sdp.Item + for pager.More() { + page, err := pager.NextPage(ctx) + if err != nil { + return nil, azureshared.QueryError(err, scope, c.Type()) + } + for _, link := range page.Value { + if link == nil || link.Name == nil { + continue + } + item, sdpErr := c.azureVirtualNetworkLinkToSDPItem(link, privateZoneName, scope) + if sdpErr != nil { + return nil, sdpErr + } + items = append(items, item) + } + } + return items, nil +} + +func (c networkDNSVirtualNetworkLinkWrapper) SearchStream(ctx context.Context, stream discovery.QueryResultStream, cache sdpcache.Cache, cacheKey sdpcache.CacheKey, scope string, queryParts ...string) { + if len(queryParts) < 1 { + stream.SendError(azureshared.QueryError(errors.New("Search requires 1 query part: privateZoneName"), scope, c.Type())) + return + } + privateZoneName := queryParts[0] + if privateZoneName == "" { + stream.SendError(azureshared.QueryError(errors.New("privateZoneName cannot be empty"), scope, c.Type())) + return + } + + rgScope, err := c.ResourceGroupScopeFromScope(scope) + if err != nil { + stream.SendError(azureshared.QueryError(err, scope, c.Type())) + return + } + pager := c.client.NewListPager(rgScope.ResourceGroup, privateZoneName, nil) + for pager.More() { + page, err := pager.NextPage(ctx) + if err != nil { + stream.SendError(azureshared.QueryError(err, scope, c.Type())) + return + } + for _, link := range page.Value { + if link == nil || link.Name == nil { + continue + } + item, sdpErr := c.azureVirtualNetworkLinkToSDPItem(link, privateZoneName, scope) + if sdpErr != nil { + stream.SendError(sdpErr) + continue + } + cache.StoreItem(ctx, item, shared.DefaultCacheDuration, cacheKey) + stream.SendItem(item) + } + } +} + +func (c networkDNSVirtualNetworkLinkWrapper) SearchLookups() []sources.ItemTypeLookups { + return []sources.ItemTypeLookups{ + {NetworkPrivateDNSZoneLookupByName}, + } +} + +func (c networkDNSVirtualNetworkLinkWrapper) azureVirtualNetworkLinkToSDPItem(link *armprivatedns.VirtualNetworkLink, privateZoneName, scope string) (*sdp.Item, *sdp.QueryError) { + if link.Name == nil { + return nil, azureshared.QueryError(errors.New("virtual network link name is nil"), scope, c.Type()) + } + + attributes, err := shared.ToAttributesWithExclude(link, "tags") + if err != nil { + return nil, azureshared.QueryError(err, scope, c.Type()) + } + + uniqueAttr := shared.CompositeLookupKey(privateZoneName, *link.Name) + if err := attributes.Set("uniqueAttr", uniqueAttr); err != nil { + return nil, azureshared.QueryError(err, scope, c.Type()) + } + + sdpItem := &sdp.Item{ + Type: azureshared.NetworkDNSVirtualNetworkLink.String(), + UniqueAttribute: "uniqueAttr", + Attributes: attributes, + Scope: scope, + Tags: azureshared.ConvertAzureTags(link.Tags), + } + + // Health from provisioning state + if link.Properties != nil && link.Properties.ProvisioningState != nil { + switch *link.Properties.ProvisioningState { + case armprivatedns.ProvisioningStateSucceeded: + sdpItem.Health = sdp.Health_HEALTH_OK.Enum() + case armprivatedns.ProvisioningStateCreating, armprivatedns.ProvisioningStateUpdating, armprivatedns.ProvisioningStateDeleting: + sdpItem.Health = sdp.Health_HEALTH_PENDING.Enum() + case armprivatedns.ProvisioningStateFailed, armprivatedns.ProvisioningStateCanceled: + sdpItem.Health = sdp.Health_HEALTH_ERROR.Enum() + default: + sdpItem.Health = sdp.Health_HEALTH_UNKNOWN.Enum() + } + } + + // Link to parent Private DNS Zone + sdpItem.LinkedItemQueries = append(sdpItem.LinkedItemQueries, &sdp.LinkedItemQuery{ + Query: &sdp.Query{ + Type: azureshared.NetworkPrivateDNSZone.String(), + Method: sdp.QueryMethod_GET, + Query: privateZoneName, + Scope: scope, + }, + }) + + // Link to the Virtual Network referenced by this link + if link.Properties != nil && link.Properties.VirtualNetwork != nil && link.Properties.VirtualNetwork.ID != nil { + vnetName := azureshared.ExtractResourceName(*link.Properties.VirtualNetwork.ID) + if vnetName != "" { + linkedScope := scope + if extractedScope := azureshared.ExtractScopeFromResourceID(*link.Properties.VirtualNetwork.ID); extractedScope != "" { + linkedScope = extractedScope + } + sdpItem.LinkedItemQueries = append(sdpItem.LinkedItemQueries, &sdp.LinkedItemQuery{ + Query: &sdp.Query{ + Type: azureshared.NetworkVirtualNetwork.String(), + Method: sdp.QueryMethod_GET, + Query: vnetName, + Scope: linkedScope, + }, + }) + } + } + + return sdpItem, nil +} + +func (c networkDNSVirtualNetworkLinkWrapper) PotentialLinks() map[shared.ItemType]bool { + return shared.NewItemTypesSet( + azureshared.NetworkPrivateDNSZone, + azureshared.NetworkVirtualNetwork, + ) +} + +// ref: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_dns_zone_virtual_network_link +func (c networkDNSVirtualNetworkLinkWrapper) TerraformMappings() []*sdp.TerraformMapping { + return []*sdp.TerraformMapping{ + { + TerraformMethod: sdp.QueryMethod_SEARCH, + TerraformQueryMap: "azurerm_private_dns_zone_virtual_network_link.id", + }, + } +} + +// ref: https://learn.microsoft.com/en-us/azure/role-based-access-control/resource-provider-operations#microsoftnetwork +func (c networkDNSVirtualNetworkLinkWrapper) IAMPermissions() []string { + return []string{ + "Microsoft.Network/privateDnsZones/virtualNetworkLinks/read", + } +} + +func (c networkDNSVirtualNetworkLinkWrapper) PredefinedRole() string { + return "Reader" +} diff --git a/sources/azure/manual/network-dns-virtual-network-link_test.go b/sources/azure/manual/network-dns-virtual-network-link_test.go new file mode 100644 index 00000000..b2e25f2b --- /dev/null +++ b/sources/azure/manual/network-dns-virtual-network-link_test.go @@ -0,0 +1,317 @@ +package manual_test + +import ( + "context" + "errors" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns" + "go.uber.org/mock/gomock" + + "github.com/overmindtech/cli/go/discovery" + "github.com/overmindtech/cli/go/sdp-go" + "github.com/overmindtech/cli/go/sdpcache" + "github.com/overmindtech/cli/sources" + "github.com/overmindtech/cli/sources/azure/clients" + "github.com/overmindtech/cli/sources/azure/manual" + azureshared "github.com/overmindtech/cli/sources/azure/shared" + "github.com/overmindtech/cli/sources/azure/shared/mocks" + "github.com/overmindtech/cli/sources/shared" +) + +func createAzureVirtualNetworkLink(name, privateZoneName, subscriptionID, resourceGroup string) *armprivatedns.VirtualNetworkLink { + provisioningState := armprivatedns.ProvisioningStateSucceeded + linkState := armprivatedns.VirtualNetworkLinkStateCompleted + registrationEnabled := true + return &armprivatedns.VirtualNetworkLink{ + ID: new("/subscriptions/" + subscriptionID + "/resourceGroups/" + resourceGroup + "/providers/Microsoft.Network/privateDnsZones/" + privateZoneName + "/virtualNetworkLinks/" + name), + Name: new(name), + Type: new("Microsoft.Network/privateDnsZones/virtualNetworkLinks"), + Location: new("global"), + Tags: map[string]*string{"env": new("test")}, + Properties: &armprivatedns.VirtualNetworkLinkProperties{ + ProvisioningState: &provisioningState, + VirtualNetworkLinkState: &linkState, + RegistrationEnabled: ®istrationEnabled, + VirtualNetwork: &armprivatedns.SubResource{ + ID: new("/subscriptions/" + subscriptionID + "/resourceGroups/" + resourceGroup + "/providers/Microsoft.Network/virtualNetworks/test-vnet"), + }, + }, + } +} + +type mockVirtualNetworkLinksPager struct { + pages []armprivatedns.VirtualNetworkLinksClientListResponse + index int +} + +func (m *mockVirtualNetworkLinksPager) More() bool { + return m.index < len(m.pages) +} + +func (m *mockVirtualNetworkLinksPager) NextPage(_ context.Context) (armprivatedns.VirtualNetworkLinksClientListResponse, error) { + if m.index >= len(m.pages) { + return armprivatedns.VirtualNetworkLinksClientListResponse{}, errors.New("no more pages") + } + page := m.pages[m.index] + m.index++ + return page, nil +} + +func newMockVirtualNetworkLinksPager(_ *gomock.Controller, items []*armprivatedns.VirtualNetworkLink) clients.VirtualNetworkLinksPager { + return &mockVirtualNetworkLinksPager{ + pages: []armprivatedns.VirtualNetworkLinksClientListResponse{ + { + VirtualNetworkLinkListResult: armprivatedns.VirtualNetworkLinkListResult{ + Value: items, + }, + }, + }, + } +} + +func TestNetworkDNSVirtualNetworkLink(t *testing.T) { + ctx := context.Background() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + subscriptionID := "test-subscription" + resourceGroup := "test-rg" + privateZoneName := "example.private.zone" + linkName := "test-link" + query := shared.CompositeLookupKey(privateZoneName, linkName) + + t.Run("Get", func(t *testing.T) { + link := createAzureVirtualNetworkLink(linkName, privateZoneName, subscriptionID, resourceGroup) + + mockClient := mocks.NewMockVirtualNetworkLinksClient(ctrl) + mockClient.EXPECT().Get(ctx, resourceGroup, privateZoneName, linkName, nil).Return( + armprivatedns.VirtualNetworkLinksClientGetResponse{ + VirtualNetworkLink: *link, + }, nil) + + wrapper := manual.NewNetworkDNSVirtualNetworkLink(mockClient, []azureshared.ResourceGroupScope{azureshared.NewResourceGroupScope(subscriptionID, resourceGroup)}) + adapter := sources.WrapperToAdapter(wrapper, sdpcache.NewNoOpCache()) + + sdpItem, qErr := adapter.Get(ctx, wrapper.Scopes()[0], query, true) + if qErr != nil { + t.Fatalf("Expected no error, got: %v", qErr) + } + + if sdpItem.GetType() != azureshared.NetworkDNSVirtualNetworkLink.String() { + t.Errorf("Expected type %s, got %s", azureshared.NetworkDNSVirtualNetworkLink.String(), sdpItem.GetType()) + } + + if sdpItem.GetUniqueAttribute() != "uniqueAttr" { + t.Errorf("Expected unique attribute 'uniqueAttr', got %s", sdpItem.GetUniqueAttribute()) + } + + expectedUnique := shared.CompositeLookupKey(privateZoneName, linkName) + if sdpItem.UniqueAttributeValue() != expectedUnique { + t.Errorf("Expected unique attribute value %s, got %s", expectedUnique, sdpItem.UniqueAttributeValue()) + } + + t.Run("StaticTests", func(t *testing.T) { + queryTests := shared.QueryTests{ + { + ExpectedType: azureshared.NetworkPrivateDNSZone.String(), + ExpectedMethod: sdp.QueryMethod_GET, + ExpectedQuery: privateZoneName, + ExpectedScope: subscriptionID + "." + resourceGroup, + }, + { + ExpectedType: azureshared.NetworkVirtualNetwork.String(), + ExpectedMethod: sdp.QueryMethod_GET, + ExpectedQuery: "test-vnet", + ExpectedScope: subscriptionID + "." + resourceGroup, + }, + } + shared.RunStaticTests(t, adapter, sdpItem, queryTests) + }) + }) + + t.Run("GetWithInsufficientQueryParts", func(t *testing.T) { + mockClient := mocks.NewMockVirtualNetworkLinksClient(ctrl) + wrapper := manual.NewNetworkDNSVirtualNetworkLink(mockClient, []azureshared.ResourceGroupScope{azureshared.NewResourceGroupScope(subscriptionID, resourceGroup)}) + adapter := sources.WrapperToAdapter(wrapper, sdpcache.NewNoOpCache()) + + _, qErr := adapter.Get(ctx, wrapper.Scopes()[0], privateZoneName, true) + if qErr == nil { + t.Error("Expected error when providing only one query part, got nil") + } + }) + + t.Run("GetWithEmptyName", func(t *testing.T) { + mockClient := mocks.NewMockVirtualNetworkLinksClient(ctrl) + wrapper := manual.NewNetworkDNSVirtualNetworkLink(mockClient, []azureshared.ResourceGroupScope{azureshared.NewResourceGroupScope(subscriptionID, resourceGroup)}) + adapter := sources.WrapperToAdapter(wrapper, sdpcache.NewNoOpCache()) + + emptyQuery := shared.CompositeLookupKey(privateZoneName, "") + _, qErr := adapter.Get(ctx, wrapper.Scopes()[0], emptyQuery, true) + if qErr == nil { + t.Error("Expected error when getting resource with empty link name, but got nil") + } + }) + + t.Run("Search", func(t *testing.T) { + link1 := createAzureVirtualNetworkLink("link-1", privateZoneName, subscriptionID, resourceGroup) + link2 := createAzureVirtualNetworkLink("link-2", privateZoneName, subscriptionID, resourceGroup) + + mockClient := mocks.NewMockVirtualNetworkLinksClient(ctrl) + mockPager := newMockVirtualNetworkLinksPager(ctrl, []*armprivatedns.VirtualNetworkLink{link1, link2}) + mockClient.EXPECT().NewListPager(resourceGroup, privateZoneName, nil).Return(mockPager) + + wrapper := manual.NewNetworkDNSVirtualNetworkLink(mockClient, []azureshared.ResourceGroupScope{azureshared.NewResourceGroupScope(subscriptionID, resourceGroup)}) + adapter := sources.WrapperToAdapter(wrapper, sdpcache.NewNoOpCache()) + + searchable, ok := adapter.(discovery.SearchableAdapter) + if !ok { + t.Fatalf("Adapter does not implement SearchableAdapter") + } + + items, qErr := searchable.Search(ctx, wrapper.Scopes()[0], privateZoneName, true) + if qErr != nil { + t.Fatalf("Expected no error, got: %v", qErr) + } + if len(items) != 2 { + t.Fatalf("Expected 2 items, got %d", len(items)) + } + for _, item := range items { + if item.Validate() != nil { + t.Fatalf("Expected valid item, got: %v", item.Validate()) + } + } + }) + + t.Run("SearchStream", func(t *testing.T) { + link := createAzureVirtualNetworkLink(linkName, privateZoneName, subscriptionID, resourceGroup) + + mockClient := mocks.NewMockVirtualNetworkLinksClient(ctrl) + mockPager := newMockVirtualNetworkLinksPager(ctrl, []*armprivatedns.VirtualNetworkLink{link}) + mockClient.EXPECT().NewListPager(resourceGroup, privateZoneName, nil).Return(mockPager) + + wrapper := manual.NewNetworkDNSVirtualNetworkLink(mockClient, []azureshared.ResourceGroupScope{azureshared.NewResourceGroupScope(subscriptionID, resourceGroup)}) + adapter := sources.WrapperToAdapter(wrapper, sdpcache.NewNoOpCache()) + + streamable, ok := adapter.(discovery.SearchStreamableAdapter) + if !ok { + t.Fatalf("Adapter does not implement SearchStreamableAdapter") + } + + var received []*sdp.Item + stream := discovery.NewQueryResultStream( + func(item *sdp.Item) { received = append(received, item) }, + func(error) {}, + ) + streamable.SearchStream(ctx, wrapper.Scopes()[0], privateZoneName, true, stream) + + if len(received) != 1 { + t.Fatalf("Expected 1 item from SearchStream, got %d", len(received)) + } + if received[0].GetType() != azureshared.NetworkDNSVirtualNetworkLink.String() { + t.Errorf("Expected type %s, got %s", azureshared.NetworkDNSVirtualNetworkLink.String(), received[0].GetType()) + } + }) + + t.Run("SearchWithEmptyZoneName", func(t *testing.T) { + mockClient := mocks.NewMockVirtualNetworkLinksClient(ctrl) + wrapper := manual.NewNetworkDNSVirtualNetworkLink(mockClient, []azureshared.ResourceGroupScope{azureshared.NewResourceGroupScope(subscriptionID, resourceGroup)}) + adapter := sources.WrapperToAdapter(wrapper, sdpcache.NewNoOpCache()) + + searchable := adapter.(discovery.SearchableAdapter) + _, qErr := searchable.Search(ctx, wrapper.Scopes()[0], "", true) + if qErr == nil { + t.Error("Expected error when providing empty zone name, got nil") + } + }) + + t.Run("ErrorHandling", func(t *testing.T) { + expectedErr := errors.New("virtual network link not found") + mockClient := mocks.NewMockVirtualNetworkLinksClient(ctrl) + mockClient.EXPECT().Get(ctx, resourceGroup, privateZoneName, linkName, nil).Return( + armprivatedns.VirtualNetworkLinksClientGetResponse{}, expectedErr) + + wrapper := manual.NewNetworkDNSVirtualNetworkLink(mockClient, []azureshared.ResourceGroupScope{azureshared.NewResourceGroupScope(subscriptionID, resourceGroup)}) + adapter := sources.WrapperToAdapter(wrapper, sdpcache.NewNoOpCache()) + + _, qErr := adapter.Get(ctx, wrapper.Scopes()[0], query, true) + if qErr == nil { + t.Error("Expected error when Get fails, got nil") + } + }) + + t.Run("GetWithCrossResourceGroupVNet", func(t *testing.T) { + link := createAzureVirtualNetworkLink(linkName, privateZoneName, subscriptionID, resourceGroup) + link.Properties.VirtualNetwork = &armprivatedns.SubResource{ + ID: new("/subscriptions/" + subscriptionID + "/resourceGroups/other-rg/providers/Microsoft.Network/virtualNetworks/cross-rg-vnet"), + } + + mockClient := mocks.NewMockVirtualNetworkLinksClient(ctrl) + mockClient.EXPECT().Get(ctx, resourceGroup, privateZoneName, linkName, nil).Return( + armprivatedns.VirtualNetworkLinksClientGetResponse{ + VirtualNetworkLink: *link, + }, nil) + + wrapper := manual.NewNetworkDNSVirtualNetworkLink(mockClient, []azureshared.ResourceGroupScope{azureshared.NewResourceGroupScope(subscriptionID, resourceGroup)}) + adapter := sources.WrapperToAdapter(wrapper, sdpcache.NewNoOpCache()) + + sdpItem, qErr := adapter.Get(ctx, wrapper.Scopes()[0], query, true) + if qErr != nil { + t.Fatalf("Expected no error, got: %v", qErr) + } + + var hasVNetLink bool + for _, lq := range sdpItem.GetLinkedItemQueries() { + q := lq.GetQuery() + if q.GetType() == azureshared.NetworkVirtualNetwork.String() && q.GetQuery() == "cross-rg-vnet" && q.GetScope() == subscriptionID+".other-rg" { + hasVNetLink = true + } + } + if !hasVNetLink { + t.Error("Expected LinkedItemQueries to include VirtualNetwork with cross-resource-group scope") + } + }) + + t.Run("GetWithoutVirtualNetwork", func(t *testing.T) { + link := createAzureVirtualNetworkLink(linkName, privateZoneName, subscriptionID, resourceGroup) + link.Properties.VirtualNetwork = nil + + mockClient := mocks.NewMockVirtualNetworkLinksClient(ctrl) + mockClient.EXPECT().Get(ctx, resourceGroup, privateZoneName, linkName, nil).Return( + armprivatedns.VirtualNetworkLinksClientGetResponse{ + VirtualNetworkLink: *link, + }, nil) + + wrapper := manual.NewNetworkDNSVirtualNetworkLink(mockClient, []azureshared.ResourceGroupScope{azureshared.NewResourceGroupScope(subscriptionID, resourceGroup)}) + adapter := sources.WrapperToAdapter(wrapper, sdpcache.NewNoOpCache()) + + sdpItem, qErr := adapter.Get(ctx, wrapper.Scopes()[0], query, true) + if qErr != nil { + t.Fatalf("Expected no error, got: %v", qErr) + } + + // Should have only the parent DNS zone link, not a VNet link + vnetLinks := 0 + for _, lq := range sdpItem.GetLinkedItemQueries() { + if lq.GetQuery().GetType() == azureshared.NetworkVirtualNetwork.String() { + vnetLinks++ + } + } + if vnetLinks != 0 { + t.Errorf("Expected no VirtualNetwork linked queries when VirtualNetwork is nil, got %d", vnetLinks) + } + }) + + t.Run("PotentialLinks", func(t *testing.T) { + mockClient := mocks.NewMockVirtualNetworkLinksClient(ctrl) + wrapper := manual.NewNetworkDNSVirtualNetworkLink(mockClient, []azureshared.ResourceGroupScope{azureshared.NewResourceGroupScope(subscriptionID, resourceGroup)}) + + potentialLinks := wrapper.PotentialLinks() + if !potentialLinks[azureshared.NetworkPrivateDNSZone] { + t.Error("Expected PotentialLinks to include NetworkPrivateDNSZone") + } + if !potentialLinks[azureshared.NetworkVirtualNetwork] { + t.Error("Expected PotentialLinks to include NetworkVirtualNetwork") + } + }) +} diff --git a/sources/azure/shared/mocks/mock_virtual_network_links_client.go b/sources/azure/shared/mocks/mock_virtual_network_links_client.go new file mode 100644 index 00000000..508b9213 --- /dev/null +++ b/sources/azure/shared/mocks/mock_virtual_network_links_client.go @@ -0,0 +1,72 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: virtual-network-links-client.go +// +// Generated by this command: +// +// mockgen -destination=../shared/mocks/mock_virtual_network_links_client.go -package=mocks -source=virtual-network-links-client.go +// + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + armprivatedns "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns" + clients "github.com/overmindtech/cli/sources/azure/clients" + gomock "go.uber.org/mock/gomock" +) + +// MockVirtualNetworkLinksClient is a mock of VirtualNetworkLinksClient interface. +type MockVirtualNetworkLinksClient struct { + ctrl *gomock.Controller + recorder *MockVirtualNetworkLinksClientMockRecorder + isgomock struct{} +} + +// MockVirtualNetworkLinksClientMockRecorder is the mock recorder for MockVirtualNetworkLinksClient. +type MockVirtualNetworkLinksClientMockRecorder struct { + mock *MockVirtualNetworkLinksClient +} + +// NewMockVirtualNetworkLinksClient creates a new mock instance. +func NewMockVirtualNetworkLinksClient(ctrl *gomock.Controller) *MockVirtualNetworkLinksClient { + mock := &MockVirtualNetworkLinksClient{ctrl: ctrl} + mock.recorder = &MockVirtualNetworkLinksClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockVirtualNetworkLinksClient) EXPECT() *MockVirtualNetworkLinksClientMockRecorder { + return m.recorder +} + +// Get mocks base method. +func (m *MockVirtualNetworkLinksClient) Get(ctx context.Context, resourceGroupName, privateZoneName, virtualNetworkLinkName string, options *armprivatedns.VirtualNetworkLinksClientGetOptions) (armprivatedns.VirtualNetworkLinksClientGetResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", ctx, resourceGroupName, privateZoneName, virtualNetworkLinkName, options) + ret0, _ := ret[0].(armprivatedns.VirtualNetworkLinksClientGetResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockVirtualNetworkLinksClientMockRecorder) Get(ctx, resourceGroupName, privateZoneName, virtualNetworkLinkName, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockVirtualNetworkLinksClient)(nil).Get), ctx, resourceGroupName, privateZoneName, virtualNetworkLinkName, options) +} + +// NewListPager mocks base method. +func (m *MockVirtualNetworkLinksClient) NewListPager(resourceGroupName, privateZoneName string, options *armprivatedns.VirtualNetworkLinksClientListOptions) clients.VirtualNetworkLinksPager { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewListPager", resourceGroupName, privateZoneName, options) + ret0, _ := ret[0].(clients.VirtualNetworkLinksPager) + return ret0 +} + +// NewListPager indicates an expected call of NewListPager. +func (mr *MockVirtualNetworkLinksClientMockRecorder) NewListPager(resourceGroupName, privateZoneName, options any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewListPager", reflect.TypeOf((*MockVirtualNetworkLinksClient)(nil).NewListPager), resourceGroupName, privateZoneName, options) +} diff --git a/sources/azure/shared/utils.go b/sources/azure/shared/utils.go index 605b5f4d..d1b52df7 100644 --- a/sources/azure/shared/utils.go +++ b/sources/azure/shared/utils.go @@ -55,6 +55,7 @@ func GetResourceIDPathKeys(resourceType string) []string { "azure-elasticsan-elastic-san-volume-group": {"elasticSans", "volumegroups"}, // "/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.ElasticSan/elasticSans/{elasticSanName}/volumegroups/{volumeGroupName}" "azure-elasticsan-elastic-san-volume-snapshot": {"elasticSans", "volumegroups", "snapshots"}, // "/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.ElasticSan/elasticSans/{elasticSanName}/volumegroups/{volumeGroupName}/snapshots/{snapshotName}" "azure-compute-disk-access-private-endpoint-connection": {"diskAccesses", "privateEndpointConnections"}, // "/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Compute/diskAccesses/{diskAccessName}/privateEndpointConnections/{connectionName}" + "azure-network-dns-virtual-network-link": {"privateDnsZones", "virtualNetworkLinks"}, // "/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Network/privateDnsZones/{zoneName}/virtualNetworkLinks/{linkName}" } if keys, ok := pathKeysMap[resourceType]; ok { diff --git a/sources/gcp/dynamic/adapter-listable.go b/sources/gcp/dynamic/adapter-listable.go index 02c745d0..a2b1cfe6 100644 --- a/sources/gcp/dynamic/adapter-listable.go +++ b/sources/gcp/dynamic/adapter-listable.go @@ -9,8 +9,8 @@ import ( "github.com/overmindtech/cli/go/discovery" "github.com/overmindtech/cli/go/sdp-go" "github.com/overmindtech/cli/go/sdpcache" - gcpshared "github.com/overmindtech/cli/sources/gcp/shared" "github.com/overmindtech/cli/sources" + gcpshared "github.com/overmindtech/cli/sources/gcp/shared" "github.com/overmindtech/cli/sources/shared" ) @@ -105,7 +105,7 @@ func (g ListableAdapter) List(ctx context.Context, scope string, ignoreCache boo items, err := aggregateSDPItems(ctx, g.Adapter, listURL, location) if err != nil { if sources.IsNotFound(err) { - g.cache.StoreError(ctx, err, shared.DefaultCacheDuration, ck) + g.cache.StoreUnavailableItem(ctx, err, shared.DefaultCacheDuration, ck) return []*sdp.Item{}, nil } return nil, err @@ -121,7 +121,7 @@ func (g ListableAdapter) List(ctx context.Context, scope string, ignoreCache boo ItemType: g.Type(), ResponderName: g.Name(), } - g.cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, ck) + g.cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, ck) return items, nil } diff --git a/sources/gcp/dynamic/adapter-searchable-listable.go b/sources/gcp/dynamic/adapter-searchable-listable.go index 509c2e0a..98ce9ba9 100644 --- a/sources/gcp/dynamic/adapter-searchable-listable.go +++ b/sources/gcp/dynamic/adapter-searchable-listable.go @@ -10,8 +10,8 @@ import ( "github.com/overmindtech/cli/go/discovery" "github.com/overmindtech/cli/go/sdp-go" "github.com/overmindtech/cli/go/sdpcache" - gcpshared "github.com/overmindtech/cli/sources/gcp/shared" "github.com/overmindtech/cli/sources" + gcpshared "github.com/overmindtech/cli/sources/gcp/shared" "github.com/overmindtech/cli/sources/shared" ) @@ -127,7 +127,7 @@ func (g SearchableListableAdapter) Search(ctx context.Context, scope, query stri items, err := aggregateSDPItems(ctx, g.Adapter, searchEndpoint, location) if err != nil { if sources.IsNotFound(err) { - g.cache.StoreError(ctx, err, shared.DefaultCacheDuration, ck) + g.cache.StoreUnavailableItem(ctx, err, shared.DefaultCacheDuration, ck) return []*sdp.Item{}, nil } return nil, err @@ -153,7 +153,7 @@ func (g SearchableListableAdapter) Search(ctx context.Context, scope, query stri ItemType: g.Type(), ResponderName: g.Name(), } - g.cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, ck) + g.cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, ck) return items, nil } diff --git a/sources/gcp/dynamic/adapter-searchable.go b/sources/gcp/dynamic/adapter-searchable.go index ebebfb53..e94b1bf5 100644 --- a/sources/gcp/dynamic/adapter-searchable.go +++ b/sources/gcp/dynamic/adapter-searchable.go @@ -10,8 +10,8 @@ import ( "github.com/overmindtech/cli/go/discovery" "github.com/overmindtech/cli/go/sdp-go" "github.com/overmindtech/cli/go/sdpcache" - gcpshared "github.com/overmindtech/cli/sources/gcp/shared" "github.com/overmindtech/cli/sources" + gcpshared "github.com/overmindtech/cli/sources/gcp/shared" "github.com/overmindtech/cli/sources/shared" ) @@ -116,7 +116,7 @@ func (g SearchableAdapter) Search(ctx context.Context, scope, query string, igno items, err := aggregateSDPItems(ctx, g.Adapter, searchEndpoint, location) if err != nil { if sources.IsNotFound(err) { - g.cache.StoreError(ctx, err, shared.DefaultCacheDuration, ck) + g.cache.StoreUnavailableItem(ctx, err, shared.DefaultCacheDuration, ck) return []*sdp.Item{}, nil } return nil, err @@ -132,7 +132,7 @@ func (g SearchableAdapter) Search(ctx context.Context, scope, query string, igno ItemType: g.Type(), ResponderName: g.Name(), } - g.cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, ck) + g.cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, ck) return items, nil } diff --git a/sources/gcp/dynamic/adapter.go b/sources/gcp/dynamic/adapter.go index 5da9c03b..106b3764 100644 --- a/sources/gcp/dynamic/adapter.go +++ b/sources/gcp/dynamic/adapter.go @@ -166,7 +166,7 @@ func (g Adapter) Get(ctx context.Context, scope string, query string, ignoreCach if err != nil { enrichNOTFOUNDQueryError(err, scope, g.Name(), g.Type()) if sources.IsNotFound(err) { - g.cache.StoreError(ctx, err, shared.DefaultCacheDuration, ck) + g.cache.StoreUnavailableItem(ctx, err, shared.DefaultCacheDuration, ck) } return nil, err } @@ -175,7 +175,7 @@ func (g Adapter) Get(ctx context.Context, scope string, query string, ignoreCach if err != nil { enrichNOTFOUNDQueryError(err, scope, g.Name(), g.Type()) if sources.IsNotFound(err) { - g.cache.StoreError(ctx, err, shared.DefaultCacheDuration, ck) + g.cache.StoreUnavailableItem(ctx, err, shared.DefaultCacheDuration, ck) } return nil, err } diff --git a/sources/gcp/dynamic/shared.go b/sources/gcp/dynamic/shared.go index d058b5e9..38912252 100644 --- a/sources/gcp/dynamic/shared.go +++ b/sources/gcp/dynamic/shared.go @@ -154,7 +154,7 @@ func externalCallSingle(ctx context.Context, httpCli *http.Client, url string) ( return nil, err } - resp, err := httpCli.Do(req) //nolint:gosec // G107 (SSRF): URL built from GCP API discovery document endpoints and project config, not user input + resp, err := httpCli.Do(req) if err != nil { return nil, err } @@ -215,7 +215,7 @@ func externalCallMulti(ctx context.Context, itemsSelector string, httpCli *http. return err } - resp, err := httpCli.Do(req) //nolint:gosec // G107 (SSRF): URL built from GCP API discovery document endpoints with pagination token from GCP responses + resp, err := httpCli.Do(req) if err != nil { return err } @@ -445,7 +445,7 @@ func streamSDPItems(ctx context.Context, a Adapter, url string, location gcpshar // so behaviour matches cached path (0 items, no error). When items were already sent, // also don't send NOTFOUND (consistent with aggregateSDPItems returning items, nil). if sources.IsNotFound(err) && itemsSent == 0 { - cache.StoreError(ctx, err, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, err, shared.DefaultCacheDuration, cacheKey) } if !sources.IsNotFound(err) { stream.SendError(err) @@ -461,7 +461,7 @@ func streamSDPItems(ctx context.Context, a Adapter, url string, location gcpshar ItemType: a.sdpAssetType.String(), ResponderName: a.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } // Note: No items found is valid. The caller's defer done() will release pending work. } @@ -486,7 +486,7 @@ func terraformMappingViaSearch(ctx context.Context, a Adapter, query string, loc a.sdpAssetType, ), } - cache.StoreError(ctx, err, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, err, shared.DefaultCacheDuration, cacheKey) return nil, err } @@ -506,7 +506,7 @@ func terraformMappingViaSearch(ctx context.Context, a Adapter, query string, loc a.Metadata().GetSupportedQueryMethods().GetSearchDescription(), ), } - cache.StoreError(ctx, err, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, err, shared.DefaultCacheDuration, cacheKey) return nil, err } @@ -514,7 +514,7 @@ func terraformMappingViaSearch(ctx context.Context, a Adapter, query string, loc if err != nil { enrichNOTFOUNDQueryError(err, location.ToScope(), a.Name(), a.Type()) if sources.IsNotFound(err) { - cache.StoreError(ctx, err, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, err, shared.DefaultCacheDuration, cacheKey) // Return empty result, nil error so behaviour matches cached NOTFOUND (caller converts to [], nil) return []*sdp.Item{}, nil } diff --git a/sources/gcp/manual/cloud-kms-crypto-key-version_test.go b/sources/gcp/manual/cloud-kms-crypto-key-version_test.go index 606c572b..adb695cb 100644 --- a/sources/gcp/manual/cloud-kms-crypto-key-version_test.go +++ b/sources/gcp/manual/cloud-kms-crypto-key-version_test.go @@ -79,7 +79,7 @@ func TestCloudKMSCryptoKeyVersion(t *testing.T) { ErrorString: "No resources found in Cloud Asset API", } cacheKey := sdpcache.CacheKeyFromParts("gcp-source", sdp.QueryMethod_GET, projectID, gcpshared.CloudKMSCryptoKeyVersion.String(), "us|test-keyring|test-key|99") - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) loader := gcpshared.NewCloudKMSAssetLoader(nil, projectID, cache, "gcp-source", []gcpshared.LocationInfo{gcpshared.NewProjectLocation(projectID)}) @@ -167,7 +167,7 @@ func TestCloudKMSCryptoKeyVersion(t *testing.T) { ErrorString: "No resources found in Cloud Asset API", } searchCacheKey := sdpcache.CacheKeyFromParts("gcp-source", sdp.QueryMethod_SEARCH, projectID, gcpshared.CloudKMSCryptoKeyVersion.String(), "us|test-keyring|empty-key") - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, searchCacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, searchCacheKey) loader := gcpshared.NewCloudKMSAssetLoader(nil, projectID, cache, "gcp-source", []gcpshared.LocationInfo{gcpshared.NewProjectLocation(projectID)}) @@ -200,7 +200,7 @@ func TestCloudKMSCryptoKeyVersion(t *testing.T) { } query := "us|test-keyring|empty-key" searchCacheKey := sdpcache.CacheKeyFromParts("gcp-source", sdp.QueryMethod_SEARCH, projectID, gcpshared.CloudKMSCryptoKeyVersion.String(), query) - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, searchCacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, searchCacheKey) loader := gcpshared.NewCloudKMSAssetLoader(nil, projectID, cache, "gcp-source", []gcpshared.LocationInfo{gcpshared.NewProjectLocation(projectID)}) wrapper := manual.NewCloudKMSCryptoKeyVersion(loader, []gcpshared.LocationInfo{gcpshared.NewProjectLocation(projectID)}) diff --git a/sources/gcp/manual/cloud-kms-crypto-key_test.go b/sources/gcp/manual/cloud-kms-crypto-key_test.go index 6790ba57..1ac3f6ef 100644 --- a/sources/gcp/manual/cloud-kms-crypto-key_test.go +++ b/sources/gcp/manual/cloud-kms-crypto-key_test.go @@ -78,7 +78,7 @@ func TestCloudKMSCryptoKey(t *testing.T) { ErrorString: "No resources found in Cloud Asset API", } cacheKey := sdpcache.CacheKeyFromParts("gcp-source", sdp.QueryMethod_GET, projectID, gcpshared.CloudKMSCryptoKey.String(), "global|test-keyring|nonexistent") - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) loader := gcpshared.NewCloudKMSAssetLoader(nil, projectID, cache, "gcp-source", []gcpshared.LocationInfo{gcpshared.NewProjectLocation(projectID)}) @@ -164,7 +164,7 @@ func TestCloudKMSCryptoKey(t *testing.T) { ErrorString: "No resources found in Cloud Asset API", } searchCacheKey := sdpcache.CacheKeyFromParts("gcp-source", sdp.QueryMethod_SEARCH, projectID, gcpshared.CloudKMSCryptoKey.String(), "global|empty-keyring") - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, searchCacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, searchCacheKey) loader := gcpshared.NewCloudKMSAssetLoader(nil, projectID, cache, "gcp-source", []gcpshared.LocationInfo{gcpshared.NewProjectLocation(projectID)}) @@ -197,7 +197,7 @@ func TestCloudKMSCryptoKey(t *testing.T) { } query := "global|empty-keyring" searchCacheKey := sdpcache.CacheKeyFromParts("gcp-source", sdp.QueryMethod_SEARCH, projectID, gcpshared.CloudKMSCryptoKey.String(), query) - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, searchCacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, searchCacheKey) loader := gcpshared.NewCloudKMSAssetLoader(nil, projectID, cache, "gcp-source", []gcpshared.LocationInfo{gcpshared.NewProjectLocation(projectID)}) wrapper := manual.NewCloudKMSCryptoKey(loader, []gcpshared.LocationInfo{gcpshared.NewProjectLocation(projectID)}) diff --git a/sources/gcp/manual/cloud-kms-key-ring_test.go b/sources/gcp/manual/cloud-kms-key-ring_test.go index f2cd5398..8d93e735 100644 --- a/sources/gcp/manual/cloud-kms-key-ring_test.go +++ b/sources/gcp/manual/cloud-kms-key-ring_test.go @@ -73,7 +73,7 @@ func TestCloudKMSKeyRing(t *testing.T) { ErrorString: "No resources found in Cloud Asset API", } cacheKey := sdpcache.CacheKeyFromParts("gcp-source", sdp.QueryMethod_GET, projectID, gcpshared.CloudKMSKeyRing.String(), "us|nonexistent") - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) loader := gcpshared.NewCloudKMSAssetLoader(nil, projectID, cache, "gcp-source", []gcpshared.LocationInfo{gcpshared.NewProjectLocation(projectID)}) @@ -158,7 +158,7 @@ func TestCloudKMSKeyRing(t *testing.T) { ErrorString: "No resources found in Cloud Asset API", } listCacheKey := sdpcache.CacheKeyFromParts("gcp-source", sdp.QueryMethod_LIST, projectID, gcpshared.CloudKMSKeyRing.String(), "") - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, listCacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, listCacheKey) loader := gcpshared.NewCloudKMSAssetLoader(nil, projectID, cache, "gcp-source", []gcpshared.LocationInfo{gcpshared.NewProjectLocation(projectID)}) @@ -190,7 +190,7 @@ func TestCloudKMSKeyRing(t *testing.T) { ErrorString: "no key rings found for list", } listCacheKey := sdpcache.CacheKeyFromParts("gcp-source", sdp.QueryMethod_LIST, projectID, gcpshared.CloudKMSKeyRing.String(), "") - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, listCacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, listCacheKey) loader := gcpshared.NewCloudKMSAssetLoader(nil, projectID, cache, "gcp-source", []gcpshared.LocationInfo{gcpshared.NewProjectLocation(projectID)}) wrapper := manual.NewCloudKMSKeyRing(loader, []gcpshared.LocationInfo{gcpshared.NewProjectLocation(projectID)}) @@ -276,7 +276,7 @@ func TestCloudKMSKeyRing(t *testing.T) { } query := "us-central1" searchCacheKey := sdpcache.CacheKeyFromParts("gcp-source", sdp.QueryMethod_SEARCH, projectID, gcpshared.CloudKMSKeyRing.String(), query) - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, searchCacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, searchCacheKey) loader := gcpshared.NewCloudKMSAssetLoader(nil, projectID, cache, "gcp-source", []gcpshared.LocationInfo{gcpshared.NewProjectLocation(projectID)}) wrapper := manual.NewCloudKMSKeyRing(loader, []gcpshared.LocationInfo{gcpshared.NewProjectLocation(projectID)}) diff --git a/sources/gcp/manual/compute-address.go b/sources/gcp/manual/compute-address.go index fcbf5f4a..9b6ef5b8 100644 --- a/sources/gcp/manual/compute-address.go +++ b/sources/gcp/manual/compute-address.go @@ -169,7 +169,7 @@ func (c computeAddressWrapper) ListStream(ctx context.Context, stream discovery. ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } @@ -244,7 +244,7 @@ func (c computeAddressWrapper) listAggregatedStream(ctx context.Context, stream ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-autoscaler.go b/sources/gcp/manual/compute-autoscaler.go index f2b21eac..2c265309 100644 --- a/sources/gcp/manual/compute-autoscaler.go +++ b/sources/gcp/manual/compute-autoscaler.go @@ -162,7 +162,7 @@ func (c computeAutoscalerWrapper) ListStream(ctx context.Context, stream discove ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } @@ -237,7 +237,7 @@ func (c computeAutoscalerWrapper) listAggregatedStream(ctx context.Context, stre ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-backend-service.go b/sources/gcp/manual/compute-backend-service.go index 3905387d..2ce85a48 100644 --- a/sources/gcp/manual/compute-backend-service.go +++ b/sources/gcp/manual/compute-backend-service.go @@ -255,7 +255,7 @@ func (c computeBackendServiceWrapper) ListStream(ctx context.Context, stream dis ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } @@ -330,7 +330,7 @@ func (c computeBackendServiceWrapper) listAggregatedStream(ctx context.Context, ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-disk.go b/sources/gcp/manual/compute-disk.go index 116e2b14..35973a87 100644 --- a/sources/gcp/manual/compute-disk.go +++ b/sources/gcp/manual/compute-disk.go @@ -167,7 +167,7 @@ func (c computeDiskWrapper) ListStream(ctx context.Context, stream discovery.Que ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } @@ -242,7 +242,7 @@ func (c computeDiskWrapper) listAggregatedStream(ctx context.Context, stream dis ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-forwarding-rule.go b/sources/gcp/manual/compute-forwarding-rule.go index 81b51302..bb18a8da 100644 --- a/sources/gcp/manual/compute-forwarding-rule.go +++ b/sources/gcp/manual/compute-forwarding-rule.go @@ -174,7 +174,7 @@ func (c computeForwardingRuleWrapper) ListStream(ctx context.Context, stream dis ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } @@ -249,7 +249,7 @@ func (c computeForwardingRuleWrapper) listAggregatedStream(ctx context.Context, ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-healthcheck.go b/sources/gcp/manual/compute-healthcheck.go index fa3ed72c..dd352948 100644 --- a/sources/gcp/manual/compute-healthcheck.go +++ b/sources/gcp/manual/compute-healthcheck.go @@ -249,7 +249,7 @@ func (c computeHealthCheckWrapper) ListStream(ctx context.Context, stream discov ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } @@ -324,7 +324,7 @@ func (c computeHealthCheckWrapper) listAggregatedStream(ctx context.Context, str ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-image.go b/sources/gcp/manual/compute-image.go index c2fc5784..2944c05b 100644 --- a/sources/gcp/manual/compute-image.go +++ b/sources/gcp/manual/compute-image.go @@ -233,7 +233,7 @@ func (c computeImageWrapper) ListStream(ctx context.Context, stream discovery.Qu ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-instance-group-manager.go b/sources/gcp/manual/compute-instance-group-manager.go index ef7f5269..3039422c 100644 --- a/sources/gcp/manual/compute-instance-group-manager.go +++ b/sources/gcp/manual/compute-instance-group-manager.go @@ -170,7 +170,7 @@ func (c computeInstanceGroupManagerWrapper) ListStream(ctx context.Context, stre ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } @@ -245,7 +245,7 @@ func (c computeInstanceGroupManagerWrapper) listAggregatedStream(ctx context.Con ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-instance-group.go b/sources/gcp/manual/compute-instance-group.go index 06d1d10c..88c32ffa 100644 --- a/sources/gcp/manual/compute-instance-group.go +++ b/sources/gcp/manual/compute-instance-group.go @@ -160,7 +160,7 @@ func (c computeInstanceGroupWrapper) ListStream(ctx context.Context, stream disc ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } @@ -235,7 +235,7 @@ func (c computeInstanceGroupWrapper) listAggregatedStream(ctx context.Context, s ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-instance.go b/sources/gcp/manual/compute-instance.go index 32c08658..aa26e71c 100644 --- a/sources/gcp/manual/compute-instance.go +++ b/sources/gcp/manual/compute-instance.go @@ -229,7 +229,7 @@ func (c computeInstanceWrapper) ListStream(ctx context.Context, stream discovery ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } @@ -305,7 +305,7 @@ func (c computeInstanceWrapper) listAggregatedStream(ctx context.Context, stream ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-instant-snapshot.go b/sources/gcp/manual/compute-instant-snapshot.go index 7fdb21d7..92edacb7 100644 --- a/sources/gcp/manual/compute-instant-snapshot.go +++ b/sources/gcp/manual/compute-instant-snapshot.go @@ -157,7 +157,7 @@ func (c computeInstantSnapshotWrapper) ListStream(ctx context.Context, stream di ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } @@ -232,7 +232,7 @@ func (c computeInstantSnapshotWrapper) listAggregatedStream(ctx context.Context, ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-machine-image.go b/sources/gcp/manual/compute-machine-image.go index 4c9343d9..ec722ef7 100644 --- a/sources/gcp/manual/compute-machine-image.go +++ b/sources/gcp/manual/compute-machine-image.go @@ -152,7 +152,7 @@ func (c computeMachineImageWrapper) ListStream(ctx context.Context, stream disco ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-node-group.go b/sources/gcp/manual/compute-node-group.go index 6e0b1253..47bd3c62 100644 --- a/sources/gcp/manual/compute-node-group.go +++ b/sources/gcp/manual/compute-node-group.go @@ -172,7 +172,7 @@ func (c computeNodeGroupWrapper) ListStream(ctx context.Context, stream discover ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } @@ -247,7 +247,7 @@ func (c computeNodeGroupWrapper) listAggregatedStream(ctx context.Context, strea ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-node-template.go b/sources/gcp/manual/compute-node-template.go index 4beea88f..72db9c81 100644 --- a/sources/gcp/manual/compute-node-template.go +++ b/sources/gcp/manual/compute-node-template.go @@ -157,7 +157,7 @@ func (c computeNodeTemplateWrapper) ListStream(ctx context.Context, stream disco ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } @@ -232,7 +232,7 @@ func (c computeNodeTemplateWrapper) listAggregatedStream(ctx context.Context, st ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-region-instance-group-manager.go b/sources/gcp/manual/compute-region-instance-group-manager.go index 02221d8a..2e6d3f8e 100644 --- a/sources/gcp/manual/compute-region-instance-group-manager.go +++ b/sources/gcp/manual/compute-region-instance-group-manager.go @@ -170,7 +170,7 @@ func (c computeRegionInstanceGroupManagerWrapper) ListStream(ctx context.Context ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } @@ -225,7 +225,7 @@ func (c computeRegionInstanceGroupManagerWrapper) listAllRegionsStream(ctx conte ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-reservation.go b/sources/gcp/manual/compute-reservation.go index cc541a54..fba0fd8e 100644 --- a/sources/gcp/manual/compute-reservation.go +++ b/sources/gcp/manual/compute-reservation.go @@ -159,7 +159,7 @@ func (c computeReservationWrapper) ListStream(ctx context.Context, stream discov ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } @@ -234,7 +234,7 @@ func (c computeReservationWrapper) listAggregatedStream(ctx context.Context, str ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-security-policy.go b/sources/gcp/manual/compute-security-policy.go index 1ccf1355..d883225f 100644 --- a/sources/gcp/manual/compute-security-policy.go +++ b/sources/gcp/manual/compute-security-policy.go @@ -140,7 +140,7 @@ func (c computeSecurityPolicyWrapper) ListStream(ctx context.Context, stream dis ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/compute-snapshot.go b/sources/gcp/manual/compute-snapshot.go index 124cba90..e7ace5cf 100644 --- a/sources/gcp/manual/compute-snapshot.go +++ b/sources/gcp/manual/compute-snapshot.go @@ -144,7 +144,7 @@ func (c computeSnapshotWrapper) ListStream(ctx context.Context, stream discovery ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/iam-service-account.go b/sources/gcp/manual/iam-service-account.go index 1d5c4f2e..dc8d51a9 100644 --- a/sources/gcp/manual/iam-service-account.go +++ b/sources/gcp/manual/iam-service-account.go @@ -159,7 +159,7 @@ func (c iamServiceAccountWrapper) ListStream(ctx context.Context, stream discove ItemType: c.Type(), ResponderName: c.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/manual/logging-sink.go b/sources/gcp/manual/logging-sink.go index b98b8726..f12c9188 100644 --- a/sources/gcp/manual/logging-sink.go +++ b/sources/gcp/manual/logging-sink.go @@ -139,7 +139,7 @@ func (l loggingSinkWrapper) ListStream(ctx context.Context, stream discovery.Que ItemType: l.Type(), ResponderName: l.Name(), } - cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) + cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, cacheKey) } } diff --git a/sources/gcp/shared/kms-asset-loader.go b/sources/gcp/shared/kms-asset-loader.go index 2bae3e7f..c0678e3b 100644 --- a/sources/gcp/shared/kms-asset-loader.go +++ b/sources/gcp/shared/kms-asset-loader.go @@ -171,15 +171,15 @@ func (l *CloudKMSAssetLoader) loadAll(ctx context.Context) error { if !hasKeyRings { listCacheKey := sdpcache.CacheKeyFromParts(l.sourceName, sdp.QueryMethod_LIST, scope, CloudKMSKeyRing.String(), "") - l.cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, listCacheKey) + l.cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, listCacheKey) } if !hasCryptoKeys { listCacheKey := sdpcache.CacheKeyFromParts(l.sourceName, sdp.QueryMethod_LIST, scope, CloudKMSCryptoKey.String(), "") - l.cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, listCacheKey) + l.cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, listCacheKey) } if !hasKeyVersions { listCacheKey := sdpcache.CacheKeyFromParts(l.sourceName, sdp.QueryMethod_LIST, scope, CloudKMSCryptoKeyVersion.String(), "") - l.cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, listCacheKey) + l.cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, listCacheKey) } return nil @@ -231,7 +231,7 @@ func (l *CloudKMSAssetLoader) fetchAssetsPage(ctx context.Context, pageToken str // Cloud Asset API requires quota project header req.Header.Set("X-Goog-User-Project", l.projectID) - resp, err := l.httpClient.Do(req) //nolint:gosec // G107 (SSRF): URL built from hardcoded https://cloudasset.googleapis.com/v1 base with project ID + resp, err := l.httpClient.Do(req) if err != nil { return nil, "", fmt.Errorf("failed to execute request: %w", err) } diff --git a/sources/snapshot/adapters/loader.go b/sources/snapshot/adapters/loader.go index eb1c9133..301cbf9b 100644 --- a/sources/snapshot/adapters/loader.go +++ b/sources/snapshot/adapters/loader.go @@ -74,7 +74,7 @@ func loadSnapshotFromURL(ctx context.Context, url string) ([]byte, error) { } client := &http.Client{} - resp, err := client.Do(req) //nolint:gosec // G107 (SSRF): URL comes from operator-supplied snapshot source config, not from untrusted network input + resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("HTTP request failed: %w", err) } diff --git a/sources/transformer.go b/sources/transformer.go index 2a978d17..1e00c1ad 100644 --- a/sources/transformer.go +++ b/sources/transformer.go @@ -333,7 +333,7 @@ func (s *standardAdapterCore) Get(ctx context.Context, scope string, query strin if err != nil { // Only cache NOTFOUND so lookup behaviour is unchanged for timeouts/other errors if IsNotFound(err) { - s.cache.StoreError(ctx, err, shared.DefaultCacheDuration, ck) + s.cache.StoreUnavailableItem(ctx, err, shared.DefaultCacheDuration, ck) } return nil, err } @@ -348,7 +348,7 @@ func (s *standardAdapterCore) Get(ctx context.Context, scope string, query strin ItemType: s.Type(), ResponderName: s.Name(), } - s.cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, ck) + s.cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, ck) return nil, notFoundErr } @@ -458,7 +458,7 @@ func (s *standardListableAdapterImpl) List(ctx context.Context, scope string, ig if err != nil { // Only cache NOTFOUND so lookup behaviour is unchanged for timeouts/other errors if IsNotFound(err) { - s.cache.StoreError(ctx, err, shared.DefaultCacheDuration, ck) + s.cache.StoreUnavailableItem(ctx, err, shared.DefaultCacheDuration, ck) } return nil, err } @@ -473,7 +473,7 @@ func (s *standardListableAdapterImpl) List(ctx context.Context, scope string, ig ItemType: s.Type(), ResponderName: s.Name(), } - s.cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, ck) + s.cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, ck) return items, nil } @@ -741,7 +741,7 @@ func (s *standardSearchableAdapterImpl) Search(ctx context.Context, scope string if err != nil { // Only cache NOTFOUND so lookup behaviour is unchanged for timeouts/other errors if IsNotFound(err) { - s.cache.StoreError(ctx, err, shared.DefaultCacheDuration, ck) + s.cache.StoreUnavailableItem(ctx, err, shared.DefaultCacheDuration, ck) } return nil, err } @@ -756,7 +756,7 @@ func (s *standardSearchableAdapterImpl) Search(ctx context.Context, scope string ItemType: s.Type(), ResponderName: s.Name(), } - s.cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, ck) + s.cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, ck) return items, nil } @@ -930,7 +930,7 @@ func (s *standardSearchableAdapterImpl) SearchStream(ctx context.Context, scope items, qErr := s.searchable.Search(ctx, scope, queryParts...) if qErr != nil { if IsNotFound(qErr) { - s.cache.StoreError(ctx, qErr, shared.DefaultCacheDuration, ck) + s.cache.StoreUnavailableItem(ctx, qErr, shared.DefaultCacheDuration, ck) } stream.SendError(qErr) return @@ -944,7 +944,7 @@ func (s *standardSearchableAdapterImpl) SearchStream(ctx context.Context, scope ItemType: s.Type(), ResponderName: s.Name(), } - s.cache.StoreError(ctx, notFoundErr, shared.DefaultCacheDuration, ck) + s.cache.StoreUnavailableItem(ctx, notFoundErr, shared.DefaultCacheDuration, ck) return } for _, item := range items { diff --git a/stdlib-source/adapters/dns.go b/stdlib-source/adapters/dns.go index dfbe264a..d5c7dbeb 100644 --- a/stdlib-source/adapters/dns.go +++ b/stdlib-source/adapters/dns.go @@ -161,7 +161,7 @@ func (d *DNSAdapter) Get(ctx context.Context, scope string, query string, ignore // makeQueryImpl returns NOTFOUND when no A/AAAA records exist; cache it to avoid repeated lookups var qe *sdp.QueryError if errors.As(err, &qe) && qe.GetErrorType() == sdp.QueryError_NOTFOUND { - d.cache.StoreError(ctx, qe, dnsCacheDuration, ck) + d.cache.StoreUnavailableItem(ctx, qe, dnsCacheDuration, ck) } return nil, err } @@ -175,7 +175,7 @@ func (d *DNSAdapter) Get(ctx context.Context, scope string, query string, ignore ItemType: d.Type(), ResponderName: d.Name(), } - d.cache.StoreError(ctx, notFoundErr, dnsCacheDuration, ck) + d.cache.StoreUnavailableItem(ctx, notFoundErr, dnsCacheDuration, ck) return nil, notFoundErr } d.cache.StoreItem(ctx, items[0], dnsCacheDuration, ck) @@ -249,7 +249,7 @@ func (d *DNSAdapter) Search(ctx context.Context, scope string, query string, ign // Only cache NOTFOUND to avoid repeated lookups; do not cache transient errors (e.g. timeouts). var qe *sdp.QueryError if errors.As(err, &qe) && qe.GetErrorType() == sdp.QueryError_NOTFOUND { - d.cache.StoreError(ctx, err, dnsCacheDuration, ck) + d.cache.StoreUnavailableItem(ctx, err, dnsCacheDuration, ck) } return nil, err } @@ -264,7 +264,7 @@ func (d *DNSAdapter) Search(ctx context.Context, scope string, query string, ign ItemType: d.Type(), ResponderName: d.Name(), } - d.cache.StoreError(ctx, notFoundErr, dnsCacheDuration, ck) + d.cache.StoreUnavailableItem(ctx, notFoundErr, dnsCacheDuration, ck) return nil, notFoundErr } @@ -285,7 +285,7 @@ func (d *DNSAdapter) Search(ctx context.Context, scope string, query string, ign // Only cache NOTFOUND to avoid repeated lookups; return (nil, error) so cache hit returns same as fresh. var qe *sdp.QueryError if errors.As(err, &qe) && qe.GetErrorType() == sdp.QueryError_NOTFOUND { - d.cache.StoreError(ctx, err, dnsCacheDuration, ck) + d.cache.StoreUnavailableItem(ctx, err, dnsCacheDuration, ck) } return nil, err } diff --git a/stdlib-source/adapters/dns_test.go b/stdlib-source/adapters/dns_test.go index 091c880f..c4fe1bea 100644 --- a/stdlib-source/adapters/dns_test.go +++ b/stdlib-source/adapters/dns_test.go @@ -193,7 +193,7 @@ func TestDnsGet(t *testing.T) { SourceName: cachedSrc.Name(), ItemType: cachedSrc.Type(), } - cache.StoreError(context.Background(), notFoundErr, dnsCacheDuration, ck) + cache.StoreUnavailableItem(context.Background(), notFoundErr, dnsCacheDuration, ck) // Get should return cached NOTFOUND without doing a DNS lookup item, err := cachedSrc.Get(context.Background(), "global", query, false) diff --git a/stdlib-source/adapters/http.go b/stdlib-source/adapters/http.go index 5b593dd7..306eb9fa 100644 --- a/stdlib-source/adapters/http.go +++ b/stdlib-source/adapters/http.go @@ -158,7 +158,7 @@ func (s *HTTPAdapter) Get(ctx context.Context, scope string, query string, ignor ErrorString: err.Error(), Scope: scope, } - s.cache.StoreError(ctx, err, httpCacheDuration, ck) + s.cache.StoreUnavailableItem(ctx, err, httpCacheDuration, ck) return nil, err } } @@ -175,7 +175,7 @@ func (s *HTTPAdapter) Get(ctx context.Context, scope string, query string, ignor return nil, qErr } if cacheHit { - // Get only caches a single item or NOTFOUND (via StoreError). Guard against empty slice for defensive safety (e.g. cache corruption). + // Get only caches a single item or NOTFOUND (via StoreUnavailableItem). Guard against empty slice for defensive safety (e.g. cache corruption). if len(cachedItems) > 0 { return cachedItems[0], nil } @@ -205,7 +205,7 @@ func (s *HTTPAdapter) Get(ctx context.Context, scope string, query string, ignor ErrorString: err.Error(), Scope: scope, } - s.cache.StoreError(ctx, err, httpCacheDuration, ck) + s.cache.StoreUnavailableItem(ctx, err, httpCacheDuration, ck) return nil, err } @@ -214,7 +214,7 @@ func (s *HTTPAdapter) Get(ctx context.Context, scope string, query string, ignor var res *http.Response - res, err = client.Do(req) //nolint:gosec // G107 (SSRF): URL is the SDP query target; hostname validated by validateHostname() which blocks link-local/metadata IPs + res, err = client.Do(req) if err != nil { err = &sdp.QueryError{ @@ -222,7 +222,7 @@ func (s *HTTPAdapter) Get(ctx context.Context, scope string, query string, ignor ErrorString: err.Error(), Scope: scope, } - s.cache.StoreError(ctx, err, httpCacheDuration, ck) + s.cache.StoreUnavailableItem(ctx, err, httpCacheDuration, ck) return nil, err } @@ -240,7 +240,7 @@ func (s *HTTPAdapter) Get(ctx context.Context, scope string, query string, ignor ItemType: s.Type(), ResponderName: s.Name(), } - s.cache.StoreError(ctx, notFoundErr, httpCacheDuration, ck) + s.cache.StoreUnavailableItem(ctx, notFoundErr, httpCacheDuration, ck) return nil, notFoundErr } @@ -269,7 +269,7 @@ func (s *HTTPAdapter) Get(ctx context.Context, scope string, query string, ignor ErrorString: err.Error(), Scope: scope, } - s.cache.StoreError(ctx, err, httpCacheDuration, ck) + s.cache.StoreUnavailableItem(ctx, err, httpCacheDuration, ck) return nil, err } diff --git a/stdlib-source/adapters/rdap-asn.go b/stdlib-source/adapters/rdap-asn.go index 41e7ae4f..dfa97be0 100644 --- a/stdlib-source/adapters/rdap-asn.go +++ b/stdlib-source/adapters/rdap-asn.go @@ -78,7 +78,7 @@ func (s *RdapASNAdapter) Get(ctx context.Context, scope string, query string, ig if err != nil { err = wrapRdapError(err, scope) - s.Cache.StoreError(ctx, err, RdapCacheDuration, ck) + s.Cache.StoreUnavailableItem(ctx, err, RdapCacheDuration, ck) return nil, err } diff --git a/stdlib-source/adapters/rdap-domain.go b/stdlib-source/adapters/rdap-domain.go index afe5e15a..91c44ad5 100644 --- a/stdlib-source/adapters/rdap-domain.go +++ b/stdlib-source/adapters/rdap-domain.go @@ -235,7 +235,7 @@ func (s *RdapDomainAdapter) Search(ctx context.Context, scope string, query stri ItemType: s.Type(), } - s.Cache.StoreError(ctx, err, RdapCacheDuration, ck) + s.Cache.StoreUnavailableItem(ctx, err, RdapCacheDuration, ck) return nil, err } diff --git a/stdlib-source/adapters/rdap-entity.go b/stdlib-source/adapters/rdap-entity.go index 1a462717..8068b14b 100644 --- a/stdlib-source/adapters/rdap-entity.go +++ b/stdlib-source/adapters/rdap-entity.go @@ -125,7 +125,7 @@ func (s *RdapEntityAdapter) runEntityRequest(ctx context.Context, query string, if err != nil { err = wrapRdapError(err, scope) - s.Cache.StoreError(ctx, err, RdapCacheDuration, cacheKey) + s.Cache.StoreUnavailableItem(ctx, err, RdapCacheDuration, cacheKey) return nil, err } diff --git a/stdlib-source/adapters/rdap-ip-network.go b/stdlib-source/adapters/rdap-ip-network.go index 5b58dc7c..7842c621 100644 --- a/stdlib-source/adapters/rdap-ip-network.go +++ b/stdlib-source/adapters/rdap-ip-network.go @@ -122,7 +122,7 @@ func (s *RdapIPNetworkAdapter) Search(ctx context.Context, scope string, query s if err != nil { err = wrapRdapError(err, scope) - s.Cache.StoreError(ctx, err, RdapCacheDuration, ck) + s.Cache.StoreUnavailableItem(ctx, err, RdapCacheDuration, ck) return nil, err } diff --git a/stdlib-source/adapters/rdap-nameserver.go b/stdlib-source/adapters/rdap-nameserver.go index 31e14e5a..e0d089fb 100644 --- a/stdlib-source/adapters/rdap-nameserver.go +++ b/stdlib-source/adapters/rdap-nameserver.go @@ -120,7 +120,7 @@ func (s *RdapNameserverAdapter) Search(ctx context.Context, scope string, query if err != nil { err = wrapRdapError(err, scope) - s.Cache.StoreError(ctx, err, RdapCacheDuration, ck) + s.Cache.StoreUnavailableItem(ctx, err, RdapCacheDuration, ck) return nil, err } diff --git a/tfutils/aws_config.go b/tfutils/aws_config.go index 3baad19b..43b02953 100644 --- a/tfutils/aws_config.go +++ b/tfutils/aws_config.go @@ -57,7 +57,7 @@ type ProviderFile struct { type AWSProvider struct { Name string `hcl:"name,label" yaml:"name,omitempty"` Alias string `hcl:"alias,optional" yaml:"alias,omitempty"` - AccessKey string `hcl:"access_key,optional" yaml:"access_key,omitempty"` //nolint:gosec // G101: field name, not a hardcoded credential; deserialized from local Terraform HCL config, never marshaled into logs or HTTP responses + AccessKey string `hcl:"access_key,optional" yaml:"access_key,omitempty"` SecretKey string `hcl:"secret_key,optional" yaml:"secret_key,omitempty"` Token string `hcl:"token,optional" yaml:"token,omitempty"` Region string `hcl:"region,optional" yaml:"region,omitempty"` diff --git a/tfutils/azure_config.go b/tfutils/azure_config.go index 81f41ed7..c10af272 100644 --- a/tfutils/azure_config.go +++ b/tfutils/azure_config.go @@ -17,7 +17,7 @@ type AzureProvider struct { SubscriptionID string `hcl:"subscription_id,optional" yaml:"subscription_id,omitempty"` TenantID string `hcl:"tenant_id,optional" yaml:"tenant_id,omitempty"` ClientID string `hcl:"client_id,optional" yaml:"client_id,omitempty"` - ClientSecret string `hcl:"client_secret,optional" yaml:"client_secret,omitempty"` //nolint:gosec // G101: field name, not a hardcoded credential; deserialized from local Terraform HCL config, never marshaled into logs or HTTP responses + ClientSecret string `hcl:"client_secret,optional" yaml:"client_secret,omitempty"` Environment string `hcl:"environment,optional" yaml:"environment,omitempty"` // Throw any additional stuff into here so it doesn't fail diff --git a/tfutils/gcp_config.go b/tfutils/gcp_config.go index a82eda01..68853ebf 100644 --- a/tfutils/gcp_config.go +++ b/tfutils/gcp_config.go @@ -15,7 +15,7 @@ type GCPProvider struct { Name string `hcl:"name,label" yaml:"name,omitempty"` Alias string `hcl:"alias,optional" yaml:"alias,omitempty"` Credentials string `hcl:"credentials,optional" yaml:"credentials,omitempty"` - AccessToken string `hcl:"access_token,optional" yaml:"access_token,omitempty"` //nolint:gosec // G101: field name, not a hardcoded credential; deserialized from local Terraform HCL config, never marshaled into logs or HTTP responses + AccessToken string `hcl:"access_token,optional" yaml:"access_token,omitempty"` ImpersonateServiceAccount string `hcl:"impersonate_service_account,optional" yaml:"impersonate_service_account,omitempty"` Project string `hcl:"project,optional" yaml:"project,omitempty"` Region string `hcl:"region,optional" yaml:"region,omitempty"`