/
update.go
161 lines (141 loc) 路 4.39 KB
/
update.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package ingress
import (
"net"
"strings"
"github.com/appscode/go/errors"
api "github.com/appscode/voyager/apis/voyager/v1beta1"
core "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
)
type UpdateMode int
const (
UpdateStats UpdateMode = 1 << iota // Update things for stats update
)
func (c *controller) updateConfigMap() error {
cMap, err := c.KubeClient.CoreV1().ConfigMaps(c.Ingress.Namespace).Get(c.Ingress.OffshootName(), metav1.GetOptions{})
if err != nil {
return errors.FromErr(err).Err()
}
if cMap.Annotations == nil {
// This is a safety check, annotations will not be nil
cMap.Annotations = make(map[string]string)
}
_, sourceNameFound := cMap.Annotations[api.OriginName]
_, sourceTypeFound := cMap.Annotations[api.OriginAPISchema]
if !sourceNameFound && !sourceTypeFound {
// Old version object
cMap.Annotations[api.OriginAPISchema] = c.Ingress.APISchema()
cMap.Annotations[api.OriginName] = c.Ingress.GetName()
}
if cMap.Data["haproxy.cfg"] != c.HAProxyConfig {
c.logger.Infoln("Specs have been changed updating config map data for HAProxy templates")
cMap.Data["haproxy.cfg"] = c.HAProxyConfig
_, err := c.KubeClient.CoreV1().ConfigMaps(c.Ingress.Namespace).Update(cMap)
if err != nil {
c.recorder.Eventf(c.Ingress.ObjectReference(), core.EventTypeWarning, "ConfigMapUpdateFailed", "HAProxy configuration Update failed, %s", err.Error())
return errors.FromErr(err).Err()
}
// Add event only if the ConfigMap Really Updated
c.recorder.Eventf(c.Ingress.ObjectReference(), core.EventTypeNormal, "ConfigMapUpdated", "ConfigMap Updated, HAProxy will restart itself now via reloader")
c.logger.Infoln("Config Map Updated, HAProxy will restart itself now via reloader")
}
return nil
}
func (c *controller) serviceRequiresUpdate(current, desired *core.Service, old *api.Ingress) (*core.Service, bool) {
if current == nil {
return nil, false // should never happen
}
needsUpdate := false
// ports
curPorts := make(map[int32]core.ServicePort)
for _, p := range current.Spec.Ports {
curPorts[p.Port] = p
}
for _, dp := range desired.Spec.Ports {
if cp, ok := curPorts[dp.Port]; !ok || // svc port not found
cp.TargetPort.IntValue() != dp.TargetPort.IntValue() || // pod port mismatch
(dp.NodePort != 0 && dp.NodePort != cp.NodePort) { // node port mismatch
if dp.NodePort == 0 && cp.NodePort > 0 {
dp.NodePort = cp.NodePort // avoid reassigning port
}
needsUpdate = true
}
delete(curPorts, dp.Port)
}
if len(curPorts) > 0 {
needsUpdate = true
}
if needsUpdate {
current.Spec.Ports = desired.Spec.Ports
}
// annotations
if current.Annotations == nil {
current.Annotations = make(map[string]string)
}
oldAnn := map[string]string{}
if old != nil {
if a, ok := old.ServiceAnnotations(c.Opt.CloudProvider); ok {
oldAnn = a
}
}
for k, v := range desired.Annotations {
if cv, found := current.Annotations[k]; !found || cv != v {
current.Annotations[k] = v
needsUpdate = true
}
delete(oldAnn, k)
}
for k := range oldAnn {
if _, ok := current.Annotations[k]; ok {
delete(current.Annotations, k)
needsUpdate = true
}
}
// LoadBalancer ranges
curRanges := sets.NewString()
for _, ips := range current.Spec.LoadBalancerSourceRanges {
if k, ok := ipnet(ips); ok {
curRanges.Insert(k)
}
}
desiredRanges := sets.NewString()
for _, ips := range desired.Spec.LoadBalancerSourceRanges {
if k, ok := ipnet(ips); ok {
desiredRanges.Insert(k)
}
}
if !curRanges.Equal(desiredRanges) {
needsUpdate = true
current.Spec.LoadBalancerSourceRanges = desired.Spec.LoadBalancerSourceRanges
}
if current.Spec.ExternalTrafficPolicy != desired.Spec.ExternalTrafficPolicy {
needsUpdate = true
current.Spec.ExternalTrafficPolicy = desired.Spec.ExternalTrafficPolicy
}
if !sets.NewString(current.Spec.ExternalIPs...).Equal(sets.NewString(desired.Spec.ExternalIPs...)) {
needsUpdate = true
current.Spec.ExternalIPs = desired.Spec.ExternalIPs
}
return current, needsUpdate
}
func ipnet(spec string) (string, bool) {
spec = strings.TrimSpace(spec)
_, ipnet, err := net.ParseCIDR(spec)
if err != nil {
return "", false
}
return ipnet.String(), true
}
func mergeAnnotations(obj, old, new map[string]string) map[string]string {
if obj == nil {
obj = make(map[string]string)
}
for k := range old {
delete(obj, k)
}
for k, v := range new {
obj[k] = v
}
return obj
}