github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/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.v2/client" 15 "gopkg.in/goose.v2/identity" 16 17 "github.com/juju/juju/environs/context" 18 "github.com/juju/juju/environs/jujutest" 19 "github.com/juju/juju/environs/storage" 20 envtesting "github.com/juju/juju/environs/testing" 21 jujutesting "github.com/juju/juju/juju/testing" 22 "github.com/juju/juju/provider/openstack" 23 coretesting "github.com/juju/juju/testing" 24 ) 25 26 // generate a different bucket name for each config instance, so that 27 // we are not polluted by previous test state. 28 func randomName() string { 29 buf := make([]byte, 8) 30 _, err := io.ReadFull(rand.Reader, buf) 31 if err != nil { 32 panic(fmt.Sprintf("error from crypto rand: %v", err)) 33 } 34 return fmt.Sprintf("%x", buf) 35 } 36 37 func makeTestConfig(cred *identity.Credentials) map[string]interface{} { 38 // The following attributes hold the environment configuration 39 // for running the OpenStack integration tests. 40 // 41 // This is missing keys for security reasons; set the following 42 // environment variables to make the OpenStack testing work: 43 // access-key: $OS_USERNAME 44 // secret-key: $OS_PASSWORD 45 // 46 attrs := coretesting.FakeConfig().Merge(coretesting.Attrs{ 47 "name": "sample-" + randomName(), 48 "type": "openstack", 49 "auth-mode": "userpass", 50 "username": cred.User, 51 "password": cred.Secrets, 52 "region": cred.Region, 53 "auth-url": cred.URL, 54 "tenant-name": cred.TenantName, 55 }) 56 return attrs 57 } 58 59 // Register tests to run against a real Openstack instance. 60 func registerLiveTests(cred *identity.Credentials) { 61 config := makeTestConfig(cred) 62 gc.Suite(&LiveTests{ 63 cred: cred, 64 LiveTests: jujutest.LiveTests{ 65 TestConfig: config, 66 Attempt: *openstack.ShortAttempt, 67 CanOpenState: true, 68 HasProvisioner: true, 69 }, 70 }) 71 } 72 73 // LiveTests contains tests that can be run against OpenStack deployments. 74 // The deployment can be a real live instance or service doubles. 75 // Each test runs using the same connection. 76 type LiveTests struct { 77 coretesting.BaseSuite 78 jujutest.LiveTests 79 cred *identity.Credentials 80 metadataStorage storage.Storage 81 } 82 83 func (t *LiveTests) SetUpSuite(c *gc.C) { 84 t.BaseSuite.SetUpSuite(c) 85 // Update some Config items now that we have services running. 86 // This is setting the simplestreams urls and auth-url because that 87 // information is set during startup of the localLiveSuite 88 cl := client.NewClient(t.cred, identity.AuthUserPass, nil) 89 err := cl.Authenticate() 90 c.Assert(err, jc.ErrorIsNil) 91 containerURL, err := cl.MakeServiceURL("object-store", "", nil) 92 c.Assert(err, jc.ErrorIsNil) 93 t.TestConfig = t.TestConfig.Merge(coretesting.Attrs{ 94 "agent-metadata-url": containerURL + "/juju-dist-test/tools", 95 "image-metadata-url": containerURL + "/juju-dist-test", 96 "auth-url": t.cred.URL, 97 }) 98 t.LiveTests.SetUpSuite(c) 99 // For testing, we create a storage instance to which is uploaded tools and image metadata. 100 t.PrepareOnce(c) 101 t.metadataStorage = openstack.MetadataStorage(t.Env) 102 // Put some fake tools metadata in place so that tests that are simply 103 // starting instances without any need to check if those instances 104 // are running can find the metadata. 105 envtesting.UploadFakeTools(c, t.metadataStorage, t.Env.Config().AgentStream(), t.Env.Config().AgentStream()) 106 } 107 108 func (t *LiveTests) TearDownSuite(c *gc.C) { 109 if t.Env == nil { 110 // This can happen if SetUpSuite fails. 111 return 112 } 113 if t.metadataStorage != nil { 114 envtesting.RemoveFakeToolsMetadata(c, t.metadataStorage) 115 } 116 t.LiveTests.TearDownSuite(c) 117 t.BaseSuite.TearDownSuite(c) 118 } 119 120 func (t *LiveTests) SetUpTest(c *gc.C) { 121 t.BaseSuite.SetUpTest(c) 122 t.LiveTests.SetUpTest(c) 123 } 124 125 func (t *LiveTests) TearDownTest(c *gc.C) { 126 t.LiveTests.TearDownTest(c) 127 t.BaseSuite.TearDownTest(c) 128 } 129 130 func (t *LiveTests) TestSetupGlobalGroupExposesCorrectPorts(c *gc.C) { 131 t.PrepareOnce(c) 132 groupName := "juju-test-group-" + randomName() 133 // Make sure things are clean before we start, and will be clean when we finish 134 cleanup := func() { 135 c.Check(openstack.DiscardSecurityGroup(t.Env, groupName), gc.IsNil) 136 } 137 cleanup() 138 defer cleanup() 139 apiPort := 34567 // Default 17070 140 group, err := openstack.SetUpGlobalGroup(t.Env, t.ProviderCallContext, groupName, apiPort) 141 c.Assert(err, jc.ErrorIsNil) 142 // We default to exporting 22, apiPort, and icmp/udp/tcp on 143 // all ports to other machines inside the same group 144 // TODO(jam): 2013-09-18 http://pad.lv/1227142 145 // We shouldn't be exposing the API port on all the machines 146 // that *aren't* hosting the controller. 147 stringRules := make([]string, 0, len(group.Rules)) 148 for _, rule := range group.Rules { 149 // Skip the default Security Group Rules created by Neutron 150 if rule.Direction == "egress" { 151 continue 152 } 153 var minInt int 154 if rule.PortRangeMin != nil { 155 minInt = *rule.PortRangeMin 156 } 157 var maxInt int 158 if rule.PortRangeMax != nil { 159 maxInt = *rule.PortRangeMax 160 } 161 ruleStr := fmt.Sprintf("%s %s %d %d %s %s %s", 162 rule.Direction, 163 *rule.IPProtocol, 164 minInt, maxInt, 165 rule.RemoteIPPrefix, 166 rule.EthernetType, 167 rule.ParentGroupId, 168 ) 169 stringRules = append(stringRules, ruleStr) 170 } 171 // We don't care about the ordering, so we sort the result, and compare it. 172 expectedRules := []string{ 173 fmt.Sprintf(`ingress tcp 22 22 ::/0 IPv6 %s`, group.Id), 174 fmt.Sprintf(`ingress tcp 22 22 0.0.0.0/0 IPv4 %s`, group.Id), 175 fmt.Sprintf(`ingress tcp %d %d ::/0 IPv6 %s`, apiPort, apiPort, group.Id), 176 fmt.Sprintf(`ingress tcp %d %d 0.0.0.0/0 IPv4 %s`, apiPort, apiPort, group.Id), 177 fmt.Sprintf(`ingress tcp 1 65535 IPv6 %s`, group.Id), 178 fmt.Sprintf(`ingress tcp 1 65535 IPv4 %s`, group.Id), 179 fmt.Sprintf(`ingress udp 1 65535 IPv6 %s`, group.Id), 180 fmt.Sprintf(`ingress udp 1 65535 IPv4 %s`, group.Id), 181 fmt.Sprintf(`ingress icmp 0 0 IPv6 %s`, group.Id), 182 fmt.Sprintf(`ingress icmp 0 0 IPv4 %s`, group.Id), 183 } 184 sort.Strings(stringRules) 185 sort.Strings(expectedRules) 186 c.Check(stringRules, gc.DeepEquals, expectedRules) 187 } 188 189 func (s *LiveTests) assertStartInstanceDefaultSecurityGroup(c *gc.C, useDefault bool) { 190 s.LiveTests.PatchValue(&s.TestConfig, s.TestConfig.Merge(coretesting.Attrs{ 191 "use-default-secgroup": useDefault, 192 })) 193 s.Destroy(c) 194 s.BootstrapOnce(c) 195 196 inst, _ := jujutesting.AssertStartInstance(c, s.Env, context.NewCloudCallContext(), s.ControllerUUID, "100") 197 // Check whether the instance has the default security group assigned. 198 novaClient := openstack.GetNovaClient(s.Env) 199 groups, err := novaClient.GetServerSecurityGroups(string(inst.Id())) 200 c.Assert(err, jc.ErrorIsNil) 201 defaultGroupFound := false 202 for _, group := range groups { 203 if group.Name == "default" { 204 defaultGroupFound = true 205 break 206 } 207 } 208 c.Assert(defaultGroupFound, gc.Equals, useDefault) 209 } 210 211 func (s *LiveTests) TestStartInstanceWithDefaultSecurityGroup(c *gc.C) { 212 s.assertStartInstanceDefaultSecurityGroup(c, true) 213 } 214 215 func (s *LiveTests) TestStartInstanceWithoutDefaultSecurityGroup(c *gc.C) { 216 s.assertStartInstanceDefaultSecurityGroup(c, false) 217 }