Skip to content

Commit

Permalink
Anexia Provider: Add field IPProvisioningExpires to status
Browse files Browse the repository at this point in the history
Adds field to check if a IP reservation is still valid,
if the IP is no longer valid a new one is requested.

This fixes a bug where we use an IP that expired already for a VM,
if the VM provisioning failed, which then leads to a race condition.
In which we wait for the VM provisioning to finish, but it can't due the IP being no longer useable,
but we also never request a new IP in that case.

Signed-off-by: Zofia hagenguth <[email protected]>
  • Loading branch information
zhagenguth committed Dec 22, 2023
1 parent 2dcaf04 commit a155ae7
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 12 deletions.
3 changes: 2 additions & 1 deletion pkg/cloudprovider/provider/anexia/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ func getIPAddress(ctx context.Context, client anxclient.Client) (string, error)
status := reconcileContext.Status

// only use IP if it is still unbound
if status.ReservedIP != "" && status.IPState == anxtypes.IPStateUnbound {
if status.ReservedIP != "" && status.IPState == anxtypes.IPStateUnbound && (!status.IPProvisioningExpires.IsZero() && status.IPProvisioningExpires.After(time.Now())) {
klog.Infof("reusing already provisioned ip %q", status.ReservedIP)
return status.ReservedIP, nil
}
Expand All @@ -240,6 +240,7 @@ func getIPAddress(ctx context.Context, client anxclient.Client) (string, error)
ip := res.Data[0].Address
status.ReservedIP = ip
status.IPState = anxtypes.IPStateUnbound
status.IPProvisioningExpires = time.Now().Add(anxtypes.IPProvisioningExpires)

return ip, nil
}
Expand Down
1 change: 1 addition & 0 deletions pkg/cloudprovider/provider/anexia/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ func TestAnexiaProvider(t *testing.T) {
expectedIP := "8.8.8.8"
providerStatus.ReservedIP = expectedIP
providerStatus.IPState = anxtypes.IPStateUnbound
providerStatus.IPProvisioningExpires = time.Now().Add(anxtypes.IPProvisioningExpires)
reservedIP, err := getIPAddress(ctx, client)
testhelper.AssertNoErr(t, err)
testhelper.AssertEquals(t, expectedIP, reservedIP)
Expand Down
23 changes: 12 additions & 11 deletions pkg/cloudprovider/provider/anexia/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ const (
GetRequestTimeout = 1 * time.Minute
DeleteRequestTimeout = 1 * time.Minute

IPStateBound = "Bound"
IPStateUnbound = "Unbound"

VmxNet3NIC = "vmxnet3"
MachinePoweredOn = "poweredOn"
IPStateBound = "Bound"
IPStateUnbound = "Unbound"
IPProvisioningExpires = 1800 * time.Second
VmxNet3NIC = "vmxnet3"
MachinePoweredOn = "poweredOn"
)

var StatusUpdateFailed = cloudprovidererrors.TerminalError{
Expand Down Expand Up @@ -72,12 +72,13 @@ type RawConfig struct {
}

type ProviderStatus struct {
InstanceID string `json:"instanceID"`
ProvisioningID string `json:"provisioningID"`
DeprovisioningID string `json:"deprovisioningID"`
ReservedIP string `json:"reservedIP"`
IPState string `json:"ipState"`
Conditions []v1.Condition `json:"conditions,omitempty"`
InstanceID string `json:"instanceID"`
ProvisioningID string `json:"provisioningID"`
DeprovisioningID string `json:"deprovisioningID"`
ReservedIP string `json:"reservedIP"`
IPState string `json:"ipState"`
IPProvisioningExpires time.Time `json:"ipProvisioningExpires"`
Conditions []v1.Condition `json:"conditions,omitempty"`
}

func GetConfig(pconfig providerconfigtypes.Config) (*RawConfig, error) {
Expand Down

0 comments on commit a155ae7

Please sign in to comment.