Fix an issue with empty ID for CustomResource (#2449)

* Fix an issue with empty ID for CustomResource

The Python runtime was checking the ID field it receives from the engine
against None, assuming that the engine would not set the ID field if one
was not present. However, it does set the ID field; it is set to the
empty string when an ID is not known.

This commit fixes an issue that can cause certain IDs to be erroneously
considered to be known during previews, which can cause problems during
the Check phase of resources that directly reference IDs of other
resources.

* Add CHANGELOG
This commit is contained in:
Sean Gillespie 2019-02-15 09:55:19 -08:00 committed by GitHub
parent 7c42f71c3c
commit e0b516d0cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 13 additions and 5 deletions

View file

@ -4,6 +4,8 @@
- When trying to `stack rm` a stack managed by pulumi.com that has resources, the error message now informs you to pass `--force` if you really want to remove a stack that still has resources under management, as this would orphan these resources (fixes [pulumi/pulumi#2431](https://github.com/pulumi/pulumi/issues/2431)).
- Enabled Python programs to delete resources in parallel (fixes [pulumi/pulumi#2382](https://github.com/pulumi/pulumi/issues/2382)). If you are using Python 2, you should upgrade to Python 3 or else you may experience problems when deleting resources.
- Fixed an issue where Python programs would occasionally fail during preview with errors about empty IDs being passed
to resources. ([pulumi/pulumi#2450](https://github.com/pulumi/pulumi/issues/2450))
## 0.16.14 (Released January 31st, 2019)

View file

@ -210,7 +210,10 @@ def register_resource(res: 'Resource', ty: str, name: str, custom: bool, props:
log.debug(f"resource registration successful: ty={ty}, urn={resp.urn}")
resolve_urn(resp.urn)
if resolve_id:
is_known = resp.id is not None
# The ID is known if (and only if) it is a non-empty string. If it's either None or an empty string,
# we should treat it as unknown. TFBridge in particular is known to send the empty string as an ID when
# doing a preview.
is_known = bool(resp.id)
resolve_id(resp.id, is_known, None)
await rpc.resolve_outputs(res, props, resp.object, resolvers)

View file

@ -34,7 +34,8 @@ class ResourceB(CustomResource):
def __init__(self, name: str, res: ResourceA) -> None:
CustomResource.__init__(self, "test:index:ResourceB", name, {
"other_in": res.inprop,
"other_out": res.outprop
"other_out": res.outprop,
"other_id": res.id,
})
a = ResourceA("resourceA")

View file

@ -35,7 +35,7 @@ class ResourceThensTest(LanghostTest):
self.assertEqual(name, "resourceA")
self.assertDictEqual(res, {"inprop": 777})
urn = self.make_urn(ty, name)
res_id = None
res_id = ""
props = {}
if not dry_run:
res_id = name
@ -54,14 +54,16 @@ class ResourceThensTest(LanghostTest):
self.assertDictEqual(res, {
"other_in": 777,
# other_out is unknown, so it is not in the dictionary.
# other_id is also unknown so it is not in the dictionary
})
else:
self.assertDictEqual(res, {
"other_in": 777,
"other_out": "output yeah"
"other_out": "output yeah",
"other_id": "resourceA",
})
res_id = None
res_id = ""
if not dry_run:
res_id = name