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 }