@@ -90,12 +90,19 @@ func (c *client) GetOrCreateNetwork(csCluster *infrav1.CloudStackCluster) (retEr
90
90
}
91
91
92
92
func (c * client ) DisassociatePublicIPAddressIfNotInUse (csCluster * infrav1.CloudStackCluster ) (retError error ) {
93
- okayToDelete , err := c .DoClusterTagsAllowDisposal (ResourceTypeIPAddress , csCluster .Status .PublicIPID )
93
+ tagsAllowDisposal , err := c .DoClusterTagsAllowDisposal (ResourceTypeIPAddress , csCluster .Status .PublicIPID )
94
94
if err != nil {
95
95
return err
96
96
}
97
97
98
- if okayToDelete {
98
+ // Can't disassociate an address if it's the source NAT address.
99
+ publicIP , _ , err := c .cs .Address .GetPublicIpAddressByID (csCluster .Status .PublicIPID )
100
+ if err != nil {
101
+ return err
102
+ }
103
+ sourceNAT := publicIP != nil && publicIP .Issourcenat
104
+
105
+ if tagsAllowDisposal && ! sourceNAT {
99
106
return c .DisassociatePublicIPAddress (csCluster )
100
107
}
101
108
@@ -152,11 +159,11 @@ func (c *client) AssociatePublicIPAddress(csCluster *infrav1.CloudStackCluster)
152
159
153
160
csCluster .Spec .ControlPlaneEndpoint .Host = publicAddress .Ipaddress
154
161
csCluster .Status .PublicIPID = publicAddress .Id
155
- allocatedByCapc := publicAddress .Allocated = = ""
162
+ alreadyAllocated := publicAddress .Allocated ! = ""
156
163
157
- if publicAddress . Allocated != "" && publicAddress .Associatednetworkid == csCluster .Status .NetworkID {
164
+ if alreadyAllocated && publicAddress .Associatednetworkid == csCluster .Status .NetworkID {
158
165
// Address already allocated to network. Allocated is a timestamp -- not a boolean.
159
- return c .AddClusterTag (ResourceTypeIPAddress , publicAddress .Id , csCluster , allocatedByCapc )
166
+ return c .AddClusterTag (ResourceTypeIPAddress , publicAddress .Id , csCluster , false )
160
167
} // Address not yet allocated. Allocate now.
161
168
162
169
// Public IP found, but not yet allocated to network.
@@ -168,10 +175,13 @@ func (c *client) AssociatePublicIPAddress(csCluster *infrav1.CloudStackCluster)
168
175
if _ , err := c .cs .Address .AssociateIpAddress (p ); err != nil {
169
176
return err
170
177
}
171
- return c .AddClusterTag (ResourceTypeIPAddress , publicAddress .Id , csCluster , allocatedByCapc )
178
+ return c .AddClusterTag (ResourceTypeIPAddress , publicAddress .Id , csCluster , ! alreadyAllocated )
172
179
}
173
180
174
181
func (c * client ) DisassociatePublicIPAddress (csCluster * infrav1.CloudStackCluster ) (retErr error ) {
182
+ // Remove the CAPC creation tag, so it won't be there the next time this address is associated.
183
+ c .DeleteCreatedByCAPCTag (ResourceTypeIPAddress , csCluster .Status .PublicIPID )
184
+
175
185
p := c .cs .Address .NewDisassociateIpAddressParams (csCluster .Status .PublicIPID )
176
186
_ , retErr = c .cs .Address .DisassociateIpAddress (p )
177
187
return retErr
0 commit comments