pulumi/sdk/nodejs/resource.ts
joeduffy 7e48e8726b Add (back) component outputs
This change adds back component output properties.  Doing so
requires splitting the RPC interface for creating resources in
half, with an initial RegisterResource which contains all of the
input properties, and a final CompleteResource which optionally
contains any output properties synthesized by the component.
2017-11-20 17:38:09 -08:00

127 lines
6.3 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)");
}
// If there wasn't an explicit parent, and a root stack exists, parent to that.
if (!parent) {
parent = runtime.getRootPulumiStack();
}
// 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);
// Unlike components, a custom resource is done as soon as its registration has happened; automatically
// finish registering custom resource state so that subclasses don't need to do so.
runtime.completeResource(this);
}
}
/**
* 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);
}
// complete finishes the initialization of this resource, with an optional bag of extra output state. All
// component subclasses *must* call this when done, otherwise they will not be present in the checkpoint file.
protected complete(extras?: ComputedValues): void {
runtime.completeResource(this, extras);
}
}
/**
* 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> };