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