Commit graph

332 commits

Author SHA1 Message Date
joeduffy
bb0822f2df Remove the Kube Fission provider
This code has moved out into its own distinct repo at pulumi/kubefission-lumipack.
2017-05-19 16:44:33 -07:00
joeduffy
ed092213d2 Remove deprecated lumix package 2017-05-19 16:27:34 -07:00
Luke Hoban
2a036c8693 More CLIDL -> LUMIDL updates 2017-05-18 17:21:08 -07:00
joeduffy
558d35e9cd Add back a missing package ec2
This was mistakenly lopped off during the license conversation.
2017-05-18 15:54:07 -07:00
joeduffy
4108c51549 Reclassify Lumi under the Apache 2.0 license
This is part of pulumi/lumi#147.
2017-05-18 14:51:52 -07:00
joeduffy
b7f3d447a1 Preserve the lumi prefix on our CLI tools
This change keeps the lumi prefix on our CLI tools.

As @lukehoban pointed out in person, as soon as we do pulumi/coconut#98,
most people (other than compiler authors themselves) won't actually be
typing the commands.  And, furthermore, the commands aren't all that bad.

Eventually I assume we'll want something like `lumi-js`, or
`lumi-js-compiler`, so that binaries are discovered dynamically in a way
that is extensible for future languages.  We can tackle this during #98.
2017-05-18 12:38:58 -07:00
joeduffy
dafeb77dff Rename Coconut to Lumi
This is part of pulumi/coconut#147.

After it has landed, I will rename the repo on GitHub.
2017-05-18 11:38:28 -07:00
joeduffy
3849761065 Rewrite Mantle functions to use assets/archives 2017-05-13 20:13:58 -04:00
joeduffy
ea7658f338 Guard against nil diffs 2017-05-08 14:52:17 -05:00
joeduffy
1e67162331 Fix a couple silly mistakes 2017-05-04 09:53:52 -07:00
joeduffy
70e75063c2 Remove superfluous output from install.sh 2017-05-01 17:43:50 -07:00
joeduffy
7f634b4cf2 Remove pulumi/coconut#141 workaround 2017-05-01 17:13:30 -07:00
joeduffy
bcd44fc06f Update cross-cloud library to support the latest changes 2017-05-01 10:21:52 -07:00
joeduffy
08626715fd Revert change to managed policy ARN casing 2017-05-01 10:17:18 -07:00
joeduffy
c1696dc684 Regenerate Kubefission with latest CIDLC 2017-05-01 09:41:02 -07:00
joeduffy
6902d7e1b2 Update AWS Lambdas to take archives, not assets 2017-05-01 09:38:23 -07:00
joeduffy
335ea01275 Implement archives
Our initial implementation of assets was intentionally naive, because
they were limited to single-file assets.  However, it turns out that for
real scenarios (like lambdas), we want to support multi-file assets.

In this change, we introduce the concept of an Archive.  An archive is
what the term classically means: a collection of files, addressed as one.
For now, we support three kinds: tarfile archives (*.tar), gzip-compressed
tarfile archives (*.tgz, *.tar), and normal zipfile archives (*.zip).

There is a fair bit of library support for manipulating Archives as a
logical collection of Assets.  I've gone to great length to avoid making
copies, however, sometimes it is unavoidable (for example, when sizes
are required in order to emit offsets).  This is also complicated by the
fact that the AWS libraries often want seekable streams, if not actual
raw contiguous []byte slices.
2017-04-30 12:37:24 -07:00
joeduffy
35a86d9089 Move AWS instanceMaps module back to ec2 2017-04-29 16:01:13 -07:00
joeduffy
0e16aa5d93 Make resource names the first constructor parameter
This reverts back to the old style of having the resource name as its
first parameter in the generated package.  Stylistically, this reads a
little nicer, and also ensures we don't need to rewrite all our existing
samples/test cases, etc.
2017-04-29 15:58:34 -07:00
joeduffy
fa24d436e3 Unpointerize some types
In a few places, an IDL type will be a pointer, but the resulting
RPC code would, ideally, be the naked type.  Namely, in both resource
and asset cases, they are required to be pointers in the IDL (because
they are by-pointer by nature), but the marshaled representations need
not be pointers.  This change depointerizes such types in the RPC
unless, of course, they are optional in which case pointers still make
sense.  This avoids some annoying dereferencing and is the kind of thing
we want to do sooner before seeing widespread use.
2017-04-29 15:38:56 -07:00
joeduffy
fe93f5e76f Strongly type resource IDs in the IDL/RPC/Providers
This change simply uses the `resource.ID` type in all the places
where it belongs, rather than using `string`-typed resource IDs.
2017-04-29 13:27:39 -07:00
joeduffy
d8627697df Unglide AWS provider
This triggers complicates with local development, due to the way
that Glide vendors dependencies.  After we move to distinct repos
for the various provider packages, we can go back to doing this.
2017-04-29 13:26:39 -07:00
joeduffy
2e49e87e38 Add an IDL generation script for Kube Fission 2017-04-29 13:23:26 -07:00
joeduffy
1a0066b938 Commit generated code for Kube Fission package 2017-04-28 16:37:10 -07:00
joeduffy
8bb31a8dd9 Migrate Kube Fission provider to new IDL model 2017-04-28 16:36:43 -07:00
joeduffy
d1dccb1b0a Further simplify the AWS provider
Now that the IDL types encode named resources as a first class concept,
there is no need to do the dynamic overriding dance in the AWS provider.
I should have included this in my final "banking" of the IDL changes.
2017-04-28 16:18:19 -07:00
joeduffy
3d391f3a44 Add the AWS package's CIDLC generated code
This change includes all of the CIDLC generated code for the AWS
package.  Just as we vendor and version the generated gRPC code,
we will do so for these files also.  This allows building of the
full packages without needing to run any special tools, in addition
to letting us keep track of generated code deltas over time.
2017-04-28 15:40:40 -07:00
joeduffy
3a4866f7c1 Add manually managed AWS package files
This checkin contains all the non-generated package files.  This includes
the package metadata, utility functions like utils/instanceMaps, and the
module layouts (these being a candidate for auto-generation down the road).

