For providers which do not natively support secrets (which is all of them today), we annotate output values coming back from the provider if there is a coresponding secret input in the inputs we passed in. This logic was not tearing into rich objects, so if you passed a secret as a member of an array or object into a resource provider, we would lose the secretness on the way back. Because of the interaction with Check (where we call Check and then take the values returned by the provider as inputs for all calls to Diff/Update), this would apply not only to the Output values of a resource but also the Inputs (because the secret metadata would not flow from the inputs of check to the outputs). This change augments our logic which transfers secrets metadata from one property map to another to handle these additional cases.
34 lines
1.6 KiB
TypeScript
34 lines
1.6 KiB
TypeScript
import * as pulumi from "@pulumi/pulumi";
|
|
import * as dynamic from "@pulumi/pulumi/dynamic";
|
|
|
|
class ReflectProvider implements dynamic.ResourceProvider {
|
|
public check(olds: any, news: any) { return Promise.resolve({ inputs: news }); }
|
|
public diff(id: pulumi.ID, olds: any, news: any) { return Promise.resolve({}); }
|
|
public delete(id: pulumi.ID, props: any) { return Promise.resolve(); }
|
|
public create(inputs: any) { return Promise.resolve({ id: "0", outs: inputs }); }
|
|
public update(id: string, olds: any, news: any) { return Promise.resolve({ outs: news }); }
|
|
}
|
|
|
|
export class ReflectResource<T> extends dynamic.Resource {
|
|
public readonly value: pulumi.Output<T>;
|
|
|
|
constructor(name: string, value: pulumi.Input<T>, opts?: pulumi.CustomResourceOptions) {
|
|
super(new ReflectProvider(), name, {value: value }, opts);
|
|
}
|
|
}
|
|
|
|
class DummyProvider implements dynamic.ResourceProvider {
|
|
public check(olds: any, news: any) { return Promise.resolve({ inputs: news }); }
|
|
public diff(id: pulumi.ID, olds: any, news: any) { return Promise.resolve({}); }
|
|
public delete(id: pulumi.ID, props: any) { return Promise.resolve(); }
|
|
public create(inputs: any) { return Promise.resolve({ id: "0", outs: {"value": "hello"} }); }
|
|
public update(id: string, olds: any, news: any) { return Promise.resolve({ outs: news }); }
|
|
}
|
|
|
|
export class DummyResource extends dynamic.Resource {
|
|
public readonly value: pulumi.Output<string>;
|
|
|
|
constructor(name: string, opts?: pulumi.CustomResourceOptions) {
|
|
super(new DummyProvider(), name, {}, opts);
|
|
}
|
|
}
|