github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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/imagemetadata" 20 "github.com/juju/juju/environs/instances" 21 "github.com/juju/juju/environs/simplestreams" 22 envstorage "github.com/juju/juju/environs/storage" 23 envtesting "github.com/juju/juju/environs/testing" 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 var ( 31 ShortAttempt = &shortAttempt 32 StorageAttempt = &storageAttempt 33 CinderAttempt = &cinderAttempt 34 ) 35 36 // MetadataStorage returns a Storage instance which is used to store simplestreams metadata for tests. 37 func MetadataStorage(e environs.Environ) envstorage.Storage { 38 env := e.(*Environ) 39 ecfg := env.ecfg() 40 container := "juju-dist-test" 41 client, err := authClient(env.cloud, ecfg) 42 if err != nil { 43 panic(fmt.Errorf("cannot create %s container: %v", container, err)) 44 } 45 metadataStorage := &openstackstorage{ 46 containerName: container, 47 swift: swift.New(client), 48 } 49 50 // Ensure the container exists. 51 err = metadataStorage.makeContainer(container, swift.PublicRead) 52 if err != nil { 53 panic(fmt.Errorf("cannot create %s container: %v", container, err)) 54 } 55 return metadataStorage 56 } 57 58 func InstanceAddress(publicIP string, addresses map[string][]nova.IPAddress) string { 59 addr, _ := network.SelectPublicAddress(convertNovaAddresses(publicIP, addresses)) 60 return addr.Value 61 } 62 63 func InstanceServerDetail(inst instance.Instance) *nova.ServerDetail { 64 return inst.(*openstackInstance).serverDetail 65 } 66 67 func InstanceFloatingIP(inst instance.Instance) *nova.FloatingIP { 68 return inst.(*openstackInstance).floatingIP 69 } 70 71 var ( 72 NovaListAvailabilityZones = &novaListAvailabilityZones 73 AvailabilityZoneAllocations = &availabilityZoneAllocations 74 NewOpenstackStorage = &newOpenstackStorage 75 ) 76 77 func NewCinderVolumeSource(s OpenstackStorage) storage.VolumeSource { 78 const envName = "testenv" 79 modelUUID := testing.ModelTag.Id() 80 return &cinderVolumeSource{ 81 storageAdapter: s, 82 envName: envName, 83 modelUUID: modelUUID, 84 namespace: fakeNamespace{}, 85 } 86 } 87 88 type fakeNamespace struct { 89 instance.Namespace 90 } 91 92 func (fakeNamespace) Value(s string) string { 93 return "juju-" + s 94 } 95 96 // Include images for arches currently supported. i386 is no longer 97 // supported, so it can be excluded. 98 var indexData = ` 99 { 100 "index": { 101 "com.ubuntu.cloud:released:openstack": { 102 "updated": "Wed, 01 May 2013 13:31:26 +0000", 103 "clouds": [ 104 { 105 "region": "{{.Region}}", 106 "endpoint": "{{.URL}}" 107 } 108 ], 109 "cloudname": "test", 110 "datatype": "image-ids", 111 "format": "products:1.0", 112 "products": [ 113 "com.ubuntu.cloud:server:16.04:s390x", 114 "com.ubuntu.cloud:server:16.04:amd64", 115 "com.ubuntu.cloud:server:16.04:arm64", 116 "com.ubuntu.cloud:server:16.04:ppc64el", 117 "com.ubuntu.cloud:server:14.04:s390x", 118 "com.ubuntu.cloud:server:14.04:amd64", 119 "com.ubuntu.cloud:server:14.04:arm64", 120 "com.ubuntu.cloud:server:14.04:ppc64el", 121 "com.ubuntu.cloud:server:12.10:amd64", 122 "com.ubuntu.cloud:server:13.04:amd64" 123 ], 124 "path": "image-metadata/products.json" 125 } 126 }, 127 "updated": "Wed, 01 May 2013 13:31:26 +0000", 128 "format": "index:1.0" 129 } 130 ` 131 132 var imagesData = ` 133 { 134 "content_id": "com.ubuntu.cloud:released:openstack", 135 "products": { 136 "com.ubuntu.cloud:server:16.04:amd64": { 137 "release": "trusty", 138 "version": "16.04", 139 "arch": "amd64", 140 "versions": { 141 "20121218": { 142 "items": { 143 "inst1": { 144 "root_store": "ebs", 145 "virt": "pv", 146 "region": "some-region", 147 "id": "1" 148 }, 149 "inst2": { 150 "root_store": "ebs", 151 "virt": "pv", 152 "region": "another-region", 153 "id": "2" 154 } 155 }, 156 "pubname": "ubuntu-trusty-16.04-amd64-server-20121218", 157 "label": "release" 158 }, 159 "20121111": { 160 "items": { 161 "inst3": { 162 "root_store": "ebs", 163 "virt": "pv", 164 "region": "some-region", 165 "id": "3" 166 } 167 }, 168 "pubname": "ubuntu-trusty-16.04-amd64-server-20121111", 169 "label": "release" 170 } 171 } 172 }, 173 "com.ubuntu.cloud:server:16.04:arm64": { 174 "release": "xenial", 175 "version": "16.04", 176 "arch": "arm64", 177 "versions": { 178 "20121111": { 179 "items": { 180 "inst1604arm64": { 181 "root_store": "ebs", 182 "virt": "pv", 183 "region": "some-region", 184 "id": "id-1604arm64" 185 } 186 }, 187 "pubname": "ubuntu-xenial-16.04-arm64-server-20121111", 188 "label": "release" 189 } 190 } 191 }, 192 "com.ubuntu.cloud:server:16.04:ppc64el": { 193 "release": "xenial", 194 "version": "16.04", 195 "arch": "ppc64el", 196 "versions": { 197 "20121111": { 198 "items": { 199 "inst1604ppc64el": { 200 "root_store": "ebs", 201 "virt": "pv", 202 "region": "some-region", 203 "id": "id-1604ppc64el" 204 } 205 }, 206 "pubname": "ubuntu-xenial-16.04-ppc64el-server-20121111", 207 "label": "release" 208 } 209 } 210 }, 211 "com.ubuntu.cloud:server:14.04:amd64": { 212 "release": "trusty", 213 "version": "14.04", 214 "arch": "amd64", 215 "versions": { 216 "20121218": { 217 "items": { 218 "inst1": { 219 "root_store": "ebs", 220 "virt": "pv", 221 "region": "some-region", 222 "id": "1" 223 }, 224 "inst2": { 225 "root_store": "ebs", 226 "virt": "pv", 227 "region": "another-region", 228 "id": "2" 229 } 230 }, 231 "pubname": "ubuntu-trusty-14.04-amd64-server-20121218", 232 "label": "release" 233 }, 234 "20121111": { 235 "items": { 236 "inst3": { 237 "root_store": "ebs", 238 "virt": "pv", 239 "region": "some-region", 240 "id": "3" 241 } 242 }, 243 "pubname": "ubuntu-trusty-14.04-amd64-server-20121111", 244 "label": "release" 245 } 246 } 247 }, 248 "com.ubuntu.cloud:server:14.04:arm64": { 249 "release": "trusty", 250 "version": "14.04", 251 "arch": "arm64", 252 "versions": { 253 "20121111": { 254 "items": { 255 "inst33": { 256 "root_store": "ebs", 257 "virt": "pv", 258 "region": "some-region", 259 "id": "33" 260 } 261 }, 262 "pubname": "ubuntu-trusty-14.04-arm64-server-20121111", 263 "label": "release" 264 } 265 } 266 }, 267 "com.ubuntu.cloud:server:14.04:ppc64el": { 268 "release": "trusty", 269 "version": "14.04", 270 "arch": "ppc64el", 271 "versions": { 272 "20121111": { 273 "items": { 274 "inst33": { 275 "root_store": "ebs", 276 "virt": "pv", 277 "region": "some-region", 278 "id": "33" 279 } 280 }, 281 "pubname": "ubuntu-trusty-14.04-ppc64el-server-20121111", 282 "label": "release" 283 } 284 } 285 }, 286 "com.ubuntu.cloud:server:12.10:amd64": { 287 "release": "quantal", 288 "version": "12.10", 289 "arch": "amd64", 290 "versions": { 291 "20121218": { 292 "items": { 293 "inst3": { 294 "root_store": "ebs", 295 "virt": "pv", 296 "region": "region-1", 297 "id": "id-1" 298 }, 299 "inst4": { 300 "root_store": "ebs", 301 "virt": "pv", 302 "region": "region-2", 303 "id": "id-2" 304 } 305 }, 306 "pubname": "ubuntu-quantal-12.14-amd64-server-20121218", 307 "label": "release" 308 } 309 } 310 }, 311 "com.ubuntu.cloud:server:13.04:amd64": { 312 "release": "raring", 313 "version": "13.04", 314 "arch": "amd64", 315 "versions": { 316 "20121218": { 317 "items": { 318 "inst5": { 319 "root_store": "ebs", 320 "virt": "pv", 321 "region": "some-region", 322 "id": "id-y" 323 }, 324 "inst6": { 325 "root_store": "ebs", 326 "virt": "pv", 327 "region": "another-region", 328 "id": "id-z" 329 } 330 }, 331 "pubname": "ubuntu-raring-13.04-amd64-server-20121218", 332 "label": "release" 333 } 334 } 335 }, 336 "com.ubuntu.cloud:server:14.04:s390x": { 337 "release": "trusty", 338 "version": "14.04", 339 "arch": "s390x", 340 "versions": { 341 "20121218": { 342 "items": { 343 "inst5": { 344 "root_store": "ebs", 345 "virt": "pv", 346 "region": "some-region", 347 "id": "id-y" 348 }, 349 "inst6": { 350 "root_store": "ebs", 351 "virt": "pv", 352 "region": "another-region", 353 "id": "id-z" 354 } 355 }, 356 "pubname": "ubuntu-trusty-14.04-s390x-server-20121218", 357 "label": "release" 358 } 359 } 360 }, 361 "com.ubuntu.cloud:server:16.04:s390x": { 362 "release": "xenial", 363 "version": "16.04", 364 "arch": "s390x", 365 "versions": { 366 "20121218": { 367 "items": { 368 "inst5": { 369 "root_store": "ebs", 370 "virt": "pv", 371 "region": "some-region", 372 "id": "id-y" 373 }, 374 "inst6": { 375 "root_store": "ebs", 376 "virt": "pv", 377 "region": "another-region", 378 "id": "id-z" 379 } 380 }, 381 "pubname": "ubuntu-xenial-16.04-s390x-server-20121218", 382 "label": "release" 383 } 384 } 385 } 386 }, 387 "format": "products:1.0" 388 } 389 ` 390 391 const productMetadatafile = "image-metadata/products.json" 392 393 func UseTestImageData(stor envstorage.Storage, cred *identity.Credentials) { 394 // Put some image metadata files into the public storage. 395 t := template.Must(template.New("").Parse(indexData)) 396 var metadata bytes.Buffer 397 if err := t.Execute(&metadata, cred); err != nil { 398 panic(fmt.Errorf("cannot generate index metdata: %v", err)) 399 } 400 data := metadata.Bytes() 401 stor.Put(simplestreams.UnsignedIndex("v1", 1), bytes.NewReader(data), int64(len(data))) 402 stor.Put( 403 productMetadatafile, strings.NewReader(imagesData), int64(len(imagesData))) 404 405 envtesting.SignTestTools(stor) 406 } 407 408 func RemoveTestImageData(stor envstorage.Storage) { 409 stor.RemoveAll() 410 } 411 412 // DiscardSecurityGroup cleans up a security group, it is not an error to 413 // delete something that doesn't exist. 414 func DiscardSecurityGroup(e environs.Environ, name string) error { 415 env := e.(*Environ) 416 novaClient := env.nova() 417 group, err := novaClient.SecurityGroupByName(name) 418 if err != nil { 419 if errors.IsNotFound(err) { 420 // Group already deleted, done 421 return nil 422 } 423 } 424 err = novaClient.DeleteSecurityGroup(group.Id) 425 if err != nil { 426 return err 427 } 428 return nil 429 } 430 431 func FindInstanceSpec( 432 e environs.Environ, 433 series, arch, cons string, 434 imageMetadata []*imagemetadata.ImageMetadata, 435 ) (spec *instances.InstanceSpec, err error) { 436 env := e.(*Environ) 437 return findInstanceSpec(env, &instances.InstanceConstraint{ 438 Series: series, 439 Arches: []string{arch}, 440 Region: env.cloud.Region, 441 Constraints: constraints.MustParse(cons), 442 }, imageMetadata) 443 } 444 445 func GetSwiftURL(e environs.Environ) (string, error) { 446 return e.(*Environ).client.MakeServiceURL("object-store", nil) 447 } 448 449 func SetUseFloatingIP(e environs.Environ, val bool) { 450 env := e.(*Environ) 451 env.ecfg().attrs["use-floating-ip"] = val 452 } 453 454 func SetUpGlobalGroup(e environs.Environ, name string, apiPort int) (nova.SecurityGroup, error) { 455 return e.(*Environ).firewaller.(*defaultFirewaller).setUpGlobalGroup(name, apiPort) 456 } 457 458 func EnsureGroup(e environs.Environ, name string, rules []nova.RuleInfo) (nova.SecurityGroup, error) { 459 return e.(*Environ).firewaller.(*defaultFirewaller).ensureGroup(name, rules) 460 } 461 462 // ImageMetadataStorage returns a Storage object pointing where the goose 463 // infrastructure sets up its keystone entry for image metadata 464 func ImageMetadataStorage(e environs.Environ) envstorage.Storage { 465 env := e.(*Environ) 466 return &openstackstorage{ 467 containerName: "imagemetadata", 468 swift: swift.New(env.client), 469 } 470 } 471 472 // CreateCustomStorage creates a swift container and returns the Storage object 473 // so you can put data into it. 474 func CreateCustomStorage(e environs.Environ, containerName string) envstorage.Storage { 475 env := e.(*Environ) 476 swiftClient := swift.New(env.client) 477 if err := swiftClient.CreateContainer(containerName, swift.PublicRead); err != nil { 478 panic(err) 479 } 480 return &openstackstorage{ 481 containerName: containerName, 482 swift: swiftClient, 483 } 484 } 485 486 // BlankContainerStorage creates a Storage object with blank container name. 487 func BlankContainerStorage() envstorage.Storage { 488 return &openstackstorage{} 489 } 490 491 func GetNovaClient(e environs.Environ) *nova.Client { 492 return e.(*Environ).nova() 493 } 494 495 // ResolveNetwork exposes environ helper function resolveNetwork for testing 496 func ResolveNetwork(e environs.Environ, networkName string) (string, error) { 497 return e.(*Environ).resolveNetwork(networkName) 498 } 499 500 var PortsToRuleInfo = portsToRuleInfo 501 var RuleMatchesPortRange = ruleMatchesPortRange 502 503 var MakeServiceURL = &makeServiceURL 504 var ProviderInstance = providerInstance 505 506 var GetVolumeEndpointURL = getVolumeEndpointURL