In addition, the install script has been updated fo reflect the new layout.
2017-04-28 15:38:45 -07:00
joeduffy
ec03441a15 Eliminate old TypeScript resource definitions
The old TypeScript resource definitions may now go away in favor of
the new IDL and associated generated code.  After this change, I will
check in the generated code, so that the repo is self-contained.
2017-04-28 15:36:22 -07:00
joeduffy
aca61a2074 Add missing Lambda Permisssion IDL type 2017-04-28 15:29:13 -07:00
joeduffy
59573fc05f Finish projecting AWS IDL types
This converts the remaining AWS resource types over to the new IDL
model; this includes the apigateway, cloudwatch, sns, and sqs packages.
2017-04-28 15:22:44 -07:00
joeduffy
e2e73cf035 Use good package names in place of "rpc"
This is just a minor stylistic change.  Instead of letting the AWS
package imports take the good names, prefer to use the generated IDL
names (since they contain the strongly typed data structures).
2017-04-28 13:04:10 -07:00
joeduffy
93255b7e8f Convert the AWS S3 provider to the new IDL model 2017-04-28 12:58:51 -07:00
joeduffy
1489a73b18 Convert the AWS Lambda module to CIDLC 2017-04-28 12:27:19 -07:00
joeduffy
2d109f736c Convert AWS IAM types and provider to new IDL model 2017-04-28 11:16:49 -07:00
joeduffy
72b4035f3a Add a script to regenerate the AWS package from IDL 2017-04-28 10:37:37 -07:00
joeduffy
df01db5df7 Finish converting the AWS EC2 resource IDLs 2017-04-27 11:53:32 -07:00
joeduffy
70f6d88a5b Implement the basic ARN/Region IDL types 2017-04-27 11:29:51 -07:00
joeduffy
47ef3f673b Rename PreviewUpdate (again)
Unfortunately, this wasn't a great name.  The old one stunk, but the
new one was misleading at best.  The thing is, this isn't about performing
an update -- it's about NOT doing an update, depending on its return value.
Further, it's not just previewing the changes, it is actively making a
decision on what to do in response to them.  InspectUpdate seems to convey
this and I've unified the InspectUpdate and Update routines to take a
ChangeRequest, instead of UpdateRequest, to help imply the desired behavior.
2017-04-27 11:18:49 -07:00
joeduffy
617ac91c92 Convert the AWS EC2 Instance provider to the new IDL model 2017-04-27 11:07:16 -07:00
joeduffy
43bb3ec766 Reject non-pointer optional fields
This change rejects non-pointer optional fields in the IDL.  Although
there is no reason this couldn't work, technically speaking, it's almost
always certainly a mistake.  Better to issue an error about it; in the
future, we could consider making this a warning.
2017-04-27 11:03:13 -07:00
joeduffy
7b66ae2be5 Add the AWS EC2 VPC IDL
This change includes just the AWS EC2 VPC IDL, and not the corresponding
provider (which is not yet implemented in our system anyway).
2017-04-27 10:49:46 -07:00
joeduffy
d88773b773 Convert AWS EC2 SecurityGroup to the new IDL model 2017-04-27 10:42:35 -07:00
joeduffy
d3899981e0 Make AWS instance DNS/IP outputs optional 2017-04-25 14:03:42 -07:00
Eric Rudder
f8405325db Fixed typo 2017-04-24 09:16:56 -07:00
joeduffy
4671e5f435 Take an initial cut at AWS API Gateway support in Mantle
There are still several loose ends, but this sketches out the
overall shape of the API Gateway usage in Mantle.
2017-04-21 16:47:31 -07:00
joeduffy
0827ca5b58 Implement creation outputs for AWS resources
This change implements the appropriate creation outputs for AWS
resource providers, both on the IDL side and in the providers themselves.
2017-04-21 16:14:59 -07:00
joeduffy
a2b37d7dda Implement an aws.ARN type
This "strongly types" the aws.ARN type.  In reality, it is simply an
alias for a string at the moment (as this is what it boils down to on
the wire), but this at least gets us some amount of compile-time safety.
2017-04-21 14:03:06 -07:00
joeduffy
9b9fac4254 Make iam.Role's managed policy ARNs a string list 2017-04-21 13:27:34 -07:00
joeduffy
cb10ec7014 Mark lambda.Permission's source args as optional 2017-04-21 13:24:56 -07:00
joeduffy
6a6b82e2ab Add the AWS lambda.Permission resource IDL 2017-04-21 13:23:13 -07:00
joeduffy
689dd06949 Add AWS API Gateway resource IDL definitions
This change includes resource IDL definitions for all of AWS API Gateway's
corresponding CloudFormation resource types.  There are no actual provider
implementations yet.
2017-04-21 10:15:19 -07:00
joeduffy
fdd441fd25 Implement the Kubernetes Fission HTTPTrigger provider 2017-04-20 18:40:05 -07:00
joeduffy
3f25aca7dd Add a http.API abstraction to Mantle
This introduces an http.API abstraction to Mantle and implements it
for Kubernetes Fission.  (The AWS implementation will come shortly,
but requires a fair bit of API Gateway elbow grease first.)

