Documentation
¶
Overview ¶
Package mac provides a custom Terraform attribute type for MAC addresses used by the Hyper-V provider. The custom type's purpose is to suppress spurious diffs and "Provider produced inconsistent result after apply" failures arising from MAC-representation mismatches between user input and what Hyper-V cmdlets emit on Read.
The mismatch is purely cosmetic: Hyper-V's Set-VMNetworkAdapter accepts MACs in any of three forms (`AA:BB:CC:DD:EE:FF`, `AA-BB-CC-DD-EE-FF`, or `AABBCCDDEEFF`) but Get-VMNetworkAdapter always echoes back the unsigned-12-hex form. Without semantic equality, the framework's plan-vs-apply consistency check fires when a user writes `AA:BB:CC:DD:EE:FF` and the post-apply Read returns `AABBCCDDEEFF` -- a real bug surfaced by the v5 acceptance tests.
Casing is also folded for comparison: Hyper-V normalizes to uppercase, but a user who writes lowercase shouldn't see a phantom diff on the next refresh.
The stored attribute value preserves the user's original form -- only equality comparison (StringSemanticEquals) normalizes. This keeps plan output readable in the user's chosen style while keeping the provider's plan/apply contract honest.
Usage:
"mac_address": schema.StringAttribute{
CustomType: mac.Type,
Optional: true,
Computed: true,
...
}
And in the model struct:
type NetworkAdapterModel struct {
MacAddress mac.MAC `tfsdk:"mac_address"`
...
}
MAC embeds basetypes.StringValue, so existing call sites that use .ValueString() / .IsNull() / .IsUnknown() continue to work unchanged.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var Type = macType{}
Type is the singleton attribute type for MAC addresses. Pass it as `CustomType:` on string attributes whose value is a MAC emitted by a Hyper-V cmdlet or supplied by an operator.
Functions ¶
func Normalize ¶
Normalize folds the two cosmetic differences (separator presence / case) that Hyper-V treats as identical. Strips colons and hyphens, then uppercases. Used by StringSemanticEquals for the framework's plan-vs-apply comparison; also exported so resource code that needs to compare MACs outside the framework's call path (e.g. NIC-update diff logic) gets the same canonical form.
Types ¶
type MAC ¶
type MAC struct {
basetypes.StringValue
}
MAC is the attribute-value implementation. Embeds StringValue so the .ValueString() / .IsNull() / .IsUnknown() accessors continue to work unchanged after a schema's CustomType is set to mac.Type.
func NewMACNull ¶
func NewMACNull() MAC
NewMACNull constructs a null MAC. Convenient for collapsing empty optional-attribute reads to schema-null on the wire.
func NewMACValue ¶
NewMACValue constructs a known, non-null MAC. Convenient when hydrating a model from a typed-client struct on Read.
func (MAC) Equal ¶
Equal compares two MAC values for raw equality (byte-for-byte). The framework calls this for known-after-apply tracking and other plan- machinery checks where strict equality is what's wanted. Semantic equality is the separate StringSemanticEquals method.
func (MAC) StringSemanticEquals ¶
func (m MAC) StringSemanticEquals(_ context.Context, newValuable basetypes.StringValuable) (bool, diag.Diagnostics)
StringSemanticEquals is the load-bearing method. The framework calls this when comparing planned vs applied (or stored vs refreshed) values; if it returns true, the framework treats the values as the same and suppresses the diff. Returning true here is what bridges "user wrote AA:BB:CC:DD:EE:01, Hyper-V returned AABBCCDDEE01" without losing the strict-equality guarantees the framework needs elsewhere.
Both values are normalized (separators stripped + uppercased) before comparison. Null/unknown handling is left to the framework's pre- check: StringSemanticEquals is only invoked when both sides are known and non-null.