Commit graph

910 commits

Author SHA1 Message Date
joeduffy 371a847eb9 Unify a bit of command logic, and hoist some failure modes 2017-02-27 14:13:27 -08:00
joeduffy 73babc13a0 Add confirmation for destroy 2017-02-27 13:53:15 -08:00
joeduffy 9b55505463 Implement AWS security group updates 2017-02-27 13:33:08 -08:00
joeduffy eca5c38406 Fix a handful of update-related issues
* Delete husks if err == nil, not err != nil.

* Swizzle the formatting padding on array elements so that the
  diff modifier + or - binds more tightly to the [N] part.

* Print the un-doubly-indented padding for array element headers.

* Add some additional logging to step application (it helped).

* Remember unchanged resources even when glogging is off.
2017-02-27 11:27:36 -08:00
joeduffy 3bdbf17af2 Rename --show-sames to --show-unchanged
Per Eric's feedback.
2017-02-27 11:08:14 -08:00
joeduffy 09e328e3e6 Extract settings from the correct old/new snapshot 2017-02-27 11:02:39 -08:00
joeduffy afbd40c960 Add a --show-sames flag
This change adds a --show-sames flag to `coco husk deploy`.  This is
useful as I'm working on updates, to show what resources haven't changed
during a deployment.
2017-02-27 10:58:24 -08:00
joeduffy 88fa0b11ed Checkpoint deployments
This change checkpoints deployments properly.  That is, even in the
face of partial failure, we should keep the huskfile up to date.  This
accomplishes that by tracking the state during plan application.

There are still ways in which this can go wrong, however.  Please see
pulumi/coconut#101 for additional thoughts on what we might do here
in the future to make checkpointing more robust in the face of failure.
2017-02-27 10:26:44 -08:00
joeduffy 604370f58b Propagate IDs from old to new during updates 2017-02-26 13:36:30 -08:00
joeduffy d3ce3cd9c6 Implement a coco husk ls command
This command is handy for development, so I whipped up a quick implementation.
All it does is print all known husks with their associated deployment time
and resource count (if any, or "n/a" for initialized husks with no deployments).
2017-02-26 13:06:33 -08:00
joeduffy 7f62740bc5 Add comment about adding cocojs to $PATH 2017-02-26 12:14:49 -08:00
joeduffy ace693290f Fix the directionality of delete edges 2017-02-26 12:05:49 -08:00
joeduffy 44783cffb7 Don't overwrite unmarshaled deployment info 2017-02-26 12:00:00 -08:00
joeduffy ff3f2232db Only use args if non-nil 2017-02-26 11:53:02 -08:00
joeduffy 2116d87f7d Tidy up some messages and error paths 2017-02-26 11:52:44 -08:00
joeduffy 1bdd24395c Recognize TextUnmarshaler and use it
This change recognizes TextUnmarshaler during object mapping, and
will defer to it when we have a string but are assigning to a
non-string target that implements the interface.
2017-02-26 11:51:38 -08:00
joeduffy 2f60a414c7 Reorganize deployment commands
As part of pulumi/coconut#94 -- adding targeting capabilities -- I've
decided to (yet again) reorganize the deployment commands a bit.  This
makes targets ("husks") more of a first class thing.

Namely, you must first initialize a husk before using it:

    $ coco husk init staging
    Coconut husk 'staging' initialized; ready for deployments

Eventually, this is when you will be given a choice to configure it.
Afterwards, you can perform deployments.  The first one is like a create,
but subsequent ones just figure out the right thing to do and do it:

    $ ... make some changes ...
    $ coco husk deploy staging
    ... standard deployment progress spew ...

Finally, should you want to teardown an entire environment:

    $ coco husk destroy staging
    ... standard deletion progress spew for all resources ...
    Coconut husk 'staging' has been destroyed!
2017-02-26 11:20:14 -08:00
joeduffy 2fec5f74d5 Make DeepEquals nullary logic match Diff 2017-02-25 18:24:12 -08:00
joeduffy 39b63daaad Fix a broken link 2017-02-25 10:57:07 -08:00
joeduffy ea7bdd265f Remove bit about symlinking 2017-02-25 10:55:56 -08:00
joeduffy 5d550cea2c Eliminate a redundant paragraph 2017-02-25 10:53:29 -08:00
joeduffy c714aa6d43 Tweak a bit more in the README 2017-02-25 10:52:01 -08:00
joeduffy 15b44c22e5 Tidy up the installation instructions 2017-02-25 10:46:26 -08:00
joeduffy b3859bd78f Use 0755, rather than 0744, for directories 2017-02-25 10:36:28 -08:00
joeduffy bfe084e3aa Fix an errant Git module 2017-02-25 10:35:51 -08:00
joeduffy 977b16b2cc Add basic targeting capability
This change partially implements pulumi/coconut#94, by adding the
ability to name targets during creation and reuse those names during
deletion and update.  This simplifies the management of deployment
records, checkpoints, and snapshots.

