pulumi/sdk/proto/resource.proto
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

119 lines
8 KiB
Protocol Buffer

// Copyright 2016-2018, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
import "google/protobuf/empty.proto";
import "google/protobuf/struct.proto";
import "provider.proto";
package pulumirpc;
// ResourceMonitor is the interface a source uses to talk back to the planning monitor orchestrating the execution.
service ResourceMonitor {
rpc SupportsFeature(SupportsFeatureRequest) returns (SupportsFeatureResponse) {}
rpc Invoke(InvokeRequest) returns (InvokeResponse) {}
rpc StreamInvoke(InvokeRequest) returns (stream InvokeResponse) {}
rpc ReadResource(ReadResourceRequest) returns (ReadResourceResponse) {}
rpc RegisterResource(RegisterResourceRequest) returns (RegisterResourceResponse) {}
rpc RegisterResourceOutputs(RegisterResourceOutputsRequest) returns (google.protobuf.Empty) {}
}
// SupportsFeatureRequest allows a client to test if the resource monitor supports a certain feature, which it may use
// to control the format or types of messages it sends.
message SupportsFeatureRequest {
string id = 1; // the ID of the feature to test support for.
}
message SupportsFeatureResponse {
bool hasSupport = 1; // true when the resource monitor supports this feature.
}
// There is a clear distinction here between the "properties" bag sent across the wire as part of these RPCs and
// properties that exist on Pulumi resources as projected into the target language. It is important to call out that the
// properties here are in the format that a provider will expect. This is to say that they are usually in camel case.
// If a language wants to project properties in a format *other* than camel-case, it is the job of the language to
// ensure that the properties are translated into camel case before invoking an RPC.
// ReadResourceRequest contains enough information to uniquely qualify and read a resource's state.
message ReadResourceRequest {
string id = 1; // the ID of the resource to read.
string type = 2; // the type of the resource object.
string name = 3; // the name, for URN purposes, of the object.
string parent = 4; // an optional parent URN that this child resource belongs to.
google.protobuf.Struct properties = 5; // optional state sufficient to uniquely identify the resource.
repeated string dependencies = 6; // a list of URNs that this read depends on, as observed by the language host.
string provider = 7; // an optional reference to the provider to use for this read.
string version = 8; // the version of the provider to use when servicing this request.
bool acceptSecrets = 9; // when true operations should return secrets as strongly typed.
repeated string additionalSecretOutputs = 10; // a list of output properties that should also be treated as secret, in addition to ones we detect.
repeated string aliases = 11; // a list of additional URNs that shoud be considered the same.
}
// ReadResourceResponse contains the result of reading a resource's state.
message ReadResourceResponse {
string urn = 1; // the URN for this resource.
google.protobuf.Struct properties = 2; // the state of the resource read from the live environment.
}
// RegisterResourceRequest contains information about a resource object that was newly allocated.
message RegisterResourceRequest {
// PropertyDependencies describes the resources that a particular property depends on.
message PropertyDependencies {
repeated string urns = 1; // A list of URNs this property depends on.
}
// CustomTimeouts allows a user to be able to create a set of custom timeout parameters.
message CustomTimeouts {
string create = 1; // The create resource timeout represented as a string e.g. 5m.
string update = 2; // The update resource timeout represented as a string e.g. 5m.
string delete = 3; // The delete resource timeout represented as a string e.g. 5m.
}
string type = 1; // the type of the object allocated.
string name = 2; // the name, for URN purposes, of the object.
string parent = 3; // an optional parent URN that this child resource belongs to.
bool custom = 4; // true if the resource is a custom, managed by a plugin's CRUD operations.
google.protobuf.Struct object = 5; // an object produced by the interpreter/source.
bool protect = 6; // true if the resource should be marked protected.
repeated string dependencies = 7; // a list of URNs that this resource depends on, as observed by the language host.
string provider = 8; // an optional reference to the provider to manage this resource's CRUD operations.
map<string, PropertyDependencies> propertyDependencies = 9; // a map from property keys to the dependencies of the property.
bool deleteBeforeReplace = 10; // true if this resource should be deleted before replacement.
string version = 11; // the version of the provider to use when servicing this request.
repeated string ignoreChanges = 12; // a list of property selectors to ignore during updates.
bool acceptSecrets = 13; // when true operations should return secrets as strongly typed.
repeated string additionalSecretOutputs = 14; // a list of output properties that should also be treated as secret, in addition to ones we detect.
repeated string aliases = 15; // a list of additional URNs that shoud be considered the same.
string importId = 16; // if set, this resource's state should be imported from the given ID.
CustomTimeouts customTimeouts = 17; // ability to pass a custom Timeout block.
bool deleteBeforeReplaceDefined = 18; // true if the deleteBeforeReplace property should be treated as defined even if it is false.
bool supportsPartialValues = 19; // true if the request is from an SDK that supports partially-known properties during preview.
}
// RegisterResourceResponse is returned by the engine after a resource has finished being initialized. It includes the
// auto-assigned URN, the provider-assigned ID, and any other properties initialized by the engine.
message RegisterResourceResponse {
string urn = 1; // the URN assigned by the engine.
string id = 2; // the unique ID assigned by the provider.
google.protobuf.Struct object = 3; // the resulting object properties, including provider defaults.
bool stable = 4; // if true, the object's state is stable and may be trusted not to change.
repeated string stables = 5; // an optional list of guaranteed-stable properties.
}
// RegisterResourceOutputsRequest adds extra resource outputs created by the program after registration has occurred.
message RegisterResourceOutputsRequest {
string urn = 1; // the URN for the resource to attach output properties to.
google.protobuf.Struct outputs = 2; // additional output properties to add to the existing resource.
}