This change switches from child lists to parent pointers, in the way resource ancestries are represented. This cleans up a fair bit of the old parenting logic, including all notion of ambient parent scopes (and will notably address pulumi/pulumi#435). This lets us show a more parent/child display in the output when doing planning and updating. For instance, here is an update of a lambda's text, which is logically part of a cloud timer: * cloud:timer:Timer: (same) [urn=urn:pulumi:malta::lm-cloud:☁️timer:Timer::lm-cts-malta-job-CleanSnapshots] * cloud:function:Function: (same) [urn=urn:pulumi:malta::lm-cloud:☁️function:Function::lm-cts-malta-job-CleanSnapshots] * aws:serverless:Function: (same) [urn=urn:pulumi:malta::lm-cloud::aws:serverless:Function::lm-cts-malta-job-CleanSnapshots] ~ aws:lambda/function:Function: (modify) [id=lm-cts-malta-job-CleanSnapshots-fee4f3bf41280741] [urn=urn:pulumi:malta::lm-cloud::aws:lambda/function:Function::lm-cts-malta-job-CleanSnapshots] - code : archive(assets:2092f44) { // etc etc etc Note that we still get walls of text, but this will be actually quite nice when combined with pulumi/pulumi#454. I've also suppressed printing properties that didn't change during updates when --detailed was not passed, and also suppressed empty strings and zero-length arrays (since TF uses these as defaults in many places and it just makes creation and deletion quite verbose). Note that this is a far cry from everything we can possibly do here as part of pulumi/pulumi#340 (and even pulumi/pulumi#417). But it's a good start towards taming some of our output spew.
118 lines
6.2 KiB
TypeScript
118 lines
6.2 KiB
TypeScript
// Copyright 2016-2017, Pulumi Corporation. All rights reserved.
|
|
|
|
import * as runtime from "./runtime";
|
|
|
|
export type ID = string; // a provider-assigned ID.
|
|
export type URN = string; // an automatically generated logical URN, used to stably identify resources.
|
|
|
|
/**
|
|
* Resource represents a class whose CRUD operations are implemented by a provider plugin.
|
|
*/
|
|
export abstract class Resource {
|
|
/**
|
|
* urn is the stable logical URN used to distinctly address a resource, both before and after deployments.
|
|
*/
|
|
public readonly urn: Promise<URN>;
|
|
|
|
/**
|
|
* Creates and registers a new resource object. t is the fully qualified type token and name is the "name" part
|
|
* to use in creating a stable and globally unique URN for the object. dependsOn is an optional list of other
|
|
* resources that this resource depends on, controlling the order in which we perform resource operations.
|
|
*
|
|
* @param t The type of the resource.
|
|
* @param name The _unqiue_ name of the resource.
|
|
* @param custom True to indicate that this is a custom resource, managed by a plugin.
|
|
* @param props The arguments to use to populate the new resource.
|
|
* @param parent An optional parent resource to which this resource belongs.
|
|
* @param dependsOn Optional additional explicit dependencies on other resources.
|
|
*/
|
|
constructor(t: string, name: string, custom: boolean, props: ComputedValues,
|
|
parent?: Resource, dependsOn?: Resource[]) {
|
|
if (!t) {
|
|
throw new Error("Missing resource type argument");
|
|
}
|
|
if (!name) {
|
|
throw new Error("Missing resource name argument (for URN creation)");
|
|
}
|
|
|
|
// Now kick off the resource registration. If we are actually performing a deployment, this resource's
|
|
// properties will be resolved asynchronously after the operation completes, so that dependent computations
|
|
// resolve normally. If we are just planning, on the other hand, values will never resolve.
|
|
runtime.registerResource(this, t, name, custom, props, parent, dependsOn);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* CustomResource is a resource whose create, read, update, and delete (CRUD) operations are managed by performing
|
|
* external operations on some physical entity. The engine understands how to diff and perform partial updates of
|
|
* them, and these CRUD operations are implemented in a dynamically loaded plugin for the defining package.
|
|
*/
|
|
export abstract class CustomResource extends Resource {
|
|
/**
|
|
* id is the provider-assigned unique ID for this managed resource. It is set during deployments and may be
|
|
* missing (undefined) during planning phases.
|
|
*/
|
|
public readonly id: Computed<ID>;
|
|
|
|
/**
|
|
* Creates and registers a new managed resource. t is the fully qualified type token and name is the "name" part
|
|
* to use in creating a stable and globally unique URN for the object. dependsOn is an optional list of other
|
|
* resources that this resource depends on, controlling the order in which we perform resource operations.
|
|
* Creating an instance does not necessarily perform a create on the physical entity which it represents, and
|
|
* instead, this is dependent upon the diffing of the new goal state compared to the current known resource state.
|
|
*
|
|
* @param t The type of the resource.
|
|
* @param name The _unqiue_ name of the resource.
|
|
* @param props The arguments to use to populate the new resource.
|
|
* @param parent An optional parent resource to which this resource belongs.
|
|
* @param dependsOn Optional additional explicit dependencies on other resources.
|
|
*/
|
|
constructor(t: string, name: string, props: ComputedValues, parent?: Resource, dependsOn?: Resource[]) {
|
|
super(t, name, true, props, parent, dependsOn);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* ComponentResource is a resource that aggregates one or more other child resources into a higher level abstraction.
|
|
* The component resource itself is a resource, but does not require custom CRUD operations for provisioning.
|
|
*/
|
|
export class ComponentResource extends Resource {
|
|
/**
|
|
* Creates and registers a new component resource. t is the fully qualified type token and name is the "name" part
|
|
* to use in creating a stable and globally unique URN for the object. parent is the optional parent for this
|
|
* component, and dependsOn is an optional list of other resources that this resource depends on, controlling the
|
|
* order in which we perform resource operations.
|
|
*
|
|
* @param t The type of the resource.
|
|
* @param name The _unqiue_ name of the resource.
|
|
* @param props The arguments to use to populate the new resource.
|
|
* @param parent An optional parent resource to which this resource belongs.
|
|
* @param dependsOn Optional additional explicit dependencies on other resources.
|
|
*/
|
|
constructor(t: string, name: string, props: ComputedValues, parent?: Resource, dependsOn?: Resource[]) {
|
|
super(t, name, false, props, parent, dependsOn);
|
|
// TODO[pulumi/pulumi#340]: we do not currently persist component output properties that are "derived"
|
|
// from its children. This would be very useful because many times an essential property of a
|
|
// component -- like an endpoint URL, to take one example -- won't be known until we have finished
|
|
// initializing its children. Fixing this, however, requires fairly dramatic changes to the engine,
|
|
// since a resource's full state won't be known until after a two-phase process has completed. As
|
|
// part of fixing pulumi/pulumi#340 overall, we will find a way to address this.
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Computed is a property output for a resource. It is just a promise that also permits undefined values. The
|
|
* undefined values are used during planning, when the actual final value of a resource may not yet be known.
|
|
*/
|
|
export type Computed<T> = Promise<T | undefined>;
|
|
|
|
/**
|
|
* ComputedValue is a property input for a resource. It may be a promptly available T or a promise for one.
|
|
*/
|
|
export type ComputedValue<T> = T | undefined | Promise<T | undefined>;
|
|
|
|
/**
|
|
* ComputedValues is a map of property name to optional property input, one for each resource property value.
|
|
*/
|
|
export type ComputedValues = { [key: string]: ComputedValue<any> };
|