Skip to content

Commit

Permalink
dataclients/kubernetes: add LoadEndpointAddresses
Browse files Browse the repository at this point in the history
Add LoadEndpointAddresses to cluster client.
It is similar to caching dataclient GetEndpointAddresses.

Signed-off-by: Alexander Yastrebov <alexander.yastrebov@zalando.de>
  • Loading branch information
AlexanderYastrebov committed Feb 12, 2024
1 parent d1e0b27 commit 1042d0f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
38 changes: 38 additions & 0 deletions dataclients/kubernetes/clusterclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,10 @@ func (c *ClusterClient) loadEndpointSlices() (map[definitions.ResourceID]*skippe
}
log.Debugf("all endpointslices received: %d", len(endpointSlices.Items))

return mapEndpointSlices(&endpointSlices), nil
}

func mapEndpointSlices(endpointSlices *endpointSliceList) map[definitions.ResourceID]*skipperEndpointSlice {
mapSlices := make(map[definitions.ResourceID][]*endpointSlice)
for _, endpointSlice := range endpointSlices.Items {
resID := endpointSlice.ToResourceID() // service resource ID
Expand Down Expand Up @@ -585,6 +589,40 @@ func (c *ClusterClient) loadEndpointSlices() (map[definitions.ResourceID]*skippe
result[resID].Endpoints = append(result[resID].Endpoints, o)
}
}
return result
}

// LoadEndpointAddresses returns the list of all addresses for the given service using endpoints or endpointslices API.
func (c *ClusterClient) LoadEndpointAddresses(namespace, name string) ([]string, error) {
var result []string
if c.enableEndpointSlices {
url := fmt.Sprintf(EndpointSlicesNamespaceFmt, namespace) +
toLabelSelectorQuery(map[string]string{endpointSliceServiceNameLabel: name})

var endpointSlices endpointSliceList
if err := c.getJSON(url, &endpointSlices); err != nil {
return nil, fmt.Errorf("requesting endpointslices for %s/%s failed: %v", namespace, name, err)
}

mapped := mapEndpointSlices(&endpointSlices)
if len(mapped) != 1 {
return nil, fmt.Errorf("unexpected number of endpoint slices for %s/%s: %d", namespace, name, len(mapped))
}

for _, eps := range mapped {
result = eps.addresses()
break
}
} else {
url := fmt.Sprintf(EndpointsNamespaceFmt, namespace) + "/" + name

var ep endpoint
if err := c.getJSON(url, &ep); err != nil {
return nil, fmt.Errorf("requesting endpoints for %s/%s failed: %v", namespace, name, err)
}
result = ep.addresses()
}
sort.Strings(result)

return result, nil
}
Expand Down
4 changes: 3 additions & 1 deletion dataclients/kubernetes/endpointslices.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"github.com/zalando/skipper/dataclients/kubernetes/definitions"
)

const endpointSliceServiceNameLabel = "kubernetes.io/service-name"

// There are [1..N] Kubernetes endpointslices created for a single Kubernetes service.
// Kubernetes endpointslices of a given service can have duplicates with different states.
// Therefore Kubernetes endpointslices need to be de-duplicated before usage.
Expand Down Expand Up @@ -97,7 +99,7 @@ type endpointSlice struct {

// ToResourceID returns the same string for a group endpointlisces created for the same svc
func (eps *endpointSlice) ToResourceID() definitions.ResourceID {
svcName := eps.Meta.Labels["kubernetes.io/service-name"]
svcName := eps.Meta.Labels[endpointSliceServiceNameLabel]
namespace := eps.Meta.Namespace
return newResourceID(namespace, svcName)
}
Expand Down

0 comments on commit 1042d0f

Please sign in to comment.