2018-05-22 21:43:36 +02:00
|
|
|
// 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.
|
2017-06-08 18:26:06 +02:00
|
|
|
|
|
|
|
package resource
|
|
|
|
|
|
|
|
import (
|
2021-03-17 14:20:05 +01:00
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/tokens"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
|
2017-06-08 18:26:06 +02:00
|
|
|
)
|
|
|
|
|
2017-06-10 03:34:37 +02:00
|
|
|
// State is a structure containing state associated with a resource. This resource may have been serialized and
|
2017-06-08 18:26:06 +02:00
|
|
|
// deserialized, or snapshotted from a live graph of resource objects. The value's state is not, however, associated
|
|
|
|
// with any runtime objects in memory that may be actively involved in ongoing computations.
|
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 18:46:30 +01:00
|
|
|
// nolint: lll
|
2017-06-10 03:34:37 +02:00
|
|
|
type State struct {
|
2019-05-09 23:27:34 +02:00
|
|
|
Type tokens.Type // the resource's type.
|
|
|
|
URN URN // the resource's object urn, a human-friendly, unique name for the resource.
|
|
|
|
Custom bool // true if the resource is custom, managed by a plugin.
|
|
|
|
Delete bool // true if this resource is pending deletion due to a replacement.
|
|
|
|
ID ID // the resource's unique ID, assigned by the resource provider (or blank if none/uncreated).
|
|
|
|
Inputs PropertyMap // the resource's input properties (as specified by the program).
|
|
|
|
Outputs PropertyMap // the resource's complete output state (as returned by the resource provider).
|
|
|
|
Parent URN // an optional parent URN that this resource belongs to.
|
|
|
|
Protect bool // true to "protect" this resource (protected resources cannot be deleted).
|
|
|
|
External bool // true if this resource is "external" to Pulumi and we don't control the lifecycle
|
|
|
|
Dependencies []URN // the resource's dependencies
|
|
|
|
InitErrors []string // the set of errors encountered in the process of initializing resource.
|
|
|
|
Provider string // the provider to use for this resource.
|
|
|
|
PropertyDependencies map[PropertyKey][]URN // the set of dependencies that affect each property.
|
|
|
|
PendingReplacement bool // true if this resource was deleted and is awaiting replacement.
|
|
|
|
AdditionalSecretOutputs []PropertyKey // an additional set of outputs that should be treated as secrets.
|
2019-06-01 08:01:01 +02:00
|
|
|
Aliases []URN // TODO
|
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-15 23:26:28 +02:00
|
|
|
CustomTimeouts CustomTimeouts // A config block that will be used to configure timeouts for CRUD operations
|
2020-04-16 03:52:40 +02:00
|
|
|
ImportID ID // the resource's import id, if this was an imported resource.
|
2017-06-08 18:26:06 +02:00
|
|
|
}
|
|
|
|
|
Overhaul resources, planning, and environments
This change, part of pulumi/lumi#90, overhauls quite a bit of the
core resource, planning, environments, and related areas.
The biggest amount of movement comes from the splitting of pkg/resource
into multiple sub-packages. This results in:
- pkg/resource: just the core resource data structures.
- pkg/resource/deployment: all planning and deployment logic.
- pkg/resource/environment: all environment, configuration, and
serialized checkpoint structures and logic.
- pkg/resource/plugin: all dynamically loaded analyzer and
provider logic, including the actual loading and RPC mechanisms.
This also splits the resource abstraction up. We now have:
- resource.Resource: a shared interface.
- resource.Object: a resource that is connected to a live object
that will periodically observe mutations due to ongoing
evaluation of computations. Snapshots of its state may be
taken; however, this is purely a "pre-planning" abstraction.
- resource.State: a snapshot of a resource's state that is frozen.
In other words, it is no longer connected to a live object.
This is what will store provider outputs (ID and properties),
and is what may be serialized into a deployment record.
The branch is in a half-baked state as of this change; more changes
are to come...
2017-06-09 01:37:40 +02:00
|
|
|
// NewState creates a new resource value from existing resource state information.
|
2017-10-05 23:08:35 +02:00
|
|
|
func NewState(t tokens.Type, urn URN, custom bool, del bool, id ID,
|
2018-08-03 23:06:00 +02:00
|
|
|
inputs PropertyMap, outputs PropertyMap, parent URN, protect bool,
|
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 18:46:30 +01:00
|
|
|
external bool, dependencies []URN, initErrors []string, provider string,
|
2019-06-01 08:01:01 +02:00
|
|
|
propertyDependencies map[PropertyKey][]URN, pendingReplacement bool,
|
2020-04-16 03:52:40 +02:00
|
|
|
additionalSecretOutputs []PropertyKey, aliases []URN, timeouts *CustomTimeouts,
|
|
|
|
importID ID) *State {
|
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 18:46:30 +01:00
|
|
|
|
2017-12-08 17:43:39 +01:00
|
|
|
contract.Assertf(t != "", "type was empty")
|
|
|
|
contract.Assertf(custom || id == "", "is custom or had empty ID")
|
|
|
|
contract.Assertf(inputs != nil, "inputs was non-nil")
|
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-15 23:26:28 +02:00
|
|
|
|
|
|
|
s := &State{
|
2019-05-09 23:27:34 +02:00
|
|
|
Type: t,
|
|
|
|
URN: urn,
|
|
|
|
Custom: custom,
|
|
|
|
Delete: del,
|
|
|
|
ID: id,
|
|
|
|
Inputs: inputs,
|
|
|
|
Outputs: outputs,
|
|
|
|
Parent: parent,
|
|
|
|
Protect: protect,
|
|
|
|
External: external,
|
|
|
|
Dependencies: dependencies,
|
|
|
|
InitErrors: initErrors,
|
|
|
|
Provider: provider,
|
|
|
|
PropertyDependencies: propertyDependencies,
|
|
|
|
PendingReplacement: pendingReplacement,
|
|
|
|
AdditionalSecretOutputs: additionalSecretOutputs,
|
2019-06-01 08:01:01 +02:00
|
|
|
Aliases: aliases,
|
2020-04-16 03:52:40 +02:00
|
|
|
ImportID: importID,
|
2017-06-08 18:26:06 +02:00
|
|
|
}
|
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-15 23:26:28 +02:00
|
|
|
|
|
|
|
if timeouts != nil {
|
|
|
|
s.CustomTimeouts = *timeouts
|
|
|
|
}
|
|
|
|
|
|
|
|
return s
|
2017-06-08 18:26:06 +02:00
|
|
|
}
|