...
1
16
17 package endpointslicemirroring
18
19 import (
20 v1 "k8s.io/api/core/v1"
21 discovery "k8s.io/api/discovery/v1"
22 endpointsliceutil "k8s.io/endpointslice/util"
23 )
24
25
26 type slicesByAction struct {
27 toCreate, toUpdate, toDelete []*discovery.EndpointSlice
28 }
29
30
31 func (s *slicesByAction) append(slices slicesByAction) {
32 s.toCreate = append(s.toCreate, slices.toCreate...)
33 s.toUpdate = append(s.toUpdate, slices.toUpdate...)
34 s.toDelete = append(s.toDelete, slices.toDelete...)
35 }
36
37
38 type totalsByAction struct {
39 added, updated, removed int
40 }
41
42
43 func (t *totalsByAction) add(totals totalsByAction) {
44 t.added += totals.added
45 t.updated += totals.updated
46 t.removed += totals.removed
47 }
48
49
50 func newDesiredCalc() *desiredCalc {
51 return &desiredCalc{
52 portsByKey: map[addrTypePortMapKey][]discovery.EndpointPort{},
53 endpointsByKey: map[addrTypePortMapKey]endpointsliceutil.EndpointSet{},
54 numDesiredEndpoints: 0,
55 }
56 }
57
58
59 type desiredCalc struct {
60 portsByKey map[addrTypePortMapKey][]discovery.EndpointPort
61 endpointsByKey map[addrTypePortMapKey]endpointsliceutil.EndpointSet
62 numDesiredEndpoints int
63 }
64
65
66
67 type multiAddrTypePortMapKey map[discovery.AddressType]addrTypePortMapKey
68
69
70
71 func (d *desiredCalc) initPorts(subsetPorts []v1.EndpointPort) multiAddrTypePortMapKey {
72 endpointPorts := epPortsToEpsPorts(subsetPorts)
73 addrTypes := []discovery.AddressType{discovery.AddressTypeIPv4, discovery.AddressTypeIPv6}
74 multiKey := multiAddrTypePortMapKey{}
75
76 for _, addrType := range addrTypes {
77 multiKey[addrType] = newAddrTypePortMapKey(endpointPorts, addrType)
78 if _, ok := d.endpointsByKey[multiKey[addrType]]; !ok {
79 d.endpointsByKey[multiKey[addrType]] = endpointsliceutil.EndpointSet{}
80 }
81 d.portsByKey[multiKey[addrType]] = endpointPorts
82 }
83
84 return multiKey
85 }
86
87
88
89 func (d *desiredCalc) addAddress(address v1.EndpointAddress, multiKey multiAddrTypePortMapKey, ready bool) bool {
90 endpoint := addressToEndpoint(address, ready)
91 addrType := getAddressType(address.IP)
92 if addrType == nil {
93 return false
94 }
95
96 d.endpointsByKey[multiKey[*addrType]].Insert(endpoint)
97 d.numDesiredEndpoints++
98 return true
99 }
100
101 type slicesByAddrType map[discovery.AddressType][]*discovery.EndpointSlice
102
103
104
105 func recycleSlices(slices *slicesByAction) {
106 toCreateByAddrType := toSlicesByAddrType(slices.toCreate)
107 toDeleteByAddrType := toSlicesByAddrType(slices.toDelete)
108
109 for addrType, slicesToCreate := range toCreateByAddrType {
110 slicesToDelete := toDeleteByAddrType[addrType]
111 for i := 0; len(slicesToCreate) > i && len(slicesToDelete) > i; i++ {
112 slices.toCreate = removeSlice(slices.toCreate, slicesToCreate[i])
113 slices.toDelete = removeSlice(slices.toDelete, slicesToDelete[i])
114 slice := slicesToCreate[i]
115 slice.Name = slicesToDelete[i].Name
116 slices.toUpdate = append(slices.toUpdate, slice)
117 }
118 }
119 }
120
121
122 func removeSlice(slices []*discovery.EndpointSlice, sliceToRemove *discovery.EndpointSlice) []*discovery.EndpointSlice {
123 for i, slice := range slices {
124 if slice.Name == sliceToRemove.Name {
125 return append(slices[:i], slices[i+1:]...)
126 }
127 }
128 return slices
129 }
130
131
132 func toSlicesByAddrType(slices []*discovery.EndpointSlice) slicesByAddrType {
133 byAddrType := slicesByAddrType{}
134 for _, slice := range slices {
135 byAddrType[slice.AddressType] = append(byAddrType[slice.AddressType], slice)
136 }
137 return byAddrType
138 }
139
View as plain text