This repository has been archived by the owner on Apr 29, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
floatingips.go
120 lines (108 loc) · 3.64 KB
/
floatingips.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
package cs
import (
"net/http"
"strconv"
"github.com/caos/orbos/internal/operator/orbiter/kinds/clusters/core/infra"
"github.com/cloudscale-ch/cloudscale-go-sdk"
"github.com/caos/orbos/internal/operator/orbiter/kinds/loadbalancers/dynamic"
)
func queryFloatingIPs(context *context, loadbalancing map[string][]*dynamic.VIP, writeTo *Current) ([]func() error, []func() error, map[string]bool, error) {
haveUnassignedVIPs := make(map[string]bool)
floatingIPs, err := context.client.FloatingIPs.List(context.ctx, func(r *http.Request) {
params := r.URL.Query()
params["orb"] = []string{context.orbID}
params["provider"] = []string{context.providerID}
})
if err != nil {
return nil, nil, nil, err
}
var ensure []func() error
createLoop:
for hostPool, vips := range loadbalancing {
for vipIdx := range vips {
vip := vips[vipIdx]
alreadyExists := false
for transportIdx := range vip.Transport {
transport := vip.Transport[transportIdx]
initCurrent(writeTo, transport)
for floatingIPIdx := range floatingIPs {
floatingIP := floatingIPs[floatingIPIdx]
if ensureCurrentIngress(floatingIP, hostPool, vipIdx, writeTo, transport) {
alreadyExists = true
if floatingIP.Server == nil || floatingIP.Server.UUID == "" {
haveUnassignedVIPs[hostPool] = true
}
}
}
}
if alreadyExists {
continue createLoop
}
ensure = append(ensure, func(hostPool string, vipIdx int) func() error {
return func() error {
_, err := context.client.FloatingIPs.Create(context.ctx, &cloudscale.FloatingIPCreateRequest{
RegionalResourceRequest: cloudscale.RegionalResourceRequest{},
TaggedResourceRequest: cloudscale.TaggedResourceRequest{Tags: map[string]string{
"orb": context.orbID,
"provider": context.providerID,
"pool": hostPool,
"idx": strconv.Itoa(vipIdx),
}},
IPVersion: 4,
Server: "",
Type: "regional",
PrefixLength: 0,
ReversePointer: "",
})
if err != nil {
return err
}
return nil
}
}(hostPool, vipIdx))
}
}
var remove []func() error
removeLoop:
for floatingIPIdx := range floatingIPs {
floatingIP := floatingIPs[floatingIPIdx]
matches := false
for hostPool, vips := range loadbalancing {
for vipIdx := range vips {
vip := vips[vipIdx]
for transpIdx := range vip.Transport {
transport := vip.Transport[transpIdx]
initCurrent(writeTo, transport)
matches = ensureCurrentIngress(floatingIP, hostPool, vipIdx, writeTo, transport) || matches
}
}
}
if matches {
continue removeLoop
}
remove = append(remove, func(ip string) func() error {
return func() error {
return context.client.FloatingIPs.Delete(context.ctx, ip)
}
}(floatingIP.IP()))
}
return ensure, remove, haveUnassignedVIPs, nil
}
func initCurrent(writeTo *Current, transport *dynamic.Transport) {
if writeTo.Current.Ingresses == nil {
writeTo.Current.Ingresses = make(map[string]*infra.Address)
}
if writeTo.Current.Ingresses[transport.Name] == nil {
writeTo.Current.Ingresses[transport.Name] = &infra.Address{}
}
}
func ensureCurrentIngress(floatingIP cloudscale.FloatingIP, hostPool string, vipIdx int, writeTo *Current, transport *dynamic.Transport) bool {
matches := false
if floatingIP.Tags["pool"] == hostPool && floatingIP.Tags["idx"] == strconv.Itoa(vipIdx) {
matches = true
writeTo.Current.Ingresses[transport.Name].Location = floatingIP.IP()
writeTo.Current.Ingresses[transport.Name].FrontendPort = uint16(transport.FrontendPort)
writeTo.Current.Ingresses[transport.Name].BackendPort = uint16(transport.BackendPort)
}
return matches
}