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

     1  package gce
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/caos/orbos/mntr"
     8  	secret2 "github.com/caos/orbos/pkg/secret"
     9  	"github.com/caos/orbos/pkg/tree"
    10  )
    11  
    12  type Desired struct {
    13  	Common        *tree.Common `yaml:",inline"`
    14  	Spec          Spec
    15  	Loadbalancing *tree.Tree
    16  }
    17  
    18  type Pool struct {
    19  	Multizonal      []string
    20  	OSImage         string
    21  	MinCPUCores     int
    22  	MinMemoryGB     int
    23  	StorageGB       int
    24  	StorageDiskType string
    25  	Preemptible     bool
    26  	LocalSSDs       uint8
    27  }
    28  
    29  func (p Pool) validate() error {
    30  
    31  	if p.MinCPUCores == 0 {
    32  		return errors.New("no cpu cores configured")
    33  	}
    34  	if p.MinMemoryGB == 0 {
    35  		return errors.New("no memory configured")
    36  	}
    37  	if p.StorageGB < 20 {
    38  		return fmt.Errorf("at least 20GB of storage is needed for the boot disk")
    39  	}
    40  
    41  	switch p.StorageDiskType {
    42  	case "pd-standard",
    43  		"pd-balanced",
    44  		"pd-ssd":
    45  		break
    46  	default:
    47  		return fmt.Errorf("DiskType \"%s\" is not supported", p.StorageDiskType)
    48  	}
    49  
    50  	return nil
    51  }
    52  
    53  type SSHKey struct {
    54  	Private *secret2.Secret `yaml:",omitempty"`
    55  	Public  *secret2.Secret `yaml:",omitempty"`
    56  }
    57  
    58  type Spec struct {
    59  	Verbose             bool
    60  	JSONKey             *secret2.Secret `yaml:",omitempty"`
    61  	Region              string
    62  	Zone                string
    63  	Pools               map[string]*Pool
    64  	SSHKey              *SSHKey
    65  	RebootRequired      []string
    66  	ReplacementRequired []string
    67  }
    68  
    69  func (d Desired) validateAdapt() (err error) {
    70  	defer func() {
    71  		err = mntr.ToUserError(err)
    72  	}()
    73  
    74  	if d.Loadbalancing == nil {
    75  		return errors.New("no loadbalancing configured")
    76  	}
    77  	if d.Spec.Region == "" {
    78  		return errors.New("no region configured")
    79  	}
    80  	if d.Spec.Zone == "" {
    81  		return errors.New("no zone configured")
    82  	}
    83  	if len(d.Spec.Pools) == 0 {
    84  		return errors.New("no pools configured")
    85  	}
    86  	for poolName, pool := range d.Spec.Pools {
    87  		if err := pool.validate(); err != nil {
    88  			return fmt.Errorf("configuring pool %s failed: %w", poolName, err)
    89  		}
    90  	}
    91  	return nil
    92  }
    93  
    94  func (d Desired) validateJSONKey() error {
    95  	if d.Spec.JSONKey == nil || d.Spec.JSONKey.Value == "" {
    96  		return mntr.ToUserError(errors.New("jsonkey missing... please provide a google service accounts jsonkey using orbctl writesecret command"))
    97  	}
    98  	return nil
    99  }
   100  
   101  func (d Desired) validateQuery() (err error) {
   102  
   103  	defer func() {
   104  		err = mntr.ToUserError(err)
   105  	}()
   106  
   107  	if err := d.validateJSONKey(); err != nil {
   108  		return err
   109  	}
   110  	if d.Spec.SSHKey == nil ||
   111  		d.Spec.SSHKey.Private == nil ||
   112  		d.Spec.SSHKey.Private.Value == "" ||
   113  		d.Spec.SSHKey.Public == nil ||
   114  		d.Spec.SSHKey.Public.Value == "" {
   115  		return errors.New("ssh key missing... please initialize your orb using orbctl configure command")
   116  	}
   117  	return nil
   118  }
   119  
   120  func parseDesiredV0(desiredTree *tree.Tree) (*Desired, error) {
   121  	desiredKind := &Desired{
   122  		Common: desiredTree.Common,
   123  		Spec:   Spec{},
   124  	}
   125  
   126  	if err := desiredTree.Original.Decode(desiredKind); err != nil {
   127  		return nil, mntr.ToUserError(fmt.Errorf("parsing desired state failed: %w", err))
   128  	}
   129  
   130  	return desiredKind, nil
   131  }