Commit graph

27 commits

Author SHA1 Message Date
CyrusNajmabadi 6f8a74f09f
wrap long comments. (#842) 2018-01-25 18:50:58 -08:00
CyrusNajmabadi f35f991140
Extract out serialization functionality from transfer function. (#835) 2018-01-25 13:34:21 -08:00
Joe Duffy bc2cf55463
Implement resource protection (#751)
This change implements resource protection, as per pulumi/pulumi#689.
The overall idea is that a resource can be marked as "protect: true",
which will prevent deletion of that resource for any reason whatsoever
(straight deletion, replacement, etc).  This is expressed in the
program.  To "unprotect" a resource, one must perform an update setting
"protect: false", and then afterwards, they can delete the resource.

For example:

    let res = new MyResource("precious", { .. }, { protect: true });

Afterwards, the resource will display in the CLI with a lock icon, and
any attempts to remove it will fail in the usual ways (in planning or,
worst case, during an actual update).

This was done by adding a new ResourceOptions bag parameter to the
base Resource types.  This is unfortunately a breaking change, but now
is the right time to take this one.  We had been adding new settings
one by one -- like parent and dependsOn -- and this new approach will
set us up to add any number of additional settings down the road,
without needing to worry about breaking anything ever again.

This is related to protected stacks, as described in
pulumi/pulumi-service#399.  Most likely this will serve as a foundational
building block that enables the coarser grained policy management.
2017-12-20 14:31:07 -08:00
joeduffy a4c7c05e27 Simplify RPC changes
This change simplifies the necessary RPC changes for components.
Instead of a Begin/End pair, which complicates the whole system
because now we have the opportunity of a missing End call, we will
simply let RPCs come in that append outputs to existing states.
2017-11-29 12:08:01 -08:00
joeduffy c5b7b6ef11 Bring back component outputs
This change brings back component outputs to the overall system again.
In doing so, it generally overhauls the way we do resource RPCs a bit:

* Instead of RegisterResource and CompleteResource, we call these
  BeginRegisterResource and EndRegisterResource, which begins to model
  these as effectively "asynchronous" resource requests.  This should also
  help with parallelism (https://github.com/pulumi/pulumi/issues/106).

* Flip the CLI/engine a little on its head.  Rather than it driving the
  planning and deployment process, we move more to a model where it
  simply observes it.  This is done by implementing an event handler
  interface with three events: OnResourceStepPre, OnResourceStepPost,
  and OnResourceComplete.  The first two are invoked immediately before
  and after any step operation, and the latter is invoked whenever a
  EndRegisterResource comes in.  The reason for the asymmetry here is
  that the checkpointing logic in the deployment engine is largely
  untouched (intentionally, as this is a sensitive part of the system),
  and so the "begin"/"end" nature doesn't flow through faithfully.

* Also make the engine more event-oriented in its terminology and the
  way it handles the incoming BeginRegisterResource and
  EndRegisterResource events from the language host.  This is the first
  step down a long road of incrementally refactoring the engine to work
  this way, a necessary prerequisite for parallelism.
2017-11-29 07:42:14 -08:00
joeduffy 5762f2d0a6 Merge remote-tracking branch 'origin/resource_parenting' into resource_parenting_lite 2017-11-28 11:03:34 -08:00
joeduffy 41ae40249e Make root resources more general 2017-11-26 12:01:13 -08:00
joeduffy 8dc9fd027c Add back stack outputs
This change simply prints a stack's output properties at the end of
running the program, since we now no longer actual record the outputs
as part of component registration.  Bringing that back is part of
pulumi/pulumi#340, however it is too risky to add hastily.  So, for
now, we will simply special case Stacks.
2017-11-26 08:14:01 -08:00
joeduffy 86f97de7eb Merge root stack changes with parenting 2017-11-26 08:14:01 -08:00
joeduffy a2ae4accf4 Switch to parent pointers; display components nicely
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.
2017-11-26 08:14:01 -08:00
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
joeduffy 86267b86b9 Merge root stack changes with parenting 2017-11-20 10:08:59 -08:00
joeduffy 5dc4b0b75c Switch to parent pointers; display components nicely
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.
2017-11-20 09:07:53 -08:00
Luke Hoban 96e4b74b15
Support for stack outputs (#581)
Adds support for top-level exports in the main script of a Pulumi Program to be captured as stack-level output properties.

This create a new `pulumi:pulumi:Stack` component as the root of the resource tree in all Pulumi programs.  That resources has properties for each top-level export in the Node.js script.

Running `pulumi stack` will display the current value of these outputs.
2017-11-17 15:22:41 -08:00
Joe Duffy 8d916dc00c
Improve promise leak diagnostics (#508)
This change adds more context information to debuggable promises
to aid with leak detection.  This was super helpful for me just now!
2017-10-31 07:48:59 -07:00
CyrusNajmabadi 3bbe21db25 Simplify the type system around 'computed' a little. (#469) 2017-10-25 12:52:49 -07:00
joeduffy d2b5ce9252 Add a Resource.runInParentlessScope function
As part of adding components, we sometimes want to allocate things
that are guaranteed not to get attributed to the calling component's
initialization code.  This includes lazily allocated pooled resources.
In those cases, we can invoke Resource.runInParentlessScope to
temporarily squelch the parent.  Also renames withParent to
runInParentScope to be more symmetric and explicit about what it does.
2017-10-18 07:39:03 -07:00
joeduffy 301739c6b5 Add auto-parenting
This changes a few things about "components":

* Rename what was previously ExternalResource to CustomResource,
  and all of the related fields and parameters that this implies.
  This just seems like a much nicer and expected name for what
  these represent.  I realize I am stealing a name we had thought
  about using elsewhere, but this seems like an appropriate use.

* Introduce ComponentResource, to make initializing resources
  that merely aggregate other resources easier to do correctly.

* Add a withParent and parentScope concept to Resource, to make
  allocating children less error-prone.  Now there's no need to
  explicitly adopt children as they are allocated; instead, any
  children allocated as part of the withParent callback will
  auto-parent to the resource provided.  This is used by
  ComponentResource's initialization function to make initialization
  easier, including the distinction between inputs and outputs.
2017-10-15 04:38:26 -07:00
joeduffy fbfca58a3f Implement components
This change implements core support for "components" in the Pulumi
Fabric.  This work is described further in pulumi/pulumi#340, where
we are still discussing some of the finer points.

In a nutshell, resources no longer imply external providers.  It's
entirely possible to have a resource that logically represents
something but without having a physical manifestation that needs to
be tracked and managed by our typical CRUD operations.

For example, the aws/serverless/Function helper is one such type.
It aggregates Lambda-related resources and exposes a nice interface.
All of the Pulumi Cloud Framework resources are also examples.

To indicate that a resource does participate in the usual CRUD resource
provider, it simply derives from ExternalResource instead of Resource.

All resources now have the ability to adopt children.  This is purely
a metadata/tagging thing, and will help us roll up displays, provide
attribution to the developer, and even hide aspects of the resource
graph as appropriate (e.g., when they are implementation details).

Our use of this capability is ultra limited right now; in fact, the
only place we display children is in the CLI output.  For instance:

    + aws:serverless:Function: (create)
      [urn=urn:pulumi:demo::serverless::aws:serverless:Function::mylambda]
      => urn:pulumi:demo::serverless::aws:iam/role:Role::mylambda-iamrole
      => urn:pulumi:demo::serverless::aws:iam/rolePolicyAttachment:RolePolicyAttachment::mylambda-iampolicy-0
      => urn:pulumi:demo::serverless::aws:lambda/function:Function::mylambda

The bit indicating whether a resource is external or not is tracked
in the resulting checkpoint file, along with any of its children.
2017-10-14 18:30:59 -07:00
joeduffy ce87899792 Add Maybe<T> as a shortcut for T | undefined
This arose during a conversation with @CyrusNajmabadi, where he
suggested it would be useful in user code to have a "name" for these,
since they show up so frequently during resource property consumption.
2017-10-11 17:35:44 -07:00
Luke Hoban c5558e2778 Convert sdk documentation to TypeDoc/JsDoc 2017-09-21 18:15:29 -07:00
joeduffy 1c2c972d37 Add back Computed<T> as a short-hand
This adds back Computed<T> as a short-hand for Promise<T | undefined>.
Subtly, all resource properties need to permit undefined flowing through
during planning  Rather than forcing the long-hand version, which is easy
to forget, we'll keep the convention of preferring Computed<T>.  It's
just a typedef and the runtime type is just a Promise.
2017-09-20 09:59:32 -07:00
joeduffy f8ee6c570e Eliminate Computed/Property in favor of Promises
As part of pulumi/pulumi-fabric#331, we've been exploring just using
undefined to indicate that a property value is absent during planning.
We also considered blocking the message loop to simplify the overall
programming model, so that all asynchrony is hidden.

It turns out ThereBeDragons 🐲 anytime you try to block the
message loop.  So, we aren't quite sure about that bit.

But the part we are convicted about is that this Computed/Property
model is far too complex.  Furthermore, it's very close to promises, and
yet frustratingly so far away.  Indeed, the original thinking in
pulumi/pulumi-fabric#271 was simply to use promises, but we wanted to
encourage dataflow styles, rather than control flow.  But we muddied up
our thinking by worrying about awaiting a promise that would never resolve.

It turns out we can achieve a middle ground: resolve planning promises to
undefined, so that they don't lead to hangs, but still use promises so
that asynchrony is explicit in the system.  This also avoids blocking the
message loop.  Who knows, this may actually be a fine final destination.
2017-09-20 09:59:32 -07:00
joeduffy 087deb7643 Add optional dependsOn to Resource constructors
This change adds an optiona dependsOn parameter to Resource constructors,
to "force" a fake dependency between resources.  We have an extremely strong
desire to resort to using this only in unusual cases -- and instead rely
on the natural dependency DAG based on properties -- but experience in other
resource provisioning frameworks tells us that we're likely to need this in
the general case.  Indeed, we've already encountered the need in AWS's
API Gateway resources... and I suspect we'll run into more especially as we
tackle non-serverless resources like EC2 Instances, where "ambient"
dependencies are far more commonplace.

This also makes parallelism the default mode of operation, and we have a
new --serialize flag that can be used to suppress this default behavior.
Full disclosure: I expect this to become more Make-like, i.e. -j 8, where
you can specify the precise width of parallelism, when we tackle
pulumi/pulumi-fabric#106.  I also think there's a good chance we will flip
the default, so that serial execution is the default, so that developers
who don't benefit from the parallelism don't need to worry about dependsOn
in awkward ways.  This tends to be the way most tools (like Make) operate.

This fixes pulumi/pulumi-fabric#335.
2017-09-15 16:38:52 -07:00
joeduffy d3bd43fea9 Rename PropertyValue<T> to MaybeComputed<T>
As I started rolling this out, I realized that end user code actually
has to use this type sometimes.  And that the current names are inconsistent,
after eschewing Property<T> in favor of Computed<T>.  The new names read better.
2017-09-05 11:14:28 -07:00
joeduffy a1ab56fc28 Prettify properties
This change makes a few simplifications to how properties are exposed in
the system, mostly in the name of usability, but also to feel a bit more
like "idiomatic JavaScript".  Namely:

* Rename `then` to `mapValue`.  This hopefully helps to suggest that this
  is meant for a dataflow style of programming.

* Move Property<T> into the runtime module, and remove PropertyState<T>,
  collapsing back down to a single type.  This also eliminates some of the
  messy internal runtime casting, accessing of internal members, etc.

* Export a Computed<T> interface from the root of the module.  This is
  the entirety of the public-facing surface area for properties, and
  exposes that single `mapValue` member function.  The internal runtime
  logic understands how to handle Property<T>s specifically in addition
  to Computed<T>s more generally (in case someone writes their own).
2017-09-05 10:55:09 -07:00
joeduffy d8635fd4f3 Move modules to package root
The organization of packages underneath lib/ breaks the easy consumption
of submodules, a la

    import {FileAsset} from "@pulumi/pulumi-fabric/asset";

We will go back to having everything hanging off the module root directory.
2017-09-04 11:35:21 -07:00
Renamed from sdk/nodejs/lib/resource.ts (Browse further)