github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/vsphere/environ_instance.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 "strings" 8 9 "github.com/juju/errors" 10 11 "github.com/juju/juju/core/instance" 12 "github.com/juju/juju/environs" 13 "github.com/juju/juju/environs/context" 14 "github.com/juju/juju/environs/instances" 15 "github.com/juju/juju/environs/tags" 16 ) 17 18 // Instances is part of the environs.Environ interface. 19 func (env *environ) Instances(ctx context.ProviderCallContext, ids []instance.Id) (instances []instances.Instance, err error) { 20 if len(ids) == 0 { 21 return nil, environs.ErrNoInstances 22 } 23 err = env.withSession(ctx, func(env *sessionEnviron) error { 24 instances, err = env.Instances(ctx, ids) 25 return err 26 }) 27 return instances, err 28 } 29 30 // Instances is part of the environs.Environ interface. 31 func (env *sessionEnviron) Instances(ctx context.ProviderCallContext, ids []instance.Id) ([]instances.Instance, error) { 32 if len(ids) == 0 { 33 return nil, environs.ErrNoInstances 34 } 35 36 allInstances, err := env.AllInstances(ctx) 37 if err != nil { 38 return nil, errors.Annotate(err, "failed to get instances") 39 } 40 findInst := func(id instance.Id) instances.Instance { 41 for _, inst := range allInstances { 42 if id == inst.Id() { 43 return inst 44 } 45 } 46 return nil 47 } 48 49 var numFound int 50 results := make([]instances.Instance, len(ids)) 51 for i, id := range ids { 52 if inst := findInst(id); inst != nil { 53 results[i] = inst 54 numFound++ 55 } 56 } 57 if numFound == 0 { 58 return nil, environs.ErrNoInstances 59 } else if numFound != len(ids) { 60 err = environs.ErrPartialInstances 61 } 62 return results, err 63 } 64 65 // ControllerInstances is part of the environs.Environ interface. 66 func (env *environ) ControllerInstances(ctx context.ProviderCallContext, controllerUUID string) (ids []instance.Id, err error) { 67 err = env.withSession(ctx, func(env *sessionEnviron) error { 68 ids, err = env.ControllerInstances(ctx, controllerUUID) 69 return err 70 }) 71 return ids, err 72 } 73 74 // ControllerInstances is part of the environs.Environ interface. 75 func (env *sessionEnviron) ControllerInstances(ctx context.ProviderCallContext, controllerUUID string) ([]instance.Id, error) { 76 instances, err := env.AllInstances(ctx) 77 if err != nil { 78 return nil, errors.Trace(err) 79 } 80 81 var results []instance.Id 82 for _, inst := range instances { 83 vm := inst.(*environInstance).base 84 metadata := vm.Config.ExtraConfig 85 var isController bool 86 for _, item := range metadata { 87 value := item.GetOptionValue() 88 if value.Key == tags.JujuIsController && value.Value == "true" { 89 isController = true 90 break 91 } 92 } 93 if isController { 94 results = append(results, inst.Id()) 95 } 96 } 97 if len(results) == 0 { 98 return nil, environs.ErrNotBootstrapped 99 } 100 return results, nil 101 } 102 103 // parsePlacement extracts the availability zone from the placement 104 // string and returns it. If no zone is found there then an error is 105 // returned. 106 func (env *sessionEnviron) parsePlacement(ctx context.ProviderCallContext, placement string) (*vmwareAvailZone, error) { 107 if placement == "" { 108 return nil, nil 109 } 110 111 pos := strings.IndexRune(placement, '=') 112 if pos == -1 { 113 return nil, errors.Errorf("unknown placement directive: %v", placement) 114 } 115 116 switch key, value := placement[:pos], placement[pos+1:]; key { 117 case "zone": 118 zone, err := env.availZone(ctx, value) 119 if err != nil { 120 return nil, errors.Trace(err) 121 } 122 return zone.(*vmwareAvailZone), nil 123 } 124 return nil, errors.Errorf("unknown placement directive: %v", placement) 125 } 126 127 func (env *sessionEnviron) modelFolderName() string { 128 cfg := env.Config() 129 return modelFolderName(cfg.UUID(), cfg.Name()) 130 }