github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/provider/ec2/config_test.go (about)

     1  // Copyright 2011, 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package ec2
     5  
     6  // TODO: Clean this up so it matches environs/openstack/config_test.go.
     7  
     8  import (
     9  	"io/ioutil"
    10  	"os"
    11  	"path/filepath"
    12  	"strings"
    13  
    14  	"github.com/juju/utils"
    15  	"launchpad.net/goamz/aws"
    16  	gc "launchpad.net/gocheck"
    17  
    18  	"github.com/juju/juju/environs"
    19  	"github.com/juju/juju/environs/config"
    20  	"github.com/juju/juju/testing"
    21  )
    22  
    23  // Use local suite since this file lives in the ec2 package
    24  // for testing internals.
    25  type ConfigSuite struct {
    26  	testing.BaseSuite
    27  	savedHome, savedAccessKey, savedSecretKey string
    28  }
    29  
    30  var _ = gc.Suite(&ConfigSuite{})
    31  
    32  var configTestRegion = aws.Region{
    33  	Name:        "configtest",
    34  	EC2Endpoint: "testregion.nowhere:1234",
    35  }
    36  
    37  var testAuth = aws.Auth{"gopher", "long teeth"}
    38  
    39  // configTest specifies a config parsing test, checking that env when
    40  // parsed as the ec2 section of a config file matches baseConfigResult
    41  // when mutated by the mutate function, or that the parse matches the
    42  // given error.
    43  type configTest struct {
    44  	config        map[string]interface{}
    45  	change        map[string]interface{}
    46  	expect        map[string]interface{}
    47  	region        string
    48  	cbucket       string
    49  	pbucket       string
    50  	pbucketRegion string
    51  	accessKey     string
    52  	secretKey     string
    53  	firewallMode  string
    54  	err           string
    55  }
    56  
    57  type attrs map[string]interface{}
    58  
    59  func (t configTest) check(c *gc.C) {
    60  	attrs := testing.FakeConfig().Merge(testing.Attrs{
    61  		"type":           "ec2",
    62  		"control-bucket": "x",
    63  	}).Merge(t.config)
    64  	cfg, err := config.New(config.NoDefaults, attrs)
    65  	c.Assert(err, gc.IsNil)
    66  	e, err := environs.New(cfg)
    67  	if t.change != nil {
    68  		c.Assert(err, gc.IsNil)
    69  
    70  		// Testing a change in configuration.
    71  		var old, changed, valid *config.Config
    72  		ec2env := e.(*environ)
    73  		old = ec2env.ecfg().Config
    74  		changed, err = old.Apply(t.change)
    75  		c.Assert(err, gc.IsNil)
    76  
    77  		// Keep err for validation below.
    78  		valid, err = providerInstance.Validate(changed, old)
    79  		if err == nil {
    80  			err = ec2env.SetConfig(valid)
    81  		}
    82  	}
    83  	if t.err != "" {
    84  		c.Check(err, gc.ErrorMatches, t.err)
    85  		return
    86  	}
    87  	c.Assert(err, gc.IsNil)
    88  
    89  	ecfg := e.(*environ).ecfg()
    90  	c.Assert(ecfg.Name(), gc.Equals, "testenv")
    91  	c.Assert(ecfg.controlBucket(), gc.Equals, "x")
    92  	if t.region != "" {
    93  		c.Assert(ecfg.region(), gc.Equals, t.region)
    94  	}
    95  	if t.accessKey != "" {
    96  		c.Assert(ecfg.accessKey(), gc.Equals, t.accessKey)
    97  		c.Assert(ecfg.secretKey(), gc.Equals, t.secretKey)
    98  		expected := map[string]string{
    99  			"access-key": t.accessKey,
   100  			"secret-key": t.secretKey,
   101  		}
   102  		c.Assert(err, gc.IsNil)
   103  		actual, err := e.Provider().SecretAttrs(ecfg.Config)
   104  		c.Assert(err, gc.IsNil)
   105  		c.Assert(expected, gc.DeepEquals, actual)
   106  	} else {
   107  		c.Assert(ecfg.accessKey(), gc.DeepEquals, testAuth.AccessKey)
   108  		c.Assert(ecfg.secretKey(), gc.DeepEquals, testAuth.SecretKey)
   109  	}
   110  	if t.firewallMode != "" {
   111  		c.Assert(ecfg.FirewallMode(), gc.Equals, t.firewallMode)
   112  	}
   113  	for name, expect := range t.expect {
   114  		actual, found := ecfg.UnknownAttrs()[name]
   115  		c.Check(found, gc.Equals, true)
   116  		c.Check(actual, gc.Equals, expect)
   117  	}
   118  
   119  	// check storage bucket is configured correctly
   120  	env := e.(*environ)
   121  	c.Assert(env.Storage().(*ec2storage).bucket.Region.Name, gc.Equals, ecfg.region())
   122  }
   123  
   124  var configTests = []configTest{
   125  	{
   126  		config: attrs{},
   127  	}, {
   128  		// check that region defaults to us-east-1
   129  		config: attrs{},
   130  		region: "us-east-1",
   131  	}, {
   132  		config: attrs{
   133  			"region": "eu-west-1",
   134  		},
   135  		region: "eu-west-1",
   136  	}, {
   137  		config: attrs{
   138  			"region": "unknown",
   139  		},
   140  		err: ".*invalid region name.*",
   141  	}, {
   142  		config: attrs{
   143  			"region": "configtest",
   144  		},
   145  		region: "configtest",
   146  	}, {
   147  		config: attrs{
   148  			"region": "configtest",
   149  		},
   150  		change: attrs{
   151  			"region": "us-east-1",
   152  		},
   153  		err: `cannot change region from "configtest" to "us-east-1"`,
   154  	}, {
   155  		config: attrs{
   156  			"region": 666,
   157  		},
   158  		err: `.*expected string, got int\(666\)`,
   159  	}, {
   160  		config: attrs{
   161  			"access-key": 666,
   162  		},
   163  		err: `.*expected string, got int\(666\)`,
   164  	}, {
   165  		config: attrs{
   166  			"secret-key": 666,
   167  		},
   168  		err: `.*expected string, got int\(666\)`,
   169  	}, {
   170  		config: attrs{
   171  			"control-bucket": 666,
   172  		},
   173  		err: `.*expected string, got int\(666\)`,
   174  	}, {
   175  		change: attrs{
   176  			"control-bucket": "new-x",
   177  		},
   178  		err: `cannot change control-bucket from "x" to "new-x"`,
   179  	}, {
   180  		config: attrs{
   181  			"access-key": "jujuer",
   182  			"secret-key": "open sesame",
   183  		},
   184  		accessKey: "jujuer",
   185  		secretKey: "open sesame",
   186  	}, {
   187  		config: attrs{
   188  			"access-key": "jujuer",
   189  		},
   190  		err: ".*environment has no access-key or secret-key",
   191  	}, {
   192  		config: attrs{
   193  			"secret-key": "badness",
   194  		},
   195  		err: ".*environment has no access-key or secret-key",
   196  	}, {
   197  		config: attrs{
   198  			"admin-secret": "Futumpsh",
   199  		},
   200  	}, {
   201  		config:       attrs{},
   202  		firewallMode: config.FwInstance,
   203  	}, {
   204  		config: attrs{
   205  			"firewall-mode": "instance",
   206  		},
   207  		firewallMode: config.FwInstance,
   208  	}, {
   209  		config: attrs{
   210  			"firewall-mode": "global",
   211  		},
   212  		firewallMode: config.FwGlobal,
   213  	}, {
   214  		config: attrs{
   215  			"ssl-hostname-verification": false,
   216  		},
   217  		err: "disabling ssh-hostname-verification is not supported",
   218  	}, {
   219  		config: attrs{
   220  			"future": "hammerstein",
   221  		},
   222  		expect: attrs{
   223  			"future": "hammerstein",
   224  		},
   225  	}, {
   226  		change: attrs{
   227  			"future": "hammerstein",
   228  		},
   229  		expect: attrs{
   230  			"future": "hammerstein",
   231  		},
   232  	},
   233  }
   234  
   235  func indent(s string, with string) string {
   236  	var r string
   237  	lines := strings.Split(s, "\n")
   238  	for _, l := range lines {
   239  		r += with + l + "\n"
   240  	}
   241  	return r
   242  }
   243  
   244  func (s *ConfigSuite) SetUpTest(c *gc.C) {
   245  	s.BaseSuite.SetUpTest(c)
   246  	s.savedHome = utils.Home()
   247  	s.savedAccessKey = os.Getenv("AWS_ACCESS_KEY_ID")
   248  	s.savedSecretKey = os.Getenv("AWS_SECRET_ACCESS_KEY")
   249  
   250  	home := c.MkDir()
   251  	sshDir := filepath.Join(home, ".ssh")
   252  	err := os.Mkdir(sshDir, 0777)
   253  	c.Assert(err, gc.IsNil)
   254  	err = ioutil.WriteFile(filepath.Join(sshDir, "id_rsa.pub"), []byte("sshkey\n"), 0666)
   255  	c.Assert(err, gc.IsNil)
   256  
   257  	utils.SetHome(home)
   258  	os.Setenv("AWS_ACCESS_KEY_ID", testAuth.AccessKey)
   259  	os.Setenv("AWS_SECRET_ACCESS_KEY", testAuth.SecretKey)
   260  	aws.Regions["configtest"] = configTestRegion
   261  }
   262  
   263  func (s *ConfigSuite) TearDownTest(c *gc.C) {
   264  	utils.SetHome(s.savedHome)
   265  	os.Setenv("AWS_ACCESS_KEY_ID", s.savedAccessKey)
   266  	os.Setenv("AWS_SECRET_ACCESS_KEY", s.savedSecretKey)
   267  	delete(aws.Regions, "configtest")
   268  	s.BaseSuite.TearDownTest(c)
   269  }
   270  
   271  func (s *ConfigSuite) TestConfig(c *gc.C) {
   272  	for i, t := range configTests {
   273  		c.Logf("test %d: %v", i, t.config)
   274  		t.check(c)
   275  	}
   276  }
   277  
   278  func (s *ConfigSuite) TestMissingAuth(c *gc.C) {
   279  	os.Setenv("AWS_ACCESS_KEY_ID", "")
   280  	os.Setenv("AWS_SECRET_ACCESS_KEY", "")
   281  	// Since r37 goamz uses these as fallbacks, so unset them too.
   282  	os.Setenv("EC2_ACCESS_KEY", "")
   283  	os.Setenv("EC2_SECRET_KEY", "")
   284  	test := configTests[0]
   285  	test.err = "environment has no access-key or secret-key"
   286  	test.check(c)
   287  }
   288  
   289  func (s *ConfigSuite) TestPrepareInsertsUniqueControlBucket(c *gc.C) {
   290  	attrs := testing.FakeConfig().Merge(testing.Attrs{
   291  		"type": "ec2",
   292  	})
   293  	cfg, err := config.New(config.NoDefaults, attrs)
   294  	c.Assert(err, gc.IsNil)
   295  
   296  	ctx := testing.Context(c)
   297  	env0, err := providerInstance.Prepare(ctx, cfg)
   298  	c.Assert(err, gc.IsNil)
   299  	bucket0 := env0.(*environ).ecfg().controlBucket()
   300  	c.Assert(bucket0, gc.Matches, "[a-f0-9]{32}")
   301  
   302  	env1, err := providerInstance.Prepare(ctx, cfg)
   303  	c.Assert(err, gc.IsNil)
   304  	bucket1 := env1.(*environ).ecfg().controlBucket()
   305  	c.Assert(bucket1, gc.Matches, "[a-f0-9]{32}")
   306  
   307  	c.Assert(bucket1, gc.Not(gc.Equals), bucket0)
   308  }
   309  
   310  func (s *ConfigSuite) TestPrepareDoesNotTouchExistingControlBucket(c *gc.C) {
   311  	attrs := testing.FakeConfig().Merge(testing.Attrs{
   312  		"type":           "ec2",
   313  		"control-bucket": "burblefoo",
   314  	})
   315  	cfg, err := config.New(config.NoDefaults, attrs)
   316  	c.Assert(err, gc.IsNil)
   317  
   318  	env, err := providerInstance.Prepare(testing.Context(c), cfg)
   319  	c.Assert(err, gc.IsNil)
   320  	bucket := env.(*environ).ecfg().controlBucket()
   321  	c.Assert(bucket, gc.Equals, "burblefoo")
   322  }