github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/internal/operator/orbiter/kinds/providers/cs/servers.go (about)

     1  package cs
     2  
     3  import (
     4  	"github.com/caos/orbos/internal/operator/orbiter/kinds/clusters/core/infra"
     5  	"github.com/caos/orbos/internal/operator/orbiter/kinds/loadbalancers/dynamic"
     6  	"github.com/cloudscale-ch/cloudscale-go-sdk"
     7  )
     8  
     9  func queryServers(context *context, current *Current, loadbalancing map[string][]*dynamic.VIP, ensureNodeAgent func(m infra.Machine) error) ([]func() error, error) {
    10  
    11  	pools, err := context.machinesService.machines()
    12  	if err != nil {
    13  		return nil, err
    14  	}
    15  
    16  	var ensureServers []func() error
    17  	for poolName, machines := range pools {
    18  		for idx := range machines {
    19  			mach := machines[idx]
    20  			ensureServers = append(ensureServers, func(poolName string, m *machine) func() error {
    21  				return func() error {
    22  					return ensureServer(context, current, loadbalancing, poolName, m, ensureNodeAgent)
    23  				}
    24  			}(poolName, mach))
    25  		}
    26  	}
    27  	return ensureServers, nil
    28  }
    29  
    30  func ensureServer(context *context, current *Current, loadbalancing map[string][]*dynamic.VIP, poolName string, machine *machine, ensureNodeAgent func(m infra.Machine) error) (err error) {
    31  	defer func() {
    32  		if err == nil {
    33  			err = ensureOS(ensureNodeAgent, machine, loadbalancing, current, context)
    34  		}
    35  	}()
    36  
    37  	_, isExternal := loadbalancing[poolName]
    38  	if context.machinesService.oneoff {
    39  		isExternal = true
    40  	}
    41  	// Always use external ips
    42  	isExternal = true
    43  	hasPublicInterface := false
    44  	var privateInterfaces []cloudscale.Interface
    45  	for idx := range machine.server.Interfaces {
    46  		interf := machine.server.Interfaces[idx]
    47  		if interf.Type == "public" {
    48  			hasPublicInterface = true
    49  		} else {
    50  			privateInterfaces = append(privateInterfaces, interf)
    51  		}
    52  	}
    53  
    54  	var updateInterfaces []cloudscale.InterfaceRequest
    55  	if isExternal && !hasPublicInterface {
    56  		updateInterfaces = append(interfaces(machine.server.Interfaces).toRequests(), cloudscale.InterfaceRequest{Network: "public"})
    57  	}
    58  
    59  	if !isExternal && hasPublicInterface {
    60  		updateInterfaces = interfaces(privateInterfaces).toRequests()
    61  	}
    62  
    63  	if updateInterfaces == nil {
    64  		return nil
    65  	}
    66  	return updateServer(context, machine.server, &updateInterfaces)
    67  
    68  }
    69  
    70  func ensureOS(ensureNodeAgent func(m infra.Machine) error, machine *machine, loadbalancing map[string][]*dynamic.VIP, current *Current, context *context) error {
    71  	if err := ensureNodeAgent(machine); err != nil {
    72  		return err
    73  	}
    74  
    75  	return nil
    76  }
    77  
    78  func updateServer(context *context, server *cloudscale.Server, interfaces *[]cloudscale.InterfaceRequest) error {
    79  	return context.client.Servers.Update(context.ctx, server.UUID, &cloudscale.ServerUpdateRequest{
    80  		TaggedResourceRequest: cloudscale.TaggedResourceRequest{Tags: server.Tags},
    81  		Name:                  server.Name,
    82  		Status:                server.Status,
    83  		Flavor:                server.Flavor.Name,
    84  		Interfaces:            interfaces,
    85  	})
    86  }
    87  
    88  type interfaces []cloudscale.Interface
    89  
    90  func (i interfaces) toRequests() []cloudscale.InterfaceRequest {
    91  	var requests []cloudscale.InterfaceRequest
    92  	for idx := range i {
    93  		interf := i[idx]
    94  		addr := addresses(interf.Addresses).toRequest()
    95  		requests = append(requests, cloudscale.InterfaceRequest{
    96  			Network:   interf.Network.UUID,
    97  			Addresses: &addr,
    98  		})
    99  	}
   100  	return requests
   101  }
   102  
   103  type addresses []cloudscale.Address
   104  
   105  func (a addresses) toRequest() []cloudscale.AddressRequest {
   106  	var requests []cloudscale.AddressRequest
   107  	for idx := range a {
   108  		addr := a[idx]
   109  		requests = append(requests, cloudscale.AddressRequest{
   110  			Subnet:  addr.Subnet.UUID,
   111  			Address: addr.Address,
   112  		})
   113  	}
   114  	return requests
   115  }