github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/internal/operator/orbiter/kinds/providers/cs/ingress.go (about) 1 package cs 2 3 import ( 4 "bytes" 5 "fmt" 6 "strings" 7 8 "github.com/caos/orbos/internal/operator/orbiter/kinds/providers/core" 9 10 "github.com/caos/orbos/mntr" 11 12 "github.com/caos/orbos/internal/operator/orbiter/kinds/clusters/core/infra" 13 "github.com/caos/orbos/internal/operator/orbiter/kinds/loadbalancers/dynamic" 14 dynamiclbmodel "github.com/caos/orbos/internal/operator/orbiter/kinds/loadbalancers/dynamic" 15 ) 16 17 func desiredToCurrentVIP(current *Current) func(vip *dynamiclbmodel.VIP) string { 18 return func(vip *dynamic.VIP) string { 19 for idx := range vip.Transport { 20 transport := vip.Transport[idx] 21 address, ok := current.Current.Ingresses[transport.Name] 22 if ok { 23 return address.Location 24 } 25 } 26 panic(fmt.Errorf("external address for %v is not ensured", vip)) 27 } 28 } 29 30 func checkAuth(_ infra.Machine) (string, int) { 31 return `#!/bin/sh 32 33 set -e 34 35 curl -f -H "Authorization: Bearer $(cat /var/orbiter/cstoken)" "https://api.cloudscale.ch/v1/floating-ips" 36 `, 0 37 } 38 39 func notifyMaster(hostPools map[string][]*dynamiclbmodel.VIP, current *Current, poolsWithUnassignedVIPs map[string]bool) func(m infra.Machine) (string, bool) { 40 return func(m infra.Machine) (string, bool) { 41 42 machine := m.(*machine) 43 return fmt.Sprintf(`#!/bin/sh 44 45 set -e 46 47 # API token (with write permission) to access the cloudscale.ch API. 48 api_token="$(cat /var/orbiter/cstoken)" 49 50 # Set of Floating IPs shared between the servers within the same VRRP group. 51 floating_ipv4='%s' 52 53 # UUID of the server that this script is running on. 54 # The UUID of the server can be retrieved using the API. 55 server_uuid='%s' 56 57 # Call the cloudscale.ch API to assign a specific Floating IP to this server. 58 set_master() { 59 curl \ 60 -f \ 61 -H "Authorization: Bearer $api_token" \ 62 -F server="$server_uuid" \ 63 "https://api.cloudscale.ch/v1/floating-ips/$1" 64 } 65 66 for VIP in "$floating_ipv4"; do 67 set_master $VIP 68 done 69 `, strings.Join(hostedVIPs(hostPools, m, current), " "), machine.server.UUID), poolsWithUnassignedVIPs[machine.poolName] 70 } 71 } 72 73 func allHostedVIPs(hostPools map[string][]*dynamiclbmodel.VIP, service core.MachinesService, current *Current) (map[string][]string, error) { 74 vips := make(map[string][]string, 0) 75 pools, err := service.ListPools() 76 if err != nil { 77 return nil, err 78 } 79 for _, pool := range pools { 80 poolMachines, err := service.List(pool) 81 if err != nil { 82 return nil, err 83 } 84 for idx := range poolMachines { 85 machine := poolMachines[idx] 86 vips[machine.ID()] = hostedVIPs(hostPools, machine, current) 87 } 88 } 89 return vips, nil 90 } 91 92 func hostedVIPs(hostPools map[string][]*dynamiclbmodel.VIP, m infra.Machine, current *Current) []string { 93 seen := make(map[string]bool) 94 var locations []string 95 for hostPool, vips := range hostPools { 96 if m.(*machine).server.Tags["pool"] != hostPool { 97 continue 98 } 99 for vipIdx := range vips { 100 vip := vips[vipIdx] 101 for transpIdx := range vip.Transport { 102 transp := vip.Transport[transpIdx] 103 addr, ok := current.Current.Ingresses[transp.Name] 104 if !ok || addr == nil { 105 continue 106 } 107 if _, ok := seen[addr.Location]; !ok { 108 seen[addr.Location] = true 109 locations = append(locations, addr.Location) 110 } 111 } 112 } 113 } 114 return locations 115 } 116 117 func ensureTokens(monitor mntr.Monitor, token []byte, authCheckResult []dynamiclbmodel.AuthCheckResult) []func() error { 118 var ensure []func() error 119 for idx := range authCheckResult { 120 ensure = append(ensure, func(result dynamiclbmodel.AuthCheckResult) func() error { 121 return func() error { return ensureToken(monitor, token, result) } 122 }(authCheckResult[idx])) 123 } 124 return ensure 125 } 126 127 func ensureToken(monitor mntr.Monitor, token []byte, authCheckResult dynamiclbmodel.AuthCheckResult) error { 128 if authCheckResult.ExitCode != 0 { 129 if err := authCheckResult.Machine.WriteFile("/var/orbiter/cstoken", bytes.NewReader(token), 600); err != nil { 130 return err 131 } 132 monitor.WithField("machine", authCheckResult.Machine.ID()).Info("API token written") 133 } 134 return nil 135 }