Documentation
¶
Overview ¶
Package planmodifiers provides shared Terraform Plugin Framework plan modifiers for use across all resource packages.
Index ¶
- func DecideResetForUnchangedString(sourceEqual bool, stateValue types.String) (types.String, bool)
- func MirrorOfString(sources ...SourceComparer) planmodifier.String
- func ResetIfSourceChangedString(sourcePaths ...path.Expression) planmodifier.String
- func UseKeyedStateForUnknownBool(key string) planmodifier.Bool
- func UseKeyedStateForUnknownString(key string) planmodifier.String
- func UseStateForUnknownInExistingBlockBool() planmodifier.Bool
- func UseStateForUnknownInExistingBlockInt64() planmodifier.Int64
- func UseStateForUnknownInExistingBlockString() planmodifier.String
- type SourceComparer
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DecideResetForUnchangedString ¶
DecideResetForUnchangedString centralises the override decision for the String plan modifier so it can be unit-tested without constructing a full tfsdk.Plan / State. The surrounding plumbing in PlanModifyString (Raw null guards, config-value precedence, path reads) is covered by the acceptance suite.
Returns (value, true) when the caller should overwrite resp.PlanValue, or (zero, false) to leave it untouched (default Unknown).
- sourceEqual=false → (_, false): leave Unknown; apply writes the fresh server value.
- sourceEqual=true + state known + state non-null → (state, true): carry forward.
- state null or unknown → (_, false).
func MirrorOfString ¶
func MirrorOfString(sources ...SourceComparer) planmodifier.String
MirrorOfString returns a plan modifier for a Computed-only string attribute that Jamf Pro derives from one or more SIBLING attributes the same resource manages — a mirror, not an independent server-assigned value.
Neither of the obvious answers is right for a mirror. Plain UseStateForUnknown promises the value cannot change unless the practitioner changes this attribute, but it changes when the *source* changes, so the plan carries a stale value into an apply that returns a fresh one and Terraform reports "Provider produced inconsistent result after apply". Omitting the modifier entirely leaves the attribute Unknown on every plan, which makes `terraform plan -refresh=false` permanently dirty for a value nobody touched.
So: carry the prior value forward while every watched source is unchanged between state and plan, and go Unknown as soon as one of them moves. The sources may be of any type — pass StringSource or BoolSource per path.
Used by jamfplatform_pro_mobile_device_app for general.description (mirrors self_service.self_service_description) and general.deployment_type (mirrors general.deploy_automatically).
func ResetIfSourceChangedString ¶
func ResetIfSourceChangedString(sourcePaths ...path.Expression) planmodifier.String
ResetIfSourceChangedString returns a plan modifier for Optional+Computed string attributes whose server-derived value depends on the bytes of a *_file_source upload input. When any watched source attribute differs between state and plan, the attribute's plan value is left Unknown so the server can populate a fresh value during apply. When all sources are unchanged, the prior state value carries forward (UseStateForUnknown semantics) so trivial metadata updates do not churn the diff.
func UseKeyedStateForUnknownBool ¶ added in v1.4.0
func UseKeyedStateForUnknownBool(key string) planmodifier.Bool
UseKeyedStateForUnknownBool is UseKeyedStateForUnknownString for bool attributes.
func UseKeyedStateForUnknownString ¶ added in v1.4.0
func UseKeyedStateForUnknownString(key string) planmodifier.String
UseKeyedStateForUnknownString carries the prior value of an Optional+Computed string attribute of a set- or list-nested element onto the planned element, but only from the prior element whose key attribute equals the planned element's.
It replaces UseNonNullStateForUnknown inside id-keyed sets. The framework pairs a planned set element with prior state by INDEX, not by identity, so the stock modifier copies whatever sits at the same position: re-keying an element, or reordering the set, hands the new element another object's values. For a server-derived value that is a perpetual or inconsistent diff; for a user-visible default it silently gives a new element the old element's settings. Keyed lookup carries only on a genuine match and otherwise leaves the value Unknown for the server to answer.
Two matches on one key, or none, carry nothing: with duplicates there is no telling which prior element a planned one continues. A list pairs by index in the framework too, which is just as wrong once an element is inserted or reordered. See issue #464.
func UseStateForUnknownInExistingBlockBool ¶ added in v1.4.0
func UseStateForUnknownInExistingBlockBool() planmodifier.Bool
UseStateForUnknownInExistingBlockBool is the bool sibling of UseStateForUnknownInExistingBlockString.
func UseStateForUnknownInExistingBlockInt64 ¶ added in v1.4.0
func UseStateForUnknownInExistingBlockInt64() planmodifier.Int64
UseStateForUnknownInExistingBlockInt64 is the int64 sibling of UseStateForUnknownInExistingBlockString.
func UseStateForUnknownInExistingBlockString ¶ added in v1.4.0
func UseStateForUnknownInExistingBlockString() planmodifier.String
UseStateForUnknownInExistingBlockString returns a plan modifier for an Optional+Computed string inside an Optional single-nested block. It behaves as UseStateForUnknown except when the block is new in this plan, where it leaves the value Unknown. See carryPrior for the rule.
Types ¶
type SourceComparer ¶
type SourceComparer func(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) (unchanged, ok bool)
SourceComparer reports whether one watched source attribute is unchanged by this plan. ok is false when the value could not be read at all, which the caller treats as "cannot tell" and resolves conservatively.
func BoolSource ¶
func BoolSource(p path.Expression) SourceComparer
BoolSource watches a bool attribute.
func NestedStringSource ¶ added in v1.3.0
func NestedStringSource(block path.Expression, attribute string) SourceComparer
NestedStringSource watches one string attribute inside a single-nested block.
Prefer it to a path into an Optional block. When the block is null, PathMatches resolves the expression only as far as the block, so a leaf watcher receives the object's path and fails with "Cannot use attr.Value basetypes.StringValue, only basetypes.ObjectValue is supported". This reads the block first and the leaf from it.
Do not watch the whole block either. compareSource calls a block unchanged only when it is null in config. A declared block with an unset Optional+Computed leaf is null there and populated in state, so the two never compare equal, and the mirror goes Unknown in every plan that changes anything else in the resource, even when the leaf it mirrors did not move.
The result per case:
- A null block, or a null leaf, is unchanged. The practitioner is not moving the source, and an unset Optional+Computed leaf carries its prior value forward itself.
- An Unknown block or leaf is changed. The value is not known until apply (interpolated from a resource still being created), so a prior mirror value may be stale by then and Terraform would reject the result.
- A leaf set where state has no block or no value is changed.
- A set leaf is unchanged exactly when it equals the state value.
- A block that cannot be read, or a leaf the block does not have, cannot be judged, so the mirror stays Unknown.
func StringSource ¶
func StringSource(p path.Expression) SourceComparer
StringSource watches a string attribute.