Commit graph

33 commits

Author SHA1 Message Date
Joe Duffy
5a1b1253ab
Save configuration under the stack by default (#696) 2017-12-11 14:41:57 -08:00
Matt Ellis
4f2c599485 Provide a way to opt out of default ignores
Outside of `.pulumiignore` we support a few "default" excludes that
try to push folks towards a pit of succes.

Previously, there was no way to opt out of these, which would be bad
if our  huristics caused something youto really care about to be
elided. With this change, we add an optional setting in Pulumi.yaml
that allows you to opt out of this behavior.

As part of the work, I changed .git to be one of these "default"
excludes instead of it only happening if you had a .pulumiignore file
in a directory
2017-11-22 12:13:44 -08:00
Joe Duffy
98ef0c4bb5
Allow overriding a Pulumi.yaml's entrypoint (#582)
Because the Pulumi.yaml file demarcates the boundary used when
uploading a program to the Pulumi.com service at the moment, we
have trouble when a Pulumi program uses "up and over" references.
For instance, our customer wants to build a Dockerfile located
in some relative path, such as `../../elsewhere/`.

To support this, we will allow the Pulumi.yaml file to live
somewhere other than the main Pulumi entrypoint.  For example,
it can live at the root of the repo, while the Pulumi program
lives in, say, `infra/`:

    Pulumi.yaml:
    name: as-before
    main: infra/

This fixes pulumi/pulumi#575.  Further work can be done here to
provide even more flexibility; see pulumi/pulumi#574.
2017-11-16 07:49:07 -08:00
Matt Ellis
ade366544e Encrypt secrets in Pulumi.yaml
We now encrypt secrets at rest based on a key derived from a user
suplied passphrase.

The system is designed in a way such that we should be able to have a
different decrypter (either using a local key or some remote service
in the Pulumi.com case in the future).

Care is taken to ensure that we do not leak decrypted secrets into the
"info" section of the checkpoint file (since we currently store the
config there).

In addtion, secrets are "pay for play", a passphrase is only needed
when dealing with a value that's encrypted. If secure config values
are not used, `pulumi` will never prompt you for a
passphrase. Otherwise, we only prompt if we know we are going to need
to decrypt the value. For example, `pulumi config <key>` only prompts
if `<key>` is encrypted and `pulumi deploy` and friends only prompt if
you are targeting a stack that has secure configuration assoicated
with it.

Secure values show up as unecrypted config values inside the language
hosts and providers.
2017-10-24 16:48:12 -07:00
Matt Ellis
e361098941 Support global configuration
Previously, config information was stored per stack. With this change,
we now allow config values which apply to every stack a program may
target.

When passed without the `-s <stack>` argument, `pulumi config`
operates on the "global" configuration. Stack specific information can
be modified by passing an explicit stack.

Stack specific configuration overwrites global configuration.

Conside the following Pulumi.yaml:

```
name: hello-world
runtime: nodejs
description: a hello world program
config:
  hello-world:config:message Hello, from Pulumi
stacks:
  production:
    config:
      hello-world:config:message Hello, from Production
```

This program contains a single configuration value,
"hello-world:config:message" which has the value "Hello, from Pulumi"
when the program is activated into any stack except for "production"
where the value is "Hello, from Production".
2017-10-20 13:30:07 -07:00
Matt Ellis
9cf9428638 Save config information in Pulumi.yaml
Instead of having information stored in the checkpoint file, save it
in the Pulumi.yaml file. We introduce a new section `stacks` which
holds information specific to a stack.

Next, we'll support adding configuration information that applies
to *all* stacks for a Program and allow the stack specific config to
overwrite or augment it.
2017-10-20 13:30:07 -07:00
Matt Ellis
9994c9c7b9 Add yaml tags to pack.Package
This will allow us to marhsall and unmarshall the structure using the
go-yaml package directly, instead of the current way we handle YAML
which is to treat it as JSON and use the JSON marshaller behind the
scenes.

By having the explicit tags and using go-yaml directly, we can ensure
the resulting order of the resulting document's properties matches the
go type instead of just being lexigraphicaly sorted.

Long term, we probably want to stop using go-yaml or other packages in
favor of parsing the YAML file into some sort of DOM that we can use
to retain comments and other formatting in the file.
2017-10-20 13:23:31 -07:00
Matt Ellis
c856c5487d Add Load and Save to pack.Package and adopt them 2017-10-20 13:23:31 -07:00
Joe Duffy
f6e694c72b Rename pulumi-fabric to pulumi
This includes a few changes:

* The repo name -- and hence the Go modules -- changes from pulumi-fabric to pulumi.

* The Node.js SDK package changes from @pulumi/pulumi-fabric to just pulumi.

* The CLI is renamed from lumi to pulumi.
2017-09-21 19:18:21 -07:00
joeduffy
1df1b6d572 Get integration tests passing
This makes a few tweaks to get the integration tests passing:

* Add `runtime: nodejs` to the minimal example's `Lumi.yaml` file.

* Remove usage of `@lumi/lumirt { printf }` and just use `console.log`.

* Remove calls to `lumijs` in the integration test framework and
  the minimal example's package.json.  Instead, we just run
  `yarn run build`, which itself internally just invokes `tsc`.

* Add package validation logic and eliminate the pkg/compiler/metadata
  library, in favor of the simpler code in pkg/engine.

* Simplify the Node.js langhost plugin CLI, and simply take an
  argument rather than requiring required and optional --flags.

* Use a default path of "." if the program path isn't provided.  This
  is a legal scenario if you've passed a pwd and just want to load
  the package's default module ("./index.js" or whatever main says).

* Add an executable script, lumi-langhost-nodejs, that fires up the
  `bin/cmd/langhost/index.js` file to serve the Node.js language plugin.
2017-09-04 11:35:21 -07:00
joeduffy
f189c40f35 Wire up Lumi to the new runtime strategy
🔥 🔥 🔥  🔥 🔥 🔥

Getting closer on #311.
2017-09-04 11:35:21 -07:00
joeduffy
35aa6b7559 Rename pulumi/lumi to pulumi/pulumi-fabric
We are renaming Lumi to Pulumi Fabric.  This change simply renames the
pulumi/lumi repo to pulumi/pulumi-fabric, without the CLI tools and other
changes that will follow soon afterwards.
2017-08-02 09:25:22 -07:00
joeduffy
2daea4c3d8 Clarify aspects of using the DCO 2017-06-26 14:46:34 -07:00
joeduffy
3c1041af49 Update license headers 2017-06-23 14:53:41 -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
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
95f59273c8 Update copyright notices from 2016 to 2017 2017-03-14 19:26:14 -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
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
fbb56ab5df Coconut! 2017-02-25 07:25:33 -08:00
joeduffy
6719a6070a Generalize default modules
This change generalizes the support for default modules (added as
part of marapongo/mu#57), to use an "alias" table.  This is just a
table of alternative module names to the real defining module name.
The default module is now just represented as a mapping from the
special default module token, ".default", to the actual defining
module.  This generalization was necessary to support Node.js-style
alternative names for modules, like "lib" mapping to "lib/index".
2017-02-15 12:53:36 -08:00
joeduffy
6c26693fea Move default to a property on package, not a bit on module
The old method of specifying a default module for a package was using
a bit on the module definition itself.  The new method is to specify the
module name as part of the package definition itself.

The new approach makes more sense for a couple reasons.  1) it doesn't
make sense to have more than one "default" for a given package, and yet
the old model didn't prevent this; the new one prevents it by construction.
2) The defaultness of a module is really an aspect of the package, not the
module, who is generally unaware of the package containing it.

