-
Notifications
You must be signed in to change notification settings - Fork 0
/
gwendpointslice_types.go
124 lines (105 loc) · 3.89 KB
/
gwendpointslice_types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package v1
import (
"context"
v1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
)
func init() {
SchemeBuilder.Register(&GWEndpointSlice{}, &GWEndpointSliceList{})
}
// GWEndpointSliceSpec is a container for the EndpointSlice object in
// the client cluster. It also contains the info needed to find the
// object on the client side.
type GWEndpointSliceSpec struct {
// ClientRef points back to the client-side object that corresponds
// to this one.
ClientRef ClientRef `json:"clientRef,omitempty"`
// ParentRef points to the client-side service that owns this slice.
ParentRef ClientRef `json:"parentRef,omitempty"`
// Slice holds the client-side EndpointSlice contents.
discoveryv1.EndpointSlice `json:",inline"`
// Map of node addresses. Key is node name, value is IP address
// represented as string.
NodeAddresses map[string]string `json:"nodeAddresses"`
}
// GWEndpointSliceStatus defines the observed state of GWEndpointSlice.
type GWEndpointSliceStatus struct {
}
//+kubebuilder:object:root=true
//+kubebuilder:resource:shortName=gwes;gwess,path=gwendpointslices,singular=gwendpointslice
//+kubebuilder:subresource:status
//+kubebuilder:printcolumn:JSONPath=".spec.clientRef.clusterID",name=Client Cluster,type=string
//+kubebuilder:printcolumn:JSONPath=".spec.clientRef.namespace",name=Client NS,type=string
//+kubebuilder:printcolumn:JSONPath=".spec.clientRef.name",name=Client Name,type=string
// GWEndpointSlice corresponds to an EndpointSlice object in a client
// cluster. It provides data for Envoy and to set up the GUE tunnels.
type GWEndpointSlice struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec GWEndpointSliceSpec `json:"spec,omitempty"`
Status GWEndpointSliceStatus `json:"status,omitempty"`
}
//+kubebuilder:object:root=true
// GWEndpointSliceList contains a list of GWEndpointSlice
type GWEndpointSliceList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []GWEndpointSlice `json:"items"`
}
// ReferencingProxies returns an array of the GWProxies that link to
// this slice via GWRoutes.
func (slice *GWEndpointSlice) ReferencingProxies(ctx context.Context, cl client.Client) ([]*GWProxy, error) {
refs := []*GWProxy{}
listOps := client.ListOptions{Namespace: slice.Namespace}
routes := GWRouteList{}
err := cl.List(ctx, &routes, &listOps)
if err != nil {
return refs, err
}
for _, route := range routes.Items {
for _, ref := range route.Backends() {
backendName := string(ref.Name)
if backendName == slice.Spec.ParentRef.UID {
for _, parent := range route.Parents() {
proxy := GWProxy{}
proxyName := types.NamespacedName{Namespace: slice.Namespace, Name: string(parent.Name)}
if err := cl.Get(ctx, proxyName, &proxy); err != nil {
// If there's an error other than "not found" then bail
// out and report it. If we can't find the Proxy that's
// probably because it was deleted which isn't an error.
if client.IgnoreNotFound(err) != nil {
return refs, err
}
} else {
refs = append(refs, &proxy)
}
}
}
}
}
return refs, nil
}
// ToEndpoints represents this slice as an array of our LB
// RemoteEndpoints.
func (slice *GWEndpointSlice) ToEndpoints() []RemoteEndpoint {
activeEPs := []RemoteEndpoint{}
for _, endpoint := range slice.Spec.Endpoints {
for _, address := range endpoint.Addresses {
activeEPs = append(activeEPs, RemoteEndpoint{
Spec: RemoteEndpointSpec{
Cluster: slice.Spec.ParentRef.UID,
Address: address,
NodeAddress: slice.Spec.NodeAddresses[*endpoint.NodeName],
Port: v1.EndpointPort{
Port: *slice.Spec.Ports[0].Port,
Protocol: *slice.Spec.Ports[0].Protocol,
},
},
})
}
}
return activeEPs
}