This lets you invoke a function in response to an API event:

    let func = new mantle.func.Function(
        (e, ctx, cb => { ... },
    );
    let api = new mantle.http.API("/hello", "GET", func);
2017-04-20 16:05:19 -07:00
joeduffy
0b6e262b46 Rename resource provider methods
This change renames two provider methods:

    * Read becomes Get.

    * UpdateImpact becomes PreviewUpdate.

These just read a whole lot nicer than the old names.
2017-04-20 14:09:00 -07:00
joeduffy
8eecc2c05b Flatten Fission metadata property
This change flattens the Fission metadata property on the Coconut
side so that it is nicer to consume.  Due to struct embedding in Go,
we need to perform translation at the serialization boundary anyway,
so the less-usable approach we had before didn't really buy us anything.
2017-04-19 16:05:33 -07:00
joeduffy
da73d81dd0 Implement the Fission function provider 2017-04-19 15:52:17 -07:00
joeduffy
47a9a6ee08 Implement Kubernetes functions
This change detects when the target scheduler is Kubernetes, and prefers
to schedule atop Fission functions.
2017-04-19 15:36:48 -07:00
joeduffy
cc6dd63556 Use inter-resource references for Fission resources
The Fission internal data structures reference one another by
name/URI.  Coconut needs the graph with dependencies, however, so
we prefer to model things using real object references in these
situations.  (This also makes it much nicer to program.)  This
changes to fit the Coconut model better; the provider will then
turn around and present names/URIs to the various APIs.
2017-04-19 15:33:33 -07:00
joeduffy
cbd3692d3d Initialize the logging libraries 2017-04-19 15:05:18 -07:00
joeduffy
958d67d444 Move NewCheckResponse into coconut/pkg/resource package 2017-04-19 14:25:49 -07:00
joeduffy
366e236853 Implement the Fission provider scaffolding; and Environments 2017-04-19 14:23:01 -07:00
joeduffy
1abda1b49e Glide the AWS provider package 2017-04-19 12:04:24 -07:00
joeduffy
ad87006611 Add an @asset decorator, and a Code asset type
This change introduces an @asset decorator in addition to a Code
asset type.  The idea here is that compilers will recognize the
presence of @asset and react by spewing the code as a textual
asset, rather than an AST and/or actually getting compiled into IL.
2017-04-19 11:43:33 -07:00
joeduffy
48677d8809 Fix some paths
😳
2017-04-19 11:26:41 -07:00
joeduffy
cc37a8078d Implement a basic Fission (Kubernetes FaaS) resource package
This change introduces some resource IDL types for the Fission
project (https://github.com/fission/fission), which is a
functions-as-a-service (FaaS) substrate on top of Kubernetes.

It has a single configuration variable,
`kube-fission:config:controller`, which controls the address of
the Fission controller in the target Kubernetes cluster.

Someday, ideally we would rebuild this atop a more general
Kubernetes resource package, and add some sort of discovery of
this controller, to minimize the amount of manual configuration
required and to make it more resilient to self-healing operations.

This is IDL-only.  The provider is coming soon.
2017-04-19 11:21:35 -07:00
joeduffy
c51fbd57c3 Introduce a new cross-cloud package, Mantle
This introduces a new experimental cross-cloud package, Mantle.  This is part
of getting pulumi/coconut#134 up and running.

For now, there isn't much here, except for configuration of the target cloud and
scheduler, plus the ability to create a cross-cloud function.  (OK, it's not truly
cross-cloud yet, since we have only implemented AWS Lambdas.)

Mantle is, of course, a placeholder name.  Since this is a higher level
abstraction than the unopinionated core primitives, the name mantle corresponds
to the Earth's upper layers (and I thought "Crust" would be a rather odd name).
2017-04-18 15:10:13 -07:00
joeduffy
da75f62865 Retry lambda creation until IAM role is available
Per Amazon's own documentation,
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#launch-instance-with-role,
IAM roles may take "several seconds" to propagate.  In the meantime, we
are apt to get the dreaded "role defined for this function cannot be assumed"
error message.  In response, we'll do what the AWS documentation suggests:
wait a bit and retry.
2017-04-18 13:56:19 -07:00
joeduffy
74772f89e4 Use the role ARN, not its name, for lambda creation 2017-04-18 13:18:04 -07:00
joeduffy
973fccf09d Implement AWS Lambda resource provider
This change introduces a basic AWS Lambda resource provider.  It supports
C--D, but not -RU-, yet.
2017-04-18 11:02:04 -07:00
joeduffy
7878a44ef5 Export inlinePolicy fields 2017-04-17 18:06:12 -07:00
joeduffy
351981a409 Implement AWS IAM Role provider 2017-04-17 17:54:20 -07:00
joeduffy
4c5e13f241 Rearrange asset modules to read nicer 2017-04-17 17:24:08 -07:00
joeduffy
aed7e45d37 Project a smattering of new AWS resource types
This change introduces a bunch of new AWS resource types:

    * aws:iam/Group
    * aws:iam/Policy
    * aws:iam/Role
    * aws:iam/User
    * aws:kms/Key
    * aws:lambda/Function
    * aws:sqs/Queue

None of the associated resource providers are included; this is
an IDL-only projection of the types, their properties, and the
associated API documentation.  Lacking these is blocking me from
making progress on the cross-platform functions project.

It's a little unfortunate to be digging the hole deeper in advance
of pulumi/coconut#133 landing.  However, we are laser-focused on the
pulumi/coconut#134 prototype, so for now I'll just keep going.
2017-04-17 16:55:18 -07:00
joeduffy
b3f430186d Implement S3 bucket objects
This change includes a first basic whack at implementing S3 bucket
objects.  It leverages the assets infrastructure put in place in the
last commit, supporting uploads from text, files, or arbitrary URIs.

Most of the interesting object properties remain unsupported for now,
but with this we can upload and delete basic S3 objects, sufficient
for a lot of the lambda functions management we need to implement.
2017-04-17 13:34:19 -07:00
joeduffy
67248789b3 Introduce assets
This change introduces the basic concept of assets.  It is far from
fully featured, however, it is enough to start adding support for various
storage kinds that require access to I/O-backed data (files, etc).

The challenge is that Coconut is deterministic by design, and so you
cannot simply read a file in an ad-hoc manner and present the bytes to
a resource provider.  Instead, we will model "assets" as first class
entities whose data source is described to the system in a more declarative
manner, so that the system and resource providers can manage them.

There are three ways to create an asset at the moment:

1. A constant, in-memory string.
2. A path to a file on the local filesystem.
3. A URI, whose scheme is extensible.

Eventually, we want to support byte blobs, but due to our use of a
"JSON-like" type system, this isn't easily expressible just yet.

The URI scheme is extensible in that file://, http://, and https://
are supported "out of the box", but individual providers are free to
recognize their own schemes and support them.  For instance, copying
one S3 object to another will be supported simply by passing a URI
with the s3:// protocol in the usual way.

Many utility functions are yet to be written, but this is a start.
2017-04-17 13:00:26 -07:00
joeduffy
89eccfad94 Add an AWS S3 bucket resource and provider 2017-04-17 10:46:19 -07:00
joeduffy
9568954187 Use coco instead of coconut during install 2017-04-17 10:38:03 -07:00
joeduffy
d23d3a5f87 Add the instance maps to the AWS library
For now, this makes the demo nicer; eventually, we probably want
to consider factoring this out into a separate "awsutils" package.
2017-03-15 19:54:29 -07:00
joeduffy
432105d627 Add an enum union type for AWS instance types 2017-03-15 16:12:24 -07:00
joeduffy
95f59273c8 Update copyright notices from 2016 to 2017 2017-03-14 19:26:14 -07:00
joeduffy
774ed45ccc Add an example cpuwatch package
This change includes a simple cpuwatch package, as a demonstration of
how easy it can be to add CPU-level monitoring to an existing stack.

It contains a single API, enableAlarm, that takes an instance and
CPU % threshold; if the CPU ever exceeds that threshold for a sustained
period of time (3 consecutive minutes), an email will be generated.

To use this, first simply install the package as usual, e.g.

    $ coco pack get cpuwatch

From there, you will need to configure the email address to send to:

    $ coco env config <env> cpuwatch:config:emailAddress joe@pulumi.com

And finally, add an import plus call to enableAlarm for all instances:

    import * as cpuwatch from "cpuwatch";
    ..
    let instance = new aws.ec2.Instance(...);
    cpuwatch.enableAlarm(instance, 90); // email if >90% CPU utilization.

As part of this, I've added the typing projections for the AWS SNS topic
and CloudWatch alarm resource types (but no providers just yet).
2017-03-13 12:26:33 -07:00
joeduffy
80d19d4f0b Use the object mapper to reduce provider boilerplate
This changes the object mapper infrastructure to offer more fine-grained
reporting of errors, and control over verification, during the mapping from
an untyped payload to a typed one.  As a result, we can eliminate a bit of
the explicit unmarshaling goo in the AWS providers (but not all of it; I'm
sure there is more we can, and should, be doing here...)
2017-03-12 14:13:44 -07:00
joeduffy
705880cb7f Add the ability to specify analyzers
This change adds the ability to specify analyzers in two ways:

1) By listing them in the project file, for example:

        analyzers:
            - acmecorp/security
            - acmecorp/gitflow

2) By explicitly listing them on the CLI, as a "one off":

        $ coco deploy <env> \
            --analyzer=acmecorp/security \
            --analyzer=acmecorp/gitflow

