diff --git a/cmd/wfctl/deploy_providers.go b/cmd/wfctl/deploy_providers.go index f5c3d3b51..79c7d8a75 100644 --- a/cmd/wfctl/deploy_providers.go +++ b/cmd/wfctl/deploy_providers.go @@ -18,7 +18,9 @@ import ( "time" "github.com/GoCodeAlone/workflow/config" + "github.com/GoCodeAlone/workflow/iac/wfctlhelpers" "github.com/GoCodeAlone/workflow/interfaces" + "github.com/GoCodeAlone/workflow/platform" "github.com/GoCodeAlone/workflow/plugin" "github.com/GoCodeAlone/workflow/plugin/external" "google.golang.org/grpc/codes" @@ -337,7 +339,32 @@ func (r *remoteIaCProvider) Capabilities() []interfaces.IaCCapabilityDeclaration return caps } -func (r *remoteIaCProvider) Plan(_ context.Context, desired []interfaces.ResourceSpec, current []interfaces.ResourceState) (*interfaces.IaCPlan, error) { +// Plan branches on the plugin manifest's iacProvider.computePlanVersion: +// +// - "v2" — delegates to platform.ComputePlan, the canonical wfctl-side +// diff engine. ResourceDriver.Diff for per-resource classification +// hits the plugin via remoteResourceDriver, so the gRPC fan-out is +// preserved while wfctl owns the plan-shape contract. +// - "" / "v1" / unknown — proxies the legacy monolithic IaCProvider.Plan +// call to the plugin via InvokeService, preserving the v1 contract +// for plugins that compute their own plans. This is the safe-default +// branch per dispatch.go's "default-to-v1" doctrine. +// +// The branch mirrors infra_apply.go's DispatchVersionFor gate so the +// wfctl-side proxy honors the same plugin-author-controlled routing that +// the in-tree apply path honors. PR #556 R1 review correction: the +// initial implementation collapsed both branches into the v2 path, which +// silently bypassed v1 plugins' own Plan endpoint via this proxy. +// +// wfctl:skip-iac-codemod (manifest-conditional dispatch is intentional — +// canonical-delegation lint expects unconditional v2 forms for plugin- +// side providers; this is a wfctl-side proxy that supports BOTH versions +// per dispatch.go's "default-to-v1" safety net.) +func (r *remoteIaCProvider) Plan(ctx context.Context, desired []interfaces.ResourceSpec, current []interfaces.ResourceState) (*interfaces.IaCPlan, error) { + if r.computePlanVersion == wfctlhelpers.DispatchVersionV2 { + plan, err := platform.ComputePlan(ctx, r, desired, current) + return &plan, err + } desiredAny, err := jsonToAny(desired) if err != nil { return nil, fmt.Errorf("IaCProvider.Plan: marshal desired: %w", err) @@ -360,7 +387,29 @@ func (r *remoteIaCProvider) Plan(_ context.Context, desired []interfaces.Resourc return &plan, nil } -func (r *remoteIaCProvider) Apply(_ context.Context, plan *interfaces.IaCPlan) (*interfaces.ApplyResult, error) { +// Apply branches on the plugin manifest's iacProvider.computePlanVersion, +// matching the same dispatch policy as Plan above: +// +// - "v2" — delegates to wfctlhelpers.ApplyPlan, which fans out per- +// action through ResourceDriver.{Create,Update,Delete,Replace} (the +// remoteResourceDriver proxies each over gRPC) and runs the +// drift-postcondition + per-action error decomposition. +// - "" / "v1" / unknown — proxies the legacy monolithic IaCProvider. +// Apply call to the plugin via InvokeService, preserving the v1 +// contract for plugins that own their own apply orchestration. +// +// The branch keeps the v1/v2 routing contract documented in dispatch.go +// intact: the dispatch gate in infra_apply.go and this proxy now agree. +// PR #556 R1 review correction (Copilot inline finding) — the initial +// implementation collapsed both branches into the v2 path, which +// silently broke v1 plugins routed through this proxy. +// +// wfctl:skip-iac-codemod (manifest-conditional dispatch is intentional — +// see Plan above for the canonical-delegation-lint rationale.) +func (r *remoteIaCProvider) Apply(ctx context.Context, plan *interfaces.IaCPlan) (*interfaces.ApplyResult, error) { + if r.computePlanVersion == wfctlhelpers.DispatchVersionV2 { + return wfctlhelpers.ApplyPlan(ctx, r, plan) + } planAny, err := jsonToAny(plan) if err != nil { return nil, fmt.Errorf("IaCProvider.Apply: marshal plan: %w", err) diff --git a/cmd/wfctl/deploy_providers_dispatch_matrix_test.go b/cmd/wfctl/deploy_providers_dispatch_matrix_test.go index e1d699b9e..b4abe597d 100644 --- a/cmd/wfctl/deploy_providers_dispatch_matrix_test.go +++ b/cmd/wfctl/deploy_providers_dispatch_matrix_test.go @@ -248,6 +248,15 @@ func TestDispatchMatrix_RemoteIaCProvider(t *testing.T) { requiredKeys []string invoke func(p *remoteIaCProvider, ri *recordingInvoker) error }{ + // Plan and Apply exercise the v1-default branch: per W-Refactor + // (PR 5), remoteIaCProvider's Plan / Apply are manifest-conditional + // — they proxy IaCProvider.Plan / IaCProvider.Apply via + // InvokeService when computePlanVersion is "" / "v1" / unknown, + // and delegate to platform.ComputePlan / wfctlhelpers.ApplyPlan + // when computePlanVersion == "v2". The matrix below pins the v1 + // wire shape (the default constructed *remoteIaCProvider has + // computePlanVersion: "" so the legacy proxy fires). v2 branch + // behavior is pinned in deploy_providers_remote_iac_test.go. { name: "Plan", wantMethod: "IaCProvider.Plan", diff --git a/cmd/wfctl/deploy_providers_remote_iac_test.go b/cmd/wfctl/deploy_providers_remote_iac_test.go index fbc87ca40..dd90800e3 100644 --- a/cmd/wfctl/deploy_providers_remote_iac_test.go +++ b/cmd/wfctl/deploy_providers_remote_iac_test.go @@ -8,10 +8,14 @@ import ( "testing" "time" + "github.com/GoCodeAlone/workflow/iac/wfctlhelpers" "github.com/GoCodeAlone/workflow/interfaces" ) // newIaCProvider builds a remoteIaCProvider backed by the given stubInvoker. +// Defaults to empty computePlanVersion (the safe-default v1 branch in +// dispatch.go's "default-to-v1" doctrine). Tests that need the v2 branch +// set p.computePlanVersion = wfctlhelpers.DispatchVersionV2 directly. func newIaCProvider(si *stubInvoker) *remoteIaCProvider { return &remoteIaCProvider{invoker: si} } @@ -67,6 +71,17 @@ func TestRemoteIaC_Capabilities_Error(t *testing.T) { } // ── Plan ────────────────────────────────────────────────────────────────────── +// +// Plan() is manifest-conditional after W-Refactor (PR 5): +// - computePlanVersion == "v2" → delegates to platform.ComputePlan +// (wfctl owns plan classification; ResourceDriver.Diff dispatches +// remotely on a per-resource basis); +// - otherwise (default v1) → proxies the legacy monolithic +// IaCProvider.Plan call to the plugin via InvokeService. +// +// Tests below pin BOTH branches. + +// v1-default branch: legacy proxy to plugin. func samplePlanResponse() map[string]any { return map[string]any{ @@ -85,9 +100,9 @@ func samplePlanResponse() map[string]any { } } -func TestRemoteIaC_Plan(t *testing.T) { +func TestRemoteIaC_Plan_V1Default_ProxiesIaCProviderPlan(t *testing.T) { si := &stubInvoker{resp: samplePlanResponse()} - p := newIaCProvider(si) + p := newIaCProvider(si) // default computePlanVersion == "" desired := []interfaces.ResourceSpec{ {Name: "db", Type: "infra.database", Config: map[string]any{"engine": "postgres"}}, @@ -101,9 +116,8 @@ func TestRemoteIaC_Plan(t *testing.T) { t.Fatalf("Plan: unexpected error: %v", err) } if si.method != "IaCProvider.Plan" { - t.Errorf("method: got %q, want IaCProvider.Plan", si.method) + t.Errorf("v1-default branch must proxy IaCProvider.Plan; got %q", si.method) } - // Args must include desired and current as slices if _, ok := si.args["desired"]; !ok { t.Error("missing arg key 'desired'") } @@ -121,18 +135,89 @@ func TestRemoteIaC_Plan(t *testing.T) { } } -func TestRemoteIaC_Plan_Error(t *testing.T) { +func TestRemoteIaC_Plan_V1Default_PropagatesError(t *testing.T) { si := &stubInvoker{err: fmt.Errorf("rpc error")} p := newIaCProvider(si) _, err := p.Plan(context.Background(), nil, nil) if err == nil { - t.Fatal("expected error") + t.Fatal("expected error from v1 IaCProvider.Plan proxy") } } -// ── Apply ───────────────────────────────────────────────────────────────────── +// v2 branch: delegates to platform.ComputePlan. + +func TestRemoteIaC_Plan_V2_DelegatesToComputePlan_NetNewResource(t *testing.T) { + // stubInvoker tracks the LAST InvokeService call. With ComputePlan + // delegation, a net-new resource emits "create" without touching the + // invoker — confirming the v2 branch routes through wfctl-side + // classification rather than the v1 IaCProvider.Plan wire. + si := &stubInvoker{} + p := newIaCProvider(si) + p.computePlanVersion = wfctlhelpers.DispatchVersionV2 + + desired := []interfaces.ResourceSpec{ + {Name: "db", Type: "infra.database", Config: map[string]any{"engine": "postgres"}}, + } + plan, err := p.Plan(context.Background(), desired, nil) + if err != nil { + t.Fatalf("Plan: unexpected error: %v", err) + } + if si.method != "" { + t.Errorf("v2 branch + net-new create should not hit InvokeService; got %q", si.method) + } + if plan == nil { + t.Fatal("Plan returned nil plan") + } + if len(plan.Actions) != 1 { + t.Fatalf("expected 1 action (create), got %d", len(plan.Actions)) + } + if plan.Actions[0].Action != "create" { + t.Errorf("action: got %q, want %q", plan.Actions[0].Action, "create") + } + if plan.Actions[0].Resource.Name != "db" { + t.Errorf("action resource name: got %q, want %q", plan.Actions[0].Resource.Name, "db") + } +} + +func TestRemoteIaC_Plan_V2_DelegatesToComputePlan_DeleteEmittedForRemoved(t *testing.T) { + si := &stubInvoker{} + p := newIaCProvider(si) + p.computePlanVersion = wfctlhelpers.DispatchVersionV2 -func TestRemoteIaC_Apply(t *testing.T) { + current := []interfaces.ResourceState{ + {Name: "old-db", Type: "infra.database", ProviderID: "pid-old"}, + } + plan, err := p.Plan(context.Background(), nil, current) + if err != nil { + t.Fatalf("Plan: unexpected error: %v", err) + } + if si.method != "" { + t.Errorf("v2 branch + delete path should not hit InvokeService; got %q", si.method) + } + if plan == nil { + t.Fatal("Plan returned nil plan") + } + if len(plan.Actions) != 1 { + t.Fatalf("expected 1 action (delete), got %d", len(plan.Actions)) + } + if plan.Actions[0].Action != "delete" { + t.Errorf("action: got %q, want %q", plan.Actions[0].Action, "delete") + } +} + +// ── Apply ───────────────────────────────────────────────────────────────────── +// +// Apply() is manifest-conditional after W-Refactor (PR 5): +// - computePlanVersion == "v2" → delegates to wfctlhelpers.ApplyPlan +// (per-action driver dispatch + drift postcondition); +// - otherwise (default v1) → proxies the legacy monolithic +// IaCProvider.Apply call to the plugin via InvokeService. +// +// Tests below pin BOTH branches. + +// v1-default branch: legacy proxy to plugin. + +func TestRemoteIaC_Apply_V1Default_ProxiesIaCProviderApply(t *testing.T) { si := &stubInvoker{resp: map[string]any{ "plan_id": "plan-abc", "resources": []any{ @@ -144,7 +229,7 @@ func TestRemoteIaC_Apply(t *testing.T) { }, }, }} - p := newIaCProvider(si) + p := newIaCProvider(si) // default computePlanVersion == "" plan := &interfaces.IaCPlan{ ID: "plan-abc", @@ -152,15 +237,13 @@ func TestRemoteIaC_Apply(t *testing.T) { {Action: "create", Resource: interfaces.ResourceSpec{Name: "db", Type: "infra.database"}}, }, } - result, err := p.Apply(context.Background(), plan) if err != nil { t.Fatalf("Apply: unexpected error: %v", err) } if si.method != "IaCProvider.Apply" { - t.Errorf("method: got %q, want IaCProvider.Apply", si.method) + t.Errorf("v1-default branch must proxy IaCProvider.Apply; got %q", si.method) } - // Plan must be wrapped under "plan" key if _, ok := si.args["plan"]; !ok { t.Error("missing arg key 'plan'") } @@ -175,12 +258,80 @@ func TestRemoteIaC_Apply(t *testing.T) { } } -func TestRemoteIaC_Apply_Error(t *testing.T) { +func TestRemoteIaC_Apply_V1Default_PropagatesError(t *testing.T) { si := &stubInvoker{err: fmt.Errorf("apply failed")} p := newIaCProvider(si) _, err := p.Apply(context.Background(), &interfaces.IaCPlan{ID: "p1"}) if err == nil { - t.Fatal("expected error") + t.Fatal("expected error from v1 IaCProvider.Apply proxy") + } +} + +// v2 branch: delegates to wfctlhelpers.ApplyPlan (per-action driver dispatch). + +func TestRemoteIaC_Apply_V2_DelegatesToApplyPlan_PerDriverDispatch(t *testing.T) { + // ApplyPlan dispatches Create on a single-create plan via + // remoteResourceDriver, which invokes "ResourceDriver.Create" through + // the stub invoker. The v1 monolithic "IaCProvider.Apply" wire is + // not used in the v2 branch. + si := &stubInvoker{resp: map[string]any{ + "output": map[string]any{ + "provider_id": "pid-123", + "name": "db", + "type": "infra.database", + "status": "running", + }, + }} + p := newIaCProvider(si) + p.computePlanVersion = wfctlhelpers.DispatchVersionV2 + + plan := &interfaces.IaCPlan{ + ID: "plan-abc", + Actions: []interfaces.PlanAction{ + {Action: "create", Resource: interfaces.ResourceSpec{Name: "db", Type: "infra.database"}}, + }, + } + result, err := p.Apply(context.Background(), plan) + if err != nil { + t.Fatalf("Apply: unexpected error: %v", err) + } + if si.method == "IaCProvider.Apply" { + t.Error("v2 branch must NOT invoke legacy IaCProvider.Apply wire") + } + if !strings.HasPrefix(si.method, "ResourceDriver.") { + t.Errorf("v2 branch: expected ResourceDriver.* per-driver dispatch, got %q", si.method) + } + if result == nil { + t.Fatal("Apply returned nil result") + } + if result.PlanID != "plan-abc" { + t.Errorf("PlanID: got %q, want %q (ApplyPlan stamps plan.ID onto result)", result.PlanID, "plan-abc") + } +} + +func TestRemoteIaC_Apply_V2_DelegatesToApplyPlan_RecordsErrorsPerAction(t *testing.T) { + // When the underlying driver returns an error, ApplyPlan records it + // in result.Errors rather than returning the error from the top-level + // call (per the per-action error decomposition contract). + si := &stubInvoker{err: fmt.Errorf("driver create failed")} + p := newIaCProvider(si) + p.computePlanVersion = wfctlhelpers.DispatchVersionV2 + + plan := &interfaces.IaCPlan{ + ID: "p1", + Actions: []interfaces.PlanAction{ + {Action: "create", Resource: interfaces.ResourceSpec{Name: "db", Type: "infra.database"}}, + }, + } + result, err := p.Apply(context.Background(), plan) + if err != nil { + t.Fatalf("Apply: unexpected top-level error (wfctlhelpers.ApplyPlan records per-action errors): %v", err) + } + if result == nil { + t.Fatal("Apply returned nil result") + } + if len(result.Errors) == 0 { + t.Error("expected ApplyResult.Errors to contain the per-action driver error") } } diff --git a/docs/adr/010-platform-vs-provider-conformance-scenarios.md b/docs/adr/010-platform-vs-provider-conformance-scenarios.md new file mode 100644 index 000000000..1eb291b1f --- /dev/null +++ b/docs/adr/010-platform-vs-provider-conformance-scenarios.md @@ -0,0 +1,51 @@ +# ADR 010: Platform-vs-Provider Conformance Scenario Classification + +**Status:** Accepted +**Date:** 2026-05-05 +**Context:** W-7 (workflow PR #535) shipped 12 conformance scenarios in `iac/conformance/`. During implementation, 4 scenarios diverged from the typical pattern of asserting against `cfg.Provider()`; instead they exercise platform-shared surfaces directly. + +## Decision + +We codify TWO classes of conformance scenario: + +**Provider-level scenarios** (8 of 12): assert against `cfg.Provider()`. Exercise per-provider behavior (Diff, Apply, ResourceDriver lookup, etc.). Scenarios: +- Scenario_NeedsReplaceTriggersReplaceAction +- Scenario_DeleteActionInApplyInvokesDriverDelete +- Scenario_DiffSurvivesGRPCRoundTrip +- Scenario_OutputsRefreshDetectsNewFields +- Scenario_CrossResourceConstraintRejection +- Scenario_OutputsConsistencyAcrossReadCycles +- Scenario_ReplaceCascadePreservesDependents +- Scenario_UpsertOnAlreadyExists + +**Platform-level scenarios** (4 of 12): bypass `cfg.Provider()`; exercise platform-shared surfaces (`inputsnapshot`, `jitsubst`, `wfctlhelpers`). cfg.Provider is required by Run's validateConfig precondition but intentionally NOT invoked. Scenarios: +- Scenario_PlanStaleDiagnostic — exercises `inputsnapshot.NewStaleError` +- Scenario_InfraOutputCrossModuleResolution — exercises `jitsubst.ResolveSpec` +- Scenario_ProtectedReplaceWithoutOverride — exercises `wfctlhelpers.ValidateAllowReplaceProtected` +- Scenario_ProtectedReplaceWithOverride — exercises `wfctlhelpers.ValidateAllowReplaceProtected` + +Each platform-level scenario carries a body comment naming the platform surface it exercises and explaining why cfg.Provider is unused. + +## Rationale + +Some root-cause issues from the IaC conformance plan (e.g. plan-stale-diagnostic, JIT secret resolution, --allow-replace gate) live at the platform layer (cross-provider-shared code), not at the per-provider layer. Conformance scenarios for those issues SHOULD test the platform surface directly — wrapping in `cfg.Provider()` calls would be vestigial. + +The 4-of-12 ratio is acceptable; the boundary is non-arbitrary (each platform-level scenario tests code that lives in `iac/` or `iac/wfctlhelpers/`, not in any specific provider). + +## Consequences + +- Future contributors adding conformance scenarios must classify their scenario at design time and document the choice in the body comment. +- The Run dispatcher does not need code changes for this classification; it already validates `cfg.Provider != nil` regardless. Platform-level scenarios pass a NoopProvider to satisfy validateConfig. +- If future iteration wants typed enforcement, a `Scenario.Platform bool` field could be added and consulted by Run for richer reporting. Out of scope for this ADR. + +## Alternatives Considered + +- **Bypass validateConfig for platform-level scenarios.** Rejected: the precondition is universal; making it conditional adds complexity without benefit. +- **Move platform-level scenarios out of conformance/ into a separate package.** Rejected: scenarios are conceptually about provider-conformance to the IaC contract; platform-shared surfaces are part of that contract. + +## References + +- Workflow PR #535 (W-7) — original implementation +- Workflow PR #538 (W-8) — codemod that surfaced the pattern in lint reports +- IaC conformance plan: `docs/plans/2026-05-03-iac-conformance-and-replace.md` +- Deferred cleanup design: `docs/plans/2026-05-05-iac-deferred-cleanup-design.md` diff --git a/example/go.mod b/example/go.mod index 50e77be98..67383ef3d 100644 --- a/example/go.mod +++ b/example/go.mod @@ -38,33 +38,32 @@ require ( github.com/Workiva/go-datastructures v1.1.7 // indirect github.com/andybalholm/brotli v1.2.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect - github.com/aws/aws-sdk-go-v2 v1.41.5 // indirect + github.com/aws/aws-sdk-go-v2 v1.41.6 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 // indirect - github.com/aws/aws-sdk-go-v2/config v1.32.14 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.19.14 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 // indirect + github.com/aws/aws-sdk-go-v2/config v1.32.16 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.19.15 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23 // indirect github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.34.1 // indirect github.com/aws/aws-sdk-go-v2/service/applicationautoscaling v1.41.14 // indirect github.com/aws/aws-sdk-go-v2/service/codebuild v1.68.13 // indirect github.com/aws/aws-sdk-go-v2/service/ec2 v1.297.0 // indirect github.com/aws/aws-sdk-go-v2/service/ecs v1.78.0 // indirect github.com/aws/aws-sdk-go-v2/service/eks v1.82.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8 // indirect github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 // indirect github.com/aws/aws-sdk-go-v2/service/kinesis v1.43.5 // indirect github.com/aws/aws-sdk-go-v2/service/route53 v1.62.5 // indirect github.com/aws/aws-sdk-go-v2/service/s3 v1.99.0 // indirect - github.com/aws/aws-sdk-go-v2/service/signin v1.0.9 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.30.15 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.19 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.41.10 // indirect - github.com/aws/smithy-go v1.24.3 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.0.10 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.16 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.42.0 // indirect + github.com/aws/smithy-go v1.25.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.24.4 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect diff --git a/example/go.sum b/example/go.sum index 1b38659ff..1b47cd7ad 100644 --- a/example/go.sum +++ b/example/go.sum @@ -86,24 +86,22 @@ github.com/antithesishq/antithesis-sdk-go v0.7.0 h1:uWDG8BqLD1lI2ps38WDz2vXflrTX github.com/antithesishq/antithesis-sdk-go v0.7.0/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY= -github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= +github.com/aws/aws-sdk-go-v2 v1.41.6 h1:1AX0AthnBQzMx1vbmir3Y4WsnJgiydmnJjiLu+LvXOg= +github.com/aws/aws-sdk-go-v2 v1.41.6/go.mod h1:dy0UzBIfwSeot4grGvY1AqFWN5zgziMmWGzysDnHFcQ= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 h1:eBMB84YGghSocM7PsjmmPffTa+1FBUeNvGvFou6V/4o= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8/go.mod h1:lyw7GFp3qENLh7kwzf7iMzAxDn+NzjXEAGjKS2UOKqI= -github.com/aws/aws-sdk-go-v2/config v1.32.14 h1:opVIRo/ZbbI8OIqSOKmpFaY7IwfFUOCCXBsUpJOwDdI= -github.com/aws/aws-sdk-go-v2/config v1.32.14/go.mod h1:U4/V0uKxh0Tl5sxmCBZ3AecYny4UNlVmObYjKuuaiOo= -github.com/aws/aws-sdk-go-v2/credentials v1.19.14 h1:n+UcGWAIZHkXzYt87uMFBv/l8THYELoX6gVcUvgl6fI= -github.com/aws/aws-sdk-go-v2/credentials v1.19.14/go.mod h1:cJKuyWB59Mqi0jM3nFYQRmnHVQIcgoxjEMAbLkpr62w= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21 h1:NUS3K4BTDArQqNu2ih7yeDLaS3bmHD0YndtA6UP884g= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.21/go.mod h1:YWNWJQNjKigKY1RHVJCuupeWDrrHjRqHm0N9rdrWzYI= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 h1:Rgg6wvjjtX8bNHcvi9OnXWwcE0a2vGpbwmtICOsvcf4= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21/go.mod h1:A/kJFst/nm//cyqonihbdpQZwiUhhzpqTsdbhDdRF9c= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 h1:PEgGVtPoB6NTpPrBgqSE5hE/o47Ij9qk/SEZFbUOe9A= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21/go.mod h1:p+hz+PRAYlY3zcpJhPwXlLC4C+kqn70WIHwnzAfs6ps= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 h1:rWyie/PxDRIdhNf4DzRk0lvjVOqFJuNnO8WwaIRVxzQ= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22/go.mod h1:zd/JsJ4P7oGfUhXn1VyLqaRZwPmZwg44Jf2dS84Dm3Y= +github.com/aws/aws-sdk-go-v2/config v1.32.16 h1:Q0iQ7quUgJP0F/SCRTieScnaMdXr9h/2+wze1u3cNeM= +github.com/aws/aws-sdk-go-v2/config v1.32.16/go.mod h1:duCCnJEFqpt2RC6no1iK6q+8HpwOAkiUua0pY507dQc= +github.com/aws/aws-sdk-go-v2/credentials v1.19.15 h1:fyvgWTszojq8hEnMi8PPBTvZdTtEVmAVyo+NFLHBhH4= +github.com/aws/aws-sdk-go-v2/credentials v1.19.15/go.mod h1:gJiYyMOjNg8OEdRWOf3CrFQxM2a98qmrtjx1zuiQfB8= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22 h1:IOGsJ1xVWhsi+ZO7/NW8OuZZBtMJLZbk4P5HDjJO0jQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22/go.mod h1:b+hYdbU+jGKfXE8kKM6g1+h+L/Go3vMvzlxBsiuGsxg= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.22 h1:GmLa5Kw1ESqtFpXsx5MmC84QWa/ZrLZvlJGa2y+4kcQ= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.22/go.mod h1:6sW9iWm9DK9YRpRGga/qzrzNLgKpT2cIxb7Vo2eNOp0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22 h1:dY4kWZiSaXIzxnKlj17nHnBcXXBfac6UlsAx2qL6XrU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.22/go.mod h1:KIpEUx0JuRZLO7U6cbV204cWAEco2iC3l061IxlwLtI= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23 h1:FPXsW9+gMuIeKmz7j6ENWcWtBGTe1kH8r9thNt5Uxx4= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.23/go.mod h1:7J8iGMdRKk6lw2C+cMIphgAnT8uTwBwNOsGkyOCm80U= github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.34.1 h1:KdeMmKNbHOcFsiFe8BhLYE2A8crvEWnetrs8GkF2od8= github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.34.1/go.mod h1:QdVi7bF8U8HE8FWQ77pa4wcAMFnxI/UPx4mmQ4azRQs= github.com/aws/aws-sdk-go-v2/service/applicationautoscaling v1.41.14 h1:0aYQ2UaSB1ccXZXUQ4a5XanrHEykKNzMLFgLEDhf8PU= @@ -118,12 +116,12 @@ github.com/aws/aws-sdk-go-v2/service/eks v1.82.0 h1:AvBDUgHffBd4AErnQY6sB9u5vY/9 github.com/aws/aws-sdk-go-v2/service/eks v1.82.0/go.mod h1:xdUh6tdF9A8hc+PE84kmHbF/zsVPNiKnc6oLgulq1Eo= github.com/aws/aws-sdk-go-v2/service/iam v1.53.7 h1:n9YLiWtX3+6pTLZWvRJmtq5JIB9NA/KFelyCg5fOlTU= github.com/aws/aws-sdk-go-v2/service/iam v1.53.7/go.mod h1:sP46Vo6MeJcM4s0ZXcG2PFmfiSyixhIuC/74W52yKuk= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8 h1:HtOTYcbVcGABLOVuPYaIihj6IlkqubBwFj10K5fxRek= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.8/go.mod h1:VsK9abqQeGlzPgUr+isNWzPlK2vKe9INMLWnY65f5Xs= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 h1:JRaIgADQS/U6uXDqlPiefP32yXTda7Kqfx+LgspooZM= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13/go.mod h1:CEuVn5WqOMilYl+tbccq8+N2ieCy0gVn3OtRb0vBNNM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 h1:c31//R3xgIJMSC8S6hEVq+38DcvUlgFY0FM6mSI5oto= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21/go.mod h1:r6+pf23ouCB718FUxaqzZdbpYFyDtehyZcmP5KL9FkA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22 h1:PUmZeJU6Y1Lbvt9WFuJ0ugUK2xn6hIWUBBbKuOWF30s= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.22/go.mod h1:nO6egFBoAaoXze24a2C0NjQCvdpk8OueRoYimvEB9jo= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 h1:ZlvrNcHSFFWURB8avufQq9gFsheUgjVD9536obIknfM= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21/go.mod h1:cv3TNhVrssKR0O/xxLJVRfd2oazSnZnkUeTf6ctUwfQ= github.com/aws/aws-sdk-go-v2/service/kinesis v1.43.5 h1:LxgRVyuY+5DEPSX7kmin/V7toE8MWZ9U8n2dqRtX+RE= @@ -132,16 +130,16 @@ github.com/aws/aws-sdk-go-v2/service/route53 v1.62.5 h1:Z+/OLsb85Kpq7TVLCspskqeP github.com/aws/aws-sdk-go-v2/service/route53 v1.62.5/go.mod h1:TmxGowuBYwjmHFOsEDxaZdsQE62JJzOmtiWafTi/czg= github.com/aws/aws-sdk-go-v2/service/s3 v1.99.0 h1:hlSuz394kV0vhv9drL5lhuEFbEOEP1VyQpy15qWh1Pk= github.com/aws/aws-sdk-go-v2/service/s3 v1.99.0/go.mod h1:uoA43SdFwacedBfSgfFSjjCvYe8aYBS7EnU5GZ/YKMM= -github.com/aws/aws-sdk-go-v2/service/signin v1.0.9 h1:QKZH0S178gCmFEgst8hN0mCX1KxLgHBKKY/CLqwP8lg= -github.com/aws/aws-sdk-go-v2/service/signin v1.0.9/go.mod h1:7yuQJoT+OoH8aqIxw9vwF+8KpvLZ8AWmvmUWHsGQZvI= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.15 h1:lFd1+ZSEYJZYvv9d6kXzhkZu07si3f+GQ1AaYwa2LUM= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.15/go.mod h1:WSvS1NLr7JaPunCXqpJnWk1Bjo7IxzZXrZi1QQCkuqM= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.19 h1:dzztQ1YmfPrxdrOiuZRMF6fuOwWlWpD2StNLTceKpys= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.19/go.mod h1:YO8TrYtFdl5w/4vmjL8zaBSsiNp3w0L1FfKVKenZT7w= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.10 h1:p8ogvvLugcR/zLBXTXrTkj0RYBUdErbMnAFFp12Lm/U= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.10/go.mod h1:60dv0eZJfeVXfbT1tFJinbHrDfSJ2GZl4Q//OSSNAVw= -github.com/aws/smithy-go v1.24.3 h1:XgOAaUgx+HhVBoP4v8n6HCQoTRDhoMghKqw4LNHsDNg= -github.com/aws/smithy-go v1.24.3/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.10 h1:a1Fq/KXn75wSzoJaPQTgZO0wHGqE9mjFnylnqEPTchA= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.10/go.mod h1:p6+MXNxW7IA6dMgHfTAzljuwSKD0NCm/4lbS4t6+7vI= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.16 h1:x6bKbmDhsgSZwv6q19wY/u3rLk/3FGjJWyqKcIRufpE= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.16/go.mod h1:CudnEVKRtLn0+3uMV0yEXZ+YZOKnAtUJ5DmDhilVnIw= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20 h1:oK/njaL8GtyEihkWMD4k3VgHCT64RQKkZwh0DG5j8ak= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20/go.mod h1:JHs8/y1f3zY7U5WcuzoJ/yAYGYtNIVPKLIbp61euvmg= +github.com/aws/aws-sdk-go-v2/service/sts v1.42.0 h1:ks8KBcZPh3PYISr5dAiXCM5/Thcuxk8l+PG4+A0exds= +github.com/aws/aws-sdk-go-v2/service/sts v1.42.0/go.mod h1:pFw33T0WLvXU3rw1WBkpMlkgIn54eCB5FYLhjDc9Foo= +github.com/aws/smithy-go v1.25.0 h1:Sz/XJ64rwuiKtB6j98nDIPyYrV1nVNJ4YU74gttcl5U= +github.com/aws/smithy-go v1.25.0/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=