blob: 99d128f0a684c3197137a2eaeff2d4068c3c417a [file] [log] [blame]
Samuel A. Falvo II704a7502013-07-10 15:23:43 -07001package main
2
3import (
4 "fmt"
5 "os"
Samuel A. Falvo IIe91ff6d2013-07-11 15:46:10 -07006 "crypto/rand"
Samuel A. Falvo II8935ca32013-07-25 21:27:06 -07007 "github.com/rackspace/gophercloud"
Samuel A. Falvo II704a7502013-07-10 15:23:43 -07008)
9
10// getCredentials will verify existence of needed credential information
11// provided through environment variables. This function will not return
12// if at least one piece of required information is missing.
13func getCredentials() (provider, username, password string) {
14 provider = os.Getenv("SDK_PROVIDER")
15 username = os.Getenv("SDK_USERNAME")
16 password = os.Getenv("SDK_PASSWORD")
17
18 if (provider == "") || (username == "") || (password == "") {
19 fmt.Fprintf(os.Stderr, "One or more of the following environment variables aren't set:\n")
20 fmt.Fprintf(os.Stderr, " SDK_PROVIDER=\"%s\"\n", provider)
21 fmt.Fprintf(os.Stderr, " SDK_USERNAME=\"%s\"\n", username)
22 fmt.Fprintf(os.Stderr, " SDK_PASSWORD=\"%s\"\n", password)
23 os.Exit(1)
24 }
25
26 return
27}
Samuel A. Falvo IIe91ff6d2013-07-11 15:46:10 -070028
29// randomString generates a string of given length, but random content.
30// All content will be within the ASCII graphic character set.
31// (Implementation from Even Shaw's contribution on
32// http://stackoverflow.com/questions/12771930/what-is-the-fastest-way-to-generate-a-long-random-string-in-go).
Samuel A. Falvo IIe3b2d7a2013-07-12 11:08:02 -070033func randomString(prefix string, n int) string {
Samuel A. Falvo IIe91ff6d2013-07-11 15:46:10 -070034 const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
35 var bytes = make([]byte, n)
36 rand.Read(bytes)
37 for i, b := range bytes {
38 bytes[i] = alphanum[b % byte(len(alphanum))]
39 }
Samuel A. Falvo IIe3b2d7a2013-07-12 11:08:02 -070040 return prefix + string(bytes)
Samuel A. Falvo II8935ca32013-07-25 21:27:06 -070041}
42
43// aSuitableImage finds a minimal image for use in dynamically creating servers.
44// If none can be found, this function will panic.
45func aSuitableImage(api gophercloud.CloudServersProvider) string {
46 images, err := api.ListImages()
47 if err != nil {
48 panic(err)
49 }
50
51 // TODO(sfalvo):
52 // Works for Rackspace, might not work for your provider!
53 // Need to figure out why ListImages() provides 0 values for
54 // Ram and Disk fields.
55 //
56 // Until then, just return Ubuntu 12.04 LTS.
57 for i := 0; i < len(images); i++ {
58 if images[i].Id == "23b564c9-c3e6-49f9-bc68-86c7a9ab5018" {
59 return images[i].Id
60 }
61 }
62 panic("Image 23b564c9-c3e6-49f9-bc68-86c7a9ab5018 (Ubuntu 12.04 LTS) not found.")
63}
64
65// aSuitableFlavor finds the minimum flavor capable of running the test image
66// chosen by aSuitableImage. If none can be found, this function will panic.
67func aSuitableFlavor(api gophercloud.CloudServersProvider) string {
68 flavors, err := api.ListFlavors()
69 if err != nil {
70 panic(err)
71 }
72
73 // TODO(sfalvo):
74 // Works for Rackspace, might not work for your provider!
75 // Need to figure out why ListFlavors() provides 0 values for
76 // Ram and Disk fields.
77 //
78 // Until then, just return Ubuntu 12.04 LTS.
79 for i := 0; i < len(flavors); i++ {
80 if flavors[i].Id == "2" {
81 return flavors[i].Id
82 }
83 }
84 panic("Flavor 2 (512MB 1-core 20GB machine) not found.")
85}
86
87// createServer creates a new server in a manner compatible with acceptance testing.
88// In particular, it ensures that the name of the server always starts with "ACPTTEST--",
89// which the delete servers acceptance test relies on to identify servers to delete.
90// Passing in empty image and flavor references will force the use of reasonable defaults.
91// An empty name string will result in a dynamically created name prefixed with "ACPTTEST--".
92// A blank admin password will cause a password to be automatically generated; however,
93// at present no means of recovering this password exists, as no acceptance tests yet require
94// this data.
95func createServer(servers gophercloud.CloudServersProvider, imageRef, flavorRef, name, adminPass string) error {
96 if imageRef == "" {
97 imageRef = aSuitableImage(servers)
98 }
99
100 if flavorRef == "" {
101 flavorRef = aSuitableFlavor(servers)
102 }
103
104 if len(name) < 1 {
105 name = randomString("ACPTTEST", 16)
106 }
107
108 if (len(name) < 8) || (name[0:8] != "ACPTTEST") {
109 name = fmt.Sprintf("ACPTTEST--%s", name)
110 }
111
112 _, err := servers.CreateServer(gophercloud.NewServer{
113 Name: name,
114 ImageRef: imageRef,
115 FlavorRef: flavorRef,
116 AdminPass: adminPass,
117 })
118
119 return err
120}