github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/internal/operator/orbiter/kinds/providers/cs/floatingips.go (about) 1 package cs 2 3 import ( 4 "net/http" 5 "strconv" 6 7 "github.com/caos/orbos/internal/operator/orbiter/kinds/clusters/core/infra" 8 9 "github.com/cloudscale-ch/cloudscale-go-sdk" 10 11 "github.com/caos/orbos/internal/operator/orbiter/kinds/loadbalancers/dynamic" 12 ) 13 14 func queryFloatingIPs(context *context, loadbalancing map[string][]*dynamic.VIP, writeTo *Current) ([]func() error, []func() error, map[string]bool, error) { 15 16 haveUnassignedVIPs := make(map[string]bool) 17 floatingIPs, err := context.client.FloatingIPs.List(context.ctx, func(r *http.Request) { 18 params := r.URL.Query() 19 params["orb"] = []string{context.orbID} 20 params["provider"] = []string{context.providerID} 21 }) 22 if err != nil { 23 return nil, nil, nil, err 24 } 25 26 var ensure []func() error 27 createLoop: 28 for hostPool, vips := range loadbalancing { 29 for vipIdx := range vips { 30 vip := vips[vipIdx] 31 alreadyExists := false 32 for transportIdx := range vip.Transport { 33 transport := vip.Transport[transportIdx] 34 initCurrent(writeTo, transport) 35 36 for floatingIPIdx := range floatingIPs { 37 floatingIP := floatingIPs[floatingIPIdx] 38 if ensureCurrentIngress(floatingIP, hostPool, vipIdx, writeTo, transport) { 39 alreadyExists = true 40 if floatingIP.Server == nil || floatingIP.Server.UUID == "" { 41 haveUnassignedVIPs[hostPool] = true 42 } 43 } 44 } 45 } 46 if alreadyExists { 47 continue createLoop 48 } 49 ensure = append(ensure, func(hostPool string, vipIdx int) func() error { 50 return func() error { 51 _, err := context.client.FloatingIPs.Create(context.ctx, &cloudscale.FloatingIPCreateRequest{ 52 RegionalResourceRequest: cloudscale.RegionalResourceRequest{}, 53 TaggedResourceRequest: cloudscale.TaggedResourceRequest{Tags: map[string]string{ 54 "orb": context.orbID, 55 "provider": context.providerID, 56 "pool": hostPool, 57 "idx": strconv.Itoa(vipIdx), 58 }}, 59 IPVersion: 4, 60 Server: "", 61 Type: "regional", 62 PrefixLength: 0, 63 ReversePointer: "", 64 }) 65 if err != nil { 66 return err 67 } 68 return nil 69 } 70 }(hostPool, vipIdx)) 71 } 72 } 73 74 var remove []func() error 75 76 removeLoop: 77 for floatingIPIdx := range floatingIPs { 78 floatingIP := floatingIPs[floatingIPIdx] 79 matches := false 80 for hostPool, vips := range loadbalancing { 81 for vipIdx := range vips { 82 vip := vips[vipIdx] 83 for transpIdx := range vip.Transport { 84 transport := vip.Transport[transpIdx] 85 initCurrent(writeTo, transport) 86 matches = ensureCurrentIngress(floatingIP, hostPool, vipIdx, writeTo, transport) || matches 87 } 88 } 89 } 90 if matches { 91 continue removeLoop 92 } 93 remove = append(remove, func(ip string) func() error { 94 return func() error { 95 return context.client.FloatingIPs.Delete(context.ctx, ip) 96 } 97 }(floatingIP.IP())) 98 } 99 return ensure, remove, haveUnassignedVIPs, nil 100 } 101 102 func initCurrent(writeTo *Current, transport *dynamic.Transport) { 103 if writeTo.Current.Ingresses == nil { 104 writeTo.Current.Ingresses = make(map[string]*infra.Address) 105 } 106 if writeTo.Current.Ingresses[transport.Name] == nil { 107 writeTo.Current.Ingresses[transport.Name] = &infra.Address{} 108 } 109 } 110 111 func ensureCurrentIngress(floatingIP cloudscale.FloatingIP, hostPool string, vipIdx int, writeTo *Current, transport *dynamic.Transport) bool { 112 matches := false 113 if floatingIP.Tags["pool"] == hostPool && floatingIP.Tags["idx"] == strconv.Itoa(vipIdx) { 114 matches = true 115 writeTo.Current.Ingresses[transport.Name].Location = floatingIP.IP() 116 writeTo.Current.Ingresses[transport.Name].FrontendPort = uint16(transport.FrontendPort) 117 writeTo.Current.Ingresses[transport.Name].BackendPort = uint16(transport.BackendPort) 118 } 119 return matches 120 }