github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/provider/vsphere/environ_policy.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package vsphere
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  
     9  	"github.com/juju/juju/core/arch"
    10  	"github.com/juju/juju/core/constraints"
    11  	"github.com/juju/juju/environs"
    12  	"github.com/juju/juju/environs/context"
    13  )
    14  
    15  // PrecheckInstance is part of the environs.Environ interface.
    16  func (env *environ) PrecheckInstance(ctx context.ProviderCallContext, args environs.PrecheckInstanceParams) error {
    17  	if args.Placement == "" && args.Constraints.String() == "" {
    18  		return nil
    19  	}
    20  	return env.withSession(ctx, func(env *sessionEnviron) error {
    21  		return env.PrecheckInstance(ctx, args)
    22  	})
    23  }
    24  
    25  // PrecheckInstance is part of the environs.Environ interface.
    26  func (env *sessionEnviron) PrecheckInstance(ctx context.ProviderCallContext, args environs.PrecheckInstanceParams) error {
    27  	if _, err := env.parsePlacement(ctx, args.Placement); err != nil {
    28  		return errors.Trace(err)
    29  	}
    30  	if err := env.checkZones(ctx, args.Constraints.Zones); err != nil {
    31  		return errors.Trace(err)
    32  	}
    33  	if err := env.checkDatastore(ctx, args.Constraints.RootDiskSource); err != nil {
    34  		return errors.Trace(err)
    35  	}
    36  	return nil
    37  }
    38  
    39  // checkZones ensures all the zones (in the constraints) are valid
    40  // availability zones.
    41  func (env *sessionEnviron) checkZones(ctx context.ProviderCallContext, zones *[]string) error {
    42  	if zones == nil || len(*zones) == 0 {
    43  		return nil
    44  	}
    45  	foundZones, err := env.AvailabilityZones(ctx)
    46  	if err != nil {
    47  		return errors.Trace(err)
    48  	}
    49  constraintZones:
    50  	for _, zone := range *zones {
    51  		for _, foundZone := range foundZones {
    52  			if zone == foundZone.Name() {
    53  				continue constraintZones
    54  			}
    55  		}
    56  		return errors.NotFoundf("availability zone %q", zone)
    57  	}
    58  	return nil
    59  }
    60  
    61  func (env *sessionEnviron) checkDatastore(ctx context.ProviderCallContext, datastore *string) error {
    62  	if datastore == nil || *datastore == "" {
    63  		return nil
    64  	}
    65  	name := *datastore
    66  	datastores, err := env.accessibleDatastores(ctx)
    67  	if err != nil {
    68  		return errors.Trace(err)
    69  	}
    70  	for _, ds := range datastores {
    71  		if name == ds.Name {
    72  			return nil
    73  		}
    74  	}
    75  	return errors.NotFoundf("datastore %q", name)
    76  }
    77  
    78  var unsupportedConstraints = []string{
    79  	constraints.Tags,
    80  	constraints.VirtType,
    81  	constraints.AllocatePublicIP,
    82  	constraints.ImageID,
    83  }
    84  
    85  // ConstraintsValidator returns a Validator value which is used to
    86  // validate and merge constraints.
    87  func (env *environ) ConstraintsValidator(ctx context.ProviderCallContext) (constraints.Validator, error) {
    88  	validator := constraints.NewValidator()
    89  	validator.RegisterUnsupported(unsupportedConstraints)
    90  	validator.RegisterVocabulary(constraints.Arch, []string{
    91  		arch.AMD64,
    92  	})
    93  	return validator, nil
    94  }