github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/caas/kubernetes/provider/precheck.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package provider
     5  
     6  import (
     7  	"strings"
     8  
     9  	"github.com/juju/errors"
    10  
    11  	"github.com/juju/juju/environs"
    12  	"github.com/juju/juju/environs/context"
    13  )
    14  
    15  // PrecheckInstance performs a preflight check on the specified
    16  // series and constraints, ensuring that they are possibly valid for
    17  // creating an instance in this model.
    18  //
    19  // PrecheckInstance is best effort, and not guaranteed to eliminate
    20  // all invalid parameters. If PrecheckInstance returns nil, it is not
    21  // guaranteed that the constraints are valid; if a non-nil error is
    22  // returned, then the constraints are definitely invalid.
    23  func (k *kubernetesClient) PrecheckInstance(ctx context.ProviderCallContext, params environs.PrecheckInstanceParams) error {
    24  	// Ensure there are no unsupported constraints.
    25  	// Clouds generally don't enforce this but we will
    26  	// for Kubernetes deployments.
    27  	validator, err := k.ConstraintsValidator(ctx)
    28  	if err != nil {
    29  		return errors.Trace(err)
    30  	}
    31  	unsupported, err := validator.Validate(params.Constraints)
    32  	if err != nil {
    33  		return errors.NotValidf("constraints %q", params.Constraints.String())
    34  	}
    35  	if len(unsupported) > 0 {
    36  		return errors.NotSupportedf("constraints %v", strings.Join(unsupported, ","))
    37  	}
    38  
    39  	if params.Placement != "" {
    40  		return errors.NotValidf("placement directive %q", params.Placement)
    41  	}
    42  	if params.Constraints.Tags == nil {
    43  		return nil
    44  	}
    45  	affinityLabels := *params.Constraints.Tags
    46  	labelsString := strings.Join(affinityLabels, ",")
    47  	for _, labelPair := range affinityLabels {
    48  		parts := strings.Split(labelPair, "=")
    49  		if len(parts) != 2 {
    50  			return errors.Errorf("invalid node affinity constraints: %v", labelsString)
    51  		}
    52  		key := strings.Trim(parts[0], " ")
    53  		if strings.HasPrefix(key, "^") {
    54  			if len(key) == 1 {
    55  				return errors.Errorf("invalid node affinity constraints: %v", labelsString)
    56  			}
    57  		}
    58  	}
    59  	return nil
    60  }