I've opted to call these things "husks" (perhaps going overboard with
joy after our recent renaming).  The basic idea is that for any
executable Nut that will be deployed, you have a nutpack/ directory
whose layout looks roughly as follows:

    nutpack/
        bin/
            Nutpack.json
            ... any other compiled artifacts ...
        husks/
            ... one snapshot per husk ...

For example, if we had a stage and prod husk, we would have:

    nutpack/
        bin/...
        husks/
            prod.json
            stage.json

In the prod.json and stage.json files, we'd have the most recent
deployment record for that environment.  These would presumably get
checked in and versioned along with the overall Nut, so that we
can use Git history for rollbacks, etc.

The create, update, and delete commands look in the right place for
these files automatically, so you don't need to manually supply them.
2017-02-25 09:24:52 -08:00
joeduffy 14762df98b Flip the summarization polarity
This change shows detailed output -- resources, their properties, and
a full articulation of plan steps -- and permits summarization with the
--summary (or -s) flag.
2017-02-25 07:55:22 -08:00
joeduffy 32379da4f5 Fix a few lingering issues from rename 2017-02-25 07:51:29 -08:00
joeduffy 08b644a3ba Delete the architecture PNG
It's now out of date (Coconut versus Mu).

And shame on me for ever checking in a binary, anyway.
2017-02-25 07:40:26 -08:00
joeduffy 99442c2ee3 Fix a small typo 2017-02-25 07:27:00 -08:00
joeduffy fbb56ab5df Coconut! 2017-02-25 07:25:33 -08:00
joeduffy e0440ad312 Print step op labels 2017-02-24 17:44:54 -08:00
joeduffy b43c374905 Fix a few more things about updates
* Eliminate some superfluous "\n"s.

* Remove the redundant properties stored on AWS resources.

* Compute array diff lengths properly (+1).

* Display object property changes from null to non-null as
  adds; and from non-null to null as deletes.

* Fix a boolean expression from ||s to &&s.  (Bone-headed).
2017-02-24 17:02:02 -08:00
joeduffy 53cf9f8b60 Tidy up a few things
* Print a pretty message if the plan has nothing to do:

        "info: nothing to do -- resources are up to date"

* Add an extra validation step after reading in a snapshot,
  so that we detect more errors sooner.  For example, I've
  fed in the wrong file several times, and it just chugs
  along as though it were actually a snapshot.

* Skip printing nulls in most plan outputs.  These just
  clutter up the output.
2017-02-24 16:44:46 -08:00
joeduffy 877fa131eb Detect duplicate object names
This change detects duplicate object names (monikers) and issues a nice
error message with source context include.  For example:

    index.ts(260,22): error MU2006: Duplicate objects with the same name:
        prod::ec2instance:index::aws:ec2/securityGroup:SecurityGroup::group

The prior code asserted and failed abruptly, whereas this actually points
us to the offending line of code:

    let group1 = new aws.ec2.SecurityGroup("group", { ... });
    let group2 = new aws.ec2.SecurityGroup("group", { ... });
                 ^^^^^^^^^^^^^^^^^^^^^^^^^
2017-02-24 16:03:06 -08:00
joeduffy 14e3f19437 Implement name property in AWS provider/library 2017-02-24 15:41:56 -08:00
joeduffy c120f62964 Redo object monikers
This change overhauls the way we do object monikers.  The old mechanism,
generating monikers using graph paths, was far too brittle and prone to
collisions.  The new approach mixes some amount of "automatic scoping"
plus some "explicit naming."  Although there is some explicitness, this
is arguably a good thing, as the monikers will be relatable back to the
source more readily by developers inspecting the graph and resource state.

Each moniker has four parts:

    <Namespace>::<AllocModule>::<Type>::<Name>

wherein each element is the following:

    <Namespace>     The namespace being deployed into
    <AllocModule>   The module in which the object was allocated
    <Type>          The type of the resource
    <Name>          The assigned name of the resource

The <Namespace> is essentially the deployment target -- so "prod",
"stage", etc -- although it is more general purpose to allow for future
namespacing within a target (e.g., "prod/customer1", etc); for now
this is rudimentary, however, see marapongo/mu#94.

The <AllocModule> is the token for the code that contained the 'new'
that led to this object being created.  In the future, we may wish to
extend this to also track the module under evaluation.  (This is a nice
aspect of monikers; they can become arbitrarily complex, so long as
they are precise, and not prone to false positives/negatives.)

