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