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