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  }