Refactor recipe settings resources to match the feature spec and support Radius.Security/secrets#12303
Refactor recipe settings resources to match the feature spec and support Radius.Security/secrets#12303sylvainsf wants to merge 7 commits into
Conversation
…adius.Security/secrets This change addresses issue #12122, where Radius.Core/bicepConfigs and Radius.Core/terraformConfigs rejected Radius.Security/secrets for registry and module credentials, accepting only Applications.Core/secretStores. While fixing that, the work revealed two deeper problems, which this change also corrects. Support Radius.Security/secrets in the recipe secret loader The recipe secret loader was hardcoded to the Applications.Core/secretStores ListSecrets API and never dispatched on the referenced resource type. It now parses the secret resource ID and routes to the correct reader: - Applications.Core/secretStores keeps the existing ListSecrets path unchanged. - Radius.Security/secrets is read by locating the backing Kubernetes Secret the resource's recipe materializes (via status.outputResources) and reading its values directly. This is required because a provisioned Radius.Security/secrets has its sensitive data redacted from the database once provisioning succeeds, so the plaintext only exists in the backing Kubernetes Secret. The Kubernetes client provider is threaded into the loader at both wiring sites (dynamic-rp and the recipe controller config). The Applications.Core path is left behavior-identical. Rename Configs -> Settings to match the feature spec The resource types were introduced as Radius.Core/terraformConfigs and Radius.Core/bicepConfigs, but the authoritative feature spec authored by @zachcasper (terraform-bicep-settings) names them Radius.Core/terraformSettings and Radius.Core/bicepSettings. The naming divergence originated in this repo, not the spec, and the resource types are not yet referenced on the docs site, so this renames them to match the spec before they ship more widely: - TypeSpec models, segments, and the environment properties terraformSettings and bicepSettings. - Datamodel types, converters, conversions, the frontend validator package, setup routing, the built-in provider manifests, and the embedded OpenAPI metadata mapping. - Regenerated clients, fakes, swagger, and bicep-types. The legacy recipeConfig transport types (datamodel.BicepConfigProperties, datamodel.TerraformConfigProperties) and the Applications.Core/environments path are intentionally left unchanged; these are new-environment-only resources. Select Bicep registry auth from the settings resource, not the secret kind Per the feature spec, the secret kind property is optional and the Bicep authentication method comes from the bicepSettings resource. Previously the Bicep driver chose the registry auth client from the secret's kind, so a kind-less Radius.Security/secrets carrying only username and password failed with "invalid type". The bicepSettings authenticationMethod is now threaded through and used to select the auth client (BasicAuth, AzureWI, AwsIrsa), so a kind-less Radius.Security/secrets works for BasicAuth. The Applications.Core/secretStores path, which leaves the method empty, continues to use the secret store's own type. Tests - Unit tests for the type-dispatching loader and the Radius.Security/secrets backing-secret reader. - A functional test (Test_TerraformSettings_SecuritySecret_Credentials) that provisions a Radius.Security/secrets resource and references it from a terraformSettings resource for private registry credentials, exercising the new loader end-to-end. Fixes #12122 Signed-off-by: Sylvain Niles <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]> Signed-off-by: Sylvain Niles <[email protected]>
…path Rewrite the security-secrets unit test to exercise loadSecuritySecret end to end (kind extraction, backing-secret lookup, key filtering, and error paths) via a fake generic-resources transport plus a fake clientset, rather than only exercising the fake clientset and ParseResource directly. Addresses PR review feedback and raises security_secrets.go coverage. Signed-off-by: Sylvain Niles <[email protected]>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
There was a problem hiding this comment.
Pull request overview
This PR aligns the implementation of Terraform/Bicep recipe configuration resources with the feature spec by renaming Radius.Core/*Configs → Radius.Core/*Settings, and fixes #12122 by extending the recipe secret loader to support Radius.Security/secrets (via reading the backing Kubernetes Secret). It also updates the Bicep registry auth selection path to be driven by the settings resource’ authenticationMethod rather than the referenced secret’s kind.
Changes:
- Rename TypeSpec/models/clients/handlers/manifests from
terraformConfigs/bicepConfigstoterraformSettings/bicepSettings, and update environment properties accordingly. - Extend
configloader.SecretsLoaderto dispatch betweenApplications.Core/secretStoresandRadius.Security/secrets, reading the latter from the backing Kubernetes Secret. - Thread
bicepSettings.authenticationMethodthrough to registry auth client selection (instead of coupling to secret kind), and add/adjust unit + functional tests.
Contributor doc impact (advisory):
docs/architecture/terraform-bicep-config.mdanddocs/architecture/README.mdstill referenceterraformConfigs/bicepConfigsand likely need an update toterraformSettings/bicepSettings.
Reviewed changes
Copilot reviewed 46 out of 55 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| typespec/Radius.Core/terraformSettings.tsp | Renames Terraform config resource/model to terraformSettings and updates secret reference docs to include Radius.Security/secrets. |
| typespec/Radius.Core/main.tsp | Switches imports from *Configs to *Settings. |
| typespec/Radius.Core/environments.tsp | Renames environment properties to terraformSettings / bicepSettings. |
| typespec/Radius.Core/bicepSettings.tsp | Renames Bicep config resource/model to bicepSettings and updates secret reference docs to include Radius.Security/secrets. |
| test/functional-portable/dynamicrp/noncloud/resources/testdata/tfbicep-combined-test.bicep | Updates resource types and environment property names to *Settings. |
| test/functional-portable/dynamicrp/noncloud/resources/testdata/terraformsettings-securitysecret-test.bicep | Adds new functional test template for Radius.Security/secrets → terraformSettings credentials path. |
| test/functional-portable/dynamicrp/noncloud/resources/testdata/terraformsettings-redis-test.bicep | Updates template to use terraformSettings and new recipe definition fields. |
| test/functional-portable/dynamicrp/noncloud/resources/testdata/bicepsettings-test.bicep | Updates template to use bicepSettings and new environment property name. |
| test/functional-portable/dynamicrp/noncloud/resources/terraformsettings_bicepsettings_test.go | Renames/extends functional tests for *Settings, adds regression test for #12122. |
| pkg/ucp/initializer/service_test.go | Updates Radius.Core RP summary expectations for new resource names. |
| pkg/ucp/initializer/radius_core_openapi.go | Updates embedded OpenAPI type mapping keys/definitions to *Settings. |
| pkg/rp/util/registry.go | Overrides SecretData.Type based on bicepSettings.authenticationMethod to select the correct registry auth client. |
| pkg/rp/util/config.go | Renames helper fetchers to FetchTerraformSettings / FetchBicepSettings and updates generated clients used. |
| pkg/recipes/controllerconfig/config.go | Threads Kubernetes provider into the secrets loader wiring. |
| pkg/recipes/configloader/security_secrets.go | Implements Radius.Security/secrets backing-Kubernetes-Secret reader. |
| pkg/recipes/configloader/security_secrets_test.go | Adds unit tests for backing secret resolution + Radius.Security/secrets secret loading. |
| pkg/recipes/configloader/secrets.go | Adds type-dispatching secret loader supporting both secretStores and security secrets + new ctor signature. |
| pkg/recipes/configloader/environment.go | Updates v20250801 environment config resolution for terraformSettings/bicepSettings and threads auth method. |
| pkg/recipes/configloader/environment_v20250801_bridge_test.go | Updates bridge tests for new resource names/clients and auth method threading. |
| pkg/dynamicrp/options.go | Updates dynamic-rp wiring to pass Kubernetes provider into secrets loader. |
| pkg/corerp/setup/setup.go | Registers terraformSettings / bicepSettings resources and updates controller wiring. |
| pkg/corerp/setup/setup_test.go | Updates handler/operation expectations for new routes/types. |
| pkg/corerp/setup/operations.go | Renames operations to *Settings/* and updates display metadata. |
| pkg/corerp/frontend/controller/environments/v20250801preview/validateconfigref_test.go | Updates validateConfigRef tests for new config ref properties/types. |
| pkg/corerp/frontend/controller/environments/v20250801preview/createorupdateenvironment.go | Updates config ref validation for terraformSettings / bicepSettings. |
| pkg/corerp/frontend/controller/environments/v20250801preview/createorupdateenvironment_test.go | Updates recipe pack validation test data to use new resource type in wrong-type test. |
| pkg/corerp/frontend/controller/bicepsettings/validator.go | Renames validator package and updates types to BicepSettings; enforces conditional required fields. |
| pkg/corerp/frontend/controller/bicepsettings/validator_test.go | Updates validator tests to BicepSettings. |
| pkg/corerp/datamodel/terraformsettings.go | Renames Terraform config datamodel to TerraformSettings and updates secret reference docs. |
| pkg/corerp/datamodel/recipe_types.go | Extends registry secret config to include AuthenticationMethod. |
| pkg/corerp/datamodel/environment_v20250801preview.go | Renames environment datamodel properties to terraformSettings/bicepSettings. |
| pkg/corerp/datamodel/converter/terraformsettings_converter.go | Renames converters to TerraformSettings* and updates versioned models. |
| pkg/corerp/datamodel/converter/bicepsettings_converter.go | Renames converters to BicepSettings* and updates versioned models. |
| pkg/corerp/datamodel/bicepsettings.go | Renames Bicep config datamodel to BicepSettings and updates secret reference docs. |
| pkg/corerp/api/v20250801preview/zz_generated_terraformsettings_client.go | Regenerates Terraform settings client/routes/types for terraformSettings. |
| pkg/corerp/api/v20250801preview/zz_generated_responses.go | Regenerates response types for *Settings clients/resources. |
| pkg/corerp/api/v20250801preview/zz_generated_options.go | Regenerates options types for *Settings clients. |
| pkg/corerp/api/v20250801preview/zz_generated_models.go | Regenerates models for *Settings resources and environment property names. |
| pkg/corerp/api/v20250801preview/zz_generated_client_factory.go | Regenerates client factory methods for *Settings. |
| pkg/corerp/api/v20250801preview/zz_generated_bicepsettings_client.go | Adds new generated Bicep settings client for bicepSettings. |
| pkg/corerp/api/v20250801preview/zz_generated_bicepconfigs_client.go | Removes old generated Bicep configs client. |
| pkg/corerp/api/v20250801preview/terraformsettings_conversion.go | Updates versioned ↔ datamodel conversions for Terraform settings. |
| pkg/corerp/api/v20250801preview/terraformsettings_conversion_test.go | Updates conversion tests for Terraform settings rename. |
| pkg/corerp/api/v20250801preview/fake/zz_generated_terraformsettings_server.go | Updates fake server/transport to TerraformSettings*. |
| pkg/corerp/api/v20250801preview/fake/zz_generated_server_factory.go | Updates fake server factory wiring for *Settings clients. |
| pkg/corerp/api/v20250801preview/fake/zz_generated_bicepsettings_server.go | Updates fake server/transport to BicepSettings*. |
| pkg/corerp/api/v20250801preview/environment_conversion.go | Updates environment conversion for renamed config ref properties. |
| pkg/corerp/api/v20250801preview/bicepsettings_conversion.go | Updates versioned ↔ datamodel conversions for Bicep settings. |
| pkg/corerp/api/v20250801preview/bicepsettings_conversion_test.go | Updates conversion tests for Bicep settings rename. |
| hack/bicep-types-radius/generated/radius/radius.core/2025-08-01-preview/types.json | Updates generated Bicep types to *Settings and updated docs. |
| hack/bicep-types-radius/generated/index.json | Updates Bicep types index keys to *Settings. |
| deploy/manifest/built-in-providers/self-hosted/radius_core.yaml | Updates built-in provider type names to terraformSettings/bicepSettings. |
| deploy/manifest/built-in-providers/dev/radius_core.yaml | Updates built-in provider type names to terraformSettings/bicepSettings. |
Files not reviewed (7)
- pkg/corerp/api/v20250801preview/fake/zz_generated_server_factory.go: Generated file
- pkg/corerp/api/v20250801preview/zz_generated_bicepsettings_client.go: Generated file
- pkg/corerp/api/v20250801preview/zz_generated_client_factory.go: Generated file
- pkg/corerp/api/v20250801preview/zz_generated_models.go: Generated file
- pkg/corerp/api/v20250801preview/zz_generated_models_serde.go: Generated file
- pkg/corerp/api/v20250801preview/zz_generated_options.go: Generated file
- pkg/corerp/api/v20250801preview/zz_generated_responses.go: Generated file
Comments suppressed due to low confidence (6)
test/functional-portable/dynamicrp/noncloud/resources/testdata/bicepsettings-test.bicep:26
- The secret store and namespace names in this template still use the old
bicepconfig-*naming (secret name +properties.resourcepath), but the updated functional test expectsbicepsettings-*. As-is, the test will fail because it looks forbicepsettings-test-secretin namespacebicepsettings-test-nswhile the template createsbicepconfig-test-secretinbicepconfig-test-ns.
test/functional-portable/dynamicrp/noncloud/resources/testdata/bicepsettings-test.bicep:45 - The environment block still uses the old
bicepconfig-*naming for the environment name and Kubernetes namespace. The test pre-createsbicepsettings-test-nsand validates an environment namedbicepsettings-test-env, so this mismatch will break the functional test.
test/functional-portable/dynamicrp/noncloud/resources/terraformsettings_bicepsettings_test.go:34 - Typo in comment:
terraformSettingssshould beterraformSettings.
test/functional-portable/dynamicrp/noncloud/resources/terraformsettings_bicepsettings_test.go:95 - Typo in comment:
bicepSettingssshould bebicepSettings.
test/functional-portable/dynamicrp/noncloud/resources/terraformsettings_bicepsettings_test.go:153 - Typos in this comment block:
terraformSettingssshould beterraformSettings.
test/functional-portable/dynamicrp/noncloud/resources/terraformsettings_bicepsettings_test.go:234 - Typos in this comment block:
terraformSettingss/bicepSettingssshould beterraformSettings/bicepSettings.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #12303 +/- ##
==========================================
+ Coverage 52.97% 53.02% +0.04%
==========================================
Files 754 755 +1
Lines 48686 48782 +96
==========================================
+ Hits 25791 25866 +75
- Misses 20469 20480 +11
- Partials 2426 2436 +10 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Unit Tests 2 files ± 0 452 suites ±0 7m 37s ⏱️ +8s Results for commit 3af57ac. ± Comparison against base commit bf1015c. This pull request removes 33 and adds 52 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
Functional Tests - dynamicrp-noncloud67 tests +3 67 ✅ +3 19m 1s ⏱️ +54s Results for commit 3af57ac. ± Comparison against base commit bf1015c. This pull request removes 9 and adds 12 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
… rename docs to *Settings - security_secrets.go: skip Kubernetes Secret output resources with an empty namespace so findKubernetesSecretOutputResource keeps searching instead of issuing a GET against an empty namespace; add unit coverage. - terraformsettings-securitysecret-test.bicep: use the current recipePacks fields (kind/source) instead of the legacy recipeKind/recipeLocation. - bicepsettings-test.bicep: rename the secret store, namespace, and environment from bicepconfig-* to bicepsettings-* to match the functional test. - terraformsettings_bicepsettings_test.go: fix terraformSettingss/bicepSettingss comment typos. - docs/architecture: rename terraform-bicep-config.md to terraform-bicep-settings.md and update all resource-type/model references and examples from *Configs to *Settings (the shipped names), keeping the legacy shared TerraformConfigProperties transport type and Applications.Core references intact; update the README and extensibility links. Signed-off-by: Sylvain Niles <[email protected]>
…OpenAPI spec The ARM-RPC namespace builder derives a resource's route parameter by trimming a trailing "s" from the type name (e.g. environments -> environmentName). For terraformSettings/bicepSettings that yields terraformSettingName/bicepSettingName, but the TypeSpec-generated OpenAPI spec keeps the plural stem (terraformSettingsName/bicepSettingsName). API validation matches the chi route pattern against the spec path via case-insensitive string equality, so the mismatched parameter name made every PUT/PATCH/GET on these resources fail with "HttpRequestPayloadAPISpecValidationFailed: failed to parse route: undefined route path". Set ResourceParamName explicitly for both resources so the registered route matches the spec path. This unblocks the dynamicrp-noncloud functional tests (Test_TerraformSettings_Redis, Test_BicepSettings_CRUD, Test_TerraformSettings_BicepSettings_Combined, and the security-secret path). Signed-off-by: Sylvain Niles <[email protected]>
…g it Radius.Core environments require their Kubernetes namespace to already exist. RPTest.CreateInitialResources only auto-creates the namespace named after the test (ct.Name), so NewPreviewEnvPreSetup worked only for callers that happened to reuse that same name as the preview namespace. Test_TerraformSettings_ SecuritySecret_Credentials uses a distinct preview namespace (tfsec-secrets-ns) that nothing created, so preview env creation failed with "Namespace 'tfsec-secrets-ns' does not exist in the Kubernetes cluster". Ensure the preview environment's namespace exists (via the deployment-target Kubernetes client, matching CreateInitialResources) before the env create CLI call. EnsureNamespace is idempotent, so existing callers whose namespace is already created are unaffected. Signed-off-by: Sylvain Niles <[email protected]>
The recipe secret loader read Radius.Security/secrets through the shared GenericResourcesClient, which is generated against api-version 2023-10-01-preview. Radius.Security/secrets only supports 2025-08-01-preview, so the GET was rejected with: BadRequest: api version "2023-10-01-preview" is not supported for resource type "Radius.Security/secrets" by location "global" which surfaced to recipe deployment as LoadSecretsFailed and failed Test_TerraformSettings_SecuritySecret_Credentials. Override the client's API version per request via a shallow copy of the ARM client options (ClientOptions.APIVersion). The arm pipeline applies this as the api-version query parameter, replacing the generated default, without mutating the shared options. Signed-off-by: Sylvain Niles <[email protected]>
Radius functional test overviewClick here to see the test run details
Test Status⌛ Building Radius and pushing container images for functional tests... |
Description
Fixes #12122.
Radius.Core/bicepConfigsandRadius.Core/terraformConfigsrejectedRadius.Security/secretsfor registry/module credentials, accepting onlyApplications.Core/secretStores. Fixing that surfaced two deeper problems — a naming divergence from the feature spec and a secret-kind coupling in the Bicep auth path — which this PR also corrects.1. Support
Radius.Security/secretsin the recipe secret loader (the bug)The recipe secret loader was hardcoded to the
Applications.Core/secretStoresListSecretsAPI and never dispatched on the referenced resource type. It now parses the secret resource ID and routes accordingly:Applications.Core/secretStoreskeeps the existingListSecretspath, behavior-identical.Radius.Security/secretsis read by locating the backing Kubernetes Secret its recipe materializes (viastatus.outputResources) and reading the values directly. This is required because a provisionedRadius.Security/secretshas its sensitivedataredacted from the database once provisioning succeeds, so the plaintext only lives in the backing Kubernetes Secret.The Kubernetes client provider is threaded into the loader at both wiring sites (dynamic-rp and the recipe controller config).
2. Refactor: rename
Configs→Settingsto match the specThese resource types were introduced (in #11780) as
Radius.Core/terraformConfigs/bicepConfigsbased on the earlier branch work by Yetkin/Vishwa, but the authoritative feature spec authored by @zachcasper (terraform-bicep-settings) names themRadius.Core/terraformSettings/bicepSettings. The naming divergence originated here, not in the spec, and the types are not yet referenced on the docs site — so this renames them to match the spec before they ship more widely:terraformSettings/bicepSettingsproperties.The legacy
recipeConfigtransport types (datamodel.BicepConfigProperties,datamodel.TerraformConfigProperties) and theApplications.Core/environmentspath are intentionally untouched — these are new-environment-only resources.3. Refactor: select Bicep registry auth from the settings resource, not the secret kind
Per the spec, the secret
kindis optional and the Bicep auth method comes from thebicepSettingsresource. Previously the Bicep driver chose the registry auth client from the secret's kind, so a kind-lessRadius.Security/secretscarrying onlyusername/passwordfailed with"invalid type". ThebicepSettings.authenticationMethodis now threaded through and used to select the auth client (BasicAuth, AzureWI, AwsIrsa). TheApplications.Core/secretStorespath leaves the method empty and continues to use the secret store's own type.Type of change
Contributor checklist
dynamicrp-noncloudCI).make generate).radius-project/design-notes; this PR aligns the implementation to it).Tests
Radius.Security/secretsbacking-secret reader.Test_TerraformSettings_SecuritySecret_Credentials— a functional test that provisions aRadius.Security/secretsresource and references it from aterraformSettingsresource for private registry credentials, exercising the new loader end-to-end.Fixes #12122