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 }