Support remote components in Python (#5375)

This commit is contained in:
Justin Van Patten 2020-09-30 21:09:20 +00:00 committed by GitHub
parent 38172999e7
commit 9bcf02e7ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 334 additions and 103 deletions

View file

@ -3,7 +3,8 @@ CHANGELOG
## HEAD (Unreleased)
_(None)_
- Add internal scaffolding for using cross-language components from Python.
[#5375](https://github.com/pulumi/pulumi/pull/5375)
## 2.11.0 (2020-09-30)
@ -18,7 +19,6 @@ _(None)_
(fixes [#5446](https://github.com/pulumi/pulumi/issues/5446))
[#5465](https://github.com/pulumi/pulumi/pull/5465)
## 2.10.2 (2020-09-21)
- [sdk/go] Add missing Version field to invokeOptions
@ -26,7 +26,7 @@ _(None)_
- Add `pulumi console` command which opens the currently selected stack in the Pulumi console.
[#5368](https://github.com/pulumi/pulumi/pull/5368)
- Python SDK: Cast numbers intended to be integers to `int`.
[#5419](https://github.com/pulumi/pulumi/pull/5419)

View file

@ -1570,6 +1570,36 @@ func (pt *ProgramTester) copyTestToTemporaryDirectory() (string, string, error)
return "", "", errors.Wrapf(err, "Failed to prepare %v", projdir)
}
// TODO[pulumi/pulumi#5455]: Dynamic providers fail to load when used from multi-lang components.
// Until that's been fixed, this environment variable can be set by a test, which results in
// a package.json being emitted in the project directory and `yarn install && yarn link @pulumi/pulumi`
// being run.
// When the underlying issue has been fixed, the use of this environment variable should be removed.
var yarnLinkPulumi bool
for _, env := range pt.opts.Env {
if env == "PULUMI_TEST_YARN_LINK_PULUMI=true" {
yarnLinkPulumi = true
break
}
}
if yarnLinkPulumi {
const packageJSON = `{
"name": "test",
"peerDependencies": {
"@pulumi/pulumi": "latest"
}
}`
if err := ioutil.WriteFile(filepath.Join(projdir, "package.json"), []byte(packageJSON), 0600); err != nil {
return "", "", err
}
if err = pt.runYarnCommand("yarn-install", []string{"install"}, projdir); err != nil {
return "", "", err
}
if err := pt.runYarnCommand("yarn-link", []string{"link", "@pulumi/pulumi"}, projdir); err != nil {
return "", "", err
}
}
fprintf(stdout, "projdir: %v\n", projdir)
return tmpdir, projdir, nil
}

View file

@ -1252,7 +1252,7 @@ proto.pulumirpc.RegisterResourceRequest.toObject = function(includeInstance, msg
customtimeouts: (f = msg.getCustomtimeouts()) && proto.pulumirpc.RegisterResourceRequest.CustomTimeouts.toObject(includeInstance, f),
deletebeforereplacedefined: jspb.Message.getBooleanFieldWithDefault(msg, 18, false),
supportspartialvalues: jspb.Message.getBooleanFieldWithDefault(msg, 19, false),
remote: jspb.Message.getBooleanFieldWithDefault(msg, 21, false)
remote: jspb.Message.getBooleanFieldWithDefault(msg, 20, false)
};
if (includeInstance) {
@ -1369,7 +1369,7 @@ proto.pulumirpc.RegisterResourceRequest.deserializeBinaryFromReader = function(m
var value = /** @type {boolean} */ (reader.readBool());
msg.setSupportspartialvalues(value);
break;
case 21:
case 20:
var value = /** @type {boolean} */ (reader.readBool());
msg.setRemote(value);
break;
@ -1537,7 +1537,7 @@ proto.pulumirpc.RegisterResourceRequest.serializeBinaryToWriter = function(messa
f = message.getRemote();
if (f) {
writer.writeBool(
21,
20,
f
);
}
@ -2351,11 +2351,11 @@ proto.pulumirpc.RegisterResourceRequest.prototype.setSupportspartialvalues = fun
/**
* optional bool remote = 21;
* optional bool remote = 20;
* @return {boolean}
*/
proto.pulumirpc.RegisterResourceRequest.prototype.getRemote = function() {
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 21, false));
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 20, false));
};
@ -2364,7 +2364,7 @@ proto.pulumirpc.RegisterResourceRequest.prototype.getRemote = function() {
* @return {!proto.pulumirpc.RegisterResourceRequest} returns this
*/
proto.pulumirpc.RegisterResourceRequest.prototype.setRemote = function(value) {
return jspb.Message.setProto3BooleanField(this, 21, value);
return jspb.Message.setProto3BooleanField(this, 20, value);
};

View file

@ -295,7 +295,7 @@ type RegisterResourceRequest struct {
CustomTimeouts *RegisterResourceRequest_CustomTimeouts `protobuf:"bytes,17,opt,name=customTimeouts,proto3" json:"customTimeouts,omitempty"`
DeleteBeforeReplaceDefined bool `protobuf:"varint,18,opt,name=deleteBeforeReplaceDefined,proto3" json:"deleteBeforeReplaceDefined,omitempty"`
SupportsPartialValues bool `protobuf:"varint,19,opt,name=supportsPartialValues,proto3" json:"supportsPartialValues,omitempty"`
Remote bool `protobuf:"varint,21,opt,name=remote,proto3" json:"remote,omitempty"`
Remote bool `protobuf:"varint,20,opt,name=remote,proto3" json:"remote,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -761,63 +761,63 @@ func init() { proto.RegisterFile("resource.proto", fileDescriptor_d1b72f771c35e3
var fileDescriptor_d1b72f771c35e3b8 = []byte{
// 927 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x5f, 0x73, 0xdb, 0x44,
0x10, 0x8f, 0xed, 0x54, 0xb1, 0x37, 0xa9, 0x13, 0x2e, 0xa9, 0x73, 0x15, 0x4c, 0x08, 0x82, 0x07,
0xc3, 0x83, 0xd3, 0x06, 0x66, 0x1a, 0x18, 0xfe, 0xcc, 0xd0, 0x16, 0xa6, 0x0f, 0x85, 0xa2, 0x30,
0x0c, 0x30, 0x03, 0x33, 0x17, 0x69, 0xe3, 0x8a, 0xc8, 0xba, 0xeb, 0xdd, 0x29, 0x33, 0x7e, 0x83,
0x47, 0xbe, 0x16, 0x9f, 0x86, 0x67, 0x3e, 0x01, 0x73, 0x77, 0x92, 0xb1, 0x2c, 0x39, 0xb1, 0xcb,
0x10, 0x8f, 0xed, 0x54, 0xb1, 0x37, 0xa9, 0x13, 0x2e, 0xc1, 0xb9, 0x0a, 0x26, 0x04, 0xc1, 0x83,
0xe1, 0xc1, 0x69, 0x03, 0x33, 0x0d, 0x0c, 0x7f, 0x66, 0x68, 0x0b, 0xd3, 0x87, 0x42, 0x51, 0x18,
0x06, 0x98, 0x81, 0x99, 0x8b, 0xb4, 0x71, 0x45, 0x64, 0xdd, 0xf5, 0xee, 0x94, 0x19, 0xbf, 0xc1,
0x23, 0x5f, 0x8b, 0x4f, 0xc3, 0x33, 0x9f, 0x80, 0xb9, 0x3b, 0xc9, 0x58, 0x96, 0x9c, 0xd8, 0xed,
0xdb, 0xed, 0xee, 0xdd, 0x4a, 0xfb, 0xfb, 0xfd, 0x76, 0xef, 0xa0, 0x2f, 0x51, 0xf1, 0x5c, 0x46,
0x38, 0x12, 0x92, 0x6b, 0x4e, 0x7a, 0x22, 0x4f, 0xf3, 0x49, 0x22, 0x45, 0xe4, 0xbf, 0x39, 0xe6,
0x38, 0x12, 0x92, 0x6b, 0x4e, 0x7a, 0x22, 0x4f, 0xf3, 0x49, 0x22, 0x45, 0xe4, 0xbf, 0x35, 0xe6,
0x7c, 0x9c, 0xe2, 0x89, 0x0d, 0x5c, 0xe4, 0x97, 0x27, 0x38, 0x11, 0x7a, 0xea, 0xf6, 0xf9, 0x6f,
0x2d, 0x06, 0x95, 0x96, 0x79, 0xa4, 0x8b, 0x68, 0x5f, 0x48, 0x7e, 0x9d, 0xc4, 0x28, 0x9d, 0x1d,
0x0c, 0x61, 0x70, 0x9e, 0x0b, 0xc1, 0xa5, 0x56, 0x5f, 0x21, 0xd3, 0xb9, 0xc4, 0x10, 0x5f, 0xe5,
0x2f, 0x06, 0x95, 0x96, 0x79, 0xa4, 0x8b, 0x68, 0x5f, 0x48, 0x7e, 0x9d, 0xc4, 0x28, 0x9d, 0x1d,
0x0c, 0x61, 0x70, 0x9e, 0x0b, 0xc1, 0xa5, 0x56, 0x5f, 0x23, 0xd3, 0xb9, 0xc4, 0x10, 0x5f, 0xe6,
0xa8, 0x34, 0xe9, 0x43, 0x3b, 0x89, 0x69, 0xeb, 0xb8, 0x35, 0xec, 0x85, 0xed, 0x24, 0x0e, 0x3e,
0x86, 0xc3, 0xda, 0x4e, 0x25, 0x78, 0xa6, 0x90, 0x1c, 0x01, 0xbc, 0x64, 0xaa, 0x88, 0xda, 0x23,
0xdd, 0x70, 0xce, 0x13, 0xfc, 0xd3, 0x86, 0xfd, 0x10, 0x59, 0x1c, 0x16, 0x15, 0x2d, 0xf9, 0x04,
0x81, 0xc3, 0xda, 0x4e, 0x25, 0x78, 0xa6, 0x90, 0x1c, 0x01, 0xbc, 0x60, 0xaa, 0x88, 0xda, 0x23,
0xdd, 0x70, 0xce, 0x13, 0xfc, 0xdb, 0x86, 0xfd, 0x10, 0x59, 0x1c, 0x16, 0x15, 0x2d, 0xf9, 0x04,
0x21, 0xb0, 0xa9, 0xa7, 0x02, 0x69, 0xdb, 0x7a, 0xec, 0xda, 0xf8, 0x32, 0x36, 0x41, 0xda, 0x71,
0x3e, 0xb3, 0x26, 0x03, 0xf0, 0x04, 0x93, 0x98, 0x69, 0xba, 0x69, 0xbd, 0x85, 0x45, 0x1e, 0x01,
0x3e, 0xb3, 0x26, 0x03, 0xf0, 0x04, 0x93, 0x98, 0x69, 0xba, 0x69, 0xbd, 0x85, 0x45, 0x1e, 0x02,
0x08, 0xc9, 0x05, 0x4a, 0x9d, 0xa0, 0xa2, 0x77, 0x8e, 0x5b, 0xc3, 0xed, 0xd3, 0xc3, 0x91, 0xc3,
0x63, 0x54, 0xe2, 0x31, 0x3a, 0xb7, 0x78, 0x84, 0x73, 0x5b, 0x49, 0x00, 0x3b, 0x31, 0x0a, 0xcc,
0x62, 0xcc, 0x22, 0x73, 0xd4, 0x3b, 0xee, 0x0c, 0x7b, 0x61, 0xc5, 0x47, 0x7c, 0xe8, 0x96, 0xd8,
0xd1, 0x2d, 0xfb, 0xd9, 0x99, 0x4d, 0x28, 0x6c, 0x5d, 0xa3, 0x54, 0x09, 0xcf, 0x68, 0xd7, 0x86,
0x4a, 0x93, 0xbc, 0x07, 0x77, 0x59, 0x14, 0xa1, 0xd0, 0xe7, 0x18, 0x49, 0xd4, 0x8a, 0xf6, 0x2c,
0x3a, 0x55, 0x27, 0x39, 0x83, 0x43, 0x16, 0xc7, 0x89, 0x4e, 0x78, 0xc6, 0x52, 0xe7, 0xfc, 0x36,
0x4a, 0x93, 0xbc, 0x0f, 0x77, 0x59, 0x14, 0xa1, 0xd0, 0xe7, 0x18, 0x49, 0xd4, 0x8a, 0xf6, 0x2c,
0x3a, 0x55, 0x27, 0x39, 0x83, 0x43, 0x16, 0xc7, 0x89, 0x4e, 0x78, 0xc6, 0x52, 0xe7, 0xfc, 0x2e,
0xd7, 0x22, 0xd7, 0x8a, 0x82, 0xfd, 0x95, 0x65, 0x61, 0xf3, 0x65, 0x96, 0x26, 0x4c, 0xa1, 0xa2,
0xdb, 0x76, 0x67, 0x69, 0x06, 0x0c, 0x0e, 0xaa, 0x98, 0x17, 0x64, 0xed, 0x41, 0x27, 0x97, 0x59,
0x81, 0xba, 0x59, 0x2e, 0xc0, 0xd6, 0x5e, 0x19, 0xb6, 0xe0, 0xef, 0x2e, 0x1c, 0x86, 0x38, 0x4e,
0x81, 0xba, 0x59, 0x2e, 0xc0, 0xd6, 0x5e, 0x19, 0xb6, 0xe0, 0x9f, 0x2e, 0x1c, 0x86, 0x38, 0x4e,
0x94, 0x46, 0xb9, 0xc8, 0x6d, 0xc9, 0x65, 0xab, 0x81, 0xcb, 0x76, 0x23, 0x97, 0x9d, 0x0a, 0x97,
0x03, 0xf0, 0xa2, 0x5c, 0x69, 0x3e, 0xb1, 0x1c, 0x77, 0xc3, 0xc2, 0x22, 0x27, 0xe0, 0xf1, 0x8b,
0xdf, 0x30, 0xd2, 0xb7, 0xf1, 0x5b, 0x6c, 0x33, 0x08, 0x99, 0x90, 0x39, 0xe1, 0xd9, 0x4c, 0xa5,
0x59, 0x63, 0x7d, 0xeb, 0x16, 0xd6, 0xbb, 0x0b, 0xac, 0x0b, 0x38, 0x28, 0xc0, 0x98, 0x3e, 0x99,
0xcf, 0xd3, 0x3b, 0xee, 0x0c, 0xb7, 0x4f, 0x3f, 0x1d, 0xcd, 0x1a, 0x76, 0xb4, 0x04, 0xa4, 0xd1,
0x8b, 0x86, 0xe3, 0x4f, 0x33, 0x2d, 0xa7, 0x61, 0x63, 0x66, 0xf2, 0x00, 0xf6, 0x63, 0x4c, 0x51,
0xe3, 0x97, 0x78, 0xc9, 0x4d, 0x03, 0x8a, 0x94, 0x45, 0x48, 0xc1, 0xd6, 0xd5, 0x14, 0x9a, 0x57,
0xe6, 0x76, 0x4d, 0x99, 0xc9, 0x38, 0xe3, 0x12, 0x1f, 0xbf, 0x64, 0xd9, 0x18, 0x15, 0xdd, 0xb1,
0xdf, 0x31, 0xd2, 0xb7, 0xf1, 0x5b, 0x6c, 0x33, 0x08, 0x99, 0x90, 0x39, 0xe1, 0xd9, 0x4c, 0xa5,
0x59, 0x63, 0x7d, 0xeb, 0x16, 0xd6, 0xbb, 0x0b, 0xac, 0x0b, 0x38, 0x28, 0xc0, 0x98, 0x3e, 0x9e,
0xcf, 0xd3, 0x3b, 0xee, 0x0c, 0xb7, 0x4f, 0x3f, 0x1b, 0xcd, 0x1a, 0x76, 0xb4, 0x04, 0xa4, 0xd1,
0xf3, 0x86, 0xe3, 0x4f, 0x32, 0x2d, 0xa7, 0x61, 0x63, 0x66, 0x72, 0x1f, 0xf6, 0x63, 0x4c, 0x51,
0xe3, 0x57, 0x78, 0xc9, 0x4d, 0x03, 0x8a, 0x94, 0x45, 0x48, 0xc1, 0xd6, 0xd5, 0x14, 0x9a, 0x57,
0xe6, 0x76, 0x4d, 0x99, 0xc9, 0x38, 0xe3, 0x12, 0x1f, 0xbd, 0x60, 0xd9, 0x18, 0x15, 0xdd, 0xb1,
0xe5, 0x57, 0x9d, 0x75, 0xfd, 0xde, 0x5d, 0x53, 0xbf, 0xfd, 0x95, 0xf5, 0xbb, 0x5b, 0xd1, 0xaf,
0x41, 0x3e, 0x99, 0x98, 0xf1, 0xf1, 0x2c, 0xa6, 0x7b, 0x0e, 0xf9, 0xd2, 0x26, 0x3f, 0x41, 0xdf,
0xc9, 0xe1, 0xfb, 0x64, 0x82, 0xdc, 0x7c, 0xe6, 0x0d, 0x2b, 0x86, 0x87, 0x2b, 0x60, 0xfe, 0xb8,
0x72, 0x30, 0x5c, 0x48, 0x44, 0x3e, 0x07, 0xbf, 0x01, 0xc7, 0x27, 0x78, 0x99, 0x64, 0x18, 0x53,
0x62, 0xab, 0xbf, 0x61, 0x07, 0xf9, 0x08, 0xee, 0xa9, 0x62, 0x4c, 0xbe, 0x60, 0x52, 0x27, 0x2c,
0xfd, 0x81, 0xa5, 0x39, 0x2a, 0xba, 0x6f, 0x8f, 0x36, 0x07, 0x8d, 0xda, 0x25, 0x4e, 0xb8, 0x46,
0x7a, 0xcf, 0xa9, 0xdd, 0x59, 0xfe, 0x07, 0x70, 0xd0, 0xa4, 0x11, 0xd3, 0x49, 0xb9, 0xcc, 0x14,
0x6d, 0x59, 0xcc, 0xec, 0xda, 0xff, 0x11, 0xfa, 0xd5, 0xda, 0x6c, 0x0f, 0x49, 0x64, 0xba, 0xec,
0x41, 0x3e, 0x99, 0x98, 0xf1, 0xf1, 0x34, 0xa6, 0x7b, 0x0e, 0xf9, 0xd2, 0x26, 0x3f, 0x43, 0xdf,
0xc9, 0xe1, 0x87, 0x64, 0x82, 0xdc, 0x7c, 0xe6, 0x0d, 0x2b, 0x86, 0x07, 0x2b, 0x60, 0xfe, 0xa8,
0x72, 0x30, 0x5c, 0x48, 0x44, 0xbe, 0x00, 0xbf, 0x01, 0xc7, 0xc7, 0x78, 0x99, 0x64, 0x18, 0x53,
0x62, 0xab, 0xbf, 0x61, 0x07, 0xf9, 0x18, 0xde, 0x54, 0xc5, 0x98, 0x7c, 0xce, 0xa4, 0x4e, 0x58,
0xfa, 0x23, 0x4b, 0x73, 0x54, 0x74, 0xdf, 0x1e, 0x6d, 0x0e, 0x1a, 0xb5, 0x4b, 0x9c, 0x70, 0x8d,
0xf4, 0xc0, 0xa9, 0xdd, 0x59, 0xfe, 0x87, 0x70, 0xd0, 0xa4, 0x11, 0xd3, 0x49, 0xb9, 0xcc, 0x14,
0x6d, 0x59, 0xcc, 0xec, 0xda, 0xff, 0x09, 0xfa, 0xd5, 0xda, 0x6c, 0x0f, 0x49, 0x64, 0xba, 0xec,
0xc2, 0xc2, 0x32, 0xfe, 0x5c, 0xc4, 0xc6, 0xef, 0x3a, 0xb1, 0xb0, 0x8c, 0xdf, 0x55, 0x56, 0xf6,
0xa2, 0xb3, 0xfc, 0xdf, 0x5b, 0x70, 0x7f, 0xa9, 0x54, 0xcd, 0x40, 0xb9, 0xc2, 0x69, 0x39, 0x50,
0xae, 0x70, 0x4a, 0x9e, 0xc3, 0x9d, 0x6b, 0x53, 0x57, 0x31, 0x4b, 0x1e, 0xbd, 0x66, 0x27, 0x84,
0x2e, 0xcb, 0x27, 0xed, 0xb3, 0x56, 0xf0, 0x57, 0x07, 0x68, 0xfd, 0xec, 0xd2, 0x91, 0xe6, 0x6e,
0x96, 0xf6, 0xec, 0x66, 0xf9, 0x6f, 0x6a, 0x74, 0x56, 0x9b, 0x1a, 0x03, 0xf0, 0x94, 0x66, 0x17,
0x29, 0x96, 0xe3, 0xc7, 0x59, 0x46, 0xaf, 0x6e, 0x65, 0xee, 0x17, 0xab, 0xd7, 0xc2, 0x24, 0xaf,
0x96, 0x4c, 0x03, 0xcf, 0x4e, 0x83, 0xcf, 0x6e, 0xc4, 0xc0, 0xd5, 0xb1, 0xee, 0x38, 0x58, 0x4b,
0x1d, 0x7f, 0xac, 0xc9, 0xe1, 0x37, 0x55, 0x0e, 0xcf, 0x5e, 0xf7, 0xff, 0xe7, 0x49, 0x44, 0x38,
0x5a, 0x3c, 0x5b, 0xcc, 0x81, 0xf2, 0xd6, 0xa8, 0x33, 0xf9, 0x10, 0xb6, 0x78, 0x31, 0x4a, 0x6e,
0xb9, 0x99, 0xca, 0x7d, 0xa7, 0x7f, 0x6e, 0xc2, 0x6e, 0x99, 0xff, 0x39, 0xcf, 0x12, 0xcd, 0x25,
0xf9, 0x19, 0x76, 0x17, 0x5e, 0x2f, 0xe4, 0x9d, 0xb9, 0x92, 0x9a, 0xdf, 0x40, 0x7e, 0x70, 0xd3,
0x16, 0x57, 0x74, 0xb0, 0x41, 0xbe, 0x00, 0xef, 0x59, 0x76, 0xcd, 0xaf, 0x90, 0xd0, 0xb9, 0xfd,
0xce, 0x55, 0x66, 0xba, 0xdf, 0x10, 0x99, 0x25, 0xf8, 0x1a, 0x76, 0xce, 0xb5, 0x44, 0x36, 0xf9,
0x5f, 0x69, 0x1e, 0xb4, 0xc8, 0x77, 0xb0, 0x33, 0x7f, 0xe7, 0x93, 0xa3, 0x0a, 0x6b, 0xb5, 0x07,
0x98, 0xff, 0xf6, 0xd2, 0xf8, 0xec, 0xdf, 0x7e, 0x81, 0xbd, 0x45, 0xce, 0x48, 0x70, 0x7b, 0x43,
0xfb, 0xef, 0xae, 0x20, 0x98, 0x60, 0x83, 0xfc, 0x5a, 0x7f, 0x41, 0x94, 0x57, 0xc3, 0xfb, 0x37,
0x64, 0xa8, 0xca, 0xc6, 0x1f, 0xd4, 0x34, 0xf1, 0xd4, 0xbc, 0x88, 0x83, 0x8d, 0x0b, 0xcf, 0x7a,
0x3e, 0xfc, 0x37, 0x00, 0x00, 0xff, 0xff, 0x7a, 0x67, 0xe8, 0xd7, 0x4e, 0x0b, 0x00, 0x00,
0xa2, 0xb3, 0xfc, 0x3f, 0x5a, 0x70, 0x6f, 0xa9, 0x54, 0xcd, 0x40, 0xb9, 0xc2, 0x69, 0x39, 0x50,
0xae, 0x70, 0x4a, 0x9e, 0xc1, 0x9d, 0x6b, 0x53, 0x57, 0x31, 0x4b, 0x1e, 0xbe, 0x62, 0x27, 0x84,
0x2e, 0xcb, 0xa7, 0xed, 0xb3, 0x56, 0xf0, 0x77, 0x07, 0x68, 0xfd, 0xec, 0xd2, 0x91, 0xe6, 0x6e,
0x96, 0xf6, 0xec, 0x66, 0xf9, 0x7f, 0x6a, 0x74, 0x56, 0x9b, 0x1a, 0x03, 0xf0, 0x94, 0x66, 0x17,
0x29, 0x96, 0xe3, 0xc7, 0x59, 0x46, 0xaf, 0x6e, 0x65, 0xee, 0x17, 0xab, 0xd7, 0xc2, 0x24, 0x2f,
0x97, 0x4c, 0x03, 0xcf, 0x4e, 0x83, 0xcf, 0x6f, 0xc4, 0xc0, 0xd5, 0xb1, 0xee, 0x38, 0x58, 0x4b,
0x1d, 0x7f, 0xae, 0xc9, 0xe1, 0xb7, 0x55, 0x0e, 0xcf, 0x5e, 0xf5, 0xff, 0xe7, 0x49, 0x44, 0x38,
0x5a, 0x3c, 0x5b, 0xcc, 0x81, 0xf2, 0xd6, 0xa8, 0x33, 0xf9, 0x00, 0xb6, 0x78, 0x31, 0x4a, 0x6e,
0xb9, 0x99, 0xca, 0x7d, 0xa7, 0x7f, 0x6d, 0xc2, 0x6e, 0x99, 0xff, 0x19, 0xcf, 0x12, 0xcd, 0x25,
0xf9, 0x05, 0x76, 0x17, 0x5e, 0x2f, 0xe4, 0xdd, 0xb9, 0x92, 0x9a, 0xdf, 0x40, 0x7e, 0x70, 0xd3,
0x16, 0x57, 0x74, 0xb0, 0x41, 0xbe, 0x04, 0xef, 0x69, 0x76, 0xcd, 0xaf, 0x90, 0xd0, 0xb9, 0xfd,
0xce, 0x55, 0x66, 0xba, 0xd7, 0x10, 0x99, 0x25, 0xf8, 0x06, 0x76, 0xce, 0xb5, 0x44, 0x36, 0x79,
0xad, 0x34, 0xf7, 0x5b, 0xe4, 0x7b, 0xd8, 0x99, 0xbf, 0xf3, 0xc9, 0x51, 0x85, 0xb5, 0xda, 0x03,
0xcc, 0x7f, 0x67, 0x69, 0x7c, 0xf6, 0x6f, 0xbf, 0xc2, 0xde, 0x22, 0x67, 0x24, 0xb8, 0xbd, 0xa1,
0xfd, 0xf7, 0x56, 0x10, 0x4c, 0xb0, 0x41, 0x7e, 0xab, 0xbf, 0x20, 0xca, 0xab, 0xe1, 0x83, 0x1b,
0x32, 0x54, 0x65, 0xe3, 0x0f, 0x6a, 0x9a, 0x78, 0x62, 0x5e, 0xc4, 0xc1, 0xc6, 0x85, 0x67, 0x3d,
0x1f, 0xfd, 0x17, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xbf, 0x6d, 0x72, 0x4e, 0x0b, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.

View file

@ -160,7 +160,8 @@ disable=print-statement,
no-self-use,
unused-import,
unsubscriptable-object,
line-too-long
line-too-long,
too-many-lines
# Enable the message, report, category or checker with the given id(s). You can

View file

@ -13,6 +13,9 @@
# limitations under the License.
"""The Resource module, containing all resource-related definitions."""
import asyncio
from typing import Optional, List, Any, Mapping, Union, Callable, TYPE_CHECKING, cast
import copy
@ -594,7 +597,9 @@ class Resource:
name: str,
custom: bool,
props: Optional['Inputs'] = None,
opts: Optional[ResourceOptions] = None) -> None:
opts: Optional[ResourceOptions] = None,
remote: bool = False,
dependency: bool = False) -> None:
"""
:param str t: The type of this resource.
:param str name: The name of this resource.
@ -602,7 +607,15 @@ class Resource:
:param Optional[dict] props: An optional list of input properties to use as inputs for the resource.
:param Optional[ResourceOptions] opts: Optional set of :class:`pulumi.ResourceOptions` to use for this
resource.
:param bool remote: True if this is a remote component resource.
:param bool dependency: True if this is a synthetic resource used internally for dependency tracking.
"""
if dependency:
self._protect = False
self._providers = {}
return
if props is None:
props = {}
if not t:
@ -699,13 +712,13 @@ class Resource:
alias, name, t, opts.parent))
if opts.id is not None:
# If this resource already exists, read its state rather than registering it anew.
# If this is a custom resource that already exists, read its state from the provider.
if not custom:
raise Exception(
"Cannot read an existing resource unless it has a custom provider")
read_resource(cast('CustomResource', self), t, name, props, opts)
else:
register_resource(self, t, name, custom, props, opts)
register_resource(self, t, name, custom, remote, DependencyResource, props, opts)
@property
def urn(self) -> 'Output[str]':
@ -790,15 +803,17 @@ class CustomResource(Resource):
t: str,
name: str,
props: Optional[dict] = None,
opts: Optional[ResourceOptions] = None) -> None:
opts: Optional[ResourceOptions] = None,
dependency: bool = False) -> None:
"""
:param str t: The type of this resource.
:param str name: The name of this resource.
:param Optional[dict] props: An optional list of input properties to use as inputs for the resource.
:param Optional[ResourceOptions] opts: Optional set of :class:`pulumi.ResourceOptions` to use for this
resource.
:param bool dependency: True if this is a synthetic resource used internally for dependency tracking.
"""
Resource.__init__(self, t, name, True, props, opts)
Resource.__init__(self, t, name, True, props, opts, False, dependency)
self.__pulumi_type = t
@property
@ -821,16 +836,18 @@ class ComponentResource(Resource):
t: str,
name: str,
props: Optional[dict] = None,
opts: Optional[ResourceOptions] = None) -> None:
opts: Optional[ResourceOptions] = None,
remote: bool = False) -> None:
"""
:param str t: The type of this resource.
:param str name: The name of this resource.
:param Optional[dict] props: An optional list of input properties to use as inputs for the resource.
:param Optional[ResourceOptions] opts: Optional set of :class:`pulumi.ResourceOptions` to use for this
resource.
:param bool remote: True if this is a remote component resource.
"""
Resource.__init__(self, t, name, False, props, opts)
self.id = None
Resource.__init__(self, t, name, False, props, opts, remote)
self.__dict__["id"] = None
def register_outputs(self, outputs):
"""
@ -858,13 +875,15 @@ class ProviderResource(CustomResource):
pkg: str,
name: str,
props: Optional[dict] = None,
opts: Optional[ResourceOptions] = None) -> None:
opts: Optional[ResourceOptions] = None,
dependency: bool = False) -> None:
"""
:param str pkg: The package type of this provider resource.
:param str name: The name of this resource.
:param Optional[dict] props: An optional list of input properties to use as inputs for the resource.
:param Optional[ResourceOptions] opts: Optional set of :class:`pulumi.ResourceOptions` to use for this
resource.
:param bool dependency: True if this is a synthetic resource used internally for dependency tracking.
"""
if opts is not None and opts.provider is not None:
@ -872,10 +891,63 @@ class ProviderResource(CustomResource):
"Explicit providers may not be used with provider resources")
# Provider resources are given a well-known type, prefixed with "pulumi:providers".
CustomResource.__init__(
self, f"pulumi:providers:{pkg}", name, props, opts)
self, f"pulumi:providers:{pkg}", name, props, opts, dependency)
self.package = pkg
class DependencyResource(CustomResource):
"""
A DependencyResource is a resource that is used to indicate that an Output has a dependency on a particular
resource. These resources are only created when dealing with remote component resources.
"""
def __init__(self, urn: str) -> None:
super().__init__(t="", name="", props={}, opts=None, dependency=True)
from . import Output # pylint: disable=import-outside-toplevel
urn_future: asyncio.Future[str] = asyncio.Future()
urn_known: asyncio.Future[bool] = asyncio.Future()
urn_secret: asyncio.Future[bool] = asyncio.Future()
urn_future.set_result(urn)
urn_known.set_result(True)
urn_secret.set_result(False)
self.__dict__["urn"] = Output({self}, urn_future, urn_known, urn_secret)
class DependencyProviderResource(ProviderResource):
"""
A DependencyProviderResource is a resource that is used by the provider SDK as a stand-in for a provider that
is only used for its reference. Its only valid properties are its URN and ID.
"""
def __init__(self, ref: str) -> None:
super().__init__(pkg="", name="", props={}, opts=None, dependency=True)
# Parse the URN and ID out of the provider reference.
last_sep = ref.rindex("::")
ref_urn = ref[:last_sep]
ref_id = ref[last_sep+2:]
from . import Output # pylint: disable=import-outside-toplevel
urn_future: asyncio.Future[str] = asyncio.Future()
urn_known: asyncio.Future[bool] = asyncio.Future()
urn_secret: asyncio.Future[bool] = asyncio.Future()
urn_future.set_result(ref_urn)
urn_known.set_result(True)
urn_secret.set_result(False)
self.__dict__["urn"] = Output({self}, urn_future, urn_known, urn_secret)
id_future: asyncio.Future[str] = asyncio.Future()
id_known: asyncio.Future[bool] = asyncio.Future()
id_secret: asyncio.Future[bool] = asyncio.Future()
id_future.set_result(ref_id)
id_known.set_result(True)
id_secret.set_result(False)
self.__dict__["id"] = Output({self}, id_future, id_known, id_secret)
def export(name: str, value: Any):
"""
Exports a named stack output.

View file

@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
package='pulumirpc',
syntax='proto3',
serialized_options=None,
serialized_pb=b'\n\x0eresource.proto\x12\tpulumirpc\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x0eprovider.proto\"$\n\x16SupportsFeatureRequest\x12\n\n\x02id\x18\x01 \x01(\t\"-\n\x17SupportsFeatureResponse\x12\x12\n\nhasSupport\x18\x01 \x01(\x08\"\xfc\x01\n\x13ReadResourceRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x0e\n\x06parent\x18\x04 \x01(\t\x12+\n\nproperties\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x14\n\x0c\x64\x65pendencies\x18\x06 \x03(\t\x12\x10\n\x08provider\x18\x07 \x01(\t\x12\x0f\n\x07version\x18\x08 \x01(\t\x12\x15\n\racceptSecrets\x18\t \x01(\x08\x12\x1f\n\x17\x61\x64\x64itionalSecretOutputs\x18\n \x03(\t\x12\x0f\n\x07\x61liases\x18\x0b \x03(\t\"P\n\x14ReadResourceResponse\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12+\n\nproperties\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\"\xaf\x06\n\x17RegisterResourceRequest\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06parent\x18\x03 \x01(\t\x12\x0e\n\x06\x63ustom\x18\x04 \x01(\x08\x12\'\n\x06object\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0f\n\x07protect\x18\x06 \x01(\x08\x12\x14\n\x0c\x64\x65pendencies\x18\x07 \x03(\t\x12\x10\n\x08provider\x18\x08 \x01(\t\x12Z\n\x14propertyDependencies\x18\t \x03(\x0b\x32<.pulumirpc.RegisterResourceRequest.PropertyDependenciesEntry\x12\x1b\n\x13\x64\x65leteBeforeReplace\x18\n \x01(\x08\x12\x0f\n\x07version\x18\x0b \x01(\t\x12\x15\n\rignoreChanges\x18\x0c \x03(\t\x12\x15\n\racceptSecrets\x18\r \x01(\x08\x12\x1f\n\x17\x61\x64\x64itionalSecretOutputs\x18\x0e \x03(\t\x12\x0f\n\x07\x61liases\x18\x0f \x03(\t\x12\x10\n\x08importId\x18\x10 \x01(\t\x12I\n\x0e\x63ustomTimeouts\x18\x11 \x01(\x0b\x32\x31.pulumirpc.RegisterResourceRequest.CustomTimeouts\x12\"\n\x1a\x64\x65leteBeforeReplaceDefined\x18\x12 \x01(\x08\x12\x1d\n\x15supportsPartialValues\x18\x13 \x01(\x08\x12\x0e\n\x06remote\x18\x15 \x01(\x08\x1a$\n\x14PropertyDependencies\x12\x0c\n\x04urns\x18\x01 \x03(\t\x1a@\n\x0e\x43ustomTimeouts\x12\x0e\n\x06\x63reate\x18\x01 \x01(\t\x12\x0e\n\x06update\x18\x02 \x01(\t\x12\x0e\n\x06\x64\x65lete\x18\x03 \x01(\t\x1at\n\x19PropertyDependenciesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x46\n\x05value\x18\x02 \x01(\x0b\x32\x37.pulumirpc.RegisterResourceRequest.PropertyDependencies:\x02\x38\x01\"\xf7\x02\n\x18RegisterResourceResponse\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12\'\n\x06object\x18\x03 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0e\n\x06stable\x18\x04 \x01(\x08\x12\x0f\n\x07stables\x18\x05 \x03(\t\x12[\n\x14propertyDependencies\x18\x06 \x03(\x0b\x32=.pulumirpc.RegisterResourceResponse.PropertyDependenciesEntry\x1a$\n\x14PropertyDependencies\x12\x0c\n\x04urns\x18\x01 \x03(\t\x1au\n\x19PropertyDependenciesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12G\n\x05value\x18\x02 \x01(\x0b\x32\x38.pulumirpc.RegisterResourceResponse.PropertyDependencies:\x02\x38\x01\"W\n\x1eRegisterResourceOutputsRequest\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12(\n\x07outputs\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct2\x89\x04\n\x0fResourceMonitor\x12Z\n\x0fSupportsFeature\x12!.pulumirpc.SupportsFeatureRequest\x1a\".pulumirpc.SupportsFeatureResponse\"\x00\x12?\n\x06Invoke\x12\x18.pulumirpc.InvokeRequest\x1a\x19.pulumirpc.InvokeResponse\"\x00\x12G\n\x0cStreamInvoke\x12\x18.pulumirpc.InvokeRequest\x1a\x19.pulumirpc.InvokeResponse\"\x00\x30\x01\x12Q\n\x0cReadResource\x12\x1e.pulumirpc.ReadResourceRequest\x1a\x1f.pulumirpc.ReadResourceResponse\"\x00\x12]\n\x10RegisterResource\x12\".pulumirpc.RegisterResourceRequest\x1a#.pulumirpc.RegisterResourceResponse\"\x00\x12^\n\x17RegisterResourceOutputs\x12).pulumirpc.RegisterResourceOutputsRequest\x1a\x16.google.protobuf.Empty\"\x00\x62\x06proto3'
serialized_pb=b'\n\x0eresource.proto\x12\tpulumirpc\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x0eprovider.proto\"$\n\x16SupportsFeatureRequest\x12\n\n\x02id\x18\x01 \x01(\t\"-\n\x17SupportsFeatureResponse\x12\x12\n\nhasSupport\x18\x01 \x01(\x08\"\xfc\x01\n\x13ReadResourceRequest\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x0e\n\x06parent\x18\x04 \x01(\t\x12+\n\nproperties\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x14\n\x0c\x64\x65pendencies\x18\x06 \x03(\t\x12\x10\n\x08provider\x18\x07 \x01(\t\x12\x0f\n\x07version\x18\x08 \x01(\t\x12\x15\n\racceptSecrets\x18\t \x01(\x08\x12\x1f\n\x17\x61\x64\x64itionalSecretOutputs\x18\n \x03(\t\x12\x0f\n\x07\x61liases\x18\x0b \x03(\t\"P\n\x14ReadResourceResponse\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12+\n\nproperties\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\"\xaf\x06\n\x17RegisterResourceRequest\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06parent\x18\x03 \x01(\t\x12\x0e\n\x06\x63ustom\x18\x04 \x01(\x08\x12\'\n\x06object\x18\x05 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0f\n\x07protect\x18\x06 \x01(\x08\x12\x14\n\x0c\x64\x65pendencies\x18\x07 \x03(\t\x12\x10\n\x08provider\x18\x08 \x01(\t\x12Z\n\x14propertyDependencies\x18\t \x03(\x0b\x32<.pulumirpc.RegisterResourceRequest.PropertyDependenciesEntry\x12\x1b\n\x13\x64\x65leteBeforeReplace\x18\n \x01(\x08\x12\x0f\n\x07version\x18\x0b \x01(\t\x12\x15\n\rignoreChanges\x18\x0c \x03(\t\x12\x15\n\racceptSecrets\x18\r \x01(\x08\x12\x1f\n\x17\x61\x64\x64itionalSecretOutputs\x18\x0e \x03(\t\x12\x0f\n\x07\x61liases\x18\x0f \x03(\t\x12\x10\n\x08importId\x18\x10 \x01(\t\x12I\n\x0e\x63ustomTimeouts\x18\x11 \x01(\x0b\x32\x31.pulumirpc.RegisterResourceRequest.CustomTimeouts\x12\"\n\x1a\x64\x65leteBeforeReplaceDefined\x18\x12 \x01(\x08\x12\x1d\n\x15supportsPartialValues\x18\x13 \x01(\x08\x12\x0e\n\x06remote\x18\x14 \x01(\x08\x1a$\n\x14PropertyDependencies\x12\x0c\n\x04urns\x18\x01 \x03(\t\x1a@\n\x0e\x43ustomTimeouts\x12\x0e\n\x06\x63reate\x18\x01 \x01(\t\x12\x0e\n\x06update\x18\x02 \x01(\t\x12\x0e\n\x06\x64\x65lete\x18\x03 \x01(\t\x1at\n\x19PropertyDependenciesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x46\n\x05value\x18\x02 \x01(\x0b\x32\x37.pulumirpc.RegisterResourceRequest.PropertyDependencies:\x02\x38\x01\"\xf7\x02\n\x18RegisterResourceResponse\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12\'\n\x06object\x18\x03 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0e\n\x06stable\x18\x04 \x01(\x08\x12\x0f\n\x07stables\x18\x05 \x03(\t\x12[\n\x14propertyDependencies\x18\x06 \x03(\x0b\x32=.pulumirpc.RegisterResourceResponse.PropertyDependenciesEntry\x1a$\n\x14PropertyDependencies\x12\x0c\n\x04urns\x18\x01 \x03(\t\x1au\n\x19PropertyDependenciesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12G\n\x05value\x18\x02 \x01(\x0b\x32\x38.pulumirpc.RegisterResourceResponse.PropertyDependencies:\x02\x38\x01\"W\n\x1eRegisterResourceOutputsRequest\x12\x0b\n\x03urn\x18\x01 \x01(\t\x12(\n\x07outputs\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct2\x89\x04\n\x0fResourceMonitor\x12Z\n\x0fSupportsFeature\x12!.pulumirpc.SupportsFeatureRequest\x1a\".pulumirpc.SupportsFeatureResponse\"\x00\x12?\n\x06Invoke\x12\x18.pulumirpc.InvokeRequest\x1a\x19.pulumirpc.InvokeResponse\"\x00\x12G\n\x0cStreamInvoke\x12\x18.pulumirpc.InvokeRequest\x1a\x19.pulumirpc.InvokeResponse\"\x00\x30\x01\x12Q\n\x0cReadResource\x12\x1e.pulumirpc.ReadResourceRequest\x1a\x1f.pulumirpc.ReadResourceResponse\"\x00\x12]\n\x10RegisterResource\x12\".pulumirpc.RegisterResourceRequest\x1a#.pulumirpc.RegisterResourceResponse\"\x00\x12^\n\x17RegisterResourceOutputs\x12).pulumirpc.RegisterResourceOutputsRequest\x1a\x16.google.protobuf.Empty\"\x00\x62\x06proto3'
,
dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,provider__pb2.DESCRIPTOR,])
@ -482,7 +482,7 @@ _REGISTERRESOURCEREQUEST = _descriptor.Descriptor(
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='remote', full_name='pulumirpc.RegisterResourceRequest.remote', index=19,
number=21, type=8, cpp_type=7, label=1,
number=20, type=8, cpp_type=7, label=1,
has_default_value=False, default_value=False,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,

View file

@ -228,7 +228,7 @@ def read_resource(res: 'CustomResource', ty: str, name: str, props: 'Inputs', op
def do_rpc_call():
if monitor is None:
# If no monitor is available, we'll need to fake up a response, for testing.
return RegisterResponse(mock_urn, None, resolver.serialized_props)
return RegisterResponse(mock_urn, None, resolver.serialized_props, None)
# If there is a monitor available, make the true RPC request to the engine.
try:
@ -256,19 +256,26 @@ def read_resource(res: 'CustomResource', ty: str, name: str, props: 'Inputs', op
log.debug(f"resource read successful: ty={ty}, urn={resp.urn}")
resolve_urn(resp.urn)
resolve_id(resolved_id, True, None) # Read IDs are always known.
await rpc.resolve_outputs(res, resolver.serialized_props, resp.properties, resolvers)
await rpc.resolve_outputs(res, resolver.serialized_props, resp.properties, {}, resolvers)
asyncio.ensure_future(RPC_MANAGER.do_rpc("read resource", do_read)())
def register_resource(res: 'Resource', ty: str, name: str, custom: bool, props: 'Inputs', opts: Optional['ResourceOptions']) -> None:
def register_resource(res: 'Resource',
ty: str,
name: str,
custom: bool,
remote: bool,
new_dependency: Callable[[str], 'Resource'],
props: 'Inputs',
opts: Optional['ResourceOptions']) -> None:
"""
Registers a new resource object with a given type t and name. It returns the
auto-generated URN and the ID that will resolve after the deployment has completed. All
properties will be initialized to property objects that the registration operation will resolve
at the right time (or remain unresolved for deployments).
"""
log.debug(f"registering resource: ty={ty}, name={name}, custom={custom}")
log.debug(f"registering resource: ty={ty}, name={name}, custom={custom}, remote={remote}")
monitor = settings.get_monitor()
from .. import Output # pylint: disable=import-outside-toplevel
@ -381,6 +388,7 @@ def register_resource(res: 'Resource', ty: str, name: str, custom: bool, props:
customTimeouts=custom_timeouts,
aliases=resolver.aliases,
supportsPartialValues=True,
remote=remote,
)
from ..resource import create_urn # pylint: disable=import-outside-toplevel
@ -389,7 +397,7 @@ def register_resource(res: 'Resource', ty: str, name: str, custom: bool, props:
def do_rpc_call():
if monitor is None:
# If no monitor is available, we'll need to fake up a response, for testing.
return RegisterResponse(mock_urn, None, resolver.serialized_props)
return RegisterResponse(mock_urn, None, resolver.serialized_props, None)
# If there is a monitor available, make the true RPC request to the engine.
try:
@ -423,7 +431,15 @@ def register_resource(res: 'Resource', ty: str, name: str, custom: bool, props:
is_known = bool(resp.id)
resolve_id(resp.id, is_known, None)
await rpc.resolve_outputs(res, resolver.serialized_props, resp.object, resolvers)
deps = {}
rpc_deps = resp.propertyDependencies
if rpc_deps:
for k, v in rpc_deps.items():
urns = list(v.urns)
deps[k] = set(map(new_dependency, urns))
await rpc.resolve_outputs(res, resolver.serialized_props, resp.object, deps, resolvers)
asyncio.ensure_future(RPC_MANAGER.do_rpc(
"register resource", do_register)())
@ -464,13 +480,26 @@ def register_resource_outputs(res: 'Resource', outputs: 'Union[Inputs, Output[In
"register resource outputs", do_register_resource_outputs)())
class PropertyDependencies:
urns: List[str]
def __init__(self, urns: List[str]):
self.urns = urns
class RegisterResponse:
urn: str
id: str
object: struct_pb2.Struct
propertyDependencies: Dict[str, PropertyDependencies]
# pylint: disable=redefined-builtin
def __init__(self, urn: str, id: str, object: struct_pb2.Struct):
def __init__(self,
urn: str,
id: str,
object: struct_pb2.Struct,
propertyDependencies: Dict[str, PropertyDependencies]):
self.urn = urn
self.id = id
self.object = object
self.propertyDependencies = propertyDependencies

View file

@ -20,7 +20,7 @@ import asyncio
from collections import abc
import functools
import inspect
from typing import List, Any, Callable, Dict, Mapping, Optional, Sequence, TYPE_CHECKING, cast
from typing import List, Any, Callable, Dict, Mapping, Optional, Sequence, Set, TYPE_CHECKING, cast
from google.protobuf import struct_pb2
import six
@ -329,7 +329,7 @@ def deserialize_property(value: Any, keep_unknowns: Optional[bool] = None) -> An
return value
Resolver = Callable[[Any, bool, bool, Optional[Exception]], None]
Resolver = Callable[[Any, bool, bool, Optional[Set['Resource']], Optional[Exception]], None]
"""
A Resolver is a function that takes four arguments:
1. A value, which represents the "resolved" value of a particular output (from the engine)
@ -355,14 +355,24 @@ def transfer_properties(res: 'Resource', props: 'Inputs') -> Dict[str, Resolver]
resolve_value: 'asyncio.Future' = asyncio.Future()
resolve_is_known: 'asyncio.Future' = asyncio.Future()
resolve_is_secret: 'asyncio.Future' = asyncio.Future()
resolve_deps: 'asyncio.Future' = asyncio.Future()
def do_resolve(value_fut: 'asyncio.Future',
def do_resolve(r: 'Resource',
value_fut: 'asyncio.Future',
known_fut: 'asyncio.Future[bool]',
secret_fut: 'asyncio.Future[bool]',
deps_fut: 'asyncio.Future[Set[Resource]]',
value: Any,
is_known: bool,
is_secret: bool,
deps: Set['Resource'],
failed: Optional[Exception]):
# Create a union of deps and the resource.
deps_union = set(deps) if deps else set()
deps_union.add(r)
deps_fut.set_result(deps_union)
# Was an exception provided? If so, this is an abnormal (exceptional) resolution. Resolve the futures
# using set_exception so that any attempts to wait for their resolution will also fail.
if failed is not None:
@ -378,8 +388,8 @@ def transfer_properties(res: 'Resource', props: 'Inputs') -> Dict[str, Resolver]
# name before translation. When properties are returned from the engine, we must first translate the name
# using res.translate_output_property and then use *that* name to index into the resolvers table.
log.debug(f"adding resolver {name}")
resolvers[name] = functools.partial(do_resolve, resolve_value, resolve_is_known, resolve_is_secret)
res.__dict__[name] = Output({res}, resolve_value, resolve_is_known, resolve_is_secret)
resolvers[name] = functools.partial(do_resolve, res, resolve_value, resolve_is_known, resolve_is_secret, resolve_deps)
res.__dict__[name] = Output(resolve_deps, resolve_value, resolve_is_known, resolve_is_secret)
return resolvers
@ -497,6 +507,7 @@ def contains_unknowns(val: Any) -> bool:
async def resolve_outputs(res: 'Resource',
serialized_props: struct_pb2.Struct,
outputs: struct_pb2.Struct,
deps: Mapping[str, Set['Resource']],
resolvers: Dict[str, Resolver]):
# Produce a combined set of property states, starting with inputs and then applying
@ -559,18 +570,18 @@ async def resolve_outputs(res: 'Resource',
if not settings.is_dry_run():
# normal 'pulumi up'. resolve the output with the value we got back
# from the engine. That output can always run its .apply calls.
resolve(value, True, is_secret, None)
resolve(value, True, is_secret, deps.get(key), None)
else:
# We're previewing. If the engine was able to give us a reasonable value back,
# then use it. Otherwise, inform the Output that the value isn't known.
resolve(value, value is not None, is_secret, None)
resolve(value, value is not None, is_secret, deps.get(key), None)
# `allProps` may not have contained a value for every resolver: for example, optional outputs may not be present.
# We will resolve all of these values as `None`, and will mark the value as known if we are not running a
# preview.
for key, resolve in resolvers.items():
if key not in all_properties:
resolve(None, not settings.is_dry_run(), False, None)
resolve(None, not settings.is_dry_run(), False, deps.get(key), None)
def resolve_outputs_due_to_exception(resolvers: Dict[str, Resolver], exn: Exception):
@ -583,4 +594,4 @@ def resolve_outputs_due_to_exception(resolvers: Dict[str, Resolver], exn: Except
"""
for key, resolve in resolvers.items():
log.debug(f"sending exception to resolver for {key}")
resolve(None, False, False, exn)
resolve(None, False, False, None, exn)

View file

@ -1,3 +1,5 @@
// Copyright 2016-2020, Pulumi Corporation. All rights reserved.
import * as pulumi from "@pulumi/pulumi";
interface ComponentArgs {

View file

@ -1,4 +1,4 @@
// Copyright 2016-2018, Pulumi Corporation. All rights reserved.
// Copyright 2016-2020, Pulumi Corporation. All rights reserved.
import { Component } from "./component";

View file

@ -0,0 +1,5 @@
*.pyc
/.pulumi/
/dist/
/*.egg-info
venv/

View file

@ -0,0 +1,3 @@
name: construct_component_py
description: A program that constructs remote component resources.
runtime: python

View file

@ -0,0 +1,7 @@
# Copyright 2016-2018, Pulumi Corporation. All rights reserved.
from component import Component
component_a = Component("a", echo=42)
component_b = Component("b", echo=component_a.echo)
component_c = Component("c", echo=component_a.childId)

View file

@ -0,0 +1,15 @@
# Copyright 2016-2020, Pulumi Corporation. All rights reserved.
from typing import Any, Optional
import pulumi
class Component(pulumi.ComponentResource):
echo: pulumi.Output[Any]
childId: pulumi.Output[str]
def __init__(self, name: str, echo: pulumi.Input[Any], opts: Optional[pulumi.ResourceOptions] = None):
props = dict()
props["echo"] = echo
props["childId"] = None
super().__init__("testcomponent:index:Component", name, props, opts, True)

View file

@ -602,24 +602,6 @@ func TestLargeResourceNode(t *testing.T) {
})
}
func testComponentPathEnv() (string, error) {
cwd, err := os.Getwd()
if err != nil {
return "", err
}
absCwd, err := filepath.Abs(cwd)
if err != nil {
return "", err
}
pluginDir := filepath.Join(absCwd, "construct_component", "testcomponent")
pathSeparator := ":"
if runtime.GOOS == "windows" {
pathSeparator = ";"
}
return "PATH=" + os.Getenv("PATH") + pathSeparator + pluginDir, nil
}
// Test remote component construction in Node.
func TestConstructNode(t *testing.T) {
pathEnv, err := testComponentPathEnv()

View file

@ -341,3 +341,59 @@ func TestPythonPylint(t *testing.T) {
}
integration.ProgramTest(t, opts)
}
// Test remote component construction in Python.
func TestConstructPython(t *testing.T) {
pathEnv, err := testComponentPathEnv()
if err != nil {
t.Fatalf("failed to build test component PATH: %v", err)
}
// TODO[pulumi/pulumi#5455]: Dynamic providers fail to load when used from multi-lang components.
// Until we've addressed this, set PULUMI_TEST_YARN_LINK_PULUMI, which tells the integration test
// module to run `yarn install && yarn link @pulumi/pulumi` in the Python program's directory, allowing
// the Node.js dynamic provider plugin to load.
// When the underlying issue has been fixed, the use of this environment variable inside the integration
// test module should be removed.
const testYarnLinkPulumiEnv = "PULUMI_TEST_YARN_LINK_PULUMI=true"
var opts *integration.ProgramTestOptions
opts = &integration.ProgramTestOptions{
Env: []string{pathEnv, testYarnLinkPulumiEnv},
Dir: filepath.Join("construct_component", "python"),
Dependencies: []string{
filepath.Join("..", "..", "sdk", "python", "env", "src"),
},
Quick: true,
ExtraRuntimeValidation: func(t *testing.T, stackInfo integration.RuntimeValidationStackInfo) {
assert.NotNil(t, stackInfo.Deployment)
if assert.Equal(t, 9, len(stackInfo.Deployment.Resources)) {
stackRes := stackInfo.Deployment.Resources[0]
assert.NotNil(t, stackRes)
assert.Equal(t, resource.RootStackType, stackRes.Type)
assert.Equal(t, "", string(stackRes.Parent))
// Check that dependencies flow correctly between the originating program and the remote component
// plugin.
urns := make(map[string]resource.URN)
for _, res := range stackInfo.Deployment.Resources[1:] {
assert.NotNil(t, res)
urns[string(res.URN.Name())] = res.URN
switch res.URN.Name() {
case "child-a":
for _, deps := range res.PropertyDependencies {
assert.Empty(t, deps)
}
case "child-b":
assert.Equal(t, []resource.URN{urns["a"]}, res.PropertyDependencies["echo"])
case "child-c":
assert.ElementsMatch(t, []resource.URN{urns["child-a"], urns["a"]},
res.PropertyDependencies["echo"])
}
}
}
},
}
integration.ProgramTest(t, opts)
}

View file

@ -4,7 +4,9 @@ package ints
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"time"
@ -563,5 +565,21 @@ func TestConfigPaths(t *testing.T) {
e.RunCommand("pulumi", "stack", "rm", "--yes")
}
// The following 4 tests are testing to ensure that we can make RPC calls >4mb
// Issue: https://github.com/pulumi/pulumi/issues/4155
//nolint:golint,deadcode
func testComponentPathEnv() (string, error) {
cwd, err := os.Getwd()
if err != nil {
return "", err
}
absCwd, err := filepath.Abs(cwd)
if err != nil {
return "", err
}
pluginDir := filepath.Join(absCwd, "construct_component", "testcomponent")
pathSeparator := ":"
if runtime.GOOS == "windows" {
pathSeparator = ";"
}
return "PATH=" + os.Getenv("PATH") + pathSeparator + pluginDir, nil
}