This closes out pulumi/coconut#119.
2017-03-11 10:07:34 -08:00
joeduffy
b4b4d26844 Add pkg/util/rpcutil to cut down on some plugin boilerplate
This change eliminates some of the boilerplate required to create a
new plugin; mostly this is gRPC-related code.
2017-03-11 09:23:09 -08:00
joeduffy
c36bb75653 Simplify the library README 2017-03-11 09:01:33 -08:00
joeduffy
78407a7477 Check AMI validity
This change checks that the AMI referenced in an instance provisioning
is valid.  If not, the deployment is rejected before even trying.  This
is part of pulumi/coconut#115.
2017-03-10 22:34:25 -08:00
joeduffy
807d355d5a Rename plugin prefix from coco-ressrv to coco-resource 2017-03-10 20:48:09 -08:00
joeduffy
e3e62e55b2 Fix install scripts to use coco pack verify 2017-03-10 09:37:16 -08:00
joeduffy
08c1b10e75 Fix some CocoJS runtime issues
This change fixes up a handful of CocoJS runtime issues preventing
it from compiling; we aren't using much of this yet, but I hope to
resurrect it soon (so more legal ECMAScript code can run).
2017-03-10 09:35:52 -08:00
joeduffy
86dc13ed5b More term rotations
This changes a few naming things:

* Rename "husk" to "environment" (`coco env` for short).

* Rename NutPack/NutIL to CocoPack/CocoIL.

* Rename the primary Nut.yaml/json project file to Coconut.yaml/json.

* Rename the compiled Nutpack.yaml/json file to Cocopack.yaml/json.

* Rename the package asset directory from nutpack/ to .coconut/.
2017-03-06 14:32:39 +00:00
joeduffy
9044047b84 Fix a go vet failure 2017-03-06 13:02:48 +00:00
joeduffy
7cb9ce2663 Implement some AWS provider checking
This change refactors the existing property verification logic for
the AWS provider to use the new checking capabilities.  Beyond just
checking for required properties, there isn't much here yet.  There
is a single check for security group description length that goes
beyond this, mostly for illustration purposes.

This is part of pulumi/coconut#115, although there is clearly more
to do here for something sufficiently snazzy and demoable.
2017-03-03 12:13:19 -08:00
joeduffy
2ce75cb946 Make security group changes imply replacement 2017-03-02 16:16:18 -08:00
joeduffy
966969945b Add a resource.NewUniqueHex API (and use it)
This change adds a new resource.NewUniqueHex API, that simply generates
a unique hex string with the given prefix, with a specific count of
random bytes, and optionally capped to a maximum length.

This is used in the AWS SecurityGroup resource provider to avoid name
collisions, which is especially important during replacements (otherwise
we cannot possibly create a new instance before deleting the old one).

This resolves pulumi/coconut#108.
2017-03-02 16:02:41 -08:00
joeduffy
523c669a03 Track which updates triggered a replacement
This change tracks which updates triggered a replacement.  This enables
better output and diagnostics.  For example, we now colorize those
properties differently in the output.  This makes it easier to diagnose
why an unexpected resource might be getting deleted and recreated.
2017-03-02 15:24:39 -08:00
joeduffy
c633d0ceb0 Add "still waiting" messages to retries 2017-03-02 13:12:40 -08:00
joeduffy
da5e737e08 Update EC2 resources to new Update model 2017-03-02 10:02:05 -08:00
joeduffy
bd613a33e6 Make replacement first class
This change, part of pulumi/coconut#105, rearranges support for
resource replacement.  The old model didn't properly account for
the cascading updates and possible replacement of dependencies.

Namely, we need to model a replacement as a creation followed by
a deletion, inserted into the overall DAG correctly so that any
resources that must be updated are updated after the creation but
prior to the deletion.  This is done by inserting *three* nodes
into the graph per replacement: a physical creation step, a
physical deletion step, and a logical replacement step.  The logical
step simply makes it nicer in the output (the plan output shows
a single "replacement" rather than the fine-grained outputs, unless
they are requested with --show-replace-steps).  It also makes it
easier to fold all of the edges into a single linchpin node.

