Documentation ¶
Overview ¶
Example ¶
package main import ( "fmt" "strings" "sigs.k8s.io/kpng/api/localv1" ) // fix the protobuf "I'll randomly choose to double spaces or not" bug (it's a bug right???) func cleanStr(v fmt.Stringer) string { if v == nil { return "<nil>" } return strings.ReplaceAll(v.String(), " ", " ") } type portsLsnr struct{} func (_ portsLsnr) AddPort(svc *localv1.Service, port *localv1.PortMapping) { fmt.Print("ADD svc: ", cleanStr(svc), "\n port: ", cleanStr(port), "\n") } func (_ portsLsnr) DeletePort(svc *localv1.Service, port *localv1.PortMapping) { fmt.Print("DEL svc: ", cleanStr(svc), "\n port: ", cleanStr(port), "\n") } type ipsLsnr struct{} func (_ ipsLsnr) AddIP(svc *localv1.Service, ip string, ipKind IPKind) { fmt.Print("ADD svc: ", cleanStr(svc), "\n ip: ", ip, " (", ipKind, ")\n") } func (_ ipsLsnr) DeleteIP(svc *localv1.Service, ip string, ipKind IPKind) { fmt.Print("DEL svc: ", cleanStr(svc), "\n ip: ", ip, " (", ipKind, ")\n") } type ipPortsLsnr struct{} func (_ ipPortsLsnr) AddIPPort(svc *localv1.Service, ip string, ipKind IPKind, port *localv1.PortMapping) { fmt.Print("ADD svc: ", cleanStr(svc), "\n ip: ", ip, " (", ipKind, ")\n port: ", cleanStr(port), "\n") } func (_ ipPortsLsnr) DeleteIPPort(svc *localv1.Service, ip string, ipKind IPKind, port *localv1.PortMapping) { fmt.Print("DEL svc: ", cleanStr(svc), "\n ip: ", ip, " (", ipKind, ")\n port: ", cleanStr(port), "\n") } type sessAffLsnr struct{} func (_ sessAffLsnr) EnableSessionAffinity(svc *localv1.Service, sessionAffinity SessionAffinity) { fmt.Print("ENABLE sessionAffinity svc: ", cleanStr(svc), "sessionAffinity: ", sessionAffinity, "\n") } func (_ sessAffLsnr) DisableSessionAffinity(svc *localv1.Service) { fmt.Print("DISABLE sessionAffinity svc: ", cleanStr(svc), "\n") } func main() { sl := New() sl.PortsListener = portsLsnr{} sl.IPsListener = ipsLsnr{} sl.IPPortsListener = ipPortsLsnr{} sl.SessionAffinityListener = sessAffLsnr{} fmt.Println("add svc with port 80") sl.SetService(&localv1.Service{ Namespace: "ns", Name: "svc-1", Ports: []*localv1.PortMapping{ {Protocol: localv1.Protocol_TCP, Port: 80}, }, }) fmt.Println("\nadd port 81") sl.SetService(&localv1.Service{ Namespace: "ns", Name: "svc-1", Ports: []*localv1.PortMapping{ {Protocol: localv1.Protocol_TCP, Port: 80}, {Protocol: localv1.Protocol_TCP, Port: 81}, }, }) fmt.Println("\nadd port 82, remove port 81") sl.SetService(&localv1.Service{ Namespace: "ns", Name: "svc-1", Ports: []*localv1.PortMapping{ {Protocol: localv1.Protocol_TCP, Port: 80}, {Protocol: localv1.Protocol_TCP, Port: 82}, }, }) fmt.Println("\nadd cluster IP") sl.SetService(&localv1.Service{ Namespace: "ns", Name: "svc-1", IPs: &localv1.ServiceIPs{ ClusterIPs: localv1.NewIPSet("10.1.1.1"), }, Ports: []*localv1.PortMapping{ {Protocol: localv1.Protocol_TCP, Port: 80}, {Protocol: localv1.Protocol_TCP, Port: 82}, }, }) fmt.Println("\nenable external traffic policy") sl.SetService(&localv1.Service{ Namespace: "ns", Name: "svc-1", IPs: &localv1.ServiceIPs{ ClusterIPs: localv1.NewIPSet("10.1.1.1"), }, Ports: []*localv1.PortMapping{ {Protocol: localv1.Protocol_TCP, Port: 80}, {Protocol: localv1.Protocol_TCP, Port: 82}, }, ExternalTrafficToLocal: true, }) fmt.Println("\ndisable external traffic policy") sl.SetService(&localv1.Service{ Namespace: "ns", Name: "svc-1", IPs: &localv1.ServiceIPs{ ClusterIPs: localv1.NewIPSet("10.1.1.1"), }, Ports: []*localv1.PortMapping{ {Protocol: localv1.Protocol_TCP, Port: 80}, {Protocol: localv1.Protocol_TCP, Port: 82}, }, ExternalTrafficToLocal: false, }) fmt.Println("\nenable internal traffic policy") sl.SetService(&localv1.Service{ Namespace: "ns", Name: "svc-1", IPs: &localv1.ServiceIPs{ ClusterIPs: localv1.NewIPSet("10.1.1.1"), }, Ports: []*localv1.PortMapping{ {Protocol: localv1.Protocol_TCP, Port: 80}, {Protocol: localv1.Protocol_TCP, Port: 82}, }, InternalTrafficToLocal: true, }) fmt.Println("\ndisable internal traffic policy") sl.SetService(&localv1.Service{ Namespace: "ns", Name: "svc-1", IPs: &localv1.ServiceIPs{ ClusterIPs: localv1.NewIPSet("10.1.1.1"), }, Ports: []*localv1.PortMapping{ {Protocol: localv1.Protocol_TCP, Port: 80}, {Protocol: localv1.Protocol_TCP, Port: 82}, }, InternalTrafficToLocal: false, }) fmt.Println("\nenable session affinity") svc := &localv1.Service{ Namespace: "ns", Name: "svc-session-affinity-1", IPs: &localv1.ServiceIPs{ ClusterIPs: localv1.NewIPSet("10.1.1.1"), }, Ports: []*localv1.PortMapping{ {Protocol: localv1.Protocol_TCP, Port: 80}, {Protocol: localv1.Protocol_TCP, Port: 82}, }, } svc.SessionAffinity = &localv1.Service_ClientIP{ ClientIP: &localv1.ClientIPAffinity{ TimeoutSeconds: 10, }, } sl.SetService(svc) fmt.Println("\ndisable session affinity") svc = &localv1.Service{ Namespace: "ns", Name: "svc-session-affinity-1", IPs: &localv1.ServiceIPs{ ClusterIPs: localv1.NewIPSet("10.1.1.1"), }, Ports: []*localv1.PortMapping{ {Protocol: localv1.Protocol_TCP, Port: 80}, {Protocol: localv1.Protocol_TCP, Port: 82}, }, } sl.SetService(svc) fmt.Println("\ndelete svc") sl.DeleteService("ns", "svc-1") sl.DeleteService("ns", "svc-session-affinity-1")
Output:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Wrap ¶
Wrap a decoder so it receives detailled events depending on which interfaces it implements.
A good practice is to ensure your decoder is implementing what you expect this way:
type MyBackend struct { } var _ servicevents.PortsListener = &MyBackend{} var _ servicevents.IPsListener = &MyBackend{} var _ servicevents.IPPortsListener = &MyBackend{}
Example ¶
package main import ( "fmt" "sigs.k8s.io/kpng/api/localv1" ) type wrapperBackend struct{} func (_ wrapperBackend) Sync() { fmt.Println("backend Sync") } func (_ wrapperBackend) Setup() { fmt.Println("backend Setup") } func (_ wrapperBackend) Reset() { fmt.Println("backend Reset") } func (_ wrapperBackend) SetService(service *localv1.Service) { fmt.Println("backend SetService") } func (_ wrapperBackend) DeleteService(namespace, name string) { fmt.Println("backend DeleteService") } func (_ wrapperBackend) WaitRequest() (nodeName string, err error) { fmt.Println("backend WaitRequest") return "localhost", nil } func (_ wrapperBackend) SetEndpoint(namespace, serviceName, key string, endpoint *localv1.Endpoint) { fmt.Println("backend SetEndpoint") } func (_ wrapperBackend) DeleteEndpoint(namespace, serviceName, key string) { fmt.Println("backend DeleteEndpoint") } func main() { w := Wrap(wrapperBackend{}) w.Setup() w.Reset() w.Sync() }
Output: backend Setup backend Reset backend Sync
Types ¶
type Diff ¶
type IPKind ¶
type IPKind int
IPKind decribes the kind of IP received by an IPsListener or and IPPortsListener.
type IPPortsListener ¶
type IPsListener ¶
type PortsListener ¶
type PortsListener interface { AddPort(svc *localv1.Service, port *localv1.PortMapping) DeletePort(svc *localv1.Service, port *localv1.PortMapping) }
type ServicesListener ¶
type ServicesListener struct { PortsListener PortsListener IPsListener IPsListener IPPortsListener IPPortsListener TrafficPolicyListener TrafficPolicyListener SessionAffinityListener SessionAffinityListener // contains filtered or unexported fields }
ServicesListener analyzes updates to the Service set and produced detailed events about the changes.
The analyze producing events is only called if the corresponding listener is present, so no cost is associated with ignored events.
Event call order is: - AddPort - DeletePort - AddIP - AddIPPort - DeleteIPPort - DeleteIP
func New ¶
func New() *ServicesListener
New creates a new ServicesListener.
Reminder: you need to associate listeners for this listener to be useful.
func (*ServicesListener) DeleteService ¶
func (sl *ServicesListener) DeleteService(namespace, name string)
DeleteService is called when a service is deleted
func (*ServicesListener) SetService ¶
func (sl *ServicesListener) SetService(svc *localv1.Service)
SetService is called when a service is added or updated
type SessionAffinity ¶
type SessionAffinity struct {
ClientIP *localv1.Service_ClientIP
}
SessionAffinity contains data about assinged session affinity
func GetSessionAffinity ¶
func GetSessionAffinity(affinity interface{}) SessionAffinity
type SessionAffinityListener ¶
type SessionAffinityListener interface { EnableSessionAffinity(svc *localv1.Service, sessionAffinity SessionAffinity) DisableSessionAffinity(svc *localv1.Service) }
type TrafficPolicyKind ¶
type TrafficPolicyKind int
TrafficPolicyKind decribes the type of traffic policy received by TrafficPolicyListener
const ( TrafficPolicyInternal TrafficPolicyKind = iota TrafficPolicyExternal )
type TrafficPolicyListener ¶
type TrafficPolicyListener interface { EnableTrafficPolicy(svc *localv1.Service, policyKind TrafficPolicyKind) DisableTrafficPolicy(svc *localv1.Service, policyKind TrafficPolicyKind) }