The other reason is that I'm auditing the code for nondeterministic map
enumerations, and this came up, which simply pushed me over the edge.
2017-02-06 18:33:31 -07:00
joeduffy
c8044b66ce Fix up a bunch of golint errors 2017-01-27 15:42:39 -08:00
joeduffy
6ea444fd7c Replace tree-walk-style type binding with token map lookups
Now that we have introduced a full blown token map -- new as of just
a few changes ago -- we can start using it for all of our symbol binding.
This also addresses some order-dependent issues, like intra-module
references looking up symbols that have been registered in the token map
but not necessarily stored in the relevant parent symbols just yet.

Plus, frankly, it's much simpler and uses a hashmap lookup instead of
a fairly complex recursive tree walk.

I've kept the tree walk case, however, to improve diagnostics upon
failure.  This allows us to tell developers, for example, that the reason
a binding failed was due to a missing package.
2017-01-26 16:49:38 -08:00
joeduffy
2c0266c9e4 Clean up package URL logic
This change rearranges the old way we dealt with URLs.  In the old system,
virtually every reference to an element, including types, was fully qualified
with a possible URL-like reference.  (The old pkg/tokens/Ref type.)  In the
new model, only dependency references are URL-like.  All maps and references
within the MuPack/MuIL format are token and name based, using the new
pkg/tokens/Token and pkg/tokens/Name family of related types.

