Skip to content

Commit

Permalink
fixup! api: linodemachine: add create validation
Browse files Browse the repository at this point in the history
  • Loading branch information
cbang-akamai committed May 8, 2024
1 parent 084aceb commit fcf9e51
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 34 deletions.
51 changes: 17 additions & 34 deletions api/v1alpha1/linodemachine_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ var _ webhook.Validator = &LinodeMachine{}
func (r *LinodeMachine) ValidateCreate() (admission.Warnings, error) {
linodemachinelog.Info("validate create", "name", r.Name)

return nil, r.validateLinodeMachine()
client := linodego.NewClient(http.DefaultClient)
return nil, r.validateLinodeMachine(context.TODO(), client)
}

// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
Expand All @@ -80,9 +81,9 @@ func (r *LinodeMachine) ValidateDelete() (admission.Warnings, error) {
return nil, nil
}

func (r *LinodeMachine) validateLinodeMachine() error {
func (r *LinodeMachine) validateLinodeMachine(ctx context.Context, client linodego.Client) error {
var errs field.ErrorList
if err := r.validateLinodeMachineSpec(); err != nil {
if err := r.validateLinodeMachineSpec(ctx, client); err != nil {
errs = slices.Concat(errs, err)
}

Expand All @@ -94,13 +95,12 @@ func (r *LinodeMachine) validateLinodeMachine() error {
r.Name, errs)
}

func (r *LinodeMachine) validateLinodeMachineSpec() field.ErrorList {
func (r *LinodeMachine) validateLinodeMachineSpec(ctx context.Context, client linodego.Client) field.ErrorList {
var (
errs field.ErrorList
client = linodego.NewClient(http.DefaultClient)
ctx = context.TODO()
errs field.ErrorList
)
if err := validateRegion(ctx, client, r.Spec.Region, field.NewPath("spec").Child("region")); err != nil {
_, err := validateRegion(ctx, client, r.Spec.Region, field.NewPath("spec").Child("region"))
if err != nil {
errs = append(errs, err)
}
plan, err := validateLinodeType(ctx, client, r.Spec.Type, field.NewPath("spec").Child("type"))
Expand All @@ -117,23 +117,6 @@ func (r *LinodeMachine) validateLinodeMachineSpec() field.ErrorList {
return errs
}

func validateRegion(ctx context.Context, client linodego.Client, region string, path *field.Path) *field.Error {
if _, err := client.GetRegion(ctx, region); err != nil {
return field.NotFound(path, region)
}

return nil
}

func validateLinodeType(ctx context.Context, client linodego.Client, plan string, path *field.Path) (*linodego.LinodeType, *field.Error) {
linodeType, err := client.GetType(ctx, plan)
if err != nil {
return nil, field.NotFound(path, plan)
}

return linodeType, nil
}

func (r *LinodeMachine) validateLinodeMachineDisks(plan *linodego.LinodeType) *field.Error {
// The Linode plan information is required to perform disk validation
if plan == nil {
Expand All @@ -148,19 +131,19 @@ func (r *LinodeMachine) validateLinodeMachineDisks(plan *linodego.LinodeType) *f
err *field.Error
)

if remainSize, err = validateDisk(r.Spec.OSDisk, field.NewPath("spec").Child("osDisk"), remainSize); err != nil {
if remainSize, err = validateDisk(r.Spec.OSDisk, field.NewPath("spec").Child("osDisk"), remainSize, &planSize); err != nil {
return err
}
if _, err := validateDataDisks(r.Spec.DataDisks, field.NewPath("spec").Child("dataDisks"), remainSize); err != nil {
if _, err := validateDataDisks(r.Spec.DataDisks, field.NewPath("spec").Child("dataDisks"), remainSize, &planSize); err != nil {
return err
}

return nil
}

func validateDataDisks(disks map[string]*InstanceDisk, path *field.Path, availSize *resource.Quantity) (*resource.Quantity, *field.Error) {
func validateDataDisks(disks map[string]*InstanceDisk, path *field.Path, availSize, planSize *resource.Quantity) (*resource.Quantity, *field.Error) {
var (
devs []string
devs = []string{}
remainSize = availSize
)

Expand All @@ -174,23 +157,23 @@ func validateDataDisks(disks map[string]*InstanceDisk, path *field.Path, availSi
devs = append(devs, dev)

var err *field.Error
if remainSize, err = validateDisk(disk, path.Child(dev), remainSize); err != nil {
if remainSize, err = validateDisk(disk, path.Child(dev), remainSize, planSize); err != nil {
return nil, err
}
}
return remainSize, nil
}

func validateDisk(disk *InstanceDisk, path *field.Path, availSize *resource.Quantity) (*resource.Quantity, *field.Error) {
func validateDisk(disk *InstanceDisk, path *field.Path, availSize, planSize *resource.Quantity) (*resource.Quantity, *field.Error) {
if disk == nil {
return availSize, nil
}

if disk.Size.Sign() == -1 {
return nil, field.Invalid(path, disk.Size.String(), "cannot be negative")
if disk.Size.Sign() < 1 {
return nil, field.Invalid(path, disk.Size.String(), "invalid size")
}
if availSize.Cmp(disk.Size) == -1 {
return nil, field.Invalid(path, disk.Size.String(), "sum of disk sizes cannot exceed plan storage")
return nil, field.Invalid(path, disk.Size.String(), fmt.Sprintf("sum disk sizes exceeds plan storage: %s", planSize.String()))
}

// Decrement the remaining amount of space available
Expand Down
26 changes: 26 additions & 0 deletions api/v1alpha1/webhook_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package v1alpha1

import (
"context"

"github.com/linode/linodego"
"k8s.io/apimachinery/pkg/util/validation/field"
)

func validateRegion(ctx context.Context, client linodego.Client, id string, path *field.Path) (*linodego.Region, *field.Error) {
region, err := client.GetRegion(ctx, id)
if err != nil {
return nil, field.NotFound(path, id)
}

return region, nil
}

func validateLinodeType(ctx context.Context, client linodego.Client, id string, path *field.Path) (*linodego.LinodeType, *field.Error) {
plan, err := client.GetType(ctx, id)
if err != nil {
return nil, field.NotFound(path, id)
}

return plan, nil
}

0 comments on commit fcf9e51

Please sign in to comment.