github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/vsphere/environ_availzones.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  	"github.com/vmware/govmomi/vim25/mo"
     9  
    10  	"github.com/juju/juju/core/instance"
    11  	"github.com/juju/juju/environs"
    12  	"github.com/juju/juju/environs/context"
    13  	"github.com/juju/juju/provider/common"
    14  )
    15  
    16  type vmwareAvailZone struct {
    17  	r mo.ComputeResource
    18  }
    19  
    20  // Name implements common.AvailabilityZone
    21  func (z *vmwareAvailZone) Name() string {
    22  	return z.r.Name
    23  }
    24  
    25  // Available implements common.AvailabilityZone
    26  func (z *vmwareAvailZone) Available() bool {
    27  	return true
    28  }
    29  
    30  // AvailabilityZones is part of the common.ZonedEnviron interface.
    31  func (env *environ) AvailabilityZones(ctx context.ProviderCallContext) (zones []common.AvailabilityZone, err error) {
    32  	err = env.withSession(ctx, func(env *sessionEnviron) error {
    33  		zones, err = env.AvailabilityZones(ctx)
    34  		return err
    35  	})
    36  	return zones, err
    37  }
    38  
    39  // AvailabilityZones is part of the common.ZonedEnviron interface.
    40  func (env *sessionEnviron) AvailabilityZones(ctx context.ProviderCallContext) ([]common.AvailabilityZone, error) {
    41  	if env.zones == nil {
    42  		computeResources, err := env.client.ComputeResources(env.ctx)
    43  		if err != nil {
    44  			HandleCredentialError(err, ctx)
    45  			return nil, errors.Trace(err)
    46  		}
    47  		zones := make([]common.AvailabilityZone, len(computeResources))
    48  		for i, cr := range computeResources {
    49  			zones[i] = &vmwareAvailZone{*cr}
    50  		}
    51  		env.zones = zones
    52  	}
    53  	return env.zones, nil
    54  }
    55  
    56  // InstanceAvailabilityZoneNames is part of the common.ZonedEnviron interface.
    57  func (env *environ) InstanceAvailabilityZoneNames(ctx context.ProviderCallContext, ids []instance.Id) (names []string, err error) {
    58  	err = env.withSession(ctx, func(env *sessionEnviron) error {
    59  		names, err = env.InstanceAvailabilityZoneNames(ctx, ids)
    60  		return err
    61  	})
    62  	return names, err
    63  }
    64  
    65  // InstanceAvailabilityZoneNames is part of the common.ZonedEnviron interface.
    66  func (env *sessionEnviron) InstanceAvailabilityZoneNames(ctx context.ProviderCallContext, ids []instance.Id) ([]string, error) {
    67  	zones, err := env.AvailabilityZones(ctx)
    68  	if err != nil {
    69  		return nil, errors.Trace(err)
    70  	}
    71  	instances, err := env.Instances(ctx, ids)
    72  	switch err {
    73  	case nil, environs.ErrPartialInstances:
    74  		break
    75  	case environs.ErrNoInstances:
    76  		return nil, err
    77  	default:
    78  		return nil, errors.Trace(err)
    79  	}
    80  
    81  	results := make([]string, len(ids))
    82  	for i, inst := range instances {
    83  		if inst == nil {
    84  			continue
    85  		}
    86  		vm := inst.(*environInstance).base
    87  		for _, zone := range zones {
    88  			cr := &zone.(*vmwareAvailZone).r
    89  			if cr.ResourcePool.Value == vm.ResourcePool.Value {
    90  				results[i] = cr.Name
    91  				break
    92  			}
    93  		}
    94  	}
    95  	return results, err
    96  }
    97  
    98  // DeriveAvailabilityZones is part of the common.ZonedEnviron interface.
    99  func (env *environ) DeriveAvailabilityZones(ctx context.ProviderCallContext, args environs.StartInstanceParams) (names []string, err error) {
   100  	err = env.withSession(ctx, func(env *sessionEnviron) error {
   101  		names, err = env.DeriveAvailabilityZones(ctx, args)
   102  		return err
   103  	})
   104  	return names, err
   105  }
   106  
   107  // DeriveAvailabilityZones is part of the common.ZonedEnviron interface.
   108  func (env *sessionEnviron) DeriveAvailabilityZones(ctx context.ProviderCallContext, args environs.StartInstanceParams) ([]string, error) {
   109  	if args.Placement != "" {
   110  		// args.Placement will always be a zone name or empty.
   111  		placement, err := env.parsePlacement(ctx, args.Placement)
   112  		if err != nil {
   113  			return nil, errors.Trace(err)
   114  		}
   115  		if placement.Name() != "" {
   116  			return []string{placement.Name()}, nil
   117  		}
   118  	}
   119  	return nil, nil
   120  }
   121  
   122  func (env *sessionEnviron) availZone(ctx context.ProviderCallContext, name string) (common.AvailabilityZone, error) {
   123  	zones, err := env.AvailabilityZones(ctx)
   124  	if err != nil {
   125  		return nil, errors.Trace(err)
   126  	}
   127  	for _, z := range zones {
   128  		if z.Name() == name {
   129  			return z, nil
   130  		}
   131  	}
   132  	return nil, errors.NotFoundf("availability zone %q", name)
   133  }