mirror of
https://github.com/cloudnativelabs/kube-router.git
synced 2025-11-19 12:01:17 +01:00
* doc(ecmp_vip.go): add info around extra withdraw Rename getWithdraw to make it more explicit what its doing here. Also add documentation as to why this is needed on Update and not Create/Delete as well as why we only treat externalIPs. * fix(ecmp_vip.go): remove superfluous AddPolicies AddPolicies is already called downstream of nrc.OnEndpointsUpdate() so there is no need to do it here as well, the only result is that this expensive operation and idempotent operation is run twice. * feat: better handling of headless services Also introduces a consolidated Service utilities section for controller functionality related to services that is shared. * fix: add logging back to tryHandleServiceDelete
61 lines
1.6 KiB
Go
61 lines
1.6 KiB
Go
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
v1core "k8s.io/api/core/v1"
|
|
"k8s.io/client-go/tools/cache"
|
|
)
|
|
|
|
func ServiceForEndpoints(ci *cache.Indexer, ep *v1core.Endpoints) (interface{}, error) {
|
|
key, err := cache.MetaNamespaceKeyFunc(ep)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
item, exists, err := (*ci).GetByKey(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if !exists {
|
|
return nil, fmt.Errorf("service resource doesn't exist for endpoints: %q", ep.Name)
|
|
}
|
|
|
|
return item, nil
|
|
}
|
|
|
|
// ServiceIsHeadless decides whether or not the this service is a headless service which is often useful to kube-router
|
|
// as there is no need to execute logic on most headless changes. Function takes a generic interface as its input
|
|
// parameter so that it can be used more easily in early processing if needed. If a non-service object is given,
|
|
// function will return false.
|
|
func ServiceIsHeadless(obj interface{}) bool {
|
|
if svc, _ := obj.(*v1core.Service); svc != nil {
|
|
if svc.Spec.Type == v1core.ServiceTypeClusterIP {
|
|
if ClusterIPIsNone(svc.Spec.ClusterIP) && containsOnlyNone(svc.Spec.ClusterIPs) {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// ClusterIPIsNone checks to see whether the ClusterIP contains "None" which would indicate that it is headless
|
|
func ClusterIPIsNone(clusterIP string) bool {
|
|
return strings.ToLower(clusterIP) == "none"
|
|
}
|
|
|
|
func ClusterIPIsNoneOrBlank(clusterIP string) bool {
|
|
return ClusterIPIsNone(clusterIP) || clusterIP == ""
|
|
}
|
|
|
|
func containsOnlyNone(clusterIPs []string) bool {
|
|
for _, clusterIP := range clusterIPs {
|
|
if !ClusterIPIsNone(clusterIP) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|