Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d3d386c

Browse files
author
Nick Sardo
committed
Review changes
1 parent 3f6d46d commit d3d386c

3 files changed

Lines changed: 160 additions & 141 deletions

File tree

pkg/cloudprovider/providers/gce/gce_address_manager.go

Lines changed: 66 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
type addressManager struct {
2929
logPrefix string
3030
svc CloudAddressService
31-
lbName string
31+
name string
3232
serviceName string
3333
targetIP string
3434
addressType lbScheme
@@ -37,13 +37,13 @@ type addressManager struct {
3737
tryRelease bool
3838
}
3939

40-
func newAddressManager(svc CloudAddressService, serviceName, region, subnetURL, lbName, targetIP string, addressType lbScheme) *addressManager {
40+
func newAddressManager(svc CloudAddressService, serviceName, region, subnetURL, name, targetIP string, addressType lbScheme) *addressManager {
4141
return &addressManager{
4242
svc: svc,
43-
logPrefix: fmt.Sprintf("AddressManager(%q)", lbName),
43+
logPrefix: fmt.Sprintf("AddressManager(%q)", name),
4444
region: region,
4545
serviceName: serviceName,
46-
lbName: lbName,
46+
name: name,
4747
targetIP: targetIP,
4848
addressType: addressType,
4949
tryRelease: true,
@@ -53,7 +53,7 @@ func newAddressManager(svc CloudAddressService, serviceName, region, subnetURL,
5353

5454
// HoldAddress will ensure that the IP is reserved with an address - either owned by the controller
5555
// or by a user. If the address is not the loadBalancerName, then it's assumed to be a user's address.
56-
func (am *addressManager) HoldAddress() error {
56+
func (am *addressManager) HoldAddress() (string, error) {
5757
// HoldAddress starts with retrieving the address that we use for this load balancer (by name).
5858
// Retrieving an address by IP will indicate if the IP is reserved and if reserved by the user
5959
// or the controller, but won't tell us the current state of the controller's IP. The address
@@ -62,28 +62,28 @@ func (am *addressManager) HoldAddress() error {
6262
// calls since it indicates whether a Delete is necessary before Reserve.
6363
glog.V(3).Infof("%v: attempting hold of IP %v with type %v", am.logPrefix, am.targetIP, am.addressType)
6464
// Get the address in case it was orphaned earlier
65-
addr, err := am.svc.GetBetaRegionAddress(am.lbName, am.region)
65+
addr, err := am.svc.GetBetaRegionAddress(am.name, am.region)
6666
if err != nil && !isNotFound(err) {
67-
return err
67+
return "", err
6868
}
6969

7070
if addr != nil {
71-
// If address exists, check if the address IP is different from what's expected.
72-
if addr.Address != am.targetIP || addr.AddressType != string(am.addressType) {
73-
glog.V(3).Infof("%v: existing address %q has IP %v Type %v which does not match targeted IP %v Type %v. Attemping to delete.", am.logPrefix, addr.Name, addr.Address, addr.AddressType, am.targetIP, am.addressType)
74-
err := am.svc.DeleteRegionAddress(addr.Name, am.region)
75-
if err != nil {
76-
if isNotFound(err) {
77-
glog.V(3).Infof("%v: address %q was not found. Ignoring.", am.logPrefix, addr.Name)
78-
} else {
79-
return err
80-
}
71+
// If address exists, check if the address had the expected attributes.
72+
if (am.targetIP == "" || am.targetIP == addr.Address) && addr.AddressType == string(am.addressType) {
73+
glog.V(3).Infof("%v: address %q already reserves IP %v of type %v. No further action required.", am.logPrefix, addr.Name, addr.Address, addr.AddressType)
74+
return addr.Address, nil
75+
}
76+
77+
glog.V(3).Infof("%v: existing address %q has IP %v Type %v which does not match targeted IP %v Type %v. Attemping to delete.", am.logPrefix, addr.Name, addr.Address, addr.AddressType, am.targetIP, am.addressType)
78+
err := am.svc.DeleteRegionAddress(addr.Name, am.region)
79+
if err != nil {
80+
if isNotFound(err) {
81+
glog.V(3).Infof("%v: address %q was not found. Ignoring.", am.logPrefix, addr.Name)
8182
} else {
82-
glog.V(3).Infof("%v: successfully deleted previous address %q", am.logPrefix, addr.Name)
83+
return "", err
8384
}
8485
} else {
85-
glog.V(3).Infof("%v: address %q already reserves targeted IP %v of type %v. No further action required.", am.logPrefix, addr.Name, am.targetIP, am.addressType)
86-
return nil
86+
glog.V(3).Infof("%v: successfully deleted previous address %q", am.logPrefix, addr.Name)
8787
}
8888
}
8989

@@ -97,59 +97,83 @@ func (am *addressManager) ReleaseAddress() error {
9797
return nil
9898
}
9999

100-
glog.V(3).Infof("%v: releasing address %v named %q", am.logPrefix, am.targetIP, am.lbName)
100+
glog.V(3).Infof("%v: releasing address %v named %q", am.logPrefix, am.targetIP, am.name)
101101
// Controller only ever tries to unreserve the address named with the load balancer's name.
102-
err := am.svc.DeleteRegionAddress(am.lbName, am.region)
102+
err := am.svc.DeleteRegionAddress(am.name, am.region)
103103
if err != nil {
104104
if isNotFound(err) {
105-
glog.Warningf("%v: address %q was not found. Ignoring.", am.logPrefix, am.targetIP, am.lbName)
105+
glog.Warningf("%v: address %q was not found. Ignoring.", am.logPrefix, am.name)
106106
return nil
107107
}
108108

109109
return err
110110
}
111111

112-
glog.V(3).Infof("%v: successfully released IP %v named %q", am.logPrefix, am.targetIP, am.lbName)
112+
glog.V(3).Infof("%v: successfully released IP %v named %q", am.logPrefix, am.targetIP, am.name)
113113
return nil
114114
}
115115

116-
func (am *addressManager) ensureAddressReservation() error {
116+
func (am *addressManager) ensureAddressReservation() (string, error) {
117117
// Try reserving the IP with controller-owned address name
118+
// If am.targetIP is an empty string, a new IP will be created.
118119
newAddr := &computebeta.Address{
119-
Name: am.lbName,
120+
Name: am.name,
120121
Description: fmt.Sprintf(`{"kubernetes.io/service-name":"%s"}`, am.serviceName),
121122
Address: am.targetIP,
122123
AddressType: string(am.addressType),
123124
Subnetwork: am.subnetURL,
124125
}
125126

126127
err := am.svc.ReserveBetaRegionAddress(newAddr, am.region)
127-
if err != nil {
128-
if !isHTTPErrorCode(err, http.StatusConflict) {
129-
return err
128+
if err == nil {
129+
if newAddr.Address != "" {
130+
glog.V(3).Infof("%v: successfully reserved IP %v with name %q", am.logPrefix, newAddr.Address, newAddr.Name)
131+
return newAddr.Address, nil
132+
}
133+
134+
addr, err := am.svc.GetRegionAddress(newAddr.Name, am.region)
135+
if err != nil {
136+
return "", err
130137
}
131-
} else {
132-
glog.V(3).Infof("%v: successfully reserved IP %v with name %q", am.logPrefix, am.targetIP, newAddr.Name)
133-
return nil
134-
}
135138

136-
glog.V(3).Infof("%v: could not reserve IP %v due to err: %v", am.logPrefix, am.targetIP, err)
139+
glog.V(3).Infof("%v: successfully created address %q which reserved IP %q", am.logPrefix, addr.Name, addr.Address)
140+
return addr.Address, nil
141+
} else if !isHTTPErrorCode(err, http.StatusConflict) && !isHTTPErrorCode(err, http.StatusBadRequest) {
142+
// If the IP is already reserved:
143+
// by an internal address: a StatusConflict is returned
144+
// by an external address: a BadRequest is returned
145+
return "", err
146+
}
137147

138148
// Reserving the address failed due to a conflict. The address manager just checked that no address
139-
// exists with the lbName, so it may belong to the user.
149+
// exists with the name, so it may belong to the user.
140150
addr, err := am.svc.GetBetaRegionAddressByIP(am.region, am.targetIP)
141151
if err != nil {
142-
return fmt.Errorf("could not find address with IP %v after getting conflict error while creating address: %v", am.targetIP, err)
152+
return "", fmt.Errorf("could not find address with IP %q after getting conflict error while creating address: %q", am.targetIP, err)
143153
}
144154

145-
// If the retrieved address is not named with the loadbalancer name, then the controller does not own it.
146-
if addr.Name != am.lbName {
147-
glog.V(3).Infof("%v: address %q was already reserved with name: %q, description: %q", am.logPrefix, am.targetIP, addr.Name, addr.Description)
148-
am.tryRelease = false
149-
} else {
155+
// Check that the address attributes are as required.
156+
if addr.AddressType != string(am.addressType) {
157+
return "", fmt.Errorf("address %q does not have the expected address type %v, actual: %v", addr.Name, am.addressType, addr.AddressType)
158+
}
159+
160+
if am.isManagedAddress(addr) {
150161
// The address with this name is checked at the beginning of 'HoldAddress()', but for some reason
151162
// it was re-created by this point. May be possible that two controllers are running.
152163
glog.Warning("%v: address %q unexpectedly existed with IP %q.", am.logPrefix, addr.Name, am.targetIP)
164+
} else {
165+
// If the retrieved address is not named with the loadbalancer name, then the controller does not own it.
166+
glog.V(3).Infof("%v: address %q was already reserved with name: %q, description: %q", am.logPrefix, am.targetIP, addr.Name, addr.Description)
167+
am.tryRelease = false
153168
}
154-
return nil
169+
170+
return addr.Address, nil
171+
}
172+
173+
func (am *addressManager) isManagedAddress(addr *computebeta.Address) bool {
174+
return addr.Name == am.name
175+
}
176+
177+
func ensureAddressDeleted(svc CloudAddressService, name, region string) error {
178+
return ignoreNotFound(svc.DeleteRegionAddress(name, region))
155179
}

0 commit comments

Comments
 (0)