mirror of https://github.com/linkerd/linkerd2.git
127 lines
3.7 KiB
Go
127 lines
3.7 KiB
Go
package destination
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
proxyNet "github.com/linkerd/linkerd2-proxy-api/go/net"
|
|
sp "github.com/linkerd/linkerd2/controller/gen/apis/serviceprofile/v1alpha1"
|
|
"github.com/linkerd/linkerd2/pkg/addr"
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
)
|
|
|
|
type collectListener struct {
|
|
context context.Context
|
|
stopCh chan struct{}
|
|
}
|
|
|
|
func (c *collectListener) ClientClose() <-chan struct{} {
|
|
return c.context.Done()
|
|
}
|
|
|
|
func (c *collectListener) ServerClose() <-chan struct{} {
|
|
return c.stopCh
|
|
}
|
|
|
|
func (c *collectListener) Stop() {
|
|
close(c.stopCh)
|
|
}
|
|
|
|
// implements the endpointUpdateListener interface
|
|
type collectUpdateListener struct {
|
|
collectListener
|
|
added []*updateAddress
|
|
removed []*updateAddress
|
|
noEndpointsCalled bool
|
|
noEndpointsExists bool
|
|
}
|
|
|
|
func (c *collectUpdateListener) Update(add, remove []*updateAddress) {
|
|
c.added = append(c.added, add...)
|
|
c.removed = append(c.removed, remove...)
|
|
}
|
|
|
|
func (c *collectUpdateListener) NoEndpoints(exists bool) {
|
|
c.noEndpointsCalled = true
|
|
c.noEndpointsExists = exists
|
|
}
|
|
|
|
func (c *collectUpdateListener) SetServiceID(id *serviceID) {}
|
|
|
|
func newCollectUpdateListener() (*collectUpdateListener, context.CancelFunc) {
|
|
ctx, cancelFn := context.WithCancel(context.Background())
|
|
return &collectUpdateListener{collectListener: collectListener{context: ctx}}, cancelFn
|
|
}
|
|
|
|
// implements the profileUpdateListener interface
|
|
type collectProfileListener struct {
|
|
collectListener
|
|
profiles []*sp.ServiceProfile
|
|
}
|
|
|
|
func (c *collectProfileListener) Update(profile *sp.ServiceProfile) {
|
|
c.profiles = append(c.profiles, profile)
|
|
}
|
|
|
|
func newCollectProfileListener() (*collectProfileListener, context.CancelFunc) {
|
|
ctx, cancelFn := context.WithCancel(context.Background())
|
|
return &collectProfileListener{collectListener: collectListener{context: ctx}}, cancelFn
|
|
}
|
|
|
|
// validate whether two servicePorts structs are equal
|
|
func equalServicePorts(servicePorts1, servicePorts2 servicePorts) error {
|
|
if len(servicePorts1) != len(servicePorts2) {
|
|
return fmt.Errorf("servicePorts length mismatch: [%+v] != [%+v]", servicePorts1, servicePorts2)
|
|
}
|
|
|
|
for serviceID := range servicePorts1 {
|
|
portMap1 := servicePorts1[serviceID]
|
|
portMap2 := servicePorts2[serviceID]
|
|
if len(portMap1) != len(portMap2) {
|
|
return fmt.Errorf("servicePorts portMap length mismatch: [%+v] != [%+v]", portMap1, portMap2)
|
|
}
|
|
|
|
for port := range portMap1 {
|
|
sp1 := portMap1[port]
|
|
sp2 := portMap2[port]
|
|
|
|
if sp1.port != sp2.port {
|
|
return fmt.Errorf("servicePort port mismatch: [%+v] != [%+v]", sp1.port, sp2.port)
|
|
}
|
|
if sp1.targetPort != sp2.targetPort {
|
|
return fmt.Errorf("servicePort targetPort mismatch: [%+v] != [%+v]", sp1.targetPort, sp2.targetPort)
|
|
}
|
|
if sp1.service != sp2.service {
|
|
return fmt.Errorf("servicePort service mismatch: [%+v] != [%+v]", sp1.service, sp2.service)
|
|
}
|
|
if len(sp1.addresses) != len(sp2.addresses) {
|
|
return fmt.Errorf("servicePort addresses mismatch: [%+v] != [%+v]", sp1.addresses, sp2.addresses)
|
|
}
|
|
if sp1.endpoints.String() != sp2.endpoints.String() {
|
|
return fmt.Errorf("servicePort endpoints mismatch: [%s] != [%s]", sp1.endpoints, sp2.endpoints)
|
|
}
|
|
for i := range sp1.addresses {
|
|
if sp1.addresses[i].String() != sp2.addresses[i].String() {
|
|
return fmt.Errorf("servicePort address mismatch: [%s] != [%s]", sp1.addresses[i], sp2.addresses[i])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func makeUpdateAddress(ipStr string, portNum uint32, name string) *updateAddress {
|
|
ip, _ := addr.ParseProxyIPV4(ipStr)
|
|
return &updateAddress{
|
|
address: &proxyNet.TcpAddress{Ip: ip, Port: portNum},
|
|
pod: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Namespace: "ns",
|
|
Name: name,
|
|
},
|
|
},
|
|
}
|
|
}
|