As such, this change renames Ref to PackageURLString, and RefParts to
PackageURL.  (The convenient name is given to the thing with "more" structure,
since we prefer to deal with structured types and not strings.)  It moves
out of the pkg/tokens package and into pkg/pack, since it is exclusively
there to support package resolution.  Similarly, the Version, VersionSpec,
and related types move out of pkg/tokens and into pkg/pack.

This change cleans up the various binder, package, and workspace logic.
Most of these changes are a natural fallout of this overall restructuring,
although in a few places we remained sloppy about the difference between
Token, Name, and URL.  Now the type system supports these distinctions and
forces us to be more methodical about any conversions that take place.
2017-01-20 11:46:36 -08:00
joeduffy
7b0dc8ee8d Overhaul names versus tokens
I was sloppy in my use of names versus tokens in the original AST.
Now that we're actually binding things to concrete symbols, etc., we
need to be more precise.  In particular, names are just identifiers
that must be "interpreted" in a given lexical context for them to
make any sense; whereas, tokens stand alone and can be resolved without
context other than the set of imported packages, modules, and overall
module structure.  As such, names are much simpler than tokens.

As explained in the comments, tokens.Names are simple identifiers:

    Name = [A-Za-z_][A-Za-z0-9_]*

and tokens.QNames are fully qualified identifiers delimited by "/":

    QName = [ <Name> "/" ]* <Name>

The legal grammar for a token depends on the subset of symbols that
token is meant to represent.  However, the most general case, that
accepts all specializations of tokens, is roughly as follows:

    Token       = <Name> |
                  <PackageName>
                    [ ":" <ModuleName>
                        [ "/" <ModuleMemberName>
                            [ "." <Class MemberName> ]
                        ]
                    ]

where:

    PackageName         = <QName>
    ModuleName          = <QName>
    ModuleMemberName    = <Name>
    ClassMemberName     = <Name>

Please refer to the comments in pkg/tokens/tokens.go for more details.
2017-01-19 17:57:20 -08:00
joeduffy
25632886c8 Begin overhauling semantic phases
This change further merges the new AST and MuPack/MuIL formats and
abstractions into the core of the compiler.  A good amount of the old
code is gone now; I decided against ripping it all out in one fell
swoop so that I can methodically check that we are preserving all
relevant decisions and/or functionality we had in the old model.

