mirror of https://github.com/pulumi/pulumi.git
136 lines
5.0 KiB
TypeScript
136 lines
5.0 KiB
TypeScript
// Copyright 2016-2018, Pulumi Corporation. All rights reserved.
|
|
|
|
import * as pulumi from "@pulumi/pulumi";
|
|
import { Random } from "./random";
|
|
|
|
class MyComponent extends pulumi.ComponentResource {
|
|
child: Random;
|
|
constructor(name: string, opts?: pulumi.ComponentResourceOptions) {
|
|
super("my:component:MyComponent", name, {}, opts);
|
|
this.child = new Random(`${name}-child`, { length: 5 }, {
|
|
parent: this,
|
|
additionalSecretOutputs: ["length"],
|
|
});
|
|
this.registerOutputs({});
|
|
}
|
|
}
|
|
|
|
// Scenario #1 - apply a transformation to a CustomResource
|
|
const res1 = new Random("res1", { length: 5 }, {
|
|
transformations: [
|
|
({ props, opts }) => {
|
|
console.log("res1 transformation");
|
|
return {
|
|
props: props,
|
|
opts: pulumi.mergeOptions(opts, { additionalSecretOutputs: ["result"] }),
|
|
};
|
|
},
|
|
],
|
|
});
|
|
|
|
// Scenario #2 - apply a transformation to a Component to transform it's children
|
|
const res2 = new MyComponent("res2", {
|
|
transformations: [
|
|
({ type, props, opts }) => {
|
|
console.log("res2 transformation");
|
|
if (type === "testprovider:index:Random") {
|
|
return {
|
|
props: { prefix: "newDefault", ...props },
|
|
opts: pulumi.mergeOptions(opts, { additionalSecretOutputs: ["result"] }),
|
|
};
|
|
}
|
|
},
|
|
],
|
|
});
|
|
|
|
// Scenario #3 - apply a transformation to the Stack to transform all (future) resources in the stack
|
|
pulumi.runtime.registerStackTransformation(({ type, props, opts }) => {
|
|
console.log("stack transformation");
|
|
if (type === "testprovider:index:Random") {
|
|
return {
|
|
props: { ...props, prefix: "stackDefault" },
|
|
opts: pulumi.mergeOptions(opts, { additionalSecretOutputs: ["result"] }),
|
|
};
|
|
}
|
|
});
|
|
|
|
const res3 = new Random("res3", { length: 5 });
|
|
|
|
// Scenario #4 - transformations are applied in order of decreasing specificity
|
|
// 1. (not in this example) Child transformation
|
|
// 2. First parent transformation
|
|
// 3. Second parent transformation
|
|
// 4. Stack transformation
|
|
const res4 = new MyComponent("res4", {
|
|
transformations: [
|
|
({ type, props, opts }) => {
|
|
console.log("res4 transformation");
|
|
if (type === "testprovider:index:Random") {
|
|
return {
|
|
props: { ...props, prefix: "default1" },
|
|
opts,
|
|
};
|
|
}
|
|
},
|
|
({ type, props, opts }) => {
|
|
console.log("res4 transformation 2");
|
|
if (type === "testprovider:index:Random") {
|
|
return {
|
|
props: { ...props, prefix: "default2" },
|
|
opts,
|
|
};
|
|
}
|
|
},
|
|
],
|
|
});
|
|
|
|
// Scenario #5 - cross-resource transformations that inject dependencies on one resource into another.
|
|
class MyOtherComponent extends pulumi.ComponentResource {
|
|
child1: Random;
|
|
child2: Random;
|
|
constructor(name: string, opts?: pulumi.ComponentResourceOptions) {
|
|
super("my:component:MyOtherComponent", name, {}, opts);
|
|
this.child1 = new Random(`${name}-child1`, { length: 5 }, { parent: this });
|
|
this.child2 = new Random(`${name}-child2`, { length: 5 }, { parent: this });
|
|
this.registerOutputs({});
|
|
}
|
|
}
|
|
|
|
const transformChild1DependsOnChild2: pulumi.ResourceTransformation = (() => {
|
|
console.log("res5 transformation")
|
|
|
|
// Create a promise that wil be resolved once we find child2. This is needed because we do not
|
|
// know what order we will see the resource registrations of child1 and child2.
|
|
let child2Found: (res: pulumi.Resource) => void;
|
|
const child2 = new Promise<pulumi.Resource>((res) => child2Found = res);
|
|
|
|
// Return a transformation which will rewrite child1 to depend on the promise for child2, and
|
|
// will resolve that promise when it finds child2.
|
|
return (args: pulumi.ResourceTransformationArgs) => {
|
|
if (args.name.endsWith("-child2")) {
|
|
// Resolve the child2 promise with the child2 resource.
|
|
child2Found(args.resource);
|
|
return undefined;
|
|
} else if (args.name.endsWith("-child1")) {
|
|
// Overwrite the `prefix` to child2 with a dependency on the `length` from child1.
|
|
const child2Result = pulumi.output(args.props["length"]).apply(async (input) => {
|
|
if (input !== 5) {
|
|
// Not strictly necessary - but shows we can confirm invariants we expect to be
|
|
// true.
|
|
throw new Error("unexpected input value");
|
|
}
|
|
return child2.then(c2Res => c2Res["result"]);
|
|
});
|
|
// Finally - overwrite the input of child2.
|
|
return {
|
|
props: { ...args.props, prefix: child2Result },
|
|
opts: args.opts,
|
|
};
|
|
}
|
|
};
|
|
})();
|
|
|
|
const res5 = new MyOtherComponent("res5", {
|
|
transformations: [ transformChild1DependsOnChild2 ],
|
|
});
|