github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/provider/gce/environ.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package gce 5 6 import ( 7 "sync" 8 9 "github.com/juju/errors" 10 11 "github.com/juju/juju/environs" 12 "github.com/juju/juju/environs/config" 13 "github.com/juju/juju/environs/simplestreams" 14 "github.com/juju/juju/network" 15 "github.com/juju/juju/provider/common" 16 "github.com/juju/juju/provider/gce/google" 17 ) 18 19 // Note: This provider/environment does *not* implement storage. 20 21 type gceConnection interface { 22 VerifyCredentials() error 23 24 // Instance gets the up-to-date info about the given instance 25 // and returns it. 26 Instance(id, zone string) (google.Instance, error) 27 Instances(prefix string, statuses ...string) ([]google.Instance, error) 28 AddInstance(spec google.InstanceSpec, zones ...string) (*google.Instance, error) 29 RemoveInstances(prefix string, ids ...string) error 30 31 Ports(fwname string) ([]network.PortRange, error) 32 OpenPorts(fwname string, ports ...network.PortRange) error 33 ClosePorts(fwname string, ports ...network.PortRange) error 34 35 AvailabilityZones(region string) ([]google.AvailabilityZone, error) 36 } 37 38 type environ struct { 39 common.SupportsUnitPlacementPolicy 40 41 name string 42 uuid string 43 gce gceConnection 44 45 lock sync.Mutex 46 ecfg *environConfig 47 48 archLock sync.Mutex 49 supportedArchitectures []string 50 } 51 52 func newEnviron(cfg *config.Config) (*environ, error) { 53 ecfg, err := newValidConfig(cfg, configDefaults) 54 if err != nil { 55 return nil, errors.Annotate(err, "invalid config") 56 } 57 58 uuid, ok := ecfg.UUID() 59 if !ok { 60 return nil, errors.New("UUID not set") 61 } 62 63 // Connect and authenticate. 64 conn, err := newConnection(ecfg) 65 if err != nil { 66 return nil, errors.Trace(err) 67 } 68 69 env := &environ{ 70 name: ecfg.Name(), 71 uuid: uuid, 72 ecfg: ecfg, 73 gce: conn, 74 } 75 return env, nil 76 } 77 78 // Name returns the name of the environment. 79 func (env *environ) Name() string { 80 return env.name 81 } 82 83 // Provider returns the environment provider that created this env. 84 func (*environ) Provider() environs.EnvironProvider { 85 return providerInstance 86 } 87 88 // Region returns the CloudSpec to use for the provider, as configured. 89 func (env *environ) Region() (simplestreams.CloudSpec, error) { 90 return env.cloudSpec(env.ecfg.region()), nil 91 } 92 93 func (env *environ) cloudSpec(region string) simplestreams.CloudSpec { 94 return simplestreams.CloudSpec{ 95 Region: region, 96 Endpoint: env.ecfg.imageEndpoint(), 97 } 98 } 99 100 // SetConfig updates the env's configuration. 101 func (env *environ) SetConfig(cfg *config.Config) error { 102 env.lock.Lock() 103 defer env.lock.Unlock() 104 105 if env.ecfg == nil { 106 return errors.New("cannot set config on uninitialized env") 107 } 108 109 if err := env.ecfg.update(cfg); err != nil { 110 return errors.Annotate(err, "invalid config change") 111 } 112 return nil 113 } 114 115 var newConnection = func(ecfg *environConfig) (gceConnection, error) { 116 connCfg := ecfg.newConnection() 117 auth := ecfg.auth() 118 return google.Connect(connCfg, auth) 119 } 120 121 // getSnapshot returns a copy of the environment. This is useful for 122 // ensuring the env you are using does not get changed by other code 123 // while you are using it. 124 func (env environ) getSnapshot() *environ { 125 return &env 126 } 127 128 // Config returns the configuration data with which the env was created. 129 func (env *environ) Config() *config.Config { 130 return env.getSnapshot().ecfg.Config 131 } 132 133 var bootstrap = common.Bootstrap 134 135 // Bootstrap creates a new instance, chosing the series and arch out of 136 // available tools. The series and arch are returned along with a func 137 // that must be called to finalize the bootstrap process by transferring 138 // the tools and installing the initial juju state server. 139 func (env *environ) Bootstrap(ctx environs.BootstrapContext, params environs.BootstrapParams) (arch, series string, _ environs.BootstrapFinalizer, _ error) { 140 return bootstrap(ctx, env, params) 141 } 142 143 var destroyEnv = common.Destroy 144 145 // Destroy shuts down all known machines and destroys the rest of the 146 // known environment. 147 func (env *environ) Destroy() error { 148 ports, err := env.Ports() 149 if err != nil { 150 return errors.Trace(err) 151 } 152 153 if len(ports) > 0 { 154 if err := env.ClosePorts(ports); err != nil { 155 return errors.Trace(err) 156 } 157 } 158 159 return destroyEnv(env) 160 }