Skip to content

Commit

Permalink
Replace host switch profiles attr with typed ones
Browse files Browse the repository at this point in the history
Deprecate list of host switch profiles, and introduce typed profile
attributes instead - `uplink_profile` and `vtep_ha_profile`.
This is because certain profile types are autoassigned by NSX, in which
case permadiff is introduced, unless the user fixes it by adding the
auto-assigned profile into resource intent.
Having type-specific computed attributes solves this problem.

Signed-off-by: Anna Khmelnitsky <[email protected]>
  • Loading branch information
annakhm committed Jan 22, 2025
1 parent 94bb0ab commit ad67f2a
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 23 deletions.
77 changes: 62 additions & 15 deletions nsxt/resource_nsxt_edge_transport_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,20 @@ func getStandardHostSwitchSchema(nodeType string) *schema.Schema {
Computed: true,
},
"host_switch_profile": getHostSwitchProfileIDsSchema(),
"ip_assignment": getIPAssignmentSchema(false),
"ipv6_assignment": getIPv6AssignmentSchema(),
"uplink_profile": {
Type: schema.TypeString,
Description: "Host switch uplink profile",
Optional: true,
Computed: true,
},
"vtep_ha_profile": {
Type: schema.TypeString,
Description: "Host switch high availability profile",
Optional: true,
Computed: true,
},
"ip_assignment": getIPAssignmentSchema(false),
"ipv6_assignment": getIPv6AssignmentSchema(),
"pnic": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -627,6 +639,8 @@ func getHostSwitchProfileIDsSchema() *schema.Schema {
Elem: &schema.Schema{
Type: schema.TypeString,
},
Computed: true,
Deprecated: "use specific profiles instead",
}
}

Expand Down Expand Up @@ -1146,8 +1160,36 @@ func getHostSwitchProfileResourceType(m interface{}, id string) (string, error)
return "", fmt.Errorf("Host Switch Profile type not found for %s", id)
}

