Commit graph

187 commits

Author SHA1 Message Date
Luke Hoban 95daaa8cec Fix broken test 2019-12-21 06:51:42 -08:00
Luke Hoban 265acaefe5
Fallback to looking for python when launching Python language host (#3692)
Fixes #3398.
2019-12-20 17:09:00 -08:00
CyrusNajmabadi f4fc00ad0e
Output.apply should lift resources from inner Outputs to the top level output. (#3663) 2019-12-17 14:11:45 -08:00
Justin Van Patten 6c84b008d8
Send resource URN and name to analyzer (#3554)
More information we want to make available to policy packs.
2019-11-21 21:01:15 +00:00
Pat Gavlin e978eaaf5a
Fix Python package versions. (#3505)
Earlier changes to the get-version script were not adopted by the Python
SDK Makefile. This caused package publishing to skip uploads due to
missing versions.
2019-11-13 11:34:59 -08:00
Pat Gavlin 137fd54f1c
Propagate inputs to outputs during preview. (#3327)
These changes restore a more-correct version of the behavior that was
disabled with #3014. The original implementation of this behavior was
done in the SDKs, which do not have access to the complete inputs for a
resource (in particular, default values filled in by the provider during
`Check` are not exposed to the SDK). This lack of information meant that
the resolved output values could disagree with the typings present in
a provider SDK. Exacerbating this problem was the fact that unknown
values were dropped entirely, causing `undefined` values to appear in
unexpected places.

By doing this in the engine and allowing unknown values to be
represented in a first-class manner in the SDK, we can attack both of
these issues.

Although this behavior is not _strictly_ consistent with respect to the
resource model--in an update, a resource's output properties will come
from its provider and may differ from its input properties--this
behavior was present in the product for a fairly long time without
significant issues. In the future, we may be able to improve the
accuracy of resource outputs during a preview by allowing the provider
to dry-run CRUD operations and return partially-known values where
possible.

These changes also introduce new APIs in the Node and Python SDKs
that work with unknown values in a first-class fashion:
- A new parameter to the `apply` function that indicates that the
  callback should be run even if the result of the apply contains
  unknown values
- `containsUnknowns` and `isUnknown`, which return true if a value
  either contains nested unknown values or is exactly an unknown value
- The `Unknown` type, which represents unknown values

The primary use case for these APIs is to allow nested, properties with
known values to be accessed via the lifted property accessor even when
the containing property is not fully know. A common example of this
pattern is the `metadata.name` property of a Kubernetes `Namespace`
object: while other properties of the `metadata` bag may be unknown,
`name` is often known. These APIs allow `ns.metadata.name` to return a
known value in this case.

In order to avoid exposing downlevel SDKs to unknown values--a change
which could break user code by exposing it to unexpected values--a
language SDK must indicate whether or not it supports first-class
unknown values as part of each `RegisterResourceRequest`.

These changes also allow us to avoid breaking user code with the new
behavior introduced by the prior commit.

Fixes #3190.
2019-11-11 12:09:34 -08:00
Alex Clemmer 25d27d09f9 Add StreamInvoke to Provider gRPC interface 2019-11-05 10:47:48 -08:00
Pat Gavlin c383810bf8
Omit unknowns in resources in stack outputs during preview. (#3427)
If a stack output includes a `Resource`, we will as of a recent change
always show the output diff, but this diff will potentially include
unknowns, leading to spurious output like:

```
+ namePrefix : output<string>
```

These changes supress these diffs by adding a special key to the POJO
we generate for resources *during preview only* that indicates that the
POJO represents a Pulumi resource, then stripping all adds of unknown
values from diffs for objects marked with that key.

Fixes #3314.
2019-10-30 11:36:03 -07:00
Chris Smith d2805fcb3f
Add support for aggregate resource analysis (#3366)
* Add AnalyzeStack method to Analyze service

* Protobuf generated code

* Hook up AnalyzeStack method

* Address PR feedback

* Address PR feedback
2019-10-25 08:29:02 -07:00
Ryan Campbell 665b4caa89 Update python FileAsset to accept os.PathLike in addition to str. (#3368)
This should fix #2896.
2019-10-18 14:31:59 -07:00
Luke Hoban 893e51d0ce
Add Python resource transformations support (#3319)
Adds Python support for resource transformations aligned with the existing NodeJS support in #3174.

This PR also moves processing of transformations to earlier in the resource construction process (for both NodeJS and Python) to ensure that invariants established in the constructor cannot be violated by transformations. This change can technically be a breaking change, but given that (a) the transformations features was just released in 1.3.0 and (b) the cases where this is a breaking change are uncommon and unlikely to have been reliable anyway - it feels like a change we should make now.

Fixes #3283.
2019-10-14 19:35:00 -05:00
Pat Gavlin 834e583c95
Revert "Propagate inputs to outputs during preview. (#3245)" (#3324)
This reverts commit 80504bf0bc.
2019-10-10 10:33:05 -07:00
Pat Gavlin 80504bf0bc
Propagate inputs to outputs during preview. (#3245)
These changes restore a more-correct version of the behavior that was
disabled with #3014. The original implementation of this behavior was
done in the SDKs, which do not have access to the complete inputs for a
resource (in particular, default values filled in by the provider during
`Check` are not exposed to the SDK). This lack of information meant that
the resolved output values could disagree with the typings present in
a provider SDK. Exacerbating this problem was the fact that unknown
values were dropped entirely, causing `undefined` values to appear in
unexpected places.

By doing this in the engine and allowing unknown values to be
represented in a first-class manner in the SDK, we can attack both of
these issues.

Although this behavior is not _strictly_ consistent with respect to the
resource model--in an update, a resource's output properties will come
from its provider and may differ from its input properties--this
behavior was present in the product for a fairly long time without
significant issues. In the future, we may be able to improve the
accuracy of resource outputs during a preview by allowing the provider
to dry-run CRUD operations and return partially-known values where
possible.

These changes also introduce new APIs in the Node and Python SDKs
that work with unknown values in a first-class fashion:
- A new parameter to the `apply` function that indicates that the
  callback should be run even if the result of the apply contains
  unknown values
- `containsUnknowns` and `isUnknown`, which return true if a value
  either contains nested unknown values or is exactly an unknown value
- The `Unknown` type, which represents unknown values

The primary use case for these APIs is to allow nested, properties with
known values to be accessed via the lifted property accessor even when
the containing property is not fully know. A common example of this
pattern is the `metadata.name` property of a Kubernetes `Namespace`
object: while other properties of the `metadata` bag may be unknown,
`name` is often known. These APIs allow `ns.metadata.name` to return a
known value in this case.

In order to avoid exposing downlevel SDKs to unknown values--a change
which could break user code by exposing it to unexpected values--a
language SDK must indicate whether or not it supports first-class
unknown values as part of each `RegisterResourceRequest`.

These changes also allow us to avoid breaking user code with the new
behavior introduced by the prior commit.

Fixes #3190.
2019-09-30 11:03:58 -07:00
CyrusNajmabadi da0bcdccda
Coerce dictionary values to a list. (#3242) 2019-09-18 15:58:20 -07:00
Pat Gavlin 82204230e1
Improve tracing support. (#3238)
* Fix some tracing issues.

- Add endpoints for `startUpdate` and `postEngineEventsBatch` so that
  spans for these invocations have proper names
- Inject a tracing span when walking a plan so that resource operations
  are properly parented
- When handling gRPC calls, inject a tracing span into the call's
  metadata if no span is already present so that resource monitor and
  engine spans are properly parented
- Do not trace client gRPC invocations of the empty method so that these
  calls (which are used to determine server availability) do not muddy
  the trace. Note that I tried parenting these spans appropriately, but
  doing so broke the trace entirely.

With these changes, the only unparented span in a typical Pulumi
invocation is a single call to `getUser`. This span is unparented
because that call does not have a context available. Plumbing a context
into that particular call is surprisingly tricky, as it is often called
by other context-less functions.

* Make tracing support more flexible.

- Add support for writing trace data to a local file using Appdash
- Add support for viewing Appdash traces via the CLI
2019-09-16 14:16:43 -07:00
Matt Ellis b019bc571e Use Python 3
Use `python3` and `pip3` explicitly, as we now depend on Python 3.
2019-09-13 11:58:23 -07:00
Matt Ellis 32ac67e6bc Remove the need for pandoc during the build
We had been using `pandoc` to convert our README.md into a README.rst
for use with `setup.py` and the python package ecosystem. It turns out
that we can use markdown if we set a content type. So let's do that
and make things a little simpler.

While I was in the area, I made the encoding of UTF-8 explicit when
opening README.md.
2019-09-09 11:15:42 -07:00
Pat Gavlin 48c8ea1e8a
Do not drop unhandled exceptions in Python (#3170)
- Do not use a non-zero-to-zero transition in the number of outstanding
  RPCs to determine the completion of a Python program until after the
  synchronous piece of the program has finished running is complete
- Instead of using a future to indicate that either a) a zero-to-one
  transition in the number of outstanding RPCs has occurred, or b) an
  unhandled exception has occurred, a) observe the transition itself,
  and b) use an optional exception field to track the presence or
  absence of an exception.

Fixes #3162.
2019-09-06 13:53:07 -07:00
Joe Duffy 2b48611d9c
Don't encourage PULUMI_TEST_MODE (#3146)
We intend to replace PULUMI_TEST_MODE with better testing support
that doesn't suffer from all the pitfalls of our current approach.
Unfortunately, we don't yet have complete guidance or validation
that the new approaches will work for all existing end users. So,
until we do, we'll take a lighter touch approach here, and simply
not encourage new usage of PULUMI_TEST_MODE.

Issue #3045 will remain open to track a mroe permanent fix.
2019-08-26 18:49:13 -07:00
CyrusNajmabadi 590114497e
Simplify merge code. (#3122) 2019-08-20 17:09:53 -07:00
Pat Gavlin 8745440c1b
Allow users to explicitly disable delete-before-replace. (#3118)
With these changes, a user may explicitly set `deleteBeforeReplace` to
`false` in order to disable DBR behavior for a particular resource. This
is the SDK + CLI escape hatch for cases where the changes in
https://github.com/pulumi/pulumi-terraform/pull/465 cause undesirable
behavior.
2019-08-20 15:51:02 -07:00
CyrusNajmabadi d0a72fc24d
Allow ResourceOptions.id to be an Input in python (to match JS sdk). (#3116) 2019-08-20 12:18:48 -07:00
CyrusNajmabadi 8290377cbd
Add some simple typechecking (#3109) 2019-08-19 13:19:16 -07:00
Matt Ellis 0bb4e6d70b Respond to PR feedback
Address post commit feedback from Cyrus on
pulumi/pulumi#3071
2019-08-15 12:42:51 -07:00
CyrusNajmabadi 20058f982d
Make 'ResourceOptions.merge' static so downstream clients don't have to manually handle None cases. (#3072) 2019-08-14 15:55:03 -07:00
Matt Ellis 9308246114 Do not taint all stack outputs as secrets if just one is
When using StackReference, if the stack you reference contains any
secret outputs, we have to mark the entire `outputs` member as a
secret output. This is because we only track secretness on a per
`Output<T>` basis.

For `getSecret` and friends, however, we know the name of the output
you are looking up and we can be smarter about if the returned
`Output<T>` should be treated as a secret or not.

This change augments the provider for StackReference such that it also
returns a list of top level stack output names who's values contain
secrets. In the language SDKs, we use this information, when present,
to decide if we should return an `Output<T>` that is marked as a
secret or not. Since the SDK and CLI are independent components, care
is taken to ensure that when the CLI does not return this information,
we behave as we did before (i.e. if any output is a secret, we treat
every output as a secret).

Fixes #2744
2019-08-13 16:11:38 -07:00
CyrusNajmabadi de254aa389
Do not include 'test' package in our python library. (#3067) 2019-08-12 11:32:33 -07:00
Pat Gavlin 7fef102bc3
Check for valid PB types in serialize_property (#3060)
Just what it says on the tin. This allows us to return an incrementally
better error.

Fixes #2939.
2019-08-09 16:48:28 -07:00
Pat Gavlin 91af1a93c4
Fix a reentrancy issue in _sync_await. (#3056)
_sync_await was not reentrant with respect to _run_once: the latter
captures the length of the ready list before it iterates it, and the
former drains the ready list by reentering _run_once. Fix this by
tracking the length of the list before pumping the event loop and then
pushing cancelled handles on to the list as necessary after pumping the
loop.

These changes also fix an issue with `export`ing awaitables.

Fixes #3038.
2019-08-08 19:51:11 -07:00
CyrusNajmabadi a13a04b193
Move resource-options check down to core layer. (#3043) 2019-08-06 17:39:34 -07:00
CyrusNajmabadi 60206e716b
Fix spellin (#3041) 2019-08-06 16:16:33 -07:00
Pat Gavlin 2ab814fd09
Do not resolve missing outputs to inputs in preview. (#3014)
This can cause `apply`s to run on values that may change during an
update, which can lead to unexpected behavior.

Fixes #2433.
2019-08-05 12:44:04 -07:00
Pat Gavlin 06034fab40
Only await input properties once. (#3024)
These changes fix a bug in the Python runtime that would cause any
awaitable input properties passed to a resource that are missing
from the resource's output properties to be awaited twice. The fix is
straightforward: rather than roundtripping an input property through
serialize/deserialize, just deserialized the already-serialized input
property.

Fixes #2940.
2019-08-03 10:29:19 -07:00
Pat Gavlin 00bc1287af
Support synchronous invokes in Python 3.6. (#3025)
Python 3.6 does not expose _{enter,leave}_task. Detect this situation
and implement the equivalent operation as necessary.
2019-08-02 16:52:56 -07:00
Pat Gavlin 63eb7abb59
Make pulumi.runtime.invoke synchronous. (#3019)
These changes make the `pulumi.runtime.invoke` function invokable in a
synchronous manner. Because this function still needs to perform
asynchronous work under the covers--namely awaiting a provider URN and
ID if a provider instance is present in the `InvokeOptions`--this
requires some creativity. This creativity comes in the form of a helper
function, `_sync_await`, that performs a logical yield from the
currently running event, manually runs the event loop until the given
future completes, performs a logical resume back to the
currently executing event, and returns the result of the future.

The code in `_sync_await` is a bit scary, as it relies upon knowledge of
(and functions in) the internals of the `asyncio` package. The necessary
work performed in this function was derived from the implementations of
`task_step` (which pointed out the need to call `_{enter,leave}_task`)
and `BaseEventLoop.run_forever` (which illustrated how the event loop is
pumped). In addition to potential breaking changes to these internals,
the code may not work if a user has provided an alternative implementation
for `EventLoop`. That said, the code is a close enough copy of
`BaseEventLoop.run_forever` that it should be a reasonable solution.
2019-08-02 14:19:56 -07:00
Charlie Hills 654f5e2d35 Fixes python get_secret always returning None (#3022)
get_secret was looking up secrets by the fully resolved key, but should use the simple key.
2019-08-02 09:59:51 -07:00
CyrusNajmabadi d1376db975
Support arbitrary stack export values in python. (#3015) 2019-08-01 20:00:07 -07:00
Luke Hoban aac25eabc4
Add requireOutput to StackReference (#3007)
Provides an additional helper function to read outputs from a stack reference in case it is known that the stack output must be present. This is similar to the design for config.get and config.require.

Fixes #2343.
2019-08-01 11:27:32 -07:00
Luke Hoban 3d4c01abeb
Add Output.concat to Python (#3006)
Fixes #2366
2019-07-31 11:35:05 -07:00
Pat Gavlin 67ec74bdc5
Pass ignoreChanges to providers. (#3005)
These changes add support for passing `ignoreChanges` paths to resource
providers. This is intended to accommodate providers that perform diffs
between resource inputs and resource state (e.g. all Terraform-based
providers, the k8s provider when using API server dry-runs). These paths
are specified using the same syntax as the paths used in detailed diffs.

In addition to passing these paths to providers, the existing support
for `ignoreChanges` in inputs has been extended to accept paths rather
than top-level keys. It is an error to specify a path that is missing
one or more component in the old or new inputs.

Fixes #2936, #2663.
2019-07-31 11:39:07 -05:00
CyrusNajmabadi 93f0bd708d
Add helper function for merging ResourceOptions (#2988) 2019-07-29 12:01:10 -07:00
CyrusNajmabadi 237f8d2222
Add python aliases support. (#2974) 2019-07-25 11:21:06 -07:00
Chris Smith 208dfc29b4
Update references to pulumi.io (#2979)
* Remove pulumi.io reference in tests

* Remove pulumi.io references in Dockerfiles

* Remove pulumi.io references in CONTRIBUTING.md

* Update README.md's

* Use correct logo
2019-07-25 09:58:12 -07:00
Luke Hoban fa4da84669
Add get_object functions to Python SDK (#2959)
Fixes #2320
2019-07-20 07:04:18 -07:00
Pat Gavlin b0fc599e02 Restore the old pickler in a try/finally (#2954)
Just what it says on the tin.
2019-07-19 12:08:15 -07:00
Luke Hoban 3768e5c690
Python Dynamic Providers (#2900)
Dynamic providers in Python.

This PR uses [dill](https://pypi.org/project/dill/) for code serialization, along with a customization to help ensure deterministic serialization results.

One notable limitation - which I believe is a general requirement of Python - is that any serialization of Python functions must serialize byte code, and byte code is not safely versioned across Python versions.  So any resource created with Python `3.x.y` can only be updated by exactly the same version of Python.  This is very constraining, but it's not clear there is any other option within the realm of what "dynamic providers" are as a feature.  It is plausible that we could ensure that updates which only update the serialized provider can avoid calling the dynamic provider operations, so that version updates could still be accomplished.  We can explore this separately.

```py
from pulumi import ComponentResource, export, Input, Output
from pulumi.dynamic import Resource, ResourceProvider, CreateResult, UpdateResult
from typing import Optional
from github import Github, GithubObject

auth = "<auth token>"
g = Github(auth)

class GithubLabelArgs(object):
    owner: Input[str]
    repo: Input[str]
    name: Input[str]
    color: Input[str]
    description: Optional[Input[str]]
    def __init__(self, owner, repo, name, color, description=None):
        self.owner = owner
        self.repo = repo
        self.name = name
        self.color = color
        self.description = description

class GithubLabelProvider(ResourceProvider):
    def create(self, props):
        l = g.get_user(props["owner"]).get_repo(props["repo"]).create_label(
            name=props["name"],
            color=props["color"],
            description=props.get("description", GithubObject.NotSet))
        return CreateResult(l.name, {**props, **l.raw_data}) 
    def update(self, id, _olds, props):
        l = g.get_user(props["owner"]).get_repo(props["repo"]).get_label(id)
        l.edit(name=props["name"],
               color=props["color"],
               description=props.get("description", GithubObject.NotSet))
        return UpdateResult({**props, **l.raw_data})
    def delete(self, id, props):
        l = g.get_user(props["owner"]).get_repo(props["repo"]).get_label(id)
        l.delete()

class GithubLabel(Resource):
    name: Output[str]
    color: Output[str]
    url: Output[str]
    description: Output[str]
    def __init__(self, name, args: GithubLabelArgs, opts = None):
        full_args = {'url':None, 'description':None, 'name':None, 'color':None, **vars(args)}
        super().__init__(GithubLabelProvider(), name, full_args, opts)

label = GithubLabel("foo", GithubLabelArgs("lukehoban", "todo", "mylabel", "d94f0b"))

export("label_color", label.color)
export("label_url", label.url)
```


Fixes https://github.com/pulumi/pulumi/issues/2902.
2019-07-19 10:18:25 -07:00
Alex Clemmer cd86475009 Add GetAnalyzerInfo to Analyzer gRPC definition
`GetAnalyzerInfo` is an RPC command that allows the Pulumi CLI to ask an
`Analyzer` for metadata about the resource policies it defines.

This is useful because the Pulumi service needs to be able to render
metadata about a policy pack after the user runs a `pulumi policy
publish`. Since we don't execute code on the server, the first step of
`policy publish` is to interrogate the policy pack program about what
policies it has, so that this metadata can be sent to the server, along
with a packed version of those policies.
2019-07-16 00:58:33 -07:00
Paul Stack 02ffff8840
Addition of Custom Timeouts (#2885)
* Plumbing the custom timeouts from the engine to the providers

* Plumbing the CustomTimeouts through to the engine and adding test to show this

* Change the provider proto to include individual timeouts

* Plumbing the CustomTimeouts from the engine through to the Provider RPC interface

* Change how the CustomTimeouts are sent across RPC

These errors were spotted in testing. We can now see that the timeout
information is arriving in the RegisterResourceRequest

```
req=&pulumirpc.RegisterResourceRequest{
           Type:                    "aws:s3/bucket:Bucket",
           Name:                    "my-bucket",
           Parent:                  "urn:pulumi:dev::aws-vpc::pulumi:pulumi:Stack::aws-vpc-dev",
           Custom:                  true,
           Object:                  &structpb.Struct{},
           Protect:                 false,
           Dependencies:            nil,
           Provider:                "",
           PropertyDependencies:    {},
           DeleteBeforeReplace:     false,
           Version:                 "",
           IgnoreChanges:           nil,
           AcceptSecrets:           true,
           AdditionalSecretOutputs: nil,
           Aliases:                 nil,
           CustomTimeouts:          &pulumirpc.RegisterResourceRequest_CustomTimeouts{
               Create:               300,
               Update:               400,
               Delete:               500,
               XXX_NoUnkeyedLiteral: struct {}{},
               XXX_unrecognized:     nil,
               XXX_sizecache:        0,
           },
           XXX_NoUnkeyedLiteral: struct {}{},
           XXX_unrecognized:     nil,
           XXX_sizecache:        0,
       }
```

* Changing the design to use strings

* CHANGELOG entry to include the CustomTimeouts work

* Changing custom timeouts to be passed around the engine as converted value

We don't want to pass around strings - the user can provide it but we want
to make the engine aware of the timeout in seconds as a float64
2019-07-16 00:26:28 +03:00
Pat Gavlin e1a52693dc
Add support for importing existing resources. (#2893)
A resource can be imported by setting the `import` property in the
resource options bag when instantiating a resource. In order to
successfully import a resource, its desired configuration (i.e. its
inputs) must not differ from its actual configuration (i.e. its state)
as calculated by the resource's provider.

There are a few interesting state transitions hiding here when importing
a resource:
1. No prior resource exists in the checkpoint file. In this case, the
   resource is simply imported.
2. An external resource exists in the checkpoint file. In this case, the
   resource is imported and the old external state is discarded.
3. A non-external resource exists in the checkpoint file and its ID is
   different from the ID to import. In this case, the new resource is
   imported and the old resource is deleted.
4. A non-external resource exists in the checkpoint file, but the ID is
   the same as the ID to import. In this case, the import ID is ignored
   and the resource is treated as it would be in all cases except for
   changes that would replace the resource. In that case, the step
   generator issues an error that indicates that the import ID should be
   removed: were we to move forward with the replace, the new state of
   the stack would fall under case (3), which is almost certainly not
   what the user intends.

Fixes #1662.
2019-07-12 11:12:01 -07:00
Matt Ellis 858517a7ca Correctly push secretness up during deserialization in runtimes
There current RPC model for Pulumi allows secret values to be deeply
embedded in lists or maps, however at the language level, since we
track secrets via `Output<T>` we need to ensure that during
deserialization, if a list or a map contains a secret, we need to
instead treat it as if the entire list or map was a secret.

We have logic in the language runtimes to do this as part of
serialization. There were a few issues this commit addresses:

- We were not promoting secretness across arrays in either Node or
  Python
- For Python, our promotion logic was buggy and caused it to behave in
  a manner where if any value was secret, the output values of the
  object would be corrupted, because we'd incorrectly treat the
  outputs as a secret who's value was a map, instead of a map of
  values (some of which may be secret).

This caused very confusing behavior, because it would appear that a
resource creation call just did not set various output properties when
one or more of them ended up containing a secret.
2019-07-09 10:40:27 -07:00