Skip to content

Commit fae49e2

Browse files
author
Paddy Carver
committed
Resolve many TODOs.
Update the docs based on feedback from the core team and actually reading their documentation, whoops.
1 parent 7d92438 commit fae49e2

File tree

4 files changed

+194
-98
lines changed

4 files changed

+194
-98
lines changed

tfprotov5/data_source.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@ type DataSourceServer interface {
1515
ValidateDataSourceConfig(context.Context, *ValidateDataSourceConfigRequest) (*ValidateDataSourceConfigResponse, error)
1616

1717
// ReadDataSource is called when Terraform is refreshing a data
18-
// source's state. It is guaranteed that all values will be known at
19-
// this time.
20-
// TODO: we can probably document the requirements the protocol has for
21-
// data sources here.
18+
// source's state.
2219
ReadDataSource(context.Context, *ReadDataSourceRequest) (*ReadDataSourceResponse, error)
2320
}
2421

@@ -32,6 +29,9 @@ type ValidateDataSourceConfigRequest struct {
3229
// See the documentation on `DynamicValue` for more information about
3330
// safely accessing the configuration.
3431
//
32+
// The configuration is represented as a tftypes.Object, with each
33+
// attribute and nested block getting its own key and value.
34+
//
3535
// This configuration may contain unknown values if a user uses
3636
// interpolation or other functionality that would prevent Terraform
3737
// from knowing the value at request time.
@@ -58,7 +58,10 @@ type ReadDataSourceRequest struct {
5858
// See the documentation on `DynamicValue` for information about safely
5959
// accessing the configuration.
6060
//
61-
// This configuration will have known values for all fields.
61+
// The configuration is represented as a tftypes.Object, with each
62+
// attribute and nested block getting its own key and value.
63+
//
64+
// This configuration may have unknown values.
6265
Config *DynamicValue
6366

6467
// ProviderMeta supplies the provider metadata configuration for the
@@ -69,6 +72,9 @@ type ReadDataSourceRequest struct {
6972
// documentation on `DynamicValue` for information about safely
7073
// accessing the configuration.
7174
//
75+
// The configuration is represented as a tftypes.Object, with each
76+
// attribute and nested block getting its own key and value.
77+
//
7278
// This configuration will have known values for all fields.
7379
ProviderMeta *DynamicValue
7480
}
@@ -80,11 +86,8 @@ type ReadDataSourceResponse struct {
8086
// `DynamicValue`. See the documentation on `DynamicValue` for
8187
// information about safely creating the `DynamicValue`.
8288
//
83-
// TODO: we should indicate what requirements providers must meet about
84-
// what must be set in state.
85-
//
86-
// TODO: we should indicate what kind of tftypes.Value providers should
87-
// be supplying to specify state in the proper format.
89+
// The state should be represented as a tftypes.Object, with each
90+
// attribute and nested block getting its own key and value.
8891
State *DynamicValue
8992

9093
// Diagnostics report errors or warnings related to retrieving the

tfprotov5/provider.go

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,13 @@ type ProviderServer interface {
2929
// implement them, but they are a handy interface for defining what a
3030
// resource is to terraform-plugin-go, so they're their own interface
3131
// that is composed into ProviderServer.
32-
//
33-
// It is common, but not required, to fill this part of the
34-
// ProviderServer interface by embeding a ResourceRouter into your
35-
// ProviderServer implementation and inheriting its implementation.
3632
ResourceServer
3733

3834
// DataSourceServer is an interface encapsulating all the data
3935
// source-related RPC requests. ProviderServer implementations must
4036
// implement them, but they are a handy interface for defining what a
4137
// data source is to terraform-plugin-go, so they're their own
4238
// interface that is composed into ProviderServer.
43-
//
44-
// It is common, but not required, to fill this part of the
45-
// ProviderServer interface by embedding a DataSourceRouter into your
46-
// ProviderServer implementation and inheriting its implementation.
4739
DataSourceServer
4840
}
4941

@@ -93,7 +85,15 @@ type PrepareProviderConfigRequest struct {
9385
// the documentation on `DynamicValue` for more information about
9486
// safely accessing the configuration.
9587
//
96-
// TODO: can this configuration contain unknown values?
88+
// The configuration is represented as a tftypes.Object, with each
89+
// attribute and nested block getting its own key and value.
90+
//
91+
// The PrepareProviderConfig RPC call will be called twice; once when
92+
// generating a plan, once when applying the plan. When called during
93+
// plan, Config can contain unknown values if fields with unknown
94+
// values are interpolated into it. At apply time, all fields will have
95+
// known values. Values that are not set in the configuration will be
96+
// null.
9797
Config *DynamicValue
9898
}
9999

@@ -114,6 +114,9 @@ type PrepareProviderConfigResponse struct {
114114
// Config property, indicating that no changes are needed to the
115115
// configuration.
116116
//
117+
// The configuration should be represented as a tftypes.Object, with
118+
// each attribute and nested block getting its own key and value.
119+
//
117120
// TODO: should we provide an implementation that does that that
118121
// provider developers can just embed and not need to implement the
119122
// method themselves, then?
@@ -142,7 +145,15 @@ type ConfigureProviderRequest struct {
142145
// RPC requests. See the documentation on `DynamicValue` for more
143146
// information about safely accessing the configuration.
144147
//
145-
// TODO: can this configuration contain unknown values?
148+
// The configuration is represented as a tftypes.Object, with each
149+
// attribute and nested block getting its own key and value.
150+
//
151+
// The ConfigureProvider RPC call will be called twice; once when
152+
// generating a plan, once when applying the plan. When called during
153+
// plan, Config can contain unknown values if fields with unknown
154+
// values are interpolated into it. At apply time, all fields will have
155+
// known values. Values that are not set in the configuration will be
156+
// null.
146157
Config *DynamicValue
147158
}
148159

tfprotov5/resource.go

Lines changed: 95 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,41 +11,30 @@ import (
1111
type ResourceServer interface {
1212
// ValidateResourceTypeConfig is called when Terraform is checking that
1313
// a resource's configuration is valid. It is guaranteed to have types
14-
// conforming to your schema, but it is not guaranteed that all values
15-
// will be known. This is your opportunity to do custom or advanced
16-
// validation prior to a plan being generated.
14+
// conforming to your schema. This is your opportunity to do custom or
15+
// advanced validation prior to a plan being generated.
1716
ValidateResourceTypeConfig(context.Context, *ValidateResourceTypeConfigRequest) (*ValidateResourceTypeConfigResponse, error)
1817

1918
// UpgradeResourceState is called when Terraform has encountered a
20-
// resource with a state format version that doesn't match the schema's
21-
// state format version. It is the provider's responsibility to modify
22-
// the state to upgrade it to the latest state format version.
19+
// resource with a state in a schema that doesn't match the schema's
20+
// current version. It is the provider's responsibility to modify the
21+
// state to upgrade it to the latest state schema.
2322
UpgradeResourceState(context.Context, *UpgradeResourceStateRequest) (*UpgradeResourceStateResponse, error)
2423

2524
// ReadResource is called when Terraform is refreshing a resource's
26-
// state. It is guaranteed that all values will be known at this time.
27-
//
28-
// TODO: is that true? Do we have all our values at this point?
29-
// TODO: we can probably document the requirements the protocol has for
30-
// what can be set in state here.
25+
// state.
3126
ReadResource(context.Context, *ReadResourceRequest) (*ReadResourceResponse, error)
3227

3328
// PlanResourceChange is called when Terraform is attempting to
3429
// calculate a plan for a resource. Terraform will suggest a proposed
3530
// new state, which the provider can modify or return unmodified to
3631
// influence Terraform's plan.
37-
//
38-
// TODO: we can probably document the requirements the protocol has for
39-
// what can be set in state here.
4032
PlanResourceChange(context.Context, *PlanResourceChangeRequest) (*PlanResourceChangeResponse, error)
4133

4234
// ApplyResourceChange is called when Terraform has detected a diff
4335
// between the resource's state and the user's config, and the user has
4436
// approved a planned change. The provider is to apply the changes
4537
// contained in the plan, and return the resulting state.
46-
//
47-
// TODO: we can probably document the requirements the protocol has for
48-
// what can be set in state here.
4938
ApplyResourceChange(context.Context, *ApplyResourceChangeRequest) (*ApplyResourceChangeResponse, error)
5039

5140
// ImportResourceState is called when a user has requested Terraform
@@ -65,9 +54,13 @@ type ValidateResourceTypeConfigRequest struct {
6554
// the documentation on `DynamicValue` for more information about
6655
// safely accessing the configuration.
6756
//
57+
// The configuration is represented as a tftypes.Object, with each
58+
// attribute and nested block getting its own key and value.
59+
//
6860
// This configuration may contain unknown values if a user uses
6961
// interpolation or other functionality that would prevent Terraform
70-
// from knowing the value at request time.
62+
// from knowing the value at request time. Any attributes not directly
63+
// set in the configuration will be null.
7164
Config *DynamicValue
7265
}
7366

@@ -103,8 +96,8 @@ type UpgradeResourceStateResponse struct {
10396
// a `DynamicValue`. See the documentation on `DynamicValue` for
10497
// information about safely creating the `DynamicValue`.
10598
//
106-
// TODO: we should indicate what kind of tftypes.Value providers should
107-
// be supplying to specify state in the proper format.
99+
// The state should be represented as a tftypes.Object, with each
100+
// attribute and nested block getting its own key and value.
108101
UpgradedState *DynamicValue
109102

110103
// Diagnostics report errors or warnings related to upgrading the
@@ -124,6 +117,9 @@ type ReadResourceRequest struct {
124117
// Terraform knows, represented as a `DynamicValue`. See the
125118
// documentation for `DynamicValue` for information about safely
126119
// accessing the state.
120+
//
121+
// The state is represented as a tftypes.Object, with each attribute
122+
// and nested block getting its own key and value.
127123
CurrentState *DynamicValue
128124

129125
// TODO: what is private for
@@ -137,6 +133,9 @@ type ReadResourceRequest struct {
137133
// documentation on `DynamicValue` for information about safely
138134
// accessing the configuration.
139135
//
136+
// The configuration is represented as a tftypes.Object, with each
137+
// attribute and nested block getting its own key and value.
138+
//
140139
// This configuration will have known values for all fields.
141140
ProviderMeta *DynamicValue
142141
}
@@ -149,11 +148,8 @@ type ReadResourceResponse struct {
149148
// `DynamicValue` for information about safely creating the
150149
// `DynamicValue`.
151150
//
152-
// TODO: we should indicate the requirements providers must meet about
153-
// what must be set in state.
154-
//
155-
// TODO: we should indicate what kind of tftypes.Value providers should
156-
// be supplying to specify state in the proper format.
151+
// The state should be represented as a tftypes.Object, with each
152+
// attribute and nested block getting its own key and value.
157153
NewState *DynamicValue
158154

159155
// Diagnostics report errors or warnings related to retrieving the
@@ -176,22 +172,34 @@ type PlanResourceChangeRequest struct {
176172
// PriorState is the state of the resource before the plan is applied,
177173
// represented as a `DynamicValue`. See the documentation for
178174
// `DynamicValue` for information about safely accessing the state.
175+
//
176+
// The state is represented as a tftypes.Object, with each attribute
177+
// and nested block getting its own key and value.
179178
PriorState *DynamicValue
180179

181180
// ProposedNewState is the state that Terraform is proposing for the
182181
// resource, with the changes in the configuration applied, represented
183182
// as a `DynamicValue`. See the documentation for `DynamicValue` for
184183
// information about safely accessing the state.
185184
//
186-
// The proposed new state may contain unknown values if a user uses
187-
// interpolation or other functionality that would prevent Terraform
188-
// from knowing the value at request time.
185+
// The ProposedNewState merges any non-null values in the configuration
186+
// with any computed attributes in PriorState as a utility to help
187+
// providers avoid needing to implement such merging functionality
188+
// themselves.
189+
//
190+
// The state is represented as a tftypes.Object, with each attribute
191+
// and nested block getting its own key and value.
192+
//
193+
// The ProposedNewState will be null when planning a delete operation.
189194
ProposedNewState *DynamicValue
190195

191196
// Config is the configuration the user supplied for the resource. See
192197
// the documentation on `DynamicValue` for more information about
193198
// safely accessing the configuration.
194199
//
200+
// The configuration is represented as a tftypes.Object, with each
201+
// attribute and nested block getting its own key and value.
202+
//
195203
// This configuration may contain unknown values if a user uses
196204
// interpolation or other functionality that would prevent Terraform
197205
// from knowing the value at request time.
@@ -208,6 +216,9 @@ type PlanResourceChangeRequest struct {
208216
// documentation on `DynamicValue` for information about safely
209217
// accessing the configuration.
210218
//
219+
// The configuration is represented as a tftypes.Object, with each
220+
// attribute and nested block getting its own key and value.
221+
//
211222
// This configuration will have known values for all fields.
212223
ProviderMeta *DynamicValue
213224
}
@@ -220,11 +231,37 @@ type PlanResourceChangeResponse struct {
220231
// the documentation for `DynamicValue` for information about safely
221232
// creating the `DynamicValue`.
222233
//
223-
// TODO: we should indicate the requirements providers must meet about
224-
// what must be set in state.
234+
// This is usually derived from the ProposedNewState passed in the
235+
// PlanResourceChangeRequest, with default values substituted for any
236+
// null values and overriding any computed values that are expected to
237+
// change as a result of the apply operation. This may contain unknown
238+
// values if the value could change but its new value won't be known
239+
// until apply time.
240+
//
241+
// Any value that was non-null in the configuration must either
242+
// preserve the exact configuration value or return the corresponding
243+
// value from the prior state. The value from the prior state should be
244+
// returned when the configuration value is semantically equivalent to
245+
// the state value.
225246
//
226-
// TODO: we should indicate what kind of tftypes.Value providers should
227-
// be supplying to specify state in the proper format.
247+
// Any value that is marked as computed in the schema and is null in
248+
// the configuration may be set by the provider to any value of the
249+
// expected type.
250+
//
251+
// PlanResourceChange will actually be called twice; once when
252+
// generating the plan for the user to approve, once during the apply.
253+
// During the apply, additional values from the configuration--upstream
254+
// values interpolated in that were computed at apply time--will be
255+
// populated. During this second call, any attribute that had a known
256+
// value in the first PlannedState must have an identical value in the
257+
// second PlannedState. Any unknown values may remain unknown or may
258+
// take on any value of the appropriate type. This means the values
259+
// returned in PlannedState should be deterministic and unknown values
260+
// should be used if a field's value may change depending on what value
261+
// ends up filling an unknown value in the config.
262+
//
263+
// The state should be represented as a tftypes.Object, with each
264+
// attribute and nested block getting its own key and value.
228265
PlannedState *DynamicValue
229266

230267
// RequiresReplace is a list of tftypes.AttributePaths that require the
@@ -266,19 +303,30 @@ type ApplyResourceChangeRequest struct {
266303
// PriorState is the state of the resource before the changes are
267304
// applied, represented as a `DynamicValue`. See the documentation for
268305
// `DynamicValue` for information about safely accessing the state.
306+
//
307+
// The state is represented as a tftypes.Object, with each attribute
308+
// and nested block getting its own key and value.
269309
PriorState *DynamicValue
270310

271311
// PlannedState is Terraform's plan for what the state should look like
272312
// after the changes are applied, represented as a `DynamicValue`. See
273313
// the documentation for `DynamicValue` for information about safely
274314
// accessing the state.
315+
//
316+
// This is the PlannedState returned during PlanResourceChange.
317+
//
318+
// The state is represented as a tftypes.Object, with each attribute
319+
// and nested block getting its own key and value.
275320
PlannedState *DynamicValue
276321

277322
// Config is the configuration the user supplied for the resource. See
278323
// the documentation on `DynamicValue` for more information about
279324
// safely accessing the configuration.
280325
//
281-
// This configuration will not contain unknown values.
326+
// The configuration is represented as a tftypes.Object, with each
327+
// attribute and nested block getting its own key and value.
328+
//
329+
// This configuration may contain unknown values.
282330
Config *DynamicValue
283331

284332
// TODO: what is planned private
@@ -292,6 +340,9 @@ type ApplyResourceChangeRequest struct {
292340
// documentation on `DynamicValue` for information about safely
293341
// accessing the configuration.
294342
//
343+
// The configuration is represented as a tftypes.Object, with each
344+
// attribute and nested block getting its own key and value.
345+
//
295346
// This configuration will have known values for all fields.
296347
ProviderMeta *DynamicValue
297348
}
@@ -304,11 +355,16 @@ type ApplyResourceChangeResponse struct {
304355
// See the documentation for `DynamicValue` for information about
305356
// safely creating the `DynamicValue`.
306357
//
307-
// TODO: we should indicate the requirements providers must meet about
308-
// what must be set in state.
358+
// Any attribute, whether computed or not, that has a known value in
359+
// the PlannedState in the ApplyResourceChangeRequest must be preserved
360+
// exactly as it was in NewState.
361+
//
362+
// Any attribute in the PlannedState in the ApplyResourceChangeRequest
363+
// that is unknown must take on a known value at this time. No unknown
364+
// values are allowed in the NewState.
309365
//
310-
// TODO: we should indicate what kind of tftypes.Value providers should
311-
// be supplying to specify state in the proper format.
366+
// The state should be represented as a tftypes.Object, with each
367+
// attribute and nested block getting its own key and value.
312368
NewState *DynamicValue
313369

314370
// TODO: what is private
@@ -371,11 +427,8 @@ type ImportedResource struct {
371427
// `DynamicValue` for information about safely creating the
372428
// `DynamicValue`.
373429
//
374-
// TODO: we should indicate the requirements providers must meet about
375-
// what must be set in state.
376-
//
377-
// TODO: we should indicate what kind of tftypes.Value providers should
378-
// be supplying to specify state in the proper format.
430+
// The state should be represented as a tftypes.Object, with each
431+
// attribute and nested block getting its own key and value.
379432
State *DynamicValue
380433

381434
// TODO: what is private

0 commit comments

Comments
 (0)