Commit graph

69 commits

Author SHA1 Message Date
Pat Gavlin
8e278ca9d3
Improve Python serialization test harness. (#5977)
- Reset the runtime prior to each test
- Use the SDK's `test` decorator instead of `async_test`
- Rename a couple classes to avoid warnings from pytest
2020-12-17 14:45:18 -08:00
Komal
48f43906f4
[sdk/python] - Support enums (#5615)
Co-authored-by: Pat Gavlin <pat@pulumi.com>
2020-11-24 19:15:11 -06:00
Pat Gavlin
3d2e31289a
Add support for serialized resource references. (#5041)
Resources are serialized as their URN, ID, and package version. Each
Pulumi package is expected to register itself with the SDK. The package
will be invoked to construct appropriate instances of rehydrated
resources. Packages are distinguished by their name and their version.

This is the foundation of cross-process resources.

Related to #2430.

Co-authored-by: Mikhail Shilkov <github@mikhail.io>
Co-authored-by: Luke Hoban <luke@pulumi.com>
Co-authored-by: Levi Blackstone <levi@pulumi.com>
2020-10-27 10:12:12 -07:00
Justin Van Patten
97c006b5ce
[sdk/python] Fix secret regression (#5496)
A recent change to output deserialization resulted in secrets being returned unwrapped. This change addresses the regression, ensuring any unwrapped secret values are rewrapped before being returned.
2020-10-01 14:57:51 -07:00
Justin Van Patten
5794a3f482
[sdk/python] Cast numbers intended to be integers to int (#5419)
We recently made a change to the Python codegen to emit `int` type annotations, instead of `float`, for properties that are typed as `schema.IntType`.

But the number values that come back from protobuf structs are always floats (like JSON), so we need to cast the values intended to be integers to `int`.
2020-09-19 21:09:53 -07:00
Justin Van Patten
1ddc09f561
[sdk/python] Add pulumi.runtime.to_json utility (#5307)
Non-string provider inputs must be projected as JSON formatted strings. The current codegen simply calls `json.dumps` for such properties, but this does not work for the new input types, which aren't JSON serializable.

This commit adds a new `pulumi.runtime.to_json` utility function to the core SDK, which is capable of serializing both raw dicts and input types as JSON. The codegen will be updated to make use of this new function rather than `json.dumps`.
2020-09-09 12:08:45 -07:00
Justin Van Patten
d0ba9fbdcd
[sdk/python] Add support for Sequence (#5282)
We currently emit array types as `List[T]` for Python, but `List[T]` is invariant, which causes type checkers like mypy to produce errors when values like `["foo", "bar"]` are passed as args typed as `List[pulumi.Input[str]]` (since `Input[str]` is an alias for `Union[T, Awaitable[T], Output[T]]`. To address this, we should move to using [`Sequence[T]`](https://docs.python.org/3/library/typing.html#typing.Sequence) which is covariant, and does not have this problem.

We actually already do this for `Dict` vs. `Mapping`, emitting map types as `Mapping[str, T]` rather than `Dict[str, T]` because `Mapping[str, T]` is covariant for the value. This change makes us consistent for array types.

These are the SDK changes necessary to support `Sequence[T]`.
2020-09-08 22:22:35 -07:00
Justin Van Patten
69fbd70330
Python: Ignore internal properties when unmarshaling (#5251) 2020-08-28 18:26:16 -07:00
Justin Van Patten
16d226d667
Avoid raising unexpected type errors with Any (#5238)
Avoid raising an `AssertionError` due to unexpected types when a type is annotated as `Any`.
2020-08-27 12:19:46 -07:00
Justin Van Patten
cd9fae599d
Python SDK changes to support input/output classes (#5033)
Python SDK changes to support strongly-typed input/output "dataclasses".
2020-08-19 01:15:56 -07:00
Justin Van Patten
af3d4b890d
Allow pulumi.export calls from unit tests (#4670)
The previous attempt to allow this didn't actually allow it, so this is
take two. As part of the previous attempt, I thought after tweaking the
test I had observed the test failing, and then succeeding after making
the product changes, but I must have been mistaken.

It turns out that our existing mocks tests weren't running at all
because of a missing `__init__.py` file. Once the missing `__init__.py`
is added, the tests run, but other tests ("test mode" tests) fail
because the code that creates the mocks and resources will run during
test discovery, and setting the mocks modifies global state.

To address the test issue, I've moved the mocks tests into their own
`test_with_mocks` package that can be run separately from other tests.

And addressed the original issue, by creating a root Stack resource if
one isn't already present when the mocks are set.
2020-05-20 09:54:40 -07:00
Justin Van Patten
16926504c1
Allow pulumi.export calls from unit tests (#4518)
This change allows importing modules with calls to `pulumi.export` in unit tests. Previously, you'd have to structure the Python program in a way that avoids the `pulumi.export` from being called from unit tests.
2020-04-29 10:03:20 -07:00
komal
28d69e963e add tests for node and python 2020-04-23 11:16:36 -07:00
Mikhail Shilkov
6d32d575e0
Enable features in mock monitor (#4272) 2020-04-03 08:33:40 +02:00
Mikhail Shilkov
0bce094dc1
Fix python mock's call (#4274)
Fix python mock's call
2020-04-03 07:28:52 +02:00
Justin Van Patten
dd104a00a7
Propagate secretness correctly in Python apply (#4273)
* Propagate secretness correctly in Python `apply`

* Improve `apply` test coverage

* Update CHANGELOG.md
2020-04-02 13:01:29 -07:00
Luke Hoban
9da774e180
Fix Python mocks (#4074)
The original version of this code caused inconsistencies in the event
loop associated with a given thread. These changes elimintate the event
loop shenanigans the mocks were trying to play by updating _sync_await
to create an event loop if none exists in the current thread.

It's possible that this will cause problems if the tests run on a
different thread than the original program, as the tests are likely to
end up waiting on outputs created by the program, which is not supported
in Python.

Also adds test coverage of the mocking/testing support in Python.
2020-03-12 21:09:47 -07: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
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
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
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
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
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
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
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
CyrusNajmabadi
d1376db975
Support arbitrary stack export values in python. (#3015) 2019-08-01 20:00:07 -07:00
Luke Hoban
3d4c01abeb
Add Output.concat to Python (#3006)
Fixes #2366
2019-07-31 11:35:05 -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
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
CyrusNajmabadi
54cbda80c1
Store information about a CustomResource's provider in __providers. (#2816) 2019-06-11 16:57:37 -07:00
CyrusNajmabadi
55bb3b2486
Simplify API for passing providers to a ComponentResource. (#2609) 2019-06-06 16:20:12 -07:00
CyrusNajmabadi
71e8bfb61b
Use 'localhost' vs 0.0.0.0 (#2806) 2019-06-06 13:49:04 -07:00
Sean Gillespie
eda5de0f88 Implementation of Read for Python (#2752)
This commit implements read_resource functionality for Python in a
manner identical to the NodeJS implementation. If an "id" option is
passed to a resource via ResourceOptions on construction, that resource
will be read and not created.
2019-05-30 11:04:47 -07:00
Matt Ellis
ae4d126d8c Support Secrets in Python SDK
A new static method, `secret` now exists on `pulumi.Output` which can
be used to create secrets.
2019-05-10 17:07:52 -07:00
Sean Gillespie
ad32d9d8ac
Plumb provider version through language hosts to engine (#2656)
* NodeJS: allow callers to override provider version

* Python: allow callers to override provider version

* NodeJS: add version for invoke

* Python: add version to invoke

* NodeJS: add tests for ReadResource

* Post-merge cleanup

* update doc comments
2019-04-23 11:02:51 -07:00
Luke Hoban
0550f71a35
Add an ignoreChanges resource option (#2657)
Fixes #2277.

Adds a new ignoreChanges resource option that allows specifying a list of property names whose values will be ignored during updates. The property values will be used for Create, but will be ignored for purposes of updates, and as a result also cannot trigger replacements.

This is a feature of the Pulumi engine, not of the resource providers, so no new logic is needed in providers to support this feature. Instead, the engine simply replaces the values of input properties in the goal state with old inputs for properties marked as ignoreChanges.

Currently, only top level properties may be specified in ignoreChanges. In the future, this could be extended to support paths to nested properties (including into array elements) with a JSONPath/JMESPath syntax.
2019-04-22 13:54:48 -07:00
Joe Duffy
644d5dc916
Enable unit testing for Pulumi programs (#2638)
* Enable unit testing for Pulumi programs

This change enables rudimentary unit testing of your Pulumi programs, by introducing a `PULUMI_TEST_MODE` envvar that, when set, allows programs to run without a CLI. That includes

* Just being able to import your Pulumi modules, and test ordinary functions -- which otherwise would have often accidentally triggered the "Not Running in a CLI" error message
* Being able to verify a subset of resource properties and shapes, with the caveat that outputs are not included, due to the fact that this is a perpetual "dry run" without any engine operations occurring

In principle, this also means you can attach a debugger and step through your code.

* Finish the unit testing features

This change

1) Incorporates CR feedback, namely requiring that test mode be
   explicitly enabled for any of this to work.

2) Implements Python support for the same capabilities.

3) Includes tests for both JavaScript and Python SDKs.

* Add a note on unit testing to the CHANGELOG

* Use Node 8 friendly assert API

* Embellish the CHANGELOG entry a bit
2019-04-16 22:20:01 -07:00
CyrusNajmabadi
1f51ec00fc
Revert 'Simplify API for passing providers to a ComponentResource (#2602)' (#2606) 2019-03-28 18:31:03 -07:00
CyrusNajmabadi
49a8e73aa7
Ensure that the values in 'dependsOn' are actually Resources. (#2605) 2019-03-28 17:27:51 -07:00
CyrusNajmabadi
7193622183
Simplify API for passing providers to a ComponentResource (#2602) 2019-03-28 15:04:07 -07:00
Sean Gillespie
e0b516d0cc
Fix an issue with empty ID for CustomResource (#2449)
* Fix an issue with empty ID for CustomResource

The Python runtime was checking the ID field it receives from the engine
against None, assuming that the engine would not set the ID field if one
was not present. However, it does set the ID field; it is set to the
empty string when an ID is not known.

This commit fixes an issue that can cause certain IDs to be erroneously
considered to be known during previews, which can cause problems during
the Check phase of resources that directly reference IDs of other
resources.

* Add CHANGELOG
2019-02-15 09:55:19 -08:00
Sean Gillespie
406c8ea16d
Add a test for exporting Futures (#2447)
It should be possible to export Futures as stack outputs - this test
ensures that this is the case.
2019-02-13 14:05:29 -08:00
Pat Gavlin
6e90ab0341
Add support for explicit delete-before-replace (#2415)
These changes add a new flag to the various `ResourceOptions` types that
indicates that a resource should be deleted before it is replaced, even
if the provider does not require this behavior. The usual
delete-before-replace cascade semantics apply.

Fixes #1620.
2019-01-31 14:27:53 -08:00
Pat Gavlin
35c60d61eb
Follow up on #2369 (#2397)
- Add support for per-property dependencies to the Go SDK
- Add tests for first-class secret rejection in the checkpoint and RPC
  layers and language SDKs
2019-01-28 17:38:16 -08:00
Pat Gavlin
1ecdc83a33 Implement more precise delete-before-replace semantics. (#2369)
This implements the new algorithm for deciding which resources must be
deleted due to a delete-before-replace operation.

We need to compute the set of resources that may be replaced by a
change to the resource under consideration. We do this by taking the
complete set of transitive dependents on the resource under
consideration and removing any resources that would not be replaced by
changes to their dependencies. We determine whether or not a resource
may be replaced by substituting unknowns for input properties that may
change due to deletion of the resources their value depends on and
calling the resource provider's Diff method.

This is perhaps clearer when described by example. Consider the
following dependency graph:

  A
__|__
B   C
|  _|_
D  E F

In this graph, all of B, C, D, E, and F transitively depend on A. It may
be the case, however, that changes to the specific properties of any of
those resources R that would occur if a resource on the path to A were
deleted and recreated may not cause R to be replaced. For example, the
edge from B to A may be a simple dependsOn edge such that a change to
B does not actually influence any of B's input properties. In that case,
neither B nor D would need to be deleted before A could be deleted.

In order to make the above algorithm a reality, the resource monitor
interface has been updated to include a map that associates an input
property key with the list of resources that input property depends on.
Older clients of the resource monitor will leave this map empty, in
which case all input properties will be treated as depending on all
dependencies of the resource. This is probably overly conservative, but
it is less conservative than what we currently implement, and is
certainly correct.
2019-01-28 09:46:30 -08:00
Sean Gillespie
3a50b84733
Explicitly convert dry_run parameter to a bool (#2361)
On startup, when we were populating the Settings object, we failed to
coerce the dry_run parameter from a string to a boolean, which resulted
in is_dry_run always believing that it was a preview. This PR fixes this
oversight by explicitly coercing to a boolean prior to sending the value
to Settings.
2019-01-16 12:06:17 -08:00