github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/provider/openstack/live_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package openstack_test 5 6 import ( 7 "crypto/rand" 8 "fmt" 9 "io" 10 "sort" 11 12 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 "gopkg.in/goose.v1/client" 15 "gopkg.in/goose.v1/identity" 16 "gopkg.in/goose.v1/nova" 17 18 "github.com/juju/juju/environs" 19 "github.com/juju/juju/environs/bootstrap" 20 "github.com/juju/juju/environs/config" 21 "github.com/juju/juju/environs/jujutest" 22 "github.com/juju/juju/environs/storage" 23 envtesting "github.com/juju/juju/environs/testing" 24 jujutesting "github.com/juju/juju/juju/testing" 25 "github.com/juju/juju/provider/openstack" 26 coretesting "github.com/juju/juju/testing" 27 ) 28 29 // generate a different bucket name for each config instance, so that 30 // we are not polluted by previous test state. 31 func randomName() string { 32 buf := make([]byte, 8) 33 _, err := io.ReadFull(rand.Reader, buf) 34 if err != nil { 35 panic(fmt.Sprintf("error from crypto rand: %v", err)) 36 } 37 return fmt.Sprintf("%x", buf) 38 } 39 40 func makeTestConfig(cred *identity.Credentials) map[string]interface{} { 41 // The following attributes hold the environment configuration 42 // for running the OpenStack integration tests. 43 // 44 // This is missing keys for security reasons; set the following 45 // environment variables to make the OpenStack testing work: 46 // access-key: $OS_USERNAME 47 // secret-key: $OS_PASSWORD 48 // 49 attrs := coretesting.FakeConfig().Merge(coretesting.Attrs{ 50 "name": "sample-" + randomName(), 51 "type": "openstack", 52 "auth-mode": "userpass", 53 "username": cred.User, 54 "password": cred.Secrets, 55 "region": cred.Region, 56 "auth-url": cred.URL, 57 "tenant-name": cred.TenantName, 58 }) 59 return attrs 60 } 61 62 // Register tests to run against a real Openstack instance. 63 func registerLiveTests(cred *identity.Credentials) { 64 config := makeTestConfig(cred) 65 gc.Suite(&LiveTests{ 66 cred: cred, 67 LiveTests: jujutest.LiveTests{ 68 TestConfig: config, 69 Attempt: *openstack.ShortAttempt, 70 CanOpenState: true, 71 HasProvisioner: true, 72 }, 73 }) 74 } 75 76 // LiveTests contains tests that can be run against OpenStack deployments. 77 // The deployment can be a real live instance or service doubles. 78 // Each test runs using the same connection. 79 type LiveTests struct { 80 coretesting.BaseSuite 81 jujutest.LiveTests 82 cred *identity.Credentials 83 metadataStorage storage.Storage 84 } 85 86 func (t *LiveTests) SetUpSuite(c *gc.C) { 87 t.BaseSuite.SetUpSuite(c) 88 // Update some Config items now that we have services running. 89 // This is setting the simplestreams urls and auth-url because that 90 // information is set during startup of the localLiveSuite 91 cl := client.NewClient(t.cred, identity.AuthUserPass, nil) 92 err := cl.Authenticate() 93 c.Assert(err, jc.ErrorIsNil) 94 containerURL, err := cl.MakeServiceURL("object-store", nil) 95 c.Assert(err, jc.ErrorIsNil) 96 t.TestConfig = t.TestConfig.Merge(coretesting.Attrs{ 97 "agent-metadata-url": containerURL + "/juju-dist-test/tools", 98 "image-metadata-url": containerURL + "/juju-dist-test", 99 "auth-url": t.cred.URL, 100 }) 101 t.LiveTests.SetUpSuite(c) 102 // For testing, we create a storage instance to which is uploaded tools and image metadata. 103 t.PrepareOnce(c) 104 t.metadataStorage = openstack.MetadataStorage(t.Env) 105 // Put some fake tools metadata in place so that tests that are simply 106 // starting instances without any need to check if those instances 107 // are running can find the metadata. 108 envtesting.UploadFakeTools(c, t.metadataStorage, t.Env.Config().AgentStream(), t.Env.Config().AgentStream()) 109 } 110 111 func (t *LiveTests) TearDownSuite(c *gc.C) { 112 if t.Env == nil { 113 // This can happen if SetUpSuite fails. 114 return 115 } 116 if t.metadataStorage != nil { 117 envtesting.RemoveFakeToolsMetadata(c, t.metadataStorage) 118 } 119 t.LiveTests.TearDownSuite(c) 120 t.BaseSuite.TearDownSuite(c) 121 } 122 123 func (t *LiveTests) SetUpTest(c *gc.C) { 124 t.BaseSuite.SetUpTest(c) 125 t.LiveTests.SetUpTest(c) 126 } 127 128 func (t *LiveTests) TearDownTest(c *gc.C) { 129 t.LiveTests.TearDownTest(c) 130 t.BaseSuite.TearDownTest(c) 131 } 132 133 func (t *LiveTests) TestEnsureGroupSetsGroupId(c *gc.C) { 134 t.PrepareOnce(c) 135 rules := []nova.RuleInfo{ 136 { // First group explicitly asks for all services 137 IPProtocol: "tcp", 138 FromPort: 22, 139 ToPort: 22, 140 Cidr: "0.0.0.0/0", 141 }, 142 { // Second group should only allow access from within the group 143 IPProtocol: "tcp", 144 FromPort: 1, 145 ToPort: 65535, 146 }, 147 } 148 groupName := "juju-test-group-" + randomName() 149 // Make sure things are clean before we start, and clean when we are done 150 cleanup := func() { 151 c.Check(openstack.DiscardSecurityGroup(t.Env, groupName), gc.IsNil) 152 } 153 cleanup() 154 defer cleanup() 155 group, err := openstack.EnsureGroup(t.Env, groupName, rules) 156 c.Assert(err, jc.ErrorIsNil) 157 c.Check(group.Rules, gc.HasLen, 2) 158 c.Check(*group.Rules[0].IPProtocol, gc.Equals, "tcp") 159 c.Check(*group.Rules[0].FromPort, gc.Equals, 22) 160 c.Check(*group.Rules[0].ToPort, gc.Equals, 22) 161 c.Check(group.Rules[0].IPRange["cidr"], gc.Equals, "0.0.0.0/0") 162 c.Check(group.Rules[0].Group.Name, gc.Equals, "") 163 c.Check(group.Rules[0].Group.TenantId, gc.Equals, "") 164 c.Check(*group.Rules[1].IPProtocol, gc.Equals, "tcp") 165 c.Check(*group.Rules[1].FromPort, gc.Equals, 1) 166 c.Check(*group.Rules[1].ToPort, gc.Equals, 65535) 167 c.Check(group.Rules[1].IPRange, gc.HasLen, 0) 168 c.Check(group.Rules[1].Group.Name, gc.Equals, groupName) 169 c.Check(group.Rules[1].Group.TenantId, gc.Equals, group.TenantId) 170 } 171 172 func (t *LiveTests) TestSetupGlobalGroupExposesCorrectPorts(c *gc.C) { 173 t.PrepareOnce(c) 174 groupName := "juju-test-group-" + randomName() 175 // Make sure things are clean before we start, and will be clean when we finish 176 cleanup := func() { 177 c.Check(openstack.DiscardSecurityGroup(t.Env, groupName), gc.IsNil) 178 } 179 cleanup() 180 defer cleanup() 181 apiPort := 34567 // Default 17070 182 group, err := openstack.SetUpGlobalGroup(t.Env, groupName, apiPort) 183 c.Assert(err, jc.ErrorIsNil) 184 // We default to exporting 22, apiPort, and icmp/udp/tcp on 185 // all ports to other machines inside the same group 186 // TODO(jam): 2013-09-18 http://pad.lv/1227142 187 // We shouldn't be exposing the API port on all the machines 188 // that *aren't* hosting the controller. 189 stringRules := make([]string, 0, len(group.Rules)) 190 for _, rule := range group.Rules { 191 ruleStr := fmt.Sprintf("%s %d %d %q %q", 192 *rule.IPProtocol, 193 *rule.FromPort, 194 *rule.ToPort, 195 rule.IPRange["cidr"], 196 rule.Group.Name, 197 ) 198 stringRules = append(stringRules, ruleStr) 199 } 200 // We don't care about the ordering, so we sort the result, and compare it. 201 expectedRules := []string{ 202 `tcp 22 22 "0.0.0.0/0" ""`, 203 fmt.Sprintf(`tcp %d %d "0.0.0.0/0" ""`, apiPort, apiPort), 204 fmt.Sprintf(`tcp 1 65535 "" "%s"`, groupName), 205 fmt.Sprintf(`udp 1 65535 "" "%s"`, groupName), 206 fmt.Sprintf(`icmp -1 -1 "" "%s"`, groupName), 207 } 208 sort.Strings(stringRules) 209 sort.Strings(expectedRules) 210 c.Check(stringRules, gc.DeepEquals, expectedRules) 211 } 212 213 func (s *LiveTests) assertStartInstanceDefaultSecurityGroup(c *gc.C, useDefault bool) { 214 attrs := s.TestConfig.Merge(coretesting.Attrs{ 215 "name": "sample-" + randomName(), 216 "use-default-secgroup": useDefault, 217 }) 218 cfg, err := config.New(config.NoDefaults, attrs) 219 c.Assert(err, jc.ErrorIsNil) 220 // Set up a test environment. 221 env, err := environs.New(cfg) 222 c.Assert(err, jc.ErrorIsNil) 223 c.Assert(env, gc.NotNil) 224 defer env.Destroy() 225 // Bootstrap and start an instance. 226 err = bootstrap.Bootstrap(envtesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) 227 c.Assert(err, jc.ErrorIsNil) 228 inst, _ := jujutesting.AssertStartInstance(c, env, "100") 229 // Check whether the instance has the default security group assigned. 230 novaClient := openstack.GetNovaClient(env) 231 groups, err := novaClient.GetServerSecurityGroups(string(inst.Id())) 232 c.Assert(err, jc.ErrorIsNil) 233 defaultGroupFound := false 234 for _, group := range groups { 235 if group.Name == "default" { 236 defaultGroupFound = true 237 break 238 } 239 } 240 c.Assert(defaultGroupFound, gc.Equals, useDefault) 241 } 242 243 func (s *LiveTests) TestStartInstanceWithDefaultSecurityGroup(c *gc.C) { 244 s.assertStartInstanceDefaultSecurityGroup(c, true) 245 } 246 247 func (s *LiveTests) TestStartInstanceWithoutDefaultSecurityGroup(c *gc.C) { 248 s.assertStartInstanceDefaultSecurityGroup(c, false) 249 }