feat: add multi-file merge support to generate command - #36
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a generate-types subcommand to manifest-to-bicep for producing only types.json, including support for merging multiple manifests that share a namespace.
Changes:
- Registers the new
generate-typesCobra subcommand. - Adds
RunGenerateTypes, manifest merge logic, andtypes.json-only output handling.
c61cf5b to
8458df0
Compare
|
Re: Copilot's comment on the Good catch. Removed the forward reference to the Fixed in the latest force-push. |
8458df0 to
81f917b
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
bicep-tools/cmd/manifest-to-bicep/main.go:121
- This multi-file path still uses the full extension generator, which produces
types.json,index.json, andindex.md. The requestedgenerate-typesbehavior needs a types-only path; otherwise callers that are aggregating namespace-specifictypes.jsonfiles will also overwrite or create index artifacts that should be rebuilt separately.
result, err = generator.GenerateFromString(merged)
81f917b to
b776515
Compare
b927fe6 to
a2cddf0
Compare
Update the existing 'generate' subcommand of manifest-to-bicep to accept multiple manifest files. When given multiple YAML manifests with the same namespace, their Types maps are merged into a single output (types.json, index.json, index.md). This supports per-type manifest files (e.g. containers.yaml, routes.yaml) as introduced by the automated resource type registration design, where each file defines a single resource type within a namespace. Backward compatible: single-file usage works exactly as before. Part of: unified Bicep extension publishing (PR 1/4)
a2cddf0 to
6f82b5d
Compare
…oject#12344) # Description Implements secure handling of **recipe secret _outputs_** (Scenario 3 of the recipe-secrets design). A recipe-generated secret (a connection string, storage/access key, API key, etc.) is materialized into a managed `Radius.Security/secrets` resource and is **never persisted as plaintext** on the owning resource, in the application graph, or in logs. The owner exposes only a read-only `secrets.name` reference; consumers bind by name via a container env `valueFrom.secretKeyRef`. **What's included** - **Schema `secrets:` block** (`pkg/schema/secrets.go`): resource types declare a top-level read-only `secrets` object with a reserved `name` reference; `GetSecretsBlock` / `ValidateSecretsBlock` helpers. `secrets` is treated as a framework-owned basic property. - **Managed-secret materializer** (`pkg/dynamicrp/backend/secret`): creates / updates / deletes a `Radius.Security/secrets` per owner via the generic resources client. The managed secret name is derived deterministically as `<owner-name>-<short-hash>-secrets`, where a short hash of the owner's fully-qualified resource ID disambiguates owners that share a name but differ in resource type or scope. - **Processor leak-fix** (`pkg/dynamicrp/backend/processor/dynamicresource.go`): once a type declares a `secrets` block, materializes **all** of the recipe's secret outputs into the managed secret (the declared keys are advisory and do not filter), sets the read-only `properties.secrets.name` reference, and **stops writing secret plaintext** into resource properties/status; cascade-deletes the managed secret on delete. - **Nested `outputs.secrets` recipe-pack mapping** for direct (AVM) modules — an entry under the reserved `secrets` key inside a recipe's `outputs` (e.g. `outputs: { host: 'name', secrets: { connectionString: 'primaryConnectionString' } }`) forces the named module output into the secret set regardless of how the module classified it. The API models `outputs` as an untyped map; the versioned↔datamodel converter splits the nested `secrets` object back out (typespec + swagger + generated models + datamodel + converter + `recipes` configloader). - **No-leak verification**: integration test asserts a recipe secret output never appears in the `rad resource show` GET/LIST body; functional test (`sensitive_fields_test.go`) asserts secret values never appear in the `rad resource show` response. - **Docs**: secret-output section in `docs/architecture/extensibility.md`. Secret _inputs_ (Scenario 1) are unchanged — already handled by `x-radius-sensitive`. ## End-to-end validation Proven end-to-end against **real Azure** across 7 resource types in `resource-types-verification`. Each run confirms the recipe secret output is materialized into a managed `Radius.Security/secrets` (`state=Succeeded`), the owner exposes only the read-only `properties.secrets.name` reference, **no plaintext appears on the owner**, and a container consumes the secret via `secretKeyRef`: | Type | PR | Base provisioning | Consumer round-trip | |---|---|---|---| | kafka | #32 | ✅ | kcat whole-value + quarkus `$(VAR)` JAAS (explicit in-pod substitution assert) → Event Hubs | | redis | #37 | ✅ | live POST/GET → Azure Managed Redis | | mongodb | #36 | ✅ | mongo-express → Cosmos DB | | rabbitmq | #38 | ✅ | bento AMQP send/receive → Service Bus | | storage | #35 | ✅ | sftpgo → Blob (multi-key secret; selects `accountKey`) | | search | #34 | ✅ | hurl → Azure AI Search | | llm/models | #33 | ✅ | LiteLLM → Azure OpenAI chat | ## Type of change - This pull request adds or changes features of Radius and has an approved issue (issue link required). Fixes: radius-project#12347 ## Related PRs - `radius-project/resource-types-contrib` radius-project#224 (merged) — container recipe env ordering fix (emit secret/`valueFrom` env vars before `value` vars), which enables the developer-side `$(VAR)` secret-composition pattern this feature relies on. - `radius-project/resource-types-verification` #32 (kafka reference) and #33–#38 (llm, search, storage, mongodb, redis, rabbitmq) — the 7-type end-to-end validation above; each pins the `radius` submodule to this branch. ## Not yet included (follow-ups) - Registration-time `secrets`-block schema validation and `readOnly` input enforcement. - Durable managed-secret provisioning status (requeue/verify the managed secret exists before marking the owner Succeeded) — see review discussion. - Scenario 2 (re-fetchable secret output: store an identifier and re-resolve the live value from the cloud provider at bind time). - Converting the shipped built-in types in `resource-types-contrib` to declare `secrets:` blocks (the verification repo converted its test manifests to prove the flow). ## Contributor checklist - An overview of proposed schema changes is included in a linked GitHub issue. - [x] Yes - [ ] Not applicable - A design document is added or updated under `eng/design-notes/` in this repository, if new APIs are being introduced. - [ ] Yes - [ ] Not applicable - The design document has been reviewed and approved by Radius maintainers/approvers. - [ ] Yes - [ ] Not applicable - A PR for [resource-types-contrib](https://github.com/radius-project/resource-types-contrib/) is created, if resource types or recipes are affected by the changes in this PR. - [x] Yes <!-- resource-types-contrib#224 --> - [ ] Not applicable - A PR for [dashboard](https://github.com/radius-project/dashboard/) is created, if the Radius Dashboard is affected by the changes in this PR. - [ ] Yes - [x] Not applicable - A PR for the [documentation repository](https://github.com/radius-project/docs) is created, if the changes in this PR affect the documentation or any user facing updates are made. - [ ] Yes - [x] Not applicable <!-- architecture doc updated in-repo; user docs to follow with the tracking issue --> --------- Signed-off-by: willdavsmith <willdavsmith@gmail.com>
Overview
Update the existing
generatesubcommand ofmanifest-to-bicepto accept multiple manifest files. When given multiple YAML manifests with the same namespace, theirTypesmaps are merged into a single output (types.json,index.json,index.md).This supports per-type manifest files (e.g.
containers.yaml,routes.yaml) as introduced by the automated resource type registration design, where each file defines a single resource type within a namespace.Backward compatible: single-file usage works exactly as before.
Part of Unified Bicep extension publishing (PR 1/4). See design doc.
Changes
bicep-tools/cmd/manifest-to-bicep/main.go: Updatedgenerateto accept<manifest1> [manifest2...] <output>(last arg is always output dir). AddedmergeManifestFiles()that validates same namespace and rejects duplicate types.Usage
Single file (backward compatible):
Multiple files (merge into one output):