Skip to content

Commit

Permalink
r/virutal_machine: Fix gateway discovery behavior
Browse files Browse the repository at this point in the history
The current gateway discovery code makes an assumption that any device
tracked by VMware tools that is not virtual hardware on the instance
will be ordered after any devices that are (even though the device key
is properly being used as the source of truth when discovering
interfaces). It does this by using the device index in a specific
gateway entry as the literal index entry for the corresponding device in
the list of devices that have actually been counted for saving in
Terraform state. This will either point to the incorrect device or a
flat out out-of-bounds value, respectively causing incorrect diffs or
crashes.

This fixes the situation by searching for the actual device key in the
guest network information discovered by VMware tools - at the index
specified by the gateway entry, and then searching for that key in the
devices being counted for state. The index of the corresponding entry is
where the gateway is saved. If any of these searches come up dry, either
the gateway has legitimately moved and needs to be fixed or more than
likely was not defined in config.

Fixes #173.
  • Loading branch information
vancluever committed Sep 26, 2017
1 parent 9a5b352 commit 3d77277
Showing 1 changed file with 31 additions and 8 deletions.
39 changes: 31 additions & 8 deletions vsphere/resource_vsphere_virtual_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -1199,16 +1199,39 @@ func resourceVSphereVirtualMachineRead(d *schema.ResourceData, meta interface{})
gatewaySetting = "ipv4_gateway"
}
if gatewaySetting != "" {
deviceID, err := strconv.Atoi(route.Gateway.Device)
if len(networkInterfaces) == 1 {
deviceID = 0
}
// We need to get the correct device index which is not always
// aligned with what we have saved in Terraform state.
//
// The index in Device corresponds with the device index in
// Guest.Net, which we can use to discover the key.
did := route.Gateway.Device
nidx, err := strconv.Atoi(did)
if err != nil {
log.Printf("[WARN] error at processing %s of device id %#v: %#v", gatewaySetting, route.Gateway.Device, err)
} else {
log.Printf("[DEBUG] %s of device id %d: %s", gatewaySetting, deviceID, route.Gateway.IpAddress)
networkInterfaces[deviceID][gatewaySetting] = route.Gateway.IpAddress
// "device" for some reason is a string, even though its result
// has always been observed to be an int. This should never
// happen, but we warn just in case.
log.Printf("[WARN] error at processing %s of device id %#v: %#v", gatewaySetting, did, err)
continue
}
key := mvm.Guest.Net[nidx].DeviceConfigId
if key < 0 {
// Gateway is not set to any hardware device, ignore.
continue
}
didx := -1
for n, dev := range networkInterfaces {
if dev["key"] == key {
didx = n
break
}
}
if didx < 0 {
// We are not tracking the device that the gateway is going to
// in state, so just skip the gateway.
continue
}
log.Printf("[DEBUG] %s of device id %d: %s", gatewaySetting, didx, route.Gateway.IpAddress)
networkInterfaces[didx][gatewaySetting] = route.Gateway.IpAddress
}
}
}
Expand Down

0 comments on commit 3d77277

Please # to comment.