As part of this, the update step no longer gets to choose whether
to recreate the resource.  Instead, the engine takes care of
orchestrating the replacement through actual create and delete calls.
2017-03-02 09:52:08 -08:00
joeduffy
8698e5abeb Implement replacement for EC2 instances 2017-03-01 13:42:10 -08:00
joeduffy
fe0bb4a265 Support replacement IDs
This change introduces a new RPC function to the provider interface;
in pseudo-code:

    UpdateImpact(id ID, t Type, olds PropertyMap, news PropertyMap)
        (bool, PropertyMap, error)

Essentially, during the planning phase, we will consult each provider
about the nature of a proposed update.  This update includes a set of
old properties and the new ones and, if the resource provider will need
to replace the property as a result of the update, it will return true;
in general, the PropertyMap will eventually contain a list of all
properties that will be modified as a result of the operation (see below).

The planning phase reacts to this by propagating the change to dependent
resources, so that they know that the ID will change (and so that they
can recalculate their own state accordingly, possibly leading to a ripple
effect).  This ensures the overall DAG / schedule is ordered correctly.

This change is most of pulumi/coconut#105.  The only missing piece
is to generalize replacing the "ID" property with replacing arbitrary
properties; there are hooks in here for this, but until pulumi/coconut#90
is addressed, it doesn't make sense to make much progress on this.
2017-03-01 09:08:53 -08:00
joeduffy
a1a8812910 Add a requireRegion helper function
This change adds a requireRegion helper function to the AWS library,
enabling easy fetching of the current region (and/or throwing if the
region hasn't been properly configured).
2017-02-28 12:37:37 -08:00
joeduffy
300f87137c Improve verify; verify packages before install
This change improves the verify command by unifying its package
discovery logic with compile.  All libraries are also now verified
before installing, just to catch silly mistakes (compiler bugs, etc).

This also fixes a verification error in the AWS library due to
pulumi/coconut#104, the inability to use `!` on "anything".
2017-02-28 12:31:50 -08:00
joeduffy
36d9251400 Export lib.es5 and lib.es6 modules
This ensures that TypeScript library references to ES5 and ES6-specific
things resolve to the correct CocoJS runtime library types.
2017-02-28 12:05:45 -08:00
joeduffy
6460ccaa83 Disable the ECMAScript runtime layer
For now, we will disable the CocoJS library's ECMAScript runtime
layer, because it's causing some troubles.  The details -- and
reenabling it -- are tracked in pulumi/coconut#103.
2017-02-28 11:38:19 -08:00
joeduffy
923c3150db Fix the cocojs library
* for ..of isn't yet supported yet (see pulumi/coconut#88); in its
  absence, use a regular for loop so that this library can compile.

* List coconut as a dependency.
2017-02-28 11:32:24 -08:00
joeduffy
679a4bf479 Export a first class Region type 2017-02-28 11:12:34 -08:00
joeduffy
2c6616831f Add AWS configuration variables 2017-02-27 16:52:06 -08:00
joeduffy
9b55505463 Implement AWS security group updates 2017-02-27 13:33:08 -08:00
joeduffy
32379da4f5 Fix a few lingering issues from rename 2017-02-25 07:51:29 -08:00
joeduffy
fbb56ab5df Coconut! 2017-02-25 07:25:33 -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
14e3f19437 Implement name property in AWS provider/library 2017-02-24 15:41:56 -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
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
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
60a51f1222 Implement simple deletion functions 2017-02-20 17:41:24 -08:00
joeduffy
0efb8bdd69 Fix a few things
* Specify MinCount/MaxCount when creating an EC2 instance.  These
  are required properties on the RunInstances API.

* Only attempt to unmarshal egressArray/ingressArray when non-nil.

* Remember the context object on the instanceProvider.

* Move the moniker and object maps into the shared context object.

* Marshal object monikers as the resource IDs to which they refer,
  since monikers are useless on "the other side" of the RPC boundary.
  This ensures that, for example, the AWS provider gets IDs it can use.

* Add some paranoia assertions.
2017-02-20 13:55:09 -08:00
joeduffy
a181956aed Store AWS resource properties directly 2017-02-20 13:06:30 -08:00
joeduffy
276b6c253d Implement a basic AWS resource provider
This commit includes a basic AWS resource provider.  Mostly it is just
scaffolding, however, it also includes prototype implementations for EC2
instance and security group resource creation operations.
2017-02-20 11:18:47 -08:00
joeduffy
6db3d0b687 Install AWS to its proper directory 2017-02-16 08:26:09 -08:00
joeduffy
6dcdf9e884 Fix a few flubs
* Add a TODO as a reminder to implement number toString formatting.

* Change the Loreley delimiters to something obscure ("<{%" and "%}>")
  to avoid conflicting with actual characters we might use in messages.
  Also, make the assertions more descriptive should Loreley fail.

* Rip out a debug.PrintStack() in verbose logging.

* Check the underlying pointer's object type for +=, not the pointer type.
2017-02-16 04:15:07 -08:00
joeduffy
b16590d6c3 Implement some ECMAScript runtime helpers
This change implements some key ECMAScript runtime helpers, straight from
the specification: https://tc39.github.io/ecma262/.  The goal here is to get
a runtime intrinsic for ECMAScript-style toString to work.
2017-02-15 20:09:03 -08:00
joeduffy
2898747db4 Implement intrinsic function machinery
This change implements intrinsic function support in the runtime.

The basic idea is to swap out references to MuIL functions with
runtime-implemented functionality, for operations that cannot be
expressed in the MuIL-subset.  For example, this change includes
two such cases: 1) a mu.runtime.isFunction(obj) function to check if
the target object is a function; and 2) a
mu.runtime.dynamicInvoke(obj,obj,obj[]) function to dynamically
invoke a target object.