The <Name> warrants more discussion.  The resource provider is consulted
via a new gRPC method, Name, that fetches the name.  How the provider
does this is entirely up to it.  For some resource types, the resource
may have properties that developers must set (e.g., `new Bucket("foo")`);
for other providers, perhaps the resource intrinsically has a property
that explicitly and uniquely qualifies the object (e.g., AWS SecurityGroups,
via `new SecurityGroup({groupName: "my-sg"}`); and finally, it's conceivable
that a provider might auto-generate the name (e.g., such as an AWS Lambda
whose name could simply be a hash of the source code contents).

This should overall produce better results with respect to moniker
collisions, ability to match resources, and the usability of the system.
2017-02-24 14:50:02 -08:00
joeduffy 9dc75da159 Diff and colorize update outputs
This change implements detailed object diffing for puposes of displaying
(and colorizing) updated properties during an update deployment.
2017-02-23 19:03:22 -08:00
joeduffy c4d1f60a7e Eliminate a superfluous map allocation 2017-02-23 15:05:30 -08:00
joeduffy 271eaefb5c Fix ec2instance CIDR property 2017-02-23 15:04:07 -08:00
joeduffy 86bfe5961d Implement updates
This change is a first whack at implementing updates.

Creation and deletion plans are pretty straightforward; we just take
a single graph, topologically sort it, and perform the operations in
the right order.  For creation, this is in dependency order (things
that are depended upon must be created before dependents); for deletion,
this is in reverse-dependency order (things that depend on others must
be deleted before dependencies).  These are just special cases of the more
general idea of performing DAG operations in dependency order.

Updates must work in terms of this more general notion.  For example:

* It is an error to delete a resource while another refers to it; thus,
  resources are deleted after deleting dependents, or after updating
  dependent properties that reference the resource to new values.

* It is an error to depend on a create a resource before it is created;
  thus, resources must be created before dependents are created, and/or
  before updates to existing resource properties that would cause them
  to refer to the new resource.

Of course, all of this is tangled up in a graph of dependencies.  As a
result, we must create a DAG of the dependencies between creates, updates,
and deletes, and then topologically sort this DAG, in order to determine
the proper order of update operations.

To do this, we slightly generalize the existing graph infrastructure,
while also specializing two kinds of graphs; the existing one becomes a
heapstate.ObjectGraph, while this new one is resource.planGraph (internal).
2017-02-23 14:56:23 -08:00
joeduffy 6fc807c7fd Tweak some progress messages 2017-02-23 10:34:03 -08:00
joeduffy 3f2697916b Also wait for SecurityGroup deletions 2017-02-23 10:27:20 -08:00
joeduffy 43432babc5 Wait for SecurityGroups to become active 2017-02-23 10:18:37 -08:00
joeduffy d9e6d8a207 Add a simple retry.Until package/function
This change introduces a simple retry package which will be used in
resource providers in order to perform waits, backoffs, etc.  It's
pretty basic right now but leverages the fancy new Golang context
support for deadlines and timeouts.  Soon we will layer AWS-specific
acceptors, etc. atop this more general purpose thing.
2017-02-22 19:16:46 -08:00
joeduffy f00b146481 Echo resource provider outputs
This change introduces a new informational message category to the
overall diagnostics infrastructure, and then wires up the resource
provider plugins stdout/stderr streams to it.  In particular, a
write to stdout implies an informational message, whereas a write to
stderr implies an error.  This is just a very simple and convenient
way for plugins to provide progress reporting; eventually we may
need something more complex, due to parallel evaluation of resource
graphs, however I hope we don't have to deviate too much from this.
2017-02-22 18:53:36 -08:00
joeduffy 2088eef6e9 Provision security group ingress/egress rules 2017-02-22 18:10:36 -08:00
joeduffy 8610a70ca4 Implement stable resource ordering
This change adds custom serialization and deserialization to preserve
the ordering of resources in snapshot files.  Unfortunately, because
Go maps are unordered, the results are scrambled (actually, it turns out,
Go will sort by the key).  An alternative would be to resort the results
after reading in the file, or storing as an array, but this would be a
change to the MuGL file format and is less clear than simply keying each
resource by its moniker as we are doing today.
2017-02-22 17:33:08 -08:00
joeduffy 83aa9cafa5 Wait for EC2 instance state changes
This change waits for EC2 instance state changes (to running when
creating, and to terminated when deleting), before proceeding.  Note
that we probably want to replace this with custom wait functionality
so that we're entirely in control of the retries, timeouts, logging, etc.
I'll do this soon as part of adding similar waits for security groups.
2017-02-22 14:59:50 -08:00
joeduffy ae99e957f9 Fix a few messages and assertions 2017-02-22 14:43:08 -08:00