github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/provider/openstack/export_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package openstack 5 6 import ( 7 "bytes" 8 "fmt" 9 "strings" 10 "text/template" 11 12 "gopkg.in/goose.v1/errors" 13 "gopkg.in/goose.v1/identity" 14 "gopkg.in/goose.v1/nova" 15 "gopkg.in/goose.v1/swift" 16 17 "github.com/juju/juju/constraints" 18 "github.com/juju/juju/environs" 19 "github.com/juju/juju/environs/config" 20 "github.com/juju/juju/environs/instances" 21 "github.com/juju/juju/environs/jujutest" 22 "github.com/juju/juju/environs/simplestreams" 23 envstorage "github.com/juju/juju/environs/storage" 24 "github.com/juju/juju/instance" 25 "github.com/juju/juju/network" 26 "github.com/juju/juju/storage" 27 "github.com/juju/juju/testing" 28 ) 29 30 // This provides the content for code accessing test:///... URLs. This allows 31 // us to set the responses for things like the Metadata server, by pointing 32 // metadata requests at test:///... rather than http://169.254.169.254 33 var testRoundTripper = &jujutest.ProxyRoundTripper{} 34 35 func init() { 36 testRoundTripper.RegisterForScheme("test") 37 } 38 39 var ( 40 ShortAttempt = &shortAttempt 41 StorageAttempt = &storageAttempt 42 CinderAttempt = &cinderAttempt 43 ) 44 45 // MetadataStorage returns a Storage instance which is used to store simplestreams metadata for tests. 46 func MetadataStorage(e environs.Environ) envstorage.Storage { 47 ecfg := e.(*environ).ecfg() 48 container := "juju-dist-test" 49 metadataStorage := &openstackstorage{ 50 containerName: container, 51 swift: swift.New(authClient(ecfg)), 52 } 53 54 // Ensure the container exists. 55 err := metadataStorage.makeContainer(container, swift.PublicRead) 56 if err != nil { 57 panic(fmt.Errorf("cannot create %s container: %v", container, err)) 58 } 59 return metadataStorage 60 } 61 62 func InstanceAddress(publicIP string, addresses map[string][]nova.IPAddress) string { 63 return network.SelectPublicAddress(convertNovaAddresses(publicIP, addresses)) 64 } 65 66 func InstanceServerDetail(inst instance.Instance) *nova.ServerDetail { 67 return inst.(*openstackInstance).serverDetail 68 } 69 70 func InstanceFloatingIP(inst instance.Instance) *nova.FloatingIP { 71 return inst.(*openstackInstance).floatingIP 72 } 73 74 var ( 75 NovaListAvailabilityZones = &novaListAvailabilityZones 76 AvailabilityZoneAllocations = &availabilityZoneAllocations 77 ) 78 79 type OpenstackStorage openstackStorage 80 81 func NewCinderProvider(s OpenstackStorage) storage.Provider { 82 return &cinderProvider{ 83 func(*config.Config) (openstackStorage, error) { 84 return openstackStorage(s), nil 85 }, 86 } 87 } 88 89 func NewCinderVolumeSource(s OpenstackStorage) storage.VolumeSource { 90 const envName = "testenv" 91 envUUID := testing.EnvironmentTag.Id() 92 return &cinderVolumeSource{openstackStorage(s), envName, envUUID} 93 } 94 95 var indexData = ` 96 { 97 "index": { 98 "com.ubuntu.cloud:released:openstack": { 99 "updated": "Wed, 01 May 2013 13:31:26 +0000", 100 "clouds": [ 101 { 102 "region": "{{.Region}}", 103 "endpoint": "{{.URL}}" 104 } 105 ], 106 "cloudname": "test", 107 "datatype": "image-ids", 108 "format": "products:1.0", 109 "products": [ 110 "com.ubuntu.cloud:server:14.04:amd64", 111 "com.ubuntu.cloud:server:14.04:i386", 112 "com.ubuntu.cloud:server:14.04:ppc64el", 113 "com.ubuntu.cloud:server:12.10:amd64", 114 "com.ubuntu.cloud:server:13.04:amd64" 115 ], 116 "path": "image-metadata/products.json" 117 } 118 }, 119 "updated": "Wed, 01 May 2013 13:31:26 +0000", 120 "format": "index:1.0" 121 } 122 ` 123 124 var imagesData = ` 125 { 126 "content_id": "com.ubuntu.cloud:released:openstack", 127 "products": { 128 "com.ubuntu.cloud:server:14.04:amd64": { 129 "release": "trusty", 130 "version": "14.04", 131 "arch": "amd64", 132 "versions": { 133 "20121218": { 134 "items": { 135 "inst1": { 136 "root_store": "ebs", 137 "virt": "pv", 138 "region": "some-region", 139 "id": "1" 140 }, 141 "inst2": { 142 "root_store": "ebs", 143 "virt": "pv", 144 "region": "another-region", 145 "id": "2" 146 } 147 }, 148 "pubname": "ubuntu-trusty-14.04-amd64-server-20121218", 149 "label": "release" 150 }, 151 "20121111": { 152 "items": { 153 "inst3": { 154 "root_store": "ebs", 155 "virt": "pv", 156 "region": "some-region", 157 "id": "3" 158 } 159 }, 160 "pubname": "ubuntu-trusty-14.04-amd64-server-20121111", 161 "label": "release" 162 } 163 } 164 }, 165 "com.ubuntu.cloud:server:14.04:i386": { 166 "release": "trusty", 167 "version": "14.04", 168 "arch": "i386", 169 "versions": { 170 "20121111": { 171 "items": { 172 "inst33": { 173 "root_store": "ebs", 174 "virt": "pv", 175 "region": "some-region", 176 "id": "33" 177 } 178 }, 179 "pubname": "ubuntu-trusty-14.04-i386-server-20121111", 180 "label": "release" 181 } 182 } 183 }, 184 "com.ubuntu.cloud:server:14.04:ppc64el": { 185 "release": "trusty", 186 "version": "14.04", 187 "arch": "ppc64el", 188 "versions": { 189 "20121111": { 190 "items": { 191 "inst33": { 192 "root_store": "ebs", 193 "virt": "pv", 194 "region": "some-region", 195 "id": "33" 196 } 197 }, 198 "pubname": "ubuntu-trusty-14.04-ppc64el-server-20121111", 199 "label": "release" 200 } 201 } 202 }, 203 "com.ubuntu.cloud:server:12.10:amd64": { 204 "release": "quantal", 205 "version": "12.10", 206 "arch": "amd64", 207 "versions": { 208 "20121218": { 209 "items": { 210 "inst3": { 211 "root_store": "ebs", 212 "virt": "pv", 213 "region": "region-1", 214 "id": "id-1" 215 }, 216 "inst4": { 217 "root_store": "ebs", 218 "virt": "pv", 219 "region": "region-2", 220 "id": "id-2" 221 } 222 }, 223 "pubname": "ubuntu-quantal-12.14-amd64-server-20121218", 224 "label": "release" 225 } 226 } 227 }, 228 "com.ubuntu.cloud:server:13.04:amd64": { 229 "release": "raring", 230 "version": "13.04", 231 "arch": "amd64", 232 "versions": { 233 "20121218": { 234 "items": { 235 "inst5": { 236 "root_store": "ebs", 237 "virt": "pv", 238 "region": "some-region", 239 "id": "id-y" 240 }, 241 "inst6": { 242 "root_store": "ebs", 243 "virt": "pv", 244 "region": "another-region", 245 "id": "id-z" 246 } 247 }, 248 "pubname": "ubuntu-raring-13.04-amd64-server-20121218", 249 "label": "release" 250 } 251 } 252 } 253 }, 254 "format": "products:1.0" 255 } 256 ` 257 258 const productMetadatafile = "image-metadata/products.json" 259 260 func UseTestImageData(stor envstorage.Storage, cred *identity.Credentials) { 261 // Put some image metadata files into the public storage. 262 t := template.Must(template.New("").Parse(indexData)) 263 var metadata bytes.Buffer 264 if err := t.Execute(&metadata, cred); err != nil { 265 panic(fmt.Errorf("cannot generate index metdata: %v", err)) 266 } 267 data := metadata.Bytes() 268 stor.Put(simplestreams.UnsignedIndex("v1", 1), bytes.NewReader(data), int64(len(data))) 269 stor.Put( 270 productMetadatafile, strings.NewReader(imagesData), int64(len(imagesData))) 271 } 272 273 func RemoveTestImageData(stor envstorage.Storage) { 274 stor.Remove(simplestreams.UnsignedIndex("v1", 1)) 275 stor.Remove(productMetadatafile) 276 } 277 278 // DiscardSecurityGroup cleans up a security group, it is not an error to 279 // delete something that doesn't exist. 280 func DiscardSecurityGroup(e environs.Environ, name string) error { 281 env := e.(*environ) 282 novaClient := env.nova() 283 group, err := novaClient.SecurityGroupByName(name) 284 if err != nil { 285 if errors.IsNotFound(err) { 286 // Group already deleted, done 287 return nil 288 } 289 } 290 err = novaClient.DeleteSecurityGroup(group.Id) 291 if err != nil { 292 return err 293 } 294 return nil 295 } 296 297 func FindInstanceSpec(e environs.Environ, series, arch, cons string) (spec *instances.InstanceSpec, err error) { 298 env := e.(*environ) 299 spec, err = findInstanceSpec(env, &instances.InstanceConstraint{ 300 Series: series, 301 Arches: []string{arch}, 302 Region: env.ecfg().region(), 303 Constraints: constraints.MustParse(cons), 304 }) 305 return 306 } 307 308 func ControlBucketName(e environs.Environ) string { 309 env := e.(*environ) 310 return env.ecfg().controlBucket() 311 } 312 313 func GetSwiftURL(e environs.Environ) (string, error) { 314 return e.(*environ).client.MakeServiceURL("object-store", nil) 315 } 316 317 func SetUseFloatingIP(e environs.Environ, val bool) { 318 env := e.(*environ) 319 env.ecfg().attrs["use-floating-ip"] = val 320 } 321 322 func SetUpGlobalGroup(e environs.Environ, name string, apiPort int) (nova.SecurityGroup, error) { 323 return e.(*environ).setUpGlobalGroup(name, apiPort) 324 } 325 326 func EnsureGroup(e environs.Environ, name string, rules []nova.RuleInfo) (nova.SecurityGroup, error) { 327 return e.(*environ).ensureGroup(name, rules) 328 } 329 330 // ImageMetadataStorage returns a Storage object pointing where the goose 331 // infrastructure sets up its keystone entry for image metadata 332 func ImageMetadataStorage(e environs.Environ) envstorage.Storage { 333 env := e.(*environ) 334 return &openstackstorage{ 335 containerName: "imagemetadata", 336 swift: swift.New(env.client), 337 } 338 } 339 340 // CreateCustomStorage creates a swift container and returns the Storage object 341 // so you can put data into it. 342 func CreateCustomStorage(e environs.Environ, containerName string) envstorage.Storage { 343 env := e.(*environ) 344 swiftClient := swift.New(env.client) 345 if err := swiftClient.CreateContainer(containerName, swift.PublicRead); err != nil { 346 panic(err) 347 } 348 return &openstackstorage{ 349 containerName: containerName, 350 swift: swiftClient, 351 } 352 } 353 354 // BlankContainerStorage creates a Storage object with blank container name. 355 func BlankContainerStorage() envstorage.Storage { 356 return &openstackstorage{} 357 } 358 359 func GetNovaClient(e environs.Environ) *nova.Client { 360 return e.(*environ).nova() 361 } 362 363 // ResolveNetwork exposes environ helper function resolveNetwork for testing 364 func ResolveNetwork(e environs.Environ, networkName string) (string, error) { 365 return e.(*environ).resolveNetwork(networkName) 366 } 367 368 var PortsToRuleInfo = portsToRuleInfo 369 var RuleMatchesPortRange = ruleMatchesPortRange 370 371 var MakeServiceURL = &makeServiceURL 372 var ProviderInstance = providerInstance