github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/internal/operator/orbiter/kinds/clusters/kubernetes/desired.go (about)

     1  package kubernetes
     2  
     3  import (
     4  	"fmt"
     5  
     6  	core "k8s.io/api/core/v1"
     7  
     8  	"github.com/caos/orbos/internal/operator/orbiter"
     9  	"github.com/caos/orbos/mntr"
    10  	"github.com/caos/orbos/pkg/secret"
    11  	"github.com/caos/orbos/pkg/tree"
    12  )
    13  
    14  type DesiredV0 struct {
    15  	Common tree.Common `yaml:",inline"`
    16  	Spec   Spec
    17  }
    18  
    19  type Spec struct {
    20  	ControlPlane Pool
    21  	Kubeconfig   *secret.Secret `yaml:",omitempty"`
    22  	Networking   struct {
    23  		DNSDomain   string
    24  		Network     string
    25  		ServiceCidr orbiter.CIDR
    26  		PodCidr     orbiter.CIDR
    27  	}
    28  	Verbose  bool
    29  	Versions struct {
    30  		Kubernetes string
    31  		Orbiter    string
    32  	}
    33  	// Use this registry to pull all kubernetes and ORBITER container images from
    34  	//@default: ghcr.io
    35  	CustomImageRegistry string
    36  	Workers             []*Pool
    37  }
    38  
    39  func parseDesiredV0(desiredTree *tree.Tree) (*DesiredV0, error) {
    40  	desiredKind := &DesiredV0{
    41  		Common: *desiredTree.Common,
    42  		Spec:   Spec{},
    43  	}
    44  	if err := desiredTree.Original.Decode(desiredKind); err != nil {
    45  		return nil, mntr.ToUserError(fmt.Errorf("parsing desired state failed: %w", err))
    46  	}
    47  
    48  	return desiredKind, nil
    49  }
    50  
    51  func (d *DesiredV0) validate() (err error) {
    52  
    53  	defer func() {
    54  		err = mntr.ToUserError(err)
    55  	}()
    56  
    57  	if d.Spec.ControlPlane.Nodes != 1 && d.Spec.ControlPlane.Nodes != 3 && d.Spec.ControlPlane.Nodes != 5 {
    58  		return fmt.Errorf("controlplane nodes can only be scaled to 1, 3 or 5 but desired are %d", d.Spec.ControlPlane.Nodes)
    59  	}
    60  
    61  	if ParseString(d.Spec.Versions.Kubernetes) == Unknown {
    62  		return fmt.Errorf("unknown kubernetes version %s", d.Spec.Versions.Kubernetes)
    63  	}
    64  
    65  	if err := d.Spec.Networking.ServiceCidr.Validate(); err != nil {
    66  		return err
    67  	}
    68  
    69  	if err := d.Spec.Networking.PodCidr.Validate(); err != nil {
    70  		return err
    71  	}
    72  
    73  	seenPools := map[string][]string{
    74  		d.Spec.ControlPlane.Provider: {d.Spec.ControlPlane.Pool},
    75  	}
    76  
    77  	for _, worker := range d.Spec.Workers {
    78  		pools, ok := seenPools[worker.Provider]
    79  		if !ok {
    80  			seenPools[worker.Provider] = []string{worker.Pool}
    81  			continue
    82  		}
    83  		for _, seenPool := range pools {
    84  			if seenPool == worker.Pool {
    85  				return fmt.Errorf("pool %s from provider %s is used multiple times", worker.Pool, worker.Provider)
    86  			}
    87  		}
    88  		seenPools[worker.Provider] = append(pools, worker.Pool)
    89  	}
    90  
    91  	return nil
    92  }
    93  
    94  type Pool struct {
    95  	UpdatesDisabled bool
    96  	Provider        string
    97  	Nodes           int
    98  	Pool            string
    99  	Taints          *Taints `yaml:"taints,omitempty"`
   100  }
   101  
   102  type Taint struct {
   103  	Key    string           `yaml:"key"`
   104  	Value  string           `yaml:"value,omitempty"`
   105  	Effect core.TaintEffect `yaml:"effect"`
   106  }
   107  
   108  type Taints []Taint
   109  
   110  func (t *Taints) ToK8sTaints() []core.Taint {
   111  	if t == nil {
   112  		return nil
   113  	}
   114  	taints := make([]core.Taint, len(*t))
   115  	for idx, taint := range *t {
   116  		taints[idx] = core.Taint{
   117  			Key:    taint.Key,
   118  			Value:  taint.Value,
   119  			Effect: taint.Effect,
   120  		}
   121  	}
   122  	return taints
   123  }