feat: meshstack_building_block resource + meshstack_building_blocks data source (building block v3)#208
Merged
Merged
Conversation
📊 Test Coverage
Uncovered functions (combined run)Combined with |
373210e to
d6be974
Compare
c2be4be to
afc625e
Compare
d6be974 to
40e598c
Compare
afc625e to
492b794
Compare
6666c94 to
1aab4ae
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Adds the new preview meshstack_building_block (v3) Terraform resource backed by the meshObject API, including run awaiting/diagnostics, sensitive input rotation semantics, and state migration from legacy building block resources. It also refactors the client HTTP layer and expands test/mocking infrastructure to support the new building block workflows.
Changes:
- Introduces
meshstack_building_blockresource with run await + rerun gating (inputs, content hash, parents, secret rotation) andmoved-state migrations from v1/v2. - Adds supporting validators, secret hash-only type/schema, and shared converters for polymorphic JSON (
clientTypes.Any) handling. - Updates landing zone ref handling, client HTTP internals, mocks, examples, docs, and changelog.
Reviewed changes
Copilot reviewed 67 out of 81 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/validators/discriminated_attributes_validator.go | New object validator for discriminator-selected attributes. |
| internal/types/secret/secret.go | Adds HashOnly + secret rotation detection helpers. |
| internal/types/secret/secret_schema_resource.go | Adds read-only secret (hash-only) schema helper. |
| internal/provider/testdata/tf-building-block/refs/heads/main | Bare git repo fixture ref for acc tests. |
| internal/provider/testdata/tf-building-block/README.md | Documents bare git repo fixture usage/editing. |
| internal/provider/testdata/tf-building-block/info/exclude | Bare git repo metadata fixture. |
| internal/provider/testdata/tf-building-block/HEAD | Bare git repo HEAD fixture. |
| internal/provider/testdata/tf-building-block/config | Bare git repo config fixture. |
| internal/provider/service_instance_data_source.go | Switches to shared clientTypes.Any converter helper. |
| internal/provider/schema_utils.go | Removes now-unused BB definition ref helper. |
| internal/provider/provider.go | Registers v1/v2/v3 building block resources. |
| internal/provider/provider_test.go | Adds helper skip functions for mixed-mode steps. |
| internal/provider/landingzone_resource.go | Accepts full ref objects; kind optional+validated. |
| internal/provider/git_http_server_test.go | Smart-HTTP server for git-based module fixture. |
| internal/provider/converter_client_type_any.go | Shared bidirectional converter for clientTypes.Any. |
| internal/provider/buildingblock_resource.go | Renames legacy v1 resource impl + deprecates it. |
| internal/provider/buildingblock_resource_test.go | Renames v1 acc test to match legacy resource symbol. |
| internal/provider/building_block_v2_resource.go | Deprecates v2; aligns schema + IO typing changes. |
| internal/provider/building_block_v2_data_source.go | Aligns v2 DS status docs + input handling. |
| internal/provider/building_block_v2_data_source_test.go | Adds subtests + sensitive-input hash assertion. |
| internal/provider/building_block_resource.go | New v3 meshstack_building_block resource implementation. |
| internal/provider/building_block_resource_await_test.go | Unit tests for await-run behavior (polling/warnings). |
| internal/provider/building_block_definition_resource_model.go | Reuses shared SecretOrAny converters; cleanup. |
| internal/provider/acctest/testconfig/build_landingzone.go | Uses computed ref objects in test builders. |
| internal/provider/acctest/testconfig/build_building_block.go | New test builder for v3 building blocks. |
| internal/clientmock/mock_client.go | Adds run client; shares stores across BB clients. |
| internal/clientmock/mock_buildingblock.go | Reworks v1 mock to map onto shared v2/v3 store. |
| internal/clientmock/mock_buildingblock_v2.go | Removes old v2 mock client implementation. |
| internal/clientmock/mock_building_block_v2.go | New v2/v3 mock with patch semantics + runs. |
| internal/clientmock/mock_building_block_run.go | Mock run log retrieval client. |
| internal/clientmock/mock_building_block_definition.go | Mock building block definition client. |
| internal/clientmock/mock_building_block_definition_version.go | Mock BBD version client incl. manual output behavior. |
| go.sum | Adds timeouts module checksums. |
| go.mod | Adds terraform-plugin-framework-timeouts dependency. |
| examples/resources/meshstack_building_block/test-support_tenant_migration_bbd.tf | Fixture BBD for v1→v3 migration test. |
| examples/resources/meshstack_building_block/test-support_tenant_migration_bb.tf | Fixture BB for v1→v3 migration test. |
| examples/resources/meshstack_building_block/test-support_other_provider.tf | Test-only secondary provider config. |
| examples/resources/meshstack_building_block/test-support_moved_from_v2.tf | Moved-block fixture for v2→v3 migration. |
| examples/resources/meshstack_building_block/test-support_moved_from_v1.tf | Moved-block fixture for v1→v3 migration. |
| examples/resources/meshstack_building_block/test-support_07_non_updateable.tf | Fixture BBD for non-updateable input behavior. |
| examples/resources/meshstack_building_block/test-support_04_sensitive_user_input.tf | Fixture BB with sensitive inputs. |
| examples/resources/meshstack_building_block/test-support_04_sensitive_user_input_bbd.tf | Fixture BBD for sensitive input scenarios. |
| examples/resources/meshstack_building_block/test-support_03_operator_inputs.tf | Fixture BBD covering operator inputs. |
| examples/resources/meshstack_building_block/test-support_02_tenant.tf | Tenant-level BBD fixture for tests. |
| examples/resources/meshstack_building_block/test-support_01_workspace.tf | Workspace-level BBD fixture for tests. |
| examples/resources/meshstack_building_block/resource_02_tenant.tf | Registry example: tenant-level v3 BB. |
| examples/resources/meshstack_building_block/resource_01_workspace.tf | Registry example: workspace-level v3 BB. |
| examples/resources/meshstack_building_block/import-by-string-id.tf | Import example for v3 BB. |
| docs/resources/landingzone.md | Regenerated docs reflecting ref/kind changes. |
| docs/resources/building_block.md | New generated registry docs for v3 BB. |
| docs/resources/building_block_v2.md | Regenerated v2 docs with updated status enum text. |
| docs/data-sources/building_block_v2.md | Regenerated v2 DS docs with updated status enum text. |
| client/types/clienttypes.go | Clarifies secret plaintext/hash semantics. |
| client/internal/options.go | Adds WithPathElems, exports WithAccept. |
| client/internal/mesh_object_client.go | Refactors to DoAuthorizedRequest + options support. |
| client/internal/http_error.go | Adds IsConflict() helper. |
| client/internal/http_client.go | Introduces DoRequest/DoAuthorizedRequest, path elems. |
| client/internal/http_client_test.go | Updates tests for new request helpers and semantics. |
| client/internal/auth.go | Switches auth flow to new DoRequest. |
| client/client.go | Extracts mesh version check + adds run client. |
| client/client_kind.go | Adds meshObject kind for building block runs. |
| client/buildingblock_v2.go | Removes legacy v2 building block client/types. |
| client/buildingblock_v2_test.go | Removes legacy v2 tests. |
| client/building_block_v2.go | New v2-preview building block client/types + enums. |
| client/building_block_v2_test.go | New tests for create/deletion success semantics. |
| client/building_block_runner.go | Adds runner client/types (preview). |
| client/building_block_run.go | Adds run log retrieval client/types. |
| client/building_block_definition.go | Adds definition client/types (preview). |
| client/building_block_definition_version.go | Adds version client/types + enums (preview). |
| client/building_block_definition_version_test.go | Adds JSON unmarshal tests for sensitive variants. |
| client/building_block_definition_version_implementation.go | Adds implementation polymorphism (manual/terraform/etc.). |
| CHANGELOG.md | Adds v0.23.0 release notes for BB v3 + landingzone changes. |
| .golangci.yml | Allows framework-timeouts dependency. |
| .agents/skills/new-resource-datasource/SKILL.md | Documents review conventions (response pointers, secret mock behavior). |
f36ac15 to
5ab60ac
Compare
2def267 to
a0a3364
Compare
grubmeshi
commented
Jun 26, 2026
grubmeshi
commented
Jun 26, 2026
grubmeshi
commented
Jun 26, 2026
grubmeshi
commented
Jun 26, 2026
grubmeshi
commented
Jun 26, 2026
grubmeshi
commented
Jun 26, 2026
grubmeshi
commented
Jun 26, 2026
grubmeshi
commented
Jun 26, 2026
grubmeshi
commented
Jun 26, 2026
a0a3364 to
115b81f
Compare
nroi
approved these changes
Jun 30, 2026
115b81f to
ed46c05
Compare
The landing zone's spec.platform_ref and mandatory/recommended building_block_refs declared `kind` as read-only (Computed only), so assigning a referenced resource's computed `ref` inline — e.g. `platform_ref = meshstack_platform.example.ref` — failed with "Cannot set value for this attribute as the provider has marked it as read-only". Make `kind` optional+computed with its single valid value as default and a OneOf validator, matching location_ref / platform_type_ref. The building block refs now reuse the shared meshUuidRefAttribute helper (uuid optional+computed) so a full ref object also works as a set element whose referenced resource is created in the same apply; the bespoke meshBuildingBlockDefinitionRefAttribute is removed. The landing zone test builder now assigns the platform and definition refs inline as a regression guard. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
meshUuidRefAttribute keeps uuid Optional+Computed so a whole computed .ref object (whose uuid is unknown until apply) can be assigned and the backend can default an omitted ref — which also let a ref be provided without a uuid, failing only later against the backend. Guard such refs with meshUuidRefValidators (objectvalidator.AlsoRequires on uuid): a provided ref object must carry its uuid, while an assigned computed .ref still passes (AlsoRequires treats an unknown value as configured). Wire it into the user-supplied ref sites — landingzone mandatory/recommended_building_block_refs and the building block definition's dependencies and integration_ref; runner refs keep optional uuid (the backend fills the shared-runner default). Also reuse the shared kind+uuid ref helpers more widely (addressing the helper TODO): the platform and tenant_v4 resources' computed .ref outputs now use meshUuidRefOutputAttribute. Bespoke refs (the discriminated target_ref, the RequiresReplace platform_ref, the uuid-only version_ref) keep their own schema; data source refs use the datasource schema package and are out of scope. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replaces doRequest/doAuthorizedRequest + GetMeshInfo/unmarshalBody helpers with a generic DoRequest[R]/DoAuthorizedRequest[R] API and adds WithPathElems JoinPath support. Strengthens the PATCH non-retry test to assert exactly one attempt against a retryable 502 response. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rename all non-v1 building-block files from buildingblock_* to building_block_* to match the resource name meshstack_building_block. De-collide v1 symbols (NewBuildingblockResource / buildingblockResource) to free the CamelCase names for the new resource, and update the v1 deprecation message target from meshstack_building_block_v3 to meshstack_building_block. Rename-only; no behaviour change. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ed46c05 to
b18a09e
Compare
… topology The acceptance suite gained real terraform-implementation BBDs (the committed tf-building-block fixture served over git smart-HTTP) plus an end-to-end sensitive-input decryption proof, so it now requires the full multiplexer fan-out — exactly what local-dev-stack and CI (.github/workflows/test.yml) run. - meshstack-services: drop the obsolete "run a single manual no-op runner" topology; defer to local-dev-stack's mux + tf + manual fan-out and explain why both real runners are required. - scratch-config-testing: the tf-block-runner already runs behind the mux as part of the standard fan-out, so terraform-impl BBDs need no runner swap; sensitive inputs decrypt out of the box (drop the stale decrypt gotcha). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds the meshstack_building_block resource (v3), superseding v2 with: - In-place updates via PUT + explicit trigger-run; no destroy+recreate. Changes to content_hash, inputs, or parent_building_blocks trigger a rerun; in-place version upgrades are supported via PUT - Sensitive input support (value_string_sensitive/value_code_sensitive), preserving secrets across upgrades and avoiding phantom drift from null USER_INPUT rows - wait_for_completion: polls up to 30 min; WAITING_FOR_* states produce actionable warnings; preserved across reads/import (null vs false) - run-log diagnostics: on poll failure addRunFailureDiagnostics surfaces step-level logs as Terraform warnings - MoveState from meshstack_buildingblock (v1) and meshstack_building_block_v2 - target_ref validators (meshTenant requires uuid, meshWorkspace requires name) - Soft-delete-aware Read: a deleted building block is removed from state - Hardens the building_block_v2 client/mock/data-source: nil-pointer guards, ABORTED + nil Status handling in CreateSuccessful, sensitive input reads in the v2 data source, mock deep-copy fidelity - Fixes CHANGELOG, truncated all_inputs.value doc, purge description, operator-input test assertions, secret docs version reference - Regenerates provider docs (building_block.md replaces building_block_v3.md) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add a read-only, filterable list data source backed by the v2-preview building block list endpoint. Each entry mirrors the meshstack_building_block resource (metadata/spec/status/all_inputs); sensitive inputs are surfaced as a hash only, reusing the secret data-source schema. Filters: workspace/project/platform identifier, name, definition_uuid, version_uuid, version_number (lenient "v1"/"1"), tenant_uuid, target_kind, status, lifecycle_states (repeated query param; empty => all), and the platform-operator scope selectors managed_by_definition_uuid / managed_by_workspace_identifier (MANAGED_BUILDINGBLOCK_LIST). Adds a List method + filter struct on the building block v2 client, a WithUrlQueryValues option for repeated query params, and a mock List implementation. Reuses the resource's all_inputs mapping via an extracted buildAllInput helper. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sensitive user inputs (STRING and CODE) sent by the deprecated meshstack_building_block_v2 resource omitted IsSensitive on the outbound MeshBuildingBlockInput. Because MeshBuildingBlockInput.UnmarshalJSON demotes a secret from SecretOrAny.X to a plain SecretOrAny.Y when IsSensitive is false, the secret was stripped on the mock client's JSON round-trip and the plaintext leaked into value_string as a raw map instead of surfacing the backend hash. Set IsSensitive on sensitive inputs so the secret stays in the X variant, matching what the v3 resource does symmetrically via buildingBlockConverterOptions. The real backend re-derives sensitivity from the definition, so this is a correctness/mock-fidelity fix with no user-facing behavior change (no CHANGELOG entry). Re-enables the previously mock-skipped v2 sensitive-input tests to run in both mock and acceptance modes, asserting the surfaced value is the hash and not the plaintext. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
b18a09e to
a90d7be
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the
meshstack_building_blockresource (v3, preview API) for managing Building Blocks via the meshObject API.What it delivers
jsonencode(...); sensitive inputs via asensitiveblock withsecret_version-controlled rotation.building_block_definition_version_ref.uuid.movedsupport frommeshstack_buildingblock(v1) andmeshstack_building_block_v2.status.latest_run_uuid(latest modifying run) and the new computedstatus.latest_dry_run_uuid; runs awaited with run-log diagnostics on failure, with a configurabletimeoutsblock (create/update/delete).Behavior contract
target_ref.*forces replacement (you cannot move a Building Block to another tenant/workspace).display_nameandinputsupdate in place.parent_building_blockschange only as part of a version upgrade — changing them on their own forces replacement.secret_versionbump), acontent_hashchange, or a parent change carried by a version upgrade; a rename or a no-op does not. An update that supplies a previously-missing input (unblocking a block parked inWAITING_FOR_OPERATOR_INPUT) awaits the resulting run instead of returning early.spec.inputs; an input set by another party but omitted is preserved server-side and surfaced read-only inall_inputs, not as drift. This lets a platform operator manage operator inputs while the consumer owns user inputs, each declaring only its own.sensitiveblock iff the definition declares the input sensitive; amovedmigration warns to re-supply the secret (it cannot travel through state).Data source:
meshstack_building_blocksAdds a read-only, filterable companion list data source (backed by the same v2-preview list endpoint). Each returned block mirrors the resource schema (
metadata/spec/status/all_inputs); sensitive inputs are surfaced as a hash only.workspace_identifier,project_identifier,platform_identifier,name,definition_uuid,version_uuid,version_number(lenientv1/1),tenant_uuid,target_kind,status,lifecycle_states(repeated param; empty ⇒ all), and the platform-operator scope selectorsmanaged_by_definition_uuid/managed_by_workspace_identifier(MANAGED_BUILDINGBLOCK_LIST).version_numberfiltering requires the paired meshfed change (meshcloud/meshfed-release#10063).What it enables — app team & operator use cases
A local end-to-end demo (operator → app team → cross-workspace upgrade) exercises the new building blocks this resource unlocks:
App team (workspace-scoped consumer)
meshstack_building_blocks/meshstack_building_block_definitionsdata sources), pinning to a chosen version.all_inputs, never as drift.run_transparency = false(status.latest_run_uuidcomes back null).Platform operator (definition owner)
content_hash(no replace, no teardown), surfacing the failing run's logs as the definition owner even when transparency is off.MANAGED_…key:importblocks keyed off the data source pull each block made from its definition into operator state, then a pure version bump upgrades them — without owning, and never deleting them (teardown useslifecycle { destroy = false }to forget, not delete).inputs = {}→ backend fills the default), and the app team's user inputs (including the sensitive one) are left untouched.Also includes
meshstack_landingzone:spec.platform_refandspec.mandatory_building_block_refs/spec.recommended_building_block_refsnow accept a referenced resource's computedrefdirectly (e.g.platform_ref = meshstack_platform.example.ref);kindis optional rather than read-only, so assigning a full ref object no longer fails.uuidis rejected up front (instead of only failing against the backend), while an assigned computed.ref— whoseuuidis unknown until apply — keeps working. Applies to the landingzone building-block refs and the building block definition'sdependencies/integration_ref.Backend counterpart: meshcloud/meshfed-release#10063.
🤖 Generated with Claude Code