-
Notifications
You must be signed in to change notification settings - Fork 266
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support sharing IP address acorss services by public IP name #4257
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -809,7 +809,7 @@ func (az *Cloud) determinePublicIPName(clusterName string, service *v1.Service, | |
|
||
// For the services with loadBalancerIP set, an existing public IP is required, primary | ||
// or secondary, or a public IP not found error would be reported. | ||
pip, err := az.findMatchedPIPByLoadBalancerIP(service, loadBalancerIP, pipResourceGroup) | ||
pip, err := az.findMatchedPIP(loadBalancerIP, "", pipResourceGroup) | ||
if err != nil { | ||
return "", false, err | ||
} | ||
|
@@ -821,20 +821,58 @@ func (az *Cloud) determinePublicIPName(clusterName string, service *v1.Service, | |
return "", false, fmt.Errorf("user supplied IP Address %s was not found in resource group %s", loadBalancerIP, pipResourceGroup) | ||
} | ||
|
||
func (az *Cloud) findMatchedPIPByLoadBalancerIP(service *v1.Service, loadBalancerIP, pipResourceGroup string) (*network.PublicIPAddress, error) { | ||
func (az *Cloud) findMatchedPIP(loadBalancerIP, pipName, pipResourceGroup string) (pip *network.PublicIPAddress, err error) { | ||
pips, err := az.listPIP(pipResourceGroup, azcache.CacheReadTypeDefault) | ||
if err != nil { | ||
return nil, fmt.Errorf("findMatchedPIPByLoadBalancerIP: failed to listPIP: %w", err) | ||
} | ||
|
||
pip, err := getExpectedPIPFromListByIPAddress(pips, loadBalancerIP) | ||
if loadBalancerIP != "" { | ||
pip, err = az.findMatchedPIPByLoadBalancerIP(&pips, loadBalancerIP, pipResourceGroup) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return pip, nil | ||
} | ||
|
||
if pipResourceGroup != "" { | ||
pip, err = az.findMatchedPIPByName(&pips, pipName, pipResourceGroup) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After pip cache code refactored, I don't think we need to put PIPs as a parameter to other methods. We can There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What will be the benefit? |
||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
return pip, nil | ||
} | ||
|
||
func (az *Cloud) findMatchedPIPByName(pips *[]network.PublicIPAddress, pipName, pipResourceGroup string) (*network.PublicIPAddress, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I extract the list call from findMatchedPIPByLoadBalancerIP so that it can reuse. |
||
for _, pip := range *pips { | ||
if strings.EqualFold(pointer.StringDeref(pip.Name, ""), pipName) { | ||
return &pip, nil | ||
} | ||
} | ||
|
||
pipList, err := az.listPIP(pipResourceGroup, azcache.CacheReadTypeForceRefresh) | ||
if err != nil { | ||
return nil, fmt.Errorf("findMatchedPIPByName: failed to listPIP force refresh: %w", err) | ||
} | ||
for _, pip := range pipList { | ||
if strings.EqualFold(pointer.StringDeref(pip.Name, ""), pipName) { | ||
return &pip, nil | ||
} | ||
} | ||
|
||
return nil, fmt.Errorf("findMatchedPIPByName: failed to find PIP %s in resource group %s", pipName, pipResourceGroup) | ||
} | ||
|
||
func (az *Cloud) findMatchedPIPByLoadBalancerIP(pips *[]network.PublicIPAddress, loadBalancerIP, pipResourceGroup string) (*network.PublicIPAddress, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since its logic is similar to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do. |
||
pip, err := getExpectedPIPFromListByIPAddress(*pips, loadBalancerIP) | ||
if err != nil { | ||
pips, err = az.listPIP(pipResourceGroup, azcache.CacheReadTypeForceRefresh) | ||
pipList, err := az.listPIP(pipResourceGroup, azcache.CacheReadTypeForceRefresh) | ||
if err != nil { | ||
return nil, fmt.Errorf("findMatchedPIPByLoadBalancerIP: failed to listPIP force refresh: %w", err) | ||
} | ||
|
||
pip, err = getExpectedPIPFromListByIPAddress(pips, loadBalancerIP) | ||
pip, err = getExpectedPIPFromListByIPAddress(pipList, loadBalancerIP) | ||
if err != nil { | ||
return nil, fmt.Errorf("findMatchedPIPByLoadBalancerIP: cannot find public IP with IP address %s in resource group %s", loadBalancerIP, pipResourceGroup) | ||
} | ||
|
@@ -3516,7 +3554,7 @@ func serviceOwnsPublicIP(service *v1.Service, pip *network.PublicIPAddress, clus | |
|
||
// if there is no service tag on the pip, it is user-created pip | ||
if serviceTag == "" { | ||
return isServiceLoadBalancerIPMatchesPIP(service, pip, isIPv6), true | ||
return isServiceSelectPIP(service, pip, isIPv6), true | ||
} | ||
|
||
// if there is service tag on the pip, it is system-created pip | ||
|
@@ -3532,18 +3570,26 @@ func serviceOwnsPublicIP(service *v1.Service, pip *network.PublicIPAddress, clus | |
} | ||
|
||
// if the service is not included in the tags of the system-created pip, check the ip address | ||
// this could happen for secondary services | ||
return isServiceLoadBalancerIPMatchesPIP(service, pip, isIPv6), false | ||
// or pip name, this could happen for secondary services | ||
return isServiceSelectPIP(service, pip, isIPv6), false | ||
} | ||
|
||
// if the pip has no tags, it should be user-created | ||
return isServiceLoadBalancerIPMatchesPIP(service, pip, isIPv6), true | ||
return isServiceSelectPIP(service, pip, isIPv6), true | ||
} | ||
|
||
func isServiceLoadBalancerIPMatchesPIP(service *v1.Service, pip *network.PublicIPAddress, isIPV6 bool) bool { | ||
return strings.EqualFold(pointer.StringDeref(pip.IPAddress, ""), getServiceLoadBalancerIP(service, isIPV6)) | ||
} | ||
|
||
func isServicePIPNameMatchesPIP(service *v1.Service, pip *network.PublicIPAddress, isIPV6 bool) bool { | ||
return strings.EqualFold(pointer.StringDeref(pip.Name, ""), getServicePIPName(service, isIPV6)) | ||
} | ||
|
||
func isServiceSelectPIP(service *v1.Service, pip *network.PublicIPAddress, isIPV6 bool) bool { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As for the name, how about using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We already have this function. |
||
return isServiceLoadBalancerIPMatchesPIP(service, pip, isIPV6) || isServicePIPNameMatchesPIP(service, pip, isIPV6) | ||
} | ||
|
||
func isSVCNameInPIPTag(tag, svcName string) bool { | ||
svcNames := parsePIPServiceTag(&tag) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked the usage and it seems
findMatchedPIP
finds PIP with LB IP or PIP name. How about returning error if both 2 variables are set or both unset?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can cover it in the doc that ip will overweight the name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, doc is good for both set.
How about both empty? I think at least a warning is needed. When somehow 2 empty values are passed in, it returns an empty PIP. It will add difficulty when debugging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They can't be both empty, we guard outside of the func.