diff --git a/cmd/wfctl/plugin_infra.go b/cmd/wfctl/plugin_infra.go index 52580f9b..01cdfc8b 100644 --- a/cmd/wfctl/plugin_infra.go +++ b/cmd/wfctl/plugin_infra.go @@ -6,6 +6,7 @@ import ( "path/filepath" "github.com/GoCodeAlone/workflow/config" + "github.com/GoCodeAlone/workflow/iac/requirements" ) // LoadPluginManifests loads all plugin.json files from the given plugins directory. @@ -96,3 +97,9 @@ func DetectPluginInfraNeeds(cfg *config.WorkflowConfig, manifests map[string]*co return needs } + +// DetectPluginRequirementsV2 exposes provider-neutral moduleInfraRequirementsV2 +// declarations without changing the legacy DetectPluginInfraNeeds return type. +func DetectPluginRequirementsV2(cfg *config.WorkflowConfig, manifests map[string]*config.PluginManifestFile) ([]requirements.Requirement, error) { + return requirements.DiscoverManifestRequirements(cfg, manifests) +} diff --git a/cmd/wfctl/plugin_infra_test.go b/cmd/wfctl/plugin_infra_test.go index 2931e56b..59205657 100644 --- a/cmd/wfctl/plugin_infra_test.go +++ b/cmd/wfctl/plugin_infra_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/GoCodeAlone/workflow/config" + "github.com/GoCodeAlone/workflow/iac/requirements" ) func TestLoadPluginManifests_EmptyDir(t *testing.T) { @@ -215,3 +216,42 @@ func TestDetectPluginInfraNeeds_ServiceModules(t *testing.T) { t.Errorf("type: got %q", needs[0].Type) } } + +func TestDetectPluginRequirementsV2(t *testing.T) { + cfg := &config.WorkflowConfig{ + Modules: []config.ModuleConfig{{Name: "telemetry", Type: "observability.telemetry"}}, + Services: map[string]*config.ServiceConfig{ + "api": { + Binary: "./cmd/api", + Expose: []config.ExposeConfig{{Port: 8080, Protocol: "http"}}, + }, + }, + } + manifests := map[string]*config.PluginManifestFile{ + "workflow-plugin-observability": { + Name: "workflow-plugin-observability", + ModuleInfraRequirementsV2: config.PluginInfraRequirementsV2{ + "observability.telemetry": { + Requires: []config.ModuleInfraRequirementV2{{ + Key: "observability.telemetry.default", + Kind: "observability", + TelemetrySignals: []string{"traces"}, + ObservabilityBackends: []string{"otel"}, + DeploymentModes: []string{"sidecar"}, + }}, + }, + }, + }, + } + + reqs, err := DetectPluginRequirementsV2(cfg, manifests) + if err != nil { + t.Fatalf("DetectPluginRequirementsV2: %v", err) + } + if len(reqs) != 1 { + t.Fatalf("requirements len = %d, want 1", len(reqs)) + } + if reqs[0].Key != "observability.telemetry.default" || reqs[0].Kind != requirements.KindObservability { + t.Fatalf("requirement = %+v", reqs[0]) + } +} diff --git a/config/config.go b/config/config.go index 5d749f89..8457cbc5 100644 --- a/config/config.go +++ b/config/config.go @@ -73,6 +73,7 @@ func IsApplicationConfig(data []byte) bool { type ModuleConfig struct { Name string `json:"name" yaml:"name"` Type string `json:"type" yaml:"type"` + Satisfies []string `json:"satisfies,omitempty" yaml:"satisfies,omitempty"` Config map[string]any `json:"config,omitempty" yaml:"config,omitempty"` DependsOn []string `json:"dependsOn,omitempty" yaml:"dependsOn,omitempty"` Branches map[string]string `json:"branches,omitempty" yaml:"branches,omitempty"` diff --git a/config/config_test.go b/config/config_test.go index 125ae887..aa4ce827 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -136,6 +136,35 @@ modules: } } +func TestLoadFromFile_ModuleSatisfies(t *testing.T) { + content := ` +modules: + - name: otel-collector + type: infra.container_service + satisfies: + - observability.telemetry.default + config: + image: otel/opentelemetry-collector-contrib:latest +` + dir := t.TempDir() + fp := filepath.Join(dir, "modules.yaml") + if err := os.WriteFile(fp, []byte(content), 0644); err != nil { + t.Fatalf("failed to write test file: %v", err) + } + + cfg, err := LoadFromFile(fp) + if err != nil { + t.Fatalf("LoadFromFile failed: %v", err) + } + if len(cfg.Modules) != 1 { + t.Fatalf("modules len = %d, want 1", len(cfg.Modules)) + } + got := cfg.Modules[0].Satisfies + if len(got) != 1 || got[0] != "observability.telemetry.default" { + t.Fatalf("Satisfies = %v, want [observability.telemetry.default]", got) + } +} + func TestExternalPluginDeclParsing(t *testing.T) { yaml := ` modules: [] diff --git a/config/plugin_manifest.go b/config/plugin_manifest.go index 8dbea6f9..741b51c9 100644 --- a/config/plugin_manifest.go +++ b/config/plugin_manifest.go @@ -3,11 +3,21 @@ package config // PluginInfraRequirements maps module types to their infrastructure needs. type PluginInfraRequirements map[string]*ModuleInfraSpec +// PluginInfraRequirementsV2 maps module types to provider-neutral IaC +// requirements. The values intentionally use manifest-friendly strings; the +// iac/requirements package owns typed enum validation and protobuf conversion. +type PluginInfraRequirementsV2 map[string]*ModuleInfraSpecV2 + // ModuleInfraSpec declares what a module type requires. type ModuleInfraSpec struct { Requires []InfraRequirement `json:"requires" yaml:"requires"` } +// ModuleInfraSpecV2 declares typed requirement metadata for a module type. +type ModuleInfraSpecV2 struct { + Requires []ModuleInfraRequirementV2 `json:"requires" yaml:"requires"` +} + // InfraRequirement is a single infrastructure dependency. type InfraRequirement struct { Type string `json:"type" yaml:"type"` @@ -20,13 +30,32 @@ type InfraRequirement struct { Optional bool `json:"optional,omitempty" yaml:"optional,omitempty"` } +// ModuleInfraRequirementV2 is the plugin.json authoring shape for derived-IaC +// requirements. It mirrors the portable fields in plugin/external/proto/iac.proto +// using strings so manifests stay easy to read and preserve unknown future +// provider details under Parameters. +type ModuleInfraRequirementV2 struct { + Key string `json:"key" yaml:"key"` + Kind string `json:"kind" yaml:"kind"` + Source string `json:"source,omitempty" yaml:"source,omitempty"` + ResourceTypeHint string `json:"resourceTypeHint,omitempty" yaml:"resourceTypeHint,omitempty"` + Environment string `json:"environment,omitempty" yaml:"environment,omitempty"` + Runtimes []string `json:"runtimes,omitempty" yaml:"runtimes,omitempty"` + TelemetrySignals []string `json:"telemetrySignals,omitempty" yaml:"telemetrySignals,omitempty"` + ObservabilityBackends []string `json:"observabilityBackends,omitempty" yaml:"observabilityBackends,omitempty"` + DeploymentModes []string `json:"deploymentModes,omitempty" yaml:"deploymentModes,omitempty"` + VendorFeatures []string `json:"vendorFeatures,omitempty" yaml:"vendorFeatures,omitempty"` + Parameters map[string]any `json:"parameters,omitempty" yaml:"parameters,omitempty"` +} + // PluginManifestFile represents the full plugin.json manifest. type PluginManifestFile struct { - Name string `json:"name" yaml:"name"` - Version string `json:"version" yaml:"version"` - Description string `json:"description" yaml:"description"` - Capabilities PluginCapabilities `json:"capabilities" yaml:"capabilities"` - ModuleInfraRequirements PluginInfraRequirements `json:"moduleInfraRequirements,omitempty" yaml:"moduleInfraRequirements,omitempty"` + Name string `json:"name" yaml:"name"` + Version string `json:"version" yaml:"version"` + Description string `json:"description" yaml:"description"` + Capabilities PluginCapabilities `json:"capabilities" yaml:"capabilities"` + ModuleInfraRequirements PluginInfraRequirements `json:"moduleInfraRequirements,omitempty" yaml:"moduleInfraRequirements,omitempty"` + ModuleInfraRequirementsV2 PluginInfraRequirementsV2 `json:"moduleInfraRequirementsV2,omitempty" yaml:"moduleInfraRequirementsV2,omitempty"` } // PluginCapabilities describes what module, step, trigger types, build hooks, diff --git a/config/plugin_manifest_test.go b/config/plugin_manifest_test.go index 86929fe4..19e1dadd 100644 --- a/config/plugin_manifest_test.go +++ b/config/plugin_manifest_test.go @@ -159,3 +159,66 @@ func TestPluginManifestNoInfraRequirements(t *testing.T) { t.Errorf("expected nil ModuleInfraRequirements, got %v", manifest.ModuleInfraRequirements) } } + +func TestPluginManifestRequirementV2YAML(t *testing.T) { + raw := ` +name: workflow-plugin-observability +version: "0.1.2" +description: Observability plugin +capabilities: + moduleTypes: + - observability.telemetry + stepTypes: [] + triggerTypes: [] +moduleInfraRequirementsV2: + observability.telemetry: + requires: + - key: observability.telemetry.default + kind: observability + source: observability.telemetry + resourceTypeHint: infra.container_service + environment: production + runtimes: + - kubernetes + - digitalocean_app_platform + telemetrySignals: + - traces + - metrics + - logs + observabilityBackends: + - otel + - datadog + deploymentModes: + - sidecar + - sibling_service + vendorFeatures: + - datadog.apm + parameters: + collector: otel +` + + var manifest PluginManifestFile + if err := yaml.Unmarshal([]byte(raw), &manifest); err != nil { + t.Fatalf("unmarshal YAML: %v", err) + } + spec := manifest.ModuleInfraRequirementsV2["observability.telemetry"] + if spec == nil { + t.Fatal("expected observability.telemetry v2 infra requirements") + } + if len(spec.Requires) != 1 { + t.Fatalf("Requires len = %d, want 1", len(spec.Requires)) + } + req := spec.Requires[0] + if req.Key != "observability.telemetry.default" { + t.Fatalf("Key = %q", req.Key) + } + if req.Kind != "observability" { + t.Fatalf("Kind = %q", req.Kind) + } + if len(req.TelemetrySignals) != 3 { + t.Fatalf("TelemetrySignals = %v", req.TelemetrySignals) + } + if req.Parameters["collector"] != "otel" { + t.Fatalf("Parameters = %v", req.Parameters) + } +} diff --git a/decisions/0043-iac-derived-requirements.md b/decisions/0043-iac-derived-requirements.md new file mode 100644 index 00000000..06671fa0 --- /dev/null +++ b/decisions/0043-iac-derived-requirements.md @@ -0,0 +1,43 @@ +# 0043. Derive IaC Through Provider Requirements + +**Status:** Accepted +**Date:** 2026-05-25 +**Decision-makers:** Workflow maintainers, autonomous pipeline +**Related:** `docs/plans/2026-05-25-iac-derived-requirements-design.md` + +## Context + +Workflow needs to derive infrastructure for higher-level application and +observability declarations without hard-coding DigitalOcean, AWS, GCP, Azure, +Datadog, Grafana, Prometheus, or Loki behavior in core. Existing +`moduleInfraRequirements` is useful but static and manifest-only. Existing IaC +provider plugins already expose strict typed gRPC services, with optional +services advertised by registration. The user also requires explicit YAML keys +for user-provided overrides and strict proto compatibility where possible, +which means portable requirement concepts should use proto enums rather than a +stringly typed vocabulary. + +## Decision + +We will add a core requirement model and `wfctl infra derive`, but provider +plugins will own requirement-to-resource mapping through an optional strict-proto +IaC service. Portable requirement fields will be proto enums; JSON bytes and +namespaced string vendor features are allowed only for provider/product +extension data that cannot be modeled generically. Generated modules will +include `satisfies` keys, and manually written modules can use the same keys to +suppress derivation. We reject a provider-specific CLI plugin command because +YAML mutation and cross-provider plugin discovery belong in `wfctl` core. We +reject apply-time derivation because it hides generated infrastructure from +review and CI. We reject core-owned provider mapping because it would recreate +provider-specific assumptions in the framework. + +## Consequences + +Derivation becomes reviewable, idempotent, and reusable for observability, web +apps, message brokers, databases, caches, and storage. Provider plugins gain a +small but real new compatibility surface and must test their mappings. Workflow +core must maintain a YAML node editor, a stable requirement proto, and secret +safety checks for generated specs. The editor must preserve `modules[].satisfies` +before generated YAML can safely round-trip visually. Older provider plugins keep +working for explicit `infra.*` YAML but cannot derive resources until they +implement the optional mapper service. diff --git a/docs/plans/2026-05-25-iac-derived-requirements-design.adversarial-review-1.md b/docs/plans/2026-05-25-iac-derived-requirements-design.adversarial-review-1.md new file mode 100644 index 00000000..f9f582f8 --- /dev/null +++ b/docs/plans/2026-05-25-iac-derived-requirements-design.adversarial-review-1.md @@ -0,0 +1,86 @@ +### Adversarial Review Report + +**Phase:** design +**Artifact:** `docs/plans/2026-05-25-iac-derived-requirements-design.md` +**Status:** FAIL + +**Findings (Critical):** +- None. + +**Findings (Important):** +- [Repo-precedent conflicts / strict proto] `Requirement Model` lines 124-138: + the design says `kind`, `runtime`, and `features` are strings, even though the + user explicitly asked to be strict-proto compatible where possible and the IaC + proto already uses enums for wire-stable concepts such as drift class. A + string vocabulary is easy to typo and hard for provider plugins to validate + compatibly. Recommendation: make category, signal, backend, deployment mode, + and runtime typed proto enums; reserve repeated string extensions only for + vendor-specific features with a documented non-strict reason. +- [Missing failure modes] `wfctl infra derive` lines 220-229: config loading + resolves imports, but YAML mutation edits one file. If a requirement comes + from an imported module, the design does not say whether generated modules go + to the root file, the source file, or a new derived file. This can corrupt + ownership boundaries in multi-file configs. Recommendation: define v1 as + root-file expansion only, with `source` diagnostics and an explicit future + `--target-file`; tests must cover imported configs. +- [User-intent drift / plugin interface] `Requirement Sources` lines 191-206: + dynamic plugin-side requirement providers are deferred to the future, but the + user's Go-interface analogy asks for plugins/modules/steps to satisfy an + interface without hard dependency. Static manifest requirements are not enough + for config-driven observability backends. Recommendation: include a v1 + lightweight Go interface for in-process providers and a strict-proto + external-plugin service, even if the first implementation supports static + manifests too. +- [Security/privacy] `Provider Mapping Service` lines 174-180: provider + mappers return concrete `ResourceSpec` configs, but there is no rule + preventing secret material from being written into YAML. Observability and + Datadog configs frequently involve API keys. Recommendation: require mappers + to emit only secret references or `secrets.generate` requirements; `wfctl` + rejects generated specs containing known secret-looking plaintext values. +- [Repo-precedent conflicts / editor preservation] `Satisfaction Keys` lines + 146-162: adding top-level `modules[].satisfies` to Go config is not enough. + `workflow-editor`'s `ModuleConfig` type does not include that field, and its + `js-yaml` round-trip reconstructs module objects. Editing generated YAML in + the editor can silently drop satisfaction keys. Recommendation: include + workflow-editor type/serialization preservation in the plan or explicitly + block editor round-trip support until it lands. + +**Findings (Minor):** +- [Missing failure modes] `wfctl infra derive` lines 212-216: provider and + runtime are passed as flags, but existing configs already declare + `iac.provider` modules and per-resource `iac_provider`/`provider` refs. + Recommendation: define precedence: explicit flag, then env-specific + provider, then single configured provider, else ambiguity error. +- [YAGNI] `Requirement Model` lines 129-136: modeling every runtime and backend + in the core design risks expanding before the first implementation proves the + shape. Recommendation: enumerate only the required observability/runtime + constants for v1 and keep vendor extension fields for provider plugins. + +**Bug-class scan transcript:** + +| Class | Result | Note | +|---|---|---| +| Unstated assumptions | Finding | The design assumes root-file YAML writes are acceptable after imported config resolution. | +| Repo-precedent conflicts | Finding | The string feature vocabulary conflicts with `plugin/external/proto/iac.proto`'s strict typed-service precedent. | +| YAGNI violations | Finding | The design risks over-modeling future backends/runtimes before the first provider mapper exists. | +| Missing failure modes | Finding | Multi-file imports, provider-precedence ambiguity, and generated secret handling need explicit behavior. | +| Security / privacy | Finding | Provider-generated ResourceSpecs may accidentally write API keys or tokens into YAML. | +| Rollback story | Clean | The rollback section covers CLI, proto, YAML schema, and provider mapper rollback. | +| Simpler alternative not considered | Clean | Static manifest-only scaffolding and apply-time derivation were considered and rejected. | +| User-intent drift | Finding | Deferring the plugin/module interface weakens the user's stated composability requirement. | + +**Options the author may not have considered:** + +1. Root-only generated overlay file: instead of mutating the main config, always + write `workflow.derived.yaml` and add it to `imports:`. This improves review + isolation but requires import-order guarantees and may be surprising when a + user expected in-place expansion. +2. Manifest-v2 first, mapper service later: ship a smaller static-only scaffold + and defer provider RPCs. This is simpler, but it fails the runtime-specific + sidecar/daemonset/ECS/DO mapping requirement and would likely be reworked. + +**Verdict reasoning:** The design direction is sound, but the strict-proto, +multi-file, secret-safety, and plugin-interface gaps are important enough to fix +before writing an implementation plan. No critical flaw requires abandoning the +approach. + diff --git a/docs/plans/2026-05-25-iac-derived-requirements-design.adversarial-review-2.md b/docs/plans/2026-05-25-iac-derived-requirements-design.adversarial-review-2.md new file mode 100644 index 00000000..ccebfed0 --- /dev/null +++ b/docs/plans/2026-05-25-iac-derived-requirements-design.adversarial-review-2.md @@ -0,0 +1,48 @@ +### Adversarial Review Report + +**Phase:** design +**Artifact:** `docs/plans/2026-05-25-iac-derived-requirements-design.md` +**Status:** PASS + +**Findings (Critical):** +- None. + +**Findings (Important):** +- None. + +**Findings (Minor):** +- [YAGNI / wording] `Self-Challenge`: after cycle-1 fixes, the self-challenge + still referred to "features are strings". Recommendation: update the wording + to match the revised enum-first requirement model. Status: fixed before this + report was committed. + +**Bug-class scan transcript:** + +| Class | Result | Note | +|---|---|---| +| Unstated assumptions | Clean | The remaining load-bearing assumptions are explicit, including root-file expansion and no live cloud calls during mapping. | +| Repo-precedent conflicts | Clean | The design now follows `plugin/external/proto/iac.proto`'s strict typed optional-service precedent and avoids `Struct` / `Any`. | +| YAGNI violations | Clean | The feature set traces to the user's stated observability/provider/IaC requirements; vendor extension strings limit enum sprawl. | +| Missing failure modes | Clean | Multi-file imports, provider ambiguity, secret leakage, YAML corruption, and unsupported provider services are now covered. | +| Security / privacy | Clean | The mapper output is constrained to secret references and `wfctl` rejects suspicious generated plaintext secrets. | +| Rollback story | Clean | Rollback covers CLI, proto/service, YAML schema, and provider mapper release rollback. | +| Simpler alternative not considered | Clean | Static manifest-only scaffolding, plugin CLI commands, and apply-time derivation were considered and rejected. | +| User-intent drift | Clean | The design now includes both CLI/IaC evaluation and plugin/module requirement-provider interfaces, matching the user's composability ask. | + +**Options the author may not have considered:** + +1. Require all provider mappers to return a plan summary only, and have core + build `ResourceSpec` locally. This would reduce provider write power but + would move provider-specific config shape back into core, conflicting with + the ownership goal. +2. Make `satisfies` live under `config:` to avoid adding a `ModuleConfig` field. + This preserves old parsers but pollutes provider config and risks provider + canonical-key warnings. The top-level field is cleaner if editor preservation + ships with it. + +**Verdict reasoning:** The revised design addresses the important cycle-1 +issues without changing the core architecture. The remaining risk is execution +discipline: the implementation plan must split core proto/YAML work, editor +preservation, observability declarations, and provider mapper rollout into +reviewable PRs with focused verification. + diff --git a/docs/plans/2026-05-25-iac-derived-requirements-design.md b/docs/plans/2026-05-25-iac-derived-requirements-design.md new file mode 100644 index 00000000..48c39e81 --- /dev/null +++ b/docs/plans/2026-05-25-iac-derived-requirements-design.md @@ -0,0 +1,442 @@ +# IaC Derived Requirements Design + +**Date:** 2026-05-25 +**Status:** Draft — revised after adversarial-review cycle 1 +**Owner:** autonomous pipeline +**Related:** `decisions/0043-iac-derived-requirements.md` + +## Problem + +Workflow configs increasingly describe application intent at a higher level than +the concrete infrastructure needed to run it. A user can declare an API app, a +NATS broker, or observability for OTel, Prometheus, Loki, Grafana, or Datadog, +but today the user or an agent still has to hand-write the matching `infra.*` +modules. That is error-prone and provider-specific. + +The target behavior is explicit and reviewable: + +1. Application and plugin declarations emit provider-neutral requirements. +2. IaC provider plugins map those requirements to provider/runtime-specific + `infra.*` modules. +3. `wfctl` expands the YAML before apply, so the resulting config is visible in + review and CI. +4. Users can satisfy a requirement manually by declaring a stable key in YAML; + `wfctl` must not guess by resource similarity. + +## Current Inventory + +- `config.PluginManifestFile.ModuleInfraRequirements` and + `cmd/wfctl/plugin_infra.go` already provide a static manifest-only dependency + detector. It is too weak for provider/runtime mapping, explicit satisfaction, + or observability variants. +- `cmd/wfctl/infra.go` plans and applies `infra.*` and `platform.*` modules + from the top-level `modules:` list. The old `infrastructure:` block is + preserved by config round-trips but is not the active provisioning path. +- IaC plugins already expose strict typed gRPC services through + `plugin/external/proto/iac.proto`. That proto explicitly avoids + `google.protobuf.Struct` and `Any`; provider-specific free-form payloads use + JSON bytes fields. +- `workflow-editor` uses `js-yaml` and preserves top-level ordering plus unknown + top-level keys, but it is not an AST-preserving comment-safe YAML mutator. + `wfctl` should use Go's existing `gopkg.in/yaml.v3` node API for targeted + edits instead of importing editor code. +- DigitalOcean, AWS, GCP, and Azure plugins all expose typed IaC capabilities + for common canonical resource types such as `infra.container_service`, + `infra.k8s_cluster`, `infra.database`, `infra.cache`, and `infra.storage`. + +## Goals + +1. Add a provider-neutral requirement model that can represent observability, + web/API apps, message brokers, databases, caches, storage, and future + support resources without provider names leaking into application config. +2. Add `wfctl infra derive` to calculate missing requirements and write the + expanded YAML before `infra plan` / `infra apply`. +3. Add deterministic explicit overrides through `modules[].satisfies`. +4. Add a strict-proto provider mapping surface so provider plugins can describe + how requirements map to their supported resource types. +5. Support observability choices across OTel first, plus Prometheus, Loki, + Grafana, and Datadog without baking those products into Workflow core + provider logic. +6. Keep the first implementation small: generate concrete modules and leave + provisioning to the existing IaC pipeline. + +## Non-Goals + +- Do not derive at apply time. `infra plan` and `infra apply` should consume the + already-expanded YAML. +- Do not infer that an arbitrary existing resource satisfies a requirement by + comparing config. Only explicit `satisfies` keys count. +- Do not build a full policy engine or Terraform-style expression language. +- Do not make Workflow core own AWS, GCP, Azure, DigitalOcean, Datadog, or + Grafana resource mapping rules. +- Do not commit application-specific names such as `cms_*` or `multisite_*` to + generic observability or IaC plugins. +- Do not require the visual editor to preserve every comment before this can + ship. The CLI owns YAML expansion; editor preservation improvements can follow. + +## Approaches Considered + +### Approach A: Core derivation engine, provider plugin mappers + +`wfctl` gathers requirements from workflow config, installed plugin metadata, +and optional plugin/provider typed services. It asks the selected IaC provider +plugin to map the unsatisfied requirements to concrete `infra.*` module +stubs, then writes those modules into YAML with `satisfies` keys. + +Pros: clear ownership boundary; works across DO/AWS/GCP/Azure; keeps provider +specifics out of core; produces reviewable YAML. Cons: adds a new provider +optional service and a YAML mutator. + +This is the recommended approach. + +### Approach B: Observability plugin directly writes provider YAML + +The observability plugin could expose a CLI command that edits config for OTel, +Datadog, Prometheus, Loki, and Grafana. + +Pros: fast for observability. Cons: repeats the same problem for NATS, web/API, +databases, caches, and provider runtimes; plugin CLI commands do not naturally +own cross-provider IaC mapping or core YAML ordering rules. + +Rejected. + +### Approach C: Derive inside `infra apply` + +`infra apply` could synthesize missing resources in memory just before planning. + +Pros: smallest command surface. Cons: hides generated infrastructure from review, +CI diffs, and agents; makes user overrides fuzzy; conflicts with the user's +explicit request for a YAML-expanding command. + +Rejected. + +## Design + +### Requirement Model + +Add a small Workflow-owned requirement model in `interfaces` or a new `iac/derive` +package, mirrored in `plugin/external/proto/iac.proto`. + +Core fields: + +- `key`: stable requirement identifier, for example + `observability.telemetry.default` or `messaging.nats.events`. +- `kind`: typed proto enum for the broad category, for example + `REQUIREMENT_KIND_OBSERVABILITY`, `REQUIREMENT_KIND_WEB_API`, + `REQUIREMENT_KIND_MESSAGE_BROKER`, `REQUIREMENT_KIND_DATABASE`, + `REQUIREMENT_KIND_CACHE`, and `REQUIREMENT_KIND_STORAGE`. +- `source`: module/service/plugin path that produced the requirement. +- `resource_type_hint`: optional canonical target such as + `infra.container_service`, `infra.k8s_cluster`, or `infra.database`. +- `environment`: optional target environment. +- `runtime`: optional typed proto enum such as `RUNTIME_KUBERNETES`, + `RUNTIME_ECS`, `RUNTIME_CLOUD_RUN`, `RUNTIME_AZURE_CONTAINER_APPS`, or + `RUNTIME_DO_APP_PLATFORM`. +- `signals`: repeated typed proto enum for telemetry signals: + `TELEMETRY_SIGNAL_TRACES`, `TELEMETRY_SIGNAL_METRICS`, and + `TELEMETRY_SIGNAL_LOGS`. +- `backends`: repeated typed proto enum for requested observability backends: + `OBSERVABILITY_BACKEND_OTEL`, `OBSERVABILITY_BACKEND_DATADOG`, + `OBSERVABILITY_BACKEND_PROMETHEUS`, `OBSERVABILITY_BACKEND_LOKI`, and + `OBSERVABILITY_BACKEND_GRAFANA`. +- `deployment_modes`: repeated typed proto enum for portable deployment shape: + `DEPLOYMENT_MODE_SIDECAR`, `DEPLOYMENT_MODE_DAEMONSET`, + `DEPLOYMENT_MODE_SIBLING_SERVICE`, and `DEPLOYMENT_MODE_MANAGED`. +- `vendor_features`: repeated strings for provider/product-specific extension + flags that do not justify a Workflow-owned enum. These are non-portable and + must be namespaced, for example `datadog.apm` or `grafana.datasource`. +- `parameters_json`: JSON bytes only for data that cannot be modeled + generically without provider or product leakage. + +`parameters_json` is a deliberate exception to pure scalar proto fields. It +follows the existing strict IaC proto pattern for provider-specific +`config_json` and avoids `Struct` / `Any`. The default is typed proto enums; +strings are allowed only for explicitly namespaced vendor extensions. + +### Satisfaction Keys + +Add `satisfies` to module config as a top-level field on `config.ModuleConfig`: + +```yaml +modules: + - name: app-telemetry + type: infra.container_service + satisfies: + - observability.telemetry.default + config: + image: otel/opentelemetry-collector-contrib:latest +``` + +The derivation engine considers a requirement satisfied when any module lists +that key. It does not inspect resource type, name, labels, sidecars, or provider +config to infer equivalence. + +Generated modules must include `satisfies` so repeated runs are idempotent. + +### Provider Mapping Service + +Add an optional strict-proto service to `plugin/external/proto/iac.proto`: + +```proto +service IaCProviderRequirementMapper { + rpc MapRequirements(MapRequirementsRequest) returns (MapRequirementsResponse); +} +``` + +The request contains typed requirement messages plus provider/runtime/environment +context. The response returns: + +- accepted requirement keys, +- rejected requirement diagnostics, +- concrete `ResourceSpec` messages to write as `modules:` entries, +- optional ordered notes for interactive display. + +Provider plugins register this service only when they support mapping. Absence +means the provider can still plan/apply explicit `infra.*` modules, but `wfctl +infra derive` cannot ask it to synthesize provider-specific modules. + +This matches the existing typed-IaC optional-service pattern: registration is +the capability signal, not a boolean flag or an unimplemented response field. + +### Requirement Sources + +Initial requirement sources: + +- Built-in config shape: web/API modules, `services:`, and common broker/cache + module types can produce neutral requirements. +- Plugin static declarations: evolve `moduleInfraRequirements` into a v2 shape + that can carry `key`, `kind`, telemetry signals, observability backends, + deployment modes, vendor features, and `resource_type_hint` while preserving + the existing v1 fields. +- Observability plugin declarations: `observability.telemetry` and + `observability.collector` declare observability requirements and supported + backends without application-specific names. + +Runtime/config-aware source: + +- Add a lightweight Go interface for in-process providers, for example + `IaCRequirementProvider`, that modules, steps, or plugin adapters can satisfy + without Workflow core depending on a concrete observability plugin package. +- Add an optional strict-proto external-plugin service for config-aware + requirement discovery. It returns the same typed requirement messages consumed + by the provider mapper. Absence of service registration means the plugin only + participates through static manifest declarations. +- The first observability implementation should use static declarations when + the module config is simple and the dynamic service when selected backends or + signal sets depend on module config. + +### `wfctl infra derive` + +Add: + +```sh +wfctl infra derive --config workflow.yaml --provider aws --env staging --runtime ecs --write +wfctl infra derive --config workflow.yaml --provider digitalocean --env prod --runtime do_app_platform --dry-run --format yaml +wfctl infra derive --config workflow.yaml --provider gcp --env prod --non-interactive --write +``` + +Behavior: + +1. Load the workflow YAML as `yaml.Node`. +2. Load the semantic config through `config.LoadFromFile`. +3. Gather requirements. +4. Remove requirements already listed by `modules[].satisfies`. +5. Resolve provider plugin and optional mapper service. +6. In interactive TTY mode, prompt only for ambiguous provider/runtime choices. +7. In non-interactive mode, fail on ambiguity with a deterministic diagnostic. +8. Insert generated modules into `modules:` while preserving existing order, + comments, unknown top-level keys, and unknown module keys where `yaml.v3` + can retain them. +9. Print a summary of added and already-satisfied requirement keys. + +`--dry-run` prints the expanded YAML or a JSON summary without writing. `--write` +updates the file atomically. A later `--output` can write to a separate path. + +Provider/runtime precedence: + +1. Explicit `--provider` and `--runtime` flags. +2. Environment-specific provider hints already present in config. +3. A single unambiguous `iac.provider` module. +4. Otherwise an ambiguity diagnostic in non-interactive mode or a prompt in TTY + mode. + +Multi-file behavior for v1: + +- `config.LoadFromFile` still resolves imports to gather requirements. +- `wfctl infra derive --write` mutates only the root `--config` file. +- Generated modules are written to the root file even when the source + requirement came from an imported file. The summary must include the source + path so the user can move the generated module manually if desired. +- A future `--target-file` can direct generated modules into a specific imported + file, but v1 does not guess ownership. + +### Observability Mapping + +The observability plugin remains generic. Applications choose names and backends +in their own YAML. The requirement features describe intent: + +- OTel collector: `backend.otel`, selected signals, deployment mode. +- Prometheus: prefer OTel metrics exporter or scrape config when possible. +- Loki: prefer OTel logs exporter when possible. +- Grafana: dashboards/datasource requirements only when a provider plugin + supports them; otherwise diagnostics explain the manual external setup. +- Datadog: prefer OTel exporter to Datadog. Direct Datadog agent sidecar or + service is supported when the requirement asks for `backend.datadog` and the + provider mapper has a runtime-specific mapping. + +Examples: + +- Kubernetes provider mapper may produce an OTel Collector deployment/daemonset + and Prometheus/Loki exporter config. +- ECS provider mapper may produce Datadog agent sidecar definitions or an OTel + collector sidecar depending on selected backend. +- DigitalOcean App Platform mapper may produce sibling service components + because its driver already models "sidecars" as sibling services. + +Secret handling: + +- Requirement mappers must not return plaintext API keys, tokens, connection + strings, or private keys in generated `ResourceSpec.Config`. +- Generated specs may reference secrets through `${SECRET_NAME}` placeholders + or add separate secret-generation/secret-requirement declarations. +- `wfctl infra derive` rejects generated YAML when provider output includes + suspicious plaintext secret-looking keys such as `api_key`, `token`, + `password`, `private_key`, or `secret` unless the value is a placeholder. +- Observability examples that need Datadog, Grafana, Prometheus remote-write, or + Loki credentials must generate secret references, not values. + +### YAML Mutation + +Use `gopkg.in/yaml.v3` node editing in a new small package, for example +`config/yamledit` or `iac/yamledit`. + +Rules: + +- Keep the original document root and mapping order. +- Create `modules:` if missing. +- Append generated modules after the last existing `infra.*` module; if no + `infra.*` module exists, append at the end of `modules:`. +- Preserve comments and unknown keys by editing nodes rather than unmarshalling + and re-marshalling the full config struct. +- Do not try to preserve comments inside newly generated nodes beyond a concise + generated block comment. +- Add golden tests with comments, anchors, unknown top-level keys, unknown module + keys, empty `modules:`, and repeated derive runs. + +The editor's `js-yaml` ordering behavior is precedent only. It is not sufficient +for CLI mutation because it does not retain comments. + +Editor preservation: + +- Add `satisfies?: string[]` to `workflow-editor`'s `ModuleConfig` type and + serialization path in the same implementation plan or a prerequisite PR. +- Until that lands, `wfctl infra derive` should warn when it detects a project + workflow-editor version below the first version that preserves `satisfies`. +- Editor support is preservation-only for v1; the visual UI does not need to + author derived requirements before the CLI command ships. + +### CLI Plugin Evaluation + +This should not be implemented as a CLI plugin. A provider or observability +plugin can add convenience commands later, but the derivation command needs +first-class access to config loading, plugin discovery, typed IaC provider +handles, and atomic YAML writes. Those are core `wfctl` responsibilities. + +CLI plugin functionality is still useful for provider-specific diagnostics +after derivation, for example `datadog verify` or `grafana datasource test`, but +not for the generic derivation engine. + +### IaC Plugin Evaluation + +IaC plugin functionality is the right extension point for mapping. Core can +define the neutral requirement model and command behavior; provider plugins own +the translation from requirements to `ResourceSpec` for Kubernetes, ECS, Cloud +Run, Azure Container Apps, DigitalOcean App Platform, and future runtimes. + +This also creates a reusable pattern for non-observability cases: + +- web/API app declaration -> `infra.container_service`, ingress, registry, + certificate, DNS as supported by the provider. +- NATS declaration -> managed broker, Kubernetes workload, ECS sidecar, or + explicit unsupported diagnostic. +- database/cache/storage declaration -> provider-managed resource or local + container for development. + +## Backwards Compatibility + +- Existing configs continue to plan/apply. `satisfies` is optional. +- Existing provider plugins continue to work; only plugins implementing the new + optional mapper service participate in derivation. +- Existing `moduleInfraRequirements` entries remain valid. The v2 fields are + additive. +- `infra plan` and `infra apply` do not auto-derive. + +## Assumptions + +1. `modules:` remains the canonical place for provisioned `infra.*` resources. +2. Provider plugins can map at least common observability and app requirements + without needing live cloud API calls. +3. The strict-proto IaC optional-service pattern is acceptable for another + optional provider capability. +4. `yaml.v3` node mutation can preserve enough source fidelity for safe + machine edits. Tests will define the exact guarantee. +5. Interactive ambiguity is limited to provider/runtime/backend choices; if this + becomes wider, the design should stop and add a richer planning report rather + than more prompts. +6. Root-file expansion is acceptable for v1 multi-file configs as long as the + command reports the source path for each generated requirement and remains + idempotent. + +## Rollback + +This affects CLI behavior, plugin contracts, YAML config schema, and provider +plugin loading paths. + +- Core command rollback: revert the `wfctl infra derive` PR. Existing expanded + YAML remains valid because generated resources are normal `infra.*` modules. +- Proto/service rollback: because the provider mapper is optional, reverting + the host support leaves existing provider plugins usable for plan/apply. + Plugins that already implemented the mapper must pin the workflow version that + includes it. +- YAML field rollback: `satisfies` is additive. Older engines ignore the field + once generated YAML contains concrete modules. +- Provider mapper rollback: release a provider patch that stops advertising the + optional service; `wfctl infra derive` will emit an unsupported-provider + diagnostic instead of generating modules. + +## Self-Challenge + +1. Laziest plausible solution: extend `moduleInfraRequirements` and add a + scaffold command with no provider plugin RPC. This fails the cross-provider + runtime mapping requirement and would bake provider choices into core. +2. Fragile assumption: provider mapping does not need live cloud calls. If false, + the mapper RPC must accept credentials/config and may become slow. The first + implementation should fail if a mapper tries to perform apply-like work. +3. YAGNI risk: modeling every observability backend upfront could get heavy. + Mitigation: v1 defines enums only for the required OTel, Datadog, + Prometheus, Loki, and Grafana path, and provider plugins can reject + unsupported combinations. +4. Partial failure: YAML write corruption would be the highest-impact bug. + Mitigation: parse as `yaml.Node`, write atomically, and add golden/idempotence + tests before implementation. +5. Repo precedent conflict: current IaC proto avoids `Struct`/`Any`. This design + follows that precedent with typed proto enums for portable concepts; only + provider-specific free-form fields use JSON bytes, matching existing + `ResourceSpec.config_json`. + +## Adversarial Review Resolution + +Cycle 1 report: +`docs/plans/2026-05-25-iac-derived-requirements-design.adversarial-review-1.md`. + +Resolved changes: + +- Replaced stringly typed `kind`, `runtime`, and observability `features` with + proto enum fields; kept namespaced strings only for vendor extensions. +- Defined v1 multi-file behavior as root-file expansion with source diagnostics. +- Promoted plugin/module requirement providers into v1 via a Go interface plus + optional strict-proto external-plugin service. +- Added secret-output rules and `wfctl` rejection behavior for generated + plaintext secrets. +- Added workflow-editor preservation work for `modules[].satisfies`. +- Added provider/runtime precedence rules. diff --git a/docs/plans/2026-05-25-iac-derived-requirements.adversarial-review-1.md b/docs/plans/2026-05-25-iac-derived-requirements.adversarial-review-1.md new file mode 100644 index 00000000..76aa4453 --- /dev/null +++ b/docs/plans/2026-05-25-iac-derived-requirements.adversarial-review-1.md @@ -0,0 +1,41 @@ +### Adversarial Review Report + +**Phase:** plan +**Artifact:** `docs/plans/2026-05-25-iac-derived-requirements.md` +**Status:** FAIL + +**Findings (Critical):** +- [under-decomposition / hidden serial dependencies] `docs/plans/2026-05-25-iac-derived-requirements.md:17-36,717-787`: The scope manifest claims 5 PRs, but PR 5 spans four provider repositories and Task 10 also includes workflow release, provider version bumps, observability version bumps, and consumer app edits. That is not one independently reviewable PR and it will confuse scope-lock and execution. Recommendation: split PR grouping by repository and make release/version-bump work explicit follow-up PRs/tasks. + +**Findings (Important):** +- [user-intent drift / missing failure mode] `docs/plans/2026-05-25-iac-derived-requirements.md:299-355` vs `docs/plans/2026-05-25-iac-derived-requirements-design.md:215-226`: The design includes optional strict-proto external-plugin requirement discovery for config-aware plugins, but the plan only implements an in-process Go interface and static manifest v2. That misses the composable plugin requirement path the user asked for. Recommendation: add a task for `IaCRequirementDiscovery` proto service, SDK registration, contract tests, and wfctl collection. +- [design drift] `docs/plans/2026-05-25-iac-derived-requirements.md:142-170` vs `docs/plans/2026-05-25-iac-derived-requirements-design.md:122-149,186-192`: The plan's proto sketch drops `source`, `resource_type_hint`, `environment`, accepted/rejected diagnostics, and ordered notes that the design says are part of the typed exchange. It replaces rejected diagnostics with plain warnings. Recommendation: model these as strict proto fields/messages unless a specific field has a documented reason to defer. +- [verification-class mismatch] `docs/plans/2026-05-25-iac-derived-requirements.md:536-550`: The Workflow CLI representative invocation uses `--provider digitalocean` before provider plugins implement the mapper. This can fail for reasons unrelated to Workflow CLI correctness. Recommendation: verify Workflow CLI with a fake/in-process mapper fixture first, then add provider-backed smoke tests only after provider mapper PRs. +- [missing rollback wiring / hidden dependencies] `docs/plans/2026-05-25-iac-derived-requirements.md:789-840`: Task 10 says to merge, tag, bump plugin minimums, remove consumer `/metrics` reliance, and commit separately per repo, but it is assigned to the provider mapper PR. This mixes release operations with code changes and has no clear rollback for a partially released Workflow tag. Recommendation: split release, plugin min-version bumps, and consumer migrations into separate tasks with explicit prereqs and no shared PR row. + +**Findings (Minor):** +- [repo-precedent conflict] `docs/plans/2026-05-25-iac-derived-requirements.md:597-618`: The editor test command is guessed as `npm test -- serialization.satisfies`; the plan should inspect the repo's package scripts and use the exact Vitest/Jest command. Recommendation: add an exploration step or replace with the verified command after checking `package.json`. +- [verification gap] `docs/plans/2026-05-25-iac-derived-requirements.md:180-188`: The proto generation step uses `go run github.com/bufbuild/buf/cmd/buf@latest`, which is convenient but not pinned. Recommendation: either use existing repo release conventions for Buf or document that this is a tool invocation only and verify generated headers/CI with committed output. + +**Bug-class scan transcript:** + +| Class | Result | Note | +|---|---|---| +| Unstated assumptions | Finding | Assumes provider plugins can be updated and released inside one PR row despite living in separate repos. | +| Repo-precedent conflicts | Finding | The plan's PR manifest is repo-local, but several tasks are cross-repo operations that cannot share one branch/PR. | +| YAGNI violations | Clean | The explicit derive command and provider mapper are justified by the user ask and prior design. | +| Missing failure modes | Finding | Partial release/version-bump failure is not decomposed or rollback-safe. | +| Security / privacy at architecture level | Clean | Secret handling is explicitly tested and rejects plaintext secret-like generated config. | +| Rollback story | Finding | Rollback notes exist per task, but the release/version-bump task has no safe rollback sequence for partially published tags. | +| Simpler alternative not considered | Clean | Manifest-only and apply-time derivation were considered and rejected in the design. | +| User-intent drift | Finding | Missing external-plugin requirement discovery weakens the Go-interface-without-hard-dependency requirement for out-of-process plugins. | +| Over-decomposition / under-decomposition | Finding | Provider and release work is under-decomposed across repos. | +| Verification-class mismatch | Finding | Workflow CLI smoke depends on provider plugin behavior before provider mapper implementation exists. | +| Hidden serial dependencies | Finding | Observability/plugin/provider tasks depend on the Workflow release tag but are grouped as if one PR can contain them. | +| Missing rollback wiring | Finding | Release and consumer migration rollback are not executable steps. | + +**Options the author may not have considered:** +1. Split Workflow into two PRs, editor into one PR, observability into one PR, each provider into its own PR, then one release/version-bump wave. This increases PR count but matches actual repository boundaries and keeps failures revertible. +2. Implement only Workflow core plus a fake mapper in the first wave, then release provider mappers incrementally. This makes `wfctl infra derive` testable without blocking on every provider, but it delays real cross-cloud proof until follow-up PRs. + +**Verdict reasoning:** The design direction is still sound, but the implementation plan is not executable as written. The largest issue is the scope manifest: it describes one provider PR and one release task where the work actually crosses at least six repositories plus consumer migrations. The strict-proto surface also regressed from the design by omitting dynamic external-plugin requirement discovery and typed mapper diagnostics. Revise the plan before alignment-check or execution. diff --git a/docs/plans/2026-05-25-iac-derived-requirements.adversarial-review-2.md b/docs/plans/2026-05-25-iac-derived-requirements.adversarial-review-2.md new file mode 100644 index 00000000..3829d0dc --- /dev/null +++ b/docs/plans/2026-05-25-iac-derived-requirements.adversarial-review-2.md @@ -0,0 +1,37 @@ +### Adversarial Review Report + +**Phase:** plan +**Artifact:** `docs/plans/2026-05-25-iac-derived-requirements.md` +**Status:** PASS + +**Findings (Critical):** +- None. + +**Findings (Important):** +- None. + +**Findings (Minor):** +- [rollback story] `docs/plans/2026-05-25-iac-derived-requirements.md:989-1014`: Release and app migration steps are operational gates outside the scope manifest. That is acceptable because they are not `### Task` items and each app migration is explicitly a separate app-repo PR, but execution must not treat them as part of the eight locked implementation PRs. + +**Bug-class scan transcript:** + +| Class | Result | Note | +|---|---|---| +| Unstated assumptions | Clean | Provider plugin work is now split by repository, and the release dependency is explicit. | +| Repo-precedent conflicts | Clean | Proto generation uses the repo's documented `buf generate` path, and CLI/editor test commands match local conventions. | +| YAGNI violations | Clean | The plan keeps derivation explicit, does not add apply-time magic, and avoids policy-engine scope. | +| Missing failure modes | Clean | Provider ambiguity, unsupported runtimes, duplicate generation, malformed mapper output, and partial release failure all have test or rollback coverage. | +| Security / privacy at architecture level | Clean | Discovery requests use typed redacted context plus module-owned config bytes and explicitly forbid full Workflow YAML or resolved secrets. | +| Rollback story | Clean | Each runtime/plugin-loading task has a rollback note; release/app migration rollback is covered separately. | +| Simpler alternative not considered | Clean | Manifest-only and apply-time derivation were considered in the design and remain rejected for stated reasons. | +| User-intent drift | Clean | Strict proto, selectable providers/backends, no generic plugin app names, and external plugin requirement discovery are represented. | +| Over-decomposition / under-decomposition | Clean | Workflow, editor, observability, and each provider plugin now have separate reviewable PR slices. | +| Verification-class mismatch | Clean | Workflow CLI verification uses a fake mapper fixture; provider-backed smoke is delayed until provider mapper releases. | +| Hidden serial dependencies | Clean | Workflow release is called out as a gate before observability/provider min-version bumps. | +| Missing rollback wiring | Clean | Provider and plugin rollbacks are per-repo; app migrations are separate PRs with per-app revert. | + +**Options the author may not have considered:** +1. Ship only Workflow core plus DigitalOcean initially, leaving AWS/GCP/Azure mapper tasks queued. This would reduce first-wave effort but would contradict the user's request that the shape not be DO-limited. +2. Put provider conformance fixtures in Workflow core as golden JSON contracts shared by plugin repos. This could reduce duplicated tests later, but it adds cross-repo fixture versioning now; per-provider local tests are simpler for the first implementation. + +**Verdict reasoning:** The revision resolves the execution blockers from cycle 1. The scope manifest now matches real repository boundaries, strict proto includes both mapping and config-aware discovery services, the discovery payload is not over-broad, and the Workflow CLI can be verified without depending on unreleased provider plugins. Remaining release and app-migration work is explicitly operational and separated from the locked PR tasks. diff --git a/docs/plans/2026-05-25-iac-derived-requirements.alignment-check-1.md b/docs/plans/2026-05-25-iac-derived-requirements.alignment-check-1.md new file mode 100644 index 00000000..52750ffa --- /dev/null +++ b/docs/plans/2026-05-25-iac-derived-requirements.alignment-check-1.md @@ -0,0 +1,59 @@ +### Alignment Report + +**Status:** PASS + +**Coverage:** + +| Design Requirement | Plan Task(s) | Status | +|---|---|---| +| Provider-neutral requirements for observability, web/API, brokers, databases, caches, and storage | Task 1, Task 2, Task 3 | Covered | +| `wfctl infra derive` calculates missing requirements and writes expanded YAML before plan/apply | Task 4, Task 5, Task 6 | Covered | +| Deterministic explicit overrides through `modules[].satisfies` | Task 2, Task 4, Task 5, Task 6, Task 7 | Covered | +| Strict-proto provider mapping surface for provider plugins | Task 1, Task 5, Task 9, Task 10, Task 11, Task 12 | Covered | +| Support OTel first, plus Prometheus, Loki, Grafana, and Datadog without Workflow core provider logic | Task 8, Task 9, Task 10, Task 11, Task 12 | Covered | +| Generate concrete `infra.*` modules and leave provisioning to existing IaC pipeline | Task 4, Task 5, Task 6 | Covered | +| No apply-time derivation | Task 6 and out-of-scope manifest | Covered | +| No heuristic existing-resource matching; only `satisfies` keys count | Task 2, Task 4, Task 5, Task 6 | Covered | +| Do not make Workflow core own provider mapping rules | Task 9, Task 10, Task 11, Task 12 | Covered | +| Do not commit app-specific names such as `cms_*` or `multisite_*` to generic plugins | Task 8 and release/migration sequence | Covered | +| Typed requirement fields, enums, vendor extension strings, and JSON bytes only for justified payload exceptions | Task 1, Task 2 | Covered | +| Config-aware requirement discovery through Go interface plus optional strict-proto external-plugin service | Task 1, Task 3, Task 8 | Covered | +| Provider/runtime precedence and non-interactive ambiguity diagnostics | Task 5, Task 6 | Covered | +| Multi-file v1 behavior mutates only the root `--config` file | Task 6 | Covered | +| Observability mapping preferences for OTel, Prometheus, Loki, Grafana, and Datadog | Task 8, Task 9, Task 10, Task 11, Task 12 | Covered | +| Secret placeholders only; reject plaintext secret-looking generated config | Task 5, Task 8, Task 9, Task 10, Task 11, Task 12 | Covered | +| YAML mutation via `gopkg.in/yaml.v3`, preserving order/comments/unknown keys where possible | Task 4, Task 6 | Covered | +| workflow-editor preserves `modules[].satisfies` | Task 7 | Covered | +| Do not implement derivation as a CLI plugin; use IaC provider plugins for mapping | Task 5, Task 6, Task 9, Task 10, Task 11, Task 12 | Covered | +| Backwards compatibility: existing configs/plugins still work and v1 manifest remains valid | Task 2, Task 3, Task 6 | Covered | +| Rollback paths for CLI, proto/service, YAML field, and provider mapper changes | Per-task rollback notes and release/migration sequence | Covered | + +**Scope Check:** + +| Plan Task | Design Requirement | Status | +|---|---|---| +| Task 1 | Strict-proto requirement/discovery/mapping services and contract registry | Justified | +| Task 2 | Local model, `satisfies`, manifest v2, backwards-compatible manifest parsing | Justified | +| Task 3 | Built-in, manifest, Go-interface, and external-plugin requirement discovery | Justified | +| Task 4 | Safe YAML node mutation and idempotent generated module insertion | Justified | +| Task 5 | Derivation engine, provider/runtime resolution, mapper diagnostics, secret rejection | Justified | +| Task 6 | `wfctl infra derive` CLI behavior, dry-run/write semantics, multi-file root mutation | Justified | +| Task 7 | workflow-editor preservation for `satisfies` | Justified | +| Task 8 | Observability plugin generic requirement emission and backend support | Justified | +| Task 9 | DigitalOcean provider-owned mapping | Justified | +| Task 10 | AWS provider-owned mapping | Justified | +| Task 11 | GCP provider-owned mapping | Justified | +| Task 12 | Azure provider-owned mapping | Justified | + +**Manifest Trace:** + +| Check | Status | +|---|---| +| `## Scope Manifest` exists | PASS | +| PR count matches PR grouping rows | PASS: 8 rows for `PR Count: 8` | +| Task count matches `### Task N` headings | PASS: 12 headings for `Tasks: 12` | +| Every PR row references existing task IDs | PASS | +| Every task appears in exactly one PR row | PASS | +| `tests/plan-scope-check.sh --plan ...` | Not present in this repository; manifest checked manually using the same invariants | + +**Drift Items:** None. diff --git a/docs/plans/2026-05-25-iac-derived-requirements.md b/docs/plans/2026-05-25-iac-derived-requirements.md new file mode 100644 index 00000000..2a98b316 --- /dev/null +++ b/docs/plans/2026-05-25-iac-derived-requirements.md @@ -0,0 +1,1049 @@ +# IaC Derived Requirements Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Add a lightweight, strict-proto-compatible path for `wfctl` to derive IaC YAML from application and plugin requirements, starting with observability and leaving room for web/api, brokers, databases, caches, and storage. + +**Architecture:** Workflow core owns requirement discovery, explicit satisfaction keys, YAML mutation, and the `wfctl infra derive` command. IaC provider plugins own provider/runtime mapping through a generated protobuf service, so DigitalOcean, AWS, GCP, Azure, and future providers can map the same canonical requirements differently without putting provider assumptions into `wfctl`. + +**Tech Stack:** Go, `gopkg.in/yaml.v3`, existing Workflow config loader, existing external-plugin gRPC/protobuf stack generated by `buf generate`, workflow-editor TypeScript serialization. + +**Base branch:** `main` + +--- + +## Scope Manifest + +**PR Count:** 8 +**Tasks:** 12 +**Estimated Lines of Change:** ~4600 + +**Out of scope:** +- Auto-applying derived IaC at `wfctl infra apply` time; derivation is explicit through `wfctl infra derive`. +- Heuristic comparison of existing IaC resources; explicit `modules[].satisfies` is the only v1 override/satisfaction mechanism. +- Provider-specific dashboard, alert, or monitor creation beyond canonical resource requirements needed to deploy telemetry collection. +- A full workflow-editor comment-preserving YAML rewrite. The editor task only preserves the new `satisfies` field through its existing parse/serialize model. +- Retrofitting every existing `workflow-plugin-*` repo in this plan. Observability plus provider mapper support are the release-blocking targets. + +**PR Grouping:** + +| PR # | Title | Tasks | Branch | +|------|-------|-------|--------| +| 1 | Add typed IaC requirement protocol | Task 1, Task 2, Task 3 | `feat/iac-requirement-proto` | +| 2 | Add derivation engine and YAML editing | Task 4, Task 5, Task 6 | `feat/iac-derive-engine` | +| 3 | Preserve `satisfies` in workflow-editor | Task 7 | `feat/editor-preserve-satisfies` | +| 4 | Emit observability requirements | Task 8 | `feat/observability-iac-requirements` | +| 5 | Map derived requirements in workflow-plugin-digitalocean | Task 9 | `feat/iac-requirement-mapper` | +| 6 | Map derived requirements in workflow-plugin-aws | Task 10 | `feat/iac-requirement-mapper` | +| 7 | Map derived requirements in workflow-plugin-gcp | Task 11 | `feat/iac-requirement-mapper` | +| 8 | Map derived requirements in workflow-plugin-azure | Task 12 | `feat/iac-requirement-mapper` | + +**Status:** Locked 2026-05-25T04:16:44Z + +## Design Inputs + +- Design: `docs/plans/2026-05-25-iac-derived-requirements-design.md` +- ADR: `decisions/0043-iac-derived-requirements.md` +- Design review reports: + - `docs/plans/2026-05-25-iac-derived-requirements-design.adversarial-review-1.md` + - `docs/plans/2026-05-25-iac-derived-requirements-design.adversarial-review-2.md` + +## Cross-Cutting Invariants + +- Strict protobuf compatibility is the default. New cross-plugin messages, services, and contracts must be concrete protobuf types/enums. Do not introduce `google.protobuf.Struct`, `Any`, or `map` equivalents. +- JSON byte fields are allowed only for provider-specific payloads that cannot be modeled generically yet, following the existing `config_json` precedent in `plugin/external/proto/iac.proto`. Every such field must have a comment explaining why it is not a proto field. +- `modules[].satisfies` values are stable requirement keys, not display names. Generated IaC modules must include the keys they satisfy. +- `wfctl infra derive` must be idempotent: running it twice with the same input must not append duplicate generated modules. +- Provider selection order is: explicit CLI flags, environment-specific hints, a single unambiguous existing `iac.provider`, then prompt/fail. +- Generated specs must never contain plaintext secrets. Use placeholders such as `${DATADOG_API_KEY}` or existing secret-reference shapes only. + +### Task 1: Extend the Strict IaC Proto + +**Files:** +- Modify: `plugin/external/proto/iac.proto` +- Modify generated: `plugin/external/proto/iac.pb.go` +- Modify generated: `plugin/external/proto/iac_grpc.pb.go` +- Modify: `plugin/external/sdk/contracts_iac_test.go` +- Modify: `plugin/external/sdk/iacserver.go` +- Modify: `plugin/external/adapter.go` + +**Step 1: Write failing contract tests** + +Add tests that assert the new mapper service is in the generated descriptors and contract registry: + +```go +func TestIaCProviderRequirementMapperIsStrictProto(t *testing.T) { + service := pb.IaCProviderRequirementMapper_ServiceDesc.ServiceName + if !strings.HasPrefix(service, "workflow.plugin.external.iac.") { + t.Fatalf("mapper service has unexpected namespace %q", service) + } + registry := sdk.BuildContractRegistry("test", nil) + assertStrictServiceContract(t, registry, service, "MapRequirements") +} +``` + +Add a proto guard test that fails if `iac.proto` imports `google/protobuf/struct.proto` or `google/protobuf/any.proto`. + +Add the same strict-contract assertion for the config-aware requirement discovery service: + +```go +func TestIaCRequirementDiscoveryIsStrictProto(t *testing.T) { + service := pb.IaCRequirementDiscovery_ServiceDesc.ServiceName + registry := sdk.BuildContractRegistry("test", nil) + assertStrictServiceContract(t, registry, service, "DiscoverRequirements") +} +``` + +**Step 2: Run tests to verify failure** + +Run: + +```sh +GOWORK=off go test ./plugin/external/sdk -run 'TestIaCProviderRequirementMapper|TestIaCRequirementDiscovery|TestIaCProtoRejectsLooseTypes' -count=1 +``` + +Expected: FAIL because `IaCProviderRequirementMapper_ServiceDesc`, `IaCRequirementDiscovery_ServiceDesc`, and the contract registry entries do not exist. + +**Step 3: Add proto types and service** + +Append strict canonical types to `plugin/external/proto/iac.proto`: + +```proto +enum RequirementKind { + REQUIREMENT_KIND_UNSPECIFIED = 0; + REQUIREMENT_KIND_OBSERVABILITY = 1; + REQUIREMENT_KIND_WEB_API = 2; + REQUIREMENT_KIND_MESSAGE_BROKER = 3; + REQUIREMENT_KIND_DATABASE = 4; + REQUIREMENT_KIND_CACHE = 5; + REQUIREMENT_KIND_STORAGE = 6; +} + +enum RequirementRuntime { + REQUIREMENT_RUNTIME_UNSPECIFIED = 0; + REQUIREMENT_RUNTIME_KUBERNETES = 1; + REQUIREMENT_RUNTIME_ECS = 2; + REQUIREMENT_RUNTIME_CLOUD_RUN = 3; + REQUIREMENT_RUNTIME_AZURE_CONTAINER_APPS = 4; + REQUIREMENT_RUNTIME_DIGITALOCEAN_APP_PLATFORM = 5; +} + +enum TelemetrySignal { + TELEMETRY_SIGNAL_UNSPECIFIED = 0; + TELEMETRY_SIGNAL_TRACES = 1; + TELEMETRY_SIGNAL_METRICS = 2; + TELEMETRY_SIGNAL_LOGS = 3; +} + +enum ObservabilityBackend { + OBSERVABILITY_BACKEND_UNSPECIFIED = 0; + OBSERVABILITY_BACKEND_OTEL = 1; + OBSERVABILITY_BACKEND_DATADOG = 2; + OBSERVABILITY_BACKEND_PROMETHEUS = 3; + OBSERVABILITY_BACKEND_LOKI = 4; + OBSERVABILITY_BACKEND_GRAFANA = 5; +} + +enum DeploymentMode { + DEPLOYMENT_MODE_UNSPECIFIED = 0; + DEPLOYMENT_MODE_SIDECAR = 1; + DEPLOYMENT_MODE_DAEMONSET = 2; + DEPLOYMENT_MODE_SIBLING_SERVICE = 3; + DEPLOYMENT_MODE_MANAGED = 4; +} + +message IaCRequirement { + string key = 1; + RequirementKind kind = 2; + string source = 3; + string resource_type_hint = 4; + string environment = 5; + repeated RequirementRuntime runtimes = 6; + repeated TelemetrySignal telemetry_signals = 7; + repeated ObservabilityBackend observability_backends = 8; + repeated DeploymentMode deployment_modes = 9; + repeated string vendor_features = 10; + bytes parameters_json = 11; +} + +message DiscoverRequirementsRequest { + RequirementContext context = 1; + bytes module_config_json = 2; +} + +message RequirementContext { + string application = 1; + string environment = 2; + repeated ModuleRef modules = 3; + repeated string plugin_ids = 4; +} + +message ModuleRef { + string name = 1; + string type = 2; + repeated string satisfies = 3; +} + +message DiscoverRequirementsResponse { + repeated IaCRequirement requirements = 1; +} + +message MapRequirementsRequest { + string provider = 1; + RequirementRuntime runtime = 2; + string environment = 3; + repeated IaCRequirement requirements = 4; +} + +message DerivedModuleSpec { + string name = 1; + string type = 2; + repeated string satisfies = 3; + bytes config_json = 4; + repeated string depends_on = 5; +} + +message MapRequirementsResponse { + repeated string accepted_keys = 1; + repeated RequirementDiagnostic rejected = 2; + repeated DerivedModuleSpec modules = 3; + repeated RequirementNote notes = 4; +} + +message RequirementDiagnostic { + string key = 1; + string code = 2; + string message = 3; +} + +message RequirementNote { + string key = 1; + string message = 2; + bool interactive = 3; +} + +service IaCRequirementDiscovery { + rpc DiscoverRequirements(DiscoverRequirementsRequest) returns (DiscoverRequirementsResponse); +} + +service IaCProviderRequirementMapper { + rpc MapRequirements(MapRequirementsRequest) returns (MapRequirementsResponse); +} +``` + +If implementation exposes a shortcoming in this schema, first try to model it as a new enum/message field. Use `parameters_json`, `module_config_json`, or `config_json` only with an inline proto comment and a plan note explaining why strict modeling was not practical. These JSON byte fields are for already-declared plugin/provider config payloads, not arbitrary cross-plugin schema. Do not send the full Workflow YAML or resolved secret values to external discovery plugins. + +**Step 4: Regenerate protobufs** + +Run: + +```sh +buf generate +``` + +Expected: `plugin/external/proto/iac.pb.go` and `plugin/external/proto/iac_grpc.pb.go` include `IaCProviderRequirementMapper` and `IaCRequirementDiscovery`. + +**Step 5: Register optional mapper service** + +Update `plugin/external/sdk/iacserver.go` so `RegisterAllIaCProviderServices` type-asserts provider implementations for the generated mapper and discovery server interfaces and registers them. Update the contract registry to advertise `IaCProviderRequirementMapper/MapRequirements` and `IaCRequirementDiscovery/DiscoverRequirements` as `CONTRACT_MODE_STRICT_PROTO`. + +**Step 6: Add wfctl-side typed client hook** + +Update `plugin/external/adapter.go` only if the existing typed adapter path needs a convenience method for the mapper. Prefer using the generated `pb.NewIaCProviderRequirementMapperClient` directly where possible; do not add hand-written marshalling when the generated client can be used. + +**Step 7: Verify** + +Run: + +```sh +GOWORK=off go test ./plugin/external/proto ./plugin/external/sdk ./plugin/external -run 'TestIaCProviderRequirementMapper|TestIaCRequirementDiscovery|TestIaCProtoRejectsLooseTypes|TestBuildContractRegistry|TestRegisterAllIaCProviderServices' -count=1 +GOWORK=off go test ./plugin/external/proto ./plugin/external/sdk ./plugin/external -count=1 +``` + +Expected: PASS. Generated service names begin with `workflow.plugin.external.iac.` and the registry advertises strict proto. + +**Rollback:** revert this PR and regenerate protobufs; provider plugins continue using existing IaC services. + +**Step 8: Commit** + +```sh +git add plugin/external/proto/iac.proto plugin/external/proto/iac.pb.go plugin/external/proto/iac_grpc.pb.go plugin/external/sdk plugin/external +git commit -m "feat: add iac requirement mapper protocol" +``` + +### Task 2: Add Local Requirement Model and Manifest v2 + +**Files:** +- Modify: `config/config.go` +- Modify: `config/config_test.go` +- Modify: `config/plugin_manifest.go` +- Test: `config/plugin_manifest_test.go` +- Create: `iac/requirements/types.go` +- Test: `iac/requirements/types_test.go` + +**Step 1: Write failing config and manifest tests** + +Add tests for: + +- `modules[].satisfies` round-trips through `config.LoadFromFile`. +- `plugin.json` can declare `moduleInfraRequirementsV2` with typed requirement fields. +- invalid requirement keys and unknown enum strings fail with actionable errors. + +Expected fixture: + +```yaml +modules: + - name: otel-collector + type: infra.container_service + satisfies: + - observability.telemetry.default + config: + image: otel/opentelemetry-collector-contrib:latest +``` + +**Step 2: Run tests to verify failure** + +Run: + +```sh +GOWORK=off go test ./config ./iac/requirements -run 'TestModuleSatisfies|TestPluginManifestRequirementV2|TestRequirementValidation' -count=1 +``` + +Expected: FAIL because `Satisfies` and the new requirement package do not exist. + +**Step 3: Implement `satisfies` and typed requirement structs** + +Add: + +```go +type ModuleConfig struct { + Name string `yaml:"name" json:"name"` + Type string `yaml:"type" json:"type"` + Satisfies []string `yaml:"satisfies,omitempty" json:"satisfies,omitempty"` + Config map[string]interface{} `yaml:"config,omitempty" json:"config,omitempty"` + DependsOn []string `yaml:"depends_on,omitempty" json:"depends_on,omitempty"` + Branches []string `yaml:"branches,omitempty" json:"branches,omitempty"` + Environments []string `yaml:"environments,omitempty" json:"environments,omitempty"` +} +``` + +Create `iac/requirements` with Go enums/string parsers that mirror the protobuf enums exactly. Include conversion helpers to/from `pb.IaCRequirement`. + +**Step 4: Extend plugin manifest parsing** + +Add `ModuleInfraRequirementsV2 []ModuleInfraRequirementV2` beside the existing v1 field. Keep v1 untouched for compatibility. Validate v2 in the manifest loader and convert to the local requirement model. + +**Step 5: Verify** + +Run: + +```sh +GOWORK=off go test ./config ./iac/requirements -count=1 +``` + +Expected: PASS, including invalid enum fixtures. + +**Rollback:** revert this PR. Existing module config files remain valid because `satisfies` is additive and omitted when empty. + +**Step 6: Commit** + +```sh +git add config iac/requirements +git commit -m "feat: model iac requirements in config" +``` + +### Task 3: Add Requirement Discovery Interfaces + +**Files:** +- Create: `iac/requirements/discovery.go` +- Create: `iac/requirements/external.go` +- Test: `iac/requirements/discovery_test.go` +- Test: `iac/requirements/external_test.go` +- Modify: `cmd/wfctl/plugin_infra.go` +- Test: `cmd/wfctl/plugin_infra_test.go` + +**Step 1: Write failing discovery tests** + +Cover: + +- built-in discovery from config shape emits web/api and broker requirements. +- static manifest v2 requirements are included. +- an in-process module/provider implementing the Go interface contributes requirements without importing a telemetry plugin. +- an out-of-process plugin implementing `IaCRequirementDiscovery` contributes typed requirements through the generated protobuf client. +- existing `modules[].satisfies` removes matching requirements from the unresolved set. + +Use an interface shaped like: + +```go +type Provider interface { + IaCRequirements(ctx context.Context, input Input) ([]Requirement, error) +} +``` + +**Step 2: Run tests to verify failure** + +Run: + +```sh +GOWORK=off go test ./iac/requirements ./cmd/wfctl -run 'TestDiscoverRequirements|TestExternalRequirementDiscovery|TestDetectPluginInfraNeedsIncludesV2' -count=1 +``` + +Expected: FAIL because discovery does not exist, static manifest v2 is ignored, and no external discovery adapter exists. + +**Step 3: Implement discovery** + +Implement requirement collection in `iac/requirements` and adapt `cmd/wfctl/plugin_infra.go` so existing `DetectPluginInfraNeeds` can expose v2 requirements without breaking current v1 output. Add an external discovery adapter that uses `pb.NewIaCRequirementDiscoveryClient` directly and converts strict proto messages to the local requirement model. + +**Step 4: Verify** + +Run: + +```sh +GOWORK=off go test ./iac/requirements ./cmd/wfctl -run 'TestDiscoverRequirements|TestExternalRequirementDiscovery|TestDetectPluginInfraNeedsIncludesV2' -count=1 +``` + +Expected: PASS. A requirement satisfied by `modules[].satisfies` is absent from unresolved output, and the external discovery adapter uses generated protobuf clients rather than a loose map bridge. + +**Rollback:** revert this PR; v1 plugin infra detection remains unchanged. + +**Step 5: Commit** + +```sh +git add iac/requirements cmd/wfctl/plugin_infra.go cmd/wfctl/plugin_infra_test.go +git commit -m "feat: discover iac requirements" +``` + +### Task 4: Add YAML Node Editing Package + +**Files:** +- Create: `config/yamledit/module_append.go` +- Test: `config/yamledit/module_append_test.go` +- Testdata: `config/yamledit/testdata/*.yaml` + +**Step 1: Write failing golden tests** + +Create golden cases for: + +- comments and unknown top-level keys preserved. +- unknown per-module keys preserved. +- `modules:` created when absent. +- generated modules appended after the last existing `infra.*` module when present, otherwise at the end of `modules`. +- anchors are parsed and re-emitted without panic. +- running the append operation twice does not duplicate modules with the same `satisfies` key. + +**Step 2: Run tests to verify failure** + +Run: + +```sh +GOWORK=off go test ./config/yamledit -count=1 +``` + +Expected: FAIL because the package does not exist. + +**Step 3: Implement with `yaml.Node`** + +Use `gopkg.in/yaml.v3` node mutation. Do not hand-roll YAML parsing or string insertion. Provide: + +```go +func AppendGeneratedModules(root *yaml.Node, modules []GeneratedModule) (changed bool, err error) +``` + +Sort generated modules by name for deterministic output. Preserve unknown keys by only mutating the `modules` sequence node. + +**Step 4: Verify** + +Run: + +```sh +GOWORK=off go test ./config/yamledit -count=1 +``` + +Expected: PASS, and repeated append golden output equals first output. + +**Rollback:** revert this PR; no runtime behavior changes exist until `wfctl infra derive` calls the package. + +**Step 5: Commit** + +```sh +git add config/yamledit +git commit -m "feat: add yaml editor for derived modules" +``` + +### Task 5: Add Derivation Engine and Provider Mapper Client + +**Files:** +- Create: `iac/derive/engine.go` +- Create: `iac/derive/provider.go` +- Test: `iac/derive/engine_test.go` +- Test: `iac/derive/provider_test.go` +- Modify: `cmd/wfctl/infra_provider_dispatch.go` + +**Step 1: Write failing engine tests** + +Cover: + +- provider/runtime precedence. +- non-interactive ambiguity returns a deterministic error. +- mapper response with plaintext secret-like config is rejected. +- mapper response with `${DATADOG_API_KEY}` is accepted. +- generated modules inherit `satisfies` keys. +- mapper rejected diagnostics and notes are surfaced. + +**Step 2: Run tests to verify failure** + +Run: + +```sh +GOWORK=off go test ./iac/derive ./cmd/wfctl -run 'TestDerive|TestProviderRuntimePrecedence' -count=1 +``` + +Expected: FAIL because the package and mapper client are absent. + +**Step 3: Implement engine** + +Implement: + +```go +type Options struct { + Provider string + Runtime requirements.Runtime + Environment string + NonInteractive bool +} + +type Result struct { + Requirements []requirements.Requirement + Modules []GeneratedModule + Rejected []Diagnostic + Notes []Note +} + +func Derive(ctx context.Context, cfg *config.WorkflowConfig, plugins []config.PluginManifest, mapper ProviderMapper, opts Options) (Result, error) +``` + +`ProviderMapper` should accept local typed requirements and use generated protobuf types internally when talking to external provider plugins. + +**Step 4: Wire provider dispatch** + +Reuse existing provider discovery in `cmd/wfctl/infra_provider_dispatch.go`. Add only small helpers needed by derivation; do not duplicate provider grouping logic. + +**Step 5: Verify** + +Run: + +```sh +GOWORK=off go test ./iac/derive ./cmd/wfctl -run 'TestDerive|TestProviderRuntimePrecedence' -count=1 +GOWORK=off go test ./iac/derive -count=1 +``` + +Expected: PASS. Secret rejection error includes the offending generated module name and key, not the secret value; rejected mapper diagnostics remain attached to the requirement key that produced them. + +**Rollback:** revert this PR. Since the CLI command is not wired yet, no user-facing behavior changes are active. + +**Step 6: Commit** + +```sh +git add iac/derive cmd/wfctl/infra_provider_dispatch.go +git commit -m "feat: derive iac modules from requirements" +``` + +### Task 6: Add `wfctl infra derive` + +**Files:** +- Modify: `cmd/wfctl/infra.go` +- Create: `cmd/wfctl/infra_derive.go` +- Test: `cmd/wfctl/infra_derive_test.go` +- Testdata: `cmd/wfctl/testdata/infra_derive/*.yaml` +- Modify docs: `docs/WFCTL.md` + +**Step 1: Write failing CLI tests** + +Use the same command style as existing `cmd/wfctl` tests. Cover: + +- `wfctl infra derive --help` includes `--write`, `--dry-run`, `--provider`, `--runtime`, `--env`, and `--non-interactive`. +- dry-run prints expanded YAML and does not mutate the file. +- write mode atomically updates the root YAML file. +- multi-file config reports imported requirements but mutates only `--config`. +- non-interactive ambiguity exits non-zero with the provider choices. +- second write is a no-op. +- tests use a fake generated-proto mapper fixture so Workflow CLI correctness does not depend on a real provider plugin release. + +**Step 2: Run tests to verify failure** + +Run: + +```sh +GOWORK=off go test ./cmd/wfctl -run 'TestInfraDerive' -count=1 +``` + +Expected: FAIL because the subcommand is not registered. + +**Step 3: Implement command** + +Add: + +```text +wfctl infra derive --config workflow.yaml --provider digitalocean --runtime do-app-platform --env production --write --non-interactive +wfctl infra derive --config workflow.yaml --provider aws --runtime ecs --dry-run --format yaml --non-interactive +``` + +Default to dry-run unless `--write` is set. `--dry-run` and `--write` are mutually exclusive. Use `config.LoadFromFile` for semantic loading and `yaml.Node` for mutation. + +**Step 4: Document command** + +Update `docs/WFCTL.md` with examples showing explicit `satisfies` override and observability derivation. Include a note that apply-time derivation is intentionally absent. + +**Step 5: Verify CLI behavior** + +Run: + +```sh +GOWORK=off go test ./cmd/wfctl -run 'TestInfraDerive' -count=1 +GOWORK=off go run ./cmd/wfctl infra derive --help +``` + +Expected: + +- Tests PASS. +- Help exits 0 and lists the derive flags. +- `TestInfraDeriveDryRunWithFakeMapper` prints YAML containing `satisfies:` without mutating the fixture. + +**Rollback:** revert this PR. Existing `wfctl infra plan/apply/bootstrap` commands are unchanged. + +**Step 6: Commit** + +```sh +git add cmd/wfctl docs/WFCTL.md +git commit -m "feat: add wfctl infra derive" +``` + +### Task 7: Preserve `satisfies` in workflow-editor + +**Repository:** `/Users/jon/workspace/workflow-editor` + +**Files:** +- Modify: `src/types/workflow.ts` +- Modify: `src/utils/serialization.ts` +- Test: existing serialization test file or create `src/utils/serialization.satisfies.test.ts` + +**Step 1: Create a feature branch** + +Run: + +```sh +cd /Users/jon/workspace/workflow-editor +git switch -c feat/editor-preserve-satisfies +``` + +Expected: branch created from current `main` or the repo's active base branch. + +**Step 2: Write failing serialization test** + +Fixture: + +```yaml +modules: + - name: otel-collector + type: infra.container_service + satisfies: + - observability.telemetry.default + config: + image: otel/opentelemetry-collector-contrib:latest +``` + +Assert parse and serialize retain `satisfies` on the module. + +**Step 3: Run test to verify failure** + +Run: + +```sh +npm test -- src/utils/serialization.satisfies.test.ts +``` + +Expected: FAIL because `satisfies` is dropped. + +**Step 4: Implement preservation** + +Add `satisfies?: string[]` to `ModuleConfig` and pass it through `nodesToConfig`, `parseYaml`, and `configToYaml`. Do not change unrelated YAML formatting behavior. + +**Step 5: Verify** + +Run: + +```sh +npm test -- src/utils/serialization.satisfies.test.ts +npm test +``` + +Expected: PASS. Serialized YAML still includes the same `satisfies` entries. + +**Rollback:** revert this PR. Workflow CLI remains usable; editor users may lose `satisfies` until this ships, so Workflow docs should warn if this PR lags. + +**Step 6: Commit and PR** + +```sh +git add src/types/workflow.ts src/utils/serialization.ts src/utils/serialization.satisfies.test.ts +git commit -m "feat: preserve module satisfies metadata" +``` + +### Task 8: Emit Observability IaC Requirements + +**Repository:** `/Users/jon/workspace/workflow-plugin-observability` + +**Files:** +- Modify: `plugin.json` +- Modify or create Go source for strict requirement descriptors, likely `internal/contracts.go` or `internal/requirements.go` +- Test: `internal/requirements_test.go` +- Modify docs: `README.md` + +**Step 1: Create a feature branch** + +Run: + +```sh +cd /Users/jon/workspace/workflow-plugin-observability +git switch -c feat/observability-iac-requirements +``` + +Expected: branch created from `main`. + +**Step 2: Bump Workflow minimum version** + +After the Workflow core PRs merge and release, update `go.mod`, `plugin.json`, and docs to depend on the new minimum Workflow version. Do not guess the version before the Workflow tag exists. + +**Step 3: Write failing tests** + +Test that the plugin emits generic keys only: + +```go +func TestObservabilityRequirementsUseGenericNames(t *testing.T) { + reqs := RequirementsForConfig(Config{Backends: []Backend{BackendOTel}}) + require.NotEmpty(t, reqs) + for _, req := range reqs { + require.NotContains(t, req.Key, "cms") + require.NotContains(t, req.Key, "multisite") + } +} +``` + +Test OTel, Datadog, Prometheus, Loki, and Grafana backend combinations map to typed requirement enums. + +**Step 4: Run tests to verify failure** + +Run: + +```sh +GOWORK=off go test ./internal -run 'TestObservabilityRequirements' -count=1 +``` + +Expected: FAIL because no requirement descriptors are emitted. + +**Step 5: Implement requirements** + +Prefer manifest v2 static descriptors when configuration is static enough. Use a runtime provider only when config-specific backend/signal selection changes required IaC. Requirement keys must be generic, for example: + +```text +observability.telemetry.default +observability.metrics.prometheus +observability.logs.loki +observability.datadog.agent +``` + +Do not add `cms_*`, `multisite_*`, or application-specific names. + +**Step 6: Verify plugin behavior** + +Run: + +```sh +GOWORK=off go test ./... -count=1 +wfctl plugin validate --strict-contracts plugin.json +wfctl plugin verify-capabilities --plugin . +``` + +Expected: PASS. Plugin contracts remain strict proto and no generated names are application-specific. + +**Rollback:** revert this PR and pin consumers to the previous observability plugin release. Existing telemetry SDK behavior remains available without IaC derivation. + +**Step 7: Commit and PR** + +```sh +git add go.mod go.sum plugin.json README.md internal +git commit -m "feat: emit observability iac requirements" +``` + +### Task 9: Add DigitalOcean Requirement Mapper + +**Repository:** `/Users/jon/workspace/workflow-plugin-digitalocean` + +**Files:** +- Modify mapper/provider files according to the repo's existing IaC provider structure. +- Test: add `TestIaCRequirementMapperDigitalOcean` near existing IaC provider tests. +- Modify: `go.mod`, `go.sum`, `plugin.json`, docs only after the Workflow release tag exists. + +**Step 1: Create feature branch** + +```sh +cd /Users/jon/workspace/workflow-plugin-digitalocean +git switch -c feat/iac-requirement-mapper +``` + +Expected: branch created from `main`. + +**Step 2: Write failing conformance tests** + +Cover OTel collector on DigitalOcean App Platform, Datadog agent where existing App Platform sidecar/sibling support allows it, unsupported runtime diagnostics, `satisfies` propagation, and no plaintext secrets in `config_json`. + +**Step 3: Run test to verify failure** + +```sh +GOWORK=off go test ./... -run 'TestIaCRequirementMapperDigitalOcean' -count=1 +``` + +Expected: FAIL because the mapper service is not implemented. + +**Step 4: Implement mapper** + +Implement generated `IaCProviderRequirementMapperServer` using DigitalOcean-owned App Platform module shapes. Return typed `RequirementDiagnostic` entries when a requested deployment mode cannot be represented. + +**Step 5: Verify** + +```sh +GOWORK=off go test ./... -count=1 +wfctl plugin validate --strict-contracts plugin.json +wfctl plugin verify-capabilities --plugin . +``` + +Expected: PASS. Capability output includes `IaCProviderRequirementMapper`. + +**Rollback:** revert this provider PR. Workflow can still derive with other providers or report that no DigitalOcean mapper is available. + +**Step 6: Commit and PR** + +```sh +git add . +git commit -m "feat: map iac requirements for digitalocean" +``` + +### Task 10: Add AWS Requirement Mapper + +**Repository:** `/Users/jon/workspace/workflow-plugin-aws` + +**Files:** +- Modify mapper/provider files according to the repo's existing IaC provider structure. +- Test: add `TestIaCRequirementMapperAWS` near existing IaC provider tests. +- Modify: `go.mod`, `go.sum`, `plugin.json`, docs only after the Workflow release tag exists. + +**Step 1: Create feature branch** + +```sh +cd /Users/jon/workspace/workflow-plugin-aws +git switch -c feat/iac-requirement-mapper +``` + +Expected: branch created from `main`. + +**Step 2: Write failing conformance tests** + +Cover ECS sidecar/service mapping for OTel and Datadog, EKS daemonset diagnostics if Kubernetes runtime is supported, unsupported runtime diagnostics, `satisfies` propagation, and secret placeholder enforcement. + +**Step 3: Run test to verify failure** + +```sh +GOWORK=off go test ./... -run 'TestIaCRequirementMapperAWS' -count=1 +``` + +Expected: FAIL because the mapper service is not implemented. + +**Step 4: Implement mapper** + +Implement generated `IaCProviderRequirementMapperServer` using AWS-owned ECS/EKS module shapes. Do not copy DigitalOcean config keys into AWS output. + +**Step 5: Verify** + +```sh +GOWORK=off go test ./... -count=1 +wfctl plugin validate --strict-contracts plugin.json +wfctl plugin verify-capabilities --plugin . +``` + +Expected: PASS. Capability output includes `IaCProviderRequirementMapper`. + +**Rollback:** revert this provider PR. Workflow can still derive with other providers or report that no AWS mapper is available. + +**Step 6: Commit and PR** + +```sh +git add . +git commit -m "feat: map iac requirements for aws" +``` + +### Task 11: Add GCP Requirement Mapper + +**Repository:** `/Users/jon/workspace/workflow-plugin-gcp` + +**Files:** +- Modify mapper/provider files according to the repo's existing IaC provider structure. +- Test: add `TestIaCRequirementMapperGCP` near existing IaC provider tests. +- Modify: `go.mod`, `go.sum`, `plugin.json`, docs only after the Workflow release tag exists. + +**Step 1: Create feature branch** + +```sh +cd /Users/jon/workspace/workflow-plugin-gcp +git switch -c feat/iac-requirement-mapper +``` + +Expected: branch created from `main`. + +**Step 2: Write failing conformance tests** + +Cover Cloud Run service/sidecar-equivalent mapping where supported, GKE daemonset mapping where supported, unsupported runtime diagnostics, `satisfies` propagation, and secret placeholder enforcement. + +**Step 3: Run test to verify failure** + +```sh +GOWORK=off go test ./... -run 'TestIaCRequirementMapperGCP' -count=1 +``` + +Expected: FAIL because the mapper service is not implemented. + +**Step 4: Implement mapper** + +Implement generated `IaCProviderRequirementMapperServer` using GCP-owned Cloud Run/GKE module shapes. Return diagnostics instead of malformed modules for runtimes that cannot host the requested mode. + +**Step 5: Verify** + +```sh +GOWORK=off go test ./... -count=1 +wfctl plugin validate --strict-contracts plugin.json +wfctl plugin verify-capabilities --plugin . +``` + +Expected: PASS. Capability output includes `IaCProviderRequirementMapper`. + +**Rollback:** revert this provider PR. Workflow can still derive with other providers or report that no GCP mapper is available. + +**Step 6: Commit and PR** + +```sh +git add . +git commit -m "feat: map iac requirements for gcp" +``` + +### Task 12: Add Azure Requirement Mapper + +**Repository:** `/Users/jon/workspace/workflow-plugin-azure` + +**Files:** +- Modify mapper/provider files according to the repo's existing IaC provider structure. +- Test: add `TestIaCRequirementMapperAzure` near existing IaC provider tests. +- Modify: `go.mod`, `go.sum`, `plugin.json`, docs only after the Workflow release tag exists. + +**Step 1: Create feature branch** + +```sh +cd /Users/jon/workspace/workflow-plugin-azure +git switch -c feat/iac-requirement-mapper +``` + +Expected: branch created from `main`. + +**Step 2: Write failing conformance tests** + +Cover Azure Container Apps sidecar-equivalent/service mapping where supported, AKS daemonset mapping where supported, unsupported runtime diagnostics, `satisfies` propagation, and secret placeholder enforcement. + +**Step 3: Run test to verify failure** + +```sh +GOWORK=off go test ./... -run 'TestIaCRequirementMapperAzure' -count=1 +``` + +Expected: FAIL because the mapper service is not implemented. + +**Step 4: Implement mapper** + +Implement generated `IaCProviderRequirementMapperServer` using Azure-owned Container Apps/AKS module shapes. Return diagnostics instead of malformed modules for runtimes that cannot host the requested mode. + +**Step 5: Verify** + +```sh +GOWORK=off go test ./... -count=1 +wfctl plugin validate --strict-contracts plugin.json +wfctl plugin verify-capabilities --plugin . +``` + +Expected: PASS. Capability output includes `IaCProviderRequirementMapper`. + +**Rollback:** revert this provider PR. Workflow can still derive with other providers or report that no Azure mapper is available. + +**Step 6: Commit and PR** + +```sh +git add . +git commit -m "feat: map iac requirements for azure" +``` + +## Release and Migration Sequence + +These steps are operational gates, not scope-manifest PR tasks. + +1. Merge Workflow PRs 1 and 2 only after CI is green. +2. Inspect the current Workflow release workflow before tagging. If tag-triggered release is current, create the next semver tag from green `main`; otherwise follow the repo's current documented release command. +3. Verify the release asset or module tag contains `wfctl infra derive`, the strict requirement proto, and `modules[].satisfies`. +4. Start observability/provider PRs only after that Workflow tag exists, then bump each plugin's minimum Workflow version to the new tag before release. +5. Release the observability plugin first, then provider mapper plugins as they go green. +6. Search owned application repos for custom `/metrics` reliance: + +```sh +rg -n '(/metrics|promhttp|prometheus|metrics endpoint|ListenAndServe.*metrics)' /Users/jon/workspace -g'*.go' -g'*.yaml' -g'*.yml' +``` + +7. For each owned application found, create a separate app-repo PR that removes the custom `/metrics` dependency and uses the released observability plugin plus `wfctl infra derive`. Do not commit app-specific names into generic plugins. +8. Smoke test a representative app after provider mapper release: + +```sh +wfctl infra derive --config /tmp/workflow-observability.yaml --provider digitalocean --runtime do-app-platform --write --non-interactive +wfctl validate --config /tmp/workflow-observability.yaml +``` + +Expected: derive exits 0, YAML includes generated modules with `satisfies`, and `wfctl validate` exits 0. + +Rollback: if Workflow release smoke fails before plugin PRs merge, do not release plugin tags. If a plugin release fails, keep consumers pinned to the previous plugin release and fix forward with a patch tag. If an app migration fails, revert only that app PR. + +## Final Verification Matrix + +Run after all PRs in a repo are ready: + +```sh +cd /Users/jon/workspace/workflow/.worktrees/iac-derived-requirements +GOWORK=off go test ./config ./config/yamledit ./iac/... ./plugin/external/proto ./plugin/external/sdk ./plugin/external ./cmd/wfctl -count=1 +GOWORK=off go vet ./config ./config/yamledit ./iac/... ./plugin/external/... ./cmd/wfctl +GOWORK=off go run ./cmd/wfctl infra derive --help +``` + +Expected: + +- All tests PASS. +- `go vet` exits 0. +- Help exits 0 and shows `derive`. + +For each plugin repo touched: + +```sh +GOWORK=off go test ./... -count=1 +wfctl plugin validate --strict-contracts plugin.json +wfctl plugin verify-capabilities --plugin . +``` + +Expected: PASS, with strict proto contracts and mapper capabilities where implemented. + +For workflow-editor: + +```sh +npm test +``` + +Expected: PASS, including the `satisfies` serialization test. diff --git a/docs/plans/2026-05-25-iac-derived-requirements.md.scope-lock b/docs/plans/2026-05-25-iac-derived-requirements.md.scope-lock new file mode 100644 index 00000000..e4c47917 --- /dev/null +++ b/docs/plans/2026-05-25-iac-derived-requirements.md.scope-lock @@ -0,0 +1 @@ +6e7289cee903e2a2b4881a4ea26e2040d1cf450ae9a053997d14f9eb8a95a742 diff --git a/iac/requirements/discovery.go b/iac/requirements/discovery.go new file mode 100644 index 00000000..7e5edb6d --- /dev/null +++ b/iac/requirements/discovery.go @@ -0,0 +1,264 @@ +package requirements + +import ( + "context" + "encoding/json" + "fmt" + "sort" + + "github.com/GoCodeAlone/workflow/config" +) + +type Input struct { + Config *config.WorkflowConfig + Manifests map[string]*config.PluginManifestFile + Providers []Provider + Environment string +} + +type Provider interface { + IaCRequirements(context.Context, Input) ([]Requirement, error) +} + +type ProviderFunc func(context.Context, Input) ([]Requirement, error) + +func (f ProviderFunc) IaCRequirements(ctx context.Context, input Input) ([]Requirement, error) { + return f(ctx, input) +} + +func Discover(ctx context.Context, input Input) ([]Requirement, error) { + var out []Requirement + seen := make(map[string]struct{}) + + add := func(req Requirement) error { + if req.Environment == "" { + req.Environment = input.Environment + } + if err := req.Validate(); err != nil { + return err + } + if _, ok := seen[req.Key]; ok { + return nil + } + seen[req.Key] = struct{}{} + out = append(out, req) + return nil + } + + builtIns := discoverBuiltIns(input.Config) + for i := range builtIns { + req := builtIns[i] + if err := add(req); err != nil { + return nil, err + } + } + manifestReqs, err := discoverManifestRequirements(input.Config, input.Manifests) + if err != nil { + return nil, err + } + for i := range manifestReqs { + req := manifestReqs[i] + if err := add(req); err != nil { + return nil, err + } + } + for _, provider := range input.Providers { + reqs, err := provider.IaCRequirements(ctx, input) + if err != nil { + return nil, err + } + for i := range reqs { + req := reqs[i] + if err := add(req); err != nil { + return nil, err + } + } + } + + satisfied := satisfiedKeys(input.Config) + if len(satisfied) == 0 { + return out, nil + } + filtered := out[:0] + for i := range out { + req := out[i] + if _, ok := satisfied[req.Key]; ok { + continue + } + filtered = append(filtered, req) + } + return filtered, nil +} + +func DiscoverManifestRequirements(cfg *config.WorkflowConfig, manifests map[string]*config.PluginManifestFile) ([]Requirement, error) { + reqs, err := discoverManifestRequirements(cfg, manifests) + if err != nil { + return nil, err + } + seen := make(map[string]struct{}) + out := make([]Requirement, 0, len(reqs)) + for i := range reqs { + req := reqs[i] + if err := req.Validate(); err != nil { + return nil, err + } + if _, ok := seen[req.Key]; ok { + continue + } + seen[req.Key] = struct{}{} + out = append(out, req) + } + satisfied := satisfiedKeys(cfg) + if len(satisfied) == 0 { + return out, nil + } + filtered := out[:0] + for i := range out { + req := out[i] + if _, ok := satisfied[req.Key]; ok { + continue + } + filtered = append(filtered, req) + } + return filtered, nil +} + +func discoverBuiltIns(cfg *config.WorkflowConfig) []Requirement { + if cfg == nil { + return nil + } + var out []Requirement + for _, name := range sortedServiceNames(cfg.Services) { + svc := cfg.Services[name] + if svc == nil { + continue + } + if svc.Binary != "" || len(svc.Expose) > 0 { + out = append(out, Requirement{ + Key: "web.api." + name, + Kind: KindWebAPI, + Source: "services." + name, + ResourceTypeHint: "infra.container_service", + }) + } + } + if cfg.Mesh != nil && (cfg.Mesh.Transport == "nats" || cfg.Mesh.NATS != nil) { + out = append(out, Requirement{ + Key: "messaging.nats.default", + Kind: KindMessageBroker, + Source: "mesh", + ResourceTypeHint: "infra.message_broker", + VendorFeatures: []string{"nats"}, + }) + } + return out +} + +func discoverManifestRequirements(cfg *config.WorkflowConfig, manifests map[string]*config.PluginManifestFile) ([]Requirement, error) { + if cfg == nil || len(manifests) == 0 { + return nil, nil + } + var out []Requirement + for _, mod := range allModules(cfg) { + for _, manifestName := range sortedManifestNames(manifests) { + manifest := manifests[manifestName] + if manifest == nil || manifest.ModuleInfraRequirementsV2 == nil { + continue + } + spec := manifest.ModuleInfraRequirementsV2[mod.Type] + if spec == nil { + continue + } + for i := range spec.Requires { + raw := spec.Requires[i] + req, err := FromManifestRequirement(raw) + if err != nil { + return nil, fmt.Errorf("module %q requirement %q: %w", mod.Type, raw.Key, err) + } + if req.Source == "" { + req.Source = mod.Type + } + out = append(out, req) + } + } + } + return out, nil +} + +func FromManifestRequirement(raw config.ModuleInfraRequirementV2) (Requirement, error) { + var params []byte + if len(raw.Parameters) > 0 { + encoded, err := json.Marshal(raw.Parameters) + if err != nil { + return Requirement{}, fmt.Errorf("marshal requirement parameters: %w", err) + } + params = encoded + } + req := Requirement{ + Key: raw.Key, + Kind: Kind(raw.Kind), + Source: raw.Source, + ResourceTypeHint: raw.ResourceTypeHint, + Environment: raw.Environment, + Runtimes: castSlice[Runtime](raw.Runtimes), + TelemetrySignals: castSlice[TelemetrySignal](raw.TelemetrySignals), + ObservabilityBackends: castSlice[ObservabilityBackend](raw.ObservabilityBackends), + DeploymentModes: castSlice[DeploymentMode](raw.DeploymentModes), + VendorFeatures: append([]string(nil), raw.VendorFeatures...), + ParametersJSON: params, + } + if err := req.Validate(); err != nil { + return Requirement{}, err + } + return req, nil +} + +func allModules(cfg *config.WorkflowConfig) []config.ModuleConfig { + if cfg == nil { + return nil + } + out := append([]config.ModuleConfig(nil), cfg.Modules...) + for _, name := range sortedServiceNames(cfg.Services) { + svc := cfg.Services[name] + if svc != nil { + out = append(out, svc.Modules...) + } + } + return out +} + +func satisfiedKeys(cfg *config.WorkflowConfig) map[string]struct{} { + out := make(map[string]struct{}) + for _, mod := range allModules(cfg) { + for _, key := range mod.Satisfies { + out[key] = struct{}{} + } + } + return out +} + +func castSlice[T ~string](in []string) []T { + out := make([]T, 0, len(in)) + for _, item := range in { + out = append(out, T(item)) + } + return out +} + +func sortedServiceNames(services map[string]*config.ServiceConfig) []string { + names := make([]string, 0, len(services)) + for name := range services { + names = append(names, name) + } + sort.Strings(names) + return names +} + +func sortedManifestNames(manifests map[string]*config.PluginManifestFile) []string { + names := make([]string, 0, len(manifests)) + for name := range manifests { + names = append(names, name) + } + sort.Strings(names) + return names +} diff --git a/iac/requirements/discovery_test.go b/iac/requirements/discovery_test.go new file mode 100644 index 00000000..7a20650c --- /dev/null +++ b/iac/requirements/discovery_test.go @@ -0,0 +1,123 @@ +package requirements + +import ( + "context" + "testing" + + "github.com/GoCodeAlone/workflow/config" +) + +func TestDiscoverRequirementsFromConfigShape(t *testing.T) { + cfg := &config.WorkflowConfig{ + Services: map[string]*config.ServiceConfig{ + "api": { + Binary: "./cmd/api", + Expose: []config.ExposeConfig{{ + Port: 8080, + Protocol: "http", + }}, + }, + }, + Mesh: &config.MeshConfig{ + Transport: "nats", + }, + } + + reqs, err := Discover(context.Background(), Input{Config: cfg}) + if err != nil { + t.Fatalf("Discover: %v", err) + } + assertHasRequirement(t, reqs, "web.api.api", KindWebAPI) + assertHasRequirement(t, reqs, "messaging.nats.default", KindMessageBroker) +} + +func TestDiscoverRequirementsFromManifestV2(t *testing.T) { + cfg := &config.WorkflowConfig{ + Modules: []config.ModuleConfig{{Name: "telemetry", Type: "observability.telemetry"}}, + } + manifests := map[string]*config.PluginManifestFile{ + "workflow-plugin-observability": { + ModuleInfraRequirementsV2: config.PluginInfraRequirementsV2{ + "observability.telemetry": { + Requires: []config.ModuleInfraRequirementV2{{ + Key: "observability.telemetry.default", + Kind: "observability", + Source: "observability.telemetry", + ResourceTypeHint: "infra.container_service", + Runtimes: []string{"kubernetes"}, + TelemetrySignals: []string{"traces", "metrics", "logs"}, + ObservabilityBackends: []string{"otel"}, + DeploymentModes: []string{"sidecar"}, + }}, + }, + }, + }, + } + + reqs, err := Discover(context.Background(), Input{Config: cfg, Manifests: manifests}) + if err != nil { + t.Fatalf("Discover: %v", err) + } + req := assertHasRequirement(t, reqs, "observability.telemetry.default", KindObservability) + if req.ResourceTypeHint != "infra.container_service" { + t.Fatalf("ResourceTypeHint = %q", req.ResourceTypeHint) + } + if len(req.TelemetrySignals) != 3 { + t.Fatalf("TelemetrySignals = %v", req.TelemetrySignals) + } +} + +func TestDiscoverRequirementsFiltersSatisfiedKeys(t *testing.T) { + cfg := &config.WorkflowConfig{ + Modules: []config.ModuleConfig{ + {Name: "telemetry", Type: "observability.telemetry"}, + {Name: "otel", Type: "infra.container_service", Satisfies: []string{"observability.telemetry.default"}}, + }, + } + manifests := map[string]*config.PluginManifestFile{ + "workflow-plugin-observability": { + ModuleInfraRequirementsV2: config.PluginInfraRequirementsV2{ + "observability.telemetry": { + Requires: []config.ModuleInfraRequirementV2{{ + Key: "observability.telemetry.default", + Kind: "observability", + }}, + }, + }, + }, + } + + reqs, err := Discover(context.Background(), Input{Config: cfg, Manifests: manifests}) + if err != nil { + t.Fatalf("Discover: %v", err) + } + if len(reqs) != 0 { + t.Fatalf("expected satisfied requirement to be filtered; got %+v", reqs) + } +} + +func TestDiscoverRequirementsFromInProcessProvider(t *testing.T) { + provider := ProviderFunc(func(context.Context, Input) ([]Requirement, error) { + return []Requirement{{Key: "cache.redis.default", Kind: KindCache}}, nil + }) + + reqs, err := Discover(context.Background(), Input{Providers: []Provider{provider}}) + if err != nil { + t.Fatalf("Discover: %v", err) + } + assertHasRequirement(t, reqs, "cache.redis.default", KindCache) +} + +func assertHasRequirement(t *testing.T, reqs []Requirement, key string, kind Kind) Requirement { + t.Helper() + for _, req := range reqs { + if req.Key == key { + if req.Kind != kind { + t.Fatalf("requirement %q kind = %q, want %q", key, req.Kind, kind) + } + return req + } + } + t.Fatalf("requirement %q not found in %+v", key, reqs) + return Requirement{} +} diff --git a/iac/requirements/external.go b/iac/requirements/external.go new file mode 100644 index 00000000..ae0e1022 --- /dev/null +++ b/iac/requirements/external.go @@ -0,0 +1,63 @@ +package requirements + +import ( + "context" + "fmt" + + "github.com/GoCodeAlone/workflow/config" + pb "github.com/GoCodeAlone/workflow/plugin/external/proto" +) + +type ExternalDiscoveryProvider struct { + Client pb.IaCRequirementDiscoveryClient + Context *pb.RequirementContext + ModuleConfigJSON []byte +} + +func (p ExternalDiscoveryProvider) IaCRequirements(ctx context.Context, input Input) ([]Requirement, error) { + if p.Client == nil { + return nil, fmt.Errorf("iac requirement discovery client is nil") + } + req := &pb.DiscoverRequirementsRequest{ + Context: p.Context, + ModuleConfigJson: append([]byte(nil), p.ModuleConfigJSON...), + } + if req.Context == nil { + req.Context = RequirementContextFromConfig(input.Config, input.Environment) + } + resp, err := p.Client.DiscoverRequirements(ctx, req) + if err != nil { + return nil, err + } + out := make([]Requirement, 0, len(resp.GetRequirements())) + for _, protoReq := range resp.GetRequirements() { + req, err := FromProto(protoReq) + if err != nil { + return nil, err + } + out = append(out, req) + } + return out, nil +} + +func RequirementContextFromConfig(cfg *config.WorkflowConfig, environment string) *pb.RequirementContext { + ctx := &pb.RequirementContext{Environment: environment} + if cfg == nil { + return ctx + } + refs := allModules(cfg) + ctx.Modules = make([]*pb.ModuleRef, 0, len(refs)) + for _, mod := range refs { + ctx.Modules = append(ctx.Modules, &pb.ModuleRef{ + Name: mod.Name, + Type: mod.Type, + Satisfies: append([]string(nil), mod.Satisfies...), + }) + } + if cfg.Plugins != nil { + for _, plugin := range cfg.Plugins.External { + ctx.PluginIds = append(ctx.PluginIds, plugin.Name) + } + } + return ctx +} diff --git a/iac/requirements/external_test.go b/iac/requirements/external_test.go new file mode 100644 index 00000000..18afe843 --- /dev/null +++ b/iac/requirements/external_test.go @@ -0,0 +1,48 @@ +package requirements + +import ( + "context" + "testing" + + pb "github.com/GoCodeAlone/workflow/plugin/external/proto" + "google.golang.org/grpc" +) + +func TestExternalRequirementDiscovery(t *testing.T) { + client := &fakeRequirementDiscoveryClient{ + resp: &pb.DiscoverRequirementsResponse{ + Requirements: []*pb.IaCRequirement{{ + Key: "observability.telemetry.default", + Kind: pb.RequirementKind_REQUIREMENT_KIND_OBSERVABILITY, + }}, + }, + } + provider := ExternalDiscoveryProvider{ + Client: client, + ModuleConfigJSON: []byte(`{"backends":["otel"]}`), + } + + reqs, err := provider.IaCRequirements(context.Background(), Input{Environment: "production"}) + if err != nil { + t.Fatalf("IaCRequirements: %v", err) + } + if string(client.last.GetModuleConfigJson()) != `{"backends":["otel"]}` { + t.Fatalf("module config json = %s", string(client.last.GetModuleConfigJson())) + } + if client.last.GetContext().GetEnvironment() != "production" { + t.Fatalf("context environment = %q", client.last.GetContext().GetEnvironment()) + } + assertHasRequirement(t, reqs, "observability.telemetry.default", KindObservability) +} + +type fakeRequirementDiscoveryClient struct { + pb.IaCRequirementDiscoveryClient + last *pb.DiscoverRequirementsRequest + resp *pb.DiscoverRequirementsResponse + err error +} + +func (f *fakeRequirementDiscoveryClient) DiscoverRequirements(_ context.Context, req *pb.DiscoverRequirementsRequest, _ ...grpc.CallOption) (*pb.DiscoverRequirementsResponse, error) { + f.last = req + return f.resp, f.err +} diff --git a/iac/requirements/types.go b/iac/requirements/types.go new file mode 100644 index 00000000..cfaea808 --- /dev/null +++ b/iac/requirements/types.go @@ -0,0 +1,200 @@ +package requirements + +import ( + "encoding/json" + "fmt" + "regexp" + + pb "github.com/GoCodeAlone/workflow/plugin/external/proto" +) + +type Kind string +type Runtime string +type TelemetrySignal string +type ObservabilityBackend string +type DeploymentMode string + +const ( + KindObservability Kind = "observability" + KindWebAPI Kind = "web_api" + KindMessageBroker Kind = "message_broker" + KindDatabase Kind = "database" + KindCache Kind = "cache" + KindStorage Kind = "storage" + + RuntimeKubernetes Runtime = "kubernetes" + RuntimeECS Runtime = "ecs" + RuntimeCloudRun Runtime = "cloud_run" + RuntimeAzureContainerApps Runtime = "azure_container_apps" + RuntimeDigitalOceanAppPlatform Runtime = "digitalocean_app_platform" + TelemetrySignalTraces TelemetrySignal = "traces" + TelemetrySignalMetrics TelemetrySignal = "metrics" + TelemetrySignalLogs TelemetrySignal = "logs" + ObservabilityBackendOTel ObservabilityBackend = "otel" + ObservabilityBackendDatadog ObservabilityBackend = "datadog" + ObservabilityBackendPrometheus ObservabilityBackend = "prometheus" + ObservabilityBackendLoki ObservabilityBackend = "loki" + ObservabilityBackendGrafana ObservabilityBackend = "grafana" + DeploymentModeSidecar DeploymentMode = "sidecar" + DeploymentModeDaemonSet DeploymentMode = "daemonset" + DeploymentModeSiblingService DeploymentMode = "sibling_service" + DeploymentModeManaged DeploymentMode = "managed" +) + +var requirementKeyPattern = regexp.MustCompile(`^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$`) + +var kindToProto = map[Kind]pb.RequirementKind{ + KindObservability: pb.RequirementKind_REQUIREMENT_KIND_OBSERVABILITY, + KindWebAPI: pb.RequirementKind_REQUIREMENT_KIND_WEB_API, + KindMessageBroker: pb.RequirementKind_REQUIREMENT_KIND_MESSAGE_BROKER, + KindDatabase: pb.RequirementKind_REQUIREMENT_KIND_DATABASE, + KindCache: pb.RequirementKind_REQUIREMENT_KIND_CACHE, + KindStorage: pb.RequirementKind_REQUIREMENT_KIND_STORAGE, +} + +var runtimeToProto = map[Runtime]pb.RequirementRuntime{ + RuntimeKubernetes: pb.RequirementRuntime_REQUIREMENT_RUNTIME_KUBERNETES, + RuntimeECS: pb.RequirementRuntime_REQUIREMENT_RUNTIME_ECS, + RuntimeCloudRun: pb.RequirementRuntime_REQUIREMENT_RUNTIME_CLOUD_RUN, + RuntimeAzureContainerApps: pb.RequirementRuntime_REQUIREMENT_RUNTIME_AZURE_CONTAINER_APPS, + RuntimeDigitalOceanAppPlatform: pb.RequirementRuntime_REQUIREMENT_RUNTIME_DIGITALOCEAN_APP_PLATFORM, +} + +var signalToProto = map[TelemetrySignal]pb.TelemetrySignal{ + TelemetrySignalTraces: pb.TelemetrySignal_TELEMETRY_SIGNAL_TRACES, + TelemetrySignalMetrics: pb.TelemetrySignal_TELEMETRY_SIGNAL_METRICS, + TelemetrySignalLogs: pb.TelemetrySignal_TELEMETRY_SIGNAL_LOGS, +} + +var backendToProto = map[ObservabilityBackend]pb.ObservabilityBackend{ + ObservabilityBackendOTel: pb.ObservabilityBackend_OBSERVABILITY_BACKEND_OTEL, + ObservabilityBackendDatadog: pb.ObservabilityBackend_OBSERVABILITY_BACKEND_DATADOG, + ObservabilityBackendPrometheus: pb.ObservabilityBackend_OBSERVABILITY_BACKEND_PROMETHEUS, + ObservabilityBackendLoki: pb.ObservabilityBackend_OBSERVABILITY_BACKEND_LOKI, + ObservabilityBackendGrafana: pb.ObservabilityBackend_OBSERVABILITY_BACKEND_GRAFANA, +} + +var deploymentModeToProto = map[DeploymentMode]pb.DeploymentMode{ + DeploymentModeSidecar: pb.DeploymentMode_DEPLOYMENT_MODE_SIDECAR, + DeploymentModeDaemonSet: pb.DeploymentMode_DEPLOYMENT_MODE_DAEMONSET, + DeploymentModeSiblingService: pb.DeploymentMode_DEPLOYMENT_MODE_SIBLING_SERVICE, + DeploymentModeManaged: pb.DeploymentMode_DEPLOYMENT_MODE_MANAGED, +} + +// Requirement is Workflow's provider-neutral IaC requirement model. It mirrors +// the strict protobuf contract while staying pleasant to author in Go tests and +// plugin manifest adapters. +type Requirement struct { + Key string + Kind Kind + Source string + ResourceTypeHint string + Environment string + Runtimes []Runtime + TelemetrySignals []TelemetrySignal + ObservabilityBackends []ObservabilityBackend + DeploymentModes []DeploymentMode + VendorFeatures []string + ParametersJSON []byte +} + +func (r Requirement) Validate() error { + if !requirementKeyPattern.MatchString(r.Key) { + return fmt.Errorf("invalid requirement key %q", r.Key) + } + if _, ok := kindToProto[r.Kind]; !ok { + return fmt.Errorf("invalid requirement kind %q", r.Kind) + } + for _, runtime := range r.Runtimes { + if _, ok := runtimeToProto[runtime]; !ok { + return fmt.Errorf("invalid requirement runtime %q", runtime) + } + } + for _, signal := range r.TelemetrySignals { + if _, ok := signalToProto[signal]; !ok { + return fmt.Errorf("invalid telemetry signal %q", signal) + } + } + for _, backend := range r.ObservabilityBackends { + if _, ok := backendToProto[backend]; !ok { + return fmt.Errorf("invalid observability backend %q", backend) + } + } + for _, mode := range r.DeploymentModes { + if _, ok := deploymentModeToProto[mode]; !ok { + return fmt.Errorf("invalid deployment mode %q", mode) + } + } + if len(r.ParametersJSON) > 0 && !json.Valid(r.ParametersJSON) { + return fmt.Errorf("parameters_json is not valid JSON") + } + return nil +} + +func (r Requirement) ToProto() (*pb.IaCRequirement, error) { + if err := r.Validate(); err != nil { + return nil, err + } + return &pb.IaCRequirement{ + Key: r.Key, + Kind: kindToProto[r.Kind], + Source: r.Source, + ResourceTypeHint: r.ResourceTypeHint, + Environment: r.Environment, + Runtimes: mapSlice(r.Runtimes, runtimeToProto), + TelemetrySignals: mapSlice(r.TelemetrySignals, signalToProto), + ObservabilityBackends: mapSlice(r.ObservabilityBackends, backendToProto), + DeploymentModes: mapSlice(r.DeploymentModes, deploymentModeToProto), + VendorFeatures: append([]string(nil), r.VendorFeatures...), + ParametersJson: append([]byte(nil), r.ParametersJSON...), + }, nil +} + +func FromProto(in *pb.IaCRequirement) (Requirement, error) { + if in == nil { + return Requirement{}, fmt.Errorf("iac requirement proto is nil") + } + out := Requirement{ + Key: in.GetKey(), + Kind: reverse(kindToProto, in.GetKind()), + Source: in.GetSource(), + ResourceTypeHint: in.GetResourceTypeHint(), + Environment: in.GetEnvironment(), + Runtimes: reverseSlice(runtimeToProto, in.GetRuntimes()), + TelemetrySignals: reverseSlice(signalToProto, in.GetTelemetrySignals()), + ObservabilityBackends: reverseSlice(backendToProto, in.GetObservabilityBackends()), + DeploymentModes: reverseSlice(deploymentModeToProto, in.GetDeploymentModes()), + VendorFeatures: append([]string(nil), in.GetVendorFeatures()...), + ParametersJSON: append([]byte(nil), in.GetParametersJson()...), + } + if err := out.Validate(); err != nil { + return Requirement{}, err + } + return out, nil +} + +func mapSlice[K comparable, V any](in []K, table map[K]V) []V { + out := make([]V, 0, len(in)) + for _, item := range in { + out = append(out, table[item]) + } + return out +} + +func reverse[K comparable, V comparable](table map[K]V, value V) K { + for k, v := range table { + if v == value { + return k + } + } + var zero K + return zero +} + +func reverseSlice[K comparable, V comparable](table map[K]V, in []V) []K { + out := make([]K, 0, len(in)) + for _, item := range in { + out = append(out, reverse(table, item)) + } + return out +} diff --git a/iac/requirements/types_test.go b/iac/requirements/types_test.go new file mode 100644 index 00000000..571a8446 --- /dev/null +++ b/iac/requirements/types_test.go @@ -0,0 +1,72 @@ +package requirements + +import ( + "testing" + + pb "github.com/GoCodeAlone/workflow/plugin/external/proto" +) + +func TestRequirementValidation(t *testing.T) { + req := Requirement{ + Key: "observability.telemetry.default", + Kind: KindObservability, + Runtimes: []Runtime{RuntimeKubernetes, RuntimeDigitalOceanAppPlatform}, + TelemetrySignals: []TelemetrySignal{TelemetrySignalTraces, TelemetrySignalMetrics, TelemetrySignalLogs}, + ObservabilityBackends: []ObservabilityBackend{ObservabilityBackendOTel, ObservabilityBackendDatadog}, + DeploymentModes: []DeploymentMode{DeploymentModeSidecar, DeploymentModeSiblingService}, + VendorFeatures: []string{"datadog.apm"}, + ResourceTypeHint: "infra.container_service", + ParametersJSON: []byte(`{"collector":"otel"}`), + } + if err := req.Validate(); err != nil { + t.Fatalf("Validate: %v", err) + } +} + +func TestRequirementValidationRejectsInvalidKey(t *testing.T) { + req := Requirement{Key: "CMS telemetry", Kind: KindObservability} + if err := req.Validate(); err == nil { + t.Fatal("expected invalid key error") + } +} + +func TestRequirementValidationRejectsUnknownEnum(t *testing.T) { + req := Requirement{Key: "observability.telemetry.default", Kind: Kind("telemetryish")} + err := req.Validate() + if err == nil { + t.Fatal("expected invalid kind error") + } + if got := err.Error(); got != `invalid requirement kind "telemetryish"` { + t.Fatalf("error = %q", got) + } +} + +func TestRequirementProtoRoundTrip(t *testing.T) { + req := Requirement{ + Key: "observability.telemetry.default", + Kind: KindObservability, + Source: "observability.telemetry", + ResourceTypeHint: "infra.container_service", + Environment: "production", + Runtimes: []Runtime{RuntimeECS}, + TelemetrySignals: []TelemetrySignal{TelemetrySignalTraces}, + ObservabilityBackends: []ObservabilityBackend{ObservabilityBackendOTel}, + DeploymentModes: []DeploymentMode{DeploymentModeSidecar}, + VendorFeatures: []string{"datadog.apm"}, + ParametersJSON: []byte(`{"sample":true}`), + } + proto, err := req.ToProto() + if err != nil { + t.Fatalf("ToProto: %v", err) + } + if proto.Kind != pb.RequirementKind_REQUIREMENT_KIND_OBSERVABILITY { + t.Fatalf("proto kind = %v", proto.Kind) + } + round, err := FromProto(proto) + if err != nil { + t.Fatalf("FromProto: %v", err) + } + if round.Key != req.Key || round.Kind != req.Kind || round.Runtimes[0] != RuntimeECS { + t.Fatalf("round trip = %+v, want %+v", round, req) + } +} diff --git a/plugin/external/proto/iac.pb.go b/plugin/external/proto/iac.pb.go index 944a2bec..1058cbd3 100644 --- a/plugin/external/proto/iac.pb.go +++ b/plugin/external/proto/iac.pb.go @@ -101,6 +101,296 @@ func (DriftClass) EnumDescriptor() ([]byte, []int) { return file_iac_proto_rawDescGZIP(), []int{0} } +// RequirementKind is the provider-neutral infrastructure category that wfctl +// and provider plugins exchange for derived IaC. Values are intentionally +// portable and provider-agnostic. +type RequirementKind int32 + +const ( + RequirementKind_REQUIREMENT_KIND_UNSPECIFIED RequirementKind = 0 + RequirementKind_REQUIREMENT_KIND_OBSERVABILITY RequirementKind = 1 + RequirementKind_REQUIREMENT_KIND_WEB_API RequirementKind = 2 + RequirementKind_REQUIREMENT_KIND_MESSAGE_BROKER RequirementKind = 3 + RequirementKind_REQUIREMENT_KIND_DATABASE RequirementKind = 4 + RequirementKind_REQUIREMENT_KIND_CACHE RequirementKind = 5 + RequirementKind_REQUIREMENT_KIND_STORAGE RequirementKind = 6 +) + +// Enum value maps for RequirementKind. +var ( + RequirementKind_name = map[int32]string{ + 0: "REQUIREMENT_KIND_UNSPECIFIED", + 1: "REQUIREMENT_KIND_OBSERVABILITY", + 2: "REQUIREMENT_KIND_WEB_API", + 3: "REQUIREMENT_KIND_MESSAGE_BROKER", + 4: "REQUIREMENT_KIND_DATABASE", + 5: "REQUIREMENT_KIND_CACHE", + 6: "REQUIREMENT_KIND_STORAGE", + } + RequirementKind_value = map[string]int32{ + "REQUIREMENT_KIND_UNSPECIFIED": 0, + "REQUIREMENT_KIND_OBSERVABILITY": 1, + "REQUIREMENT_KIND_WEB_API": 2, + "REQUIREMENT_KIND_MESSAGE_BROKER": 3, + "REQUIREMENT_KIND_DATABASE": 4, + "REQUIREMENT_KIND_CACHE": 5, + "REQUIREMENT_KIND_STORAGE": 6, + } +) + +func (x RequirementKind) Enum() *RequirementKind { + p := new(RequirementKind) + *p = x + return p +} + +func (x RequirementKind) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (RequirementKind) Descriptor() protoreflect.EnumDescriptor { + return file_iac_proto_enumTypes[1].Descriptor() +} + +func (RequirementKind) Type() protoreflect.EnumType { + return &file_iac_proto_enumTypes[1] +} + +func (x RequirementKind) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use RequirementKind.Descriptor instead. +func (RequirementKind) EnumDescriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{1} +} + +// RequirementRuntime describes the target runtime shape the provider mapper +// should generate for. Provider plugins return diagnostics for unsupported +// runtime/mode combinations instead of emitting malformed modules. +type RequirementRuntime int32 + +const ( + RequirementRuntime_REQUIREMENT_RUNTIME_UNSPECIFIED RequirementRuntime = 0 + RequirementRuntime_REQUIREMENT_RUNTIME_KUBERNETES RequirementRuntime = 1 + RequirementRuntime_REQUIREMENT_RUNTIME_ECS RequirementRuntime = 2 + RequirementRuntime_REQUIREMENT_RUNTIME_CLOUD_RUN RequirementRuntime = 3 + RequirementRuntime_REQUIREMENT_RUNTIME_AZURE_CONTAINER_APPS RequirementRuntime = 4 + RequirementRuntime_REQUIREMENT_RUNTIME_DIGITALOCEAN_APP_PLATFORM RequirementRuntime = 5 +) + +// Enum value maps for RequirementRuntime. +var ( + RequirementRuntime_name = map[int32]string{ + 0: "REQUIREMENT_RUNTIME_UNSPECIFIED", + 1: "REQUIREMENT_RUNTIME_KUBERNETES", + 2: "REQUIREMENT_RUNTIME_ECS", + 3: "REQUIREMENT_RUNTIME_CLOUD_RUN", + 4: "REQUIREMENT_RUNTIME_AZURE_CONTAINER_APPS", + 5: "REQUIREMENT_RUNTIME_DIGITALOCEAN_APP_PLATFORM", + } + RequirementRuntime_value = map[string]int32{ + "REQUIREMENT_RUNTIME_UNSPECIFIED": 0, + "REQUIREMENT_RUNTIME_KUBERNETES": 1, + "REQUIREMENT_RUNTIME_ECS": 2, + "REQUIREMENT_RUNTIME_CLOUD_RUN": 3, + "REQUIREMENT_RUNTIME_AZURE_CONTAINER_APPS": 4, + "REQUIREMENT_RUNTIME_DIGITALOCEAN_APP_PLATFORM": 5, + } +) + +func (x RequirementRuntime) Enum() *RequirementRuntime { + p := new(RequirementRuntime) + *p = x + return p +} + +func (x RequirementRuntime) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (RequirementRuntime) Descriptor() protoreflect.EnumDescriptor { + return file_iac_proto_enumTypes[2].Descriptor() +} + +func (RequirementRuntime) Type() protoreflect.EnumType { + return &file_iac_proto_enumTypes[2] +} + +func (x RequirementRuntime) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use RequirementRuntime.Descriptor instead. +func (RequirementRuntime) EnumDescriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{2} +} + +type TelemetrySignal int32 + +const ( + TelemetrySignal_TELEMETRY_SIGNAL_UNSPECIFIED TelemetrySignal = 0 + TelemetrySignal_TELEMETRY_SIGNAL_TRACES TelemetrySignal = 1 + TelemetrySignal_TELEMETRY_SIGNAL_METRICS TelemetrySignal = 2 + TelemetrySignal_TELEMETRY_SIGNAL_LOGS TelemetrySignal = 3 +) + +// Enum value maps for TelemetrySignal. +var ( + TelemetrySignal_name = map[int32]string{ + 0: "TELEMETRY_SIGNAL_UNSPECIFIED", + 1: "TELEMETRY_SIGNAL_TRACES", + 2: "TELEMETRY_SIGNAL_METRICS", + 3: "TELEMETRY_SIGNAL_LOGS", + } + TelemetrySignal_value = map[string]int32{ + "TELEMETRY_SIGNAL_UNSPECIFIED": 0, + "TELEMETRY_SIGNAL_TRACES": 1, + "TELEMETRY_SIGNAL_METRICS": 2, + "TELEMETRY_SIGNAL_LOGS": 3, + } +) + +func (x TelemetrySignal) Enum() *TelemetrySignal { + p := new(TelemetrySignal) + *p = x + return p +} + +func (x TelemetrySignal) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TelemetrySignal) Descriptor() protoreflect.EnumDescriptor { + return file_iac_proto_enumTypes[3].Descriptor() +} + +func (TelemetrySignal) Type() protoreflect.EnumType { + return &file_iac_proto_enumTypes[3] +} + +func (x TelemetrySignal) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TelemetrySignal.Descriptor instead. +func (TelemetrySignal) EnumDescriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{3} +} + +type ObservabilityBackend int32 + +const ( + ObservabilityBackend_OBSERVABILITY_BACKEND_UNSPECIFIED ObservabilityBackend = 0 + ObservabilityBackend_OBSERVABILITY_BACKEND_OTEL ObservabilityBackend = 1 + ObservabilityBackend_OBSERVABILITY_BACKEND_DATADOG ObservabilityBackend = 2 + ObservabilityBackend_OBSERVABILITY_BACKEND_PROMETHEUS ObservabilityBackend = 3 + ObservabilityBackend_OBSERVABILITY_BACKEND_LOKI ObservabilityBackend = 4 + ObservabilityBackend_OBSERVABILITY_BACKEND_GRAFANA ObservabilityBackend = 5 +) + +// Enum value maps for ObservabilityBackend. +var ( + ObservabilityBackend_name = map[int32]string{ + 0: "OBSERVABILITY_BACKEND_UNSPECIFIED", + 1: "OBSERVABILITY_BACKEND_OTEL", + 2: "OBSERVABILITY_BACKEND_DATADOG", + 3: "OBSERVABILITY_BACKEND_PROMETHEUS", + 4: "OBSERVABILITY_BACKEND_LOKI", + 5: "OBSERVABILITY_BACKEND_GRAFANA", + } + ObservabilityBackend_value = map[string]int32{ + "OBSERVABILITY_BACKEND_UNSPECIFIED": 0, + "OBSERVABILITY_BACKEND_OTEL": 1, + "OBSERVABILITY_BACKEND_DATADOG": 2, + "OBSERVABILITY_BACKEND_PROMETHEUS": 3, + "OBSERVABILITY_BACKEND_LOKI": 4, + "OBSERVABILITY_BACKEND_GRAFANA": 5, + } +) + +func (x ObservabilityBackend) Enum() *ObservabilityBackend { + p := new(ObservabilityBackend) + *p = x + return p +} + +func (x ObservabilityBackend) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ObservabilityBackend) Descriptor() protoreflect.EnumDescriptor { + return file_iac_proto_enumTypes[4].Descriptor() +} + +func (ObservabilityBackend) Type() protoreflect.EnumType { + return &file_iac_proto_enumTypes[4] +} + +func (x ObservabilityBackend) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ObservabilityBackend.Descriptor instead. +func (ObservabilityBackend) EnumDescriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{4} +} + +type DeploymentMode int32 + +const ( + DeploymentMode_DEPLOYMENT_MODE_UNSPECIFIED DeploymentMode = 0 + DeploymentMode_DEPLOYMENT_MODE_SIDECAR DeploymentMode = 1 + DeploymentMode_DEPLOYMENT_MODE_DAEMONSET DeploymentMode = 2 + DeploymentMode_DEPLOYMENT_MODE_SIBLING_SERVICE DeploymentMode = 3 + DeploymentMode_DEPLOYMENT_MODE_MANAGED DeploymentMode = 4 +) + +// Enum value maps for DeploymentMode. +var ( + DeploymentMode_name = map[int32]string{ + 0: "DEPLOYMENT_MODE_UNSPECIFIED", + 1: "DEPLOYMENT_MODE_SIDECAR", + 2: "DEPLOYMENT_MODE_DAEMONSET", + 3: "DEPLOYMENT_MODE_SIBLING_SERVICE", + 4: "DEPLOYMENT_MODE_MANAGED", + } + DeploymentMode_value = map[string]int32{ + "DEPLOYMENT_MODE_UNSPECIFIED": 0, + "DEPLOYMENT_MODE_SIDECAR": 1, + "DEPLOYMENT_MODE_DAEMONSET": 2, + "DEPLOYMENT_MODE_SIBLING_SERVICE": 3, + "DEPLOYMENT_MODE_MANAGED": 4, + } +) + +func (x DeploymentMode) Enum() *DeploymentMode { + p := new(DeploymentMode) + *p = x + return p +} + +func (x DeploymentMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (DeploymentMode) Descriptor() protoreflect.EnumDescriptor { + return file_iac_proto_enumTypes[5].Descriptor() +} + +func (DeploymentMode) Type() protoreflect.EnumType { + return &file_iac_proto_enumTypes[5] +} + +func (x DeploymentMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use DeploymentMode.Descriptor instead. +func (DeploymentMode) EnumDescriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{5} +} + // PlanDiagnosticSeverity mirrors interfaces.PlanDiagnosticSeverity. // Wire ordering matches the Go iota: INFO=0, WARNING=1, ERROR=2. type PlanDiagnosticSeverity int32 @@ -136,11 +426,11 @@ func (x PlanDiagnosticSeverity) String() string { } func (PlanDiagnosticSeverity) Descriptor() protoreflect.EnumDescriptor { - return file_iac_proto_enumTypes[1].Descriptor() + return file_iac_proto_enumTypes[6].Descriptor() } func (PlanDiagnosticSeverity) Type() protoreflect.EnumType { - return &file_iac_proto_enumTypes[1] + return &file_iac_proto_enumTypes[6] } func (x PlanDiagnosticSeverity) Number() protoreflect.EnumNumber { @@ -149,7 +439,7 @@ func (x PlanDiagnosticSeverity) Number() protoreflect.EnumNumber { // Deprecated: Use PlanDiagnosticSeverity.Descriptor instead. func (PlanDiagnosticSeverity) EnumDescriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{1} + return file_iac_proto_rawDescGZIP(), []int{6} } // ActionStatus categorizes per-action outcomes for wfctl-side hook dispatch. @@ -204,11 +494,11 @@ func (x ActionStatus) String() string { } func (ActionStatus) Descriptor() protoreflect.EnumDescriptor { - return file_iac_proto_enumTypes[2].Descriptor() + return file_iac_proto_enumTypes[7].Descriptor() } func (ActionStatus) Type() protoreflect.EnumType { - return &file_iac_proto_enumTypes[2] + return &file_iac_proto_enumTypes[7] } func (x ActionStatus) Number() protoreflect.EnumNumber { @@ -217,7 +507,7 @@ func (x ActionStatus) Number() protoreflect.EnumNumber { // Deprecated: Use ActionStatus.Descriptor instead. func (ActionStatus) EnumDescriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{2} + return file_iac_proto_rawDescGZIP(), []int{7} } // ───────────────────────────────────────────────────────────────────────────── @@ -262,11 +552,11 @@ func (x LogCaptureType) String() string { } func (LogCaptureType) Descriptor() protoreflect.EnumDescriptor { - return file_iac_proto_enumTypes[3].Descriptor() + return file_iac_proto_enumTypes[8].Descriptor() } func (LogCaptureType) Type() protoreflect.EnumType { - return &file_iac_proto_enumTypes[3] + return &file_iac_proto_enumTypes[8] } func (x LogCaptureType) Number() protoreflect.EnumNumber { @@ -275,7 +565,7 @@ func (x LogCaptureType) Number() protoreflect.EnumNumber { // Deprecated: Use LogCaptureType.Descriptor instead. func (LogCaptureType) EnumDescriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{3} + return file_iac_proto_rawDescGZIP(), []int{8} } // ResourceSpec mirrors interfaces.ResourceSpec. @@ -1026,28 +1316,717 @@ func (x *DiffResult) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use DiffResult.ProtoReflect.Descriptor instead. -func (*DiffResult) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{9} +// Deprecated: Use DiffResult.ProtoReflect.Descriptor instead. +func (*DiffResult) Descriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{9} +} + +func (x *DiffResult) GetNeedsUpdate() bool { + if x != nil { + return x.NeedsUpdate + } + return false +} + +func (x *DiffResult) GetNeedsReplace() bool { + if x != nil { + return x.NeedsReplace + } + return false +} + +func (x *DiffResult) GetChanges() []*FieldChange { + if x != nil { + return x.Changes + } + return nil +} + +type IaCRequirement struct { + state protoimpl.MessageState `protogen:"open.v1"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Kind RequirementKind `protobuf:"varint,2,opt,name=kind,proto3,enum=workflow.plugin.external.iac.RequirementKind" json:"kind,omitempty"` + Source string `protobuf:"bytes,3,opt,name=source,proto3" json:"source,omitempty"` + ResourceTypeHint string `protobuf:"bytes,4,opt,name=resource_type_hint,json=resourceTypeHint,proto3" json:"resource_type_hint,omitempty"` + Environment string `protobuf:"bytes,5,opt,name=environment,proto3" json:"environment,omitempty"` + Runtimes []RequirementRuntime `protobuf:"varint,6,rep,packed,name=runtimes,proto3,enum=workflow.plugin.external.iac.RequirementRuntime" json:"runtimes,omitempty"` + TelemetrySignals []TelemetrySignal `protobuf:"varint,7,rep,packed,name=telemetry_signals,json=telemetrySignals,proto3,enum=workflow.plugin.external.iac.TelemetrySignal" json:"telemetry_signals,omitempty"` + ObservabilityBackends []ObservabilityBackend `protobuf:"varint,8,rep,packed,name=observability_backends,json=observabilityBackends,proto3,enum=workflow.plugin.external.iac.ObservabilityBackend" json:"observability_backends,omitempty"` + DeploymentModes []DeploymentMode `protobuf:"varint,9,rep,packed,name=deployment_modes,json=deploymentModes,proto3,enum=workflow.plugin.external.iac.DeploymentMode" json:"deployment_modes,omitempty"` + VendorFeatures []string `protobuf:"bytes,10,rep,name=vendor_features,json=vendorFeatures,proto3" json:"vendor_features,omitempty"` + // parameters_json is JSON-encoded plugin-owned requirement detail for data + // that is not portable enough to promote to a Workflow-owned proto field. + // Prefer adding enum/message fields for portable concepts. + ParametersJson []byte `protobuf:"bytes,11,opt,name=parameters_json,json=parametersJson,proto3" json:"parameters_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *IaCRequirement) Reset() { + *x = IaCRequirement{} + mi := &file_iac_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *IaCRequirement) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IaCRequirement) ProtoMessage() {} + +func (x *IaCRequirement) ProtoReflect() protoreflect.Message { + mi := &file_iac_proto_msgTypes[10] + 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 IaCRequirement.ProtoReflect.Descriptor instead. +func (*IaCRequirement) Descriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{10} +} + +func (x *IaCRequirement) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *IaCRequirement) GetKind() RequirementKind { + if x != nil { + return x.Kind + } + return RequirementKind_REQUIREMENT_KIND_UNSPECIFIED +} + +func (x *IaCRequirement) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *IaCRequirement) GetResourceTypeHint() string { + if x != nil { + return x.ResourceTypeHint + } + return "" +} + +func (x *IaCRequirement) GetEnvironment() string { + if x != nil { + return x.Environment + } + return "" +} + +func (x *IaCRequirement) GetRuntimes() []RequirementRuntime { + if x != nil { + return x.Runtimes + } + return nil +} + +func (x *IaCRequirement) GetTelemetrySignals() []TelemetrySignal { + if x != nil { + return x.TelemetrySignals + } + return nil +} + +func (x *IaCRequirement) GetObservabilityBackends() []ObservabilityBackend { + if x != nil { + return x.ObservabilityBackends + } + return nil +} + +func (x *IaCRequirement) GetDeploymentModes() []DeploymentMode { + if x != nil { + return x.DeploymentModes + } + return nil +} + +func (x *IaCRequirement) GetVendorFeatures() []string { + if x != nil { + return x.VendorFeatures + } + return nil +} + +func (x *IaCRequirement) GetParametersJson() []byte { + if x != nil { + return x.ParametersJson + } + return nil +} + +type DiscoverRequirementsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Context *RequirementContext `protobuf:"bytes,1,opt,name=context,proto3" json:"context,omitempty"` + // module_config_json is JSON-encoded module config owned by the plugin that + // implements IaCRequirementDiscovery. Hosts must not send full Workflow YAML + // or resolved secret values here. + ModuleConfigJson []byte `protobuf:"bytes,2,opt,name=module_config_json,json=moduleConfigJson,proto3" json:"module_config_json,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DiscoverRequirementsRequest) Reset() { + *x = DiscoverRequirementsRequest{} + mi := &file_iac_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DiscoverRequirementsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DiscoverRequirementsRequest) ProtoMessage() {} + +func (x *DiscoverRequirementsRequest) ProtoReflect() protoreflect.Message { + mi := &file_iac_proto_msgTypes[11] + 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 DiscoverRequirementsRequest.ProtoReflect.Descriptor instead. +func (*DiscoverRequirementsRequest) Descriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{11} +} + +func (x *DiscoverRequirementsRequest) GetContext() *RequirementContext { + if x != nil { + return x.Context + } + return nil +} + +func (x *DiscoverRequirementsRequest) GetModuleConfigJson() []byte { + if x != nil { + return x.ModuleConfigJson + } + return nil +} + +type RequirementContext struct { + state protoimpl.MessageState `protogen:"open.v1"` + Application string `protobuf:"bytes,1,opt,name=application,proto3" json:"application,omitempty"` + Environment string `protobuf:"bytes,2,opt,name=environment,proto3" json:"environment,omitempty"` + Modules []*ModuleRef `protobuf:"bytes,3,rep,name=modules,proto3" json:"modules,omitempty"` + PluginIds []string `protobuf:"bytes,4,rep,name=plugin_ids,json=pluginIds,proto3" json:"plugin_ids,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RequirementContext) Reset() { + *x = RequirementContext{} + mi := &file_iac_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RequirementContext) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequirementContext) ProtoMessage() {} + +func (x *RequirementContext) ProtoReflect() protoreflect.Message { + mi := &file_iac_proto_msgTypes[12] + 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 RequirementContext.ProtoReflect.Descriptor instead. +func (*RequirementContext) Descriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{12} +} + +func (x *RequirementContext) GetApplication() string { + if x != nil { + return x.Application + } + return "" +} + +func (x *RequirementContext) GetEnvironment() string { + if x != nil { + return x.Environment + } + return "" +} + +func (x *RequirementContext) GetModules() []*ModuleRef { + if x != nil { + return x.Modules + } + return nil +} + +func (x *RequirementContext) GetPluginIds() []string { + if x != nil { + return x.PluginIds + } + return nil +} + +type ModuleRef struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Satisfies []string `protobuf:"bytes,3,rep,name=satisfies,proto3" json:"satisfies,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ModuleRef) Reset() { + *x = ModuleRef{} + mi := &file_iac_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ModuleRef) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ModuleRef) ProtoMessage() {} + +func (x *ModuleRef) ProtoReflect() protoreflect.Message { + mi := &file_iac_proto_msgTypes[13] + 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 ModuleRef.ProtoReflect.Descriptor instead. +func (*ModuleRef) Descriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{13} +} + +func (x *ModuleRef) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ModuleRef) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *ModuleRef) GetSatisfies() []string { + if x != nil { + return x.Satisfies + } + return nil +} + +type DiscoverRequirementsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Requirements []*IaCRequirement `protobuf:"bytes,1,rep,name=requirements,proto3" json:"requirements,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DiscoverRequirementsResponse) Reset() { + *x = DiscoverRequirementsResponse{} + mi := &file_iac_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DiscoverRequirementsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DiscoverRequirementsResponse) ProtoMessage() {} + +func (x *DiscoverRequirementsResponse) ProtoReflect() protoreflect.Message { + mi := &file_iac_proto_msgTypes[14] + 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 DiscoverRequirementsResponse.ProtoReflect.Descriptor instead. +func (*DiscoverRequirementsResponse) Descriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{14} +} + +func (x *DiscoverRequirementsResponse) GetRequirements() []*IaCRequirement { + if x != nil { + return x.Requirements + } + return nil +} + +type MapRequirementsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Provider string `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` + Runtime RequirementRuntime `protobuf:"varint,2,opt,name=runtime,proto3,enum=workflow.plugin.external.iac.RequirementRuntime" json:"runtime,omitempty"` + Environment string `protobuf:"bytes,3,opt,name=environment,proto3" json:"environment,omitempty"` + Requirements []*IaCRequirement `protobuf:"bytes,4,rep,name=requirements,proto3" json:"requirements,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MapRequirementsRequest) Reset() { + *x = MapRequirementsRequest{} + mi := &file_iac_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MapRequirementsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MapRequirementsRequest) ProtoMessage() {} + +func (x *MapRequirementsRequest) ProtoReflect() protoreflect.Message { + mi := &file_iac_proto_msgTypes[15] + 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 MapRequirementsRequest.ProtoReflect.Descriptor instead. +func (*MapRequirementsRequest) Descriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{15} +} + +func (x *MapRequirementsRequest) GetProvider() string { + if x != nil { + return x.Provider + } + return "" +} + +func (x *MapRequirementsRequest) GetRuntime() RequirementRuntime { + if x != nil { + return x.Runtime + } + return RequirementRuntime_REQUIREMENT_RUNTIME_UNSPECIFIED +} + +func (x *MapRequirementsRequest) GetEnvironment() string { + if x != nil { + return x.Environment + } + return "" +} + +func (x *MapRequirementsRequest) GetRequirements() []*IaCRequirement { + if x != nil { + return x.Requirements + } + return nil +} + +type DerivedModuleSpec struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Satisfies []string `protobuf:"bytes,3,rep,name=satisfies,proto3" json:"satisfies,omitempty"` + // config_json is JSON-encoded provider-owned module config. Provider + // mappers must emit secret placeholders/references, never plaintext secret + // values. + ConfigJson []byte `protobuf:"bytes,4,opt,name=config_json,json=configJson,proto3" json:"config_json,omitempty"` + DependsOn []string `protobuf:"bytes,5,rep,name=depends_on,json=dependsOn,proto3" json:"depends_on,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DerivedModuleSpec) Reset() { + *x = DerivedModuleSpec{} + mi := &file_iac_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DerivedModuleSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DerivedModuleSpec) ProtoMessage() {} + +func (x *DerivedModuleSpec) ProtoReflect() protoreflect.Message { + mi := &file_iac_proto_msgTypes[16] + 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 DerivedModuleSpec.ProtoReflect.Descriptor instead. +func (*DerivedModuleSpec) Descriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{16} +} + +func (x *DerivedModuleSpec) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DerivedModuleSpec) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *DerivedModuleSpec) GetSatisfies() []string { + if x != nil { + return x.Satisfies + } + return nil +} + +func (x *DerivedModuleSpec) GetConfigJson() []byte { + if x != nil { + return x.ConfigJson + } + return nil +} + +func (x *DerivedModuleSpec) GetDependsOn() []string { + if x != nil { + return x.DependsOn + } + return nil +} + +type RequirementDiagnostic struct { + state protoimpl.MessageState `protogen:"open.v1"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"` + Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RequirementDiagnostic) Reset() { + *x = RequirementDiagnostic{} + mi := &file_iac_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RequirementDiagnostic) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequirementDiagnostic) ProtoMessage() {} + +func (x *RequirementDiagnostic) ProtoReflect() protoreflect.Message { + mi := &file_iac_proto_msgTypes[17] + 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 RequirementDiagnostic.ProtoReflect.Descriptor instead. +func (*RequirementDiagnostic) Descriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{17} +} + +func (x *RequirementDiagnostic) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *RequirementDiagnostic) GetCode() string { + if x != nil { + return x.Code + } + return "" +} + +func (x *RequirementDiagnostic) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +type RequirementNote struct { + state protoimpl.MessageState `protogen:"open.v1"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Interactive bool `protobuf:"varint,3,opt,name=interactive,proto3" json:"interactive,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RequirementNote) Reset() { + *x = RequirementNote{} + mi := &file_iac_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RequirementNote) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequirementNote) ProtoMessage() {} + +func (x *RequirementNote) ProtoReflect() protoreflect.Message { + mi := &file_iac_proto_msgTypes[18] + 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 RequirementNote.ProtoReflect.Descriptor instead. +func (*RequirementNote) Descriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{18} +} + +func (x *RequirementNote) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *RequirementNote) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *RequirementNote) GetInteractive() bool { + if x != nil { + return x.Interactive + } + return false +} + +type MapRequirementsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + AcceptedKeys []string `protobuf:"bytes,1,rep,name=accepted_keys,json=acceptedKeys,proto3" json:"accepted_keys,omitempty"` + Rejected []*RequirementDiagnostic `protobuf:"bytes,2,rep,name=rejected,proto3" json:"rejected,omitempty"` + Modules []*DerivedModuleSpec `protobuf:"bytes,3,rep,name=modules,proto3" json:"modules,omitempty"` + Notes []*RequirementNote `protobuf:"bytes,4,rep,name=notes,proto3" json:"notes,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MapRequirementsResponse) Reset() { + *x = MapRequirementsResponse{} + mi := &file_iac_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MapRequirementsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MapRequirementsResponse) ProtoMessage() {} + +func (x *MapRequirementsResponse) ProtoReflect() protoreflect.Message { + mi := &file_iac_proto_msgTypes[19] + 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 MapRequirementsResponse.ProtoReflect.Descriptor instead. +func (*MapRequirementsResponse) Descriptor() ([]byte, []int) { + return file_iac_proto_rawDescGZIP(), []int{19} +} + +func (x *MapRequirementsResponse) GetAcceptedKeys() []string { + if x != nil { + return x.AcceptedKeys + } + return nil } -func (x *DiffResult) GetNeedsUpdate() bool { +func (x *MapRequirementsResponse) GetRejected() []*RequirementDiagnostic { if x != nil { - return x.NeedsUpdate + return x.Rejected } - return false + return nil } -func (x *DiffResult) GetNeedsReplace() bool { +func (x *MapRequirementsResponse) GetModules() []*DerivedModuleSpec { if x != nil { - return x.NeedsReplace + return x.Modules } - return false + return nil } -func (x *DiffResult) GetChanges() []*FieldChange { +func (x *MapRequirementsResponse) GetNotes() []*RequirementNote { if x != nil { - return x.Changes + return x.Notes } return nil } @@ -1068,7 +2047,7 @@ type DriftResult struct { func (x *DriftResult) Reset() { *x = DriftResult{} - mi := &file_iac_proto_msgTypes[10] + mi := &file_iac_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1080,7 +2059,7 @@ func (x *DriftResult) String() string { func (*DriftResult) ProtoMessage() {} func (x *DriftResult) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[10] + mi := &file_iac_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1093,7 +2072,7 @@ func (x *DriftResult) ProtoReflect() protoreflect.Message { // Deprecated: Use DriftResult.ProtoReflect.Descriptor instead. func (*DriftResult) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{10} + return file_iac_proto_rawDescGZIP(), []int{20} } func (x *DriftResult) GetName() string { @@ -1157,7 +2136,7 @@ type DriftEntry struct { func (x *DriftEntry) Reset() { *x = DriftEntry{} - mi := &file_iac_proto_msgTypes[11] + mi := &file_iac_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1169,7 +2148,7 @@ func (x *DriftEntry) String() string { func (*DriftEntry) ProtoMessage() {} func (x *DriftEntry) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[11] + mi := &file_iac_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1182,7 +2161,7 @@ func (x *DriftEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use DriftEntry.ProtoReflect.Descriptor instead. func (*DriftEntry) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{11} + return file_iac_proto_rawDescGZIP(), []int{21} } func (x *DriftEntry) GetName() string { @@ -1217,7 +2196,7 @@ type HealthResult struct { func (x *HealthResult) Reset() { *x = HealthResult{} - mi := &file_iac_proto_msgTypes[12] + mi := &file_iac_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1229,7 +2208,7 @@ func (x *HealthResult) String() string { func (*HealthResult) ProtoMessage() {} func (x *HealthResult) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[12] + mi := &file_iac_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1242,7 +2221,7 @@ func (x *HealthResult) ProtoReflect() protoreflect.Message { // Deprecated: Use HealthResult.ProtoReflect.Descriptor instead. func (*HealthResult) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{12} + return file_iac_proto_rawDescGZIP(), []int{22} } func (x *HealthResult) GetHealthy() bool { @@ -1273,7 +2252,7 @@ type Diagnostic struct { func (x *Diagnostic) Reset() { *x = Diagnostic{} - mi := &file_iac_proto_msgTypes[13] + mi := &file_iac_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1285,7 +2264,7 @@ func (x *Diagnostic) String() string { func (*Diagnostic) ProtoMessage() {} func (x *Diagnostic) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[13] + mi := &file_iac_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1298,7 +2277,7 @@ func (x *Diagnostic) ProtoReflect() protoreflect.Message { // Deprecated: Use Diagnostic.ProtoReflect.Descriptor instead. func (*Diagnostic) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{13} + return file_iac_proto_rawDescGZIP(), []int{23} } func (x *Diagnostic) GetId() string { @@ -1349,7 +2328,7 @@ type PlanDiagnostic struct { func (x *PlanDiagnostic) Reset() { *x = PlanDiagnostic{} - mi := &file_iac_proto_msgTypes[14] + mi := &file_iac_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1361,7 +2340,7 @@ func (x *PlanDiagnostic) String() string { func (*PlanDiagnostic) ProtoMessage() {} func (x *PlanDiagnostic) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[14] + mi := &file_iac_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1374,7 +2353,7 @@ func (x *PlanDiagnostic) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanDiagnostic.ProtoReflect.Descriptor instead. func (*PlanDiagnostic) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{14} + return file_iac_proto_rawDescGZIP(), []int{24} } func (x *PlanDiagnostic) GetSeverity() PlanDiagnosticSeverity { @@ -1419,7 +2398,7 @@ type PlanAction struct { func (x *PlanAction) Reset() { *x = PlanAction{} - mi := &file_iac_proto_msgTypes[15] + mi := &file_iac_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1431,7 +2410,7 @@ func (x *PlanAction) String() string { func (*PlanAction) ProtoMessage() {} func (x *PlanAction) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[15] + mi := &file_iac_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1444,7 +2423,7 @@ func (x *PlanAction) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanAction.ProtoReflect.Descriptor instead. func (*PlanAction) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{15} + return file_iac_proto_rawDescGZIP(), []int{25} } func (x *PlanAction) GetAction() string { @@ -1497,7 +2476,7 @@ type IaCPlan struct { func (x *IaCPlan) Reset() { *x = IaCPlan{} - mi := &file_iac_proto_msgTypes[16] + mi := &file_iac_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1509,7 +2488,7 @@ func (x *IaCPlan) String() string { func (*IaCPlan) ProtoMessage() {} func (x *IaCPlan) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[16] + mi := &file_iac_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1522,7 +2501,7 @@ func (x *IaCPlan) ProtoReflect() protoreflect.Message { // Deprecated: Use IaCPlan.ProtoReflect.Descriptor instead. func (*IaCPlan) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{16} + return file_iac_proto_rawDescGZIP(), []int{26} } func (x *IaCPlan) GetId() string { @@ -1579,7 +2558,7 @@ type ActionError struct { func (x *ActionError) Reset() { *x = ActionError{} - mi := &file_iac_proto_msgTypes[17] + mi := &file_iac_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1591,7 +2570,7 @@ func (x *ActionError) String() string { func (*ActionError) ProtoMessage() {} func (x *ActionError) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[17] + mi := &file_iac_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1604,7 +2583,7 @@ func (x *ActionError) ProtoReflect() protoreflect.Message { // Deprecated: Use ActionError.ProtoReflect.Descriptor instead. func (*ActionError) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{17} + return file_iac_proto_rawDescGZIP(), []int{27} } func (x *ActionError) GetResource() string { @@ -1639,7 +2618,7 @@ type DestroyResult struct { func (x *DestroyResult) Reset() { *x = DestroyResult{} - mi := &file_iac_proto_msgTypes[18] + mi := &file_iac_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1651,7 +2630,7 @@ func (x *DestroyResult) String() string { func (*DestroyResult) ProtoMessage() {} func (x *DestroyResult) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[18] + mi := &file_iac_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1664,7 +2643,7 @@ func (x *DestroyResult) ProtoReflect() protoreflect.Message { // Deprecated: Use DestroyResult.ProtoReflect.Descriptor instead. func (*DestroyResult) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{18} + return file_iac_proto_rawDescGZIP(), []int{28} } func (x *DestroyResult) GetDestroyed() []string { @@ -1694,7 +2673,7 @@ type BootstrapResult struct { func (x *BootstrapResult) Reset() { *x = BootstrapResult{} - mi := &file_iac_proto_msgTypes[19] + mi := &file_iac_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1706,7 +2685,7 @@ func (x *BootstrapResult) String() string { func (*BootstrapResult) ProtoMessage() {} func (x *BootstrapResult) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[19] + mi := &file_iac_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1719,7 +2698,7 @@ func (x *BootstrapResult) ProtoReflect() protoreflect.Message { // Deprecated: Use BootstrapResult.ProtoReflect.Descriptor instead. func (*BootstrapResult) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{19} + return file_iac_proto_rawDescGZIP(), []int{29} } func (x *BootstrapResult) GetBucket() string { @@ -1772,7 +2751,7 @@ type MigrationRepairRequest struct { func (x *MigrationRepairRequest) Reset() { *x = MigrationRepairRequest{} - mi := &file_iac_proto_msgTypes[20] + mi := &file_iac_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1784,7 +2763,7 @@ func (x *MigrationRepairRequest) String() string { func (*MigrationRepairRequest) ProtoMessage() {} func (x *MigrationRepairRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[20] + mi := &file_iac_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1797,7 +2776,7 @@ func (x *MigrationRepairRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MigrationRepairRequest.ProtoReflect.Descriptor instead. func (*MigrationRepairRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{20} + return file_iac_proto_rawDescGZIP(), []int{30} } func (x *MigrationRepairRequest) GetAppResourceName() string { @@ -1893,7 +2872,7 @@ type MigrationRepairResult struct { func (x *MigrationRepairResult) Reset() { *x = MigrationRepairResult{} - mi := &file_iac_proto_msgTypes[21] + mi := &file_iac_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1905,7 +2884,7 @@ func (x *MigrationRepairResult) String() string { func (*MigrationRepairResult) ProtoMessage() {} func (x *MigrationRepairResult) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[21] + mi := &file_iac_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1918,7 +2897,7 @@ func (x *MigrationRepairResult) ProtoReflect() protoreflect.Message { // Deprecated: Use MigrationRepairResult.ProtoReflect.Descriptor instead. func (*MigrationRepairResult) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{21} + return file_iac_proto_rawDescGZIP(), []int{31} } func (x *MigrationRepairResult) GetProviderJobId() string { @@ -1966,7 +2945,7 @@ type InitializeRequest struct { func (x *InitializeRequest) Reset() { *x = InitializeRequest{} - mi := &file_iac_proto_msgTypes[22] + mi := &file_iac_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1978,7 +2957,7 @@ func (x *InitializeRequest) String() string { func (*InitializeRequest) ProtoMessage() {} func (x *InitializeRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[22] + mi := &file_iac_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1991,7 +2970,7 @@ func (x *InitializeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use InitializeRequest.ProtoReflect.Descriptor instead. func (*InitializeRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{22} + return file_iac_proto_rawDescGZIP(), []int{32} } func (x *InitializeRequest) GetConfigJson() []byte { @@ -2009,7 +2988,7 @@ type InitializeResponse struct { func (x *InitializeResponse) Reset() { *x = InitializeResponse{} - mi := &file_iac_proto_msgTypes[23] + mi := &file_iac_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2021,7 +3000,7 @@ func (x *InitializeResponse) String() string { func (*InitializeResponse) ProtoMessage() {} func (x *InitializeResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[23] + mi := &file_iac_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2034,7 +3013,7 @@ func (x *InitializeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use InitializeResponse.ProtoReflect.Descriptor instead. func (*InitializeResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{23} + return file_iac_proto_rawDescGZIP(), []int{33} } type NameRequest struct { @@ -2045,7 +3024,7 @@ type NameRequest struct { func (x *NameRequest) Reset() { *x = NameRequest{} - mi := &file_iac_proto_msgTypes[24] + mi := &file_iac_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2057,7 +3036,7 @@ func (x *NameRequest) String() string { func (*NameRequest) ProtoMessage() {} func (x *NameRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[24] + mi := &file_iac_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2070,7 +3049,7 @@ func (x *NameRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use NameRequest.ProtoReflect.Descriptor instead. func (*NameRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{24} + return file_iac_proto_rawDescGZIP(), []int{34} } type NameResponse struct { @@ -2082,7 +3061,7 @@ type NameResponse struct { func (x *NameResponse) Reset() { *x = NameResponse{} - mi := &file_iac_proto_msgTypes[25] + mi := &file_iac_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2094,7 +3073,7 @@ func (x *NameResponse) String() string { func (*NameResponse) ProtoMessage() {} func (x *NameResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[25] + mi := &file_iac_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2107,7 +3086,7 @@ func (x *NameResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use NameResponse.ProtoReflect.Descriptor instead. func (*NameResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{25} + return file_iac_proto_rawDescGZIP(), []int{35} } func (x *NameResponse) GetName() string { @@ -2125,7 +3104,7 @@ type VersionRequest struct { func (x *VersionRequest) Reset() { *x = VersionRequest{} - mi := &file_iac_proto_msgTypes[26] + mi := &file_iac_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2137,7 +3116,7 @@ func (x *VersionRequest) String() string { func (*VersionRequest) ProtoMessage() {} func (x *VersionRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[26] + mi := &file_iac_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2150,7 +3129,7 @@ func (x *VersionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionRequest.ProtoReflect.Descriptor instead. func (*VersionRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{26} + return file_iac_proto_rawDescGZIP(), []int{36} } type VersionResponse struct { @@ -2162,7 +3141,7 @@ type VersionResponse struct { func (x *VersionResponse) Reset() { *x = VersionResponse{} - mi := &file_iac_proto_msgTypes[27] + mi := &file_iac_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2174,7 +3153,7 @@ func (x *VersionResponse) String() string { func (*VersionResponse) ProtoMessage() {} func (x *VersionResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[27] + mi := &file_iac_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2187,7 +3166,7 @@ func (x *VersionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionResponse.ProtoReflect.Descriptor instead. func (*VersionResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{27} + return file_iac_proto_rawDescGZIP(), []int{37} } func (x *VersionResponse) GetVersion() string { @@ -2205,7 +3184,7 @@ type CapabilitiesRequest struct { func (x *CapabilitiesRequest) Reset() { *x = CapabilitiesRequest{} - mi := &file_iac_proto_msgTypes[28] + mi := &file_iac_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2217,7 +3196,7 @@ func (x *CapabilitiesRequest) String() string { func (*CapabilitiesRequest) ProtoMessage() {} func (x *CapabilitiesRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[28] + mi := &file_iac_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2230,7 +3209,7 @@ func (x *CapabilitiesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CapabilitiesRequest.ProtoReflect.Descriptor instead. func (*CapabilitiesRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{28} + return file_iac_proto_rawDescGZIP(), []int{38} } type CapabilitiesResponse struct { @@ -2254,7 +3233,7 @@ type CapabilitiesResponse struct { func (x *CapabilitiesResponse) Reset() { *x = CapabilitiesResponse{} - mi := &file_iac_proto_msgTypes[29] + mi := &file_iac_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2266,7 +3245,7 @@ func (x *CapabilitiesResponse) String() string { func (*CapabilitiesResponse) ProtoMessage() {} func (x *CapabilitiesResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[29] + mi := &file_iac_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2279,7 +3258,7 @@ func (x *CapabilitiesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CapabilitiesResponse.ProtoReflect.Descriptor instead. func (*CapabilitiesResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{29} + return file_iac_proto_rawDescGZIP(), []int{39} } func (x *CapabilitiesResponse) GetCapabilities() []*IaCCapabilityDeclaration { @@ -2313,7 +3292,7 @@ type PlanRequest struct { func (x *PlanRequest) Reset() { *x = PlanRequest{} - mi := &file_iac_proto_msgTypes[30] + mi := &file_iac_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2325,7 +3304,7 @@ func (x *PlanRequest) String() string { func (*PlanRequest) ProtoMessage() {} func (x *PlanRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[30] + mi := &file_iac_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2338,7 +3317,7 @@ func (x *PlanRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanRequest.ProtoReflect.Descriptor instead. func (*PlanRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{30} + return file_iac_proto_rawDescGZIP(), []int{40} } func (x *PlanRequest) GetDesired() []*ResourceSpec { @@ -2364,7 +3343,7 @@ type PlanResponse struct { func (x *PlanResponse) Reset() { *x = PlanResponse{} - mi := &file_iac_proto_msgTypes[31] + mi := &file_iac_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2376,7 +3355,7 @@ func (x *PlanResponse) String() string { func (*PlanResponse) ProtoMessage() {} func (x *PlanResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[31] + mi := &file_iac_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2389,7 +3368,7 @@ func (x *PlanResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanResponse.ProtoReflect.Descriptor instead. func (*PlanResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{31} + return file_iac_proto_rawDescGZIP(), []int{41} } func (x *PlanResponse) GetPlan() *IaCPlan { @@ -2408,7 +3387,7 @@ type DestroyRequest struct { func (x *DestroyRequest) Reset() { *x = DestroyRequest{} - mi := &file_iac_proto_msgTypes[32] + mi := &file_iac_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2420,7 +3399,7 @@ func (x *DestroyRequest) String() string { func (*DestroyRequest) ProtoMessage() {} func (x *DestroyRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[32] + mi := &file_iac_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2433,7 +3412,7 @@ func (x *DestroyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DestroyRequest.ProtoReflect.Descriptor instead. func (*DestroyRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{32} + return file_iac_proto_rawDescGZIP(), []int{42} } func (x *DestroyRequest) GetRefs() []*ResourceRef { @@ -2452,7 +3431,7 @@ type DestroyResponse struct { func (x *DestroyResponse) Reset() { *x = DestroyResponse{} - mi := &file_iac_proto_msgTypes[33] + mi := &file_iac_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2464,7 +3443,7 @@ func (x *DestroyResponse) String() string { func (*DestroyResponse) ProtoMessage() {} func (x *DestroyResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[33] + mi := &file_iac_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2477,7 +3456,7 @@ func (x *DestroyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DestroyResponse.ProtoReflect.Descriptor instead. func (*DestroyResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{33} + return file_iac_proto_rawDescGZIP(), []int{43} } func (x *DestroyResponse) GetResult() *DestroyResult { @@ -2496,7 +3475,7 @@ type StatusRequest struct { func (x *StatusRequest) Reset() { *x = StatusRequest{} - mi := &file_iac_proto_msgTypes[34] + mi := &file_iac_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2508,7 +3487,7 @@ func (x *StatusRequest) String() string { func (*StatusRequest) ProtoMessage() {} func (x *StatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[34] + mi := &file_iac_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2521,7 +3500,7 @@ func (x *StatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusRequest.ProtoReflect.Descriptor instead. func (*StatusRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{34} + return file_iac_proto_rawDescGZIP(), []int{44} } func (x *StatusRequest) GetRefs() []*ResourceRef { @@ -2540,7 +3519,7 @@ type StatusResponse struct { func (x *StatusResponse) Reset() { *x = StatusResponse{} - mi := &file_iac_proto_msgTypes[35] + mi := &file_iac_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2552,7 +3531,7 @@ func (x *StatusResponse) String() string { func (*StatusResponse) ProtoMessage() {} func (x *StatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[35] + mi := &file_iac_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2565,7 +3544,7 @@ func (x *StatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead. func (*StatusResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{35} + return file_iac_proto_rawDescGZIP(), []int{45} } func (x *StatusResponse) GetStatuses() []*ResourceStatus { @@ -2585,7 +3564,7 @@ type ImportRequest struct { func (x *ImportRequest) Reset() { *x = ImportRequest{} - mi := &file_iac_proto_msgTypes[36] + mi := &file_iac_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2597,7 +3576,7 @@ func (x *ImportRequest) String() string { func (*ImportRequest) ProtoMessage() {} func (x *ImportRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[36] + mi := &file_iac_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2610,7 +3589,7 @@ func (x *ImportRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ImportRequest.ProtoReflect.Descriptor instead. func (*ImportRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{36} + return file_iac_proto_rawDescGZIP(), []int{46} } func (x *ImportRequest) GetProviderId() string { @@ -2636,7 +3615,7 @@ type ImportResponse struct { func (x *ImportResponse) Reset() { *x = ImportResponse{} - mi := &file_iac_proto_msgTypes[37] + mi := &file_iac_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2648,7 +3627,7 @@ func (x *ImportResponse) String() string { func (*ImportResponse) ProtoMessage() {} func (x *ImportResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[37] + mi := &file_iac_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2661,7 +3640,7 @@ func (x *ImportResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ImportResponse.ProtoReflect.Descriptor instead. func (*ImportResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{37} + return file_iac_proto_rawDescGZIP(), []int{47} } func (x *ImportResponse) GetState() *ResourceState { @@ -2682,7 +3661,7 @@ type ResolveSizingRequest struct { func (x *ResolveSizingRequest) Reset() { *x = ResolveSizingRequest{} - mi := &file_iac_proto_msgTypes[38] + mi := &file_iac_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2694,7 +3673,7 @@ func (x *ResolveSizingRequest) String() string { func (*ResolveSizingRequest) ProtoMessage() {} func (x *ResolveSizingRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[38] + mi := &file_iac_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2707,7 +3686,7 @@ func (x *ResolveSizingRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResolveSizingRequest.ProtoReflect.Descriptor instead. func (*ResolveSizingRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{38} + return file_iac_proto_rawDescGZIP(), []int{48} } func (x *ResolveSizingRequest) GetResourceType() string { @@ -2740,7 +3719,7 @@ type ResolveSizingResponse struct { func (x *ResolveSizingResponse) Reset() { *x = ResolveSizingResponse{} - mi := &file_iac_proto_msgTypes[39] + mi := &file_iac_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2752,7 +3731,7 @@ func (x *ResolveSizingResponse) String() string { func (*ResolveSizingResponse) ProtoMessage() {} func (x *ResolveSizingResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[39] + mi := &file_iac_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2765,7 +3744,7 @@ func (x *ResolveSizingResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResolveSizingResponse.ProtoReflect.Descriptor instead. func (*ResolveSizingResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{39} + return file_iac_proto_rawDescGZIP(), []int{49} } func (x *ResolveSizingResponse) GetSizing() *ProviderSizing { @@ -2785,7 +3764,7 @@ type BootstrapStateBackendRequest struct { func (x *BootstrapStateBackendRequest) Reset() { *x = BootstrapStateBackendRequest{} - mi := &file_iac_proto_msgTypes[40] + mi := &file_iac_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2797,7 +3776,7 @@ func (x *BootstrapStateBackendRequest) String() string { func (*BootstrapStateBackendRequest) ProtoMessage() {} func (x *BootstrapStateBackendRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[40] + mi := &file_iac_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2810,7 +3789,7 @@ func (x *BootstrapStateBackendRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BootstrapStateBackendRequest.ProtoReflect.Descriptor instead. func (*BootstrapStateBackendRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{40} + return file_iac_proto_rawDescGZIP(), []int{50} } func (x *BootstrapStateBackendRequest) GetConfigJson() []byte { @@ -2829,7 +3808,7 @@ type BootstrapStateBackendResponse struct { func (x *BootstrapStateBackendResponse) Reset() { *x = BootstrapStateBackendResponse{} - mi := &file_iac_proto_msgTypes[41] + mi := &file_iac_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2841,7 +3820,7 @@ func (x *BootstrapStateBackendResponse) String() string { func (*BootstrapStateBackendResponse) ProtoMessage() {} func (x *BootstrapStateBackendResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[41] + mi := &file_iac_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2854,7 +3833,7 @@ func (x *BootstrapStateBackendResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BootstrapStateBackendResponse.ProtoReflect.Descriptor instead. func (*BootstrapStateBackendResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{41} + return file_iac_proto_rawDescGZIP(), []int{51} } func (x *BootstrapStateBackendResponse) GetResult() *BootstrapResult { @@ -2876,7 +3855,7 @@ type EnumerateAllRequest struct { func (x *EnumerateAllRequest) Reset() { *x = EnumerateAllRequest{} - mi := &file_iac_proto_msgTypes[42] + mi := &file_iac_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2888,7 +3867,7 @@ func (x *EnumerateAllRequest) String() string { func (*EnumerateAllRequest) ProtoMessage() {} func (x *EnumerateAllRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[42] + mi := &file_iac_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2901,7 +3880,7 @@ func (x *EnumerateAllRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EnumerateAllRequest.ProtoReflect.Descriptor instead. func (*EnumerateAllRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{42} + return file_iac_proto_rawDescGZIP(), []int{52} } func (x *EnumerateAllRequest) GetResourceType() string { @@ -2920,7 +3899,7 @@ type EnumerateAllResponse struct { func (x *EnumerateAllResponse) Reset() { *x = EnumerateAllResponse{} - mi := &file_iac_proto_msgTypes[43] + mi := &file_iac_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2932,7 +3911,7 @@ func (x *EnumerateAllResponse) String() string { func (*EnumerateAllResponse) ProtoMessage() {} func (x *EnumerateAllResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[43] + mi := &file_iac_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2945,7 +3924,7 @@ func (x *EnumerateAllResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EnumerateAllResponse.ProtoReflect.Descriptor instead. func (*EnumerateAllResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{43} + return file_iac_proto_rawDescGZIP(), []int{53} } func (x *EnumerateAllResponse) GetOutputs() []*ResourceOutput { @@ -2964,7 +3943,7 @@ type EnumerateByTagRequest struct { func (x *EnumerateByTagRequest) Reset() { *x = EnumerateByTagRequest{} - mi := &file_iac_proto_msgTypes[44] + mi := &file_iac_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2976,7 +3955,7 @@ func (x *EnumerateByTagRequest) String() string { func (*EnumerateByTagRequest) ProtoMessage() {} func (x *EnumerateByTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[44] + mi := &file_iac_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2989,7 +3968,7 @@ func (x *EnumerateByTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EnumerateByTagRequest.ProtoReflect.Descriptor instead. func (*EnumerateByTagRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{44} + return file_iac_proto_rawDescGZIP(), []int{54} } func (x *EnumerateByTagRequest) GetTag() string { @@ -3008,7 +3987,7 @@ type EnumerateByTagResponse struct { func (x *EnumerateByTagResponse) Reset() { *x = EnumerateByTagResponse{} - mi := &file_iac_proto_msgTypes[45] + mi := &file_iac_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3020,7 +3999,7 @@ func (x *EnumerateByTagResponse) String() string { func (*EnumerateByTagResponse) ProtoMessage() {} func (x *EnumerateByTagResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[45] + mi := &file_iac_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3033,7 +4012,7 @@ func (x *EnumerateByTagResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EnumerateByTagResponse.ProtoReflect.Descriptor instead. func (*EnumerateByTagResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{45} + return file_iac_proto_rawDescGZIP(), []int{55} } func (x *EnumerateByTagResponse) GetRefs() []*ResourceRef { @@ -3055,7 +4034,7 @@ type DetectDriftRequest struct { func (x *DetectDriftRequest) Reset() { *x = DetectDriftRequest{} - mi := &file_iac_proto_msgTypes[46] + mi := &file_iac_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3067,7 +4046,7 @@ func (x *DetectDriftRequest) String() string { func (*DetectDriftRequest) ProtoMessage() {} func (x *DetectDriftRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[46] + mi := &file_iac_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3080,7 +4059,7 @@ func (x *DetectDriftRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DetectDriftRequest.ProtoReflect.Descriptor instead. func (*DetectDriftRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{46} + return file_iac_proto_rawDescGZIP(), []int{56} } func (x *DetectDriftRequest) GetRefs() []*ResourceRef { @@ -3099,7 +4078,7 @@ type DetectDriftResponse struct { func (x *DetectDriftResponse) Reset() { *x = DetectDriftResponse{} - mi := &file_iac_proto_msgTypes[47] + mi := &file_iac_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3111,7 +4090,7 @@ func (x *DetectDriftResponse) String() string { func (*DetectDriftResponse) ProtoMessage() {} func (x *DetectDriftResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[47] + mi := &file_iac_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3124,7 +4103,7 @@ func (x *DetectDriftResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DetectDriftResponse.ProtoReflect.Descriptor instead. func (*DetectDriftResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{47} + return file_iac_proto_rawDescGZIP(), []int{57} } func (x *DetectDriftResponse) GetDrifts() []*DriftResult { @@ -3146,7 +4125,7 @@ type DetectDriftWithSpecsRequest struct { func (x *DetectDriftWithSpecsRequest) Reset() { *x = DetectDriftWithSpecsRequest{} - mi := &file_iac_proto_msgTypes[48] + mi := &file_iac_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3158,7 +4137,7 @@ func (x *DetectDriftWithSpecsRequest) String() string { func (*DetectDriftWithSpecsRequest) ProtoMessage() {} func (x *DetectDriftWithSpecsRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[48] + mi := &file_iac_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3171,7 +4150,7 @@ func (x *DetectDriftWithSpecsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DetectDriftWithSpecsRequest.ProtoReflect.Descriptor instead. func (*DetectDriftWithSpecsRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{48} + return file_iac_proto_rawDescGZIP(), []int{58} } func (x *DetectDriftWithSpecsRequest) GetRefs() []*ResourceRef { @@ -3197,7 +4176,7 @@ type DetectDriftWithSpecsResponse struct { func (x *DetectDriftWithSpecsResponse) Reset() { *x = DetectDriftWithSpecsResponse{} - mi := &file_iac_proto_msgTypes[49] + mi := &file_iac_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3209,7 +4188,7 @@ func (x *DetectDriftWithSpecsResponse) String() string { func (*DetectDriftWithSpecsResponse) ProtoMessage() {} func (x *DetectDriftWithSpecsResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[49] + mi := &file_iac_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3222,7 +4201,7 @@ func (x *DetectDriftWithSpecsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DetectDriftWithSpecsResponse.ProtoReflect.Descriptor instead. func (*DetectDriftWithSpecsResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{49} + return file_iac_proto_rawDescGZIP(), []int{59} } func (x *DetectDriftWithSpecsResponse) GetDrifts() []*DriftResult { @@ -3247,7 +4226,7 @@ type RevokeProviderCredentialRequest struct { func (x *RevokeProviderCredentialRequest) Reset() { *x = RevokeProviderCredentialRequest{} - mi := &file_iac_proto_msgTypes[50] + mi := &file_iac_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3259,7 +4238,7 @@ func (x *RevokeProviderCredentialRequest) String() string { func (*RevokeProviderCredentialRequest) ProtoMessage() {} func (x *RevokeProviderCredentialRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[50] + mi := &file_iac_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3272,7 +4251,7 @@ func (x *RevokeProviderCredentialRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RevokeProviderCredentialRequest.ProtoReflect.Descriptor instead. func (*RevokeProviderCredentialRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{50} + return file_iac_proto_rawDescGZIP(), []int{60} } func (x *RevokeProviderCredentialRequest) GetSource() string { @@ -3297,7 +4276,7 @@ type RevokeProviderCredentialResponse struct { func (x *RevokeProviderCredentialResponse) Reset() { *x = RevokeProviderCredentialResponse{} - mi := &file_iac_proto_msgTypes[51] + mi := &file_iac_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3309,7 +4288,7 @@ func (x *RevokeProviderCredentialResponse) String() string { func (*RevokeProviderCredentialResponse) ProtoMessage() {} func (x *RevokeProviderCredentialResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[51] + mi := &file_iac_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3322,7 +4301,7 @@ func (x *RevokeProviderCredentialResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RevokeProviderCredentialResponse.ProtoReflect.Descriptor instead. func (*RevokeProviderCredentialResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{51} + return file_iac_proto_rawDescGZIP(), []int{61} } // ───────────────────────────────────────────────────────────────────────────── @@ -3339,7 +4318,7 @@ type FinalizeApplyRequest struct { func (x *FinalizeApplyRequest) Reset() { *x = FinalizeApplyRequest{} - mi := &file_iac_proto_msgTypes[52] + mi := &file_iac_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3351,7 +4330,7 @@ func (x *FinalizeApplyRequest) String() string { func (*FinalizeApplyRequest) ProtoMessage() {} func (x *FinalizeApplyRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[52] + mi := &file_iac_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3364,7 +4343,7 @@ func (x *FinalizeApplyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FinalizeApplyRequest.ProtoReflect.Descriptor instead. func (*FinalizeApplyRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{52} + return file_iac_proto_rawDescGZIP(), []int{62} } func (x *FinalizeApplyRequest) GetPlanId() string { @@ -3399,7 +4378,7 @@ type FinalizeApplyResponse struct { func (x *FinalizeApplyResponse) Reset() { *x = FinalizeApplyResponse{} - mi := &file_iac_proto_msgTypes[53] + mi := &file_iac_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3411,7 +4390,7 @@ func (x *FinalizeApplyResponse) String() string { func (*FinalizeApplyResponse) ProtoMessage() {} func (x *FinalizeApplyResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[53] + mi := &file_iac_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3424,7 +4403,7 @@ func (x *FinalizeApplyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FinalizeApplyResponse.ProtoReflect.Descriptor instead. func (*FinalizeApplyResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{53} + return file_iac_proto_rawDescGZIP(), []int{63} } func (x *FinalizeApplyResponse) GetErrors() []*ActionError { @@ -3446,7 +4425,7 @@ type RepairDirtyMigrationRequest struct { func (x *RepairDirtyMigrationRequest) Reset() { *x = RepairDirtyMigrationRequest{} - mi := &file_iac_proto_msgTypes[54] + mi := &file_iac_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3458,7 +4437,7 @@ func (x *RepairDirtyMigrationRequest) String() string { func (*RepairDirtyMigrationRequest) ProtoMessage() {} func (x *RepairDirtyMigrationRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[54] + mi := &file_iac_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3471,7 +4450,7 @@ func (x *RepairDirtyMigrationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RepairDirtyMigrationRequest.ProtoReflect.Descriptor instead. func (*RepairDirtyMigrationRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{54} + return file_iac_proto_rawDescGZIP(), []int{64} } func (x *RepairDirtyMigrationRequest) GetRequest() *MigrationRepairRequest { @@ -3490,7 +4469,7 @@ type RepairDirtyMigrationResponse struct { func (x *RepairDirtyMigrationResponse) Reset() { *x = RepairDirtyMigrationResponse{} - mi := &file_iac_proto_msgTypes[55] + mi := &file_iac_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3502,7 +4481,7 @@ func (x *RepairDirtyMigrationResponse) String() string { func (*RepairDirtyMigrationResponse) ProtoMessage() {} func (x *RepairDirtyMigrationResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[55] + mi := &file_iac_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3515,7 +4494,7 @@ func (x *RepairDirtyMigrationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RepairDirtyMigrationResponse.ProtoReflect.Descriptor instead. func (*RepairDirtyMigrationResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{55} + return file_iac_proto_rawDescGZIP(), []int{65} } func (x *RepairDirtyMigrationResponse) GetResult() *MigrationRepairResult { @@ -3537,7 +4516,7 @@ type ValidatePlanRequest struct { func (x *ValidatePlanRequest) Reset() { *x = ValidatePlanRequest{} - mi := &file_iac_proto_msgTypes[56] + mi := &file_iac_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3549,7 +4528,7 @@ func (x *ValidatePlanRequest) String() string { func (*ValidatePlanRequest) ProtoMessage() {} func (x *ValidatePlanRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[56] + mi := &file_iac_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3562,7 +4541,7 @@ func (x *ValidatePlanRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidatePlanRequest.ProtoReflect.Descriptor instead. func (*ValidatePlanRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{56} + return file_iac_proto_rawDescGZIP(), []int{66} } func (x *ValidatePlanRequest) GetPlan() *IaCPlan { @@ -3581,7 +4560,7 @@ type ValidatePlanResponse struct { func (x *ValidatePlanResponse) Reset() { *x = ValidatePlanResponse{} - mi := &file_iac_proto_msgTypes[57] + mi := &file_iac_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3593,7 +4572,7 @@ func (x *ValidatePlanResponse) String() string { func (*ValidatePlanResponse) ProtoMessage() {} func (x *ValidatePlanResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[57] + mi := &file_iac_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3606,7 +4585,7 @@ func (x *ValidatePlanResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ValidatePlanResponse.ProtoReflect.Descriptor instead. func (*ValidatePlanResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{57} + return file_iac_proto_rawDescGZIP(), []int{67} } func (x *ValidatePlanResponse) GetDiagnostics() []*PlanDiagnostic { @@ -3632,7 +4611,7 @@ type DetectDriftConfigRequest struct { func (x *DetectDriftConfigRequest) Reset() { *x = DetectDriftConfigRequest{} - mi := &file_iac_proto_msgTypes[58] + mi := &file_iac_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3644,7 +4623,7 @@ func (x *DetectDriftConfigRequest) String() string { func (*DetectDriftConfigRequest) ProtoMessage() {} func (x *DetectDriftConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[58] + mi := &file_iac_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3657,7 +4636,7 @@ func (x *DetectDriftConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DetectDriftConfigRequest.ProtoReflect.Descriptor instead. func (*DetectDriftConfigRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{58} + return file_iac_proto_rawDescGZIP(), []int{68} } func (x *DetectDriftConfigRequest) GetRefs() []*ResourceRef { @@ -3683,7 +4662,7 @@ type DetectDriftConfigResponse struct { func (x *DetectDriftConfigResponse) Reset() { *x = DetectDriftConfigResponse{} - mi := &file_iac_proto_msgTypes[59] + mi := &file_iac_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3695,7 +4674,7 @@ func (x *DetectDriftConfigResponse) String() string { func (*DetectDriftConfigResponse) ProtoMessage() {} func (x *DetectDriftConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[59] + mi := &file_iac_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3708,7 +4687,7 @@ func (x *DetectDriftConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DetectDriftConfigResponse.ProtoReflect.Descriptor instead. func (*DetectDriftConfigResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{59} + return file_iac_proto_rawDescGZIP(), []int{69} } func (x *DetectDriftConfigResponse) GetDrifts() []*DriftResult { @@ -3735,7 +4714,7 @@ type CaptureLogsRequest struct { func (x *CaptureLogsRequest) Reset() { *x = CaptureLogsRequest{} - mi := &file_iac_proto_msgTypes[60] + mi := &file_iac_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3747,7 +4726,7 @@ func (x *CaptureLogsRequest) String() string { func (*CaptureLogsRequest) ProtoMessage() {} func (x *CaptureLogsRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[60] + mi := &file_iac_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3760,7 +4739,7 @@ func (x *CaptureLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CaptureLogsRequest.ProtoReflect.Descriptor instead. func (*CaptureLogsRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{60} + return file_iac_proto_rawDescGZIP(), []int{70} } func (x *CaptureLogsRequest) GetResourceName() string { @@ -3837,7 +4816,7 @@ type LogChunk struct { func (x *LogChunk) Reset() { *x = LogChunk{} - mi := &file_iac_proto_msgTypes[61] + mi := &file_iac_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3849,7 +4828,7 @@ func (x *LogChunk) String() string { func (*LogChunk) ProtoMessage() {} func (x *LogChunk) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[61] + mi := &file_iac_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3862,7 +4841,7 @@ func (x *LogChunk) ProtoReflect() protoreflect.Message { // Deprecated: Use LogChunk.ProtoReflect.Descriptor instead. func (*LogChunk) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{61} + return file_iac_proto_rawDescGZIP(), []int{71} } func (x *LogChunk) GetData() []byte { @@ -3902,7 +4881,7 @@ type ResourceCreateRequest struct { func (x *ResourceCreateRequest) Reset() { *x = ResourceCreateRequest{} - mi := &file_iac_proto_msgTypes[62] + mi := &file_iac_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3914,7 +4893,7 @@ func (x *ResourceCreateRequest) String() string { func (*ResourceCreateRequest) ProtoMessage() {} func (x *ResourceCreateRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[62] + mi := &file_iac_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3927,7 +4906,7 @@ func (x *ResourceCreateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceCreateRequest.ProtoReflect.Descriptor instead. func (*ResourceCreateRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{62} + return file_iac_proto_rawDescGZIP(), []int{72} } func (x *ResourceCreateRequest) GetResourceType() string { @@ -3953,7 +4932,7 @@ type ResourceCreateResponse struct { func (x *ResourceCreateResponse) Reset() { *x = ResourceCreateResponse{} - mi := &file_iac_proto_msgTypes[63] + mi := &file_iac_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3965,7 +4944,7 @@ func (x *ResourceCreateResponse) String() string { func (*ResourceCreateResponse) ProtoMessage() {} func (x *ResourceCreateResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[63] + mi := &file_iac_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3978,7 +4957,7 @@ func (x *ResourceCreateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceCreateResponse.ProtoReflect.Descriptor instead. func (*ResourceCreateResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{63} + return file_iac_proto_rawDescGZIP(), []int{73} } func (x *ResourceCreateResponse) GetOutput() *ResourceOutput { @@ -3998,7 +4977,7 @@ type ResourceReadRequest struct { func (x *ResourceReadRequest) Reset() { *x = ResourceReadRequest{} - mi := &file_iac_proto_msgTypes[64] + mi := &file_iac_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4010,7 +4989,7 @@ func (x *ResourceReadRequest) String() string { func (*ResourceReadRequest) ProtoMessage() {} func (x *ResourceReadRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[64] + mi := &file_iac_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4023,7 +5002,7 @@ func (x *ResourceReadRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceReadRequest.ProtoReflect.Descriptor instead. func (*ResourceReadRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{64} + return file_iac_proto_rawDescGZIP(), []int{74} } func (x *ResourceReadRequest) GetResourceType() string { @@ -4049,7 +5028,7 @@ type ResourceReadResponse struct { func (x *ResourceReadResponse) Reset() { *x = ResourceReadResponse{} - mi := &file_iac_proto_msgTypes[65] + mi := &file_iac_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4061,7 +5040,7 @@ func (x *ResourceReadResponse) String() string { func (*ResourceReadResponse) ProtoMessage() {} func (x *ResourceReadResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[65] + mi := &file_iac_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4074,7 +5053,7 @@ func (x *ResourceReadResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceReadResponse.ProtoReflect.Descriptor instead. func (*ResourceReadResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{65} + return file_iac_proto_rawDescGZIP(), []int{75} } func (x *ResourceReadResponse) GetOutput() *ResourceOutput { @@ -4095,7 +5074,7 @@ type ResourceUpdateRequest struct { func (x *ResourceUpdateRequest) Reset() { *x = ResourceUpdateRequest{} - mi := &file_iac_proto_msgTypes[66] + mi := &file_iac_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4107,7 +5086,7 @@ func (x *ResourceUpdateRequest) String() string { func (*ResourceUpdateRequest) ProtoMessage() {} func (x *ResourceUpdateRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[66] + mi := &file_iac_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4120,7 +5099,7 @@ func (x *ResourceUpdateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceUpdateRequest.ProtoReflect.Descriptor instead. func (*ResourceUpdateRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{66} + return file_iac_proto_rawDescGZIP(), []int{76} } func (x *ResourceUpdateRequest) GetResourceType() string { @@ -4153,7 +5132,7 @@ type ResourceUpdateResponse struct { func (x *ResourceUpdateResponse) Reset() { *x = ResourceUpdateResponse{} - mi := &file_iac_proto_msgTypes[67] + mi := &file_iac_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4165,7 +5144,7 @@ func (x *ResourceUpdateResponse) String() string { func (*ResourceUpdateResponse) ProtoMessage() {} func (x *ResourceUpdateResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[67] + mi := &file_iac_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4178,7 +5157,7 @@ func (x *ResourceUpdateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceUpdateResponse.ProtoReflect.Descriptor instead. func (*ResourceUpdateResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{67} + return file_iac_proto_rawDescGZIP(), []int{77} } func (x *ResourceUpdateResponse) GetOutput() *ResourceOutput { @@ -4198,7 +5177,7 @@ type ResourceDeleteRequest struct { func (x *ResourceDeleteRequest) Reset() { *x = ResourceDeleteRequest{} - mi := &file_iac_proto_msgTypes[68] + mi := &file_iac_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4210,7 +5189,7 @@ func (x *ResourceDeleteRequest) String() string { func (*ResourceDeleteRequest) ProtoMessage() {} func (x *ResourceDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[68] + mi := &file_iac_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4223,7 +5202,7 @@ func (x *ResourceDeleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceDeleteRequest.ProtoReflect.Descriptor instead. func (*ResourceDeleteRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{68} + return file_iac_proto_rawDescGZIP(), []int{78} } func (x *ResourceDeleteRequest) GetResourceType() string { @@ -4248,7 +5227,7 @@ type ResourceDeleteResponse struct { func (x *ResourceDeleteResponse) Reset() { *x = ResourceDeleteResponse{} - mi := &file_iac_proto_msgTypes[69] + mi := &file_iac_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4260,7 +5239,7 @@ func (x *ResourceDeleteResponse) String() string { func (*ResourceDeleteResponse) ProtoMessage() {} func (x *ResourceDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[69] + mi := &file_iac_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4273,7 +5252,7 @@ func (x *ResourceDeleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceDeleteResponse.ProtoReflect.Descriptor instead. func (*ResourceDeleteResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{69} + return file_iac_proto_rawDescGZIP(), []int{79} } type ResourceDiffRequest struct { @@ -4287,7 +5266,7 @@ type ResourceDiffRequest struct { func (x *ResourceDiffRequest) Reset() { *x = ResourceDiffRequest{} - mi := &file_iac_proto_msgTypes[70] + mi := &file_iac_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4299,7 +5278,7 @@ func (x *ResourceDiffRequest) String() string { func (*ResourceDiffRequest) ProtoMessage() {} func (x *ResourceDiffRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[70] + mi := &file_iac_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4312,7 +5291,7 @@ func (x *ResourceDiffRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceDiffRequest.ProtoReflect.Descriptor instead. func (*ResourceDiffRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{70} + return file_iac_proto_rawDescGZIP(), []int{80} } func (x *ResourceDiffRequest) GetResourceType() string { @@ -4345,7 +5324,7 @@ type ResourceDiffResponse struct { func (x *ResourceDiffResponse) Reset() { *x = ResourceDiffResponse{} - mi := &file_iac_proto_msgTypes[71] + mi := &file_iac_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4357,7 +5336,7 @@ func (x *ResourceDiffResponse) String() string { func (*ResourceDiffResponse) ProtoMessage() {} func (x *ResourceDiffResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[71] + mi := &file_iac_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4370,7 +5349,7 @@ func (x *ResourceDiffResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceDiffResponse.ProtoReflect.Descriptor instead. func (*ResourceDiffResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{71} + return file_iac_proto_rawDescGZIP(), []int{81} } func (x *ResourceDiffResponse) GetResult() *DiffResult { @@ -4391,7 +5370,7 @@ type ResourceScaleRequest struct { func (x *ResourceScaleRequest) Reset() { *x = ResourceScaleRequest{} - mi := &file_iac_proto_msgTypes[72] + mi := &file_iac_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4403,7 +5382,7 @@ func (x *ResourceScaleRequest) String() string { func (*ResourceScaleRequest) ProtoMessage() {} func (x *ResourceScaleRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[72] + mi := &file_iac_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4416,7 +5395,7 @@ func (x *ResourceScaleRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceScaleRequest.ProtoReflect.Descriptor instead. func (*ResourceScaleRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{72} + return file_iac_proto_rawDescGZIP(), []int{82} } func (x *ResourceScaleRequest) GetResourceType() string { @@ -4449,7 +5428,7 @@ type ResourceScaleResponse struct { func (x *ResourceScaleResponse) Reset() { *x = ResourceScaleResponse{} - mi := &file_iac_proto_msgTypes[73] + mi := &file_iac_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4461,7 +5440,7 @@ func (x *ResourceScaleResponse) String() string { func (*ResourceScaleResponse) ProtoMessage() {} func (x *ResourceScaleResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[73] + mi := &file_iac_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4474,7 +5453,7 @@ func (x *ResourceScaleResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceScaleResponse.ProtoReflect.Descriptor instead. func (*ResourceScaleResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{73} + return file_iac_proto_rawDescGZIP(), []int{83} } func (x *ResourceScaleResponse) GetOutput() *ResourceOutput { @@ -4494,7 +5473,7 @@ type ResourceHealthCheckRequest struct { func (x *ResourceHealthCheckRequest) Reset() { *x = ResourceHealthCheckRequest{} - mi := &file_iac_proto_msgTypes[74] + mi := &file_iac_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4506,7 +5485,7 @@ func (x *ResourceHealthCheckRequest) String() string { func (*ResourceHealthCheckRequest) ProtoMessage() {} func (x *ResourceHealthCheckRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[74] + mi := &file_iac_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4519,7 +5498,7 @@ func (x *ResourceHealthCheckRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceHealthCheckRequest.ProtoReflect.Descriptor instead. func (*ResourceHealthCheckRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{74} + return file_iac_proto_rawDescGZIP(), []int{84} } func (x *ResourceHealthCheckRequest) GetResourceType() string { @@ -4545,7 +5524,7 @@ type ResourceHealthCheckResponse struct { func (x *ResourceHealthCheckResponse) Reset() { *x = ResourceHealthCheckResponse{} - mi := &file_iac_proto_msgTypes[75] + mi := &file_iac_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4557,7 +5536,7 @@ func (x *ResourceHealthCheckResponse) String() string { func (*ResourceHealthCheckResponse) ProtoMessage() {} func (x *ResourceHealthCheckResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[75] + mi := &file_iac_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4570,7 +5549,7 @@ func (x *ResourceHealthCheckResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceHealthCheckResponse.ProtoReflect.Descriptor instead. func (*ResourceHealthCheckResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{75} + return file_iac_proto_rawDescGZIP(), []int{85} } func (x *ResourceHealthCheckResponse) GetResult() *HealthResult { @@ -4589,7 +5568,7 @@ type SensitiveKeysRequest struct { func (x *SensitiveKeysRequest) Reset() { *x = SensitiveKeysRequest{} - mi := &file_iac_proto_msgTypes[76] + mi := &file_iac_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4601,7 +5580,7 @@ func (x *SensitiveKeysRequest) String() string { func (*SensitiveKeysRequest) ProtoMessage() {} func (x *SensitiveKeysRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[76] + mi := &file_iac_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4614,7 +5593,7 @@ func (x *SensitiveKeysRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SensitiveKeysRequest.ProtoReflect.Descriptor instead. func (*SensitiveKeysRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{76} + return file_iac_proto_rawDescGZIP(), []int{86} } func (x *SensitiveKeysRequest) GetResourceType() string { @@ -4633,7 +5612,7 @@ type SensitiveKeysResponse struct { func (x *SensitiveKeysResponse) Reset() { *x = SensitiveKeysResponse{} - mi := &file_iac_proto_msgTypes[77] + mi := &file_iac_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4645,7 +5624,7 @@ func (x *SensitiveKeysResponse) String() string { func (*SensitiveKeysResponse) ProtoMessage() {} func (x *SensitiveKeysResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[77] + mi := &file_iac_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4658,7 +5637,7 @@ func (x *SensitiveKeysResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SensitiveKeysResponse.ProtoReflect.Descriptor instead. func (*SensitiveKeysResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{77} + return file_iac_proto_rawDescGZIP(), []int{87} } func (x *SensitiveKeysResponse) GetKeys() []string { @@ -4679,7 +5658,7 @@ type TroubleshootRequest struct { func (x *TroubleshootRequest) Reset() { *x = TroubleshootRequest{} - mi := &file_iac_proto_msgTypes[78] + mi := &file_iac_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4691,7 +5670,7 @@ func (x *TroubleshootRequest) String() string { func (*TroubleshootRequest) ProtoMessage() {} func (x *TroubleshootRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[78] + mi := &file_iac_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4704,7 +5683,7 @@ func (x *TroubleshootRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use TroubleshootRequest.ProtoReflect.Descriptor instead. func (*TroubleshootRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{78} + return file_iac_proto_rawDescGZIP(), []int{88} } func (x *TroubleshootRequest) GetResourceType() string { @@ -4737,7 +5716,7 @@ type TroubleshootResponse struct { func (x *TroubleshootResponse) Reset() { *x = TroubleshootResponse{} - mi := &file_iac_proto_msgTypes[79] + mi := &file_iac_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4749,7 +5728,7 @@ func (x *TroubleshootResponse) String() string { func (*TroubleshootResponse) ProtoMessage() {} func (x *TroubleshootResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[79] + mi := &file_iac_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4762,7 +5741,7 @@ func (x *TroubleshootResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use TroubleshootResponse.ProtoReflect.Descriptor instead. func (*TroubleshootResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{79} + return file_iac_proto_rawDescGZIP(), []int{89} } func (x *TroubleshootResponse) GetDiagnostics() []*Diagnostic { @@ -4796,7 +5775,7 @@ type IaCState struct { func (x *IaCState) Reset() { *x = IaCState{} - mi := &file_iac_proto_msgTypes[80] + mi := &file_iac_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4808,7 +5787,7 @@ func (x *IaCState) String() string { func (*IaCState) ProtoMessage() {} func (x *IaCState) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[80] + mi := &file_iac_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4821,7 +5800,7 @@ func (x *IaCState) ProtoReflect() protoreflect.Message { // Deprecated: Use IaCState.ProtoReflect.Descriptor instead. func (*IaCState) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{80} + return file_iac_proto_rawDescGZIP(), []int{90} } func (x *IaCState) GetResourceId() string { @@ -4929,7 +5908,7 @@ type ConfigureRequest struct { func (x *ConfigureRequest) Reset() { *x = ConfigureRequest{} - mi := &file_iac_proto_msgTypes[81] + mi := &file_iac_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4941,7 +5920,7 @@ func (x *ConfigureRequest) String() string { func (*ConfigureRequest) ProtoMessage() {} func (x *ConfigureRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[81] + mi := &file_iac_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4954,7 +5933,7 @@ func (x *ConfigureRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigureRequest.ProtoReflect.Descriptor instead. func (*ConfigureRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{81} + return file_iac_proto_rawDescGZIP(), []int{91} } func (x *ConfigureRequest) GetBackendName() string { @@ -4979,7 +5958,7 @@ type ConfigureResponse struct { func (x *ConfigureResponse) Reset() { *x = ConfigureResponse{} - mi := &file_iac_proto_msgTypes[82] + mi := &file_iac_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4991,7 +5970,7 @@ func (x *ConfigureResponse) String() string { func (*ConfigureResponse) ProtoMessage() {} func (x *ConfigureResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[82] + mi := &file_iac_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5004,7 +5983,7 @@ func (x *ConfigureResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigureResponse.ProtoReflect.Descriptor instead. func (*ConfigureResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{82} + return file_iac_proto_rawDescGZIP(), []int{92} } type GetStateRequest struct { @@ -5016,7 +5995,7 @@ type GetStateRequest struct { func (x *GetStateRequest) Reset() { *x = GetStateRequest{} - mi := &file_iac_proto_msgTypes[83] + mi := &file_iac_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5028,7 +6007,7 @@ func (x *GetStateRequest) String() string { func (*GetStateRequest) ProtoMessage() {} func (x *GetStateRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[83] + mi := &file_iac_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5041,7 +6020,7 @@ func (x *GetStateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetStateRequest.ProtoReflect.Descriptor instead. func (*GetStateRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{83} + return file_iac_proto_rawDescGZIP(), []int{93} } func (x *GetStateRequest) GetResourceId() string { @@ -5061,7 +6040,7 @@ type GetStateResponse struct { func (x *GetStateResponse) Reset() { *x = GetStateResponse{} - mi := &file_iac_proto_msgTypes[84] + mi := &file_iac_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5073,7 +6052,7 @@ func (x *GetStateResponse) String() string { func (*GetStateResponse) ProtoMessage() {} func (x *GetStateResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[84] + mi := &file_iac_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5086,7 +6065,7 @@ func (x *GetStateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetStateResponse.ProtoReflect.Descriptor instead. func (*GetStateResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{84} + return file_iac_proto_rawDescGZIP(), []int{94} } func (x *GetStateResponse) GetState() *IaCState { @@ -5112,7 +6091,7 @@ type SaveStateRequest struct { func (x *SaveStateRequest) Reset() { *x = SaveStateRequest{} - mi := &file_iac_proto_msgTypes[85] + mi := &file_iac_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5124,7 +6103,7 @@ func (x *SaveStateRequest) String() string { func (*SaveStateRequest) ProtoMessage() {} func (x *SaveStateRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[85] + mi := &file_iac_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5137,7 +6116,7 @@ func (x *SaveStateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SaveStateRequest.ProtoReflect.Descriptor instead. func (*SaveStateRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{85} + return file_iac_proto_rawDescGZIP(), []int{95} } func (x *SaveStateRequest) GetState() *IaCState { @@ -5155,7 +6134,7 @@ type SaveStateResponse struct { func (x *SaveStateResponse) Reset() { *x = SaveStateResponse{} - mi := &file_iac_proto_msgTypes[86] + mi := &file_iac_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5167,7 +6146,7 @@ func (x *SaveStateResponse) String() string { func (*SaveStateResponse) ProtoMessage() {} func (x *SaveStateResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[86] + mi := &file_iac_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5180,7 +6159,7 @@ func (x *SaveStateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SaveStateResponse.ProtoReflect.Descriptor instead. func (*SaveStateResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{86} + return file_iac_proto_rawDescGZIP(), []int{96} } type ListStatesRequest struct { @@ -5192,7 +6171,7 @@ type ListStatesRequest struct { func (x *ListStatesRequest) Reset() { *x = ListStatesRequest{} - mi := &file_iac_proto_msgTypes[87] + mi := &file_iac_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5204,7 +6183,7 @@ func (x *ListStatesRequest) String() string { func (*ListStatesRequest) ProtoMessage() {} func (x *ListStatesRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[87] + mi := &file_iac_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5217,7 +6196,7 @@ func (x *ListStatesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListStatesRequest.ProtoReflect.Descriptor instead. func (*ListStatesRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{87} + return file_iac_proto_rawDescGZIP(), []int{97} } func (x *ListStatesRequest) GetFilter() map[string]string { @@ -5236,7 +6215,7 @@ type ListStatesResponse struct { func (x *ListStatesResponse) Reset() { *x = ListStatesResponse{} - mi := &file_iac_proto_msgTypes[88] + mi := &file_iac_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5248,7 +6227,7 @@ func (x *ListStatesResponse) String() string { func (*ListStatesResponse) ProtoMessage() {} func (x *ListStatesResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[88] + mi := &file_iac_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5261,7 +6240,7 @@ func (x *ListStatesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListStatesResponse.ProtoReflect.Descriptor instead. func (*ListStatesResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{88} + return file_iac_proto_rawDescGZIP(), []int{98} } func (x *ListStatesResponse) GetStates() []*IaCState { @@ -5280,7 +6259,7 @@ type DeleteStateRequest struct { func (x *DeleteStateRequest) Reset() { *x = DeleteStateRequest{} - mi := &file_iac_proto_msgTypes[89] + mi := &file_iac_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5292,7 +6271,7 @@ func (x *DeleteStateRequest) String() string { func (*DeleteStateRequest) ProtoMessage() {} func (x *DeleteStateRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[89] + mi := &file_iac_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5305,7 +6284,7 @@ func (x *DeleteStateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteStateRequest.ProtoReflect.Descriptor instead. func (*DeleteStateRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{89} + return file_iac_proto_rawDescGZIP(), []int{99} } func (x *DeleteStateRequest) GetResourceId() string { @@ -5323,7 +6302,7 @@ type DeleteStateResponse struct { func (x *DeleteStateResponse) Reset() { *x = DeleteStateResponse{} - mi := &file_iac_proto_msgTypes[90] + mi := &file_iac_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5335,7 +6314,7 @@ func (x *DeleteStateResponse) String() string { func (*DeleteStateResponse) ProtoMessage() {} func (x *DeleteStateResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[90] + mi := &file_iac_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5348,7 +6327,7 @@ func (x *DeleteStateResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteStateResponse.ProtoReflect.Descriptor instead. func (*DeleteStateResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{90} + return file_iac_proto_rawDescGZIP(), []int{100} } type LockRequest struct { @@ -5360,7 +6339,7 @@ type LockRequest struct { func (x *LockRequest) Reset() { *x = LockRequest{} - mi := &file_iac_proto_msgTypes[91] + mi := &file_iac_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5372,7 +6351,7 @@ func (x *LockRequest) String() string { func (*LockRequest) ProtoMessage() {} func (x *LockRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[91] + mi := &file_iac_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5385,7 +6364,7 @@ func (x *LockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LockRequest.ProtoReflect.Descriptor instead. func (*LockRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{91} + return file_iac_proto_rawDescGZIP(), []int{101} } func (x *LockRequest) GetResourceId() string { @@ -5403,7 +6382,7 @@ type LockResponse struct { func (x *LockResponse) Reset() { *x = LockResponse{} - mi := &file_iac_proto_msgTypes[92] + mi := &file_iac_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5415,7 +6394,7 @@ func (x *LockResponse) String() string { func (*LockResponse) ProtoMessage() {} func (x *LockResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[92] + mi := &file_iac_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5428,7 +6407,7 @@ func (x *LockResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LockResponse.ProtoReflect.Descriptor instead. func (*LockResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{92} + return file_iac_proto_rawDescGZIP(), []int{102} } type UnlockRequest struct { @@ -5440,7 +6419,7 @@ type UnlockRequest struct { func (x *UnlockRequest) Reset() { *x = UnlockRequest{} - mi := &file_iac_proto_msgTypes[93] + mi := &file_iac_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5452,7 +6431,7 @@ func (x *UnlockRequest) String() string { func (*UnlockRequest) ProtoMessage() {} func (x *UnlockRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[93] + mi := &file_iac_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5465,7 +6444,7 @@ func (x *UnlockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UnlockRequest.ProtoReflect.Descriptor instead. func (*UnlockRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{93} + return file_iac_proto_rawDescGZIP(), []int{103} } func (x *UnlockRequest) GetResourceId() string { @@ -5483,7 +6462,7 @@ type UnlockResponse struct { func (x *UnlockResponse) Reset() { *x = UnlockResponse{} - mi := &file_iac_proto_msgTypes[94] + mi := &file_iac_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5495,7 +6474,7 @@ func (x *UnlockResponse) String() string { func (*UnlockResponse) ProtoMessage() {} func (x *UnlockResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[94] + mi := &file_iac_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5508,7 +6487,7 @@ func (x *UnlockResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UnlockResponse.ProtoReflect.Descriptor instead. func (*UnlockResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{94} + return file_iac_proto_rawDescGZIP(), []int{104} } // ListBackendNames lets the engine ask a loaded plugin which iac.state backend @@ -5522,7 +6501,7 @@ type ListBackendNamesRequest struct { func (x *ListBackendNamesRequest) Reset() { *x = ListBackendNamesRequest{} - mi := &file_iac_proto_msgTypes[95] + mi := &file_iac_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5534,7 +6513,7 @@ func (x *ListBackendNamesRequest) String() string { func (*ListBackendNamesRequest) ProtoMessage() {} func (x *ListBackendNamesRequest) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[95] + mi := &file_iac_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5547,7 +6526,7 @@ func (x *ListBackendNamesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListBackendNamesRequest.ProtoReflect.Descriptor instead. func (*ListBackendNamesRequest) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{95} + return file_iac_proto_rawDescGZIP(), []int{105} } type ListBackendNamesResponse struct { @@ -5559,7 +6538,7 @@ type ListBackendNamesResponse struct { func (x *ListBackendNamesResponse) Reset() { *x = ListBackendNamesResponse{} - mi := &file_iac_proto_msgTypes[96] + mi := &file_iac_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5571,7 +6550,7 @@ func (x *ListBackendNamesResponse) String() string { func (*ListBackendNamesResponse) ProtoMessage() {} func (x *ListBackendNamesResponse) ProtoReflect() protoreflect.Message { - mi := &file_iac_proto_msgTypes[96] + mi := &file_iac_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5584,7 +6563,7 @@ func (x *ListBackendNamesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListBackendNamesResponse.ProtoReflect.Descriptor instead. func (*ListBackendNamesResponse) Descriptor() ([]byte, []int) { - return file_iac_proto_rawDescGZIP(), []int{96} + return file_iac_proto_rawDescGZIP(), []int{106} } func (x *ListBackendNamesResponse) GetBackendNames() []string { @@ -5674,7 +6653,61 @@ const file_iac_proto_rawDesc = "" + "DiffResult\x12!\n" + "\fneeds_update\x18\x01 \x01(\bR\vneedsUpdate\x12#\n" + "\rneeds_replace\x18\x02 \x01(\bR\fneedsReplace\x12C\n" + - "\achanges\x18\x03 \x03(\v2).workflow.plugin.external.iac.FieldChangeR\achanges\"\xed\x01\n" + + "\achanges\x18\x03 \x03(\v2).workflow.plugin.external.iac.FieldChangeR\achanges\"\x8d\x05\n" + + "\x0eIaCRequirement\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12A\n" + + "\x04kind\x18\x02 \x01(\x0e2-.workflow.plugin.external.iac.RequirementKindR\x04kind\x12\x16\n" + + "\x06source\x18\x03 \x01(\tR\x06source\x12,\n" + + "\x12resource_type_hint\x18\x04 \x01(\tR\x10resourceTypeHint\x12 \n" + + "\venvironment\x18\x05 \x01(\tR\venvironment\x12L\n" + + "\bruntimes\x18\x06 \x03(\x0e20.workflow.plugin.external.iac.RequirementRuntimeR\bruntimes\x12Z\n" + + "\x11telemetry_signals\x18\a \x03(\x0e2-.workflow.plugin.external.iac.TelemetrySignalR\x10telemetrySignals\x12i\n" + + "\x16observability_backends\x18\b \x03(\x0e22.workflow.plugin.external.iac.ObservabilityBackendR\x15observabilityBackends\x12W\n" + + "\x10deployment_modes\x18\t \x03(\x0e2,.workflow.plugin.external.iac.DeploymentModeR\x0fdeploymentModes\x12'\n" + + "\x0fvendor_features\x18\n" + + " \x03(\tR\x0evendorFeatures\x12'\n" + + "\x0fparameters_json\x18\v \x01(\fR\x0eparametersJson\"\x97\x01\n" + + "\x1bDiscoverRequirementsRequest\x12J\n" + + "\acontext\x18\x01 \x01(\v20.workflow.plugin.external.iac.RequirementContextR\acontext\x12,\n" + + "\x12module_config_json\x18\x02 \x01(\fR\x10moduleConfigJson\"\xba\x01\n" + + "\x12RequirementContext\x12 \n" + + "\vapplication\x18\x01 \x01(\tR\vapplication\x12 \n" + + "\venvironment\x18\x02 \x01(\tR\venvironment\x12A\n" + + "\amodules\x18\x03 \x03(\v2'.workflow.plugin.external.iac.ModuleRefR\amodules\x12\x1d\n" + + "\n" + + "plugin_ids\x18\x04 \x03(\tR\tpluginIds\"Q\n" + + "\tModuleRef\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" + + "\x04type\x18\x02 \x01(\tR\x04type\x12\x1c\n" + + "\tsatisfies\x18\x03 \x03(\tR\tsatisfies\"p\n" + + "\x1cDiscoverRequirementsResponse\x12P\n" + + "\frequirements\x18\x01 \x03(\v2,.workflow.plugin.external.iac.IaCRequirementR\frequirements\"\xf4\x01\n" + + "\x16MapRequirementsRequest\x12\x1a\n" + + "\bprovider\x18\x01 \x01(\tR\bprovider\x12J\n" + + "\aruntime\x18\x02 \x01(\x0e20.workflow.plugin.external.iac.RequirementRuntimeR\aruntime\x12 \n" + + "\venvironment\x18\x03 \x01(\tR\venvironment\x12P\n" + + "\frequirements\x18\x04 \x03(\v2,.workflow.plugin.external.iac.IaCRequirementR\frequirements\"\x99\x01\n" + + "\x11DerivedModuleSpec\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" + + "\x04type\x18\x02 \x01(\tR\x04type\x12\x1c\n" + + "\tsatisfies\x18\x03 \x03(\tR\tsatisfies\x12\x1f\n" + + "\vconfig_json\x18\x04 \x01(\fR\n" + + "configJson\x12\x1d\n" + + "\n" + + "depends_on\x18\x05 \x03(\tR\tdependsOn\"W\n" + + "\x15RequirementDiagnostic\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x12\n" + + "\x04code\x18\x02 \x01(\tR\x04code\x12\x18\n" + + "\amessage\x18\x03 \x01(\tR\amessage\"_\n" + + "\x0fRequirementNote\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x18\n" + + "\amessage\x18\x02 \x01(\tR\amessage\x12 \n" + + "\vinteractive\x18\x03 \x01(\bR\vinteractive\"\x9f\x02\n" + + "\x17MapRequirementsResponse\x12#\n" + + "\raccepted_keys\x18\x01 \x03(\tR\facceptedKeys\x12O\n" + + "\brejected\x18\x02 \x03(\v23.workflow.plugin.external.iac.RequirementDiagnosticR\brejected\x12I\n" + + "\amodules\x18\x03 \x03(\v2/.workflow.plugin.external.iac.DerivedModuleSpecR\amodules\x12C\n" + + "\x05notes\x18\x04 \x03(\v2-.workflow.plugin.external.iac.RequirementNoteR\x05notes\"\xed\x01\n" + "\vDriftResult\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" + "\x04type\x18\x02 \x01(\tR\x04type\x12\x18\n" + @@ -5977,7 +7010,40 @@ const file_iac_proto_rawDesc = "" + "\x13DRIFT_CLASS_UNKNOWN\x10\x00\x12\x17\n" + "\x13DRIFT_CLASS_IN_SYNC\x10\x01\x12\x15\n" + "\x11DRIFT_CLASS_GHOST\x10\x02\x12\x16\n" + - "\x12DRIFT_CLASS_CONFIG\x10\x03*j\n" + + "\x12DRIFT_CLASS_CONFIG\x10\x03*\xf3\x01\n" + + "\x0fRequirementKind\x12 \n" + + "\x1cREQUIREMENT_KIND_UNSPECIFIED\x10\x00\x12\"\n" + + "\x1eREQUIREMENT_KIND_OBSERVABILITY\x10\x01\x12\x1c\n" + + "\x18REQUIREMENT_KIND_WEB_API\x10\x02\x12#\n" + + "\x1fREQUIREMENT_KIND_MESSAGE_BROKER\x10\x03\x12\x1d\n" + + "\x19REQUIREMENT_KIND_DATABASE\x10\x04\x12\x1a\n" + + "\x16REQUIREMENT_KIND_CACHE\x10\x05\x12\x1c\n" + + "\x18REQUIREMENT_KIND_STORAGE\x10\x06*\xfe\x01\n" + + "\x12RequirementRuntime\x12#\n" + + "\x1fREQUIREMENT_RUNTIME_UNSPECIFIED\x10\x00\x12\"\n" + + "\x1eREQUIREMENT_RUNTIME_KUBERNETES\x10\x01\x12\x1b\n" + + "\x17REQUIREMENT_RUNTIME_ECS\x10\x02\x12!\n" + + "\x1dREQUIREMENT_RUNTIME_CLOUD_RUN\x10\x03\x12,\n" + + "(REQUIREMENT_RUNTIME_AZURE_CONTAINER_APPS\x10\x04\x121\n" + + "-REQUIREMENT_RUNTIME_DIGITALOCEAN_APP_PLATFORM\x10\x05*\x89\x01\n" + + "\x0fTelemetrySignal\x12 \n" + + "\x1cTELEMETRY_SIGNAL_UNSPECIFIED\x10\x00\x12\x1b\n" + + "\x17TELEMETRY_SIGNAL_TRACES\x10\x01\x12\x1c\n" + + "\x18TELEMETRY_SIGNAL_METRICS\x10\x02\x12\x19\n" + + "\x15TELEMETRY_SIGNAL_LOGS\x10\x03*\xe9\x01\n" + + "\x14ObservabilityBackend\x12%\n" + + "!OBSERVABILITY_BACKEND_UNSPECIFIED\x10\x00\x12\x1e\n" + + "\x1aOBSERVABILITY_BACKEND_OTEL\x10\x01\x12!\n" + + "\x1dOBSERVABILITY_BACKEND_DATADOG\x10\x02\x12$\n" + + " OBSERVABILITY_BACKEND_PROMETHEUS\x10\x03\x12\x1e\n" + + "\x1aOBSERVABILITY_BACKEND_LOKI\x10\x04\x12!\n" + + "\x1dOBSERVABILITY_BACKEND_GRAFANA\x10\x05*\xaf\x01\n" + + "\x0eDeploymentMode\x12\x1f\n" + + "\x1bDEPLOYMENT_MODE_UNSPECIFIED\x10\x00\x12\x1b\n" + + "\x17DEPLOYMENT_MODE_SIDECAR\x10\x01\x12\x1d\n" + + "\x19DEPLOYMENT_MODE_DAEMONSET\x10\x02\x12#\n" + + "\x1fDEPLOYMENT_MODE_SIBLING_SERVICE\x10\x03\x12\x1b\n" + + "\x17DEPLOYMENT_MODE_MANAGED\x10\x04*j\n" + "\x16PlanDiagnosticSeverity\x12\x18\n" + "\x14PLAN_DIAGNOSTIC_INFO\x10\x00\x12\x1b\n" + "\x17PLAN_DIAGNOSTIC_WARNING\x10\x01\x12\x19\n" + @@ -6025,7 +7091,11 @@ const file_iac_proto_rawDesc = "" + "\x1eIaCProviderDriftConfigDetector\x12\x84\x01\n" + "\x11DetectDriftConfig\x126.workflow.plugin.external.iac.DetectDriftConfigRequest\x1a7.workflow.plugin.external.iac.DetectDriftConfigResponse2\x82\x01\n" + "\x15IaCProviderLogCapture\x12i\n" + - "\vCaptureLogs\x120.workflow.plugin.external.iac.CaptureLogsRequest\x1a&.workflow.plugin.external.iac.LogChunk0\x012\xb5\b\n" + + "\vCaptureLogs\x120.workflow.plugin.external.iac.CaptureLogsRequest\x1a&.workflow.plugin.external.iac.LogChunk0\x012\xa9\x01\n" + + "\x17IaCRequirementDiscovery\x12\x8d\x01\n" + + "\x14DiscoverRequirements\x129.workflow.plugin.external.iac.DiscoverRequirementsRequest\x1a:.workflow.plugin.external.iac.DiscoverRequirementsResponse2\x9e\x01\n" + + "\x1cIaCProviderRequirementMapper\x12~\n" + + "\x0fMapRequirements\x124.workflow.plugin.external.iac.MapRequirementsRequest\x1a5.workflow.plugin.external.iac.MapRequirementsResponse2\xb5\b\n" + "\x0eResourceDriver\x12s\n" + "\x06Create\x123.workflow.plugin.external.iac.ResourceCreateRequest\x1a4.workflow.plugin.external.iac.ResourceCreateResponse\x12m\n" + "\x04Read\x121.workflow.plugin.external.iac.ResourceReadRequest\x1a2.workflow.plugin.external.iac.ResourceReadResponse\x12s\n" + @@ -6059,269 +7129,301 @@ func file_iac_proto_rawDescGZIP() []byte { return file_iac_proto_rawDescData } -var file_iac_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_iac_proto_msgTypes = make([]protoimpl.MessageInfo, 104) +var file_iac_proto_enumTypes = make([]protoimpl.EnumInfo, 9) +var file_iac_proto_msgTypes = make([]protoimpl.MessageInfo, 114) var file_iac_proto_goTypes = []any{ (DriftClass)(0), // 0: workflow.plugin.external.iac.DriftClass - (PlanDiagnosticSeverity)(0), // 1: workflow.plugin.external.iac.PlanDiagnosticSeverity - (ActionStatus)(0), // 2: workflow.plugin.external.iac.ActionStatus - (LogCaptureType)(0), // 3: workflow.plugin.external.iac.LogCaptureType - (*ResourceSpec)(nil), // 4: workflow.plugin.external.iac.ResourceSpec - (*ResourceRef)(nil), // 5: workflow.plugin.external.iac.ResourceRef - (*ResourceHints)(nil), // 6: workflow.plugin.external.iac.ResourceHints - (*ProviderSizing)(nil), // 7: workflow.plugin.external.iac.ProviderSizing - (*IaCCapabilityDeclaration)(nil), // 8: workflow.plugin.external.iac.IaCCapabilityDeclaration - (*ResourceState)(nil), // 9: workflow.plugin.external.iac.ResourceState - (*ResourceOutput)(nil), // 10: workflow.plugin.external.iac.ResourceOutput - (*ResourceStatus)(nil), // 11: workflow.plugin.external.iac.ResourceStatus - (*FieldChange)(nil), // 12: workflow.plugin.external.iac.FieldChange - (*DiffResult)(nil), // 13: workflow.plugin.external.iac.DiffResult - (*DriftResult)(nil), // 14: workflow.plugin.external.iac.DriftResult - (*DriftEntry)(nil), // 15: workflow.plugin.external.iac.DriftEntry - (*HealthResult)(nil), // 16: workflow.plugin.external.iac.HealthResult - (*Diagnostic)(nil), // 17: workflow.plugin.external.iac.Diagnostic - (*PlanDiagnostic)(nil), // 18: workflow.plugin.external.iac.PlanDiagnostic - (*PlanAction)(nil), // 19: workflow.plugin.external.iac.PlanAction - (*IaCPlan)(nil), // 20: workflow.plugin.external.iac.IaCPlan - (*ActionError)(nil), // 21: workflow.plugin.external.iac.ActionError - (*DestroyResult)(nil), // 22: workflow.plugin.external.iac.DestroyResult - (*BootstrapResult)(nil), // 23: workflow.plugin.external.iac.BootstrapResult - (*MigrationRepairRequest)(nil), // 24: workflow.plugin.external.iac.MigrationRepairRequest - (*MigrationRepairResult)(nil), // 25: workflow.plugin.external.iac.MigrationRepairResult - (*InitializeRequest)(nil), // 26: workflow.plugin.external.iac.InitializeRequest - (*InitializeResponse)(nil), // 27: workflow.plugin.external.iac.InitializeResponse - (*NameRequest)(nil), // 28: workflow.plugin.external.iac.NameRequest - (*NameResponse)(nil), // 29: workflow.plugin.external.iac.NameResponse - (*VersionRequest)(nil), // 30: workflow.plugin.external.iac.VersionRequest - (*VersionResponse)(nil), // 31: workflow.plugin.external.iac.VersionResponse - (*CapabilitiesRequest)(nil), // 32: workflow.plugin.external.iac.CapabilitiesRequest - (*CapabilitiesResponse)(nil), // 33: workflow.plugin.external.iac.CapabilitiesResponse - (*PlanRequest)(nil), // 34: workflow.plugin.external.iac.PlanRequest - (*PlanResponse)(nil), // 35: workflow.plugin.external.iac.PlanResponse - (*DestroyRequest)(nil), // 36: workflow.plugin.external.iac.DestroyRequest - (*DestroyResponse)(nil), // 37: workflow.plugin.external.iac.DestroyResponse - (*StatusRequest)(nil), // 38: workflow.plugin.external.iac.StatusRequest - (*StatusResponse)(nil), // 39: workflow.plugin.external.iac.StatusResponse - (*ImportRequest)(nil), // 40: workflow.plugin.external.iac.ImportRequest - (*ImportResponse)(nil), // 41: workflow.plugin.external.iac.ImportResponse - (*ResolveSizingRequest)(nil), // 42: workflow.plugin.external.iac.ResolveSizingRequest - (*ResolveSizingResponse)(nil), // 43: workflow.plugin.external.iac.ResolveSizingResponse - (*BootstrapStateBackendRequest)(nil), // 44: workflow.plugin.external.iac.BootstrapStateBackendRequest - (*BootstrapStateBackendResponse)(nil), // 45: workflow.plugin.external.iac.BootstrapStateBackendResponse - (*EnumerateAllRequest)(nil), // 46: workflow.plugin.external.iac.EnumerateAllRequest - (*EnumerateAllResponse)(nil), // 47: workflow.plugin.external.iac.EnumerateAllResponse - (*EnumerateByTagRequest)(nil), // 48: workflow.plugin.external.iac.EnumerateByTagRequest - (*EnumerateByTagResponse)(nil), // 49: workflow.plugin.external.iac.EnumerateByTagResponse - (*DetectDriftRequest)(nil), // 50: workflow.plugin.external.iac.DetectDriftRequest - (*DetectDriftResponse)(nil), // 51: workflow.plugin.external.iac.DetectDriftResponse - (*DetectDriftWithSpecsRequest)(nil), // 52: workflow.plugin.external.iac.DetectDriftWithSpecsRequest - (*DetectDriftWithSpecsResponse)(nil), // 53: workflow.plugin.external.iac.DetectDriftWithSpecsResponse - (*RevokeProviderCredentialRequest)(nil), // 54: workflow.plugin.external.iac.RevokeProviderCredentialRequest - (*RevokeProviderCredentialResponse)(nil), // 55: workflow.plugin.external.iac.RevokeProviderCredentialResponse - (*FinalizeApplyRequest)(nil), // 56: workflow.plugin.external.iac.FinalizeApplyRequest - (*FinalizeApplyResponse)(nil), // 57: workflow.plugin.external.iac.FinalizeApplyResponse - (*RepairDirtyMigrationRequest)(nil), // 58: workflow.plugin.external.iac.RepairDirtyMigrationRequest - (*RepairDirtyMigrationResponse)(nil), // 59: workflow.plugin.external.iac.RepairDirtyMigrationResponse - (*ValidatePlanRequest)(nil), // 60: workflow.plugin.external.iac.ValidatePlanRequest - (*ValidatePlanResponse)(nil), // 61: workflow.plugin.external.iac.ValidatePlanResponse - (*DetectDriftConfigRequest)(nil), // 62: workflow.plugin.external.iac.DetectDriftConfigRequest - (*DetectDriftConfigResponse)(nil), // 63: workflow.plugin.external.iac.DetectDriftConfigResponse - (*CaptureLogsRequest)(nil), // 64: workflow.plugin.external.iac.CaptureLogsRequest - (*LogChunk)(nil), // 65: workflow.plugin.external.iac.LogChunk - (*ResourceCreateRequest)(nil), // 66: workflow.plugin.external.iac.ResourceCreateRequest - (*ResourceCreateResponse)(nil), // 67: workflow.plugin.external.iac.ResourceCreateResponse - (*ResourceReadRequest)(nil), // 68: workflow.plugin.external.iac.ResourceReadRequest - (*ResourceReadResponse)(nil), // 69: workflow.plugin.external.iac.ResourceReadResponse - (*ResourceUpdateRequest)(nil), // 70: workflow.plugin.external.iac.ResourceUpdateRequest - (*ResourceUpdateResponse)(nil), // 71: workflow.plugin.external.iac.ResourceUpdateResponse - (*ResourceDeleteRequest)(nil), // 72: workflow.plugin.external.iac.ResourceDeleteRequest - (*ResourceDeleteResponse)(nil), // 73: workflow.plugin.external.iac.ResourceDeleteResponse - (*ResourceDiffRequest)(nil), // 74: workflow.plugin.external.iac.ResourceDiffRequest - (*ResourceDiffResponse)(nil), // 75: workflow.plugin.external.iac.ResourceDiffResponse - (*ResourceScaleRequest)(nil), // 76: workflow.plugin.external.iac.ResourceScaleRequest - (*ResourceScaleResponse)(nil), // 77: workflow.plugin.external.iac.ResourceScaleResponse - (*ResourceHealthCheckRequest)(nil), // 78: workflow.plugin.external.iac.ResourceHealthCheckRequest - (*ResourceHealthCheckResponse)(nil), // 79: workflow.plugin.external.iac.ResourceHealthCheckResponse - (*SensitiveKeysRequest)(nil), // 80: workflow.plugin.external.iac.SensitiveKeysRequest - (*SensitiveKeysResponse)(nil), // 81: workflow.plugin.external.iac.SensitiveKeysResponse - (*TroubleshootRequest)(nil), // 82: workflow.plugin.external.iac.TroubleshootRequest - (*TroubleshootResponse)(nil), // 83: workflow.plugin.external.iac.TroubleshootResponse - (*IaCState)(nil), // 84: workflow.plugin.external.iac.IaCState - (*ConfigureRequest)(nil), // 85: workflow.plugin.external.iac.ConfigureRequest - (*ConfigureResponse)(nil), // 86: workflow.plugin.external.iac.ConfigureResponse - (*GetStateRequest)(nil), // 87: workflow.plugin.external.iac.GetStateRequest - (*GetStateResponse)(nil), // 88: workflow.plugin.external.iac.GetStateResponse - (*SaveStateRequest)(nil), // 89: workflow.plugin.external.iac.SaveStateRequest - (*SaveStateResponse)(nil), // 90: workflow.plugin.external.iac.SaveStateResponse - (*ListStatesRequest)(nil), // 91: workflow.plugin.external.iac.ListStatesRequest - (*ListStatesResponse)(nil), // 92: workflow.plugin.external.iac.ListStatesResponse - (*DeleteStateRequest)(nil), // 93: workflow.plugin.external.iac.DeleteStateRequest - (*DeleteStateResponse)(nil), // 94: workflow.plugin.external.iac.DeleteStateResponse - (*LockRequest)(nil), // 95: workflow.plugin.external.iac.LockRequest - (*LockResponse)(nil), // 96: workflow.plugin.external.iac.LockResponse - (*UnlockRequest)(nil), // 97: workflow.plugin.external.iac.UnlockRequest - (*UnlockResponse)(nil), // 98: workflow.plugin.external.iac.UnlockResponse - (*ListBackendNamesRequest)(nil), // 99: workflow.plugin.external.iac.ListBackendNamesRequest - (*ListBackendNamesResponse)(nil), // 100: workflow.plugin.external.iac.ListBackendNamesResponse - nil, // 101: workflow.plugin.external.iac.ResourceOutput.SensitiveEntry - nil, // 102: workflow.plugin.external.iac.IaCPlan.InputSnapshotEntry - nil, // 103: workflow.plugin.external.iac.BootstrapResult.EnvVarsEntry - nil, // 104: workflow.plugin.external.iac.MigrationRepairRequest.EnvEntry - nil, // 105: workflow.plugin.external.iac.DetectDriftWithSpecsRequest.SpecsEntry - nil, // 106: workflow.plugin.external.iac.DetectDriftConfigRequest.SpecsEntry - nil, // 107: workflow.plugin.external.iac.ListStatesRequest.FilterEntry - (*timestamppb.Timestamp)(nil), // 108: google.protobuf.Timestamp + (RequirementKind)(0), // 1: workflow.plugin.external.iac.RequirementKind + (RequirementRuntime)(0), // 2: workflow.plugin.external.iac.RequirementRuntime + (TelemetrySignal)(0), // 3: workflow.plugin.external.iac.TelemetrySignal + (ObservabilityBackend)(0), // 4: workflow.plugin.external.iac.ObservabilityBackend + (DeploymentMode)(0), // 5: workflow.plugin.external.iac.DeploymentMode + (PlanDiagnosticSeverity)(0), // 6: workflow.plugin.external.iac.PlanDiagnosticSeverity + (ActionStatus)(0), // 7: workflow.plugin.external.iac.ActionStatus + (LogCaptureType)(0), // 8: workflow.plugin.external.iac.LogCaptureType + (*ResourceSpec)(nil), // 9: workflow.plugin.external.iac.ResourceSpec + (*ResourceRef)(nil), // 10: workflow.plugin.external.iac.ResourceRef + (*ResourceHints)(nil), // 11: workflow.plugin.external.iac.ResourceHints + (*ProviderSizing)(nil), // 12: workflow.plugin.external.iac.ProviderSizing + (*IaCCapabilityDeclaration)(nil), // 13: workflow.plugin.external.iac.IaCCapabilityDeclaration + (*ResourceState)(nil), // 14: workflow.plugin.external.iac.ResourceState + (*ResourceOutput)(nil), // 15: workflow.plugin.external.iac.ResourceOutput + (*ResourceStatus)(nil), // 16: workflow.plugin.external.iac.ResourceStatus + (*FieldChange)(nil), // 17: workflow.plugin.external.iac.FieldChange + (*DiffResult)(nil), // 18: workflow.plugin.external.iac.DiffResult + (*IaCRequirement)(nil), // 19: workflow.plugin.external.iac.IaCRequirement + (*DiscoverRequirementsRequest)(nil), // 20: workflow.plugin.external.iac.DiscoverRequirementsRequest + (*RequirementContext)(nil), // 21: workflow.plugin.external.iac.RequirementContext + (*ModuleRef)(nil), // 22: workflow.plugin.external.iac.ModuleRef + (*DiscoverRequirementsResponse)(nil), // 23: workflow.plugin.external.iac.DiscoverRequirementsResponse + (*MapRequirementsRequest)(nil), // 24: workflow.plugin.external.iac.MapRequirementsRequest + (*DerivedModuleSpec)(nil), // 25: workflow.plugin.external.iac.DerivedModuleSpec + (*RequirementDiagnostic)(nil), // 26: workflow.plugin.external.iac.RequirementDiagnostic + (*RequirementNote)(nil), // 27: workflow.plugin.external.iac.RequirementNote + (*MapRequirementsResponse)(nil), // 28: workflow.plugin.external.iac.MapRequirementsResponse + (*DriftResult)(nil), // 29: workflow.plugin.external.iac.DriftResult + (*DriftEntry)(nil), // 30: workflow.plugin.external.iac.DriftEntry + (*HealthResult)(nil), // 31: workflow.plugin.external.iac.HealthResult + (*Diagnostic)(nil), // 32: workflow.plugin.external.iac.Diagnostic + (*PlanDiagnostic)(nil), // 33: workflow.plugin.external.iac.PlanDiagnostic + (*PlanAction)(nil), // 34: workflow.plugin.external.iac.PlanAction + (*IaCPlan)(nil), // 35: workflow.plugin.external.iac.IaCPlan + (*ActionError)(nil), // 36: workflow.plugin.external.iac.ActionError + (*DestroyResult)(nil), // 37: workflow.plugin.external.iac.DestroyResult + (*BootstrapResult)(nil), // 38: workflow.plugin.external.iac.BootstrapResult + (*MigrationRepairRequest)(nil), // 39: workflow.plugin.external.iac.MigrationRepairRequest + (*MigrationRepairResult)(nil), // 40: workflow.plugin.external.iac.MigrationRepairResult + (*InitializeRequest)(nil), // 41: workflow.plugin.external.iac.InitializeRequest + (*InitializeResponse)(nil), // 42: workflow.plugin.external.iac.InitializeResponse + (*NameRequest)(nil), // 43: workflow.plugin.external.iac.NameRequest + (*NameResponse)(nil), // 44: workflow.plugin.external.iac.NameResponse + (*VersionRequest)(nil), // 45: workflow.plugin.external.iac.VersionRequest + (*VersionResponse)(nil), // 46: workflow.plugin.external.iac.VersionResponse + (*CapabilitiesRequest)(nil), // 47: workflow.plugin.external.iac.CapabilitiesRequest + (*CapabilitiesResponse)(nil), // 48: workflow.plugin.external.iac.CapabilitiesResponse + (*PlanRequest)(nil), // 49: workflow.plugin.external.iac.PlanRequest + (*PlanResponse)(nil), // 50: workflow.plugin.external.iac.PlanResponse + (*DestroyRequest)(nil), // 51: workflow.plugin.external.iac.DestroyRequest + (*DestroyResponse)(nil), // 52: workflow.plugin.external.iac.DestroyResponse + (*StatusRequest)(nil), // 53: workflow.plugin.external.iac.StatusRequest + (*StatusResponse)(nil), // 54: workflow.plugin.external.iac.StatusResponse + (*ImportRequest)(nil), // 55: workflow.plugin.external.iac.ImportRequest + (*ImportResponse)(nil), // 56: workflow.plugin.external.iac.ImportResponse + (*ResolveSizingRequest)(nil), // 57: workflow.plugin.external.iac.ResolveSizingRequest + (*ResolveSizingResponse)(nil), // 58: workflow.plugin.external.iac.ResolveSizingResponse + (*BootstrapStateBackendRequest)(nil), // 59: workflow.plugin.external.iac.BootstrapStateBackendRequest + (*BootstrapStateBackendResponse)(nil), // 60: workflow.plugin.external.iac.BootstrapStateBackendResponse + (*EnumerateAllRequest)(nil), // 61: workflow.plugin.external.iac.EnumerateAllRequest + (*EnumerateAllResponse)(nil), // 62: workflow.plugin.external.iac.EnumerateAllResponse + (*EnumerateByTagRequest)(nil), // 63: workflow.plugin.external.iac.EnumerateByTagRequest + (*EnumerateByTagResponse)(nil), // 64: workflow.plugin.external.iac.EnumerateByTagResponse + (*DetectDriftRequest)(nil), // 65: workflow.plugin.external.iac.DetectDriftRequest + (*DetectDriftResponse)(nil), // 66: workflow.plugin.external.iac.DetectDriftResponse + (*DetectDriftWithSpecsRequest)(nil), // 67: workflow.plugin.external.iac.DetectDriftWithSpecsRequest + (*DetectDriftWithSpecsResponse)(nil), // 68: workflow.plugin.external.iac.DetectDriftWithSpecsResponse + (*RevokeProviderCredentialRequest)(nil), // 69: workflow.plugin.external.iac.RevokeProviderCredentialRequest + (*RevokeProviderCredentialResponse)(nil), // 70: workflow.plugin.external.iac.RevokeProviderCredentialResponse + (*FinalizeApplyRequest)(nil), // 71: workflow.plugin.external.iac.FinalizeApplyRequest + (*FinalizeApplyResponse)(nil), // 72: workflow.plugin.external.iac.FinalizeApplyResponse + (*RepairDirtyMigrationRequest)(nil), // 73: workflow.plugin.external.iac.RepairDirtyMigrationRequest + (*RepairDirtyMigrationResponse)(nil), // 74: workflow.plugin.external.iac.RepairDirtyMigrationResponse + (*ValidatePlanRequest)(nil), // 75: workflow.plugin.external.iac.ValidatePlanRequest + (*ValidatePlanResponse)(nil), // 76: workflow.plugin.external.iac.ValidatePlanResponse + (*DetectDriftConfigRequest)(nil), // 77: workflow.plugin.external.iac.DetectDriftConfigRequest + (*DetectDriftConfigResponse)(nil), // 78: workflow.plugin.external.iac.DetectDriftConfigResponse + (*CaptureLogsRequest)(nil), // 79: workflow.plugin.external.iac.CaptureLogsRequest + (*LogChunk)(nil), // 80: workflow.plugin.external.iac.LogChunk + (*ResourceCreateRequest)(nil), // 81: workflow.plugin.external.iac.ResourceCreateRequest + (*ResourceCreateResponse)(nil), // 82: workflow.plugin.external.iac.ResourceCreateResponse + (*ResourceReadRequest)(nil), // 83: workflow.plugin.external.iac.ResourceReadRequest + (*ResourceReadResponse)(nil), // 84: workflow.plugin.external.iac.ResourceReadResponse + (*ResourceUpdateRequest)(nil), // 85: workflow.plugin.external.iac.ResourceUpdateRequest + (*ResourceUpdateResponse)(nil), // 86: workflow.plugin.external.iac.ResourceUpdateResponse + (*ResourceDeleteRequest)(nil), // 87: workflow.plugin.external.iac.ResourceDeleteRequest + (*ResourceDeleteResponse)(nil), // 88: workflow.plugin.external.iac.ResourceDeleteResponse + (*ResourceDiffRequest)(nil), // 89: workflow.plugin.external.iac.ResourceDiffRequest + (*ResourceDiffResponse)(nil), // 90: workflow.plugin.external.iac.ResourceDiffResponse + (*ResourceScaleRequest)(nil), // 91: workflow.plugin.external.iac.ResourceScaleRequest + (*ResourceScaleResponse)(nil), // 92: workflow.plugin.external.iac.ResourceScaleResponse + (*ResourceHealthCheckRequest)(nil), // 93: workflow.plugin.external.iac.ResourceHealthCheckRequest + (*ResourceHealthCheckResponse)(nil), // 94: workflow.plugin.external.iac.ResourceHealthCheckResponse + (*SensitiveKeysRequest)(nil), // 95: workflow.plugin.external.iac.SensitiveKeysRequest + (*SensitiveKeysResponse)(nil), // 96: workflow.plugin.external.iac.SensitiveKeysResponse + (*TroubleshootRequest)(nil), // 97: workflow.plugin.external.iac.TroubleshootRequest + (*TroubleshootResponse)(nil), // 98: workflow.plugin.external.iac.TroubleshootResponse + (*IaCState)(nil), // 99: workflow.plugin.external.iac.IaCState + (*ConfigureRequest)(nil), // 100: workflow.plugin.external.iac.ConfigureRequest + (*ConfigureResponse)(nil), // 101: workflow.plugin.external.iac.ConfigureResponse + (*GetStateRequest)(nil), // 102: workflow.plugin.external.iac.GetStateRequest + (*GetStateResponse)(nil), // 103: workflow.plugin.external.iac.GetStateResponse + (*SaveStateRequest)(nil), // 104: workflow.plugin.external.iac.SaveStateRequest + (*SaveStateResponse)(nil), // 105: workflow.plugin.external.iac.SaveStateResponse + (*ListStatesRequest)(nil), // 106: workflow.plugin.external.iac.ListStatesRequest + (*ListStatesResponse)(nil), // 107: workflow.plugin.external.iac.ListStatesResponse + (*DeleteStateRequest)(nil), // 108: workflow.plugin.external.iac.DeleteStateRequest + (*DeleteStateResponse)(nil), // 109: workflow.plugin.external.iac.DeleteStateResponse + (*LockRequest)(nil), // 110: workflow.plugin.external.iac.LockRequest + (*LockResponse)(nil), // 111: workflow.plugin.external.iac.LockResponse + (*UnlockRequest)(nil), // 112: workflow.plugin.external.iac.UnlockRequest + (*UnlockResponse)(nil), // 113: workflow.plugin.external.iac.UnlockResponse + (*ListBackendNamesRequest)(nil), // 114: workflow.plugin.external.iac.ListBackendNamesRequest + (*ListBackendNamesResponse)(nil), // 115: workflow.plugin.external.iac.ListBackendNamesResponse + nil, // 116: workflow.plugin.external.iac.ResourceOutput.SensitiveEntry + nil, // 117: workflow.plugin.external.iac.IaCPlan.InputSnapshotEntry + nil, // 118: workflow.plugin.external.iac.BootstrapResult.EnvVarsEntry + nil, // 119: workflow.plugin.external.iac.MigrationRepairRequest.EnvEntry + nil, // 120: workflow.plugin.external.iac.DetectDriftWithSpecsRequest.SpecsEntry + nil, // 121: workflow.plugin.external.iac.DetectDriftConfigRequest.SpecsEntry + nil, // 122: workflow.plugin.external.iac.ListStatesRequest.FilterEntry + (*timestamppb.Timestamp)(nil), // 123: google.protobuf.Timestamp } var file_iac_proto_depIdxs = []int32{ - 6, // 0: workflow.plugin.external.iac.ResourceSpec.hints:type_name -> workflow.plugin.external.iac.ResourceHints - 108, // 1: workflow.plugin.external.iac.ResourceState.created_at:type_name -> google.protobuf.Timestamp - 108, // 2: workflow.plugin.external.iac.ResourceState.updated_at:type_name -> google.protobuf.Timestamp - 108, // 3: workflow.plugin.external.iac.ResourceState.last_drift_check:type_name -> google.protobuf.Timestamp - 101, // 4: workflow.plugin.external.iac.ResourceOutput.sensitive:type_name -> workflow.plugin.external.iac.ResourceOutput.SensitiveEntry - 12, // 5: workflow.plugin.external.iac.DiffResult.changes:type_name -> workflow.plugin.external.iac.FieldChange - 0, // 6: workflow.plugin.external.iac.DriftResult.class:type_name -> workflow.plugin.external.iac.DriftClass - 108, // 7: workflow.plugin.external.iac.Diagnostic.at:type_name -> google.protobuf.Timestamp - 1, // 8: workflow.plugin.external.iac.PlanDiagnostic.severity:type_name -> workflow.plugin.external.iac.PlanDiagnosticSeverity - 4, // 9: workflow.plugin.external.iac.PlanAction.resource:type_name -> workflow.plugin.external.iac.ResourceSpec - 9, // 10: workflow.plugin.external.iac.PlanAction.current:type_name -> workflow.plugin.external.iac.ResourceState - 12, // 11: workflow.plugin.external.iac.PlanAction.changes:type_name -> workflow.plugin.external.iac.FieldChange - 19, // 12: workflow.plugin.external.iac.IaCPlan.actions:type_name -> workflow.plugin.external.iac.PlanAction - 108, // 13: workflow.plugin.external.iac.IaCPlan.created_at:type_name -> google.protobuf.Timestamp - 102, // 14: workflow.plugin.external.iac.IaCPlan.input_snapshot:type_name -> workflow.plugin.external.iac.IaCPlan.InputSnapshotEntry - 21, // 15: workflow.plugin.external.iac.DestroyResult.errors:type_name -> workflow.plugin.external.iac.ActionError - 103, // 16: workflow.plugin.external.iac.BootstrapResult.env_vars:type_name -> workflow.plugin.external.iac.BootstrapResult.EnvVarsEntry - 104, // 17: workflow.plugin.external.iac.MigrationRepairRequest.env:type_name -> workflow.plugin.external.iac.MigrationRepairRequest.EnvEntry - 17, // 18: workflow.plugin.external.iac.MigrationRepairResult.diagnostics:type_name -> workflow.plugin.external.iac.Diagnostic - 8, // 19: workflow.plugin.external.iac.CapabilitiesResponse.capabilities:type_name -> workflow.plugin.external.iac.IaCCapabilityDeclaration - 4, // 20: workflow.plugin.external.iac.PlanRequest.desired:type_name -> workflow.plugin.external.iac.ResourceSpec - 9, // 21: workflow.plugin.external.iac.PlanRequest.current:type_name -> workflow.plugin.external.iac.ResourceState - 20, // 22: workflow.plugin.external.iac.PlanResponse.plan:type_name -> workflow.plugin.external.iac.IaCPlan - 5, // 23: workflow.plugin.external.iac.DestroyRequest.refs:type_name -> workflow.plugin.external.iac.ResourceRef - 22, // 24: workflow.plugin.external.iac.DestroyResponse.result:type_name -> workflow.plugin.external.iac.DestroyResult - 5, // 25: workflow.plugin.external.iac.StatusRequest.refs:type_name -> workflow.plugin.external.iac.ResourceRef - 11, // 26: workflow.plugin.external.iac.StatusResponse.statuses:type_name -> workflow.plugin.external.iac.ResourceStatus - 9, // 27: workflow.plugin.external.iac.ImportResponse.state:type_name -> workflow.plugin.external.iac.ResourceState - 6, // 28: workflow.plugin.external.iac.ResolveSizingRequest.hints:type_name -> workflow.plugin.external.iac.ResourceHints - 7, // 29: workflow.plugin.external.iac.ResolveSizingResponse.sizing:type_name -> workflow.plugin.external.iac.ProviderSizing - 23, // 30: workflow.plugin.external.iac.BootstrapStateBackendResponse.result:type_name -> workflow.plugin.external.iac.BootstrapResult - 10, // 31: workflow.plugin.external.iac.EnumerateAllResponse.outputs:type_name -> workflow.plugin.external.iac.ResourceOutput - 5, // 32: workflow.plugin.external.iac.EnumerateByTagResponse.refs:type_name -> workflow.plugin.external.iac.ResourceRef - 5, // 33: workflow.plugin.external.iac.DetectDriftRequest.refs:type_name -> workflow.plugin.external.iac.ResourceRef - 14, // 34: workflow.plugin.external.iac.DetectDriftResponse.drifts:type_name -> workflow.plugin.external.iac.DriftResult - 5, // 35: workflow.plugin.external.iac.DetectDriftWithSpecsRequest.refs:type_name -> workflow.plugin.external.iac.ResourceRef - 105, // 36: workflow.plugin.external.iac.DetectDriftWithSpecsRequest.specs:type_name -> workflow.plugin.external.iac.DetectDriftWithSpecsRequest.SpecsEntry - 14, // 37: workflow.plugin.external.iac.DetectDriftWithSpecsResponse.drifts:type_name -> workflow.plugin.external.iac.DriftResult - 21, // 38: workflow.plugin.external.iac.FinalizeApplyResponse.errors:type_name -> workflow.plugin.external.iac.ActionError - 24, // 39: workflow.plugin.external.iac.RepairDirtyMigrationRequest.request:type_name -> workflow.plugin.external.iac.MigrationRepairRequest - 25, // 40: workflow.plugin.external.iac.RepairDirtyMigrationResponse.result:type_name -> workflow.plugin.external.iac.MigrationRepairResult - 20, // 41: workflow.plugin.external.iac.ValidatePlanRequest.plan:type_name -> workflow.plugin.external.iac.IaCPlan - 18, // 42: workflow.plugin.external.iac.ValidatePlanResponse.diagnostics:type_name -> workflow.plugin.external.iac.PlanDiagnostic - 5, // 43: workflow.plugin.external.iac.DetectDriftConfigRequest.refs:type_name -> workflow.plugin.external.iac.ResourceRef - 106, // 44: workflow.plugin.external.iac.DetectDriftConfigRequest.specs:type_name -> workflow.plugin.external.iac.DetectDriftConfigRequest.SpecsEntry - 14, // 45: workflow.plugin.external.iac.DetectDriftConfigResponse.drifts:type_name -> workflow.plugin.external.iac.DriftResult - 3, // 46: workflow.plugin.external.iac.CaptureLogsRequest.log_type:type_name -> workflow.plugin.external.iac.LogCaptureType - 4, // 47: workflow.plugin.external.iac.ResourceCreateRequest.spec:type_name -> workflow.plugin.external.iac.ResourceSpec - 10, // 48: workflow.plugin.external.iac.ResourceCreateResponse.output:type_name -> workflow.plugin.external.iac.ResourceOutput - 5, // 49: workflow.plugin.external.iac.ResourceReadRequest.ref:type_name -> workflow.plugin.external.iac.ResourceRef - 10, // 50: workflow.plugin.external.iac.ResourceReadResponse.output:type_name -> workflow.plugin.external.iac.ResourceOutput - 5, // 51: workflow.plugin.external.iac.ResourceUpdateRequest.ref:type_name -> workflow.plugin.external.iac.ResourceRef - 4, // 52: workflow.plugin.external.iac.ResourceUpdateRequest.spec:type_name -> workflow.plugin.external.iac.ResourceSpec - 10, // 53: workflow.plugin.external.iac.ResourceUpdateResponse.output:type_name -> workflow.plugin.external.iac.ResourceOutput - 5, // 54: workflow.plugin.external.iac.ResourceDeleteRequest.ref:type_name -> workflow.plugin.external.iac.ResourceRef - 4, // 55: workflow.plugin.external.iac.ResourceDiffRequest.desired:type_name -> workflow.plugin.external.iac.ResourceSpec - 10, // 56: workflow.plugin.external.iac.ResourceDiffRequest.current:type_name -> workflow.plugin.external.iac.ResourceOutput - 13, // 57: workflow.plugin.external.iac.ResourceDiffResponse.result:type_name -> workflow.plugin.external.iac.DiffResult - 5, // 58: workflow.plugin.external.iac.ResourceScaleRequest.ref:type_name -> workflow.plugin.external.iac.ResourceRef - 10, // 59: workflow.plugin.external.iac.ResourceScaleResponse.output:type_name -> workflow.plugin.external.iac.ResourceOutput - 5, // 60: workflow.plugin.external.iac.ResourceHealthCheckRequest.ref:type_name -> workflow.plugin.external.iac.ResourceRef - 16, // 61: workflow.plugin.external.iac.ResourceHealthCheckResponse.result:type_name -> workflow.plugin.external.iac.HealthResult - 5, // 62: workflow.plugin.external.iac.TroubleshootRequest.ref:type_name -> workflow.plugin.external.iac.ResourceRef - 17, // 63: workflow.plugin.external.iac.TroubleshootResponse.diagnostics:type_name -> workflow.plugin.external.iac.Diagnostic - 84, // 64: workflow.plugin.external.iac.GetStateResponse.state:type_name -> workflow.plugin.external.iac.IaCState - 84, // 65: workflow.plugin.external.iac.SaveStateRequest.state:type_name -> workflow.plugin.external.iac.IaCState - 107, // 66: workflow.plugin.external.iac.ListStatesRequest.filter:type_name -> workflow.plugin.external.iac.ListStatesRequest.FilterEntry - 84, // 67: workflow.plugin.external.iac.ListStatesResponse.states:type_name -> workflow.plugin.external.iac.IaCState - 4, // 68: workflow.plugin.external.iac.DetectDriftWithSpecsRequest.SpecsEntry.value:type_name -> workflow.plugin.external.iac.ResourceSpec - 4, // 69: workflow.plugin.external.iac.DetectDriftConfigRequest.SpecsEntry.value:type_name -> workflow.plugin.external.iac.ResourceSpec - 26, // 70: workflow.plugin.external.iac.IaCProviderRequired.Initialize:input_type -> workflow.plugin.external.iac.InitializeRequest - 28, // 71: workflow.plugin.external.iac.IaCProviderRequired.Name:input_type -> workflow.plugin.external.iac.NameRequest - 30, // 72: workflow.plugin.external.iac.IaCProviderRequired.Version:input_type -> workflow.plugin.external.iac.VersionRequest - 32, // 73: workflow.plugin.external.iac.IaCProviderRequired.Capabilities:input_type -> workflow.plugin.external.iac.CapabilitiesRequest - 34, // 74: workflow.plugin.external.iac.IaCProviderRequired.Plan:input_type -> workflow.plugin.external.iac.PlanRequest - 36, // 75: workflow.plugin.external.iac.IaCProviderRequired.Destroy:input_type -> workflow.plugin.external.iac.DestroyRequest - 38, // 76: workflow.plugin.external.iac.IaCProviderRequired.Status:input_type -> workflow.plugin.external.iac.StatusRequest - 40, // 77: workflow.plugin.external.iac.IaCProviderRequired.Import:input_type -> workflow.plugin.external.iac.ImportRequest - 42, // 78: workflow.plugin.external.iac.IaCProviderRequired.ResolveSizing:input_type -> workflow.plugin.external.iac.ResolveSizingRequest - 44, // 79: workflow.plugin.external.iac.IaCProviderRequired.BootstrapStateBackend:input_type -> workflow.plugin.external.iac.BootstrapStateBackendRequest - 46, // 80: workflow.plugin.external.iac.IaCProviderEnumerator.EnumerateAll:input_type -> workflow.plugin.external.iac.EnumerateAllRequest - 48, // 81: workflow.plugin.external.iac.IaCProviderEnumerator.EnumerateByTag:input_type -> workflow.plugin.external.iac.EnumerateByTagRequest - 50, // 82: workflow.plugin.external.iac.IaCProviderDriftDetector.DetectDrift:input_type -> workflow.plugin.external.iac.DetectDriftRequest - 52, // 83: workflow.plugin.external.iac.IaCProviderDriftDetector.DetectDriftWithSpecs:input_type -> workflow.plugin.external.iac.DetectDriftWithSpecsRequest - 54, // 84: workflow.plugin.external.iac.IaCProviderCredentialRevoker.RevokeProviderCredential:input_type -> workflow.plugin.external.iac.RevokeProviderCredentialRequest - 56, // 85: workflow.plugin.external.iac.IaCProviderFinalizer.FinalizeApply:input_type -> workflow.plugin.external.iac.FinalizeApplyRequest - 58, // 86: workflow.plugin.external.iac.IaCProviderMigrationRepairer.RepairDirtyMigration:input_type -> workflow.plugin.external.iac.RepairDirtyMigrationRequest - 60, // 87: workflow.plugin.external.iac.IaCProviderValidator.ValidatePlan:input_type -> workflow.plugin.external.iac.ValidatePlanRequest - 62, // 88: workflow.plugin.external.iac.IaCProviderDriftConfigDetector.DetectDriftConfig:input_type -> workflow.plugin.external.iac.DetectDriftConfigRequest - 64, // 89: workflow.plugin.external.iac.IaCProviderLogCapture.CaptureLogs:input_type -> workflow.plugin.external.iac.CaptureLogsRequest - 66, // 90: workflow.plugin.external.iac.ResourceDriver.Create:input_type -> workflow.plugin.external.iac.ResourceCreateRequest - 68, // 91: workflow.plugin.external.iac.ResourceDriver.Read:input_type -> workflow.plugin.external.iac.ResourceReadRequest - 70, // 92: workflow.plugin.external.iac.ResourceDriver.Update:input_type -> workflow.plugin.external.iac.ResourceUpdateRequest - 72, // 93: workflow.plugin.external.iac.ResourceDriver.Delete:input_type -> workflow.plugin.external.iac.ResourceDeleteRequest - 74, // 94: workflow.plugin.external.iac.ResourceDriver.Diff:input_type -> workflow.plugin.external.iac.ResourceDiffRequest - 76, // 95: workflow.plugin.external.iac.ResourceDriver.Scale:input_type -> workflow.plugin.external.iac.ResourceScaleRequest - 78, // 96: workflow.plugin.external.iac.ResourceDriver.HealthCheck:input_type -> workflow.plugin.external.iac.ResourceHealthCheckRequest - 80, // 97: workflow.plugin.external.iac.ResourceDriver.SensitiveKeys:input_type -> workflow.plugin.external.iac.SensitiveKeysRequest - 82, // 98: workflow.plugin.external.iac.ResourceDriver.Troubleshoot:input_type -> workflow.plugin.external.iac.TroubleshootRequest - 85, // 99: workflow.plugin.external.iac.IaCStateBackend.Configure:input_type -> workflow.plugin.external.iac.ConfigureRequest - 87, // 100: workflow.plugin.external.iac.IaCStateBackend.GetState:input_type -> workflow.plugin.external.iac.GetStateRequest - 89, // 101: workflow.plugin.external.iac.IaCStateBackend.SaveState:input_type -> workflow.plugin.external.iac.SaveStateRequest - 91, // 102: workflow.plugin.external.iac.IaCStateBackend.ListStates:input_type -> workflow.plugin.external.iac.ListStatesRequest - 93, // 103: workflow.plugin.external.iac.IaCStateBackend.DeleteState:input_type -> workflow.plugin.external.iac.DeleteStateRequest - 95, // 104: workflow.plugin.external.iac.IaCStateBackend.Lock:input_type -> workflow.plugin.external.iac.LockRequest - 97, // 105: workflow.plugin.external.iac.IaCStateBackend.Unlock:input_type -> workflow.plugin.external.iac.UnlockRequest - 99, // 106: workflow.plugin.external.iac.IaCStateBackend.ListBackendNames:input_type -> workflow.plugin.external.iac.ListBackendNamesRequest - 27, // 107: workflow.plugin.external.iac.IaCProviderRequired.Initialize:output_type -> workflow.plugin.external.iac.InitializeResponse - 29, // 108: workflow.plugin.external.iac.IaCProviderRequired.Name:output_type -> workflow.plugin.external.iac.NameResponse - 31, // 109: workflow.plugin.external.iac.IaCProviderRequired.Version:output_type -> workflow.plugin.external.iac.VersionResponse - 33, // 110: workflow.plugin.external.iac.IaCProviderRequired.Capabilities:output_type -> workflow.plugin.external.iac.CapabilitiesResponse - 35, // 111: workflow.plugin.external.iac.IaCProviderRequired.Plan:output_type -> workflow.plugin.external.iac.PlanResponse - 37, // 112: workflow.plugin.external.iac.IaCProviderRequired.Destroy:output_type -> workflow.plugin.external.iac.DestroyResponse - 39, // 113: workflow.plugin.external.iac.IaCProviderRequired.Status:output_type -> workflow.plugin.external.iac.StatusResponse - 41, // 114: workflow.plugin.external.iac.IaCProviderRequired.Import:output_type -> workflow.plugin.external.iac.ImportResponse - 43, // 115: workflow.plugin.external.iac.IaCProviderRequired.ResolveSizing:output_type -> workflow.plugin.external.iac.ResolveSizingResponse - 45, // 116: workflow.plugin.external.iac.IaCProviderRequired.BootstrapStateBackend:output_type -> workflow.plugin.external.iac.BootstrapStateBackendResponse - 47, // 117: workflow.plugin.external.iac.IaCProviderEnumerator.EnumerateAll:output_type -> workflow.plugin.external.iac.EnumerateAllResponse - 49, // 118: workflow.plugin.external.iac.IaCProviderEnumerator.EnumerateByTag:output_type -> workflow.plugin.external.iac.EnumerateByTagResponse - 51, // 119: workflow.plugin.external.iac.IaCProviderDriftDetector.DetectDrift:output_type -> workflow.plugin.external.iac.DetectDriftResponse - 53, // 120: workflow.plugin.external.iac.IaCProviderDriftDetector.DetectDriftWithSpecs:output_type -> workflow.plugin.external.iac.DetectDriftWithSpecsResponse - 55, // 121: workflow.plugin.external.iac.IaCProviderCredentialRevoker.RevokeProviderCredential:output_type -> workflow.plugin.external.iac.RevokeProviderCredentialResponse - 57, // 122: workflow.plugin.external.iac.IaCProviderFinalizer.FinalizeApply:output_type -> workflow.plugin.external.iac.FinalizeApplyResponse - 59, // 123: workflow.plugin.external.iac.IaCProviderMigrationRepairer.RepairDirtyMigration:output_type -> workflow.plugin.external.iac.RepairDirtyMigrationResponse - 61, // 124: workflow.plugin.external.iac.IaCProviderValidator.ValidatePlan:output_type -> workflow.plugin.external.iac.ValidatePlanResponse - 63, // 125: workflow.plugin.external.iac.IaCProviderDriftConfigDetector.DetectDriftConfig:output_type -> workflow.plugin.external.iac.DetectDriftConfigResponse - 65, // 126: workflow.plugin.external.iac.IaCProviderLogCapture.CaptureLogs:output_type -> workflow.plugin.external.iac.LogChunk - 67, // 127: workflow.plugin.external.iac.ResourceDriver.Create:output_type -> workflow.plugin.external.iac.ResourceCreateResponse - 69, // 128: workflow.plugin.external.iac.ResourceDriver.Read:output_type -> workflow.plugin.external.iac.ResourceReadResponse - 71, // 129: workflow.plugin.external.iac.ResourceDriver.Update:output_type -> workflow.plugin.external.iac.ResourceUpdateResponse - 73, // 130: workflow.plugin.external.iac.ResourceDriver.Delete:output_type -> workflow.plugin.external.iac.ResourceDeleteResponse - 75, // 131: workflow.plugin.external.iac.ResourceDriver.Diff:output_type -> workflow.plugin.external.iac.ResourceDiffResponse - 77, // 132: workflow.plugin.external.iac.ResourceDriver.Scale:output_type -> workflow.plugin.external.iac.ResourceScaleResponse - 79, // 133: workflow.plugin.external.iac.ResourceDriver.HealthCheck:output_type -> workflow.plugin.external.iac.ResourceHealthCheckResponse - 81, // 134: workflow.plugin.external.iac.ResourceDriver.SensitiveKeys:output_type -> workflow.plugin.external.iac.SensitiveKeysResponse - 83, // 135: workflow.plugin.external.iac.ResourceDriver.Troubleshoot:output_type -> workflow.plugin.external.iac.TroubleshootResponse - 86, // 136: workflow.plugin.external.iac.IaCStateBackend.Configure:output_type -> workflow.plugin.external.iac.ConfigureResponse - 88, // 137: workflow.plugin.external.iac.IaCStateBackend.GetState:output_type -> workflow.plugin.external.iac.GetStateResponse - 90, // 138: workflow.plugin.external.iac.IaCStateBackend.SaveState:output_type -> workflow.plugin.external.iac.SaveStateResponse - 92, // 139: workflow.plugin.external.iac.IaCStateBackend.ListStates:output_type -> workflow.plugin.external.iac.ListStatesResponse - 94, // 140: workflow.plugin.external.iac.IaCStateBackend.DeleteState:output_type -> workflow.plugin.external.iac.DeleteStateResponse - 96, // 141: workflow.plugin.external.iac.IaCStateBackend.Lock:output_type -> workflow.plugin.external.iac.LockResponse - 98, // 142: workflow.plugin.external.iac.IaCStateBackend.Unlock:output_type -> workflow.plugin.external.iac.UnlockResponse - 100, // 143: workflow.plugin.external.iac.IaCStateBackend.ListBackendNames:output_type -> workflow.plugin.external.iac.ListBackendNamesResponse - 107, // [107:144] is the sub-list for method output_type - 70, // [70:107] is the sub-list for method input_type - 70, // [70:70] is the sub-list for extension type_name - 70, // [70:70] is the sub-list for extension extendee - 0, // [0:70] is the sub-list for field type_name + 11, // 0: workflow.plugin.external.iac.ResourceSpec.hints:type_name -> workflow.plugin.external.iac.ResourceHints + 123, // 1: workflow.plugin.external.iac.ResourceState.created_at:type_name -> google.protobuf.Timestamp + 123, // 2: workflow.plugin.external.iac.ResourceState.updated_at:type_name -> google.protobuf.Timestamp + 123, // 3: workflow.plugin.external.iac.ResourceState.last_drift_check:type_name -> google.protobuf.Timestamp + 116, // 4: workflow.plugin.external.iac.ResourceOutput.sensitive:type_name -> workflow.plugin.external.iac.ResourceOutput.SensitiveEntry + 17, // 5: workflow.plugin.external.iac.DiffResult.changes:type_name -> workflow.plugin.external.iac.FieldChange + 1, // 6: workflow.plugin.external.iac.IaCRequirement.kind:type_name -> workflow.plugin.external.iac.RequirementKind + 2, // 7: workflow.plugin.external.iac.IaCRequirement.runtimes:type_name -> workflow.plugin.external.iac.RequirementRuntime + 3, // 8: workflow.plugin.external.iac.IaCRequirement.telemetry_signals:type_name -> workflow.plugin.external.iac.TelemetrySignal + 4, // 9: workflow.plugin.external.iac.IaCRequirement.observability_backends:type_name -> workflow.plugin.external.iac.ObservabilityBackend + 5, // 10: workflow.plugin.external.iac.IaCRequirement.deployment_modes:type_name -> workflow.plugin.external.iac.DeploymentMode + 21, // 11: workflow.plugin.external.iac.DiscoverRequirementsRequest.context:type_name -> workflow.plugin.external.iac.RequirementContext + 22, // 12: workflow.plugin.external.iac.RequirementContext.modules:type_name -> workflow.plugin.external.iac.ModuleRef + 19, // 13: workflow.plugin.external.iac.DiscoverRequirementsResponse.requirements:type_name -> workflow.plugin.external.iac.IaCRequirement + 2, // 14: workflow.plugin.external.iac.MapRequirementsRequest.runtime:type_name -> workflow.plugin.external.iac.RequirementRuntime + 19, // 15: workflow.plugin.external.iac.MapRequirementsRequest.requirements:type_name -> workflow.plugin.external.iac.IaCRequirement + 26, // 16: workflow.plugin.external.iac.MapRequirementsResponse.rejected:type_name -> workflow.plugin.external.iac.RequirementDiagnostic + 25, // 17: workflow.plugin.external.iac.MapRequirementsResponse.modules:type_name -> workflow.plugin.external.iac.DerivedModuleSpec + 27, // 18: workflow.plugin.external.iac.MapRequirementsResponse.notes:type_name -> workflow.plugin.external.iac.RequirementNote + 0, // 19: workflow.plugin.external.iac.DriftResult.class:type_name -> workflow.plugin.external.iac.DriftClass + 123, // 20: workflow.plugin.external.iac.Diagnostic.at:type_name -> google.protobuf.Timestamp + 6, // 21: workflow.plugin.external.iac.PlanDiagnostic.severity:type_name -> workflow.plugin.external.iac.PlanDiagnosticSeverity + 9, // 22: workflow.plugin.external.iac.PlanAction.resource:type_name -> workflow.plugin.external.iac.ResourceSpec + 14, // 23: workflow.plugin.external.iac.PlanAction.current:type_name -> workflow.plugin.external.iac.ResourceState + 17, // 24: workflow.plugin.external.iac.PlanAction.changes:type_name -> workflow.plugin.external.iac.FieldChange + 34, // 25: workflow.plugin.external.iac.IaCPlan.actions:type_name -> workflow.plugin.external.iac.PlanAction + 123, // 26: workflow.plugin.external.iac.IaCPlan.created_at:type_name -> google.protobuf.Timestamp + 117, // 27: workflow.plugin.external.iac.IaCPlan.input_snapshot:type_name -> workflow.plugin.external.iac.IaCPlan.InputSnapshotEntry + 36, // 28: workflow.plugin.external.iac.DestroyResult.errors:type_name -> workflow.plugin.external.iac.ActionError + 118, // 29: workflow.plugin.external.iac.BootstrapResult.env_vars:type_name -> workflow.plugin.external.iac.BootstrapResult.EnvVarsEntry + 119, // 30: workflow.plugin.external.iac.MigrationRepairRequest.env:type_name -> workflow.plugin.external.iac.MigrationRepairRequest.EnvEntry + 32, // 31: workflow.plugin.external.iac.MigrationRepairResult.diagnostics:type_name -> workflow.plugin.external.iac.Diagnostic + 13, // 32: workflow.plugin.external.iac.CapabilitiesResponse.capabilities:type_name -> workflow.plugin.external.iac.IaCCapabilityDeclaration + 9, // 33: workflow.plugin.external.iac.PlanRequest.desired:type_name -> workflow.plugin.external.iac.ResourceSpec + 14, // 34: workflow.plugin.external.iac.PlanRequest.current:type_name -> workflow.plugin.external.iac.ResourceState + 35, // 35: workflow.plugin.external.iac.PlanResponse.plan:type_name -> workflow.plugin.external.iac.IaCPlan + 10, // 36: workflow.plugin.external.iac.DestroyRequest.refs:type_name -> workflow.plugin.external.iac.ResourceRef + 37, // 37: workflow.plugin.external.iac.DestroyResponse.result:type_name -> workflow.plugin.external.iac.DestroyResult + 10, // 38: workflow.plugin.external.iac.StatusRequest.refs:type_name -> workflow.plugin.external.iac.ResourceRef + 16, // 39: workflow.plugin.external.iac.StatusResponse.statuses:type_name -> workflow.plugin.external.iac.ResourceStatus + 14, // 40: workflow.plugin.external.iac.ImportResponse.state:type_name -> workflow.plugin.external.iac.ResourceState + 11, // 41: workflow.plugin.external.iac.ResolveSizingRequest.hints:type_name -> workflow.plugin.external.iac.ResourceHints + 12, // 42: workflow.plugin.external.iac.ResolveSizingResponse.sizing:type_name -> workflow.plugin.external.iac.ProviderSizing + 38, // 43: workflow.plugin.external.iac.BootstrapStateBackendResponse.result:type_name -> workflow.plugin.external.iac.BootstrapResult + 15, // 44: workflow.plugin.external.iac.EnumerateAllResponse.outputs:type_name -> workflow.plugin.external.iac.ResourceOutput + 10, // 45: workflow.plugin.external.iac.EnumerateByTagResponse.refs:type_name -> workflow.plugin.external.iac.ResourceRef + 10, // 46: workflow.plugin.external.iac.DetectDriftRequest.refs:type_name -> workflow.plugin.external.iac.ResourceRef + 29, // 47: workflow.plugin.external.iac.DetectDriftResponse.drifts:type_name -> workflow.plugin.external.iac.DriftResult + 10, // 48: workflow.plugin.external.iac.DetectDriftWithSpecsRequest.refs:type_name -> workflow.plugin.external.iac.ResourceRef + 120, // 49: workflow.plugin.external.iac.DetectDriftWithSpecsRequest.specs:type_name -> workflow.plugin.external.iac.DetectDriftWithSpecsRequest.SpecsEntry + 29, // 50: workflow.plugin.external.iac.DetectDriftWithSpecsResponse.drifts:type_name -> workflow.plugin.external.iac.DriftResult + 36, // 51: workflow.plugin.external.iac.FinalizeApplyResponse.errors:type_name -> workflow.plugin.external.iac.ActionError + 39, // 52: workflow.plugin.external.iac.RepairDirtyMigrationRequest.request:type_name -> workflow.plugin.external.iac.MigrationRepairRequest + 40, // 53: workflow.plugin.external.iac.RepairDirtyMigrationResponse.result:type_name -> workflow.plugin.external.iac.MigrationRepairResult + 35, // 54: workflow.plugin.external.iac.ValidatePlanRequest.plan:type_name -> workflow.plugin.external.iac.IaCPlan + 33, // 55: workflow.plugin.external.iac.ValidatePlanResponse.diagnostics:type_name -> workflow.plugin.external.iac.PlanDiagnostic + 10, // 56: workflow.plugin.external.iac.DetectDriftConfigRequest.refs:type_name -> workflow.plugin.external.iac.ResourceRef + 121, // 57: workflow.plugin.external.iac.DetectDriftConfigRequest.specs:type_name -> workflow.plugin.external.iac.DetectDriftConfigRequest.SpecsEntry + 29, // 58: workflow.plugin.external.iac.DetectDriftConfigResponse.drifts:type_name -> workflow.plugin.external.iac.DriftResult + 8, // 59: workflow.plugin.external.iac.CaptureLogsRequest.log_type:type_name -> workflow.plugin.external.iac.LogCaptureType + 9, // 60: workflow.plugin.external.iac.ResourceCreateRequest.spec:type_name -> workflow.plugin.external.iac.ResourceSpec + 15, // 61: workflow.plugin.external.iac.ResourceCreateResponse.output:type_name -> workflow.plugin.external.iac.ResourceOutput + 10, // 62: workflow.plugin.external.iac.ResourceReadRequest.ref:type_name -> workflow.plugin.external.iac.ResourceRef + 15, // 63: workflow.plugin.external.iac.ResourceReadResponse.output:type_name -> workflow.plugin.external.iac.ResourceOutput + 10, // 64: workflow.plugin.external.iac.ResourceUpdateRequest.ref:type_name -> workflow.plugin.external.iac.ResourceRef + 9, // 65: workflow.plugin.external.iac.ResourceUpdateRequest.spec:type_name -> workflow.plugin.external.iac.ResourceSpec + 15, // 66: workflow.plugin.external.iac.ResourceUpdateResponse.output:type_name -> workflow.plugin.external.iac.ResourceOutput + 10, // 67: workflow.plugin.external.iac.ResourceDeleteRequest.ref:type_name -> workflow.plugin.external.iac.ResourceRef + 9, // 68: workflow.plugin.external.iac.ResourceDiffRequest.desired:type_name -> workflow.plugin.external.iac.ResourceSpec + 15, // 69: workflow.plugin.external.iac.ResourceDiffRequest.current:type_name -> workflow.plugin.external.iac.ResourceOutput + 18, // 70: workflow.plugin.external.iac.ResourceDiffResponse.result:type_name -> workflow.plugin.external.iac.DiffResult + 10, // 71: workflow.plugin.external.iac.ResourceScaleRequest.ref:type_name -> workflow.plugin.external.iac.ResourceRef + 15, // 72: workflow.plugin.external.iac.ResourceScaleResponse.output:type_name -> workflow.plugin.external.iac.ResourceOutput + 10, // 73: workflow.plugin.external.iac.ResourceHealthCheckRequest.ref:type_name -> workflow.plugin.external.iac.ResourceRef + 31, // 74: workflow.plugin.external.iac.ResourceHealthCheckResponse.result:type_name -> workflow.plugin.external.iac.HealthResult + 10, // 75: workflow.plugin.external.iac.TroubleshootRequest.ref:type_name -> workflow.plugin.external.iac.ResourceRef + 32, // 76: workflow.plugin.external.iac.TroubleshootResponse.diagnostics:type_name -> workflow.plugin.external.iac.Diagnostic + 99, // 77: workflow.plugin.external.iac.GetStateResponse.state:type_name -> workflow.plugin.external.iac.IaCState + 99, // 78: workflow.plugin.external.iac.SaveStateRequest.state:type_name -> workflow.plugin.external.iac.IaCState + 122, // 79: workflow.plugin.external.iac.ListStatesRequest.filter:type_name -> workflow.plugin.external.iac.ListStatesRequest.FilterEntry + 99, // 80: workflow.plugin.external.iac.ListStatesResponse.states:type_name -> workflow.plugin.external.iac.IaCState + 9, // 81: workflow.plugin.external.iac.DetectDriftWithSpecsRequest.SpecsEntry.value:type_name -> workflow.plugin.external.iac.ResourceSpec + 9, // 82: workflow.plugin.external.iac.DetectDriftConfigRequest.SpecsEntry.value:type_name -> workflow.plugin.external.iac.ResourceSpec + 41, // 83: workflow.plugin.external.iac.IaCProviderRequired.Initialize:input_type -> workflow.plugin.external.iac.InitializeRequest + 43, // 84: workflow.plugin.external.iac.IaCProviderRequired.Name:input_type -> workflow.plugin.external.iac.NameRequest + 45, // 85: workflow.plugin.external.iac.IaCProviderRequired.Version:input_type -> workflow.plugin.external.iac.VersionRequest + 47, // 86: workflow.plugin.external.iac.IaCProviderRequired.Capabilities:input_type -> workflow.plugin.external.iac.CapabilitiesRequest + 49, // 87: workflow.plugin.external.iac.IaCProviderRequired.Plan:input_type -> workflow.plugin.external.iac.PlanRequest + 51, // 88: workflow.plugin.external.iac.IaCProviderRequired.Destroy:input_type -> workflow.plugin.external.iac.DestroyRequest + 53, // 89: workflow.plugin.external.iac.IaCProviderRequired.Status:input_type -> workflow.plugin.external.iac.StatusRequest + 55, // 90: workflow.plugin.external.iac.IaCProviderRequired.Import:input_type -> workflow.plugin.external.iac.ImportRequest + 57, // 91: workflow.plugin.external.iac.IaCProviderRequired.ResolveSizing:input_type -> workflow.plugin.external.iac.ResolveSizingRequest + 59, // 92: workflow.plugin.external.iac.IaCProviderRequired.BootstrapStateBackend:input_type -> workflow.plugin.external.iac.BootstrapStateBackendRequest + 61, // 93: workflow.plugin.external.iac.IaCProviderEnumerator.EnumerateAll:input_type -> workflow.plugin.external.iac.EnumerateAllRequest + 63, // 94: workflow.plugin.external.iac.IaCProviderEnumerator.EnumerateByTag:input_type -> workflow.plugin.external.iac.EnumerateByTagRequest + 65, // 95: workflow.plugin.external.iac.IaCProviderDriftDetector.DetectDrift:input_type -> workflow.plugin.external.iac.DetectDriftRequest + 67, // 96: workflow.plugin.external.iac.IaCProviderDriftDetector.DetectDriftWithSpecs:input_type -> workflow.plugin.external.iac.DetectDriftWithSpecsRequest + 69, // 97: workflow.plugin.external.iac.IaCProviderCredentialRevoker.RevokeProviderCredential:input_type -> workflow.plugin.external.iac.RevokeProviderCredentialRequest + 71, // 98: workflow.plugin.external.iac.IaCProviderFinalizer.FinalizeApply:input_type -> workflow.plugin.external.iac.FinalizeApplyRequest + 73, // 99: workflow.plugin.external.iac.IaCProviderMigrationRepairer.RepairDirtyMigration:input_type -> workflow.plugin.external.iac.RepairDirtyMigrationRequest + 75, // 100: workflow.plugin.external.iac.IaCProviderValidator.ValidatePlan:input_type -> workflow.plugin.external.iac.ValidatePlanRequest + 77, // 101: workflow.plugin.external.iac.IaCProviderDriftConfigDetector.DetectDriftConfig:input_type -> workflow.plugin.external.iac.DetectDriftConfigRequest + 79, // 102: workflow.plugin.external.iac.IaCProviderLogCapture.CaptureLogs:input_type -> workflow.plugin.external.iac.CaptureLogsRequest + 20, // 103: workflow.plugin.external.iac.IaCRequirementDiscovery.DiscoverRequirements:input_type -> workflow.plugin.external.iac.DiscoverRequirementsRequest + 24, // 104: workflow.plugin.external.iac.IaCProviderRequirementMapper.MapRequirements:input_type -> workflow.plugin.external.iac.MapRequirementsRequest + 81, // 105: workflow.plugin.external.iac.ResourceDriver.Create:input_type -> workflow.plugin.external.iac.ResourceCreateRequest + 83, // 106: workflow.plugin.external.iac.ResourceDriver.Read:input_type -> workflow.plugin.external.iac.ResourceReadRequest + 85, // 107: workflow.plugin.external.iac.ResourceDriver.Update:input_type -> workflow.plugin.external.iac.ResourceUpdateRequest + 87, // 108: workflow.plugin.external.iac.ResourceDriver.Delete:input_type -> workflow.plugin.external.iac.ResourceDeleteRequest + 89, // 109: workflow.plugin.external.iac.ResourceDriver.Diff:input_type -> workflow.plugin.external.iac.ResourceDiffRequest + 91, // 110: workflow.plugin.external.iac.ResourceDriver.Scale:input_type -> workflow.plugin.external.iac.ResourceScaleRequest + 93, // 111: workflow.plugin.external.iac.ResourceDriver.HealthCheck:input_type -> workflow.plugin.external.iac.ResourceHealthCheckRequest + 95, // 112: workflow.plugin.external.iac.ResourceDriver.SensitiveKeys:input_type -> workflow.plugin.external.iac.SensitiveKeysRequest + 97, // 113: workflow.plugin.external.iac.ResourceDriver.Troubleshoot:input_type -> workflow.plugin.external.iac.TroubleshootRequest + 100, // 114: workflow.plugin.external.iac.IaCStateBackend.Configure:input_type -> workflow.plugin.external.iac.ConfigureRequest + 102, // 115: workflow.plugin.external.iac.IaCStateBackend.GetState:input_type -> workflow.plugin.external.iac.GetStateRequest + 104, // 116: workflow.plugin.external.iac.IaCStateBackend.SaveState:input_type -> workflow.plugin.external.iac.SaveStateRequest + 106, // 117: workflow.plugin.external.iac.IaCStateBackend.ListStates:input_type -> workflow.plugin.external.iac.ListStatesRequest + 108, // 118: workflow.plugin.external.iac.IaCStateBackend.DeleteState:input_type -> workflow.plugin.external.iac.DeleteStateRequest + 110, // 119: workflow.plugin.external.iac.IaCStateBackend.Lock:input_type -> workflow.plugin.external.iac.LockRequest + 112, // 120: workflow.plugin.external.iac.IaCStateBackend.Unlock:input_type -> workflow.plugin.external.iac.UnlockRequest + 114, // 121: workflow.plugin.external.iac.IaCStateBackend.ListBackendNames:input_type -> workflow.plugin.external.iac.ListBackendNamesRequest + 42, // 122: workflow.plugin.external.iac.IaCProviderRequired.Initialize:output_type -> workflow.plugin.external.iac.InitializeResponse + 44, // 123: workflow.plugin.external.iac.IaCProviderRequired.Name:output_type -> workflow.plugin.external.iac.NameResponse + 46, // 124: workflow.plugin.external.iac.IaCProviderRequired.Version:output_type -> workflow.plugin.external.iac.VersionResponse + 48, // 125: workflow.plugin.external.iac.IaCProviderRequired.Capabilities:output_type -> workflow.plugin.external.iac.CapabilitiesResponse + 50, // 126: workflow.plugin.external.iac.IaCProviderRequired.Plan:output_type -> workflow.plugin.external.iac.PlanResponse + 52, // 127: workflow.plugin.external.iac.IaCProviderRequired.Destroy:output_type -> workflow.plugin.external.iac.DestroyResponse + 54, // 128: workflow.plugin.external.iac.IaCProviderRequired.Status:output_type -> workflow.plugin.external.iac.StatusResponse + 56, // 129: workflow.plugin.external.iac.IaCProviderRequired.Import:output_type -> workflow.plugin.external.iac.ImportResponse + 58, // 130: workflow.plugin.external.iac.IaCProviderRequired.ResolveSizing:output_type -> workflow.plugin.external.iac.ResolveSizingResponse + 60, // 131: workflow.plugin.external.iac.IaCProviderRequired.BootstrapStateBackend:output_type -> workflow.plugin.external.iac.BootstrapStateBackendResponse + 62, // 132: workflow.plugin.external.iac.IaCProviderEnumerator.EnumerateAll:output_type -> workflow.plugin.external.iac.EnumerateAllResponse + 64, // 133: workflow.plugin.external.iac.IaCProviderEnumerator.EnumerateByTag:output_type -> workflow.plugin.external.iac.EnumerateByTagResponse + 66, // 134: workflow.plugin.external.iac.IaCProviderDriftDetector.DetectDrift:output_type -> workflow.plugin.external.iac.DetectDriftResponse + 68, // 135: workflow.plugin.external.iac.IaCProviderDriftDetector.DetectDriftWithSpecs:output_type -> workflow.plugin.external.iac.DetectDriftWithSpecsResponse + 70, // 136: workflow.plugin.external.iac.IaCProviderCredentialRevoker.RevokeProviderCredential:output_type -> workflow.plugin.external.iac.RevokeProviderCredentialResponse + 72, // 137: workflow.plugin.external.iac.IaCProviderFinalizer.FinalizeApply:output_type -> workflow.plugin.external.iac.FinalizeApplyResponse + 74, // 138: workflow.plugin.external.iac.IaCProviderMigrationRepairer.RepairDirtyMigration:output_type -> workflow.plugin.external.iac.RepairDirtyMigrationResponse + 76, // 139: workflow.plugin.external.iac.IaCProviderValidator.ValidatePlan:output_type -> workflow.plugin.external.iac.ValidatePlanResponse + 78, // 140: workflow.plugin.external.iac.IaCProviderDriftConfigDetector.DetectDriftConfig:output_type -> workflow.plugin.external.iac.DetectDriftConfigResponse + 80, // 141: workflow.plugin.external.iac.IaCProviderLogCapture.CaptureLogs:output_type -> workflow.plugin.external.iac.LogChunk + 23, // 142: workflow.plugin.external.iac.IaCRequirementDiscovery.DiscoverRequirements:output_type -> workflow.plugin.external.iac.DiscoverRequirementsResponse + 28, // 143: workflow.plugin.external.iac.IaCProviderRequirementMapper.MapRequirements:output_type -> workflow.plugin.external.iac.MapRequirementsResponse + 82, // 144: workflow.plugin.external.iac.ResourceDriver.Create:output_type -> workflow.plugin.external.iac.ResourceCreateResponse + 84, // 145: workflow.plugin.external.iac.ResourceDriver.Read:output_type -> workflow.plugin.external.iac.ResourceReadResponse + 86, // 146: workflow.plugin.external.iac.ResourceDriver.Update:output_type -> workflow.plugin.external.iac.ResourceUpdateResponse + 88, // 147: workflow.plugin.external.iac.ResourceDriver.Delete:output_type -> workflow.plugin.external.iac.ResourceDeleteResponse + 90, // 148: workflow.plugin.external.iac.ResourceDriver.Diff:output_type -> workflow.plugin.external.iac.ResourceDiffResponse + 92, // 149: workflow.plugin.external.iac.ResourceDriver.Scale:output_type -> workflow.plugin.external.iac.ResourceScaleResponse + 94, // 150: workflow.plugin.external.iac.ResourceDriver.HealthCheck:output_type -> workflow.plugin.external.iac.ResourceHealthCheckResponse + 96, // 151: workflow.plugin.external.iac.ResourceDriver.SensitiveKeys:output_type -> workflow.plugin.external.iac.SensitiveKeysResponse + 98, // 152: workflow.plugin.external.iac.ResourceDriver.Troubleshoot:output_type -> workflow.plugin.external.iac.TroubleshootResponse + 101, // 153: workflow.plugin.external.iac.IaCStateBackend.Configure:output_type -> workflow.plugin.external.iac.ConfigureResponse + 103, // 154: workflow.plugin.external.iac.IaCStateBackend.GetState:output_type -> workflow.plugin.external.iac.GetStateResponse + 105, // 155: workflow.plugin.external.iac.IaCStateBackend.SaveState:output_type -> workflow.plugin.external.iac.SaveStateResponse + 107, // 156: workflow.plugin.external.iac.IaCStateBackend.ListStates:output_type -> workflow.plugin.external.iac.ListStatesResponse + 109, // 157: workflow.plugin.external.iac.IaCStateBackend.DeleteState:output_type -> workflow.plugin.external.iac.DeleteStateResponse + 111, // 158: workflow.plugin.external.iac.IaCStateBackend.Lock:output_type -> workflow.plugin.external.iac.LockResponse + 113, // 159: workflow.plugin.external.iac.IaCStateBackend.Unlock:output_type -> workflow.plugin.external.iac.UnlockResponse + 115, // 160: workflow.plugin.external.iac.IaCStateBackend.ListBackendNames:output_type -> workflow.plugin.external.iac.ListBackendNamesResponse + 122, // [122:161] is the sub-list for method output_type + 83, // [83:122] is the sub-list for method input_type + 83, // [83:83] is the sub-list for extension type_name + 83, // [83:83] is the sub-list for extension extendee + 0, // [0:83] is the sub-list for field type_name } func init() { file_iac_proto_init() } @@ -6334,10 +7436,10 @@ func file_iac_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_iac_proto_rawDesc), len(file_iac_proto_rawDesc)), - NumEnums: 4, - NumMessages: 104, + NumEnums: 9, + NumMessages: 114, NumExtensions: 0, - NumServices: 11, + NumServices: 13, }, GoTypes: file_iac_proto_goTypes, DependencyIndexes: file_iac_proto_depIdxs, diff --git a/plugin/external/proto/iac.proto b/plugin/external/proto/iac.proto index cb23280b..c3d157da 100644 --- a/plugin/external/proto/iac.proto +++ b/plugin/external/proto/iac.proto @@ -4,7 +4,7 @@ // Plan: docs/plans/2026-05-10-strict-contracts-force-cutover.md (Task 3) // // Hard invariants (per cycle 4 §Acceptance criteria): -// - NO google.protobuf.Struct, NO google.protobuf.Any used in any message. +// - NO loose Struct/Any wrapper types used in any message. // - Free-form per-resource Config / Outputs payloads cross the wire as // bytes _json, JSON-encoded by the plugin/host. The plugin owns // the serialization shape; the proto layer carries opaque bytes. @@ -90,6 +90,24 @@ service IaCProviderLogCapture { rpc CaptureLogs(CaptureLogsRequest) returns (stream LogChunk); } +// IaCRequirementDiscovery is an optional service for config-aware plugins that +// need to emit provider-neutral infrastructure requirements from their own +// module configuration. Hosts pass a typed, redacted Workflow context plus the +// plugin-owned module config as JSON bytes. The full Workflow YAML and +// resolved secret values must not cross this boundary. +service IaCRequirementDiscovery { + rpc DiscoverRequirements(DiscoverRequirementsRequest) returns (DiscoverRequirementsResponse); +} + +// IaCProviderRequirementMapper is an optional provider-owned service that maps +// provider-neutral requirements to concrete infra.* module specs for a selected +// provider/runtime/environment. Absence of this registration is the negative +// signal: the provider can still plan/apply explicit modules, but wfctl cannot +// ask it to synthesize derived IaC. +service IaCProviderRequirementMapper { + rpc MapRequirements(MapRequirementsRequest) returns (MapRequirementsResponse); +} + // ───────────────────────────────────────────────────────────────────────────── // ResourceDriver — separate gRPC service for per-resource-type CRUD dispatch. // The driver instance is identified by (resource_type) carried on every RPC. @@ -235,6 +253,134 @@ enum DriftClass { DRIFT_CLASS_CONFIG = 3; } +// RequirementKind is the provider-neutral infrastructure category that wfctl +// and provider plugins exchange for derived IaC. Values are intentionally +// portable and provider-agnostic. +enum RequirementKind { + REQUIREMENT_KIND_UNSPECIFIED = 0; + REQUIREMENT_KIND_OBSERVABILITY = 1; + REQUIREMENT_KIND_WEB_API = 2; + REQUIREMENT_KIND_MESSAGE_BROKER = 3; + REQUIREMENT_KIND_DATABASE = 4; + REQUIREMENT_KIND_CACHE = 5; + REQUIREMENT_KIND_STORAGE = 6; +} + +// RequirementRuntime describes the target runtime shape the provider mapper +// should generate for. Provider plugins return diagnostics for unsupported +// runtime/mode combinations instead of emitting malformed modules. +enum RequirementRuntime { + REQUIREMENT_RUNTIME_UNSPECIFIED = 0; + REQUIREMENT_RUNTIME_KUBERNETES = 1; + REQUIREMENT_RUNTIME_ECS = 2; + REQUIREMENT_RUNTIME_CLOUD_RUN = 3; + REQUIREMENT_RUNTIME_AZURE_CONTAINER_APPS = 4; + REQUIREMENT_RUNTIME_DIGITALOCEAN_APP_PLATFORM = 5; +} + +enum TelemetrySignal { + TELEMETRY_SIGNAL_UNSPECIFIED = 0; + TELEMETRY_SIGNAL_TRACES = 1; + TELEMETRY_SIGNAL_METRICS = 2; + TELEMETRY_SIGNAL_LOGS = 3; +} + +enum ObservabilityBackend { + OBSERVABILITY_BACKEND_UNSPECIFIED = 0; + OBSERVABILITY_BACKEND_OTEL = 1; + OBSERVABILITY_BACKEND_DATADOG = 2; + OBSERVABILITY_BACKEND_PROMETHEUS = 3; + OBSERVABILITY_BACKEND_LOKI = 4; + OBSERVABILITY_BACKEND_GRAFANA = 5; +} + +enum DeploymentMode { + DEPLOYMENT_MODE_UNSPECIFIED = 0; + DEPLOYMENT_MODE_SIDECAR = 1; + DEPLOYMENT_MODE_DAEMONSET = 2; + DEPLOYMENT_MODE_SIBLING_SERVICE = 3; + DEPLOYMENT_MODE_MANAGED = 4; +} + +message IaCRequirement { + string key = 1; + RequirementKind kind = 2; + string source = 3; + string resource_type_hint = 4; + string environment = 5; + repeated RequirementRuntime runtimes = 6; + repeated TelemetrySignal telemetry_signals = 7; + repeated ObservabilityBackend observability_backends = 8; + repeated DeploymentMode deployment_modes = 9; + repeated string vendor_features = 10; + // parameters_json is JSON-encoded plugin-owned requirement detail for data + // that is not portable enough to promote to a Workflow-owned proto field. + // Prefer adding enum/message fields for portable concepts. + bytes parameters_json = 11; +} + +message DiscoverRequirementsRequest { + RequirementContext context = 1; + // module_config_json is JSON-encoded module config owned by the plugin that + // implements IaCRequirementDiscovery. Hosts must not send full Workflow YAML + // or resolved secret values here. + bytes module_config_json = 2; +} + +message RequirementContext { + string application = 1; + string environment = 2; + repeated ModuleRef modules = 3; + repeated string plugin_ids = 4; +} + +message ModuleRef { + string name = 1; + string type = 2; + repeated string satisfies = 3; +} + +message DiscoverRequirementsResponse { + repeated IaCRequirement requirements = 1; +} + +message MapRequirementsRequest { + string provider = 1; + RequirementRuntime runtime = 2; + string environment = 3; + repeated IaCRequirement requirements = 4; +} + +message DerivedModuleSpec { + string name = 1; + string type = 2; + repeated string satisfies = 3; + // config_json is JSON-encoded provider-owned module config. Provider + // mappers must emit secret placeholders/references, never plaintext secret + // values. + bytes config_json = 4; + repeated string depends_on = 5; +} + +message RequirementDiagnostic { + string key = 1; + string code = 2; + string message = 3; +} + +message RequirementNote { + string key = 1; + string message = 2; + bool interactive = 3; +} + +message MapRequirementsResponse { + repeated string accepted_keys = 1; + repeated RequirementDiagnostic rejected = 2; + repeated DerivedModuleSpec modules = 3; + repeated RequirementNote notes = 4; +} + // DriftResult mirrors interfaces.DriftResult. message DriftResult { string name = 1; diff --git a/plugin/external/proto/iac_grpc.pb.go b/plugin/external/proto/iac_grpc.pb.go index 612ce07e..f9d22569 100644 --- a/plugin/external/proto/iac_grpc.pb.go +++ b/plugin/external/proto/iac_grpc.pb.go @@ -1421,6 +1421,236 @@ var IaCProviderLogCapture_ServiceDesc = grpc.ServiceDesc{ Metadata: "iac.proto", } +const ( + IaCRequirementDiscovery_DiscoverRequirements_FullMethodName = "/workflow.plugin.external.iac.IaCRequirementDiscovery/DiscoverRequirements" +) + +// IaCRequirementDiscoveryClient is the client API for IaCRequirementDiscovery service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// IaCRequirementDiscovery is an optional service for config-aware plugins that +// need to emit provider-neutral infrastructure requirements from their own +// module configuration. Hosts pass a typed, redacted Workflow context plus the +// plugin-owned module config as JSON bytes. The full Workflow YAML and +// resolved secret values must not cross this boundary. +type IaCRequirementDiscoveryClient interface { + DiscoverRequirements(ctx context.Context, in *DiscoverRequirementsRequest, opts ...grpc.CallOption) (*DiscoverRequirementsResponse, error) +} + +type iaCRequirementDiscoveryClient struct { + cc grpc.ClientConnInterface +} + +func NewIaCRequirementDiscoveryClient(cc grpc.ClientConnInterface) IaCRequirementDiscoveryClient { + return &iaCRequirementDiscoveryClient{cc} +} + +func (c *iaCRequirementDiscoveryClient) DiscoverRequirements(ctx context.Context, in *DiscoverRequirementsRequest, opts ...grpc.CallOption) (*DiscoverRequirementsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(DiscoverRequirementsResponse) + err := c.cc.Invoke(ctx, IaCRequirementDiscovery_DiscoverRequirements_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// IaCRequirementDiscoveryServer is the server API for IaCRequirementDiscovery service. +// All implementations must embed UnimplementedIaCRequirementDiscoveryServer +// for forward compatibility. +// +// IaCRequirementDiscovery is an optional service for config-aware plugins that +// need to emit provider-neutral infrastructure requirements from their own +// module configuration. Hosts pass a typed, redacted Workflow context plus the +// plugin-owned module config as JSON bytes. The full Workflow YAML and +// resolved secret values must not cross this boundary. +type IaCRequirementDiscoveryServer interface { + DiscoverRequirements(context.Context, *DiscoverRequirementsRequest) (*DiscoverRequirementsResponse, error) + mustEmbedUnimplementedIaCRequirementDiscoveryServer() +} + +// UnimplementedIaCRequirementDiscoveryServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedIaCRequirementDiscoveryServer struct{} + +func (UnimplementedIaCRequirementDiscoveryServer) DiscoverRequirements(context.Context, *DiscoverRequirementsRequest) (*DiscoverRequirementsResponse, error) { + return nil, status.Error(codes.Unimplemented, "method DiscoverRequirements not implemented") +} +func (UnimplementedIaCRequirementDiscoveryServer) mustEmbedUnimplementedIaCRequirementDiscoveryServer() { +} +func (UnimplementedIaCRequirementDiscoveryServer) testEmbeddedByValue() {} + +// UnsafeIaCRequirementDiscoveryServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to IaCRequirementDiscoveryServer will +// result in compilation errors. +type UnsafeIaCRequirementDiscoveryServer interface { + mustEmbedUnimplementedIaCRequirementDiscoveryServer() +} + +func RegisterIaCRequirementDiscoveryServer(s grpc.ServiceRegistrar, srv IaCRequirementDiscoveryServer) { + // If the following call panics, it indicates UnimplementedIaCRequirementDiscoveryServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&IaCRequirementDiscovery_ServiceDesc, srv) +} + +func _IaCRequirementDiscovery_DiscoverRequirements_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DiscoverRequirementsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IaCRequirementDiscoveryServer).DiscoverRequirements(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: IaCRequirementDiscovery_DiscoverRequirements_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IaCRequirementDiscoveryServer).DiscoverRequirements(ctx, req.(*DiscoverRequirementsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// IaCRequirementDiscovery_ServiceDesc is the grpc.ServiceDesc for IaCRequirementDiscovery service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var IaCRequirementDiscovery_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "workflow.plugin.external.iac.IaCRequirementDiscovery", + HandlerType: (*IaCRequirementDiscoveryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "DiscoverRequirements", + Handler: _IaCRequirementDiscovery_DiscoverRequirements_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "iac.proto", +} + +const ( + IaCProviderRequirementMapper_MapRequirements_FullMethodName = "/workflow.plugin.external.iac.IaCProviderRequirementMapper/MapRequirements" +) + +// IaCProviderRequirementMapperClient is the client API for IaCProviderRequirementMapper service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// IaCProviderRequirementMapper is an optional provider-owned service that maps +// provider-neutral requirements to concrete infra.* module specs for a selected +// provider/runtime/environment. Absence of this registration is the negative +// signal: the provider can still plan/apply explicit modules, but wfctl cannot +// ask it to synthesize derived IaC. +type IaCProviderRequirementMapperClient interface { + MapRequirements(ctx context.Context, in *MapRequirementsRequest, opts ...grpc.CallOption) (*MapRequirementsResponse, error) +} + +type iaCProviderRequirementMapperClient struct { + cc grpc.ClientConnInterface +} + +func NewIaCProviderRequirementMapperClient(cc grpc.ClientConnInterface) IaCProviderRequirementMapperClient { + return &iaCProviderRequirementMapperClient{cc} +} + +func (c *iaCProviderRequirementMapperClient) MapRequirements(ctx context.Context, in *MapRequirementsRequest, opts ...grpc.CallOption) (*MapRequirementsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(MapRequirementsResponse) + err := c.cc.Invoke(ctx, IaCProviderRequirementMapper_MapRequirements_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// IaCProviderRequirementMapperServer is the server API for IaCProviderRequirementMapper service. +// All implementations must embed UnimplementedIaCProviderRequirementMapperServer +// for forward compatibility. +// +// IaCProviderRequirementMapper is an optional provider-owned service that maps +// provider-neutral requirements to concrete infra.* module specs for a selected +// provider/runtime/environment. Absence of this registration is the negative +// signal: the provider can still plan/apply explicit modules, but wfctl cannot +// ask it to synthesize derived IaC. +type IaCProviderRequirementMapperServer interface { + MapRequirements(context.Context, *MapRequirementsRequest) (*MapRequirementsResponse, error) + mustEmbedUnimplementedIaCProviderRequirementMapperServer() +} + +// UnimplementedIaCProviderRequirementMapperServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedIaCProviderRequirementMapperServer struct{} + +func (UnimplementedIaCProviderRequirementMapperServer) MapRequirements(context.Context, *MapRequirementsRequest) (*MapRequirementsResponse, error) { + return nil, status.Error(codes.Unimplemented, "method MapRequirements not implemented") +} +func (UnimplementedIaCProviderRequirementMapperServer) mustEmbedUnimplementedIaCProviderRequirementMapperServer() { +} +func (UnimplementedIaCProviderRequirementMapperServer) testEmbeddedByValue() {} + +// UnsafeIaCProviderRequirementMapperServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to IaCProviderRequirementMapperServer will +// result in compilation errors. +type UnsafeIaCProviderRequirementMapperServer interface { + mustEmbedUnimplementedIaCProviderRequirementMapperServer() +} + +func RegisterIaCProviderRequirementMapperServer(s grpc.ServiceRegistrar, srv IaCProviderRequirementMapperServer) { + // If the following call panics, it indicates UnimplementedIaCProviderRequirementMapperServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&IaCProviderRequirementMapper_ServiceDesc, srv) +} + +func _IaCProviderRequirementMapper_MapRequirements_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MapRequirementsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(IaCProviderRequirementMapperServer).MapRequirements(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: IaCProviderRequirementMapper_MapRequirements_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(IaCProviderRequirementMapperServer).MapRequirements(ctx, req.(*MapRequirementsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// IaCProviderRequirementMapper_ServiceDesc is the grpc.ServiceDesc for IaCProviderRequirementMapper service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var IaCProviderRequirementMapper_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "workflow.plugin.external.iac.IaCProviderRequirementMapper", + HandlerType: (*IaCProviderRequirementMapperServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "MapRequirements", + Handler: _IaCProviderRequirementMapper_MapRequirements_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "iac.proto", +} + const ( ResourceDriver_Create_FullMethodName = "/workflow.plugin.external.iac.ResourceDriver/Create" ResourceDriver_Read_FullMethodName = "/workflow.plugin.external.iac.ResourceDriver/Read" diff --git a/plugin/external/sdk/contracts_iac_test.go b/plugin/external/sdk/contracts_iac_test.go index b67aebaf..380f6810 100644 --- a/plugin/external/sdk/contracts_iac_test.go +++ b/plugin/external/sdk/contracts_iac_test.go @@ -1,6 +1,8 @@ package sdk_test import ( + "os" + "strings" "testing" "google.golang.org/grpc" @@ -40,6 +42,44 @@ func TestBuildContractRegistry_AdvertisesRegisteredIaCServices(t *testing.T) { } } +func TestBuildContractRegistry_AdvertisesRequirementServices(t *testing.T) { + grpcSrv := grpc.NewServer() + provider := &iacRequirementContractProviderStub{} + if err := sdk.RegisterAllIaCProviderServices(grpcSrv, provider); err != nil { + t.Fatalf("register: %v", err) + } + + registry := sdk.BuildContractRegistry(grpcSrv) + services := serviceNamesFromRegistry(registry) + want := []string{ + pb.IaCRequirementDiscovery_ServiceDesc.ServiceName, + pb.IaCProviderRequirementMapper_ServiceDesc.ServiceName, + } + for _, name := range want { + if !services[name] { + t.Errorf("ContractRegistry missing service %q; have: %v", name, services) + } + } +} + +func TestIaCProtoRejectsLooseTypes(t *testing.T) { + body, err := os.ReadFile("../proto/iac.proto") + if err != nil { + t.Fatalf("read iac.proto: %v", err) + } + proto := string(body) + for _, forbidden := range []string{ + `import "google/protobuf/struct.proto"`, + `import "google/protobuf/any.proto"`, + "google.protobuf.Struct", + "google.protobuf.Any", + } { + if strings.Contains(proto, forbidden) { + t.Fatalf("iac.proto must stay strict-proto compatible; found %q", forbidden) + } + } +} + // TestBuildContractRegistry_ServiceContractsUseStrictProtoMode asserts // that auto-emitted IaC service descriptors carry Mode=STRICT_PROTO so // the host can distinguish them from the legacy structpb-mode contracts @@ -93,3 +133,9 @@ type iacContractProviderStub struct { pb.UnimplementedIaCProviderEnumeratorServer pb.UnimplementedIaCProviderDriftDetectorServer } + +type iacRequirementContractProviderStub struct { + pb.UnimplementedIaCProviderRequiredServer + pb.UnimplementedIaCRequirementDiscoveryServer + pb.UnimplementedIaCProviderRequirementMapperServer +} diff --git a/plugin/external/sdk/iacserver.go b/plugin/external/sdk/iacserver.go index 0eed44f8..1e079b69 100644 --- a/plugin/external/sdk/iacserver.go +++ b/plugin/external/sdk/iacserver.go @@ -38,6 +38,8 @@ import ( // pb.IaCProviderValidatorServer // pb.IaCProviderDriftConfigDetectorServer // pb.IaCProviderLogCaptureServer +// pb.IaCRequirementDiscoveryServer +// pb.IaCProviderRequirementMapperServer // pb.IaCStateBackendServer // // ResourceDriver: @@ -169,6 +171,12 @@ func registerIaCServicesOnly(s *grpc.Server, provider any) error { if v, ok := provider.(pb.IaCProviderLogCaptureServer); ok { pb.RegisterIaCProviderLogCaptureServer(s, v) } + if v, ok := provider.(pb.IaCRequirementDiscoveryServer); ok { + pb.RegisterIaCRequirementDiscoveryServer(s, v) + } + if v, ok := provider.(pb.IaCProviderRequirementMapperServer); ok { + pb.RegisterIaCProviderRequirementMapperServer(s, v) + } // IaCProviderFinalizer is the workflow#695 Phase 2.5 optional service // for plugins needing a post-apply-loop finalizer hook under v2 // dispatch. Per ADR 0024 the absence of this registration IS the diff --git a/plugin/external/sdk/iacserver_test.go b/plugin/external/sdk/iacserver_test.go index cd5203b1..ed13c676 100644 --- a/plugin/external/sdk/iacserver_test.go +++ b/plugin/external/sdk/iacserver_test.go @@ -156,6 +156,30 @@ func TestRegisterAll_RegistersIaCProviderFinalizer(t *testing.T) { } } +func TestRegisterAll_RegistersIaCRequirementDiscovery(t *testing.T) { + grpcSrv := grpc.NewServer() + provider := &requirementDiscoveryProviderStub{} + if err := sdk.RegisterAllIaCProviderServices(grpcSrv, provider); err != nil { + t.Fatalf("unexpected error: %v", err) + } + info := grpcSrv.GetServiceInfo() + if _, ok := info[pb.IaCRequirementDiscovery_ServiceDesc.ServiceName]; !ok { + t.Fatalf("IaCRequirementDiscovery service NOT registered despite provider satisfying interface; have: %v", serviceNames(info)) + } +} + +func TestRegisterAll_RegistersIaCProviderRequirementMapper(t *testing.T) { + grpcSrv := grpc.NewServer() + provider := &requirementMapperProviderStub{} + if err := sdk.RegisterAllIaCProviderServices(grpcSrv, provider); err != nil { + t.Fatalf("unexpected error: %v", err) + } + info := grpcSrv.GetServiceInfo() + if _, ok := info[pb.IaCProviderRequirementMapper_ServiceDesc.ServiceName]; !ok { + t.Fatalf("IaCProviderRequirementMapper service NOT registered despite provider satisfying interface; have: %v", serviceNames(info)) + } +} + // TestRegisterAll_SkipsIaCProviderFinalizerWhenNotImplemented locks the // negative signal contract: a provider that does NOT satisfy // pb.IaCProviderFinalizerServer MUST NOT have the service registered. @@ -202,6 +226,16 @@ type finalizerProviderStub struct { pb.UnimplementedIaCProviderFinalizerServer } +type requirementDiscoveryProviderStub struct { + pb.UnimplementedIaCProviderRequiredServer + pb.UnimplementedIaCRequirementDiscoveryServer +} + +type requirementMapperProviderStub struct { + pb.UnimplementedIaCProviderRequiredServer + pb.UnimplementedIaCProviderRequirementMapperServer +} + // allCapabilitiesStub satisfies every required + optional IaC service plus // ResourceDriver — used to assert auto-registration covers the full surface. type allCapabilitiesStub struct { @@ -213,6 +247,8 @@ type allCapabilitiesStub struct { pb.UnimplementedIaCProviderValidatorServer pb.UnimplementedIaCProviderDriftConfigDetectorServer pb.UnimplementedIaCProviderFinalizerServer + pb.UnimplementedIaCRequirementDiscoveryServer + pb.UnimplementedIaCProviderRequirementMapperServer pb.UnimplementedResourceDriverServer } diff --git a/wftest/bdd/strict_iac.go b/wftest/bdd/strict_iac.go index 03098076..62eb4fa1 100644 --- a/wftest/bdd/strict_iac.go +++ b/wftest/bdd/strict_iac.go @@ -81,6 +81,14 @@ var iacServiceChecks = []iacServiceCheck{ _, ok := p.(pb.IaCStateBackendServer) return ok }}, + {"workflow.plugin.external.iac.IaCRequirementDiscovery", func(p any) bool { + _, ok := p.(pb.IaCRequirementDiscoveryServer) + return ok + }}, + {"workflow.plugin.external.iac.IaCProviderRequirementMapper", func(p any) bool { + _, ok := p.(pb.IaCProviderRequirementMapperServer) + return ok + }}, } // AssertProviderCapabilitiesMatchRegistration asserts that every typed diff --git a/wftest/bdd/strict_iac_test.go b/wftest/bdd/strict_iac_test.go index ca87d352..d8eced94 100644 --- a/wftest/bdd/strict_iac_test.go +++ b/wftest/bdd/strict_iac_test.go @@ -62,6 +62,8 @@ func TestAssertProviderCapabilitiesMatchRegistration_ManuallyRegisteredMissingOp "IaCProviderValidator", "IaCProviderDriftConfigDetector", "ResourceDriver", + "IaCRequirementDiscovery", + "IaCProviderRequirementMapper", } joined := strings.Join(rec.errors, "\n") for _, name := range wantContains { @@ -149,6 +151,8 @@ type allCapabilitiesStub struct { pb.UnimplementedIaCProviderValidatorServer pb.UnimplementedIaCProviderDriftConfigDetectorServer pb.UnimplementedResourceDriverServer + pb.UnimplementedIaCRequirementDiscoveryServer + pb.UnimplementedIaCProviderRequirementMapperServer } // requiredOnlyStub satisfies Required ONLY.