These will be used most immediately to implement ECMAScript toString
functionality in the MuJS runtime library, however it will also come
in handy shortly to implement things like printf (marapongo/mu#86),
string and array functions (marapongo/mu#80), and, eventually, the
ECMAScript-specific operators and behavior (marapongo/mu#61).
2017-02-15 15:35:52 -08:00
joeduffy
5b29215195 Implement a MuJS standard library
This change introduces a MuJS standard library.  This will allow us
to support an increasing amount of ECMAScript functionality without
needing to do it in the runtime or the compiler.

The basic idea is as follows.

In the TypeScript compiler, all uses of ECMAScript standard types and
functions get bound to the TypeScript library headers.  These headers
are in the node_modules/typescript/lib/ directory, and there is one
per ECMAScript "standard" (lib.d.ts for ECMAScript 5, lib.es2015.d.ts
for ECMAScript 6, lib.es5016.d.ts for ECMAScript 7, and so on).  Note
that these libraries are "header only", since the functionality for
these are of course supplied by whatever runtime (V8, Chakra, etc)
actually executes the resulting JavaScript code.

In our case, we have no such luxury.  So instead, we intercept these
bindings and transform them into bindings to a MuJS standard library.
This library is just a MuIL library written in MuJS code.  Only the
set of operations expressable in basic MuIL can be used to implement
these.  In select few cases, we will need runtime intrinsics, but those
will not be specific to MuJS and will go into the basic Mu library and
shared among all MetaMu compilers.

At this point, the MuJS standard library only contains the ECMAScript
Error type, so that we can represent throwing errors in MuJS/MuIL.
2017-02-15 11:57:25 -08:00
joeduffy
1568b88e4e Move Mu library files back to root
This change moves the Mu library files back to the root.  Until
marapongo/mu#57 allows us to choose a different index file, via
package.json's "main" attribute, the default module logic won't
work properly with the files underneath src/.
2017-02-13 10:02:40 -08:00
joeduffy
38d9664bf7 Store the resource arguments 2017-02-12 13:36:17 -08:00
joeduffy
acd52778b7 Eliminate the expandTags functionality
This change eliminates the AWS package's cloudformation.expandTags
functionality.  The primary reason is that we haven't yet implemented
string/array intrinsics (see marapongo/mu#80), and so the presence of
this routine was preventing verification of the AWS library.  But, it
turns out, the expandTags routine was violating our "zero artistic
license" principle for the foundational cloud packages.  Namely, it
was auto-adding the Name=<name> tag, when the name property was set,
capturing an idiomatic AWS resource pattern.  Instead of doing that,
we will just project tags in their raw form, and add such conveniences
(possibly) add a higher level in the layer cake.
2017-02-10 15:10:30 -08:00
joeduffy
11b7880547 Further reshuffle Protobufs; generate JavaScript code
After a bit more thinking, we will create new SDK packages for each
of the languages we wish to support writing resource providers in.
This is where the RPC goo will live, so I have created a new sdk/
directory, moved the Protobuf/gRPC definitions underneath sdk/proto/,
and put the generated code into sdk/go/ and sdk/js/.
2017-02-10 09:28:46 -08:00
joeduffy
d67de40cf6 Move Mu library source files underneath src/ directory 2017-02-10 09:10:36 -08:00
joeduffy
432b9666fe Add an install script for the AWS library
Eventually this won't be required, but for now, it will simplify
bringing up our first end-to-end working example.
2017-02-09 16:36:53 -08:00
joeduffy
a3e18fb79a Add a basic Mu standard library install script 2017-02-09 11:18:08 -08:00
joeduffy
37f262e046 Prepare the Mu standard library package
This change:

* Renames the Mu standard library NPM package from "mu" to "@mu/mu".
  This reflects the convention that MuPackages published on NPM will,
  at least initially, be published under the "@mu" scope.  This
  indicates that a package is intended to be consumed by Mu programs.

* Adds an NPM peerDependency on the Mu package from the AWS package.

* Adds a Mu dependency on the Mu package from the AWS MuPackage.
2017-02-09 09:43:18 -08:00
joeduffy
aaefbae956 Eliminate json.ts from the Mu standard library
This is a leftover bit of code from a long time ago, and is no longer needed.
2017-02-09 08:44:39 -08:00
Joe Duffy
382de02bc6 Minor comment update 2017-02-03 05:40:22 -08:00
Luke Hoban
464bd4fe28 Simple EC2 instance example 2017-02-02 22:03:12 -08:00
joeduffy
b9dea700f1 Eliminate some cruft
This nixes the old *.mu files from the AWS MuPackage (when Mull was a thing),
and the nasty YAML files (when Go templates in YAML was a thing...(?!)).  The
TypeScript variants remain, however, which is what we'll use going forward.
2017-02-02 12:48:55 -08:00
joeduffy
b1d371a10e Fix a minor typo with library scope name 2017-02-02 11:13:40 -08:00
joeduffy
6065d2dc26 Update some READMEs from last night
This change updates the READMEs based on some difficulties we had
getting Kurt and Luke's enlistments up and running last night.
2017-02-02 11:09:33 -08:00
joeduffy
8c9c481048 Check in the Mu standard library 2017-02-01 21:06:34 -08:00
joeduffy
bf33605195 Rearrange the library code
This rearranges the library code:

* sdk/... goes away.

* What used to be sdk/javascript/ is now lib/mu/, an actual MuPackage
  that provides the base abstractions for all other MuPackages to use.

* lib/aws is the @mu/aws MuPackage that exposes all AWS resources.

* lib/mux is the @mu/x MuPackage that provides cross-cloud abstractions.
  A lot of what used to be in lib/mu goes here.  In particular, autoscaler,
  func, ..., all the "general purpose" abstractions, really.
2017-01-20 10:30:43 -08:00
joeduffy
729af81e44 Move all cloud switching to mu/x MuPackage
In the old system, the core runtime/toolset understood that we are targeting
specific cloud providers at a very deep level.  In fact, the whole code-generation
phase of the compiler was based on it.

In the new system, this difference is less of a "special" concern, and more of
a general one of mapping MuIL objects to resource providers, and letting *them*
gather up any configuration they need in a more general purpose way.

Therefore, most of this stuff can go.  I've merged in a small amount of it to
the mu/x MuPackage, since that has to switch on cloud IaaS and CaaS providers in
order to decide what kind of resources to provision.  For example, it has a
mu.x.Cluster stack type that itself provisions a lot of the barebone essential
resources, like a virtual private cloud and its associated networking components.

I suspect *some* knowledge of this will surface again as we implement more
runtime presence (discovery, etc).  But for the time being, it's a distraction
getting the core model running.  I've retained some of the old AWS code in the
new pkg/resource/providers/aws package, in case I want to reuse some of it when
implementing our first AWS resource providers.  (Although we won't be using
CloudFormation, some of the name generation code might be useful.)  So, the
ships aren't completely burned to the ground, but they are certainly on 🔥.
2017-01-20 09:46:59 -08:00
joeduffy
33f67f16ae Remove the index entrypoint
For now, an index entrypoint in the MuPackage metadata isn't
required (and in fact, gets rejected as an unrecognized field).
2017-01-17 15:07:11 -08:00
joeduffy
97f5f54fd0 Update the library mu examples to the latest 2016-12-16 11:23:37 -08:00
joeduffy
540d058cf2 Use a separate service for AWS cluster
This change encapsulates what's required for an AWS cluster in new service,
mu/clouds/aws/Cluster, so that mu/Cluster can remain fairly simplistic (it
just switches on the names and dispatches to the appropriate sub-modules).
2016-12-14 15:15:29 -08:00
joeduffy
4bc7737545 Eliminate quotes from module/import statements
There's no need for quotes here and having them makes it feel somehow
"dynamically typed" (I was subconsciously influenced by Go, I think).
Removing them...
2016-12-13 16:47:27 -08:00
joeduffy
468d7f8f3e A few renames
This change renames a few things; more to come, but this is at least
a self-consistent checkpoint:

* Use the "new" keyword to create service objects and not "resource".

* Use the "func" keyword to indicate functions and not "macro".

* Use "bool" instead of "boolean" for boolean types (more Go-like).
2016-12-13 16:39:37 -08:00
joeduffy
e1c3494ba3 Fix two minor issues in the *.mu files
First, I meant to rename "func" to "macro".  This is perhaps contentious,
however my thinking was to differentiate between functions which have runtime
representations -- like lambdas, API gateway handlers, and the like -- and
macros which are purely a metadata/compile-time construct.

Second, there was a resource naming typo.
2016-12-13 15:44:12 -08:00
joeduffy
2d003a2df3 Sketching out a minimal configuration language
This sketches out a minimal configuration language, inspired by a combination
of the Mull document, Hashicorp's various language efforts, Protobufs, and a
mixture of TypeScript.  I'm attempting to whittle down the concepts to the bare
minimum necessary for a universal "intermediate language" for our runtime that
is (a) complete enough to serve our needs, (b) advanced enough to deliver some
of the improvements in componentization and reuse that we desire, (c) appealing
enough that humans are able to write code in the language while possibly even
enjoying it, and, yet, (d) sufficient for machine interoperability needs.

Of course, I will capture all of this in a proper specification (overwriting
the existing Mull one), however I wanted to land these as a proof of concept and
for feedback purposes.  Obviously, none of this code actually compiles or works!
2016-12-13 15:33:13 -08:00
joeduffy
1a3bfc182c Use strongly typed mu.Stacks, not strings, for CloudFormation's dependsOn 2016-12-12 18:56:37 -08:00
joeduffy
832bb80b47 Checkin an initial Mu container that targets AWS ECS
This is a work-in-progress.  In fact, it's going to radically change
given the new approach to representing resource construction, however
I wanted the snapshot in source control as we evolve things.
2016-12-12 17:56:54 -08:00
joeduffy
e731229901 Make the Mu library a Node package; get it compiling
This change morphs the Mu library into a Node package and gets it
compiling against the latest AWS library and SDK changes.
2016-12-12 17:56:13 -08:00
joeduffy
47c67e7d5c Turn the AWS library into a Node package 2016-12-12 17:55:30 -08:00
joeduffy
c7f0465c41 Make an aws/cloudformation module
This includes the original CloudFormation resource type in addition
to the various tag helpers.
2016-12-12 17:54:50 -08:00
joeduffy
d10f2e6bff Get the AWS stacks compiling
This actually compiles... and does absolutely nothing (yet).
2016-12-12 17:25:27 -08:00
joeduffy
3c082ce20e Modularize the AWS proof of concept stacks
And get them building.  Mostly.
2016-12-12 15:35:56 -08:00
joeduffy
5f647b6cc0 Create proof of concept TypeScript resources
This demonstrates what infra-as-code might look like.  Given the difficulties
in expressing everything purely as metadata, I've decided to embark upon a little
spike to see what this would look like.  At first glance, I like it.

To see the difference, compare these to the Mu.yaml files alongside them.
2016-12-12 14:35:00 -08:00
joeduffy
af059c8121 Require cloud=="aws" for aws/x/cf 2016-12-09 13:22:35 -08:00
joeduffy
20e584122a Update aws/ecs/task schema to new format 2016-12-05 18:33:26 -08:00
joeduffy
a9fa42a60c Project ECS task resource stack
This projects the basic AWS::ECS::TaskDefinition CloudFormation template
type as a stack.  It also maps a bunch of schema types using fictitious
syntax, since we don't yet support this (see marapongo/mu#9).  On to that next...
2016-12-05 17:14:22 -08:00
joeduffy
a28f02ce68 Use intrinsics in place of predefineds
This change leverages intrinsics in place of the predefined types.
It remains to be seen if we can reach 100% on this, however I am hopeful.
It's also nice that the system will be built "out of itself" with this
approach; in other words, each of the types is simply a Mufile that can
use conditional targeting as appropriate for the given cloud providers.
If we find that this isn't enough, we can always bring back the concept.
2016-12-05 16:13:49 -08:00
joeduffy
690ee352df Map Route's internet gateway as GatewayId
The route resource is a bit funny, in that it lets you jam in either
an internet gateway ID or a VPC ID as the GatewayId property, whereas
all of the other target kinds get their own property.  Our stack type
offers stronger typing than this (using service references), but we
need to map the resulting ref strings correctly.
2016-12-05 15:37:16 -08:00
joeduffy
069342fef6 Issue an error for missing property names 2016-12-05 15:18:04 -08:00
joeduffy
a82a49291b Simplify mu/x/cf property mapping
I think things have gotten a little out of hand with the way mu/x/cf
auto-maps properties.  In the beginning, it looked like everything could
be trivially auto-mapped, and I wanted to avoid the verbosity of mapping
each property by hand (since you can easily fat finger a name, mess up
capitalization, forget one, etc).  But then we began mapping service
references using proper CloudFormation !Refs, which meant suppressing
some of the auto-mappings, etc., etc.  This led to properties, extraProperties,
skipProperties, renamedProperties, and so on... Pretty confusing IMHO.

I just took a step back and decided to eliminate auto-mapping.  Instead,
you get two options: properties just lists a set of property name mappings,
and extraProperties lets you do template magic to map thing instead if you
wish to take matters into your own hands.  The result isn't too verbose
and has a lot less magic going on so it's easier to understand.
2016-12-05 15:04:33 -08:00
joeduffy
73a3699ea0 Add a renamedProperties section to aws/x/cf
This enables properties to be mapped to arbitrary names, as is needed
to translate strongly typed capability references into string CF IDs.
2016-12-05 14:25:23 -08:00
joeduffy
5b791aab77 Introduce intrinsic types
This change eliminates the special type mu/extension in favor of extensible
intrinsic types.  This subsumes the previous functionality while also fixing
a number of warts with the old model.

In particular, the old mu/extension approach deferred property binding until
very late in the compiler.  In fact, too late.  The backend provider for an
extension simply received an untyped bag of stuff, which it then had to
deal with.  Unfortunately, some operations in the binder are inaccessible
at this point because doing so would cause a cycle.  Furthermore, some
pertinent information is gone at this point, like the scopes and symtables.

The canonical example where we need this is binding services names to the
services themselves; e.g., the AWS CloudFormation "DependsOn" property should
resolve to the actual service names, not the string values.  In the limit,
this requires full binding information.

There were a few solutions I considered, including ones that've required
less code motion, however this one feels the most elegant.

Now we permit types to be marked as "intrinsic."  Binding to these names
is done exactly as ordinary name binding, unlike the special mu/extension
provider name.  In fact, just about everything except code-generation for
these types is the same as ordinary types.  This is perfect for the use case
at hand, which is binding properties.

After this change, for example, "DependsOn" is expanded to real service
names precisely as we need.

As part of this change, I added support for three new basic schema types:

* ast.StringList ("string[]"): a list of strings.
* ast.StringMap ("map[string]any"): a map of strings to anys.
* ast.ServiceList ("service[]"): a list of service references.

Obviously we need to revisit this and add a more complete set.  This work
is already tracked by marapongo/mu#9.

At the end of the day, it's likely I will replace all hard-coded predefined
types with intrinsic types, for similar reasons to the above.
2016-12-05 13:46:18 -08:00
joeduffy
5591103218 Fix a few minor metadata mistakes
As of this, the full cluster Mufile, and its dependencies, typechecks
and produces a valid CloudFormation template!
2016-12-03 15:26:12 -08:00
joeduffy
895f39155e Comment out unmapped AWS types
Now that we're actually type-checking property types, a number of the
AWS stacks began failing, because we haven't yet mapped the full set of
resource types.  I began doing that for the missing ones, but pulling on
that thread just leads to an even larger set ... (possibly all of them!)
due to extra dependencies.  For now, since they aren't required for the
basic scenario, I'll just comment these out; I've logged marapongo/mu#27
to track mapping the full set of resource types.
2016-12-03 11:44:18 -08:00
joeduffy
85b1b5fe0a Fix a YAML problem 2016-12-01 09:13:00 -08:00
joeduffy
68181fd0fd Eliminate <>s in cap names
I wasn't sure at first how we'd distinguish between strings and cap names.
At first, I thought we'd need special syntax, e.g. `<vpn>`; however, now I
am leaning towards a "type inference" approach, where we will interpret the
string as a cap name rather than string if that's what the target property
expects.  Although this isn't quite as explicitly typed, that's probably a
good thing in this case, as it eliminates verbosity and weird characters.
2016-11-29 14:48:55 -08:00
joeduffy
b7b1c5a715 Add readonly annotations on relevant AWS properties 2016-11-29 14:36:07 -08:00
joeduffy
182ae190f1 Use Go template whitespace trimming on AWS templates
To avoid injecting needless whitespace -- which is unfortunately meaningful
in YAML -- we need to use the new "-" trimming operators, available in Go 1.6.
2016-11-29 14:22:09 -08:00
joeduffy
e68ee3523d Project more EC2 Mu Stacks
This change projects several EC2 Mu stacks that are required for Mu cluster
bootstrapping.  This includes:

        - aws/ec2/internetGateway
        - aws/ec2/route
        - aws/ec2/routeTable
        - aws/ec2/securityGroup
        - aws/ec2/subnet
        - aws/ec2/vpc
        - aws/ec2/vpcGatewayAttachment

This is still not complete, and in fact some of these reference other EC2
Stacks that do not yet exist.  But we're getting a bit closer...
2016-11-29 12:37:52 -08:00
joeduffy
d722cc284f Inject the availability zone from cluster settings 2016-11-28 16:30:32 -08:00
joeduffy
f511d30a37 Project the AWS::EC2::VPC resource type into Mu 2016-11-28 16:28:23 -08:00
joeduffy
6f572a6a5b Add an initial whack at a cluster Mufile
This change adds a super simple initial whack at a basic cluster topology
comprised of VPC, subnet, internet gateway, attachments, and route tables.
This is actually written in Mu itself, and I am committing this early, since
there are quite a few features required before we can actually make progress
getting this up and running.
2016-11-28 16:18:38 -08:00
joeduffy
6e77e0f462 Sketch out some cross-cloud abstraction thinking 2016-11-23 16:20:40 -08:00
joeduffy
e37aa602c9 Add an aws/dynamodb/table type 2016-11-23 16:07:26 -08:00
joeduffy
0d6208bb00 Simplify cf/template extension provider
For now, we can simply auto-map the Mu properties to CF properties,
eliminating the need to manually map them in the templates.  Eventually
we'll want more sophistication here to control various aspects of the CF
templates, but this eliminates a lot of tedious manual work in the meantime.
2016-11-23 14:16:35 -08:00