func getHostSwitchProfileIDsFromSchema(m interface{}, hswProfileList []interface{}) ([]mpmodel.HostSwitchProfileTypeIdEntry, error) {
func getHostSwitchProfileIDsFromSchema(m interface{}, parentMap map[string]interface{}) ([]mpmodel.HostSwitchProfileTypeIdEntry, error) {
var hswProfiles []mpmodel.HostSwitchProfileTypeIdEntry

uplinkProfile := parentMap["uplink_profile"].(string)
haProfile := parentMap["vtep_ha_profile"].(string)

if len(uplinkProfile) > 0 {
profileType := mpmodel.BaseHostSwitchProfile_RESOURCE_TYPE_UPLINKHOSTSWITCHPROFILE
elem := mpmodel.HostSwitchProfileTypeIdEntry{
Key: &profileType,
Value: &uplinkProfile,
}
hswProfiles = append(hswProfiles, elem)
}

if len(haProfile) > 0 {
profileType := mpmodel.BaseHostSwitchProfile_RESOURCE_TYPE_VTEPHAHOSTSWITCHPROFILE
elem := mpmodel.HostSwitchProfileTypeIdEntry{
Key: &profileType,
Value: &haProfile,
}
hswProfiles = append(hswProfiles, elem)
}

if len(hswProfiles) > 0 {
return hswProfiles, nil
}

// Deprecated way of specifying profiles as single list
hswProfileList := parentMap["host_switch_profile"].([]interface{})
for _, hswp := range hswProfileList {
val := hswp.(string)
key, err := getHostSwitchProfileResourceType(m, getPolicyIDFromPath(val))
Expand Down Expand Up @@ -1434,7 +1476,7 @@ func getHostSwitchSpecFromSchema(d *schema.ResourceData, m interface{}, nodeType
hostSwitchMode = mpmodel.StandardHostSwitch_HOST_SWITCH_MODE_STANDARD
hostSwitchType = mpmodel.StandardHostSwitch_HOST_SWITCH_TYPE_NVDS
}
hostSwitchProfileIDs, err := getHostSwitchProfileIDsFromSchema(m, swData["host_switch_profile"].([]interface{}))
hostSwitchProfileIDs, err := getHostSwitchProfileIDsFromSchema(m, swData)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1559,7 +1601,7 @@ func getTransportNodeSubProfileCfg(m interface{}, iface interface{}) ([]mpmodel.
for _, cfgOpt := range data["host_switch_config_option"].([]interface{}) {
opt := cfgOpt.(map[string]interface{})
swID := opt["host_switch_id"].(string)
profileIDs, err := getHostSwitchProfileIDsFromSchema(m, opt["host_switch_profile"].([]interface{}))
profileIDs, err := getHostSwitchProfileIDsFromSchema(m, opt)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1768,10 +1810,7 @@ func setHostSwitchSpecInSchema(d *schema.ResourceData, spec *data.StructValue, n
elem := make(map[string]interface{})
elem["host_switch_id"] = sw.HostSwitchId
elem["host_switch_name"] = sw.HostSwitchName
profiles := setHostSwitchProfileIDsInSchema(sw.HostSwitchProfileIds)
if len(profiles) > 0 {
elem["host_switch_profile"] = profiles
}
setHostSwitchProfileIDsInSchema(sw.HostSwitchProfileIds, elem)
var err error
if sw.IpAssignmentSpec != nil {
elem["ip_assignment"], err = setIPAssignmentInSchema(sw.IpAssignmentSpec)
Expand Down Expand Up @@ -1810,10 +1849,7 @@ func setHostSwitchSpecInSchema(d *schema.ResourceData, spec *data.StructValue, n
e := make(map[string]interface{})
hsCfgOpt := make(map[string]interface{})
hsCfgOpt["host_switch_id"] = tnpsc.HostSwitchConfigOption.HostSwitchId
profiles := setHostSwitchProfileIDsInSchema(tnpsc.HostSwitchConfigOption.HostSwitchProfileIds)
if len(profiles) > 0 {
hsCfgOpt["host_switch_profile"] = profiles
}
setHostSwitchProfileIDsInSchema(tnpsc.HostSwitchConfigOption.HostSwitchProfileIds, hsCfgOpt)
if tnpsc.HostSwitchConfigOption.IpAssignmentSpec != nil {
hsCfgOpt["ip_assignment"], err = setIPAssignmentInSchema(tnpsc.HostSwitchConfigOption.IpAssignmentSpec)
if err != nil {
Expand Down Expand Up @@ -2006,12 +2042,23 @@ func setIPv6AssignmentInSchema(spec *data.StructValue) (interface{}, error) {
return []interface{}{elem}, nil
}

func setHostSwitchProfileIDsInSchema(hspIDs []mpmodel.HostSwitchProfileTypeIdEntry) []interface{} {
func setHostSwitchProfileIDsInSchema(hspIDs []mpmodel.HostSwitchProfileTypeIdEntry, parentMap map[string]interface{}) {
var hostSwitchProfileIDs []interface{}
for _, hspID := range hspIDs {
if hspID.Key == nil {
continue
}
if *hspID.Key == mpmodel.BaseHostSwitchProfile_RESOURCE_TYPE_UPLINKHOSTSWITCHPROFILE {
parentMap["uplink_profile"] = hspID.Value
}
if *hspID.Key == mpmodel.BaseHostSwitchProfile_RESOURCE_TYPE_VTEPHAHOSTSWITCHPROFILE {
parentMap["vtep_ha_profile"] = hspID.Value
}
hostSwitchProfileIDs = append(hostSwitchProfileIDs, hspID.Value)
}
return hostSwitchProfileIDs

// deprecated way of specifying profiles in single list
parentMap["host_switch_profile"] = hostSwitchProfileIDs
}

func resourceNsxtEdgeTransportNodeUpdate(d *schema.ResourceData, m interface{}) error {
Expand Down
6 changes: 4 additions & 2 deletions website/docs/r/edge_transport_node.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ resource "nsxt_edge_transport_node" "test_node" {
transport_zone_endpoint {
transport_zone = data.nsxt_policy_transport_zone.vlan_tz.id
}
host_switch_profile = [data.nsxt_policy_uplink_host_switch_profile.edge_uplink_profile.id]
uplink_profile = data.nsxt_policy_uplink_host_switch_profile.edge_uplink_profile.id
pnic {
device_name = "fp-eth0"
uplink_name = "uplink1"
Expand All @@ -102,7 +102,9 @@ The following arguments are supported:
* `standard_host_switch` - (Required) Standard host switch specification.
* `host_switch_id` - (Optional) The host switch id. This ID will be used to reference a host switch.
* `host_switch_name` - (Optional) Host switch name. This name will be used to reference a host switch.
* `host_switch_profile` - (Optional) Identifiers of host switch profiles to be associated with this host switch.
* `host_switch_profile` - (Deprecated) Identifiers of host switch profiles to be associated with this host switch. This attribute is deprecated, please use type-specific attribute instead (such as `uplink_profile`)
* `uplink_profile` - (Optional) Uplink host switch profile id.
* `vtep_ha_profile` - (Optional) VTEP high availablility host switch profile id. Only applicable with VDS switch.
* `ip_assignment` - (Required) - Specification for IPs to be used with host switch virtual tunnel endpoints. Should contain exatly one of the below:
* `assigned_by_dhcp` - (Optional) Enables DHCP assignment.
* `no_ipv4` - (Optional) No IPv4 for this host switch.
Expand Down
8 changes: 5 additions & 3 deletions website/docs/r/policy_host_transport_node.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ resource "nsxt_policy_host_transport_node" "test" {
discovered_node_id = data.nsxt_discovered_node.dn.id
standard_host_switch {
host_switch_id = "50 0b 31 a4 b8 af 35 df-40 56 b6 f9 aa d3 ee 12"
host_switch_profile = [data.nsxt_policy_uplink_host_switch_profile.uplink_host_switch_profile.path]
host_switch_id = "50 0b 31 a4 b8 af 35 df-40 56 b6 f9 aa d3 ee 12"
uplink_profile = data.nsxt_policy_uplink_host_switch_profile.uplink_host_switch_profile.path
ip_assignment {
assigned_by_dhcp = true
Expand Down Expand Up @@ -65,7 +65,9 @@ The following arguments are supported:
* `host_switch_id` - (Optional) The host switch id. This ID will be used to reference a host switch.
* `host_switch_name` - (Optional) Host switch name. This name will be used to reference a host switch.
* `host_switch_mode` - (Optional) Operational mode of a HostSwitch. Accepted values - 'STANDARD', 'ENS', 'ENS_INTERRUPT' or 'LEGACY'.
* `host_switch_profile` - (Optional) Policy path of host switch profiles to be associated with this host switch.
* `host_switch_profile` - (Deprecated) Policy paths of host switch profiles to be associated with this host switch. This attribute is deprecated, please use type-specific attribute instead (such as `uplink_profile`)
* `uplink_profile` - (Optional) Uplink host switch profile path.
* `vtep_ha_profile` - (Optional) VTEP high availablility host switch profile path. Only applicable with VDS switch.
* `ip_assignment` - (Optional) - Specification for IPs to be used with host switch virtual tunnel endpoints. Should contain exatly one of the below:
* `assigned_by_dhcp` - (Optional) Enables DHCP assignment.
* `no_ipv4` - (Optional) No IPv4 for this host switch.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ resource "nsxt_policy_host_transport_node_profile" "test" {
transport_zone_endpoint {
transport_zone = data.nsxt_policy_transport_zone.tz1.path
}
host_switch_profile = [nsxt_policy_uplink_host_switch_profile.hsw_profile1.path]
is_migrate_pnics = false
uplink_profile = nsxt_policy_uplink_host_switch_profile.hsw_profile1.path
is_migrate_pnics = false
pnic {
device_name = "fp-eth0"
uplink_name = "uplink1"
Expand All @@ -46,7 +46,9 @@ The following arguments are supported:
* `host_switch_id` - (Optional) The host switch id. This ID will be used to reference a host switch.
* `host_switch_name` - (Optional) Host switch name. This name will be used to reference a host switch.
* `host_switch_mode` - (Optional) Operational mode of a HostSwitch. Accepted values - 'STANDARD', 'ENS', 'ENS_INTERRUPT' or 'LEGACY'.
* `host_switch_profile` - (Optional) Policy paths of host switch profiles to be associated with this host switch.
* `host_switch_profile` - (Deprecated) Policy paths of host switch profiles to be associated with this host switch. This attribute is deprecated, please use type-specific attribute instead (such as `uplink_profile`)
* `uplink_profile` - (Optional) Uplink host switch profile path.
* `vtep_ha_profile` - (Optional) VTEP high availablility host switch profile path. Only applicable with VDS switch.
* `ip_assignment` - (Required) - Specification for IPs to be used with host switch virtual tunnel endpoints. Should contain exactly one of the below:
* `assigned_by_dhcp` - (Optional) Enables DHCP assignment.
* `static_ip` - (Optional) IP assignment specification for Static IP List.
Expand Down

0 comments on commit ad67f2a

Please sign in to comment.