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