The changes are too numerous to outline in this commit message,
however, here are the noteworthy ones:

    * Split up the notion of symbols and tokens, resulting in:

        - pkg/symbols for true compiler symbols (bound nodes)
        - pkg/tokens for name-based tokens, identifiers, constants

    * Several packages move underneath pkg/compiler:

        - pkg/ast becomes pkg/compiler/ast
        - pkg/errors becomes pkg/compiler/errors
        - pkg/symbols becomes pkg/compiler/symbols

    * pkg/ast/... becomes pkg/compiler/legacy/ast/...

    * pkg/pack/ast becomes pkg/compiler/ast.

    * pkg/options goes away, merged back into pkg/compiler.

    * All binding functionality moves underneath a dedicated
      package, pkg/compiler/binder.  The legacy.go file contains
      cruft that will eventually go away, while the other files
      represent a halfway point between new and old, but are
      expected to stay roughly in the current shape.

    * All parsing functionality is moved underneath a new
      pkg/compiler/metadata namespace, and we adopt new terminology
      "metadata reading" since real parsing happens in the MetaMu
      compilers.  Hence, Parser has become metadata.Reader.

    * In general phases of the compiler no longer share access to
      the actual compiler.Compiler object.  Instead, shared state is
      moved to the core.Context object underneath pkg/compiler/core.

    * Dependency resolution during binding has been rewritten to
      the new model, including stashing bound package symbols in the
      context object, and detecting import cycles.

    * Compiler construction does not take a workspace object.  Instead,
      creation of a workspace is entirely hidden inside of the compiler's
      constructor logic.

    * There are three Compile* functions on the Compiler interface, to
      support different styles of invoking compilation: Compile() auto-
      detects a Mu package, based on the workspace; CompilePath(string)
      loads the target as a Mu package and compiles it, regardless of
      the workspace settings; and, CompilePackage(*pack.Package) will
      compile a pre-loaded package AST, again regardless of workspace.

    * Delete the _fe, _sema, and parsetree phases.  They are no longer
      relevant and the functionality is largely subsumed by the above.

...and so very much more.  I'm surprised I ever got this to compile again!
2017-01-18 12:18:37 -08:00
joeduffy
bc376f8f8d Move pkg/pack/symbols to pkg/symbols 2017-01-17 15:06:53 -08:00
joeduffy
2849a3e64b Print descriptions as header comments 2017-01-16 14:45:32 -08:00
joeduffy
1ad99bcea1 Fix a few AST marshaling things
This fixes a few things so that MuPackages now unmarshal:

* Mark Module.Members as requiring "custom" decoding.  This is required
  because that's the first point in the tree that leverages polymorphism.
  Everything "above" this unmarshals just fine (e.g., package+modules).

* As such, stop marking Package.Modules as "custom".

* Add the Kind field to the Node.  Although we won't use this for type
  discrimination in the same way, since Go gives us RTTI on the structs,
  it is required for unmarshaling (to avoid "unrecognized fields" errors)
  and it's probably handy to have around for logging, messages, etc.

* Mark Position.Line and Column with "json" annotations so that they
  unmarshal correctly.
2017-01-14 11:22:54 -08:00
joeduffy
ab2d0ae6cb Implement tag-directed decoding
This change eliminates boilerplate decoding logic in all the different
data structures, and instead uses a new tag-directed decoding scheme.
This works a lot like the JSON deserializers, in that it recognizes the
`json:"name"` tags, except that we permit annotation of fields that
require custom deserialization, as `json:"name,custom"`.  The existing
`json:"name,omitempty"` tag is recognized for optional fields.
2017-01-14 09:42:05 -08:00
joeduffy
d334ea322b Add custom decoding for MuPack metadata
This adds basic custom decoding for the MuPack metadata section of
the incoming JSON/YAML.  Because of the type discriminated union nature
of the incoming payload, we cannot rely on the simple built-in JSON/YAML
unmarshaling behavior.  Note that for the metadata section -- what is
in this checkin -- we could have, but the IL AST nodes are problematic.
(To know what kind of structure to creat requires inspecting the "kind"
field of the IL.)  We will use a reflection-driven walk of the target
structure plus a weakly typed deserialized map[string]interface{}, as
is fairly customary in Go for scenarios like this (though good libaries
seem to be lacking in this area...).
2017-01-14 07:40:13 -08:00
joeduffy
e7dbfa59c3 Create MuPack and MuIL packages in our Go toolset
This change carries over all of the metadata shapes in the MuPack
and MuIL file formats to our Go toolset.  This includes creating a
proper discriminated AST type tree along with correct annotations
so that the metadata will serialize and deserialize correctly.
2017-01-13 14:32:10 -08:00