Skip to content

Commit 42cd812

Browse files
committed
fix(pulumi): set ComputeID for s3_export_policy_rule (empty resource.ID)
The FlashBlade S3ExportPolicyRule API schema does not expose an 'id' field (verified against api_references/2.22.md and the OpenAPI spec). The TF resource assigns data.ID = rule.ID, which the API leaves empty, so the Pulumi bridge rejected Create with 'plugin for package mica returned empty resource.ID from create'. Add a bridge ComputeID that derives the Pulumi resource ID from the composite policyName/index, matching the TF ImportState format (policy_name/rule_index). Also regenerate the Python SDK package directory under pulumi_mica/ to match the v2.22.4 rebrand (the previous beta still shipped pulumi_flashblade/).
1 parent 309379c commit 42cd812

112 files changed

Lines changed: 780 additions & 716 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pulumi/CHANGELOG.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,25 @@ First post-rebrand Pulumi release. Distributed via GitHub Releases (no Pulumi Re
1010
- Python wheel: `pulumi_mica-2.22.6-py3-none-any.whl` published as a release asset.
1111
- Go SDK companion tag: `sdk/go/v0.1.0-pulumi.beta`.
1212

13+
### Fixed
14+
15+
- `mica:index:S3ExportPolicyRule` Create no longer fails with `plugin for package
16+
'mica' returned empty resource.ID from create`. The FlashBlade
17+
`S3ExportPolicyRule` API schema does not expose an `id` field, so the
18+
bridge-inherited TF `id` attribute was always empty and Pulumi rejected the
19+
resource. A bridge `ComputeID` now derives the Pulumi resource ID from the
20+
composite `policyName/index`, matching the TF `ImportState` format
21+
(`policy_name/rule_index`). Existing stacks that hit this error during Create
22+
must `pulumi destroy --target` the failed URN (or remove it from state) and
23+
re-apply.
24+
- Python SDK package directory regenerated under `pulumi_mica/` to match the
25+
v2.22.4 rebrand (the previous beta still shipped the legacy
26+
`pulumi_flashblade/` directory).
27+
1328
### Notes
1429

1530
- Builds against the same provider sources as the Terraform `v2.22.6` release (registry-published manifest fix).
16-
- No schema, behavior, or token changes vs `[2.22.4]` rebrand baseline — see that entry for the breaking changes from the `pulumi-flashblade` era.
31+
- No schema or token changes vs `[2.22.4]` rebrand baseline — see that entry for the breaking changes from the `pulumi-flashblade` era.
1732

1833
## [2.22.4] — 2026-04-28
1934

pulumi/provider/resources.go

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,34 @@ func Provider() tfbridge.ProviderInfo {
137137
panic("flashblade_file_system resource not found after MustComputeTokens")
138138
}
139139

140-
// flashblade_s3_export_policy_rule — TF data.ID is rule.ID (UUID from the API).
141-
// No ComputeID override: the bridge uses the TF "id" attribute directly via the shim.
142-
// A ComputeID producing "policyName/ruleName" would diverge from the UUID and break
143-
// pulumi import / pulumi refresh round-trips (I1).
144-
if _, ok := prov.Resources["flashblade_s3_export_policy_rule"]; !ok {
140+
// ---- COMPOSITE-S3RULE: flashblade_s3_export_policy_rule ComputeID ----
141+
// The S3ExportPolicyRule API schema does NOT expose an `id` field (verified
142+
// against api_references/2.22.md and FlashBlade swagger). The TF "id" attribute
143+
// is Computed and assigned from rule.ID, but the API response leaves it empty,
144+
// so the Pulumi bridge fails Create with "empty resource.ID from create".
145+
// Composite ID matches the TF ImportState format: "policy_name/rule_index"
146+
// (verified against internal/provider/s3_export_policy_rule_resource.go ImportState).
147+
if r, ok := prov.Resources["flashblade_s3_export_policy_rule"]; ok {
148+
r.ComputeID = func(ctx context.Context, state resource.PropertyMap) (resource.ID, error) {
149+
policyName, ok1 := state["policyName"]
150+
index, ok2 := state["index"]
151+
if !ok1 || !ok2 {
152+
return "", fmt.Errorf(
153+
"s3_export_policy_rule: missing policyName or index in state (got keys %v)",
154+
mapKeys(state),
155+
)
156+
}
157+
ps, psOk := policyName.V.(string)
158+
if !psOk {
159+
return "", fmt.Errorf("s3_export_policy_rule: policyName must be a string")
160+
}
161+
idx, idxOk := index.V.(float64)
162+
if !idxOk {
163+
return "", fmt.Errorf("s3_export_policy_rule: index must be a number")
164+
}
165+
return resource.ID(fmt.Sprintf("%s/%d", ps, int64(idx))), nil
166+
}
167+
} else {
145168
panic("flashblade_s3_export_policy_rule resource not found after MustComputeTokens")
146169
}
147170

pulumi/provider/resources_test.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,18 +304,22 @@ func TestProviderInfo_SoftDeleteResourcesRegistered(t *testing.T) {
304304
// Only resources where the TF schema does NOT expose an "id" attribute need ComputeID:
305305
// - flashblade_bucket_access_policy_rule: no "id" in TF schema, bridge cannot infer it.
306306
// - flashblade_management_access_policy_directory_service_role_membership: id is composite role/policy.
307+
// - flashblade_s3_export_policy_rule: TF "id" is computed from rule.ID, but the
308+
// S3ExportPolicyRule API schema does not expose `id` — TF state.ID is therefore
309+
// always empty and the bridge fails Create with "empty resource.ID". Composite
310+
// ID matches ImportState format: "policy_name/rule_index" (COMPOSITE-S3RULE).
307311
//
308312
// Resources where TF already exposes a computed "id" attribute do NOT need ComputeID:
309313
// - flashblade_object_store_access_policy_rule: TF id = compositeID(policyName, ruleName).
310314
// - flashblade_network_access_policy_rule: TF id = rule.ID (UUID from API).
311-
// - flashblade_s3_export_policy_rule: TF id = rule.ID (UUID from API).
312315
// - flashblade_snapshot_policy_rule: TF id = compositeID(policyName, ruleName).
313316
func TestProviderInfo_AllCompositeIDsPresent(t *testing.T) {
314317
prov := Provider()
315318
// Resources requiring explicit ComputeID (no "id" attribute in TF schema).
316319
compositeResources := []string{
317320
"flashblade_bucket_access_policy_rule",
318321
"flashblade_management_access_policy_directory_service_role_membership",
322+
"flashblade_s3_export_policy_rule",
319323
}
320324
for _, name := range compositeResources {
321325
r, ok := prov.Resources[name]
@@ -331,7 +335,6 @@ func TestProviderInfo_AllCompositeIDsPresent(t *testing.T) {
331335
noComputeIDResources := []string{
332336
"flashblade_object_store_access_policy_rule",
333337
"flashblade_network_access_policy_rule",
334-
"flashblade_s3_export_policy_rule",
335338
}
336339
for _, name := range noComputeIDResources {
337340
r, ok := prov.Resources[name]
@@ -366,6 +369,29 @@ func TestProviderInfo_ComputeID_BucketAccessPolicyRule(t *testing.T) {
366369
}
367370
}
368371

372+
// TestProviderInfo_ComputeID_S3ExportPolicyRule invokes the COMPOSITE-S3RULE closure
373+
// with sample PropertyMap data and asserts the returned ID matches the TF ImportState
374+
// format "policy_name/rule_index" (COMPOSITE-S3RULE).
375+
func TestProviderInfo_ComputeID_S3ExportPolicyRule(t *testing.T) {
376+
prov := Provider()
377+
r := prov.Resources["flashblade_s3_export_policy_rule"]
378+
if r == nil || r.ComputeID == nil {
379+
t.Fatalf("ComputeID not set on flashblade_s3_export_policy_rule")
380+
}
381+
state := resource.PropertyMap{
382+
"policyName": resource.NewStringProperty("my-policy"),
383+
"index": resource.NewNumberProperty(3),
384+
"name": resource.NewStringProperty("rule-3"),
385+
}
386+
id, err := r.ComputeID(context.Background(), state)
387+
if err != nil {
388+
t.Fatalf("ComputeID error: %v", err)
389+
}
390+
if string(id) != "my-policy/3" {
391+
t.Errorf("expected 'my-policy/3', got %q", id)
392+
}
393+
}
394+
369395
// TestProviderInfo_NetworkAccessPolicyRuleNoComputeID verifies that
370396
// flashblade_network_access_policy_rule does NOT have a ComputeID override.
371397
// TF data.ID = rule.ID (UUID from API) — the bridge uses the TF "id" attribute

pulumi/sdk/python/Pulumi.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
name: flashblade
2-
description: A Pulumi resource provider for flashblade.
1+
name: mica
2+
description: A Pulumi resource provider for mica.
33
language: python

0 commit comments

Comments
 (0)