Skip to content

Commit f6f0aaa

Browse files
authored
refactor Service Controller to it's own file (#6395)
1 parent 3517036 commit f6f0aaa

File tree

5 files changed

+353
-337
lines changed

5 files changed

+353
-337
lines changed

internal/k8s/controller.go

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -507,15 +507,6 @@ func (nsi *namespacedInformer) addSecretHandler(handlers cache.ResourceEventHand
507507
nsi.cacheSyncs = append(nsi.cacheSyncs, informer.HasSynced)
508508
}
509509

510-
// addServiceHandler adds the handler for services to the controller
511-
func (nsi *namespacedInformer) addServiceHandler(handlers cache.ResourceEventHandlerFuncs) {
512-
informer := nsi.sharedInformerFactory.Core().V1().Services().Informer()
513-
informer.AddEventHandler(handlers)
514-
nsi.svcLister = informer.GetStore()
515-
516-
nsi.cacheSyncs = append(nsi.cacheSyncs, informer.HasSynced)
517-
}
518-
519510
// addIngressHandler adds the handler for ingresses to the controller
520511
func (nsi *namespacedInformer) addIngressHandler(handlers cache.ResourceEventHandlerFuncs) {
521512
informer := nsi.sharedInformerFactory.Networking().V1().Ingresses().Informer()
@@ -1618,79 +1609,6 @@ func (lbc *LoadBalancerController) updateVirtualServerMetrics() {
16181609
lbc.metricsCollector.SetVirtualServerRoutes(vsrCount)
16191610
}
16201611

1621-
func (lbc *LoadBalancerController) syncService(task task) {
1622-
key := task.Key
1623-
1624-
var obj interface{}
1625-
var exists bool
1626-
var err error
1627-
1628-
ns, _, _ := cache.SplitMetaNamespaceKey(key)
1629-
obj, exists, err = lbc.getNamespacedInformer(ns).svcLister.GetByKey(key)
1630-
if err != nil {
1631-
lbc.syncQueue.Requeue(task, err)
1632-
return
1633-
}
1634-
1635-
// First case: the service is the external service for the Ingress Controller
1636-
// In that case we need to update the statuses of all resources
1637-
1638-
if lbc.IsExternalServiceKeyForStatus(key) {
1639-
glog.V(3).Infof("Syncing service %v", key)
1640-
1641-
if !exists {
1642-
// service got removed
1643-
lbc.statusUpdater.ClearStatusFromExternalService()
1644-
} else {
1645-
// service added or updated
1646-
lbc.statusUpdater.SaveStatusFromExternalService(obj.(*api_v1.Service))
1647-
}
1648-
1649-
if lbc.reportStatusEnabled() {
1650-
ingresses := lbc.configuration.GetResourcesWithFilter(resourceFilter{Ingresses: true})
1651-
1652-
glog.V(3).Infof("Updating status for %v Ingresses", len(ingresses))
1653-
1654-
err := lbc.statusUpdater.UpdateExternalEndpointsForResources(ingresses)
1655-
if err != nil {
1656-
glog.Errorf("error updating ingress status in syncService: %v", err)
1657-
}
1658-
}
1659-
1660-
if lbc.areCustomResourcesEnabled && lbc.reportCustomResourceStatusEnabled() {
1661-
virtualServers := lbc.configuration.GetResourcesWithFilter(resourceFilter{VirtualServers: true})
1662-
1663-
glog.V(3).Infof("Updating status for %v VirtualServers", len(virtualServers))
1664-
1665-
err := lbc.statusUpdater.UpdateExternalEndpointsForResources(virtualServers)
1666-
if err != nil {
1667-
glog.V(3).Infof("error updating VirtualServer/VirtualServerRoute status in syncService: %v", err)
1668-
}
1669-
}
1670-
1671-
// we don't return here because technically the same service could be used in the second case
1672-
}
1673-
1674-
// Second case: the service is referenced by some resources in the cluster
1675-
1676-
// it is safe to ignore the error
1677-
namespace, name, _ := ParseNamespaceName(key)
1678-
1679-
resources := lbc.configuration.FindResourcesForService(namespace, name)
1680-
1681-
if len(resources) == 0 {
1682-
return
1683-
}
1684-
glog.V(3).Infof("Syncing service %v", key)
1685-
1686-
glog.V(3).Infof("Updating %v resources", len(resources))
1687-
1688-
resourceExes := lbc.createExtendedResources(resources)
1689-
1690-
warnings, updateErr := lbc.configurator.AddOrUpdateResources(resourceExes, true)
1691-
lbc.updateResourcesStatusAndEvents(resources, warnings, updateErr)
1692-
}
1693-
16941612
// IsExternalServiceForStatus matches the service specified by the external-service cli arg
16951613
func (lbc *LoadBalancerController) IsExternalServiceForStatus(svc *api_v1.Service) bool {
16961614
return lbc.statusUpdater.namespace == svc.Namespace && lbc.statusUpdater.externalServiceName == svc.Name

internal/k8s/handlers.go

Lines changed: 0 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package k8s
33
import (
44
"fmt"
55
"reflect"
6-
"sort"
76

87
"github.com/jinzhu/copier"
98

@@ -103,109 +102,6 @@ func createSecretHandlers(lbc *LoadBalancerController) cache.ResourceEventHandle
103102
}
104103
}
105104

106-
// createServiceHandlers builds the handler funcs for services.
107-
//
108-
// In the update handlers below we catch two cases:
109-
// (1) the service is the external service
110-
// (2) the service had a change like a change of the port field of a service port (for such a change Kubernetes doesn't
111-
// update the corresponding endpoints resource, that we monitor as well)
112-
// or a change of the externalName field of an ExternalName service.
113-
//
114-
// In both cases we enqueue the service to be processed by syncService
115-
func createServiceHandlers(lbc *LoadBalancerController) cache.ResourceEventHandlerFuncs {
116-
return cache.ResourceEventHandlerFuncs{
117-
AddFunc: func(obj interface{}) {
118-
svc := obj.(*v1.Service)
119-
120-
glog.V(3).Infof("Adding service: %v", svc.Name)
121-
lbc.AddSyncQueue(svc)
122-
},
123-
DeleteFunc: func(obj interface{}) {
124-
svc, isSvc := obj.(*v1.Service)
125-
if !isSvc {
126-
deletedState, ok := obj.(cache.DeletedFinalStateUnknown)
127-
if !ok {
128-
glog.V(3).Infof("Error received unexpected object: %v", obj)
129-
return
130-
}
131-
svc, ok = deletedState.Obj.(*v1.Service)
132-
if !ok {
133-
glog.V(3).Infof("Error DeletedFinalStateUnknown contained non-Service object: %v", deletedState.Obj)
134-
return
135-
}
136-
}
137-
138-
glog.V(3).Infof("Removing service: %v", svc.Name)
139-
lbc.AddSyncQueue(svc)
140-
},
141-
UpdateFunc: func(old, cur interface{}) {
142-
if !reflect.DeepEqual(old, cur) {
143-
curSvc := cur.(*v1.Service)
144-
if lbc.IsExternalServiceForStatus(curSvc) {
145-
lbc.AddSyncQueue(curSvc)
146-
return
147-
}
148-
oldSvc := old.(*v1.Service)
149-
if hasServiceChanges(oldSvc, curSvc) {
150-
glog.V(3).Infof("Service %v changed, syncing", curSvc.Name)
151-
lbc.AddSyncQueue(curSvc)
152-
}
153-
}
154-
},
155-
}
156-
}
157-
158-
type portSort []v1.ServicePort
159-
160-
func (a portSort) Len() int {
161-
return len(a)
162-
}
163-
164-
func (a portSort) Swap(i, j int) {
165-
a[i], a[j] = a[j], a[i]
166-
}
167-
168-
func (a portSort) Less(i, j int) bool {
169-
if a[i].Name == a[j].Name {
170-
return a[i].Port < a[j].Port
171-
}
172-
return a[i].Name < a[j].Name
173-
}
174-
175-
// hasServicedChanged checks if the service has changed based on custom rules we define (eg. port).
176-
func hasServiceChanges(oldSvc, curSvc *v1.Service) bool {
177-
if hasServicePortChanges(oldSvc.Spec.Ports, curSvc.Spec.Ports) {
178-
return true
179-
}
180-
if hasServiceExternalNameChanges(oldSvc, curSvc) {
181-
return true
182-
}
183-
return false
184-
}
185-
186-
// hasServiceExternalNameChanges only compares Service.Spec.Externalname for Type ExternalName services.
187-
func hasServiceExternalNameChanges(oldSvc, curSvc *v1.Service) bool {
188-
return curSvc.Spec.Type == v1.ServiceTypeExternalName && oldSvc.Spec.ExternalName != curSvc.Spec.ExternalName
189-
}
190-
191-
// hasServicePortChanges only compares ServicePort.Name and .Port.
192-
func hasServicePortChanges(oldServicePorts []v1.ServicePort, curServicePorts []v1.ServicePort) bool {
193-
if len(oldServicePorts) != len(curServicePorts) {
194-
return true
195-
}
196-
197-
sort.Sort(portSort(oldServicePorts))
198-
sort.Sort(portSort(curServicePorts))
199-
200-
for i := range oldServicePorts {
201-
if oldServicePorts[i].Port != curServicePorts[i].Port ||
202-
oldServicePorts[i].Name != curServicePorts[i].Name {
203-
return true
204-
}
205-
}
206-
return false
207-
}
208-
209105
func createVirtualServerHandlers(lbc *LoadBalancerController) cache.ResourceEventHandlerFuncs {
210106
return cache.ResourceEventHandlerFuncs{
211107
AddFunc: func(obj interface{}) {

internal/k8s/handlers_test.go

Lines changed: 0 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -4,160 +4,9 @@ import (
44
"errors"
55
"testing"
66

7-
v1 "k8s.io/api/core/v1"
87
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
9-
"k8s.io/apimachinery/pkg/util/intstr"
108
)
119

12-
func TestHasServicePortChanges(t *testing.T) {
13-
t.Parallel()
14-
cases := []struct {
15-
a []v1.ServicePort
16-
b []v1.ServicePort
17-
result bool
18-
reason string
19-
}{
20-
{
21-
[]v1.ServicePort{},
22-
[]v1.ServicePort{},
23-
false,
24-
"Empty should report no changes",
25-
},
26-
{
27-
[]v1.ServicePort{{
28-
Port: 80,
29-
}},
30-
[]v1.ServicePort{{
31-
Port: 8080,
32-
}},
33-
true,
34-
"Different Ports",
35-
},
36-
{
37-
[]v1.ServicePort{{
38-
Port: 80,
39-
}},
40-
[]v1.ServicePort{{
41-
Port: 80,
42-
}},
43-
false,
44-
"Same Ports",
45-
},
46-
{
47-
[]v1.ServicePort{{
48-
Name: "asdf",
49-
Port: 80,
50-
}},
51-
[]v1.ServicePort{{
52-
Name: "asdf",
53-
Port: 80,
54-
}},
55-
false,
56-
"Same Port and Name",
57-
},
58-
{
59-
[]v1.ServicePort{{
60-
Name: "foo",
61-
Port: 80,
62-
}},
63-
[]v1.ServicePort{{
64-
Name: "bar",
65-
Port: 80,
66-
}},
67-
true,
68-
"Different Name same Port",
69-
},
70-
{
71-
[]v1.ServicePort{{
72-
Name: "foo",
73-
Port: 8080,
74-
}},
75-
[]v1.ServicePort{{
76-
Name: "bar",
77-
Port: 80,
78-
}},
79-
true,
80-
"Different Name different Port",
81-
},
82-
{
83-
[]v1.ServicePort{{
84-
Name: "foo",
85-
}},
86-
[]v1.ServicePort{{
87-
Name: "fooo",
88-
}},
89-
true,
90-
"Very similar Name",
91-
},
92-
{
93-
[]v1.ServicePort{{
94-
Name: "asdf",
95-
Port: 80,
96-
TargetPort: intstr.IntOrString{
97-
IntVal: 80,
98-
},
99-
}},
100-
[]v1.ServicePort{{
101-
Name: "asdf",
102-
Port: 80,
103-
TargetPort: intstr.IntOrString{
104-
IntVal: 8080,
105-
},
106-
}},
107-
false,
108-
"TargetPort should be ignored",
109-
},
110-
{
111-
[]v1.ServicePort{{
112-
Name: "foo",
113-
}, {
114-
Name: "bar",
115-
}},
116-
[]v1.ServicePort{{
117-
Name: "foo",
118-
}, {
119-
Name: "bar",
120-
}},
121-
false,
122-
"Multiple same names",
123-
},
124-
{
125-
[]v1.ServicePort{{
126-
Name: "foo",
127-
}, {
128-
Name: "bar",
129-
}},
130-
[]v1.ServicePort{{
131-
Name: "foo",
132-
}, {
133-
Name: "bars",
134-
}},
135-
true,
136-
"Multiple different names",
137-
},
138-
{
139-
[]v1.ServicePort{{
140-
Name: "foo",
141-
}, {
142-
Port: 80,
143-
}},
144-
[]v1.ServicePort{{
145-
Port: 80,
146-
}, {
147-
Name: "foo",
148-
}},
149-
false,
150-
"Some names some ports",
151-
},
152-
}
153-
154-
for _, c := range cases {
155-
if c.result != hasServicePortChanges(c.a, c.b) {
156-
t.Errorf("hasServicePortChanges returned %v, but expected %v for %q case", c.result, !c.result, c.reason)
157-
}
158-
}
159-
}
160-
16110
func TestAreResourcesDifferent(t *testing.T) {
16211
t.Parallel()
16312
tests := []struct {

0 commit comments

Comments
 (0)